glide2gl/src/Glide64/Glide64_Ini.h000664 001750 001750 00000000157 12655644434 017546 0ustar00sergiosergio000000 000000 #ifndef _GLIDE64_INI_OVER_H #define _GLIDE64_INI_OVER_H void ReadSpecialSettings (const char * name); #endif mupen64plus-core/src/ri/rdram.c000664 001750 001750 00000005765 12655644434 017536 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - rdram.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "rdram.h" #include "ri_controller.h" #include "../memory/memory.h" #include void connect_rdram(struct rdram* rdram, uint32_t* dram, size_t dram_size) { rdram->dram = dram; rdram->dram_size = dram_size; } void init_rdram(struct rdram* rdram) { memset(rdram->regs, 0, RDRAM_REGS_COUNT*sizeof(uint32_t)); memset(rdram->dram, 0, rdram->dram_size); } int read_rdram_regs(void* opaque, uint32_t address, uint32_t* value) { struct ri_controller* ri = (struct ri_controller*)opaque; uint32_t reg = RDRAM_REG(address); *value = ri->rdram.regs[reg]; return 0; } int write_rdram_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask) { struct ri_controller* ri = (struct ri_controller*)opaque; uint32_t reg = RDRAM_REG(address); ri->rdram.regs[reg] = MASKED_WRITE(&ri->rdram.regs[reg], value, mask); return 0; } int read_rdram_dram(void* opaque, uint32_t address, uint32_t* value) { struct ri_controller* ri = (struct ri_controller*)opaque; uint32_t addr = RDRAM_DRAM_ADDR(address); *value = ri->rdram.dram[addr]; return 0; } int write_rdram_dram(void* opaque, uint32_t address, uint32_t value, uint32_t mask) { struct ri_controller* ri = (struct ri_controller*)opaque; uint32_t addr = RDRAM_DRAM_ADDR(address); ri->rdram.dram[addr] = MASKED_WRITE(&ri->rdram.dram[addr], value, mask); return 0; } glide2gl/src/Glide64/TexLoad.h000664 001750 001750 00000004555 12655644434 017117 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** #ifndef TEXLOAD_H #define TEXLOAD_H #include typedef uint32_t (*texfunc)(uintptr_t, uintptr_t, int, int, int, int, int); extern texfunc load_table[4][5]; void LoadBlock32b(uint32_t tile, uint32_t ul_s, uint32_t ul_t, uint32_t lr_s, uint32_t dxt); void LoadTile32b(uint32_t tile, uint32_t ul_s, uint32_t ul_t, uint32_t width, uint32_t height); void loadBlock(uint32_t *src, uint32_t *dst, uint32_t off, int dxt, int cnt); void loadTile(uint32_t *src, uint32_t *dst, int width, int height, int line, int off, uint32_t *end); #endif mupen64plus-core/src/r4300/empty_dynarec.c000664 001750 001750 00000017020 12655644434 021415 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - empty_dynarec.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Richard42, Nmn * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "recomp.h" /* From assemble.c */ void init_assembler(void *block_jumps_table, int block_jumps_number, void *block_riprel_table, int block_riprel_number) { } void free_assembler(void **block_jumps_table, int *block_jumps_number, void **block_riprel_table, int *block_riprel_number) { } void passe2(precomp_instr *dest, int start, int end, precomp_block *block) { } /* From gbc.c */ void genbc1f() { } void genbc1f_out() { } void genbc1f_idle() { } void genbc1t() { } void genbc1t_out() { } void genbc1t_idle() { } void genbc1fl() { } void genbc1fl_out() { } void genbc1fl_idle() { } void genbc1tl() { } void genbc1tl_out() { } void genbc1tl_idle() { } /* From gcop0.c */ void genmfc0() { } void genmtc0() { } /* From gcop1.c */ void genmfc1() { } void gendmfc1() { } void gencfc1() { } void genmtc1() { } void gendmtc1() { } void genctc1() { } /* From gcop1_d.c */ void genadd_d() { } void gensub_d() { } void genmul_d() { } void gendiv_d() { } void gensqrt_d() { } void genabs_d() { } void genmov_d() { } void genneg_d() { } void genround_l_d() { } void gentrunc_l_d() { } void genceil_l_d() { } void genfloor_l_d() { } void genround_w_d() { } void gentrunc_w_d() { } void genceil_w_d() { } void genfloor_w_d() { } void gencvt_s_d() { } void gencvt_w_d() { } void gencvt_l_d() { } void genc_f_d() { } void genc_un_d() { } void genc_eq_d() { } void genc_ueq_d() { } void genc_olt_d() { } void genc_ult_d() { } void genc_ole_d() { } void genc_ule_d() { } void genc_sf_d() { } void genc_ngle_d() { } void genc_seq_d() { } void genc_ngl_d() { } void genc_lt_d() { } void genc_nge_d() { } void genc_le_d() { } void genc_ngt_d() { } /* From gcop1_l.c */ void gencvt_s_l() { } void gencvt_d_l() { } /* From gcop1_s.c */ void genadd_s() { } void gensub_s() { } void genmul_s() { } void gendiv_s() { } void gensqrt_s() { } void genabs_s() { } void genmov_s() { } void genneg_s() { } void genround_l_s() { } void gentrunc_l_s() { } void genceil_l_s() { } void genfloor_l_s() { } void genround_w_s() { } void gentrunc_w_s() { } void genceil_w_s() { } void genfloor_w_s() { } void gencvt_d_s() { } void gencvt_w_s() { } void gencvt_l_s() { } void genc_f_s() { } void genc_un_s() { } void genc_eq_s() { } void genc_ueq_s() { } void genc_olt_s() { } void genc_ult_s() { } void genc_ole_s() { } void genc_ule_s() { } void genc_sf_s() { } void genc_ngle_s() { } void genc_seq_s() { } void genc_ngl_s() { } void genc_lt_s() { } void genc_nge_s() { } void genc_le_s() { } void genc_ngt_s() { } /* From gcop1_w.c */ void gencvt_s_w() { } void gencvt_d_w() { } /* From gr4300.c */ void gennotcompiled() { } void genlink_subblock() { } #ifdef COMPARE_CORE void gendebug() { } #endif void genni() { } void genreserved() { } void genfin_block() { } void gennop() { } void genj() { } void genj_out() { } void genj_idle() { } void genjal() { } void genjal_out() { } void genjal_idle() { } void genbne() { } void genbne_out() { } void genbne_idle() { } void genblez() { } void genblez_idle() { } void genbgtz() { } void genbgtz_out() { } void genbgtz_idle() { } void genaddi() { } void genaddiu() { } void genslti() { } void gensltiu() { } void genandi() { } void genori() { } void genxori() { } void genlui() { } void genbeql() { } void genbeql_out() { } void genbeql_idle() { } void genbeq() { } void genbeq_out() { } void genbeq_idle() { } void genbnel() { } void genbnel_out() { } void genbnel_idle() { } void genblezl() { } void genblezl_out() { } void genblezl_idle() { } void genbgtzl() { } void genbgtzl_out() { } void genbgtzl_idle() { } void gendaddi() { } void gendaddiu() { } void genldl() { } void genldr() { } void genlb() { } void genlh() { } void genlwl() { } void genlw() { } void genlbu() { } void genlhu() { } void genlwr() { } void genlwu() { } void gensb() { } void gensh() { } void genswl() { } void gensw() { } void gensdl() { } void gensdr() { } void genswr() { } void genlwc1() { } void genldc1() { } void gencache() { } void genld() { } void genswc1() { } void gensdc1() { } void gensd() { } void genll() { } void gensc() { } void genblez_out() { } /* From gregimm.c */ void genbltz() { } void genbltz_out() { } void genbltz_idle() { } void genbgez() { } void genbgez_out() { } void genbgez_idle() { } void genbltzl() { } void genbltzl_out() { } void genbltzl_idle() { } void genbgezl() { } void genbgezl_out() { } void genbgezl_idle() { } void genbltzal() { } void genbltzal_out() { } void genbltzal_idle() { } void genbgezal() { } void genbgezal_out() { } void genbgezal_idle() { } void genbltzall() { } void genbltzall_out() { } void genbltzall_idle() { } void genbgezall() { } void genbgezall_out() { } void genbgezall_idle() { } /* From gspecial.c */ void gensll() { } void gensrl() { } void gensra() { } void gensllv() { } void gensrlv() { } void gensrav() { } void genjr() { } void genjalr() { } void gensyscall() { } void gensync() { } void genmfhi() { } void genmthi() { } void genmflo() { } void genmtlo() { } void gendsllv() { } void gendsrlv() { } void gendsrav() { } void genmult() { } void genmultu() { } void gendiv() { } void gendivu() { } void gendmult() { } void gendmultu() { } void genddiv() { } void genddivu() { } void genadd() { } void genaddu() { } void gensub() { } void gensubu() { } void genand() { } void genor() { } void genxor() { } void gennor() { } void genslt() { } void gensltu() { } void gendadd() { } void gendaddu() { } void gendsub() { } void gendsubu() { } void genteq() { } void gendsll() { } void gendsrl() { } void gendsra() { } void gendsll32() { } void gendsrl32() { } void gendsra32() { } /* From gtlb.c */ void gentlbwi() { } void gentlbp() { } void gentlbr() { } void generet() { } void gentlbwr() { } /* From regcache.c */ void init_cache(precomp_instr* start) { } void free_all_registers() { } /* From rjump.c */ void dyna_jump() { } void dyna_stop() { } mupen64plus-core/src/r4300/interupt.h000664 001750 001750 00000005025 12655644434 020433 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - interupt.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_R4300_INTERRUPT_H #define M64P_R4300_INTERRUPT_H #include void init_interupt(void); /* set to avoid savestates/reset if state may be inconsistent * (e.g. in the middle of an instruction) */ extern int interupt_unsafe_state; void raise_maskable_interrupt(uint32_t cause); void gen_interupt(void); void check_interupt(void); void translate_event_queue(unsigned int base); void remove_event(int type); void add_interupt_event_count(int type, unsigned int count); void add_interupt_event(int type, unsigned int delay); unsigned int get_event(int type); int get_next_event_type(void); int save_eventqueue_infos(char *buf); void load_eventqueue_infos(char *buf); #define VI_INT 0x001 #define COMPARE_INT 0x002 #define CHECK_INT 0x004 #define SI_INT 0x008 #define PI_INT 0x010 #define SPECIAL_INT 0x020 #define AI_INT 0x040 #define SP_INT 0x080 #define DP_INT 0x100 #define HW2_INT 0x200 #define NMI_INT 0x400 #define CART_INT 0x800 #endif /* M64P_R4300_INTERRUPT_H */ mupen64plus-video-gliden64/src/windows/CommonAPIImpl_windows.cpp000664 001750 001750 00000002204 12655644434 026000 0ustar00sergiosergio000000 000000 #include #include "GLideN64_Windows.h" #include #include "../PluginAPI.h" #include "../OpenGL.h" #include "../RSP.h" #ifdef OS_WINDOWS EXTERN_C IMAGE_DOS_HEADER __ImageBase; #endif BOOL CALLBACK FindToolBarProc( HWND _hWnd, LPARAM lParam ) { if (GetWindowLong( _hWnd, GWL_STYLE ) & RBS_VARHEIGHT) { hToolBar = _hWnd; return FALSE; } return TRUE; } int PluginAPI::InitiateGFX(const GFX_INFO & _gfxInfo) { _initiateGFX(_gfxInfo); hWnd = _gfxInfo.hWnd; hStatusBar = _gfxInfo.hStatusBar; hToolBar = NULL; EnumChildWindows( hWnd, FindToolBarProc, 0 ); return TRUE; } void PluginAPI::FindPluginPath(wchar_t * _strPath) { if (_strPath == NULL) return; ::GetModuleFileName((HINSTANCE)&__ImageBase, _strPath, PLUGIN_PATH_SIZE); std::wstring pluginPath(_strPath); std::replace(pluginPath.begin(), pluginPath.end(), L'\\', L'/'); std::wstring::size_type pos = pluginPath.find_last_of(L"/"); wcscpy(_strPath, pluginPath.substr(0, pos).c_str()); } void PluginAPI::GetUserDataPath(wchar_t * _strPath) { FindPluginPath(_strPath); } void PluginAPI::GetUserCachePath(wchar_t * _strPath) { FindPluginPath(_strPath); } mupen64plus-video-gliden64/src/mupenplus/MupenPlusAPIImpl.cpp000664 001750 001750 00000005626 12655644434 025277 0ustar00sergiosergio000000 000000 #include "GLideN64_mupenplus.h" #include "../PluginAPI.h" #include "../GLideN64.h" #include "../OpenGL.h" ptr_ConfigGetSharedDataFilepath ConfigGetSharedDataFilepath = NULL; ptr_ConfigGetUserConfigPath ConfigGetUserConfigPath = NULL; ptr_ConfigGetUserDataPath ConfigGetUserDataPath = NULL; ptr_ConfigGetUserCachePath ConfigGetUserCachePath = NULL; ptr_ConfigOpenSection ConfigOpenSection = NULL; ptr_ConfigDeleteSection ConfigDeleteSection = NULL; ptr_ConfigSaveSection ConfigSaveSection = NULL; ptr_ConfigSaveFile ConfigSaveFile = NULL; ptr_ConfigSetDefaultInt ConfigSetDefaultInt = NULL; ptr_ConfigSetDefaultFloat ConfigSetDefaultFloat = NULL; ptr_ConfigSetDefaultBool ConfigSetDefaultBool = NULL; ptr_ConfigSetDefaultString ConfigSetDefaultString = NULL; ptr_ConfigGetParamInt ConfigGetParamInt = NULL; ptr_ConfigGetParamFloat ConfigGetParamFloat = NULL; ptr_ConfigGetParamBool ConfigGetParamBool = NULL; ptr_ConfigGetParamString ConfigGetParamString = NULL; /* definitions of pointers to Core video extension functions */ ptr_VidExt_Init CoreVideo_Init = NULL; ptr_VidExt_Quit CoreVideo_Quit = NULL; ptr_VidExt_ListFullscreenModes CoreVideo_ListFullscreenModes = NULL; ptr_VidExt_SetVideoMode CoreVideo_SetVideoMode = NULL; ptr_VidExt_SetCaption CoreVideo_SetCaption = NULL; ptr_VidExt_ToggleFullScreen CoreVideo_ToggleFullScreen = NULL; ptr_VidExt_ResizeWindow CoreVideo_ResizeWindow = NULL; ptr_VidExt_GL_GetProcAddress CoreVideo_GL_GetProcAddress = NULL; ptr_VidExt_GL_SetAttribute CoreVideo_GL_SetAttribute = NULL; ptr_VidExt_GL_GetAttribute CoreVideo_GL_GetAttribute = NULL; ptr_VidExt_GL_SwapBuffers CoreVideo_GL_SwapBuffers = NULL; void(*renderCallback)(int) = NULL; m64p_error PluginAPI::PluginStartup(m64p_dynlib_handle _CoreLibHandle) { return M64ERR_SUCCESS; } m64p_error PluginAPI::PluginShutdown() { #ifdef RSPTHREAD _callAPICommand(acRomClosed); delete m_pRspThread; m_pRspThread = NULL; #else video().stop(); #endif return M64ERR_SUCCESS; } m64p_error PluginAPI::PluginGetVersion( m64p_plugin_type * _PluginType, int * _PluginVersion, int * _APIVersion, const char ** _PluginNamePtr, int * _Capabilities ) { /* set version info */ if (_PluginType != NULL) *_PluginType = M64PLUGIN_GFX; if (_PluginVersion != NULL) *_PluginVersion = PLUGIN_VERSION; if (_APIVersion != NULL) *_APIVersion = VIDEO_PLUGIN_API_VERSION; if (_PluginNamePtr != NULL) *_PluginNamePtr = pluginName; if (_Capabilities != NULL) { *_Capabilities = 0; } return M64ERR_SUCCESS; } void PluginAPI::SetRenderingCallback(void (*callback)(int)) { renderCallback = callback; } void PluginAPI::ResizeVideoOutput(int _Width, int _Height) { video().setWindowSize(_Width, _Height); } void PluginAPI::ReadScreen2(void * _dest, int * _width, int * _height, int _front) { video().readScreen2(_dest, _width, _height, _front); } gles2n64/src/gDP.h000664 001750 001750 00000016643 12655644434 014707 0ustar00sergiosergio000000 000000 #ifndef GDP_H #define GDP_H #include "Types.h" #ifdef __cplusplus extern "C" { #endif #define CHANGED_RENDERMODE 0x0001 #define CHANGED_CYCLETYPE 0x0002 #define CHANGED_SCISSOR 0x0004 #define CHANGED_TMEM 0x0008 #define CHANGED_TILE 0x0010 #define CHANGED_COMBINE 0x0040 #define CHANGED_FB_TEXTURE 0x0200 #define TEXTUREMODE_NORMAL 0 #define TEXTUREMODE_TEXRECT 1 #define TEXTUREMODE_BGIMAGE 2 #define TEXTUREMODE_FRAMEBUFFER 3 /* New GLiden64 define */ #define TEXTUREMODE_FRAMEBUFFER_BG 4 #define LOADTYPE_BLOCK 0 #define LOADTYPE_TILE 1 typedef struct { union { struct { // muxs1 unsigned aA1 : 3; unsigned sbA1 : 3; unsigned aRGB1 : 3; unsigned aA0 : 3; unsigned sbA0 : 3; unsigned aRGB0 : 3; unsigned mA1 : 3; unsigned saA1 : 3; unsigned sbRGB1 : 4; unsigned sbRGB0 : 4; // muxs0 unsigned mRGB1 : 5; unsigned saRGB1 : 4; unsigned mA0 : 3; unsigned saA0 : 3; unsigned mRGB0 : 5; unsigned saRGB0 : 4; }; struct { u32 muxs1, muxs0; }; u64 mux; }; } gDPCombine; struct FrameBuffer; typedef struct { u32 format, size, line, tmem, palette; union { struct { unsigned mirrort : 1; unsigned clampt : 1; unsigned pad0 : 30; unsigned mirrors : 1; unsigned clamps : 1; unsigned pad1 : 30; }; struct { u32 cmt, cms; }; }; u32 maskt, masks; u32 shiftt, shifts; f32 fuls, fult, flrs, flrt; u32 uls, ult, lrs, lrt; u32 textureMode; u32 loadType; u32 imageAddress; struct FrameBuffer *frameBuffer; } gDPTile; struct gDPLoadTileInfo { u8 size; u8 loadType; u16 uls; u16 ult; u16 width; u16 height; u16 texWidth; u32 texAddress; u32 dxt; }; typedef struct { struct { union { struct { unsigned int alphaCompare : 2; unsigned int depthSource : 1; // struct // { unsigned int AAEnable : 1; unsigned int depthCompare : 1; unsigned int depthUpdate : 1; unsigned int imageRead : 1; unsigned int clearOnCvg : 1; unsigned int cvgDest : 2; unsigned int depthMode : 2; unsigned int cvgXAlpha : 1; unsigned int alphaCvgSel : 1; unsigned int forceBlender : 1; unsigned int textureEdge : 1; // } renderMode; //struct //{ unsigned int c2_m2b : 2; unsigned int c1_m2b : 2; unsigned int c2_m2a : 2; unsigned int c1_m2a : 2; unsigned int c2_m1b : 2; unsigned int c1_m1b : 2; unsigned int c2_m1a : 2; unsigned int c1_m1a : 2; //} blender; unsigned int blendMask : 4; unsigned int alphaDither : 2; unsigned int colorDither : 2; unsigned int combineKey : 1; unsigned int textureConvert : 3; unsigned int textureFilter : 2; unsigned int textureLUT : 2; unsigned int textureLOD : 1; unsigned int textureDetail : 2; unsigned int texturePersp : 1; unsigned int cycleType : 2; unsigned int unusedColorDither : 1; // unsupported unsigned int pipelineMode : 1; unsigned int pad : 8; }; u64 _u64; struct { u32 l, h; }; }; } otherMode; gDPCombine combine; gDPTile tiles[8], *loadTile; struct Color { f32 r, g, b, a; } fogColor, blendColor, envColor; struct { f32 z, dz; u32 color; } fillColor; struct { u32 m; f32 l, r, g, b, a; } primColor; struct { f32 z, deltaZ; } primDepth; struct { u32 format, size, width, bpl; u32 address; } textureImage; struct { u32 format, size, width, height, bpl; u32 address, changed; u32 depthImage; } colorImage; u32 depthImageAddress; struct { u32 mode; f32 ulx, uly, lrx, lry; } scissor; struct { f32 k0, k1, k2, k3, k4, k5; } convert; struct { struct { f32 r, g, b, a; } center, scale, width; } key; struct { u32 width, height; } texRect; u32 changed; u16 TexFilterPalette[512]; u32 paletteCRC16[16]; u32 paletteCRC256; u32 half_1, half_2; struct gDPLoadTileInfo loadInfo[512]; } gDPInfo; extern gDPInfo gDP; void gDPSetOtherMode( u32 mode0, u32 mode1 ); void gDPSetPrimDepth( u16 z, u16 dz ); void gDPPipelineMode( u32 mode ); void gDPSetCycleType( u32 type ); void gDPSetTexturePersp( u32 enable ); void gDPSetTextureLUT( u32 mode ); void gDPSetCombineKey( u32 type ); void gDPSetAlphaCompare( u32 mode ); void gDPSetCombine( s32 muxs0, s32 muxs1 ); void gDPSetColorImage( u32 format, u32 size, u32 width, u32 address ); void gDPSetTextureImage( u32 format, u32 size, u32 width, u32 address ); void gDPSetDepthImage( u32 address ); void gDPSetEnvColor( u32 r, u32 g, u32 b, u32 a ); void gDPSetBlendColor( u32 r, u32 g, u32 b, u32 a ); void gDPSetFogColor( u32 r, u32 g, u32 b, u32 a ); void gDPSetFillColor( u32 c ); void gDPSetPrimColor( u32 m, u32 l, u32 r, u32 g, u32 b, u32 a ); void gDPSetTile( u32 format, u32 size, u32 line, u32 tmem, u32 tile, u32 palette, u32 cmt, u32 cms, u32 maskt, u32 masks, u32 shiftt, u32 shifts ); void gDPSetTileSize( u32 tile, u32 uls, u32 ult, u32 lrs, u32 lrt ); void gDPLoadTile( u32 tile, u32 uls, u32 ult, u32 lrs, u32 lrt ); void gDPLoadBlock( u32 tile, u32 uls, u32 ult, u32 lrs, u32 dxt ); void gDPLoadTLUT( u32 tile, u32 uls, u32 ult, u32 lrs, u32 lrt ); void gDPSetScissor( u32 mode, f32 ulx, f32 uly, f32 lrx, f32 lry ); void gDPFillRectangle( s32 ulx, s32 uly, s32 lrx, s32 lry ); void gDPSetConvert( s32 k0, s32 k1, s32 k2, s32 k3, s32 k4, s32 k5 ); void gDPSetKeyR( u32 cR, u32 sR, u32 wR ); void gDPSetKeyGB(u32 cG, u32 sG, u32 wG, u32 cB, u32 sB, u32 wB ); void gDPTextureRectangle( f32 ulx, f32 uly, f32 lrx, f32 lry, s32 tile, f32 s, f32 t, f32 dsdx, f32 dtdy ); void gDPTextureRectangleFlip( f32 ulx, f32 uly, f32 lrx, f32 lry, s32 tile, f32 s, f32 t, f32 dsdx, f32 dtdy ); void gDPFullSync(void); void gDPTileSync(void); void gDPPipeSync(void); void gDPLoadSync(void); void gDPNoOp(void); void gDPTriFill(u32 w0, u32 w1); void gDPTriFillZ(u32 w0, u32 w1); void gDPTriShadeZ(u32 w0, u32 w1); void gDPTriTxtrZ(u32 w0, u32 w1); void gDPTriTxtr(u32 w0, u32 w1); void gDPTriShadeTxtrZ(u32 w0, u32 w1); void gDPTriShadeTxtr(u32 w0, u32 w1); #ifdef __cplusplus } #endif #endif glide2gl/src/Glide64/TexLoad.c000664 001750 001750 00000073122 12655644434 017106 0ustar00sergiosergio000000 000000 #include "TexLoad.h" #include "Gfx_1.3.h" #include "Combine.h" #include "Util.h" #define ALOWORD(x) (*((uint16_t*)&x)) // low word static INLINE void load4bCI(uint8_t *src, uint8_t *dst, int wid_64, int height, uint16_t line, int ext, uint16_t *pal) { uint32_t *src32 =(uint32_t*)src; uint32_t *dst32 =(uint32_t*)dst; unsigned odd = 0; while (height--) { int width = wid_64; while (width--) { uint32_t v12 = m64p_swap32(src32[odd]); uint32_t v16 = m64p_swap32(src32[!odd]); uint32_t pix = width + 1; ALOWORD(pix) = ror16(*(uint16_t*)((uint8_t*)pal + ((v12 >> 23) & 0x1E)), 1); pix = pix << 16; ALOWORD(pix) = ror16(*(uint16_t*)((uint8_t*)pal + ((v12 >> 27) & 0x1E)), 1); *dst32++ = pix; ALOWORD(pix) = ror16(*(uint16_t*)((uint8_t*)pal + ((v12 >> 15) & 0x1E)), 1); pix <<= 16; ALOWORD(pix) = ror16(*(uint16_t*)((uint8_t*)pal + ((v12 >> 19) & 0x1E)), 1); *dst32++ = pix; ALOWORD(pix) = ror16(*(uint16_t*)((uint8_t*)pal + ((v12 >> 7) & 0x1E)), 1); pix <<= 16; ALOWORD(pix) = ror16(*(uint16_t*)((uint8_t*)pal + ((v12 >> 11) & 0x1E)), 1); *dst32++ = pix; ALOWORD(pix) = ror16(*(uint16_t*)((uint8_t*)pal + (2 *(uint8_t)v12 & 0x1E)), 1); pix <<= 16; ALOWORD(pix) = ror16(*(uint16_t*)((uint8_t*)pal + ((v12 >> 3) & 0x1E)), 1); *dst32++ = pix; ALOWORD(pix) = ror16(*(uint16_t*)((uint8_t*)pal + ((v16 >> 23) & 0x1E)), 1); pix <<= 16; ALOWORD(pix) = ror16(*(uint16_t*)((uint8_t*)pal + ((v16 >> 27) & 0x1E)), 1); *dst32++ = pix; ALOWORD(pix) = ror16(*(uint16_t*)((uint8_t*)pal + ((v16 >> 15) & 0x1E)), 1); pix <<= 16; ALOWORD(pix) = ror16(*(uint16_t*)((uint8_t*)pal + ((v16 >> 19) & 0x1E)), 1); *dst32++ = pix; ALOWORD(pix) = ror16(*(uint16_t*)((uint8_t*)pal + ((v16 >> 7) & 0x1E)), 1); pix <<= 16; ALOWORD(pix) = ror16(*(uint16_t*)((uint8_t*)pal + ((v16 >> 11) & 0x1E)), 1); *dst32++ = pix; ALOWORD(pix) = ror16(*(uint16_t*)((uint8_t*)pal + (2 *(uint8_t)v16 & 0x1E)), 1); pix <<= 16; ALOWORD(pix) = ror16(*(uint16_t*)((uint8_t*)pal + ((v16 >> 3) & 0x1E)), 1); *dst32++ = pix; src32 += 2; } src32 =(uint32_t*)&src[(line +(uintptr_t)src32 -(uintptr_t)src) & 0x7FF]; dst32 =(uint32_t*)((uint8_t*)dst32 + ext); odd ^= 1; } } static INLINE void load4bIAPal(uint8_t *src, uint8_t *dst, int wid_64, int height, int line, int ext, uint16_t *pal) { uint32_t *src32 =(uint32_t*)src; uint32_t *dst32 =(uint32_t*)dst; unsigned odd = 0; while (height--) { int width = wid_64; while (width--) { uint32_t ab = m64p_swap32(src32[odd]); uint32_t cd = m64p_swap32(src32[!odd]); uint32_t pix = width + 1; ALOWORD(pix) = ror16(*(uint16_t *)((char *)pal + ((ab >> 23) & 0x1E)), 8); pix = pix << 16; ALOWORD(pix) = ror16(*(uint16_t *)((char *)pal + ((ab >> 27) & 0x1E)), 8); *dst32++ = pix; ALOWORD(pix) = ror16(*(uint16_t *)((char *)pal + ((ab >> 15) & 0x1E)), 8); pix <<= 16; ALOWORD(pix) = ror16(*(uint16_t *)((char *)pal + ((ab >> 19) & 0x1E)), 8); *dst32++ = pix; ALOWORD(pix) = ror16(*(uint16_t *)((char *)pal + ((ab >> 7) & 0x1E)), 8); pix <<= 16; ALOWORD(pix) = ror16(*(uint16_t *)((char *)pal + ((ab >> 11) & 0x1E)), 8); *dst32++ = pix; ALOWORD(pix) = ror16(*(uint16_t *)((char *)pal + (2 *(uint8_t)ab & 0x1E)), 8); pix <<= 16; ALOWORD(pix) = ror16(*(uint16_t *)((char *)pal + ((ab >> 3) & 0x1E)), 8); *dst32++ = pix; ALOWORD(pix) = ror16(*(uint16_t *)((char *)pal + ((cd >> 23) & 0x1E)), 8); pix <<= 16; ALOWORD(pix) = ror16(*(uint16_t *)((char *)pal + ((cd >> 27) & 0x1E)), 8); *dst32++ = pix; ALOWORD(pix) = ror16(*(uint16_t *)((char *)pal + ((cd >> 15) & 0x1E)), 8); pix <<= 16; ALOWORD(pix) = ror16(*(uint16_t *)((char *)pal + ((cd >> 19) & 0x1E)), 8); *dst32++ = pix; ALOWORD(pix) = ror16(*(uint16_t *)((char *)pal + ((cd >> 7) & 0x1E)), 8); pix <<= 16; ALOWORD(pix) = ror16(*(uint16_t *)((char *)pal + ((cd >> 11) & 0x1E)), 8); *dst32++ = pix; ALOWORD(pix) = ror16(*(uint16_t *)((char *)pal + (2 *(uint8_t)cd & 0x1E)), 8); pix <<= 16; ALOWORD(pix) = ror16(*(uint16_t *)((char *)pal + ((cd >> 3) & 0x1E)), 8); *dst32++ = pix; src32 += 2; } src32 =(uint32_t*)&src[(line +(uintptr_t)src32 -(uintptr_t)src) & 0x7FF]; dst32 =(uint32_t*)((uint8_t*)dst32 + ext); odd ^= 1; } } static INLINE void load4bIA(uint8_t *src, uint8_t *dst, int wid_64, int height, int line, int ext) { unsigned odd = 0; uint32_t *src32 = (uint32_t*)src; uint32_t *dst32 = (uint32_t*)dst; while (height--) { int count = wid_64; while (count--) { uint32_t v1, v2, v3, v4, v5, v6, v7, v8, v9, v10; #define do_load4biA \ v2 = v1;\ v3 = (8 * (v1 & 0x100000)) | (4 * (v1 & 0x100000)) | (2 * (v1 & 0x100000)) | (v1 & 0x100000) | ((((v1 >> 16) & 0xE00) >> 3) & 0x100) | ((v1 >> 16) & 0xE00) | (8 * ((v1 >> 12) & 0x1000)) | (4 * ((v1 >> 12) & 0x1000)) | (2 * ((v1 >> 12) & 0x1000)) | ((v1 >> 12) & 0x1000) | ((((v1 >> 28) & 0xE) >> 3)) | ((v1 >> 28) & 0xE) | (8 * ((v1 >> 24) & 0x10)) | (4 * ((v1 >> 24) & 0x10)) | (2 * ((v1 >> 24) & 0x10)) | ((v1 >> 24) & 0x10);\ v1 = (v1 >> 4) & 0xE0000u;\ v4 = v1 | v3;\ v1 >>= 3;\ *dst32++ = ((((v2 << 8) & 0xE000000) >> 3) & 0x1000000) | ((v2 << 8) & 0xE000000) | (8 * ((v2 << 12) & 0x10000000)) | (4 * ((v2 << 12) & 0x10000000)) | (2 * ((v2 << 12) & 0x10000000)) | ((v2 << 12) & 0x10000000) | (v1 & 0x10000) | v4;\ \ v5 = 16 * (uint16_t)v2 & 0x1000;\ v6 = (((v2 & 0xE00) >> 3) & 0x100) | (v2 & 0xE00) | (8 * v5) | (4 * v5) | (2 * v5) | (v5) | ((((v2 >> 12) & 0xE) >> 3)) | ((v2 >> 12) & 0xE) | (8 * ((v2 >> 8) & 0x10)) | (4 * ((v2 >> 8) & 0x10)) | (2 * ((v2 >> 8) & 0x10)) | ((v2 >> 8) & 0x10);\ v7 = v2 << 16;\ v8 = (8 * (v7 & 0x100000)) | (4 * (v7 & 0x100000)) | (2 * (v7 & 0x100000)) | (v7 & 0x100000) | v6;\ v9 = (v2 << 12) & 0xE0000u;\ v10 = v9 | v8;\ v9 >>= 3;\ *dst32++ = ((((v2 << 24) & 0xE000000) >> 3) & 0x1000000) | ((v2 << 24) & 0xE000000) | (8 * ((v2 << 28) & 0x10000000)) | (4 * ((v2 << 28) & 0x10000000)) | (2 * ((v2 << 28) & 0x10000000)) | ((v2 << 28) & 0x10000000) | (v9 & 0x10000) | v10 v1 = m64p_swap32(src32[odd]); do_load4biA; v1 = m64p_swap32(src32[!odd]); do_load4biA; #undef do_load4biA src32 += 2; } src32 = (uint32_t*)((char*)src32 + line); dst32 = (uint32_t*)((char*)dst32 + ext); odd ^= 1; } } static INLINE void load4bI(uint8_t *src, uint8_t *dst, int wid_64, int height, int line, int ext) { uint32_t *src32 =(uint32_t*)src; uint32_t *dst32 =(uint32_t*)dst; unsigned odd = 0; while (height--) { int width = wid_64; while (width--) { uint32_t ab = m64p_swap32(src32[odd]); uint32_t cd = m64p_swap32(src32[!odd]); uint32_t pix; pix = ab >> 4; *dst32++ = (16 * ((ab << 8) & 0xF000000)) | ((ab << 8) & 0xF000000) | (16 * (pix & 0xF0000)) | (pix & 0xF0000) | (16 * ((ab >> 16) & 0xF00)) | ((ab >> 16) & 0xF00) | (16 * (ab >> 28)) | (ab >> 28); pix = ab << 12; *dst32++ = (16 * ((ab << 24) & 0xF000000)) | ((ab << 24) & 0xF000000) | (16 * (pix & 0xF0000)) | (pix & 0xF0000) | (16 * (ab & 0xF00)) | (ab & 0xF00) | (16 * ((uint16_t)ab >> 12)) | ((uint16_t)ab >> 12); pix = cd >> 4; *dst32++ = (16 * ((cd << 8) & 0xF000000)) | ((cd << 8) & 0xF000000) | (16 * (pix & 0xF0000)) | (pix & 0xF0000) | (16 * ((cd >> 16) & 0xF00)) | ((cd >> 16) & 0xF00) | (16 * (cd >> 28)) | (cd >> 28); pix = cd << 12; *dst32++ = (16 * ((cd << 24) & 0xF000000)) | ((cd << 24) & 0xF000000) | (16 * (pix & 0xF0000)) | (pix & 0xF0000) | (16 * (cd & 0xF00)) | (cd & 0xF00) | (16 * ((uint16_t)cd >> 12)) | ((uint16_t)cd >> 12); src32 += 2; } src32 =(uint32_t*)((uint8_t*)src32 + line); dst32 =(uint32_t*)((uint8_t*)dst32 + ext); odd ^= 1; } } static INLINE void load8bCI(uint8_t *src, uint8_t *dst, int wid_64, int height, int line, int ext, uint16_t *pal) { uint32_t *src32 =(uint32_t*)src; uint32_t *dst32 =(uint32_t *)dst; unsigned odd = 0; while (height--) { int width = wid_64; while (width--) { uint32_t abcd = m64p_swap32(src32[odd]); uint32_t efgh = m64p_swap32(src32[!odd]); uint32_t pix = width + 1; ALOWORD(pix) = ror16(*(uint16_t*)((uint8_t*)pal + ((abcd >> 15) & 0x1FE)), 1); pix = pix << 16; ALOWORD(pix) = ror16(*(uint16_t*)((uint8_t*)pal + ((abcd >> 23) & 0x1FE)), 1); *dst32++ = pix; ALOWORD(pix) = ror16(*(uint16_t*)((uint8_t*)pal + (2 *(uint16_t)abcd & 0x1FE)), 1); pix <<= 16; ALOWORD(pix) = ror16(*(uint16_t*)((uint8_t*)pal + ((abcd >> 7) & 0x1FE)), 1); *dst32++ = pix; ALOWORD(pix) = ror16(*(uint16_t*)((uint8_t*)pal + ((efgh >> 15) & 0x1FE)), 1); pix <<= 16; ALOWORD(pix) = ror16(*(uint16_t*)((uint8_t*)pal + ((efgh >> 23) & 0x1FE)), 1); *dst32++ = pix; ALOWORD(pix) = ror16(*(uint16_t*)((uint8_t*)pal + (2 *(uint16_t)efgh & 0x1FE)), 1); pix <<= 16; ALOWORD(pix) = ror16(*(uint16_t*)((uint8_t*)pal + ((efgh >> 7) & 0x1FE)), 1); *dst32++ = pix; src32 += 2; } src32 =(uint32_t*)&src[(line +(uintptr_t)src32 -(uintptr_t)src) & 0x7FF]; dst32 =(uint32_t*)((char *)dst32 + ext); odd ^= 1; } } static INLINE void load8bIA8(uint8_t *src, uint8_t *dst, int wid_64, int height, int line, int ext, uint16_t *pal) { uint32_t *src32 =(uint32_t *)src; uint32_t *dst32 =(uint32_t *)dst; unsigned odd = 0; while (height--) { int width = wid_64; while (width--) { uint32_t abcd = m64p_swap32(src32[odd]); uint32_t efgh = m64p_swap32(src32[!odd]); uint32_t pix = width + 1; ALOWORD(pix) = ror16(*(uint16_t *)((uint8_t*)pal + ((abcd >> 15) & 0x1FE)), 8); pix = pix << 16; ALOWORD(pix) = ror16(*(uint16_t *)((uint8_t*)pal + ((abcd >> 23) & 0x1FE)), 8); *dst32++ = pix; ALOWORD(pix) = ror16(*(uint16_t *)((uint8_t*)pal + (2 *(uint16_t)abcd & 0x1FE)), 8); pix <<= 16; ALOWORD(pix) = ror16(*(uint16_t *)((uint8_t*)pal + ((abcd >> 7) & 0x1FE)), 8); *dst32++ = pix; ALOWORD(pix) = ror16(*(uint16_t *)((uint8_t*)pal + ((efgh >> 15) & 0x1FE)), 8); pix <<= 16; ALOWORD(pix) = ror16(*(uint16_t *)((uint8_t*)pal + ((efgh >> 23) & 0x1FE)), 8); *dst32++ = pix; ALOWORD(pix) = ror16(*(uint16_t *)((uint8_t*)pal + (2 *(uint16_t)efgh & 0x1FE)), 8); pix <<= 16; ALOWORD(pix) = ror16(*(uint16_t *)((uint8_t*)pal + ((efgh >> 7) & 0x1FE)), 8); *dst32++ = pix; src32 += 2; } src32 =(uint32_t *)((uint8_t*)src32 + line); dst32 =(uint32_t *)((uint8_t*)dst32 + ext); odd ^= 1; } } static INLINE void load8bIA4(uint8_t *src, uint8_t *dst, int wid_64, int height, int line, int ext) { uint32_t *src32 =(uint32_t *)src; uint32_t *dst32 =(uint32_t *)dst; unsigned odd = 0; while (height--) { int width = wid_64; while(width--) { uint32_t ab = src32[odd]; uint32_t cd = src32[!odd]; *dst32++ = (16 * ab & 0xF0F0F0F0) | ((ab >> 4) & 0xF0F0F0F); *dst32++ = (16 * cd & 0xF0F0F0F0) | ((cd >> 4) & 0xF0F0F0F); src32 += 2; } src32 =(uint32_t *)((uint8_t*)src32 + line); dst32 =(uint32_t *)((uint8_t*)dst32 + ext); odd ^= 1; } } static INLINE void load8bI(uint8_t *src, uint8_t *dst, int wid_64, int height, int line, int ext) { uint32_t *src32 =(uint32_t *)src; uint32_t *dst32 =(uint32_t *)dst; unsigned odd = 0; while (height--) { int width = wid_64; while (width--) { *dst32++ = src32[odd]; *dst32++ = src32[!odd]; src32 += 2; } src32 =(uint32_t *)((uint8_t*)src32 + line); dst32 =(uint32_t *)((uint8_t*)dst32 + ext); odd ^= 1; } } static INLINE void load16bRGBA(uint8_t *src, uint8_t *dst, int wid_64, int height, int line, int ext) { uint32_t *src32 =(uint32_t*)src; uint32_t *dst32 =(uint32_t*)dst; unsigned odd = 0; while (height--) { int width = wid_64; while (width--) { uint32_t ab = m64p_swap32(src32[odd]); uint32_t cd = m64p_swap32(src32[!odd]); ALOWORD(ab) = ror16((uint16_t)ab, 1); ALOWORD(cd) = ror16((uint16_t)cd, 1); ab = ror32(ab, 16); cd = ror32(cd, 16); ALOWORD(ab) = ror16((uint16_t)ab, 1); ALOWORD(cd) = ror16((uint16_t)cd, 1); *dst32++ = ab; *dst32++ = cd; src32 += 2; } src32 =(uint32_t*)&src[(line +(uintptr_t)src32 -(uintptr_t)src) & 0xFFF]; dst32 =(uint32_t*)((uint8_t*)dst32 + ext); odd ^= 1; } } static INLINE void load16bIA(uint8_t *src, uint8_t *dst, int wid_64, int height, int line, int ext) { uint32_t *src32 =(uint32_t *)src; uint32_t *dst32 =(uint32_t *)dst; unsigned odd = 0; while (height--) { int width = wid_64; while (width--) { *dst32++ = src32[odd]; *dst32++ = src32[!odd]; src32 += 2; } src32 =(uint32_t*)((uint8_t*)src32 + line); dst32 =(uint32_t*)((uint8_t*)dst32 + ext); odd ^= 1; } } static uint32_t LoadNone(uintptr_t dst, uintptr_t src, int wid_64, int height, int line, int real_width, int tile) { (void)dst; (void)src; (void)wid_64; (void)height; (void)line; (void)real_width; (void)tile; return GR_TEXFMT_ARGB_1555; } //**************************************************************** // Size: 0, Format: 2 static uint32_t Load4bCI(uintptr_t dst, uintptr_t src, int wid_64, int height, int line, int real_width, int tile) { int ext; uintptr_t pal; if (wid_64 < 1) wid_64 = 1; if (height < 1) height = 1; ext = (real_width - (wid_64 << 4)); if (rdp.tlut_mode == 0) { //in tlut DISABLE mode load CI texture as plain intensity texture instead of palette dereference. //Thanks to angrylion for the advice load4bI ((uint8_t *)src,(uint8_t *)dst, wid_64, height, line, ext); return /*(0 << 16) | */GR_TEXFMT_ALPHA_INTENSITY_44; } pal =(uintptr_t)(rdp.pal_8 + (g_gdp.tile[tile].palette << 4)); if (rdp.tlut_mode == 2) { ext <<= 1; load4bCI ((uint8_t *)src,(uint8_t *)dst, wid_64, height, line, ext,(uint16_t *)pal); return (1 << 16) | GR_TEXFMT_ARGB_1555; } ext <<= 1; load4bIAPal ((uint8_t *)src,(uint8_t *)dst, wid_64, height, line, ext,(uint16_t *)pal); return (1 << 16) | GR_TEXFMT_ALPHA_INTENSITY_88; } //**************************************************************** // Size: 0, Format: 3 // // ** BY GUGAMAN ** static uint32_t Load4bIA(uintptr_t dst, uintptr_t src, int wid_64, int height, int line, int real_width, int tile) { int ext; if (rdp.tlut_mode != 0) return Load4bCI (dst, src, wid_64, height, line, real_width, tile); if (wid_64 < 1) wid_64 = 1; if (height < 1) height = 1; ext = (real_width - (wid_64 << 4)); load4bIA ((uint8_t *)src,(uint8_t *)dst, wid_64, height, line, ext); return /*(0 << 16) | */GR_TEXFMT_ALPHA_INTENSITY_44; } //**************************************************************** // Size: 0, Format: 4 static uint32_t Load4bI(uintptr_t dst, uintptr_t src, int wid_64, int height, int line, int real_width, int tile) { int ext; if (rdp.tlut_mode != 0) return Load4bCI (dst, src, wid_64, height, line, real_width, tile); if (wid_64 < 1) wid_64 = 1; if (height < 1) height = 1; ext = (real_width - (wid_64 << 4)); load4bI ((uint8_t *)src,(uint8_t *)dst, wid_64, height, line, ext); return /*(0 << 16) | */GR_TEXFMT_ALPHA_INTENSITY_44; } //**************************************************************** // Size: 0, Format: 0 static uint32_t Load4bSelect(uintptr_t dst, uintptr_t src, int wid_64, int height, int line, int real_width, int tile) { if (rdp.tlut_mode == 0) return Load4bI (dst, src, wid_64, height, line, real_width, tile); return Load4bCI (dst, src, wid_64, height, line, real_width, tile); } //**************************************************************** // Size: 1, Format: 2 // static uint32_t Load8bCI(uintptr_t dst, uintptr_t src, int wid_64, int height, int line, int real_width, int tile) { int ext; unsigned short *pal; if (wid_64 < 1) wid_64 = 1; if (height < 1) height = 1; ext = (real_width - (wid_64 << 3)); pal = (unsigned short*)rdp.pal_8; switch (rdp.tlut_mode) { case 0: //palette is not used //in tlut DISABLE mode load CI texture as plain intensity texture instead of palette dereference. //Thanks to angrylion for the advice load8bI ((uint8_t *)src,(uint8_t *)dst, wid_64, height, line, ext); return /*(0 << 16) | */GR_TEXFMT_ALPHA_8; case 2: //color palette ext <<= 1; load8bCI ((uint8_t *)src,(uint8_t *)dst, wid_64, height, line, ext, pal); return (1 << 16) | GR_TEXFMT_ARGB_1555; default: //IA palette ext <<= 1; load8bIA8 ((uint8_t *)src,(uint8_t *)dst, wid_64, height, line, ext, pal); return (1 << 16) | GR_TEXFMT_ALPHA_INTENSITY_88; } } //**************************************************************** // Size: 1, Format: 3 // // ** by Gugaman ** static uint32_t Load8bIA(uintptr_t dst, uintptr_t src, int wid_64, int height, int line, int real_width, int tile) { int ext; if (rdp.tlut_mode != 0) return Load8bCI (dst, src, wid_64, height, line, real_width, tile); if (wid_64 < 1) wid_64 = 1; if (height < 1) height = 1; ext = (real_width - (wid_64 << 3)); load8bIA4 ((uint8_t *)src,(uint8_t *)dst, wid_64, height, line, ext); return /*(0 << 16) | */GR_TEXFMT_ALPHA_INTENSITY_44; } //**************************************************************** // Size: 1, Format: 4 // // ** by Gugaman ** static uint32_t Load8bI(uintptr_t dst, uintptr_t src, int wid_64, int height, int line, int real_width, int tile) { int ext; if (rdp.tlut_mode != 0) return Load8bCI (dst, src, wid_64, height, line, real_width, tile); if (wid_64 < 1) wid_64 = 1; if (height < 1) height = 1; ext = (real_width - (wid_64 << 3)); load8bI ((uint8_t *)src,(uint8_t *)dst, wid_64, height, line, ext); return /*(0 << 16) | */GR_TEXFMT_ALPHA_8; } //**************************************************************** // Size: 2, Format: 0 // static uint32_t Load16bRGBA(uintptr_t dst, uintptr_t src, int wid_64, int height, int line, int real_width, int tile) { int ext; if (wid_64 < 1) wid_64 = 1; if (height < 1) height = 1; ext = (real_width - (wid_64 << 2)) << 1; load16bRGBA((uint8_t *)src,(uint8_t *)dst, wid_64, height, line, ext); return (1 << 16) | GR_TEXFMT_ARGB_1555; } //**************************************************************** // Size: 2, Format: 3 // // ** by Gugaman/Dave2001 ** static uint32_t Load16bIA(uintptr_t dst, uintptr_t src, int wid_64, int height, int line, int real_width, int tile) { int ext; if (wid_64 < 1) wid_64 = 1; if (height < 1) height = 1; ext = (real_width - (wid_64 << 2)) << 1; load16bIA((uint8_t *)src,(uint8_t *)dst, wid_64, height, line, ext); return (1 << 16) | GR_TEXFMT_ALPHA_INTENSITY_88; } //**************************************************************** // Size: 2, Format: 1 // static uint16_t yuv_to_rgb565(uint8_t y, uint8_t u, uint8_t v) { float r = y + (1.370705f * (v-128)); float g = y - (0.698001f * (v-128)) - (0.337633f * (u-128)); float b = y + (1.732446f * (u-128)); r *= 0.125f; g *= 0.25f; b *= 0.125f; //clipping the result if (r > 31) r = 31; if (g > 63) g = 63; if (b > 31) b = 31; if (r < 0) r = 0; if (g < 0) g = 0; if (b < 0) b = 0; return(uint16_t)(((uint16_t)(r) << 11) | ((uint16_t)(g) << 5) | (uint16_t)(b) ); //*/ /* const uint32_t c = y - 16; const uint32_t d = u - 128; const uint32_t e = v - 128; uint32_t r = (298 * c + 409 * e + 128) & 0xf800; uint32_t g = ((298 * c - 100 * d - 208 * e + 128) >> 5) & 0x7e0; uint32_t b = ((298 * c + 516 * d + 128) >> 11) & 0x1f; WORD texel = (WORD)(r | g | b); return texel; */ } //**************************************************************** // Size: 2, Format: 1 // static uint32_t Load16bYUV(uintptr_t dst, uintptr_t src, int wid_64, int height, int line, int real_width, int tile) { uint16_t i; uint32_t *mb =(uint32_t*)(gfx_info.RDRAM+rdp.addr[g_gdp.tile[tile].tmem]); //pointer to the macro block uint16_t *tex =(uint16_t*)dst; for (i = 0; i < 128; i++) { uint32_t t = mb[i]; //each uint32_t contains 2 pixels uint8_t y1 =(uint8_t)t&0xFF; uint8_t v =(uint8_t)(t>>8)&0xFF; uint8_t y0 =(uint8_t)(t>>16)&0xFF; uint8_t u =(uint8_t)(t>>24)&0xFF; uint16_t c = yuv_to_rgb565(y0, u, v); *(tex++) = c; c = yuv_to_rgb565(y1, u, v); *(tex++) = c; } return (1 << 16) | GR_TEXFMT_RGB_565; } //**************************************************************** // Size: 2, Format: 0 // // Load 32bit RGBA texture // Based on sources of angrylion's software plugin. // static uint32_t Load32bRGBA(uintptr_t dst, uintptr_t src, int wid_64, int height, int line, int real_width, int tile) { uint32_t s, t, c, *tex; uint16_t rg, ba; int id; uint32_t mod; const uint16_t *tmem16 =(uint16_t*)g_gdp.tmem; const uint32_t tbase = (src -(uintptr_t)g_gdp.tmem) >> 1; const uint32_t width = max(1, wid_64 << 1); const int ext = real_width - width; line = width + (line>>2); tex =(uint32_t*)dst; if (height < 1) height = 1; for (t = 0; t <(uint32_t)height; t++) { uint32_t tline = tbase + line * t; uint32_t xorval = (t & 1) ? 3 : 1; for (s = 0; s < width; s++) { uint32_t taddr = ((tline + s) ^ xorval) & 0x3ff; rg = tmem16[taddr]; ba = tmem16[taddr|0x400]; c = ((ba&0xFF)<<24) | (rg << 8) | (ba>>8); *tex++ = c; } tex += ext; } id = tile - rdp.cur_tile; mod = (id == 0) ? cmb.mod_0 : cmb.mod_1; if (mod /*|| !voodoo.sup_32bit_tex*/) { uint32_t i; //convert to ARGB_4444 const uint32_t tex_size = real_width * height; uint16_t *tex16 = (uint16_t*)dst; tex = (uint32_t *)dst; for (i = 0; i < tex_size; i++) { uint16_t a, r, g, b; c = tex[i]; a = (c >> 28) & 0xF; r = (c >> 20) & 0xF; g = (c >> 12) & 0xF; b = (c >> 4) & 0xF; tex16[i] = (a <<12) | (r << 8) | (g << 4) | b; } return (1 << 16) | GR_TEXFMT_ARGB_4444; } return (2 << 16) | GR_TEXFMT_ARGB_8888; } //**************************************************************** // LoadTile for 32bit RGBA texture // Based on sources of angrylion's software plugin. // void LoadTile32b(uint32_t tile, uint32_t ul_s, uint32_t ul_t, uint32_t width, uint32_t height) { uint32_t j; const uint32_t line = g_gdp.tile[tile].line << 2; const uint32_t tbase = g_gdp.tile[tile].tmem << 2; const uint32_t addr = g_gdp.ti_address >> 2; const uint32_t* src = (const uint32_t*)gfx_info.RDRAM; uint16_t *tmem16 =(uint16_t*)g_gdp.tmem; for (j = 0; j < height; j++) { uint32_t i; uint32_t tline = tbase + line * j; uint32_t s = ((j + ul_t) * g_gdp.ti_width) + ul_s; uint32_t xorval = (j & 1) ? 3 : 1; for (i = 0; i < width; i++) { uint32_t c = src[addr + s + i]; uint32_t ptr = ((tline + i) ^ xorval) & 0x3ff; tmem16[ptr] = c >> 16; tmem16[ptr|0x400] = c & 0xffff; } } } //**************************************************************** // LoadBlock for 32bit RGBA texture // Based on sources of angrylion's software plugin. // void LoadBlock32b(uint32_t tile, uint32_t ul_s, uint32_t ul_t, uint32_t lr_s, uint32_t dxt) { const uint32_t * src = (const uint32_t*)gfx_info.RDRAM; const uint32_t tb = g_gdp.tile[tile].tmem << 2; const uint32_t tiwindwords = g_gdp.ti_width; const uint32_t slindwords = ul_s; const uint32_t line = g_gdp.tile[tile].line << 2; uint16_t *tmem16 =(uint16_t*)g_gdp.tmem; uint32_t addr = g_gdp.ti_address >> 2; uint32_t width = (lr_s - ul_s + 1) << 2; if (width & 7) width = (width & (~7)) + 8; if (dxt != 0) { uint32_t i; uint32_t t = 0; uint32_t j = 0; uint32_t oldt = 0; addr += (ul_t * tiwindwords) + slindwords; for (i = 0; i < width; i += 2) { uint32_t c, ptr; oldt = t; t = ((j >> 11) & 1) ? 3 : 1; if (t != oldt) i += line; ptr = ((tb + i) ^ t) & 0x3ff; c = src[addr + i]; tmem16[ptr] = c >> 16; tmem16[ptr|0x400] = c & 0xffff; ptr = ((tb+ i + 1) ^ t) & 0x3ff; c = src[addr + i + 1]; tmem16[ptr] = c >> 16; tmem16[ptr|0x400] = c & 0xffff; j += dxt; } } else { uint32_t i; addr += (ul_t * tiwindwords) + slindwords; for (i = 0; i < width; i ++) { uint32_t ptr = ((tb + i) ^ 1) & 0x3ff; uint32_t c = src[addr + i]; tmem16[ptr] = c >> 16; tmem16[ptr|0x400] = c & 0xffff; } } } texfunc load_table[4][5] = { // [size][format] { Load4bSelect, LoadNone, Load4bCI, Load4bIA, Load4bI }, { Load8bCI, LoadNone, Load8bCI, Load8bIA, Load8bI }, { Load16bRGBA, Load16bYUV, Load16bRGBA, Load16bIA, LoadNone }, { Load32bRGBA, LoadNone, LoadNone, LoadNone, LoadNone } }; static INLINE void load_block_line(uint32_t *src, uint32_t *dst, unsigned offset, unsigned width, bool is_load_block) { unsigned length = width; uint32_t *src32 = (uint32_t*)((uint8_t*)src + (offset & 0xFFFFFFFC)); uint32_t *dst32 = dst; if (!length) return; if (offset & 3) { uint32_t numrot = offset & 3; uint32_t nwords = 4 - numrot; uint32_t word = *src32++; while (numrot--) word = rol32(word, 8); if (is_load_block) { while (nwords--) { word = rol32(word, 8); *dst32++ = word; } } else { while (nwords--) { word = rol32(word, 8); *(uint8_t*)dst32 = word; dst32 = (uint32_t*)((uint8_t*)dst32 + 1); } } *dst32++ = m64p_swap32(*src32++); --length; } while (length--) { *dst32++ = m64p_swap32(*src32++); *dst32++ = m64p_swap32(*src32++); } if (offset & 3) { uint32_t nwords = offset & 3; uint32_t word = *(uint32_t*)((uint8_t*)src + ((8 * width + offset) & 0xFFFFFFFC)); if (is_load_block) { while (nwords--) { word = rol32(word, 8); *dst32++ = word; } } else { while (nwords--) { word = rol32(word, 8); *(uint8_t*)dst32 = word; dst32 = (uint32_t*)((uint8_t*)dst32 + 1); } } } } static INLINE void dxt_swap(uint32_t *line, int width) { while (width--) { line[0] ^= line[1]; line[1] ^= line[0]; line[0] ^= line[1]; line += 2; } } void loadTile(uint32_t *src, uint32_t *dst, int width, int height, int line, int off, uint32_t *end) { unsigned odd = 0; while (height-- && end >= dst) { load_block_line(src, dst, off, width, false); if (odd) dxt_swap(dst, width); dst += width * 2; off += line; odd ^= 1; } } void loadBlock(uint32_t *src, uint32_t *dst, uint32_t off, int dxt, int cnt) { int32_t v16 = 0; int32_t length = cnt; load_block_line(src, dst, off, cnt, true); while (length-- > 0) { int32_t v18 = 0; dst += 2; v16 += dxt; while (v16 < 0 && length--) { ++v18; v16 += dxt; } dxt_swap(dst, v18); dst += v18 * 2; } } mupen64plus-core/src/r4300/interupt.c000664 001750 001750 00000033672 12655644434 020437 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - interupt.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #define M64P_CORE_PROTOTYPES 1 #include "interupt.h" #include "cached_interp.h" #include "cp0_private.h" #include "exception.h" #include "new_dynarec/new_dynarec.h" #include "r4300.h" #include "r4300_core.h" #include "reset.h" #include "../ai/ai_controller.h" #include "../api/m64p_types.h" #include "../api/callbacks.h" #include "../main/main.h" #include "../main/savestates.h" #include "../pi/pi_controller.h" #include "../rdp/rdp_core.h" #include "../rsp/rsp_core.h" #include "../si/si_controller.h" #include "../vi/vi_controller.h" #include "../dd/dd_controller.h" #include #include #include extern int retro_return(bool just_flipping); int interupt_unsafe_state = 0; struct interrupt_event { int type; unsigned int count; }; /*************************************************************************** * Pool of Single Linked List Nodes **************************************************************************/ #define POOL_CAPACITY 16 struct node { struct interrupt_event data; struct node *next; }; struct pool { struct node nodes [POOL_CAPACITY]; struct node *stack [POOL_CAPACITY]; size_t index; }; static struct node* alloc_node(struct pool* p); static void free_node(struct pool* p, struct node* node); static void clear_pool(struct pool* p); /* node allocation/deallocation on a given pool */ static struct node* alloc_node(struct pool* p) { /* return NULL if pool is too small */ if (p->index >= POOL_CAPACITY) return NULL; return p->stack[p->index++]; } static void free_node(struct pool *p, struct node *node) { if (p->index == 0 || !node) return; p->stack[--p->index] = node; } /* release all nodes */ static void clear_pool(struct pool *p) { size_t i; for(i = 0; i < POOL_CAPACITY; ++i) p->stack[i] = &p->nodes[i]; p->index = 0; } /*************************************************************************** * Interrupt Queue **************************************************************************/ struct interrupt_queue { struct pool pool; struct node *first; }; static struct interrupt_queue q; static void clear_queue(void) { q.first = NULL; clear_pool(&q.pool); } static int SPECIAL_done = 0; static int before_event(unsigned int evt1, unsigned int evt2, int type2) { if(evt1 - g_cp0_regs[CP0_COUNT_REG] < UINT32_C(0x80000000)) { if(evt2 - g_cp0_regs[CP0_COUNT_REG] < UINT32_C(0x80000000)) { if((evt1 - g_cp0_regs[CP0_COUNT_REG]) < (evt2 - g_cp0_regs[CP0_COUNT_REG])) return 1; } else { if((g_cp0_regs[CP0_COUNT_REG] - evt2) < UINT32_C(0x10000000)) { if (type2 == SPECIAL_INT) if (SPECIAL_done) return 1; } else return 1; } } return 0; } void add_interupt_event(int type, unsigned int delay) { add_interupt_event_count(type, g_cp0_regs[CP0_COUNT_REG] + delay); } void add_interupt_event_count(int type, unsigned count) { struct node *event = NULL; struct node *e = NULL; int special = (type == SPECIAL_INT); if(g_cp0_regs[CP0_COUNT_REG] > UINT32_C(0x80000000)) SPECIAL_done = 0; event = alloc_node(&q.pool); if (!event) { DebugMessage(M64MSG_ERROR, "Failed to allocate node for new interrupt event"); return; } event->data.count = count; event->data.type = type; if (!q.first) { q.first = event; event->next = NULL; next_interupt = q.first->data.count; } else if (before_event(count, q.first->data.count, q.first->data.type) && !special) { event->next = q.first; q.first = event; next_interupt = q.first->data.count; } else { for(e = q.first; e && e->next && (!before_event(count, e->next->data.count, e->next->data.type) || special); e = e->next); if (!e->next) { e->next = event; event->next = NULL; } else { if (!special) for(; e->next && e->next->data.count == count; e = e->next); event->next = e->next; e->next = event; } } } static void remove_interupt_event(void) { struct node *e = q.first; q.first = e->next; free_node(&q.pool, e); next_interupt = (q.first && (q.first->data.count > g_cp0_regs[CP0_COUNT_REG] || (g_cp0_regs[CP0_COUNT_REG] - q.first->data.count) < UINT32_C(0x80000000))) ? q.first->data.count : 0; } unsigned int get_event(int type) { struct node* e = q.first; if (!e) return 0; if (e->data.type == type) return e->data.count; for(; e->next && e->next->data.type != type; e = e->next); return (e->next) ? e->next->data.count : 0; } int get_next_event_type(void) { return (q.first) ? q.first->data.type : 0; } void remove_event(int type) { struct node* to_del; struct node* e = q.first; if (!e) return; if (e->data.type == type) { q.first = e->next; free_node(&q.pool, e); } else { for(; e->next && e->next->data.type != type; e = e->next); if (e->next) { to_del = e->next; e->next = to_del->next; free_node(&q.pool, to_del); } } } void translate_event_queue(unsigned int base) { struct node *e; remove_event(COMPARE_INT); remove_event(SPECIAL_INT); for(e = q.first; e != NULL; e = e->next) e->data.count = (e->data.count - g_cp0_regs[CP0_COUNT_REG]) + base; add_interupt_event_count(COMPARE_INT, g_cp0_regs[CP0_COMPARE_REG]); add_interupt_event_count(SPECIAL_INT, 0); } int save_eventqueue_infos(char *buf) { int len = 0; struct node *e; for (e = q.first; e != NULL; e = e->next) { memcpy(buf + len , &e->data.type , 4); memcpy(buf + len + 4, &e->data.count, 4); len += 8; } *((unsigned int*)&buf[len]) = 0xFFFFFFFF; return len+4; } void load_eventqueue_infos(char *buf) { int len = 0; clear_queue(); while (*((unsigned int*)&buf[len]) != 0xFFFFFFFF) { int type = *((unsigned int*)&buf[len]); unsigned int count = *((unsigned int*)&buf[len+4]); add_interupt_event_count(type, count); len += 8; } } void init_interupt(void) { SPECIAL_done = 1; g_vi.delay = g_vi.next_vi = 5000; clear_queue(); add_interupt_event_count(VI_INT, g_vi.next_vi); add_interupt_event_count(SPECIAL_INT, 0); } void check_interupt(void) { struct node *event; if ((g_r4300.mi.regs[MI_INTR_REG] & g_r4300.mi.regs[MI_INTR_REG])) g_cp0_regs[CP0_CAUSE_REG] = (g_cp0_regs[CP0_CAUSE_REG] | UINT32_C(0x400)) & UINT32_C(0xFFFFFF83); else g_cp0_regs[CP0_CAUSE_REG] &= ~UINT32_C(0x400); if ((g_cp0_regs[CP0_STATUS_REG] & UINT32_C(7)) != 1) return; if (g_cp0_regs[CP0_STATUS_REG] & g_cp0_regs[CP0_CAUSE_REG] & UINT32_C(0xFF00)) { event = alloc_node(&q.pool); if (!event) { DebugMessage(M64MSG_ERROR, "Failed to allocate node for new interrupt event"); return; } event->data.count = next_interupt = g_cp0_regs[CP0_COUNT_REG]; event->data.type = CHECK_INT; if (!q.first) { q.first = event; event->next = NULL; } else { event->next = q.first; q.first = event; } } } static void wrapped_exception_general(void) { #ifdef NEW_DYNAREC if (r4300emu == CORE_DYNAREC) { g_cp0_regs[CP0_EPC_REG] = pcaddr; pcaddr = 0x80000180; g_cp0_regs[CP0_STATUS_REG] |= UINT32_C(2); g_cp0_regs[CP0_CAUSE_REG] &= UINT32_C(0x7FFFFFFF); pending_exception=1; } else #endif exception_general(); } void raise_maskable_interrupt(uint32_t cause) { g_cp0_regs[CP0_CAUSE_REG] = (g_cp0_regs[CP0_CAUSE_REG] | cause) & UINT32_C(0xffffff83); if (!(g_cp0_regs[CP0_STATUS_REG] & g_cp0_regs[CP0_CAUSE_REG] & UINT32_C(0xff00))) return; if ((g_cp0_regs[CP0_STATUS_REG] & 7) != 1) return; wrapped_exception_general(); } static void special_int_handler(void) { if (g_cp0_regs[CP0_COUNT_REG] > UINT32_C(0x10000000)) return; SPECIAL_done = 1; remove_interupt_event(); add_interupt_event_count(SPECIAL_INT, 0); } static void compare_int_handler(void) { remove_interupt_event(); g_cp0_regs[CP0_COUNT_REG]+=count_per_op; add_interupt_event_count(COMPARE_INT, g_cp0_regs[CP0_COMPARE_REG]); g_cp0_regs[CP0_COUNT_REG]-=count_per_op; raise_maskable_interrupt(UINT32_C(0x8000)); } static void hw2_int_handler(void) { /* Hardware Interrupt 2 -- remove interrupt event from queue */ remove_interupt_event(); g_cp0_regs[CP0_STATUS_REG] = (g_cp0_regs[CP0_STATUS_REG] & ~UINT32_C(0x00380000)) | UINT32_C(0x1000); g_cp0_regs[CP0_CAUSE_REG] = (g_cp0_regs[CP0_CAUSE_REG] | UINT32_C(0x1000)) & UINT32_C(0xffffff83); wrapped_exception_general(); } static void nmi_int_handler(void) { /* Non Maskable Interrupt -- remove interrupt event from queue */ remove_interupt_event(); /* setup r4300 g_cp0_regs[CP0_STATUS_REG] flags: reset TS and SR, set BEV, ERL, and SR */ g_cp0_regs[CP0_STATUS_REG] = (g_cp0_regs[CP0_STATUS_REG] & ~UINT32_C(0x00380000)) | UINT32_C(0x00500004); g_cp0_regs[CP0_CAUSE_REG] = 0x00000000; /* simulate the soft reset code which would run from the PIF ROM */ r4300_reset_soft(); /* clear all interrupts, reset interrupt counters back to 0 */ g_cp0_regs[CP0_COUNT_REG] = 0; g_gs_vi_counter = 0; init_interupt(); /* clear the audio status register so that * subsequent write_ai() calls will work properly */ g_ai.regs[AI_STATUS_REG] = 0; /* set ErrorEPC with the last instruction address */ g_cp0_regs[CP0_ERROREPC_REG] = PC->addr; /* reset the r4300 internal state */ if (r4300emu != CORE_PURE_INTERPRETER) { /* clear all the compiled instruction blocks and re-initialize */ free_blocks(); init_blocks(); } /* adjust ErrorEPC if we were in a delay slot, * and clear the delay_slot and dyna_interp flags */ if(delay_slot==1 || delay_slot==3) g_cp0_regs[CP0_ERROREPC_REG] -= 4; delay_slot = 0; dyna_interp = 0; /* set next instruction address to reset vector */ last_addr = UINT32_C(0xa4000040); generic_jump_to(UINT32_C(0xa4000040)); } void gen_interupt(void) { if (stop == 1) { #ifndef SINGLE_THREAD g_gs_vi_counter = 0; /* debug */ #endif dyna_stop(); } if (!interupt_unsafe_state) { if (reset_hard_job) { reset_hard(); reset_hard_job = 0; return; } } if (skip_jump) { uint32_t dest = skip_jump; skip_jump = 0; next_interupt = (q.first->data.count > g_cp0_regs[CP0_COUNT_REG] || (g_cp0_regs[CP0_COUNT_REG] - q.first->data.count) < UINT32_C(0x80000000)) ? q.first->data.count : 0; last_addr = dest; generic_jump_to(dest); return; } switch(q.first->data.type) { case SPECIAL_INT: special_int_handler(); break; case VI_INT: remove_interupt_event(); vi_vertical_interrupt_event(&g_vi); #ifdef __LIBRETRO__ retro_return(false); #endif break; case COMPARE_INT: compare_int_handler(); break; case CHECK_INT: remove_interupt_event(); wrapped_exception_general(); break; case SI_INT: remove_interupt_event(); si_end_of_dma_event(&g_si); break; case PI_INT: remove_interupt_event(); pi_end_of_dma_event(&g_pi); break; case AI_INT: remove_interupt_event(); ai_end_of_dma_event(&g_ai); break; case SP_INT: remove_interupt_event(); rsp_interrupt_event(&g_sp); break; case DP_INT: remove_interupt_event(); rdp_interrupt_event(&g_dp); break; case HW2_INT: hw2_int_handler(); break; case NMI_INT: nmi_int_handler(); break; case CART_INT: g_cp0_regs[CP0_CAUSE_REG] |= 0x00000800; /* set IP3 */ g_cp0_regs[CP0_CAUSE_REG] &= 0xFFFFFF83; /* mask out old exception code */ if (dd_end_of_dma_event(&g_dd) == 1) { remove_interupt_event(); g_cp0_regs[CP0_CAUSE_REG] &= ~0x00000800; } break; default: DebugMessage(M64MSG_ERROR, "Unknown interrupt queue event type %.8X.", q.first->data.type); remove_interupt_event(); break; } } gles2rice/src/RSP_GBI0.h000664 001750 001750 00000064465 12655644434 015762 0ustar00sergiosergio000000 000000 /* Copyright (C) 2002 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "Render.h" #include "Timing.h" void RSP_GBI1_SpNoop(Gfx *gfx) { SP_Timing(RSP_GBI1_SpNoop); if( (gfx+1)->words.cmd == 0x00 && gRSP.ucode >= 17 ) { RSP_RDP_NOIMPL("Double SPNOOP, Skip remain ucodes, PC=%08X, Cmd1=%08X", gDlistStack[gDlistStackPointer].pc, gfx->words.w1); RDP_GFX_PopDL(); //if( gRSP.ucode < 17 ) TriggerDPInterrupt(); } } void RSP_GBI0_Mtx(Gfx *gfx) { SP_Timing(RSP_GBI0_Mtx); uint32_t addr = RSPSegmentAddr((gfx->gbi0matrix.addr)); LOG_UCODE(" Command: %s %s %s Length %d Address 0x%08x", gfx->gbi0matrix.projection == 1 ? "Projection" : "ModelView", gfx->gbi0matrix.load == 1 ? "Load" : "Mul", gfx->gbi0matrix.push == 1 ? "Push" : "NoPush", gfx->gbi0matrix.len, addr); if (addr + 64 > g_dwRamSize) { TRACE1("Mtx: Address invalid (0x%08x)", addr); return; } LoadMatrix(addr); if (gfx->gbi0matrix.projection) { CRender::g_pRender->SetProjection(matToLoad, gfx->gbi0matrix.push, gfx->gbi0matrix.load); } else { CRender::g_pRender->SetWorldView(matToLoad, gfx->gbi0matrix.push, gfx->gbi0matrix.load); } #ifdef DEBUGGER const char *loadstr = gfx->gbi0matrix.load == 1 ? "Load" : "Mul"; const char *pushstr = gfx->gbi0matrix.push == 1 ? "Push" : "Nopush"; int projlevel = CRender::g_pRender->GetProjectMatrixLevel(); int worldlevel = CRender::g_pRender->GetWorldViewMatrixLevel(); if( pauseAtNext && eventToPause == NEXT_MATRIX_CMD ) { pauseAtNext = false; debuggerPause = true; if (gfx->gbi0matrix.projection) { TRACE3("Pause after %s and %s Matrix: Projection, level=%d\n", loadstr, pushstr, projlevel ); } else { TRACE3("Pause after %s and %s Matrix: WorldView level=%d\n", loadstr, pushstr, worldlevel); } } else { if( pauseAtNext && logMatrix ) { if (gfx->gbi0matrix.projection) { TRACE3("Matrix: %s and %s Projection level=%d\n", loadstr, pushstr, projlevel); } else { TRACE3("Matrix: %s and %s WorldView\n level=%d", loadstr, pushstr, worldlevel); } } } #endif } void RSP_GBI1_Reserved(Gfx *gfx) { SP_Timing(RSP_GBI1_Reserved); RSP_RDP_NOIMPL("RDP: Reserved (0x%08x 0x%08x)", (gfx->words.w0), (gfx->words.w1)); } void RSP_GBI1_MoveMem(Gfx *gfx) { SP_Timing(RSP_GBI1_MoveMem); uint32_t type = ((gfx->words.w0)>>16)&0xFF; uint32_t dwLength = ((gfx->words.w0))&0xFFFF; uint32_t addr = RSPSegmentAddr((gfx->words.w1)); switch (type) { case RSP_GBI1_MV_MEM_VIEWPORT: { LOG_UCODE(" RSP_GBI1_MV_MEM_VIEWPORT. Address: 0x%08x, Length: 0x%04x", addr, dwLength); RSP_MoveMemViewport(addr); } break; case RSP_GBI1_MV_MEM_LOOKATY: LOG_UCODE(" RSP_GBI1_MV_MEM_LOOKATY"); break; case RSP_GBI1_MV_MEM_LOOKATX: LOG_UCODE(" RSP_GBI1_MV_MEM_LOOKATX"); break; case RSP_GBI1_MV_MEM_L0: case RSP_GBI1_MV_MEM_L1: case RSP_GBI1_MV_MEM_L2: case RSP_GBI1_MV_MEM_L3: case RSP_GBI1_MV_MEM_L4: case RSP_GBI1_MV_MEM_L5: case RSP_GBI1_MV_MEM_L6: case RSP_GBI1_MV_MEM_L7: { uint32_t dwLight = (type-RSP_GBI1_MV_MEM_L0)/2; LOG_UCODE(" RSP_GBI1_MV_MEM_L%d", dwLight); LOG_UCODE(" Light%d: Length:0x%04x, Address: 0x%08x", dwLight, dwLength, addr); RSP_MoveMemLight(dwLight, addr); } break; case RSP_GBI1_MV_MEM_TXTATT: LOG_UCODE(" RSP_GBI1_MV_MEM_TXTATT"); break; case RSP_GBI1_MV_MEM_MATRIX_1: RSP_GFX_Force_Matrix(addr); break; case RSP_GBI1_MV_MEM_MATRIX_2: break; case RSP_GBI1_MV_MEM_MATRIX_3: break; case RSP_GBI1_MV_MEM_MATRIX_4: break; default: RSP_RDP_NOIMPL("MoveMem: Unknown Move Type, cmd=%08X, %08X", gfx->words.w0, gfx->words.w1); break; } } void RSP_GBI0_Vtx(Gfx *gfx) { SP_Timing(RSP_GBI0_Vtx); int n = gfx->gbi0vtx.n + 1; int v0 = gfx->gbi0vtx.v0; uint32_t addr = RSPSegmentAddr((gfx->gbi0vtx.addr)); LOG_UCODE(" Address 0x%08x, v0: %d, Num: %d, Length: 0x%04x", addr, v0, n, gfx->gbi0vtx.len); if ((v0 + n) > 80) { TRACE3("Warning, invalid vertex positions, N=%d, v0=%d, Addr=0x%08X", n, v0, addr); n = 32 - v0; } // Check that address is valid... if ((addr + n*16) > g_dwRamSize) { TRACE1("Vertex Data: Address out of range (0x%08x)", addr); } else { ProcessVertexData(addr, v0, n); status.dwNumVertices += n; DisplayVertexInfo(addr, v0, n); } } void RSP_GBI0_DL(Gfx *gfx) { SP_Timing(RSP_GBI0_DL); uint32_t addr = RSPSegmentAddr((gfx->gbi0dlist.addr)) & (g_dwRamSize-1); LOG_UCODE(" Address=0x%08x Push: 0x%02x", addr, gfx->gbi0dlist.param); if( addr > g_dwRamSize ) { RSP_RDP_NOIMPL("Error: DL addr = %08X out of range, PC=%08X", addr, gDlistStack[gDlistStackPointer].pc ); addr &= (g_dwRamSize-1); DebuggerPauseCountN( NEXT_DLIST ); } if( gfx->gbi0dlist.param == RSP_DLIST_PUSH ) gDlistStackPointer++; gDlistStack[gDlistStackPointer].pc = addr; gDlistStack[gDlistStackPointer].countdown = MAX_DL_COUNT; LOG_UCODE("Level=%d", gDlistStackPointer+1); LOG_UCODE("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"); } void RSP_GBI1_RDPHalf_Cont(Gfx *gfx) { SP_Timing(RSP_GBI1_RDPHalf_Cont); LOG_UCODE("RDPHalf_Cont: (Ignored)"); } void RSP_GBI1_RDPHalf_2(Gfx *gfx) { SP_Timing(RSP_GBI1_RDPHalf_2); LOG_UCODE("RDPHalf_2: (Ignored)"); } void RSP_GBI1_RDPHalf_1(Gfx *gfx) { SP_Timing(RSP_GBI1_RDPHalf_1); LOG_UCODE("RDPHalf_1: (Ignored)"); } void RSP_GBI1_Line3D(Gfx *gfx) { status.primitiveType = PRIM_LINE3D; uint32_t dwPC = gDlistStack[gDlistStackPointer].pc; bool bTrisAdded = false; if( gfx->ln3dtri2.v3 == 0 ) { // Flying Dragon uint32_t dwV0 = gfx->ln3dtri2.v0/gRSP.vertexMult; uint32_t dwV1 = gfx->ln3dtri2.v1/gRSP.vertexMult; uint32_t dwWidth = gfx->ln3dtri2.v2; //uint32_t dwFlag = gfx->ln3dtri2.v3/gRSP.vertexMult; CRender::g_pRender->SetCombinerAndBlender(); status.dwNumTrisRendered++; CRender::g_pRender->Line3D(dwV0, dwV1, dwWidth); SP_Timing(RSP_GBI1_Line3D); DP_Timing(RSP_GBI1_Line3D); } else { do { uint32_t dwV3 = gfx->ln3dtri2.v3/gRSP.vertexMult; uint32_t dwV0 = gfx->ln3dtri2.v0/gRSP.vertexMult; uint32_t dwV1 = gfx->ln3dtri2.v1/gRSP.vertexMult; uint32_t dwV2 = gfx->ln3dtri2.v2/gRSP.vertexMult; LOG_UCODE(" Line3D: V0: %d, V1: %d, V2: %d, V3: %d", dwV0, dwV1, dwV2, dwV3); // Do first tri if (IsTriangleVisible(dwV0, dwV1, dwV2)) { DEBUG_DUMP_VERTEXES("Line3D 1/2", dwV0, dwV1, dwV2); if (!bTrisAdded && CRender::g_pRender->IsTextureEnabled()) { PrepareTextures(); InitVertexTextureConstants(); } if( !bTrisAdded ) { CRender::g_pRender->SetCombinerAndBlender(); } bTrisAdded = true; PrepareTriangle(dwV0, dwV1, dwV2); } // Do second tri if (IsTriangleVisible(dwV2, dwV3, dwV0)) { DEBUG_DUMP_VERTEXES("Line3D 2/2", dwV0, dwV1, dwV2); if (!bTrisAdded && CRender::g_pRender->IsTextureEnabled()) { PrepareTextures(); InitVertexTextureConstants(); } if( !bTrisAdded ) { CRender::g_pRender->SetCombinerAndBlender(); } bTrisAdded = true; PrepareTriangle(dwV2, dwV3, dwV0); } gfx++; dwPC += 8; #ifdef DEBUGGER } while (gfx->words.cmd == (uint8_t)RSP_LINE3D && !(pauseAtNext && eventToPause==NEXT_FLUSH_TRI)); #else } while (gfx->words.cmd == (uint8_t)RSP_LINE3D); #endif gDlistStack[gDlistStackPointer].pc = dwPC-8; if (bTrisAdded) { CRender::g_pRender->DrawTriangles(); } } } void RSP_GBI1_ClearGeometryMode(Gfx *gfx) { SP_Timing(RSP_GBI1_ClearGeometryMode); uint32_t dwMask = ((gfx->words.w1)); #ifdef DEBUGGER LOG_UCODE(" Mask=0x%08x", dwMask); if (dwMask & G_ZBUFFER) LOG_UCODE(" Disabling ZBuffer"); if (dwMask & G_TEXTURE_ENABLE) LOG_UCODE(" Disabling Texture"); if (dwMask & G_SHADE) LOG_UCODE(" Disabling Shade"); if (dwMask & G_SHADING_SMOOTH) LOG_UCODE(" Disabling Smooth Shading"); if (dwMask & G_CULL_FRONT) LOG_UCODE(" Disabling Front Culling"); if (dwMask & G_CULL_BACK) LOG_UCODE(" Disabling Back Culling"); if (dwMask & G_FOG) LOG_UCODE(" Disabling Fog"); if (dwMask & G_LIGHTING) LOG_UCODE(" Disabling Lighting"); if (dwMask & G_TEXTURE_GEN) LOG_UCODE(" Disabling Texture Gen"); if (dwMask & G_TEXTURE_GEN_LINEAR) LOG_UCODE(" Disabling Texture Gen Linear"); if (dwMask & G_LOD) LOG_UCODE(" Disabling LOD (no impl)"); #endif gRDP.geometryMode &= ~dwMask; RSP_GFX_InitGeometryMode(); } void RSP_GBI1_SetGeometryMode(Gfx *gfx) { SP_Timing(RSP_GBI1_SetGeometryMode); uint32_t dwMask = ((gfx->words.w1)); #ifdef DEBUGGER LOG_UCODE(" Mask=0x%08x", dwMask); if (dwMask & G_ZBUFFER) LOG_UCODE(" Enabling ZBuffer"); if (dwMask & G_TEXTURE_ENABLE) LOG_UCODE(" Enabling Texture"); if (dwMask & G_SHADE) LOG_UCODE(" Enabling Shade"); if (dwMask & G_SHADING_SMOOTH) LOG_UCODE(" Enabling Smooth Shading"); if (dwMask & G_CULL_FRONT) LOG_UCODE(" Enabling Front Culling"); if (dwMask & G_CULL_BACK) LOG_UCODE(" Enabling Back Culling"); if (dwMask & G_FOG) LOG_UCODE(" Enabling Fog"); if (dwMask & G_LIGHTING) LOG_UCODE(" Enabling Lighting"); if (dwMask & G_TEXTURE_GEN) LOG_UCODE(" Enabling Texture Gen"); if (dwMask & G_TEXTURE_GEN_LINEAR) LOG_UCODE(" Enabling Texture Gen Linear"); if (dwMask & G_LOD) LOG_UCODE(" Enabling LOD (no impl)"); #endif // DEBUGGER gRDP.geometryMode |= dwMask; RSP_GFX_InitGeometryMode(); } void RSP_GBI1_EndDL(Gfx *gfx) { SP_Timing(RSP_GBI1_EndDL); RDP_GFX_PopDL(); } void RSP_GBI1_SetOtherModeL(Gfx *gfx) { SP_Timing(RSP_GBI1_SetOtherModeL); uint32_t dwShift = ((gfx->words.w0)>>8)&0xFF; uint32_t dwLength= ((gfx->words.w0) )&0xFF; uint32_t dwData = (gfx->words.w1); uint32_t dwMask = ((1<words.w0)>>8)&0xFF; uint32_t dwLength= ((gfx->words.w0) )&0xFF; uint32_t dwData = (gfx->words.w1); uint32_t dwMask = ((1<texture.scaleS) / (65536.0f * 32.0f); float fTextureScaleT = (float)(gfx->texture.scaleT) / (65536.0f * 32.0f); if( (((gfx->words.w1)>>16)&0xFFFF) == 0xFFFF ) { fTextureScaleS = 1/32.0f; } else if( (((gfx->words.w1)>>16)&0xFFFF) == 0x8000 ) { fTextureScaleS = 1/64.0f; } #ifdef DEBUGGER else if( ((gfx->words.w1>>16)&0xFFFF) != 0 ) { //DebuggerAppendMsg("Warning, texture scale = %08X is not integer", (word1>>16)&0xFFFF); } #endif if( (((gfx->words.w1) )&0xFFFF) == 0xFFFF ) { fTextureScaleT = 1/32.0f; } else if( (((gfx->words.w1) )&0xFFFF) == 0x8000 ) { fTextureScaleT = 1/64.0f; } #ifdef DEBUGGER else if( (gfx->words.w1&0xFFFF) != 0 ) { //DebuggerAppendMsg("Warning, texture scale = %08X is not integer", (word1)&0xFFFF); } #endif if( gRSP.ucode == 6 ) { if( fTextureScaleS == 0 ) fTextureScaleS = 1.0f/32.0f; if( fTextureScaleT == 0 ) fTextureScaleT = 1.0f/32.0f; } CRender::g_pRender->SetTextureEnableAndScale(gfx->texture.tile, gfx->texture.enable_gbi0, fTextureScaleS, fTextureScaleT); // What happens if these are 0? Interpret as 1.0f? LOG_TEXTURE( { DebuggerAppendMsg("SetTexture: Level: %d Tile: %d %s\n", gfx->texture.level, gfx->texture.tile, gfx->texture.enable_gbi0 ? "enabled":"disabled"); DebuggerAppendMsg(" ScaleS: %f, ScaleT: %f\n", fTextureScaleS*32.0f, fTextureScaleT*32.0f); }); DEBUGGER_PAUSE_COUNT_N(NEXT_SET_TEXTURE); LOG_UCODE(" Level: %d Tile: %d %s", gfx->texture.level, gfx->texture.tile, gfx->texture.enable_gbi0 ? "enabled":"disabled"); LOG_UCODE(" ScaleS: %f, ScaleT: %f", fTextureScaleS*32.0f, fTextureScaleT*32.0f); } extern void RSP_RDP_InsertMatrix(uint32_t word0, uint32_t word1); void RSP_GBI1_MoveWord(Gfx *gfx) { SP_Timing(RSP_GBI1_MoveWord); switch (gfx->gbi0moveword.type) { case RSP_MOVE_WORD_MATRIX: RSP_RDP_InsertMatrix(gfx); break; case RSP_MOVE_WORD_NUMLIGHT: { uint32_t dwNumLights = (((gfx->gbi0moveword.value)-0x80000000)/32)-1; LOG_UCODE(" RSP_MOVE_WORD_NUMLIGHT: Val:%d", dwNumLights); gRSP.ambientLightIndex = dwNumLights; SetNumLights(dwNumLights); } break; case RSP_MOVE_WORD_CLIP: { switch (gfx->gbi0moveword.offset) { case RSP_MV_WORD_OFFSET_CLIP_RNX: case RSP_MV_WORD_OFFSET_CLIP_RNY: case RSP_MV_WORD_OFFSET_CLIP_RPX: case RSP_MV_WORD_OFFSET_CLIP_RPY: CRender::g_pRender->SetClipRatio(gfx->gbi0moveword.offset, gfx->gbi0moveword.value); break; default: LOG_UCODE(" RSP_MOVE_WORD_CLIP ? : 0x%08x", gfx->words.w1); break; } } break; case RSP_MOVE_WORD_SEGMENT: { uint32_t dwSegment = (gfx->gbi0moveword.offset >> 2) & 0xF; uint32_t dwBase = (gfx->gbi0moveword.value)&0x00FFFFFF; LOG_UCODE(" RSP_MOVE_WORD_SEGMENT Seg[%d] = 0x%08x", dwSegment, dwBase); if( dwBase > g_dwRamSize ) { gRSP.segments[dwSegment] = dwBase; #ifdef DEBUGGER if( pauseAtNext ) DebuggerAppendMsg("warning: Segment %d addr is %8X", dwSegment, dwBase); #endif } else { gRSP.segments[dwSegment] = dwBase; } } break; case RSP_MOVE_WORD_FOG: { uint16_t wMult = (uint16_t)(((gfx->gbi0moveword.value) >> 16) & 0xFFFF); uint16_t wOff = (uint16_t)(((gfx->gbi0moveword.value) ) & 0xFFFF); float fMult = (float)(short)wMult; float fOff = (float)(short)wOff; float rng = 128000.0f / fMult; float fMin = 500.0f - (fOff*rng/256.0f); float fMax = rng + fMin; FOG_DUMP(TRACE4("Set Fog: Min=%f, Max=%f, Mul=%f, Off=%f", fMin, fMax, fMult, fOff)); //if( fMult <= 0 || fMin > fMax || fMax < 0 || fMin > 1000 ) if( fMult <= 0 || fMax < 0 ) { // Hack fMin = 996; fMax = 1000; fMult = 0; fOff = 1; } LOG_UCODE(" RSP_MOVE_WORD_FOG/Mul=%d: Off=%d", wMult, wOff); FOG_DUMP(TRACE3("Set Fog: Min=%f, Max=%f, Data=%08X", fMin, fMax, gfx->gbi0moveword.value)); SetFogMinMax(fMin, fMax, fMult, fOff); } break; case RSP_MOVE_WORD_LIGHTCOL: { uint32_t dwLight = gfx->gbi0moveword.offset / 0x20; uint32_t dwField = (gfx->gbi0moveword.offset & 0x7); LOG_UCODE(" RSP_MOVE_WORD_LIGHTCOL/0x%08x: 0x%08x", gfx->gbi0moveword.offset, gfx->words.w1); switch (dwField) { case 0: if (dwLight == gRSP.ambientLightIndex) { SetAmbientLight( ((gfx->gbi0moveword.value)>>8) ); } else { SetLightCol(dwLight, gfx->gbi0moveword.value); } break; case 4: break; default: TRACE1("RSP_MOVE_WORD_LIGHTCOL with unknown offset 0x%08x", dwField); break; } } break; case RSP_MOVE_WORD_POINTS: { uint32_t vtx = gfx->gbi0moveword.offset/40; uint32_t where = gfx->gbi0moveword.offset - vtx*40; ModifyVertexInfo(where, vtx, gfx->gbi0moveword.value); } break; case RSP_MOVE_WORD_PERSPNORM: LOG_UCODE(" RSP_MOVE_WORD_PERSPNORM"); //if( word1 != 0x1A ) DebuggerAppendMsg("PerspNorm: 0x%04x", (short)word1); break; default: RSP_RDP_NOIMPL("Unknown MoveWord, %08X, %08X", gfx->words.w0, gfx->words.w1); break; } } void RSP_GBI1_PopMtx(Gfx *gfx) { SP_Timing(RSP_GBI1_PopMtx); LOG_UCODE(" Command: (%s)", gfx->gbi0popmatrix.projection ? "Projection" : "ModelView"); // Do any of the other bits do anything? // So far only Extreme-G seems to Push/Pop projection matrices if (gfx->gbi0popmatrix.projection) { CRender::g_pRender->PopProjection(); } else { CRender::g_pRender->PopWorldView(); } #ifdef DEBUGGER if( pauseAtNext && eventToPause == NEXT_MATRIX_CMD ) { pauseAtNext = false; debuggerPause = true; DebuggerAppendMsg("Pause after Pop Matrix: %s\n", gfx->gbi0popmatrix.projection ? "Proj":"World"); } else { if( pauseAtNext && logMatrix ) { DebuggerAppendMsg("Pause after Pop Matrix: %s\n", gfx->gbi0popmatrix.projection ? "Proj":"World"); } } #endif } void RSP_GBI1_CullDL(Gfx *gfx) { SP_Timing(RSP_GBI1_CullDL); #ifdef DEBUGGER if( !debuggerEnableCullFace ) { return; //Disable Culling } #endif if( g_curRomInfo.bDisableCulling ) { return; //Disable Culling } uint32_t dwVFirst = ((gfx->words.w0) & 0xFFF) / gRSP.vertexMult; uint32_t dwVLast = (((gfx->words.w1)) & 0xFFF) / gRSP.vertexMult; LOG_UCODE(" Culling using verts %d to %d", dwVFirst, dwVLast); // Mask into range dwVFirst &= 0x1f; dwVLast &= 0x1f; if( dwVLast < dwVFirst ) return; if( !gRSP.bRejectVtx ) return; for (uint32_t i = dwVFirst; i <= dwVLast; i++) { if (g_clipFlag[i] == 0) { LOG_UCODE(" Vertex %d is visible, continuing with display list processing", i); return; } } status.dwNumDListsCulled++; LOG_UCODE(" No vertices were visible, culling rest of display list"); RDP_GFX_PopDL(); } void RSP_GBI1_Tri1(Gfx *gfx) { status.primitiveType = PRIM_TRI1; bool bTrisAdded = false; bool bTexturesAreEnabled = CRender::g_pRender->IsTextureEnabled(); // While the next command pair is Tri1, add vertices uint32_t dwPC = gDlistStack[gDlistStackPointer].pc; do { uint32_t dwV0 = gfx->tri1.v0/gRSP.vertexMult; uint32_t dwV1 = gfx->tri1.v1/gRSP.vertexMult; uint32_t dwV2 = gfx->tri1.v2/gRSP.vertexMult; if (IsTriangleVisible(dwV0, dwV1, dwV2)) { DEBUG_DUMP_VERTEXES("Tri1", dwV0, dwV1, dwV2); LOG_UCODE(" Tri1: 0x%08x 0x%08x %d,%d,%d", gfx->words.w0, gfx->words.w1, dwV0, dwV1, dwV2); if (!bTrisAdded) { if( bTexturesAreEnabled ) { PrepareTextures(); InitVertexTextureConstants(); } CRender::g_pRender->SetCombinerAndBlender(); bTrisAdded = true; } PrepareTriangle(dwV0, dwV1, dwV2); } gfx++; dwPC += 8; #ifdef DEBUGGER } while (!(pauseAtNext && eventToPause==NEXT_TRIANGLE) && gfx->words.cmd == (uint8_t)RSP_TRI1); #else } while (gfx->words.cmd == (uint8_t)RSP_TRI1); #endif gDlistStack[gDlistStackPointer].pc = dwPC-8; if (bTrisAdded) { CRender::g_pRender->DrawTriangles(); } DEBUG_TRIANGLE(TRACE0("Pause at GBI0 TRI1")); } void RSP_GBI0_Tri4(Gfx *gfx) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; uint32_t w0 = gfx->words.w0; uint32_t w1 = gfx->words.w1; status.primitiveType = PRIM_TRI2; // While the next command pair is Tri2, add vertices uint32_t dwPC = gDlistStack[gDlistStackPointer].pc; bool bTrisAdded = false; do { uint32_t dwFlag = (w0>>16)&0xFF; LOG_UCODE(" PD Tri4: 0x%08x 0x%08x Flag: 0x%02x", gfx->words.w0, gfx->words.w1, dwFlag); for( int i=0; i<4; i++) { uint32_t v0 = (w1>>(4+(i<<3))) & 0xF; uint32_t v1 = (w1>>( (i<<3))) & 0xF; uint32_t v2 = (w0>>( (i<<2))) & 0xF; bool bVisible = IsTriangleVisible(v0, v2, v1); LOG_UCODE(" (%d, %d, %d) %s", v0, v1, v2, bVisible ? "": "(clipped)"); if (bVisible) { DEBUG_DUMP_VERTEXES("Tri4_PerfectDark 1/2", v0, v1, v2); if (!bTrisAdded && CRender::g_pRender->IsTextureEnabled()) { PrepareTextures(); InitVertexTextureConstants(); } if( !bTrisAdded ) { CRender::g_pRender->SetCombinerAndBlender(); } bTrisAdded = true; PrepareTriangle(v0, v2, v1); } } w0 = *(uint32_t *)(rdram_u8 + dwPC+0); w1 = *(uint32_t *)(rdram_u8 + dwPC+4); dwPC += 8; #ifdef DEBUGGER } while (!(pauseAtNext && eventToPause==NEXT_TRIANGLE) && (w0>>24) == (uint8_t)RSP_TRI2); #else } while (((w0)>>24) == (uint8_t)RSP_TRI2); #endif gDlistStack[gDlistStackPointer].pc = dwPC-8; if (bTrisAdded) { CRender::g_pRender->DrawTriangles(); } DEBUG_TRIANGLE(TRACE0("Pause at GBI0 TRI4")); gRSP.DKRVtxCount=0; } //Nintro64 uses Sprite2d void RSP_RDP_Nothing(Gfx *gfx) { SP_Timing(RSP_RDP_Nothing); #ifdef DEBUGGER if( logWarning ) { TRACE0("Stack Trace"); for( int i=0; iwords.w0, gfx->words.w1); } DEBUGGER_PAUSE_AND_DUMP_COUNT_N(NEXT_UNKNOWN_OP, {TRACE0("Paused at unknown ucode\n");}) if( debuggerContinueWithUnknown ) { return; } #endif if( options.bEnableHacks ) return; gDlistStackPointer=-1; } void RSP_RDP_InsertMatrix(Gfx *gfx) { float fraction; UpdateCombinedMatrix(); if ((gfx->words.w0) & 0x20) { int x = ((gfx->words.w0) & 0x1F) >> 1; int y = x >> 2; x &= 3; fraction = ((gfx->words.w1)>>16)/65536.0f; gRSPworldProject.m[y][x] = (float)(int)gRSPworldProject.m[y][x]; gRSPworldProject.m[y][x] += fraction; fraction = ((gfx->words.w1)&0xFFFF)/65536.0f; gRSPworldProject.m[y][x+1] = (float)(int)gRSPworldProject.m[y][x+1]; gRSPworldProject.m[y][x+1] += fraction; } else { int x = ((gfx->words.w0) & 0x1F) >> 1; int y = x >> 2; x &= 3; float integer = (float)(short)((gfx->words.w1)>>16); fraction = (float)fabs(gRSPworldProject.m[y][x] - (int)gRSPworldProject.m[y][x]); if(integer >= 0.0f) gRSPworldProject.m[y][x] = integer + fraction; else gRSPworldProject.m[y][x] = integer - fraction; integer = (float)(short)((gfx->words.w1)&0xFFFF); fraction = (float)fabs(gRSPworldProject.m[y][x+1] - (int)gRSPworldProject.m[y][x+1]); if(integer >= 0.0f) gRSPworldProject.m[y][x+1] = integer + fraction; else gRSPworldProject.m[y][x+1] = integer - fraction; } gRSP.bMatrixIsUpdated = false; gRSP.bCombinedMatrixIsUpdated = true; #ifdef DEBUGGER if( pauseAtNext && eventToPause == NEXT_MATRIX_CMD ) { pauseAtNext = false; debuggerPause = true; DebuggerAppendMsg("Pause after insert matrix: %08X, %08X", gfx->words.w0, gfx->words.w1); } else { if( pauseAtNext && logMatrix ) { DebuggerAppendMsg("insert matrix: %08X, %08X", gfx->words.w0, gfx->words.w1); } } #endif } gles2n64/src/gDP.c000664 001750 001750 00000125103 12655644434 014672 0ustar00sergiosergio000000 000000 #include #include #include #include "Common.h" #include "gles2N64.h" #include "N64.h" #include "GBI.h" #include "RSP.h" #include "RDP.h" #include "gDP.h" #include "gSP.h" #include "Types.h" #include "Debug.h" #include "convert.h" #include "OpenGL.h" #include "CRC.h" #include "FrameBuffer.h" #include "DepthBuffer.h" #include "VI.h" #include "Config.h" #include "ShaderCombiner.h" #include "../../mupen64plus-core/src/rdp_common/gdp.h" gDPInfo gDP; void gDPSetOtherMode( u32 mode0, u32 mode1 ) { gDP.otherMode.h = mode0; gDP.otherMode.l = mode1; gDP.changed |= CHANGED_RENDERMODE | CHANGED_CYCLETYPE; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetOtherMode( %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s, %s | %s | %s%s%s%s%s | %s | %s%s%s );\n", AlphaDitherText[gDP.otherMode.alphaDither], ColorDitherText[gDP.otherMode.colorDither], CombineKeyText[gDP.otherMode.combineKey], TextureConvertText[gDP.otherMode.textureConvert], TextureFilterText[gDP.otherMode.textureFilter], TextureLUTText[gDP.otherMode.textureLUT], TextureLODText[gDP.otherMode.textureLOD], TextureDetailText[gDP.otherMode.textureDetail], TexturePerspText[gDP.otherMode.texturePersp], CycleTypeText[gDP.otherMode.cycleType], PipelineModeText[gDP.otherMode.pipelineMode], AlphaCompareText[gDP.otherMode.alphaCompare], DepthSourceText[gDP.otherMode.depthSource], gDP.otherMode.AAEnable ? "AA_EN | " : "", gDP.otherMode.depthCompare ? "Z_CMP | " : "", gDP.otherMode.depthUpdate ? "Z_UPD | " : "", gDP.otherMode.imageRead ? "IM_RD | " : "", CvgDestText[gDP.otherMode.cvgDest], DepthModeText[gDP.otherMode.depthMode], gDP.otherMode.cvgXAlpha ? "CVG_X_ALPHA | " : "", gDP.otherMode.alphaCvgSel ? "ALPHA_CVG_SEL | " : "", gDP.otherMode.forceBlender ? "FORCE_BL" : "" ); #endif } void gDPSetPrimDepth( u16 z, u16 dz ) { if (gSP.viewport.vscale[2] == 0) gDP.primDepth.z = _FIXED2FLOAT(_SHIFTR(z, 0, 15), 15); else gDP.primDepth.z = min(1.0f, max(-1.0f, (_FIXED2FLOAT(_SHIFTR(z, 0, 15), 15) - gSP.viewport.vtrans[2]) / gSP.viewport.vscale[2])); gDP.primDepth.deltaZ = _FIXED2FLOAT(_SHIFTR(dz, 0, 15), 15); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetPrimDepth( %f, %f );\n", gDP.primDepth.z, gDP.primDepth.deltaZ); #endif } void gDPSetTexturePersp( u32 enable ) { gDP.otherMode.texturePersp = enable & 1; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPSetTexturePersp( %s );\n", TexturePerspText[gDP.otherMode.texturePersp] ); #endif } void gDPSetCycleType( u32 type ) { gDP.otherMode.cycleType = type; gDP.changed |= CHANGED_CYCLETYPE; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetCycleType( %s );\n", CycleTypeText[gDP.otherMode.cycleType] ); #endif } void gDPSetTextureLUT( u32 mode ) { gDP.otherMode.textureLUT = mode & 3; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPSetTextureLUT( %s );\n", TextureLUTText[gDP.otherMode.textureLUT] ); #endif } void gDPSetCombineKey( u32 type ) { gDP.otherMode.combineKey = type; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_COMBINE, "gDPSetCombineKey( %s );\n", CombineKeyText[gDP.otherMode.combineKey] ); #endif } void gDPSetCombine( s32 muxs0, s32 muxs1 ) { gDP.combine.muxs0 = muxs0; gDP.combine.muxs1 = muxs1; gDP.changed |= CHANGED_COMBINE; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_COMBINE, "gDPSetCombine( %s, %s, %s, %s, %s, %s, %s, %s,\n", saRGBText[gDP.combine.saRGB0], sbRGBText[gDP.combine.sbRGB0], mRGBText[gDP.combine.mRGB0], aRGBText[gDP.combine.aRGB0], saAText[gDP.combine.saA0], sbAText[gDP.combine.sbA0], mAText[gDP.combine.mA0], aAText[gDP.combine.aA0] ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_COMBINE, " %s, %s, %s, %s, %s, %s, %s, %s );\n", saRGBText[gDP.combine.saRGB1], sbRGBText[gDP.combine.sbRGB1], mRGBText[gDP.combine.mRGB1], aRGBText[gDP.combine.aRGB1], saAText[gDP.combine.saA1], sbAText[gDP.combine.sbA1], mAText[gDP.combine.mA1], aAText[gDP.combine.aA1] ); #endif } void gDPSetColorImage( u32 format, u32 size, u32 width, u32 address ) { u32 addr = RSP_SegmentToPhysical( address ); if (gDP.colorImage.address != address || gDP.colorImage.width != width || gDP.colorImage.size != size) { u32 height = 1; if (width == VI.width) height = VI.height; #if 0 else if (!__RSP.bLLE && width == gDP.scissor.lrx && width == gSP.viewport.width) #else else if (width == gDP.scissor.lrx && width == gSP.viewport.width) #endif { height = max(gDP.scissor.lry, gSP.viewport.height); height = min(height, VI.height); } else if (width == gDP.scissor.lrx) height = gDP.scissor.lry; else if (width <= 64) height = width; else if (gSP.viewport.height > 0) height = gSP.viewport.height; #if 0 else if (!__RSP.bLLE && gSP.viewport.height > 0) height = gSP.viewport.height; #endif else height = gDP.scissor.lry; if (config.frameBufferEmulation.enable) { FrameBuffer_SaveBuffer(address, (u16)format, (u16)size, (u16)width, height, false); gDP.colorImage.height = 0; } else gDP.colorImage.height = height; } gDP.colorImage.format = format; gDP.colorImage.size = size; gDP.colorImage.width = width; gDP.colorImage.address = addr; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetColorImage( %s, %s, %i, 0x%08X );\n", ImageFormatText[gDP.colorImage.format], ImageSizeText[gDP.colorImage.size], gDP.colorImage.width, gDP.colorImage.address ); #endif } void gDPSetTextureImage( u32 format, u32 size, u32 width, u32 address ) { gDP.textureImage.format = format; gDP.textureImage.size = size; gDP.textureImage.width = width; gDP.textureImage.address = RSP_SegmentToPhysical( address ); gDP.textureImage.bpl = gDP.textureImage.width << gDP.textureImage.size >> 1; if (gSP.DMAOffsets.tex_offset != 0) { if (format == G_IM_FMT_RGBA) { u16 * t = (u16*)(gfx_info.RDRAM + gSP.DMAOffsets.tex_offset); gSP.DMAOffsets.tex_shift = t[gSP.DMAOffsets.tex_count ^ 1]; gDP.textureImage.address += gSP.DMAOffsets.tex_shift; } else { gSP.DMAOffsets.tex_offset = 0; gSP.DMAOffsets.tex_shift = 0; gSP.DMAOffsets.tex_count = 0; } } #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPSetTextureImage( %s, %s, %i, 0x%08X );\n", ImageFormatText[gDP.textureImage.format], ImageSizeText[gDP.textureImage.size], gDP.textureImage.width, gDP.textureImage.address ); #endif } /* TODO/FIXME - update */ void gDPSetDepthImage( u32 address ) { address = RSP_SegmentToPhysical(address); gDP.depthImageAddress = address; #if 0 depthBufferList().saveBuffer(address); #else DepthBuffer_SetBuffer(address); if (depthBuffer.current->cleared) OGL_ClearDepthBuffer(false); #endif #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetDepthImage( 0x%08X );\n", gDP.depthImageAddress ); #endif } void gDPSetEnvColor( u32 r, u32 g, u32 b, u32 a ) { gDP.envColor.r = r * 0.0039215689f; gDP.envColor.g = g * 0.0039215689f; gDP.envColor.b = b * 0.0039215689f; gDP.envColor.a = a * 0.0039215689f; ShaderCombiner_UpdateEnvColor(); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_COMBINE, "gDPSetEnvColor( %u, %u, %u, %u );\n", r, g, b, a ); #endif } void gDPSetBlendColor( u32 r, u32 g, u32 b, u32 a ) { gDP.blendColor.r = r * 0.0039215689f; gDP.blendColor.g = g * 0.0039215689f; gDP.blendColor.b = b * 0.0039215689f; gDP.blendColor.a = a * 0.0039215689f; ShaderCombiner_UpdateBlendColor(); #if 0 gDP.changed |= CHANGED_BLENDCOLOR; #endif #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetBlendColor( %u, %u, %u, %u );\n", r, g, b, a ); #endif } void gDPSetFogColor( u32 r, u32 g, u32 b, u32 a ) { gDP.fogColor.r = r * 0.0039215689f; gDP.fogColor.g = g * 0.0039215689f; gDP.fogColor.b = b * 0.0039215689f; gDP.fogColor.a = a * 0.0039215689f; ShaderCombiner_UpdateFogColor(); #if 0 gDP.changed |= CHANGED_FOGCOLOR; #endif #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetFogColor( %u, %u, %u, %u );\n", r, g, b, a ); #endif } void gDPSetFillColor( u32 c ) { gDP.fillColor.color = c; gDP.fillColor.z = (f32)_SHIFTR( c, 2, 14 ); gDP.fillColor.dz = (f32)_SHIFTR( c, 0, 2 ); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetFillColor( 0x%08X );\n", c ); #endif } void gDPGetFillColor(f32 _fillColor[4]) { const u32 c = gDP.fillColor.color; if (gDP.colorImage.size < 3) { _fillColor[0] = _SHIFTR( c, 11, 5 ) * 0.032258064f; _fillColor[1] = _SHIFTR( c, 6, 5 ) * 0.032258064f; _fillColor[2] = _SHIFTR( c, 1, 5 ) * 0.032258064f; _fillColor[3] = (f32)_SHIFTR( c, 0, 1 ); } else { _fillColor[0] = _SHIFTR( c, 24, 8 ) * 0.0039215686f; _fillColor[1] = _SHIFTR( c, 16, 8 ) * 0.0039215686f; _fillColor[2] = _SHIFTR( c, 8, 8 ) * 0.0039215686f; _fillColor[3] = _SHIFTR( c, 0, 8 ) * 0.0039215686f; } } void gDPSetPrimColor( u32 m, u32 l, u32 r, u32 g, u32 b, u32 a ) { gDP.primColor.m = m * 0.0312500000; gDP.primColor.l = l * 0.0039215689f; gDP.primColor.r = r * 0.0039215689f; gDP.primColor.g = g * 0.0039215689f; gDP.primColor.b = b * 0.0039215689f; gDP.primColor.a = a * 0.0039215689f; ShaderCombiner_UpdatePrimColor(); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_COMBINE, "gDPSetPrimColor( %u, %u, %u, %u, %u, %u );\n", m, l, r, g, b, a ); #endif } void gDPSetTile( u32 format, u32 size, u32 line, u32 tmem, u32 tile, u32 palette, u32 cmt, u32 cms, u32 maskt, u32 masks, u32 shiftt, u32 shifts ) { gDP.tiles[tile].format = format; gDP.tiles[tile].size = size; gDP.tiles[tile].line = line; gDP.tiles[tile].tmem = tmem; gDP.tiles[tile].palette = palette; gDP.tiles[tile].cmt = cmt; gDP.tiles[tile].cms = cms; gDP.tiles[tile].maskt = maskt; gDP.tiles[tile].masks = masks; gDP.tiles[tile].shiftt = shiftt; gDP.tiles[tile].shifts = shifts; if (!gDP.tiles[tile].masks) gDP.tiles[tile].clamps = 1; if (!gDP.tiles[tile].maskt) gDP.tiles[tile].clampt = 1; if (tile == gSP.texture.tile || tile == gSP.texture.tile + 1) { u32 nTile = 7; while(gDP.tiles[nTile].tmem != tmem && nTile > gSP.texture.tile + 1) --nTile; if (nTile > gSP.texture.tile + 1) { gDP.tiles[tile].textureMode = gDP.tiles[nTile].textureMode; gDP.tiles[tile].loadType = gDP.tiles[nTile].loadType; gDP.tiles[tile].frameBuffer = gDP.tiles[nTile].frameBuffer; gDP.tiles[tile].imageAddress = gDP.tiles[nTile].imageAddress; } } #if 0 gDP.changed |= CHANGED_TILE; #endif #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPSetTile( %s, %s, %i, %i, %i, %i, %s%s, %s%s, %i, %i, %i, %i );\n", ImageFormatText[format], ImageSizeText[size], line, tmem, tile, palette, cmt & G_TX_MIRROR ? "G_TX_MIRROR" : "G_TX_NOMIRROR", cmt & G_TX_CLAMP ? " | G_TX_CLAMP" : "", cms & G_TX_MIRROR ? "G_TX_MIRROR" : "G_TX_NOMIRROR", cms & G_TX_CLAMP ? " | G_TX_CLAMP" : "", maskt, masks, shiftt, shifts ); #endif } void gDPSetTileSize( u32 tile, u32 uls, u32 ult, u32 lrs, u32 lrt ) { gDP.tiles[tile].uls = _SHIFTR( uls, 2, 10 ); gDP.tiles[tile].ult = _SHIFTR( ult, 2, 10 ); gDP.tiles[tile].lrs = _SHIFTR( lrs, 2, 10 ); gDP.tiles[tile].lrt = _SHIFTR( lrt, 2, 10 ); gDP.tiles[tile].fuls = _FIXED2FLOAT( uls, 2 ); gDP.tiles[tile].fult = _FIXED2FLOAT( ult, 2 ); gDP.tiles[tile].flrs = _FIXED2FLOAT( lrs, 2 ); gDP.tiles[tile].flrt = _FIXED2FLOAT( lrt, 2 ); gDP.changed |= CHANGED_TILE; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPSetTileSize( %u, %.2f, %.2f, %.2f, %.2f );\n", tile, gDP.tiles[tile].fuls, gDP.tiles[tile].fult, gDP.tiles[tile].flrs, gDP.tiles[tile].flrt ); #endif } static bool CheckForFrameBufferTexture(u32 _address, u32 _bytes) { int nTile; bool bRes = false; gDP.loadTile->textureMode = TEXTUREMODE_NORMAL; gDP.loadTile->frameBuffer = NULL; gDP.changed |= CHANGED_TMEM; if (!config.frameBufferEmulation.enable) return false; struct FrameBuffer *pBuffer = FrameBuffer_FindBuffer(_address); #if 0 FrameBuffer *pBuffer = fbList.findBuffer(_address); #endif bRes = pBuffer != NULL; if (bRes) { u32 texEndAddress; if ((config.generalEmulation.hacks & hack_blurPauseScreen) != 0) { #ifdef NEW if (gDP.colorImage.address == gDP.depthImageAddress && pBuffer->m_RdramCrc != 0) { memcpy(RDRAM + gDP.depthImageAddress, RDRAM + pBuffer->m_startAddress, (pBuffer->m_width* pBuffer->m_height) << pBuffer->m_size >> 1); pBuffer->m_RdramCrc = 0; frameBufferList().getCurrent()->m_isPauseScreen = true; } if (pBuffer->m_isPauseScreen) bRes = false; #endif } #ifdef NEW if (pBuffer->m_cfb) { FrameBuffer_RemoveBuffer(pBuffer->m_startAddress); bRes = false; } #endif #if 0 if ((config.generalEmulation.hacks & hack_noDepthFrameBuffers) != 0 && pBuffer->m_isDepthBuffer) #else if ((config.generalEmulation.hacks & hack_noDepthFrameBuffers) != 0 /* && pBuffer->m_isDepthBuffer */) #endif { FrameBuffer_RemoveBuffer(pBuffer->m_startAddress); bRes = false; } texEndAddress = _address + _bytes - 1; if (_address > pBuffer->m_startAddress && texEndAddress > (pBuffer->m_endAddress + (pBuffer->m_width << pBuffer->m_size >> 1))) bRes = false; if (bRes && gDP.loadTile->loadType == LOADTYPE_TILE && gDP.textureImage.width != pBuffer->m_width && gDP.textureImage.size != pBuffer->m_size) bRes = false; #ifdef NEW if (bRes && pBuffer->m_validityChecked != __RSP.DList) { if (pBuffer->m_cleared) { const u32 color = pBuffer->m_fillcolor & 0xFFFEFFFE; u32 wrongPixels = 0; for (u32 i = pBuffer->m_startAddress + 4; i < pBuffer->m_endAddress; i += 4) { if (((*(u32*)&RDRAM[i]) & 0xFFFEFFFE) != color) ++wrongPixels; } bRes = wrongPixels < (pBuffer->m_endAddress - pBuffer->m_startAddress)/100; // treshold level 1% if (bRes) pBuffer->m_validityChecked = __RSP.DList; else frameBufferList().removeBuffer(pBuffer->m_startAddress); } else if (pBuffer->m_RdramCrc != 0) { const u32 crc = textureCRC(RDRAM + pBuffer->m_startAddress, pBuffer->m_height, pBuffer->m_width << pBuffer->m_size >> 1); bRes = (pBuffer->m_RdramCrc == crc); if (bRes) pBuffer->m_validityChecked = __RSP.DList; else frameBufferList().removeBuffer(pBuffer->m_startAddress); } } #endif if (bRes) { #ifdef NEW pBuffer->m_pLoadTile = gDP.loadTile; #endif gDP.loadTile->frameBuffer = pBuffer; gDP.loadTile->textureMode = TEXTUREMODE_FRAMEBUFFER; } } for (nTile = gSP.texture.tile; nTile < 6; ++nTile) { if (gDP.tiles[nTile].tmem == gDP.loadTile->tmem) { gDPTile *curTile = (gDPTile*)&gDP.tiles[nTile]; curTile->textureMode = gDP.loadTile->textureMode; curTile->loadType = gDP.loadTile->loadType; curTile->imageAddress = gDP.loadTile->imageAddress; curTile->frameBuffer = gDP.loadTile->frameBuffer; } } return bRes; } //**************************************************************** // LoadTile for 32bit RGBA texture // Based on sources of angrylion's software plugin. // void gDPLoadTile32b(u32 uls, u32 ult, u32 lrs, u32 lrt) { u32 i, j; const u32 width = lrs - uls + 1; const u32 height = lrt - ult + 1; const u32 line = gDP.loadTile->line << 2; const u32 tbase = gDP.loadTile->tmem << 2; const u32 addr = gDP.textureImage.address >> 2; const u32 * src = (const u32*)gfx_info.RDRAM; u16 * tmem16 = (u16*)TMEM; u32 c, ptr, tline, s, xorval; for (j = 0; j < height; ++j) { tline = tbase + line * j; s = ((j + ult) * gDP.textureImage.width) + uls; xorval = (j & 1) ? 3 : 1; for (i = 0; i < width; ++i) { c = src[addr + s + i]; ptr = ((tline + i) ^ xorval) & 0x3ff; tmem16[ptr] = c >> 16; tmem16[ptr | 0x400] = c & 0xffff; } } } void gDPLoadTile(u32 tile, u32 uls, u32 ult, u32 lrs, u32 lrt) { gDPSetTileSize( tile, uls, ult, lrs, lrt ); gDP.loadTile = &gDP.tiles[tile]; gDP.loadTile->loadType = LOADTYPE_TILE; gDP.loadTile->imageAddress = gDP.textureImage.address; const u32 width = (gDP.loadTile->lrs - gDP.loadTile->uls + 1) & 0x03FF; u32 height = (gDP.loadTile->lrt - gDP.loadTile->ult + 1) & 0x03FF; struct gDPLoadTileInfo *info = (struct gDPLoadTileInfo*)&gDP.loadInfo[gDP.loadTile->tmem]; info->texAddress = gDP.loadTile->imageAddress; info->uls = gDP.loadTile->uls; info->ult = gDP.loadTile->ult; info->width = gDP.loadTile->masks != 0 ? (u16)min(width, 1U<masks) : (u16)width; info->height = gDP.loadTile->maskt != 0 ? (u16)min(height, 1U<maskt) : (u16)height; info->texWidth = gDP.textureImage.width; info->size = gDP.textureImage.size; info->loadType = LOADTYPE_TILE; if (gDP.loadTile->line == 0) return; u32 address = gDP.textureImage.address + gDP.loadTile->ult * gDP.textureImage.bpl + (gDP.loadTile->uls << gDP.textureImage.size >> 1); if ((address + height * gDP.textureImage.bpl) > RDRAMSize) return; const u32 bpl = gDP.loadTile->line << 3; u32 bpl2 = bpl; if (gDP.loadTile->lrs > gDP.textureImage.width) bpl2 = (gDP.textureImage.width - gDP.loadTile->uls); u32 height2 = height; if (gDP.loadTile->lrt > gDP.scissor.lry) height2 = gDP.scissor.lry - gDP.loadTile->ult; if (CheckForFrameBufferTexture(address, bpl2*height2)) return; if (gDP.loadTile->size == G_IM_SIZ_32b) gDPLoadTile32b(gDP.loadTile->uls, gDP.loadTile->ult, gDP.loadTile->lrs, gDP.loadTile->lrt); else { u32 y; u32 tmemAddr = gDP.loadTile->tmem; const u32 line = gDP.loadTile->line; for (y = 0; y < height; ++y) { UnswapCopyWrap(gfx_info.RDRAM, address, (u8*)TMEM, tmemAddr << 3, 0xFFF, bpl); if (y & 1) DWordInterleaveWrap((u32*)TMEM, tmemAddr << 1, 0x3FF, line); address += gDP.textureImage.bpl; tmemAddr += line; } } #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPLoadTile( %i, %i, %i, %i, %i );\n", tile, gDP.loadTile->uls, gDP.loadTile->ult, gDP.loadTile->lrs, gDP.loadTile->lrt ); #endif } //**************************************************************** // LoadBlock for 32bit RGBA texture // Based on sources of angrylion's software plugin. // void gDPLoadBlock32(u32 uls,u32 lrs, u32 dxt) { const u32 * src = (const u32*)gfx_info.RDRAM; const u32 tb = gDP.loadTile->tmem << 2; const u32 line = gDP.loadTile->line << 2; u16 *tmem16 = (u16*)TMEM; u32 addr = gDP.loadTile->imageAddress >> 2; u32 width = (lrs - uls + 1) << 2; if (width == 4) // lr_s == 0, 1x1 texture width = 1; else if (width & 7) width = (width & (~7)) + 8; if (dxt != 0) { u32 i; u32 j = 0; u32 t = 0; u32 oldt = 0; u32 ptr; u32 c = 0; for (i = 0; i < width; i += 2) { oldt = t; t = ((j >> 11) & 1) ? 3 : 1; if (t != oldt) i += line; ptr = ((tb + i) ^ t) & 0x3ff; c = src[addr + i]; tmem16[ptr] = c >> 16; tmem16[ptr | 0x400] = c & 0xffff; ptr = ((tb + i + 1) ^ t) & 0x3ff; c = src[addr + i + 1]; tmem16[ptr] = c >> 16; tmem16[ptr | 0x400] = c & 0xffff; j += dxt; } } else { u32 c, ptr, i; for (i = 0; i < width; i++) { ptr = ((tb + i) ^ 1) & 0x3ff; c = src[addr + i]; tmem16[ptr] = c >> 16; tmem16[ptr | 0x400] = c & 0xffff; } } } void gDPLoadBlock(u32 tile, u32 uls, u32 ult, u32 lrs, u32 dxt) { gDPSetTileSize( tile, uls, ult, lrs, dxt ); gDP.loadTile = &gDP.tiles[tile]; gDP.loadTile->loadType = LOADTYPE_BLOCK; if (gSP.DMAOffsets.tex_offset != 0) { if (gSP.DMAOffsets.tex_shift % (((lrs>>2) + 1) << 3)) { gDP.textureImage.address -= gSP.DMAOffsets.tex_shift; gSP.DMAOffsets.tex_offset = 0; gSP.DMAOffsets.tex_shift = 0; gSP.DMAOffsets.tex_count = 0; } else ++gSP.DMAOffsets.tex_count; } gDP.loadTile->imageAddress = gDP.textureImage.address; struct gDPLoadTileInfo *info = (struct gDPLoadTileInfo*)&gDP.loadInfo[gDP.loadTile->tmem]; info->texAddress = gDP.loadTile->imageAddress; info->width = gDP.loadTile->lrs; info->dxt = dxt; info->size = gDP.textureImage.size; info->loadType = LOADTYPE_BLOCK; u32 bytes = (lrs - uls + 1) << gDP.loadTile->size >> 1; if ((bytes & 7) != 0) bytes = (bytes & (~7)) + 8; u32 address = gDP.textureImage.address + ult * gDP.textureImage.bpl + (uls << gDP.textureImage.size >> 1); if (bytes == 0 || (address + bytes) > RDRAMSize) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR | DEBUG_TEXTURE, "// Attempting to load texture block out of range\n" ); DebugMsg(DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPLoadBlock( %i, %i, %i, %i, %i );\n", tile, uls, ult, lrs, dxt ); #endif return; } gDP.loadTile->textureMode = TEXTUREMODE_NORMAL; gDP.loadTile->frameBuffer = NULL; CheckForFrameBufferTexture(address, bytes); // Load data to TMEM even if FB texture is found. See comment to texturedRectDepthBufferCopy if (gDP.loadTile->size == G_IM_SIZ_32b) gDPLoadBlock32(gDP.loadTile->uls, gDP.loadTile->lrs, dxt); else if (gDP.loadTile->format == G_IM_FMT_YUV) memcpy(TMEM, &gfx_info.RDRAM[address], bytes); // HACK! else { u32 tmemAddr = gDP.loadTile->tmem; if (dxt > 0) { u32 y; u32 line = (2047 + dxt) / dxt; u32 bpl = line << 3; u32 height = bytes / bpl; for (y = 0; y < height; ++y) { UnswapCopyWrap(gfx_info.RDRAM, address, (u8*)TMEM, tmemAddr << 3, 0xFFF, bpl); if (y & 1) DWordInterleaveWrap((u32*)TMEM, tmemAddr << 1, 0x3FF, line); address += bpl; tmemAddr += line; } } else UnswapCopyWrap(gfx_info.RDRAM, address, (u8*)TMEM, tmemAddr << 3, 0xFFF, bytes); } #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPLoadBlock( %i, %i, %i, %i, %i );\n", tile, uls, ult, lrs, dxt ); #endif } void gDPLoadTLUT( u32 tile, u32 uls, u32 ult, u32 lrs, u32 lrt ) { int i; u32 address; u16 count, pal, *dest, j; gDPSetTileSize( tile, uls, ult, lrs, lrt ); if (gDP.tiles[tile].tmem < 256) return; count = (u16)((gDP.tiles[tile].lrs - gDP.tiles[tile].uls + 1) * (gDP.tiles[tile].lrt - gDP.tiles[tile].ult + 1)); address = gDP.textureImage.address + gDP.tiles[tile].ult * gDP.textureImage.bpl + (gDP.tiles[tile].uls << gDP.textureImage.size >> 1); pal = (u16)((gDP.tiles[tile].tmem - 256) >> 4); dest = (u16*)&TMEM[gDP.tiles[tile].tmem]; i = 0; while (i < count) { for (j = 0; (j < 16) && (i < count); ++j, ++i) { *dest = swapword(*(u16*)(gfx_info.RDRAM + (address ^ 2))); address += 2; dest += 4; } /* TODO/FIXME - should be CRC_CalculatePalette here instead */ gDP.paletteCRC16[pal] = Hash_Calculate(0xFFFFFFFF, &TMEM[256 + (pal << 4)], 16); ++pal; } gDP.paletteCRC256 = Hash_Calculate(0xFFFFFFFF, gDP.paletteCRC16, 64); #ifdef TEXTURE_FILTER if (TFH.isInited()) { const u16 start = gDP.tiles[tile].tmem - 256; // starting location in the palettes u16 *spal = (u16*)(gfx_info.RDRAM + gDP.textureImage.address); memcpy((u8*)(gDP.TexFilterPalette + start), spal, count<<1); } #endif gDP.changed |= CHANGED_TMEM; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPLoadTLUT( %i, %i, %i, %i, %i );\n", tile, gDP.tiles[tile].uls, gDP.tiles[tile].ult, gDP.tiles[tile].lrs, gDP.tiles[tile].lrt ); #endif } void gDPSetScissor( u32 mode, f32 ulx, f32 uly, f32 lrx, f32 lry ) { gDP.scissor.mode = mode; gDP.scissor.ulx = ulx; gDP.scissor.uly = uly; gDP.scissor.lrx = lrx; gDP.scissor.lry = lry; gDP.changed |= CHANGED_SCISSOR; #if 0 frameBufferList().correctHeight(); #endif #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_IGNORED, "gDPSetScissor( %s, %.2f, %.2f, %.2f, %.2f );\n", ScissorModeText[gDP.scissor.mode], gDP.scissor.ulx, gDP.scissor.uly, gDP.scissor.lrx, gDP.scissor.lry ); #endif } const bool g_bDepthClearOnly = false; void gDPFillRDRAM(u32 address, s32 ulx, s32 uly, s32 lrx, s32 lry, u32 width, u32 size, u32 color, bool scissor) { u32 y, x; if (g_bDepthClearOnly && color != DepthClearColor) return; struct FrameBuffer * pCurrentBuffer = FrameBuffer_GetCurrent(); if (pCurrentBuffer != NULL) { #ifdef NEW pCurrentBuffer->m_cleared = true; pCurrentBuffer->m_fillcolor = color; #endif } if (scissor) { ulx = min(max((float)ulx, gDP.scissor.ulx), gDP.scissor.lrx); lrx = min(max((float)lrx, gDP.scissor.ulx), gDP.scissor.lrx); uly = min(max((float)uly, gDP.scissor.uly), gDP.scissor.lry); lry = min(max((float)lry, gDP.scissor.uly), gDP.scissor.lry); } const u32 stride = width << size >> 1; const u32 lowerBound = address + lry*stride; if (lowerBound > RDRAMSize) lry -= (lowerBound - RDRAMSize) / stride; u32 ci_width_in_dwords = width >> (3 - size); ulx >>= (3 - size); lrx >>= (3 - size); u32 * dst = (u32*)(gfx_info.RDRAM + address); dst += uly * ci_width_in_dwords; for (y = uly; y < lry; ++y) { for (x = ulx; x < lrx; ++x) dst[x] = color; dst += ci_width_in_dwords; } } void gDPFillRectangle( s32 ulx, s32 uly, s32 lrx, s32 lry ) { f32 fillColor[4]; DepthBuffer *buffer = NULL; if (gDP.otherMode.cycleType == G_CYC_FILL) { ++lrx; ++lry; } else if (lry == uly) ++lry; buffer = (DepthBuffer*)DepthBuffer_FindBuffer( gDP.colorImage.address ); if (buffer) buffer->cleared = TRUE; if (gDP.depthImageAddress == gDP.colorImage.address) { /* Game may use depth texture as auxilary color texture. Example: Mario Tennis * If color is not depth clear color, that is most likely the case */ if (gDP.fillColor.color == DepthClearColor) { gDPFillRDRAM(gDP.colorImage.address, ulx, uly, lrx, lry, gDP.colorImage.width, gDP.colorImage.size, gDP.fillColor.color, true); OGL_ClearDepthBuffer(lrx - ulx >= gDP.scissor.lrx - gDP.scissor.ulx && lry - uly >= gDP.scissor.lry - gDP.scissor.uly); return; } } else if (gDP.fillColor.color == DepthClearColor && gDP.otherMode.cycleType == G_CYC_FILL) { #ifdef NEW depthBufferList().saveBuffer(gDP.colorImage.address); #endif gDPFillRDRAM(gDP.colorImage.address, ulx, uly, lrx, lry, gDP.colorImage.width, gDP.colorImage.size, gDP.fillColor.color, true); OGL_ClearDepthBuffer(lrx - ulx == gDP.scissor.lrx - gDP.scissor.ulx && lry - uly == gDP.scissor.lry - gDP.scissor.uly); return; } #ifdef NEW frameBufferList().setBufferChanged(); #endif gDPGetFillColor(fillColor); if (gDP.otherMode.cycleType == G_CYC_FILL) { if ((ulx == 0) && (uly == 0) && (lrx == gDP.scissor.lrx) && (lry == gDP.scissor.lry)) { gDPFillRDRAM(gDP.colorImage.address, ulx, uly, lrx, lry, gDP.colorImage.width, gDP.colorImage.size, gDP.fillColor.color, true); if ((*gfx_info.VI_STATUS_REG & 8) != 0) { fillColor[0] = sqrtf(fillColor[0]); fillColor[1] = sqrtf(fillColor[1]); fillColor[2] = sqrtf(fillColor[2]); } OGL_ClearColorBuffer(&fillColor[0]); return; } } OGL_DrawRect( ulx, uly, lrx, lry, fillColor); /* TODO/FIXME - remove? */ if (depthBuffer.current) depthBuffer.current->cleared = FALSE; if (gDP.otherMode.cycleType == G_CYC_FILL) { if (lry > (u32)gDP.scissor.lry) gDP.colorImage.height = (u32)max( gDP.colorImage.height, (unsigned int)gDP.scissor.lry ); else gDP.colorImage.height = (u32)max((s32)gDP.colorImage.height, lry); } else gDP.colorImage.height = max( gDP.colorImage.height, (unsigned int)lry ); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPFillRectangle( %i, %i, %i, %i );\n", ulx, uly, lrx, lry ); #endif } void gDPSetConvert( s32 k0, s32 k1, s32 k2, s32 k3, s32 k4, s32 k5 ) { gDP.convert.k0 = SIGN(k0, 9); gDP.convert.k1 = SIGN(k1, 9); gDP.convert.k2 = SIGN(k2, 9); gDP.convert.k3 = SIGN(k3, 9); gDP.convert.k4 = SIGN(k4, 9); gDP.convert.k5 = SIGN(k5, 9); ShaderCombiner_UpdateConvertColor(); } void gDPSetKeyR( u32 cR, u32 sR, u32 wR ) { gDP.key.center.r = cR * 0.0039215689f;; gDP.key.scale.r = sR * 0.0039215689f;; gDP.key.width.r = wR * 0.0039215689f;; } void gDPSetKeyGB(u32 cG, u32 sG, u32 wG, u32 cB, u32 sB, u32 wB ) { gDP.key.center.g = cG * 0.0039215689f;; gDP.key.scale.g = sG * 0.0039215689f;; gDP.key.width.g = wG * 0.0039215689f;; gDP.key.center.b = cB * 0.0039215689f;; gDP.key.scale.b = sB * 0.0039215689f;; gDP.key.width.b = wB * 0.0039215689f;; ShaderCombiner_UpdateKeyColor(); } void gDPTextureRectangle( f32 ulx, f32 uly, f32 lrx, f32 lry, s32 tile, f32 s, f32 t, f32 dsdx, f32 dtdy ) { struct TexturedRectParams params; f32 lrs, lrt; float tmp; if (gDP.otherMode.cycleType == G_CYC_COPY) { dsdx = 1.0f; lrx += 1.0f; lry += 1.0f; } lry = max(lry, uly + 1.0f); gDPTile *textureTileOrg[2]; textureTileOrg[0] = gSP.textureTile[0]; textureTileOrg[1] = gSP.textureTile[1]; gSP.textureTile[0] = &gDP.tiles[tile]; gSP.textureTile[1] = &gDP.tiles[(tile + 1) & 7]; if (gDP.loadTile->textureMode == TEXTUREMODE_NORMAL) gDP.loadTile->textureMode = TEXTUREMODE_TEXRECT; if (gSP.textureTile[1]->textureMode == TEXTUREMODE_NORMAL) gSP.textureTile[1]->textureMode = TEXTUREMODE_TEXRECT; // HACK ALERT! if (((int)(s) == 512) && (gDP.colorImage.width < 512)) s = 0.0f; if (__RSP.cmd == G_TEXRECTFLIP) { lrs = s + (lry - uly - 1) * dtdy; lrt = t + (lrx - ulx - 1) * dsdx; } else { lrs = s + (lrx - ulx - 1) * dsdx; lrt = t + (lry - uly - 1) * dtdy; } gDP.texRect.width = (unsigned int)(max( lrs, s ) + dsdx); gDP.texRect.height = (unsigned int)(max( lrt, t ) + dtdy); params.ulx = ulx; params.uly = uly; params.lrx = lrx; params.lry = lry; params.uls = s; params.ult = t; params.lrs = lrs; params.lrt = lrt; params.flip = (__RSP.cmd == G_TEXRECTFLIP); OGL_DrawTexturedRect(¶ms); gSP.textureTile[0] = textureTileOrg[0]; gSP.textureTile[1] = textureTileOrg[1]; #if 1 if (depthBuffer.current) depthBuffer.current->cleared = FALSE; gDP.colorImage.changed = TRUE; #else frameBufferList().setBufferChanged(); #endif if (gDP.colorImage.width < 64) gDP.colorImage.height = (u32)max( (f32)gDP.colorImage.height, lry ); else gDP.colorImage.height = (unsigned int)(max( gDP.colorImage.height, gDP.scissor.lry )); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPTextureRectangle( %f, %f, %f, %f, %i, %f, %f, %f, %f );\n", ulx, uly, lrx, lry, tile, s, t, dsdx, dtdy ); #endif } void gDPTextureRectangleFlip( f32 ulx, f32 uly, f32 lrx, f32 lry, s32 tile, f32 s, f32 t, f32 dsdx, f32 dtdy ) { gDPTextureRectangle( ulx, uly, lrx, lry, tile, s, t, dsdx, dtdy ); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPTextureRectangleFlip( %f, %f, %f, %f, %i, %f, %f, %f, %f);\n", ulx, uly, lrx, lry, tile, s, t, dsdx, dtdy ); #endif } void gDPFullSync(void) { #if 0 if (config.frameBufferEmulation.copyAuxToRDRAM != 0) { frameBufferList().copyAux(); frameBufferList().removeAux(); } const bool sync = config.frameBufferEmulation.copyToRDRAM == Config::ctSync; if (config.frameBufferEmulation.copyToRDRAM != Config::ctDisable) FrameBuffer_CopyToRDRAM(gDP.colorImage.address, sync); if (__RSP.bLLE) { if (config.frameBufferEmulation.copyDepthToRDRAM != Config::ctDisable) FrameBuffer_CopyDepthBuffer(gDP.colorImage.address); } #endif *gfx_info.MI_INTR_REG |= MI_INTR_DP; if (gfx_info.CheckInterrupts) gfx_info.CheckInterrupts(); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPFullSync();\n" ); #endif } void gDPTileSync(void) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_IGNORED | DEBUG_TEXTURE, "gDPTileSync();\n" ); #endif } void gDPPipeSync(void) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_IGNORED, "gDPPipeSync();\n" ); #endif } void gDPLoadSync(void) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_IGNORED, "gDPLoadSync();\n" ); #endif } void gDPNoOp(void) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_IGNORED, "gDPNoOp();\n" ); #endif } /******************************************* * Low level triangle * ******************************************* * based on sources of ziggy's z64 * *******************************************/ #define XSCALE(x) ((float)(x)/(1<<18)) #define YSCALE(y) ((float)(y)/(1<<2)) #define ZSCALE(z) ((gDP.otherMode.depthSource == G_ZS_PRIM) ? (gDP.primDepth.z) : ((float)((u32)((z))) / 0xffff0000)) #define PERSP_EN (gDP.otherMode.texturePersp != 0) #define WSCALE(z) 1.0f/(PERSP_EN? ((float)((u32)(z) + 0x10000)/0xffff0000) : 1.0f) #define CSCALE(c) ((((c)>0x3ff0000? 0x3ff0000:((c)<0? 0 : (c)))>>18)*0.0039215689f) #define _PERSP(w) ( w ) #define PERSP(s, w) ( ((s64)(s) << 20) / (_PERSP(w)? _PERSP(w):1) ) #define SSCALE(s, _w) (PERSP_EN? (float)(PERSP(s, _w))/(1 << 10) : (float)(s)/(1<<21)) #define TSCALE(s, w) (PERSP_EN? (float)(PERSP(s, w))/(1 << 10) : (float)(s)/(1<<21)) void gDPLLETriangle(u32 _w1, u32 _w2, int _shade, int _texture, int _zbuffer, u32 * _pRdpCmd) { const u32 tile = _SHIFTR(_w1, 16, 3); gDPTile *textureTileOrg[2]; textureTileOrg[0] = gSP.textureTile[0]; textureTileOrg[1] = gSP.textureTile[1]; gSP.textureTile[0] = &gDP.tiles[tile]; gSP.textureTile[1] = &gDP.tiles[(tile + 1) & 7]; int j; int xleft, xright, xleft_inc, xright_inc; int r, g, b, a, z, s, t, w; int drdx = 0, dgdx = 0, dbdx = 0, dadx = 0, dzdx = 0, dsdx = 0, dtdx = 0, dwdx = 0; int drde = 0, dgde = 0, dbde = 0, dade = 0, dzde = 0, dsde = 0, dtde = 0, dwde = 0; int flip = (_w1 & 0x800000) ? 1 : 0; s32 yl, ym, yh; s32 xl, xm, xh; s32 dxldy, dxhdy, dxmdy; u32 w3, w4, w5, w6, w7, w8; u32 * shade_base = _pRdpCmd + 8; u32 * texture_base = _pRdpCmd + 8; u32 * zbuffer_base = _pRdpCmd + 8; if (_shade != 0) { texture_base += 16; zbuffer_base += 16; } if (_texture != 0) { zbuffer_base += 16; } w3 = _pRdpCmd[2]; w4 = _pRdpCmd[3]; w5 = _pRdpCmd[4]; w6 = _pRdpCmd[5]; w7 = _pRdpCmd[6]; w8 = _pRdpCmd[7]; yl = (_w1 & 0x3fff); ym = ((_w2 >> 16) & 0x3fff); yh = ((_w2 >> 0) & 0x3fff); xl = (s32)(w3); xh = (s32)(w5); xm = (s32)(w7); dxldy = (s32)(w4); dxhdy = (s32)(w6); dxmdy = (s32)(w8); if (yl & (0x800<<2)) yl |= 0xfffff000<<2; if (ym & (0x800<<2)) ym |= 0xfffff000<<2; if (yh & (0x800<<2)) yh |= 0xfffff000<<2; yh &= ~3; r = 0xff; g = 0xff; b = 0xff; a = 0xff; z = 0xffff0000; s = 0; t = 0; w = 0x30000; if (_shade != 0) { r = (shade_base[0] & 0xffff0000) | ((shade_base[+4 ] >> 16) & 0x0000ffff); g = ((shade_base[0 ] << 16) & 0xffff0000) | (shade_base[4 ] & 0x0000ffff); b = (shade_base[1 ] & 0xffff0000) | ((shade_base[5 ] >> 16) & 0x0000ffff); a = ((shade_base[1 ] << 16) & 0xffff0000) | (shade_base[5 ] & 0x0000ffff); drdx = (shade_base[2 ] & 0xffff0000) | ((shade_base[6 ] >> 16) & 0x0000ffff); dgdx = ((shade_base[2 ] << 16) & 0xffff0000) | (shade_base[6 ] & 0x0000ffff); dbdx = (shade_base[3 ] & 0xffff0000) | ((shade_base[7 ] >> 16) & 0x0000ffff); dadx = ((shade_base[3 ] << 16) & 0xffff0000) | (shade_base[7 ] & 0x0000ffff); drde = (shade_base[8 ] & 0xffff0000) | ((shade_base[12] >> 16) & 0x0000ffff); dgde = ((shade_base[8 ] << 16) & 0xffff0000) | (shade_base[12] & 0x0000ffff); dbde = (shade_base[9 ] & 0xffff0000) | ((shade_base[13] >> 16) & 0x0000ffff); dade = ((shade_base[9 ] << 16) & 0xffff0000) | (shade_base[13] & 0x0000ffff); } if (_texture != 0) { s = (texture_base[0 ] & 0xffff0000) | ((texture_base[4 ] >> 16) & 0x0000ffff); t = ((texture_base[0 ] << 16) & 0xffff0000) | (texture_base[4 ] & 0x0000ffff); w = (texture_base[1 ] & 0xffff0000) | ((texture_base[5 ] >> 16) & 0x0000ffff); // w = abs(w); dsdx = (texture_base[2 ] & 0xffff0000) | ((texture_base[6 ] >> 16) & 0x0000ffff); dtdx = ((texture_base[2 ] << 16) & 0xffff0000) | (texture_base[6 ] & 0x0000ffff); dwdx = (texture_base[3 ] & 0xffff0000) | ((texture_base[7 ] >> 16) & 0x0000ffff); dsde = (texture_base[8 ] & 0xffff0000) | ((texture_base[12] >> 16) & 0x0000ffff); dtde = ((texture_base[8 ] << 16) & 0xffff0000) | (texture_base[12] & 0x0000ffff); dwde = (texture_base[9 ] & 0xffff0000) | ((texture_base[13] >> 16) & 0x0000ffff); } if (_zbuffer != 0) { z = zbuffer_base[0]; dzdx = zbuffer_base[1]; dzde = zbuffer_base[2]; } xh <<= 2; xm <<= 2; xl <<= 2; r <<= 2; g <<= 2; b <<= 2; a <<= 2; dsde >>= 2; dtde >>= 2; dsdx >>= 2; dtdx >>= 2; dzdx >>= 2; dzde >>= 2; dwdx >>= 2; dwde >>= 2; SPVertex * vtx0 = (SPVertex*)&OGL.triangles.vertices[0]; SPVertex * vtx = (SPVertex*)vtx0; xleft = xm; xright = xh; xleft_inc = dxmdy; xright_inc = dxhdy; while (yh xright-0x10000))) { xleft += xleft_inc; xright += xright_inc; s += dsde; t += dtde; w += dwde; r += drde; g += dgde; b += dbde; a += dade; z += dzde; yh++; } j = ym-yh; if (j > 0) { int dx = (xleft-xright)>>16; if ((!flip && xleft < xright) || (flip/* && xleft > xright*/)) { if (_shade != 0) { vtx->r = CSCALE(r+drdx*dx); vtx->g = CSCALE(g+dgdx*dx); vtx->b = CSCALE(b+dbdx*dx); vtx->a = CSCALE(a+dadx*dx); } if (_texture != 0) { vtx->s = SSCALE(s+dsdx*dx, w+dwdx*dx); vtx->t = TSCALE(t+dtdx*dx, w+dwdx*dx); } vtx->x = XSCALE(xleft); vtx->y = YSCALE(yh); vtx->z = ZSCALE(z+dzdx*dx); vtx->w = WSCALE(w+dwdx*dx); ++vtx; } if ((!flip/* && xleft < xright*/) || (flip && xleft > xright)) { if (_shade != 0) { vtx->r = CSCALE(r); vtx->g = CSCALE(g); vtx->b = CSCALE(b); vtx->a = CSCALE(a); } if (_texture != 0) { vtx->s = SSCALE(s, w); vtx->t = TSCALE(t, w); } vtx->x = XSCALE(xright); vtx->y = YSCALE(yh); vtx->z = ZSCALE(z); vtx->w = WSCALE(w); ++vtx; } xleft += xleft_inc*j; xright += xright_inc*j; s += dsde*j; t += dtde*j; if (w + dwde*j) w += dwde*j; else w += dwde*(j-1); r += drde*j; g += dgde*j; b += dbde*j; a += dade*j; z += dzde*j; // render ... } if (xl != xh) xleft = xl; //if (yl-ym > 0) { int dx = (xleft-xright)>>16; if ((!flip && xleft <= xright) || (flip/* && xleft >= xright*/)) { if (_shade != 0) { vtx->r = CSCALE(r+drdx*dx); vtx->g = CSCALE(g+dgdx*dx); vtx->b = CSCALE(b+dbdx*dx); vtx->a = CSCALE(a+dadx*dx); } if (_texture != 0) { vtx->s = SSCALE(s+dsdx*dx, w+dwdx*dx); vtx->t = TSCALE(t+dtdx*dx, w+dwdx*dx); } vtx->x = XSCALE(xleft); vtx->y = YSCALE(ym); vtx->z = ZSCALE(z+dzdx*dx); vtx->w = WSCALE(w+dwdx*dx); ++vtx; } if ((!flip/* && xleft <= xright*/) || (flip && xleft >= xright)) { if (_shade != 0) { vtx->r = CSCALE(r); vtx->g = CSCALE(g); vtx->b = CSCALE(b); vtx->a = CSCALE(a); } if (_texture != 0) { vtx->s = SSCALE(s, w); vtx->t = TSCALE(t, w); } vtx->x = XSCALE(xright); vtx->y = YSCALE(ym); vtx->z = ZSCALE(z); vtx->w = WSCALE(w); ++vtx; } } xleft_inc = dxldy; xright_inc = dxhdy; j = yl-ym; //j--; // ? xleft += xleft_inc*j; xright += xright_inc*j; s += dsde*j; t += dtde*j; w += dwde*j; r += drde*j; g += dgde*j; b += dbde*j; a += dade*j; z += dzde*j; while (yl>ym && !((!flip && xleft < xright+0x10000) || (flip && xleft > xright-0x10000))) { xleft -= xleft_inc; xright -= xright_inc; s -= dsde; t -= dtde; w -= dwde; r -= drde; g -= dgde; b -= dbde; a -= dade; z -= dzde; --j; --yl; } // render ... if (j >= 0) { int dx = (xleft-xright)>>16; if ((!flip && xleft <= xright) || (flip/* && xleft >= xright*/)) { if (_shade != 0) { vtx->r = CSCALE(r+drdx*dx); vtx->g = CSCALE(g+dgdx*dx); vtx->b = CSCALE(b+dbdx*dx); vtx->a = CSCALE(a+dadx*dx); } if (_texture != 0) { vtx->s = SSCALE(s+dsdx*dx, w+dwdx*dx); vtx->t = TSCALE(t+dtdx*dx, w+dwdx*dx); } vtx->x = XSCALE(xleft); vtx->y = YSCALE(yl); vtx->z = ZSCALE(z+dzdx*dx); vtx->w = WSCALE(w+dwdx*dx); ++vtx; } if ((!flip/* && xleft <= xright*/) || (flip && xleft >= xright)) { if (_shade != 0) { vtx->r = CSCALE(r); vtx->g = CSCALE(g); vtx->b = CSCALE(b); vtx->a = CSCALE(a); } if (_texture != 0) { vtx->s = SSCALE(s, w); vtx->t = TSCALE(t, w); } vtx->x = XSCALE(xright); vtx->y = YSCALE(yl); vtx->z = ZSCALE(z); vtx->w = WSCALE(w); ++vtx; } } if (_texture != 0) gSP.changed |= CHANGED_TEXTURE; if (_zbuffer != 0) gSP.geometryMode |= G_ZBUFFER; OGL_DrawLLETriangle(vtx - vtx0); gSP.textureTile[0] = textureTileOrg[0]; gSP.textureTile[1] = textureTileOrg[1]; } static void gDPTriangle(u32 _w1, u32 _w2, int shade, int texture, int zbuffer) { gDPLLETriangle(_w1, _w2, shade, texture, zbuffer, __RDP.cmd_data + __RDP.cmd_cur); } void gDPTriFill(u32 w0, u32 w1) { gDPTriangle(w0, w1, 0, 0, 0); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "trifill\n"); #endif } void gDPTriShade(u32 w0, u32 w1) { gDPTriangle(w0, w1, 1, 0, 0); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "trishade\n"); #endif } void gDPTriTxtr(u32 w0, u32 w1) { gDPTriangle(w0, w1, 0, 1, 0); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "tritxtr\n"); #endif } void gDPTriShadeTxtr(u32 w0, u32 w1) { gDPTriangle(w0, w1, 1, 1, 0); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "trishadetxtr\n"); #endif } void gDPTriFillZ(u32 w0, u32 w1) { gDPTriangle(w0, w1, 0, 0, 1); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "trifillz\n"); #endif } void gDPTriShadeZ(u32 w0, u32 w1) { gDPTriangle(w0, w1, 1, 0, 1); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "trishadez\n"); #endif } void gDPTriTxtrZ(u32 w0, u32 w1) { gDPTriangle(w0, w1, 0, 1, 1); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "tritxtrz\n"); #endif } void gDPTriShadeTxtrZ(u32 w0, u32 w1) { gDPTriangle(w0, w1, 1, 1, 1); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "trishadetxtrz\n"); #endif } mupen64plus-video-gliden64/src/GLideNHQ/gpl-2.0.txt000664 001750 001750 00000043103 12655644434 022602 0ustar00sergiosergio000000 000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. glide2gl/src/Glide64/Glide64_Ini.c000664 001750 001750 00000142437 12655644434 017551 0ustar00sergiosergio000000 000000 #include #include "Glide64_Ini.h" #include "Glide64_UCode.h" #include "rdp.h" #include "DepthBufferRender.h" #include "api/libretro.h" #include "../../libretro/SDL.h" extern bool no_audio; extern uint8_t microcode[4096]; extern uint32_t gfx_plugin_accuracy; extern SETTINGS settings; extern retro_environment_t environ_cb; extern void update_variables(bool startup); extern void glide_set_filtering(unsigned value); void ReadSettings(void) { struct retro_variable var = { "mupen64-screensize", 0 }; unsigned screen_width = 640; unsigned screen_height = 480; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { if (sscanf(var.value ? var.value : "640x480", "%dx%d", &screen_width, &screen_height) != 2) { screen_width = 640; screen_height = 480; } } settings.scr_res_x = screen_width; settings.scr_res_y = screen_height; settings.res_x = 320; settings.res_y = 240; settings.vsync = 1; settings.autodetect_ucode = true; settings.ucode = 2; settings.fog = 1; settings.buff_clear = 1; settings.unk_as_red = false; settings.unk_clear = false; } void ReadSpecialSettings (const char * name) { int smart_read, hires, get_fbinfo, read_always, depth_render, fb_crc_mode, read_back_to_screen, cpu_write_hack, optimize_texrect, hires_buf_clear, read_alpha, ignore_aux_copy, useless_is_useless; uint32_t i, uc_crc; bool updated; struct retro_variable var; fprintf(stderr, "ReadSpecialSettings: %s\n", name); /* frame buffer */ smart_read = 0; hires = 0; get_fbinfo = 0; read_always = 0; depth_render = 1; fb_crc_mode = 1; read_back_to_screen = 0; cpu_write_hack = 0; optimize_texrect = 1; hires_buf_clear = 0; read_alpha = 0; ignore_aux_copy = 0; useless_is_useless = 0; updated = false; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated) update_variables(false); if (strstr(name, (const char *)"DEFAULT")) { settings.filtering = 0; settings.buff_clear = 1; settings.swapmode = 1; settings.swapmode_retro = false; settings.lodmode = 0; /* frame buffer */ settings.alt_tex_size = 0; settings.force_microcheck = 0; settings.force_quad3d = 0; settings.force_calc_sphere = 0; settings.depth_bias = 20; settings.increase_texrect_edge = 0; settings.decrease_fillrect_edge = 0; settings.stipple_mode = 2; settings.stipple_pattern = 0x3E0F83E0; settings.clip_zmin = 0; settings.adjust_aspect = 1; settings.correct_viewport = 0; settings.zmode_compare_less = 0; settings.old_style_adither = 0; settings.n64_z_scale = 0; settings.pal230 = 0; } settings.hacks = 0; // We might want to detect some games by ucode crc, so set // up uc_crc here uc_crc = 0; for (i = 0; i < 3072 >> 2; i++) uc_crc += ((uint32_t*)microcode)[i]; // Glide64 mk2 INI config if (strstr(name, (const char *)"1080 SNOWBOARDING")) { settings.swapmode_retro = true; //settings.alt_tex_size = 1; //depthmode = 0 settings.swapmode = 2; smart_read = 1; #ifdef HAVE_HWFBE optimize_texrect = 1; hires = 1; #endif //fb_clear = 1; } else if (strstr(name, (const char *)"A Bug's Life")) { //depthmode = 0 settings.zmode_compare_less = 1; } else if (strstr(name, (const char *)"Toy Story 2")) { settings.zmode_compare_less = 1; } else if (strstr(name, (const char *)"AERO FIGHTERS ASSAUL")) { settings.clip_zmin = 1; } else if (strstr(name, (const char *)"AIDYN CHRONICLES")) { //depthmode = 1 } else if (strstr(name, (const char *)"All-Star Baseball 20")) { //force_depth_compare = 1 } else if ( strstr(name, (const char *)"All-Star Baseball 99") || strstr(name, (const char *)"All Star Baseball 99") ) { //force_depth_compare = 1 //depthmode = 1 settings.buff_clear = 0; } else if (strstr(name, (const char *)"All-Star Baseball '0")) { //force_depth_compare = 1 //depthmode = 0 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char *)"ARMYMENAIRCOMBAT")) { settings.increase_texrect_edge = 1; //depthmode = 1 } else if (strstr(name, (const char *)"BURABURA POYON")) { //fix_tex_coord = 1 //depthmode = 0 } // ;Bakushou Jinsei 64 - Mezease! Resort Ou. else if (strstr(name, (const char *)"ÊÞ¸¼®³¼Þþ²64")) { //fb_info_disable = 1 //depthmode = 0 } else if (strstr(name, (const char *)"BAKU-BOMBERMAN") || strstr(name, (const char *)"BOMBERMAN64E") || strstr(name, (const char *)"BOMBERMAN64U")) { //depthmode = 0 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char *)"BAKUBOMB2") || strstr(name, (const char *)"BOMBERMAN64U2")) { settings.swapmode_retro = true; settings.filtering = 1; //depthmode = 0 } else if (strstr(name, (const char *)"BANGAIOH")) { //depthmode = 1 } else if ( strstr(name, (const char *)"Banjo-Kazooie") || strstr(name, (const char *)"BANJO KAZOOIE 2") || strstr(name, (const char *)"BANJO TOOIE") ) { settings.swapmode_retro = true; settings.filtering = 1; //depthmode = 1 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #else read_always = 1; #endif } else if (strstr(name, (const char *)"BASS HUNTER 64")) { //fix_tex_coord = 1 //depthmode = 1 settings.buff_clear = 0; settings.swapmode = 2; } else if (strstr(name, (const char *)"BATTLEZONE")) { //force_depth_compare = 1 //depthmode = 1 } else if ( strstr(name, (const char *)"BEETLE ADVENTURE JP") || strstr(name, (const char *)"Beetle Adventure Rac") ) { //wrap_big_tex = 1 settings.n64_z_scale = 1; settings.filtering = 1; //depthmode = 1 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char *)"Bust A Move 3 DX") || strstr(name, (const char *)"Bust A Move '99") ) { settings.filtering = 2; //depthmode = 1 } else if (strstr(name, (const char *)"Bust A Move 2")) { //fix_tex_coord = 1 settings.filtering = 2; //depthmode = 1 settings.fog = 0; } else if (strstr(name, (const char *)"CARMAGEDDON64")) { //wrap_big_tex = 1 settings. filtering = 1; //depthmode = 1 } else if (strstr(name, (const char *)"HYDRO THUNDER")) { settings. filtering = 1; } else if (strstr(name, (const char *)"CENTRE COURT TENNIS")) { //soft_depth_compare = 1 //depthmode = 0 } else if (strstr(name, (const char *)"Chameleon Twist2")) { settings.filtering = 1; //depthmode = 0 } else if (strstr(name, (const char *)"extreme_g") || strstr(name, (const char *)"extremeg")) { settings.swapmode_retro = true; //depthmode = 0 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char *)"Forsaken")) { settings.swapmode_retro = true; } else if (strstr(name, (const char *)"Extreme G 2")) { //depthmode = 0 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif //fb_clear = 1 } else if (strstr(name, (const char *)"MICKEY USA") || strstr(name, (const char *)"MICKEY USA PAL") ) { settings.swapmode_retro = true; settings.alt_tex_size = 1; //depthmode = 1 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif //fb_clear = 1 } else if (strstr(name, (const char *)"MISCHIEF MAKERS") || strstr(name, (const char *)"TROUBLE MAKERS")) { settings.swapmode_retro = true; //mischief_tex_hack = 0 //tex_wrap_hack = 0 //depthmode = 1 settings.filtering = 1; settings.fog = 0; } else if (strstr(name, (const char *)"Sin and Punishment")) { settings.swapmode_retro = true; settings.filtering = 1; settings.old_style_adither = 1; //depthmode = 1 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char*)"Tigger's Honey Hunt")) { settings.zmode_compare_less = 1; //depthmode = 0 settings.buff_clear = 0; } else if (strstr(name, (const char*)"TOM AND JERRY")) { settings.depth_bias = 2; settings.filtering = 1; //depthmode = 0 } else if (strstr(name, (const char*)"SPACE DYNAMITES")) { settings.force_microcheck = 1; } else if (strstr(name, (const char*)"SPIDERMAN")) { } else if (strstr(name, (const char*)"STARCRAFT 64")) { settings.force_microcheck = 1; settings.aspectmode = 2; //depthmode = 1 } else if (strstr(name, (const char*)"STAR SOLDIER")) { settings.force_microcheck = 1; settings.filtering = 1; //depthmode = 1 settings.swapmode = 0; } else if (strstr(name, (const char*)"STAR WARS EP1 RACER")) { settings.swapmode = 2; } else if (strstr(name, (const char*)"TELEFOOT SOCCER 2000")) { settings.buff_clear = 0; } else if (strstr(name, (const char*)"TG RALLY 2")) { settings.filtering = 1; //depthmode = 1 settings.buff_clear = 0; settings.swapmode = 2; } else if (strstr(name, (const char*)"Tonic Trouble")) { //depthmode = 0 cpu_write_hack = 1; } else if (strstr(name, (const char*)"SUPERROBOTSPIRITS")) { settings.aspectmode = 2; } else if (strstr(name, (const char*)"THPS2") || strstr(name, (const char*)"THPS3") || strstr(name, (const char*)"TONY HAWK PRO SKATER") || strstr(name, (const char*)"TONY HAWK SKATEBOARD") ) { settings.filtering = 1; //depthmode = 0 } else if (strstr(name, (const char*)"TOP GEAR RALLY 2")) { settings.filtering = 1; //depthmode = 1 settings.buff_clear = 0; settings.swapmode = 2; } else if (strstr(name, (const char*)"TRIPLE PLAY 2000")) { //wrap_big_tex = 1 //depthmode = 0 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char*)"TSUWAMONO64")) { settings.force_microcheck = 1; //depthmode = 0 } else if (strstr(name, (const char *)"TSUMI TO BATSU")) { settings.swapmode_retro = true; settings.filtering = 1; settings.old_style_adither = 1; //depthmode = 1 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif //fb_clear = 1 } else if (strstr(name, (const char *)"MortalKombatTrilogy")) { settings.filtering = 2; //depthmode = 1 } else if (strstr(name, (const char *)"Perfect Dark")) { settings.swapmode_retro = true; useless_is_useless = 1; settings.decrease_fillrect_edge = 1; settings.filtering = 1; //depthmode = 1 smart_read = 1; #ifdef HAVE_HWFBE optimize_texrect = 0; hires = 1; #endif //fb_clear = 1 } else if (strstr(name, (const char *)"Resident Evil II") || strstr(name, (const char *)"BioHazard II")) { cpu_write_hack = 1; settings.adjust_aspect = 0; settings.n64_z_scale = 1; //fix_tex_coord = 128 //depthmode = 0 settings.swapmode = 2; smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char *)"World Cup 98")) { //depthmode = 0 settings.swapmode = 0; smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char *)"EXCITEBIKE64")) { //depthmode = 0 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char *)"´¸½ÄذÑG2")) { //depthmode = 0 smart_read = 0; #ifdef HAVE_HWFBE hires = 1; #endif //fb_clear = 1 } else if (strstr(name, (const char *)"EARTHWORM JIM 3D")) { //increase_primdepth = 1 settings.filtering = 1; //depthmode = 0 settings.buff_clear = 0; } else if (strstr(name, (const char *)"Cruis'n USA")) { settings.filtering = 1; //depthmode = 1 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif //fb_clear = 1 } else if (strstr(name, (const char *)"CruisnExotica")) { settings.filtering = 1; //depthmode = 1 settings.buff_clear = 0; settings.swapmode = 0; } else if (strstr(name, (const char *)"custom robo") || strstr(name, (const char *)"CUSTOMROBOV2")) { //depthmode = 0 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char *)"´²º³É¾ÃıÃÄÞØ­°½")) { //;Eikou no Saint Andrew settings.correct_viewport = 1; } else if (strstr(name, (const char *)"Eltail")) { settings.filtering = 2; //depthmode = 1 } else if (strstr(name, (const char *)"DeadlyArts")) { //soft_depth_compare = 1 //depthmode = 0 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif settings.clip_zmin = 1; } else if (strstr(name, (const char *)"Bottom of the 9th")) { settings.filtering = 1; //depthmode = 0; smart_read = 1; #ifdef HAVE_HWFBE optimize_texrect = 0; hires = 1; #endif } else if (strstr(name, (const char *)"BRUNSWICKBOWLING")) { //depthmode = 0 settings.buff_clear = 0; settings.swapmode = 0; } else if (strstr(name, (const char *)"CHOPPER ATTACK")) { settings.filtering = 1; //depthmode = 0 } else if (strstr(name, (const char *)"CITY TOUR GP")) { settings.force_microcheck = 1; settings.filtering = 1; //depthmode = 1 } else if (strstr(name, (const char *)"Command&Conquer")) { //fix_tex_coord = 1 settings.adjust_aspect = 2; settings.filtering = 1; //depthmode = 1 settings.fog = 0; } else if (strstr(name, (const char *)"CONKER BFD")) { //ignore_previous = 1 settings.lodmode = 1; settings.filtering = 1; //depthmode = 0 smart_read = 1; #ifdef HAVE_HWFBE optimize_texrect = 1; hires = 1; #endif //fb_clear = 1 } else if (strstr(name, (const char*)"DARK RIFT")) { settings.force_microcheck = 1; } else if (strstr(name, (const char*)"Donald Duck Goin' Qu") || strstr(name, (const char*)"Donald Duck Quack At")) { cpu_write_hack = 1; //depthmode = 0 } else if (strstr(name, (const char*)"ÄÞ×´ÓÃ3 ÉËÞÀÉÃÃSOS!")) { //;Doraemon 3 - Nobita no Machi SOS! (J) settings.clip_zmin = 1; } else if (strstr(name, (const char*)"DR.MARIO 64")) { //fix_tex_coord = 256 //optimize_write = 1 read_back_to_screen = 1; //depthmode = 1 smart_read = 1; #ifdef HAVE_HWFBE hires = 0; #endif } else if (strstr(name, (const char*)"F1 POLE POSITION 64")) { settings.clip_zmin = 1; settings.filtering = 2; //depthmode = 1 } else if (strstr(name, (const char*)"HUMAN GRAND PRIX")) { settings.filtering = 2; //depthmode = 0 } else if (strstr(name, (const char*)"F1RacingChampionship")) { //depthmode = 0 settings.buff_clear = 0; settings.swapmode = 0; } else if (strstr(name, (const char*)"F1 WORLD GRAND PRIX") || strstr(name, (const char*)"F1 WORLD GRAND PRIX2")) { //soft_depth_compare = 1 //wrap_big_tex = 1 //depthmode = 0 settings.buff_clear = 0; } else if (strstr(name, (const char*)"F3 ̳ײɼÚÃ2")) { //;Fushigi no Dungeon - Furai no Shiren 2 (J) settings.decrease_fillrect_edge = 1; //depthmode = 0 } else if (strstr(name, (const char*)"G.A.S.P!!Fighters'NE")) { //soft_depth_compare = 1 //depthmode = 0 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif settings.clip_zmin = 1; } else if (strstr(name, (const char*)"MS. PAC-MAN MM")) { cpu_write_hack = 1; //depthmode = 1 } else if (strstr(name, (const char*)"NBA Courtside 2") || strstr(name, (const char*)"NASCAR 2000") || strstr(name, (const char*)"NASCAR 99") ) { //depthmode = 0 settings.buff_clear = 0; settings.swapmode = 0; } else if (strstr(name, (const char*)"NBA JAM 2000") || strstr(name, (const char*)"NBA JAM 99") ) { settings.buff_clear = 0; } else if (strstr(name, (const char*)"NBA LIVE 2000") ) { settings.adjust_aspect = 0; } else if (strstr(name, (const char*)"NBA Live 99") ) { settings.swapmode = 0; settings.adjust_aspect = 0; } else if (strstr(name, (const char*)"NINTAMAGAMEGALLERY64")) { settings.force_microcheck = 1; //depthmode = 0 } else if (strstr(name, (const char*)"NFL QBC 2000") || strstr(name, (const char*)"NFL Quarterback Club") ) { //wrap_big_tex = 1 //depthmode = 0 settings.swapmode = 0; } else if (strstr(name, (const char*)"GANBAKE GOEMON") //|| strstr(name, (const char*)"¶ÞÃÊÞÚ\ ºÞ´ÓÃ") */ TODO: illegal characters - find by ucode CRC */ || strstr(name, (const char*)"MYSTICAL NINJA") || strstr(name, (const char*)"MYSTICAL NINJA2 SG") ) { optimize_texrect = 0; settings.alt_tex_size = 1; settings.filtering = 1; //depthmode = 1 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char*)"GAUNTLET LEGENDS")) { //depthmode = 1 settings.swapmode = 2; } else if (strstr(name, (const char*)"Getter Love!!")) { settings.zmode_compare_less = 1; //texrect_compare_less = 1 settings.filtering = 2; //depthmode = 1 } else if (strstr(name, (const char*)"GOEMON2 DERODERO") || strstr(name, (const char*)"GOEMONS GREAT ADV")) { settings.filtering = 1; //depthmode = 1 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char*)"GOLDEN NUGGET 64")) { settings.filtering = 2; //depthmode = 1 } else if (strstr(name, (const char*)"GT64")) { settings.force_microcheck = 1; settings.filtering = 1; //depthmode = 1 } else if (strstr(name, (const char*)"ÊѽÀ°ÓɶÞÀØ64") ) { settings.force_microcheck = 1; //depthmode = 0 } else if (strstr(name, (const char*)"HARVESTMOON64") || strstr(name, (const char*)"ÎÞ¸¼Þ®³ÓɶÞÀØ2") ) { settings.zmode_compare_less = 1; //depthmode = 0 settings.fog = 0; } else if (strstr(name, (const char*)"MGAH VOL1")) { settings.force_microcheck = 1; //depthmode = 1 settings.zmode_compare_less = 1; smart_read = 1; } else if (strstr(name, (const char*)"MARIO STORY") || strstr(name, (const char*)"PAPER MARIO") ) { useless_is_useless = 1; hires_buf_clear = 0; settings.filtering = 1; //depthmode = 1 settings.swapmode = 2; smart_read = 1; #ifdef HAVE_HWFBE optimize_texrect = 0; hires = 1; #endif read_alpha = 1; } else if (strstr(name, (const char*)"Mia Hamm Soccer 64")) { settings.buff_clear = 0; } else if (strstr(name, (const char*)"NITRO64")) { smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char*)"NUCLEARSTRIKE64")) { settings.buff_clear = 0; } else if (strstr(name, (const char*)"NFL BLITZ") || strstr(name, (const char*)"NFL BLITZ 2001") || strstr(name, (const char*)"NFL BLITZ SPECIAL ED") ) { settings.lodmode = 1; } else if (strstr(name, (const char*)"Monaco Grand Prix") || strstr(name, (const char*)"Monaco GP Racing 2") ) { //depthmode = 0 settings.buff_clear = 0; } else if (strstr(name, (const char*)"ÓØÀ¼®³·Þ64")) { //;Morita Shogi 64 settings.correct_viewport = 1; } else if (strstr(name, (const char*)"NEWTETRIS")) { settings.pal230 = 1; //fix_tex_coord = 1 settings.increase_texrect_edge = 1; //depthmode = 0 settings.fog = 0; } else if (strstr(name, (const char*)"MLB FEATURING K G JR")) { read_back_to_screen = 2; //depthmode = 1 } else if (strstr(name, (const char*)"HSV ADVENTURE RACING")) { //wrap_big_tex = 1 settings.n64_z_scale = 1; settings.filtering = 1; //depthmode = 1 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char*)"MarioGolf64")) { //fb_info_disable = 1 ignore_aux_copy = 1; settings.buff_clear = 0; //depthmode = 0 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif //fb_clear = 1 } else if (strstr(name, (const char*)"Virtual Pool 64")) { //depthmode = 1 settings.buff_clear = 0; } else if (strstr(name, (const char*)"TWINE")) { settings.filtering = 1; //depthmode = 0 } else if (strstr(name, (const char*)"V-RALLY")) { //fix_tex_coord = 3 settings.filtering = 1; //depthmode = 0 settings.buff_clear = 0; settings.swapmode = 0; } else if (strstr(name, (const char*)"Waialae Country Club")) { //wrap_big_tex = 1 //depthmode = 0 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char*)"TWISTED EDGE")) { //depthmode = 1 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif //fb_clear = 1 } else if (strstr(name, (const char*)"STAR TWINS") || strstr(name, (const char*)"JET FORCE GEMINI") || strstr(name, (const char*)"J F G DISPLAY") ) { read_back_to_screen = 1; settings.decrease_fillrect_edge = 1; //settings.alt_tex_size = 1; //depthmode = 1 settings.swapmode = 2; smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char*)"ÄÞ×´Óà ïÂɾ²Ú²¾·")) { //;Doraemon - Mittsu no Seireiseki (J) read_back_to_screen = 1; //depthmode = 1 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char*)"HEIWA ÊßÃú ܰÙÄÞ64")) { //; Heiwa Pachinko World //depthmode = 0 settings.fog = 0; settings.swapmode = 2; smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char*)"·×¯Ä¶²¹Â 64ÀÃòÀÞÃ")) { settings.filtering = 1; //depthmode = 0 settings.buff_clear = 0; } else if (strstr(name, (const char*)"½°Êß°ÛÎÞ¯ÄÀ²¾Ã64")) { //;Super Robot Taisen 64 (J) smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char*)"Supercross")) { //depthmode = 1 settings.buff_clear = 0; } else if (strstr(name, (const char*)"Top Gear Overdrive")) { //fb_info_disable = 1 //depthmode = 0 settings.buff_clear = 0; } else if (strstr(name, (const char*)"TOP GEAR RALLY")) { no_audio = true; } else if (strstr(name, (const char*)"½½Ò!À²¾ÃÊß½ÞÙÀÞÃ")) { settings.force_microcheck = 1; //depthmode = 1 settings.fog = 0; settings.swapmode = 0; } else if (strstr(name, (const char*)"ÃÃÅÃÞÀúޯÃܰÙÄÞ")) { //;Tamagotchi World 64 (J) //depthmode = 0 settings.fog = 0; } else if (strstr(name, (const char*)"Taz Express")) { settings.filtering = 1; //depthmode = 0 settings.buff_clear = 0; } else if (strstr(name, (const char*)"Top Gear Hyper Bike")) { //fb_info_disable = 1 settings.swapmode = 2; //depthmode = 0 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif //fb_clear = 1 } else if (strstr(name, (const char*)"I S S 64")) { //depthmode = 1 settings.swapmode = 2; settings.old_style_adither = 1; } else if (strstr(name, (const char*)"I.S.S.2000")) { //depthmode = 1 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char*)"ITF 2000") || strstr(name, (const char*)"IT&F SUMMERGAMES") ) { settings.filtering = 1; //depthmode = 1 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char*)"J_league 1997")) { //fix_tex_coord = 1 //depthmode = 1 settings.swapmode = 0; } #if 0 // TODO: illegal characters - will have to find this game by ucode CRC // later else if (strstr(name, (const char*)"Jذ¸Þ\ ²ÚÌÞÃËÞ°Ä1997")) { //;J.League Eleven Beat 1997 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } #endif else if (strstr(name, (const char*)"J WORLD SOCCER3")) { //depthmode = 1 settings.swapmode = 2; } else if (strstr(name, (const char*)"KEN GRIFFEY SLUGFEST")) { read_back_to_screen = 2; //depthmode = 1 settings.swapmode = 0; smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char*)"MASTERS'98")) { //wrap_big_tex = 1 //depthmode = 0 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char*)"MO WORLD LEAGUE SOCC")) { settings.buff_clear = 0; } else if (strstr(name, (const char*)"ǼÂÞØ64")) { //; Nushi Zuri 64 settings.force_microcheck = 1; //wrap_big_tex = 0 //depthmode = 0 settings.buff_clear = 0; } else if (strstr(name, (const char*)"PACHINKO365NICHI")) { settings.correct_viewport = 1; } else if (strstr(name, (const char*)"PERFECT STRIKER")) { //depthmode = 1 settings.swapmode = 2; } else if (strstr(name, (const char*)"ROCKETROBOTONWHEELS")) { settings.clip_zmin = 1; } else if (strstr(name, (const char*)"SD HIRYU STADIUM")) { settings.force_microcheck = 1; //depthmode = 0 } else if (strstr(name, (const char*)"Shadow of the Empire")) { settings.swapmode = 2; } else if (strstr(name, (const char*)"RUSH 2049")) { //force_texrect_zbuf = 1 settings.filtering = 1; //depthmode = 0 } else if (strstr(name, (const char*)"SCARS")) { settings.filtering = 1; //depthmode = 0 } else if (strstr(name, (const char*)"LEGORacers")) { cpu_write_hack = 1; //depthmode = 1 settings.buff_clear = 0; smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif read_alpha = 1; } else if (strstr(name, (const char*)"Lode Runner 3D")) { settings.swapmode = 0; } else if (strstr(name, (const char*)"Parlor PRO 64")) { settings.force_microcheck = 1; settings.filtering = 1; //depthmode = 1 } else if (strstr(name, (const char*)"PUZZLE LEAGUE N64") || strstr(name, (const char*)"PUZZLE LEAGUE")) { //PPL = 1 settings.force_microcheck = 1; //fix_tex_coord = 1 settings.filtering = 2; //depthmode = 1 settings.fog = 0; settings.buff_clear = 0; smart_read = 1; #ifdef HAVE_HWFBE hires = 0; #endif read_alpha = 1; } else if (strstr(name, (const char*)"POKEMON SNAP")) { //depthmode = 1 #ifdef HAVE_HWFBE hires = 0; #else read_always = 1; #endif //fb_clear = 1 } else if (strstr(name, (const char*)"POKEMON STADIUM") || strstr(name, (const char*)"POKEMON STADIUM G&S") ) { //depthmode = 1 settings.buff_clear = 0; smart_read = 1; #ifdef HAVE_HWFBE optimize_texrect = 0; hires = 0; #endif read_alpha = 1; fb_crc_mode = 2; } else if (strstr(name, (const char*)"POKEMON STADIUM 2")) { //depthmode = 1 settings.buff_clear = 0; settings.swapmode = 2; smart_read = 1; #ifdef HAVE_HWFBE optimize_texrect = 0; hires = 1; #endif read_alpha = 1; fb_crc_mode = 2; } else if (strstr(name, (const char*)"RAINBOW SIX")) { settings.increase_texrect_edge = 1; //depthmode = 1 } else if (strstr(name, (const char*)"RALLY CHALLENGE") || strstr(name, (const char*)"Rally'99")) { settings.filtering = 1; //depthmode = 1 settings.buff_clear = 0; smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char*)"Rayman 2")) { //depthmode = 0 cpu_write_hack = 1; } else if (strstr(name, (const char*)"quarterback_club_98")) { hires_buf_clear = 0; settings.filtering = 1; //depthmode = 1 settings.swapmode = 0; settings.buff_clear = 0; smart_read = 1; #ifdef HAVE_HWFBE optimize_texrect = 0; hires = 1; #endif read_alpha = 1; } else if (strstr(name, (const char*)"PowerLeague64")) { settings.force_quad3d = 1; } else if (strstr(name, (const char*)"Racing Simulation 2")) { //depthmode = 0 settings.buff_clear = 0; } else if (strstr(name, (const char*)"TOP GEAR RALLY")) { settings.depth_bias = 64; //fillcolor_fix = 1 //depthmode = 0 } else if (strstr(name, (const char*)"SMASH BROTHERS")) { settings.swapmode_retro = true; } #if 0 else if (strstr(name, (const char*)"POLARISSNOCROSS")) { //fix_tex_coord = 5 //depthmode = 1 } else if (strstr(name, (const char*)"READY 2 RUMBLE")) { //fix_tex_coord = 64 //depthmode = 0 } else if (strstr(name, (const char*)"Ready to Rumble")) { //fix_tex_coord = 1 //depthmode = 0 } else if (strstr(name, (const char*)"LT DUCK DODGERS")) { //wrap_big_tex = 1 //depthmode = 1 } else if (strstr(name, (const char*)"LET'S SMASH")) { //soft_depth_compare = 1 //depthmode = 0 } else if (strstr(name, (const char*)"LCARS - WT_Riker")) { //depthmode = 1 } else if (strstr(name, (const char*)"RUGRATS IN PARIS")) { //depthmode = 1 } else if (strstr(name, (const char*)"Shadowman")) { //depthmode = 0 } else if (strstr(name, (const char*)"J LEAGUE LIVE 64")) { //wrap_big_tex = 1 //depthmode = 1 } else if (strstr(name, (const char*)"Iggy's Reckin' Balls")) { //fix_tex_coord = 512 //depthmode = 0 } else if (strstr(name, (const char*)"Ultraman Battle JAPA")) { //depthmode = 0 } else if (strstr(name, (const char*)"D K DISPLAY")) { //depthmode = 1 //fb_clear = 1 } else if (strstr(name, (const char*)"MarioParty3")) { //fix_tex_coord = 1 //depthmode = 0 } else if (strstr(name, (const char*)"MK_MYTHOLOGIES")) { //depthmode = 1 } else if (strstr(name, (const char*)"NFL QBC '99")) { //force_depth_compare = 1 //wrap_big_tex = 1 //depthmode = 0 } else if (strstr(name, (const char*)"OgreBattle64")) { //fb_info_disable = 1 //force_depth_compare = 1 //depthmode = 1 } else if (strstr(name, (const char*)"MICROMACHINES64TURBO")) { //depthmode = 0 } else if (strstr(name, (const char*)"Fighting Force")) { //depthmode = 1 } else if (strstr(name, (const char *)"D K DISPLAY")) { //depthmode = 1 //fb_clear = 1 } else if (strstr(name, (const char *)"DAFFY DUCK STARRING")) { //depthmode = 1 //wrap_big_tex = 1 } else if (strstr(name, (const char *)"CyberTiger")) { //fix_tex_coord = 16 //depthmode = 0 } else if (strstr(name, (const char *)"F-Zero X") || strstr(name, (const char *)"F-ZERO X")) { settings.swapmode_retro = true; //depthmode = 1 } else if (strstr(name, (const char *)"DERBYSTALLION64")) { //fix_tex_coord = 1 //depthmode = 0 } else if (strstr(name, (const char *)"DUKE NUKEM")) { //increase_primdepth = 1 //depthmode = 0 } else if (strstr(name, (const char *)"EVANGELION")) { //depthmode = 1 } else if (strstr(name, (const char *)"Big Mountain 2000")) { //depthmode = 1 } else if (strstr(name, (const char *)"YAKOUTYUU2")) { //depthmode = 0 } else if (strstr(name, (const char *)"WRESTLEMANIA 2000")) { //depthmode = 0 } #endif else if (strstr(name, (const char *)"Pilot Wings64")) { settings.swapmode_retro = true; settings.depth_bias = 10; //depthmode = 1 settings.buff_clear = 0; } else if (strstr(name, (const char *)"DRACULA MOKUSHIROKU") || strstr(name, (const char *)"DRACULA MOKUSHIROKU2") ) { //depthmode = 0 //fb_clear = 1 settings.old_style_adither = 1; } else if (strstr(name, (const char *)"CASTLEVANIA") || strstr(name, (const char *)"CASTLEVANIA2")) { settings.swapmode_retro = true; settings.old_style_adither = 1; //depthmode = 0 //fb_clear = 1 #ifndef HAVE_HWFBE read_always = 1; #endif } else if (strstr(name, (const char *)"Dual heroes JAPAN") || strstr(name, (const char *)"Dual heroes PAL") || strstr(name, (const char *)"Dual heroes USA")) { settings.filtering = 1; //depthmode = 0 settings.swapmode = 0; } else if (strstr(name, (const char *)"JEREMY MCGRATH SUPER")) { //depthmode = 0 settings.swapmode = 0; } else if (strstr(name, (const char *)"Kirby64")) { settings.filtering = 1; //depthmode = 0 settings.buff_clear = 0; settings.swapmode = 0; } else if (strstr(name, (const char *)"GOLDENEYE")) { settings.swapmode_retro = true; settings.lodmode = 1; settings.depth_bias = 40; settings.filtering = 1; //depthmode = 0 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char *)"DONKEY KONG 64")) { settings.lodmode = 1; settings.depth_bias = 64; //depthmode = 1 //fb_clear = 1 read_always = 1; } else if (strstr(name, (const char *)"Glover")) { settings.filtering = 1; //depthmode = 0; } else if (strstr(name, (const char *)"GEX: ENTER THE GECKO") || strstr(name, (const char *)"Gex 3 Deep Cover Gec")) { settings.filtering = 1; //depthmode = 0; } else if (strstr(name, (const char *)"WAVE RACE 64")) { settings.swapmode_retro = true; settings.lodmode = 1; settings.pal230 = 1; } else if (strstr(name, (const char *)"WILD CHOPPERS")) { settings.filtering = 1; //depthmode = 0 } else if (strstr(name, (const char *)"Wipeout 64")) { settings.filtering = 1; //depthmode = 0 settings.swapmode = 0; } else if (strstr(name, (const char *)"WONDER PROJECT J2")) { //depthmode = 0 settings.buff_clear = 0; settings.swapmode = 0; } else if (strstr(name, (const char *)"Doom64")) { settings.swapmode_retro = true; //fillcolor_fix = 1 //depthmode = 1 } else if (strstr(name, (const char *)"HEXEN")) { cpu_write_hack = 1; settings.filtering = 1; //depthmode = 1 settings.buff_clear = 0; settings.swapmode = 2; } else if (strstr(name, (const char *)"ZELDA MAJORA'S MASK") || strstr(name, (const char *)"THE MASK OF MUJURA")) { settings.swapmode_retro = true; //wrap_big_tex = 1 settings.filtering = 1; smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif //fb_clear = 1 fb_crc_mode = 0; } else if (strstr(name, (const char *)"THE LEGEND OF ZELDA") || strstr(name, (const char *)"ZELDA MASTER QUEST")) { settings.swapmode_retro = true; settings.filtering = 1; //depthmode = 1 settings.lodmode = 1; smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif //fb_clear = 1 // settings.hacks |= hack_OOT; } else if (strstr(name, (const char*)"Re-Volt")) { //depthmode = 1 } else if (strstr(name, (const char*)"RIDGE RACER 64")) { settings.swapmode_retro = true; settings.force_calc_sphere = 1; //depthmode = 0 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #else read_always = 1; #endif } else if (strstr(name, (const char*)"ROAD RASH 64")) { //depthmode = 0 settings.swapmode = 2; } else if (strstr(name, (const char*)"Robopon64")) { //depthmode = 0 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char*)"RONALDINHO SOCCER")) { //depthmode = 1 settings.swapmode = 2; settings.old_style_adither = 1; } else if (strstr(name, (const char*)"RTL WLS2000")) { settings.buff_clear = 0; } else if (strstr(name, (const char*)"BIOFREAKS")) { //depthmode = 0 settings.buff_clear = 0; smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char *)"Blast Corps") || strstr(name, (const char *)"Blastdozer")) { //depthmode = 1 settings.swapmode = 0; smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif read_alpha = 1; } else if (strstr(name, (const char *)"blitz2k")) { settings.lodmode = 1; } else if (strstr(name, (const char *)"Body Harvest")) { //depthmode = 1 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char *)"Killer Instinct Gold") || strstr(name, (const char *)"KILLER INSTINCT GOLD")) { settings.swapmode_retro = true; settings.filtering = 1; //depthmode = 0 settings.buff_clear = 0; } else if (strstr(name, (const char*)"KNIFE EDGE")) { //wrap_big_tex = 1 settings.filtering = 1; //depthmode = 1 } else if (strstr(name, (const char*)"Knockout Kings 2000")) { //fb_info_disable = 1 //depthmode = 1 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif //fb_clear = 1 read_alpha = 1; } else if (strstr(name, (const char *)"MACE")) { settings.swapmode_retro = true; #if 1 // Not in original INI - fixes black stripes on big textures // TODO: check for regressions settings.increase_texrect_edge = 1; #endif //fix_tex_coord = 8 settings.filtering = 1; //depthmode = 1 } else if (strstr(name, (const char *)"Quake")) { settings.force_microcheck = 1; settings.buff_clear = 0; settings.swapmode = 2; } else if (strstr(name, (const char *)"QUAKE II")) { smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char *)"Holy Magic Century")) { settings.filtering = 2; //depthmode = 1 } else if (strstr(name, (const char *)"Quest 64")) { //depthmode = 1 } else if (strstr(name, (const char*)"Silicon Valley")) { settings.filtering = 1; //depthmode = 0 } else if (strstr(name, (const char*)"SNOWBOARD KIDS2") || strstr(name, (const char*)"Snobow Kids 2")) { settings.swapmode = 0; settings.filtering = 1; } else if (strstr(name, (const char*)"South Park Chef's Lu") || strstr(name, (const char*)"South Park: Chef's L")) { //fix_tex_coord = 4 settings.filtering = 1; //depthmode = 1 settings.fog = 0; settings.buff_clear = 0; } else if (strstr(name, (const char*)"LAMBORGHINI")) { } else if (strstr(name, (const char*)"MAGICAL TETRIS")) { settings.force_microcheck = 1; //depthmode = 1 settings.fog = 0; } else if (strstr(name, (const char *)"MarioParty")) { settings.clip_zmin = 1; //depthmode = 0 settings.swapmode = 2; } else if (strstr(name, (const char*)"MarioParty2")) { //depthmode = 0 settings.swapmode = 2; } else if (strstr(name, (const char *)"Mega Man 64") || strstr(name, (const char *)"RockMan Dash")) { settings.increase_texrect_edge = 1; //depthmode = 1 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif } else if (strstr(name, (const char *)"TUROK_DINOSAUR_HUNTE")) { settings.swapmode_retro = true; settings.depth_bias = 1; settings.lodmode = 1; } else if (strstr(name, (const char *)"Turok 2")) { settings.swapmode_retro = true; } else if (strstr(name, (const char *)"SUPER MARIO 64") || strstr(name, (const char *)"SUPERMARIO64")) { settings.swapmode_retro = true; settings.depth_bias = 64; settings.lodmode = 1; settings.filtering = 1; //depthmode = 1 } else if (strstr(name, (const char *)"SM64 Star Road")) { settings.depth_bias = 1; settings.lodmode = 1; settings.filtering = 1; //depthmode = 1 } else if (strstr(name, (const char *)"SUPERMAN")) { cpu_write_hack = 1; } else if (strstr(name, (const char *)"TETRISPHERE")) { settings.alt_tex_size = 1; settings.increase_texrect_edge = 1; //depthmode = 1 smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif fb_crc_mode = 2; } else if (strstr(name, (const char *)"MARIOKART64")) { settings.swapmode_retro = true; settings.depth_bias = 30; settings.stipple_mode = 1; settings.stipple_pattern = (uint32_t)4286595040UL; //depthmode = 1 #ifndef HAVE_HWFBE read_always = 1; #endif } else if (strstr(name, (const char *)"YOSHI STORY")) { settings.swapmode_retro = true; //fix_tex_coord = 32 //depthmode = 1 settings.filtering = 1; settings.fog = 0; } else if (strstr(name, (const char *)"STARFOX64")) { settings.swapmode_retro = true; } else { if (strstr(name, (const char*)"Mini Racers") || uc_crc == UCODE_MINI_RACERS_CRC1 || uc_crc == UCODE_MINI_RACERS_CRC2) { /* Mini Racers (prototype ROM ) does not have a valid name, so detect by ucode crc */ settings.force_microcheck = 1; settings.buff_clear = 0; smart_read = 1; #ifdef HAVE_HWFBE hires = 1; #endif settings.swapmode = 0; } } //detect games which require special hacks if (strstr(name, (const char *)"ZELDA") || strstr(name, (const char *)"MASK")) { settings.hacks |= hack_Zelda; settings.flame_corona = 1; //settings.flame_corona = (settings.hacks & hack_Zelda) && !fb_depth_render_enabled; } else if (strstr(name, (const char *)"ROADSTERS TROPHY")) settings.hacks |= hack_Zelda; else if (strstr(name, (const char *)"Diddy Kong Racing")) { settings.swapmode_retro = true; settings.hacks |= hack_Diddy; } else if (strstr(name, (const char *)"Tonic Trouble")) settings.hacks |= hack_Tonic; else if (strstr(name, (const char *)"All") && strstr(name, (const char *)"Star") && strstr(name, (const char *)"Baseball")) settings.hacks |= hack_ASB; else if (strstr(name, (const char *)"Beetle") || strstr(name, (const char *)"BEETLE") || strstr(name, (const char *)"HSV")) settings.hacks |= hack_BAR; else if (strstr(name, (const char *)"I S S 64") || strstr(name, (const char *)"J WORLD SOCCER3") || strstr(name, (const char *)"PERFECT STRIKER") || strstr(name, (const char *)"RONALDINHO SOCCER")) settings.hacks |= hack_ISS64; else if (strstr(name, (const char *)"MARIOKART64")) settings.hacks |= hack_MK64; else if (strstr(name, (const char *)"NITRO64")) settings.hacks |= hack_WCWnitro; else if (strstr(name, (const char *)"CHOPPER_ATTACK") || strstr(name, (const char *)"WILD CHOPPERS")) settings.hacks |= hack_Chopper; else if (strstr(name, (const char *)"Resident Evil II") || strstr(name, (const char *)"BioHazard II")) settings.hacks |= hack_RE2; else if (strstr(name, (const char *)"YOSHI STORY")) settings.hacks |= hack_Yoshi; else if (strstr(name, (const char *)"F-Zero X") || strstr(name, (const char *)"F-ZERO X")) settings.hacks |= hack_Fzero; else if (strstr(name, (const char *)"PAPER MARIO") || strstr(name, (const char *)"MARIO STORY")) settings.hacks |= hack_PMario; else if (strstr(name, (const char *)"TOP GEAR RALLY 2")) settings.hacks |= hack_TGR2; else if (strstr(name, (const char *)"TOP GEAR RALLY")) settings.hacks |= hack_TGR; else if (strstr(name, (const char *)"Top Gear Hyper Bike")) settings.hacks |= hack_Hyperbike; else if (strstr(name, (const char *)"Killer Instinct Gold") || strstr(name, (const char *)"KILLER INSTINCT GOLD")) settings.hacks |= hack_KI; else if (strstr(name, (const char *)"Knockout Kings 2000")) settings.hacks |= hack_Knockout; else if (strstr(name, (const char *)"LEGORacers")) settings.hacks |= hack_Lego; else if (strstr(name, (const char *)"OgreBattle64")) settings.hacks |= hack_Ogre64; else if (strstr(name, (const char *)"Pilot Wings64")) settings.hacks |= hack_Pilotwings; else if (strstr(name, (const char *)"Supercross")) settings.hacks |= hack_Supercross; else if (strstr(name, (const char *)"STARCRAFT 64")) settings.hacks |= hack_Starcraft; else if (strstr(name, (const char *)"BANJO KAZOOIE 2") || strstr(name, (const char *)"BANJO TOOIE")) settings.hacks |= hack_Banjo2; else if (strstr(name, (const char *)"FIFA: RTWC 98") || strstr(name, (const char *)"RoadToWorldCup98")) settings.hacks |= hack_Fifa98; else if (strstr(name, (const char *)"Mega Man 64") || strstr(name, (const char *)"RockMan Dash")) settings.hacks |= hack_Megaman; else if (strstr(name, (const char *)"MISCHIEF MAKERS") || strstr(name, (const char *)"TROUBLE MAKERS")) settings.hacks |= hack_Makers; else if (strstr(name, (const char *)"GOLDENEYE")) settings.hacks |= hack_GoldenEye; else if (strstr(name, (const char *)"Blast Corps") || strstr(name, (const char *)"Blastdozer")) settings.hacks |= hack_Blastcorps; //else if (strstr(name, (const char *)"PUZZLE LEAGUE")) //settings.hacks |= hack_PPL; switch (gfx_plugin_accuracy) { case 2: /* HIGH */ break; case 1: /* MEDIUM */ if (read_always > 0) // turn off read_always { read_always = 0; if (smart_read == 0) // turn on smart_read instead smart_read = 1; } break; case 0: /* LOW */ if (read_always > 0) read_always = 0; if (smart_read > 0) smart_read = 0; break; } if (settings.n64_z_scale) ZLUT_init(); //frame buffer if (optimize_texrect > 0) settings.frame_buffer |= fb_optimize_texrect; else if (optimize_texrect == 0) settings.frame_buffer &= ~fb_optimize_texrect; if (ignore_aux_copy > 0) settings.frame_buffer |= fb_ignore_aux_copy; else if (ignore_aux_copy == 0) settings.frame_buffer &= ~fb_ignore_aux_copy; if (hires_buf_clear > 0) settings.frame_buffer |= fb_hwfbe_buf_clear; else if (hires_buf_clear == 0) settings.frame_buffer &= ~fb_hwfbe_buf_clear; if (read_alpha > 0) settings.frame_buffer |= fb_read_alpha; else if (read_alpha == 0) settings.frame_buffer &= ~fb_read_alpha; if (useless_is_useless > 0) settings.frame_buffer |= fb_useless_is_useless; else settings.frame_buffer &= ~fb_useless_is_useless; if (fb_crc_mode >= 0) settings.fb_crc_mode = fb_crc_mode; if (smart_read > 0) settings.frame_buffer |= fb_emulation; else if (smart_read == 0) settings.frame_buffer &= ~fb_emulation; if (hires > 0) settings.frame_buffer |= fb_hwfbe; else if (hires == 0) settings.frame_buffer &= ~fb_hwfbe; if (read_always > 0) settings.frame_buffer |= fb_ref; else if (read_always == 0) settings.frame_buffer &= ~fb_ref; if (read_back_to_screen == 1) settings.frame_buffer |= fb_read_back_to_screen; else if (read_back_to_screen == 2) settings.frame_buffer |= fb_read_back_to_screen2; else if (read_back_to_screen == 0) settings.frame_buffer &= ~(fb_read_back_to_screen|fb_read_back_to_screen2); if (cpu_write_hack > 0) settings.frame_buffer |= fb_cpu_write_hack; else if (cpu_write_hack == 0) settings.frame_buffer &= ~fb_cpu_write_hack; if (get_fbinfo > 0) settings.frame_buffer |= fb_get_info; else if (get_fbinfo == 0) settings.frame_buffer &= ~fb_get_info; if (depth_render > 0) settings.frame_buffer |= fb_depth_render; else if (depth_render == 0) settings.frame_buffer &= ~fb_depth_render; settings.frame_buffer |= fb_motionblur; var.key = "mupen64-filtering"; var.value = NULL; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { if (strcmp(var.value, "N64 3-point") == 0) #ifdef DISABLE_3POINT glide_set_filtering(3); #else glide_set_filtering(1); #endif else if (strcmp(var.value, "nearest") == 0) glide_set_filtering(2); else if (strcmp(var.value, "bilinear") == 0) glide_set_filtering(3); } /* this has to be done here. */ if (strstr(name, "POKEMON STADIUM 2")) settings.frame_buffer &= ~fb_emulation; } mupen64plus-video-gliden64/src/RSP.cpp000664 001750 001750 00000015447 12655644434 020611 0ustar00sergiosergio000000 000000 #include #include "Debug.h" #include "RSP.h" #include "RDP.h" #include "N64.h" #include "F3D.h" #include "Turbo3D.h" #include "VI.h" #include "Combiner.h" #include "FrameBuffer.h" #include "DepthBuffer.h" #include "GBI.h" #include "PluginAPI.h" #include "Config.h" using namespace std; RSPInfo __RSP; void RSP_LoadMatrix( f32 mtx[4][4], u32 address ) { f32 recip = 1.5258789e-05f; struct _N64Matrix { SHORT integer[4][4]; WORD fraction[4][4]; } *n64Mat = (struct _N64Matrix *)&gfx_info.RDRAM[address]; int i, j; for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) mtx[i][j] = (GLfloat)(n64Mat->integer[i][j^1]) + (GLfloat)(n64Mat->fraction[i][j^1]) * recip; } void RSP_CheckDLCounter(void) { if (__RSP.count != -1) { --__RSP.count; if (__RSP.count == 0) { __RSP.count = -1; --__RSP.PCi; DebugMsg( DEBUG_LOW | DEBUG_HANDLED, "End of DL\n" ); } } } void RSP_ProcessDList(void) { if (ConfigOpen || video().isResizeWindow()) { gDPFullSync(); return; } if (*REG.VI_ORIGIN != VI.lastOrigin) { VI_UpdateSize(); video().updateScale(); } __RSP.PC[0] = *(u32*)&DMEM[0x0FF0]; __RSP.PCi = 0; __RSP.count = -1; __RSP.halt = FALSE; __RSP.busy = TRUE; gSP.matrix.stackSize = min( 32U, *(u32*)&DMEM[0x0FE4] >> 6 ); if (gSP.matrix.stackSize == 0) gSP.matrix.stackSize = 32; gSP.matrix.modelViewi = 0; gSP.changed |= CHANGED_MATRIX; gDP.changed &= ~CHANGED_CPU_FB_WRITE; gDPSetTexturePersp(G_TP_PERSP); u32 uc_start = *(u32*)&DMEM[0x0FD0]; u32 uc_dstart = *(u32*)&DMEM[0x0FD8]; u32 uc_dsize = *(u32*)&DMEM[0x0FDC]; if ((uc_start != __RSP.uc_start) || (uc_dstart != __RSP.uc_dstart)) gSPLoadUcodeEx(uc_start, uc_dstart, uc_dsize); depthBufferList().setNotCleared(); if (GBI.getMicrocodeType() == Turbo3D) RunTurbo3D(); else { while (!__RSP.halt) { if ((__RSP.PC[__RSP.PCi] + 8) > RDRAMSize) { #ifdef DEBUG switch (Debug.level) { case DEBUG_LOW: DebugMsg( DEBUG_LOW | DEBUG_ERROR, "ATTEMPTING TO EXECUTE RSP COMMAND AT INVALID RDRAM LOCATION\n" ); break; case DEBUG_MEDIUM: DebugMsg( DEBUG_MEDIUM | DEBUG_ERROR, "Attempting to execute RSP command at invalid RDRAM location\n" ); break; case DEBUG_HIGH: DebugMsg( DEBUG_HIGH | DEBUG_ERROR, "// Attempting to execute RSP command at invalid RDRAM location\n" ); break; } #endif break; } u32 w0 = *(u32*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi]]; u32 w1 = *(u32*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi] + 4]; __RSP.cmd = _SHIFTR(w0, 24, 8); #ifdef DEBUG DebugRSPState( __RSP.PCi, __RSP.PC[__RSP.PCi], _SHIFTR( w0, 24, 8 ), w0, w1 ); DebugMsg( DEBUG_LOW | DEBUG_HANDLED, "0x%08lX: CMD=0x%02lX W0=0x%08lX W1=0x%08lX\n", __RSP.PC[__RSP.PCi], _SHIFTR( w0, 24, 8 ), w0, w1 ); #endif __RSP.PC[__RSP.PCi] += 8; __RSP.nextCmd = _SHIFTR(*(u32*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi]], 24, 8); GBI.cmd[__RSP.cmd](w0, w1); RSP_CheckDLCounter(); } } if (config.frameBufferEmulation.copyDepthToRDRAM != Config::ctDisable) FrameBuffer_CopyDepthBuffer(gDP.colorImage.address); __RSP.busy = FALSE; gDP.changed |= CHANGED_COLORBUFFER; } static void RSP_SetDefaultState(void) { memset(&gSP, 0, sizeof(gSPInfo)); gSPTexture(1.0f, 1.0f, 0, 0, TRUE); gDP.loadTile = &gDP.tiles[7]; gSP.textureTile[0] = &gDP.tiles[0]; gSP.textureTile[1] = &gDP.tiles[1]; gSP.lookat[0].x = gSP.lookat[1].x = 1.0f; gSP.lookatEnable = false; gSP.objMatrix.A = 1.0f; gSP.objMatrix.B = 0.0f; gSP.objMatrix.C = 0.0f; gSP.objMatrix.D = 1.0f; gSP.objMatrix.X = 0.0f; gSP.objMatrix.Y = 0.0f; gSP.objMatrix.baseScaleX = 1.0f; gSP.objMatrix.baseScaleY = 1.0f; gSP.objRendermode = 0; for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) gSP.matrix.modelView[0][i][j] = 0.0f; gSP.matrix.modelView[0][0][0] = 1.0f; gSP.matrix.modelView[0][1][1] = 1.0f; gSP.matrix.modelView[0][2][2] = 1.0f; gSP.matrix.modelView[0][3][3] = 1.0f; gDP.otherMode._u64 = 0U; } u32 DepthClearColor = 0xfffcfffc; static void setDepthClearColor(void) { if (strstr(__RSP.romname, (const char *)"Elmo's") != NULL) DepthClearColor = 0xFFFFFFFF; else if (strstr(__RSP.romname, (const char *)"Taz Express") != NULL) DepthClearColor = 0xFFBCFFBC; else if (strstr(__RSP.romname, (const char *)"NFL QBC 2000") != NULL || strstr(__RSP.romname, (const char *)"NFL Quarterback Club") != NULL || strstr(RSP.romname, (const char *)"Jeremy McGrath Super") != NULL) DepthClearColor = 0xFFFDFFFC; else DepthClearColor = 0xFFFCFFFC; } void RSP_Init(void) { #ifdef OS_WINDOWS // Calculate RDRAM size by intentionally causing an access violation u32 test; try { test = RDRAM[0x007FFFFF] + 1; } catch (...) { test = 0; } if (test > 0) RDRAMSize = 0x7FFFFF; else RDRAMSize = 0x3FFFFF; #else // OS_WINDOWS RDRAMSize = 1024 * 1024 * 8 - 1; #endif // OS_WINDOWS __RSP.uc_start = __RSP.uc_dstart = 0; __RSP.bLLE = false; // get the name of the ROM char romname[21]; for (int i = 0; i < 20; ++i) romname[i] = HEADER[(32 + i) ^ 3]; romname[20] = 0; // remove all trailing spaces while (romname[strlen(romname) - 1] == ' ') romname[strlen(romname) - 1] = 0; if (strcmp(__RSP.romname, romname) != 0) TFH.shutdown(); strncpy(__RSP.romname, romname, 21); setDepthClearColor(); config.generalEmulation.hacks = 0; if (strstr(__RSP.romname, (const char *)"OgreBattle64") != NULL) config.generalEmulation.hacks |= hack_Ogre64; else if (strstr(__RSP.romname, (const char *)"MarioGolf64") != NULL || strstr(__RSP.romname, (const char *)"F1 POLE POSITION 64") != NULL ) config.generalEmulation.hacks |= hack_noDepthFrameBuffers; else if (strstr(__RSP.romname, (const char *)"CONKER BFD") != NULL || strstr(__RSP.romname, (const char *)"MICKEY USA") != NULL ) config.generalEmulation.hacks |= hack_blurPauseScreen; else if (strstr(__RSP.romname, (const char *)"MarioTennis64") != NULL) config.generalEmulation.hacks |= hack_scoreboardJ; else if (strstr(__RSP.romname, (const char *)"MarioTennis") != NULL) config.generalEmulation.hacks |= hack_scoreboard; else if (strstr(__RSP.romname, (const char *)"Pilot Wings64") != NULL) config.generalEmulation.hacks |= hack_pilotWings; else if (strstr(__RSP.romname, (const char *)"THE LEGEND OF ZELDA") != NULL || strstr(__RSP.romname, (const char *)"ZELDA MASTER QUEST") != NULL || strstr(__RSP.romname, (const char *)"DOUBUTSUNOMORI") != NULL ) config.generalEmulation.hacks |= hack_subscreen; else if (strstr(__RSP.romname, (const char *)"Blast") != NULL) config.generalEmulation.hacks |= hack_blastCorps; else if (strstr(__RSP.romname, (const char *)"SPACE INVADERS") != NULL) config.generalEmulation.hacks |= hack_ignoreVIHeightChange; else if (strstr(__RSP.romname, (const char *)"MASK") != NULL) // Zelda MM config.generalEmulation.hacks |= hack_skipVIChangeCheck | hack_ZeldaCamera; api().FindPluginPath(__RSP.pluginpath); RSP_SetDefaultState(); } mupen64plus-video-gliden64/src/gDP.h000664 001750 001750 00000014023 12655644434 020251 0ustar00sergiosergio000000 000000 #ifndef GDP_H #define GDP_H #include "Types.h" #define CHANGED_RENDERMODE 0x001 #define CHANGED_CYCLETYPE 0x002 #define CHANGED_SCISSOR 0x004 #define CHANGED_TMEM 0x008 #define CHANGED_TILE 0x010 //#define CHANGED_COMBINE_COLORS 0x020 #define CHANGED_COMBINE 0x040 #define CHANGED_ALPHACOMPARE 0x080 #define CHANGED_FOGCOLOR 0x100 #define CHANGED_BLENDCOLOR 0x200 #define CHANGED_FB_TEXTURE 0x400 #define CHANGED_COLORBUFFER 0x1000 #define CHANGED_CPU_FB_WRITE 0x2000 #define TEXTUREMODE_NORMAL 0 #define TEXTUREMODE_BGIMAGE 2 #define TEXTUREMODE_FRAMEBUFFER 3 #define TEXTUREMODE_FRAMEBUFFER_BG 4 #define LOADTYPE_BLOCK 0 #define LOADTYPE_TILE 1 struct gDPCombine { union { struct { // muxs1 unsigned aA1 : 3; unsigned sbA1 : 3; unsigned aRGB1 : 3; unsigned aA0 : 3; unsigned sbA0 : 3; unsigned aRGB0 : 3; unsigned mA1 : 3; unsigned saA1 : 3; unsigned sbRGB1 : 4; unsigned sbRGB0 : 4; // muxs0 unsigned mRGB1 : 5; unsigned saRGB1 : 4; unsigned mA0 : 3; unsigned saA0 : 3; unsigned mRGB0 : 5; unsigned saRGB0 : 4; }; struct { u32 muxs1, muxs0; }; u64 mux; }; }; struct FrameBuffer; struct gDPTile { u32 format, size, line, tmem, palette; union { struct { unsigned mirrort : 1; unsigned clampt : 1; unsigned pad0 : 30; unsigned mirrors : 1; unsigned clamps : 1; unsigned pad1 : 30; }; struct { u32 cmt, cms; }; }; u32 maskt, masks; u32 shiftt, shifts; f32 fuls, fult, flrs, flrt; u32 uls, ult, lrs, lrt; u32 textureMode; u32 loadType; u32 imageAddress; FrameBuffer *frameBuffer; }; struct gDPLoadTileInfo { u8 size; u8 loadType; u16 uls; u16 ult; u16 width; u16 height; u16 texWidth; u32 texAddress; u32 dxt; }; struct gDPInfo { struct { union { struct { unsigned int alphaCompare : 2; unsigned int depthSource : 1; // struct // { unsigned int AAEnable : 1; unsigned int depthCompare : 1; unsigned int depthUpdate : 1; unsigned int imageRead : 1; unsigned int clearOnCvg : 1; unsigned int cvgDest : 2; unsigned int depthMode : 2; unsigned int cvgXAlpha : 1; unsigned int alphaCvgSel : 1; unsigned int forceBlender : 1; unsigned int textureEdge : 1; // } renderMode; // struct // { unsigned int c2_m2b : 2; unsigned int c1_m2b : 2; unsigned int c2_m2a : 2; unsigned int c1_m2a : 2; unsigned int c2_m1b : 2; unsigned int c1_m1b : 2; unsigned int c2_m1a : 2; unsigned int c1_m1a : 2; // } blender; unsigned int blendMask : 4; unsigned int alphaDither : 2; unsigned int colorDither : 2; unsigned int combineKey : 1; unsigned int textureConvert : 3; unsigned int textureFilter : 2; unsigned int textureLUT : 2; unsigned int textureLOD : 1; unsigned int textureDetail : 2; unsigned int texturePersp : 1; unsigned int cycleType : 2; unsigned int unusedColorDither : 1; // unsupported unsigned int pipelineMode : 1; unsigned int pad : 8; }; u64 _u64; struct { u32 l, h; }; }; } otherMode; gDPCombine combine; gDPTile tiles[8], *loadTile; struct Color { f32 r, g, b, a; } fogColor, blendColor, envColor; struct { f32 z, dz; u32 color; } fillColor; struct PrimColor : public Color { f32 l, m; } primColor; struct { f32 z, deltaZ; } primDepth; struct { u32 format, size, width, bpl; u32 address; } textureImage; struct { u32 format, size, width, height, bpl; u32 address, changed; u32 depthImage; } colorImage; u32 depthImageAddress; struct { u32 mode; f32 ulx, uly, lrx, lry; } scissor; struct { s32 k0, k1, k2, k3, k4, k5; } convert; struct { Color center, scale, width; } key; u32 changed; u16 TexFilterPalette[512]; u32 paletteCRC16[16]; u32 paletteCRC256; u32 half_1, half_2; gDPLoadTileInfo loadInfo[512]; }; extern gDPInfo gDP; void gDPSetOtherMode( u32 mode0, u32 mode1 ); void gDPSetPrimDepth( u16 z, u16 dz ); void gDPSetTexturePersp( u32 enable ); void gDPSetTextureLUT( u32 mode ); void gDPSetCombine( s32 muxs0, s32 muxs1 ); void gDPSetColorImage( u32 format, u32 size, u32 width, u32 address ); void gDPSetTextureImage( u32 format, u32 size, u32 width, u32 address ); void gDPSetDepthImage( u32 address ); void gDPSetEnvColor( u32 r, u32 g, u32 b, u32 a ); void gDPSetBlendColor( u32 r, u32 g, u32 b, u32 a ); void gDPSetFogColor( u32 r, u32 g, u32 b, u32 a ); void gDPSetFillColor( u32 c ); void gDPGetFillColor(f32 _fillColor[4]); void gDPSetPrimColor( u32 m, u32 l, u32 r, u32 g, u32 b, u32 a ); void gDPSetTile( u32 format, u32 size, u32 line, u32 tmem, u32 tile, u32 palette, u32 cmt, u32 cms, u32 maskt, u32 masks, u32 shiftt, u32 shifts ); void gDPSetTileSize( u32 tile, u32 uls, u32 ult, u32 lrs, u32 lrt ); void gDPLoadTile( u32 tile, u32 uls, u32 ult, u32 lrs, u32 lrt ); void gDPLoadBlock( u32 tile, u32 uls, u32 ult, u32 lrs, u32 dxt ); void gDPLoadTLUT( u32 tile, u32 uls, u32 ult, u32 lrs, u32 lrt ); void gDPSetScissor( u32 mode, f32 ulx, f32 uly, f32 lrx, f32 lry ); void gDPFillRectangle( s32 ulx, s32 uly, s32 lrx, s32 lry ); void gDPSetConvert( s32 k0, s32 k1, s32 k2, s32 k3, s32 k4, s32 k5 ); void gDPSetKeyR( u32 cR, u32 sR, u32 wR ); void gDPSetKeyGB(u32 cG, u32 sG, u32 wG, u32 cB, u32 sB, u32 wB ); void gDPTextureRectangle( f32 ulx, f32 uly, f32 lrx, f32 lry, s32 tile, f32 s, f32 t, f32 dsdx, f32 dtdy ); void gDPTextureRectangleFlip( f32 ulx, f32 uly, f32 lrx, f32 lry, s32 tile, f32 s, f32 t, f32 dsdx, f32 dtdy ); void gDPFullSync(); void gDPTileSync(); void gDPPipeSync(); void gDPLoadSync(); void gDPNoOp(); void gDPTriFill( u32 w0, u32 w1 ); void gDPTriShade( u32 w0, u32 w1 ); void gDPTriTxtr( u32 w0, u32 w1 ); void gDPTriShadeTxtr( u32 w0, u32 w1 ); void gDPTriFillZ( u32 w0, u32 w1 ); void gDPTriShadeZ( u32 w0, u32 w1 ); void gDPTriTxtrZ( u32 w0, u32 w1 ); void gDPTriShadeTxtrZ( u32 w0, u32 w1 ); void gDPFillRDRAM( u32 address, s32 ulx, s32 uly, s32 lrx, s32 lry, u32 width, u32 size, u32 color, bool scissor=true ); #endif mupen64plus-video-gliden64/src/F3DDKR.cpp000664 001750 001750 00000006765 12655644434 021065 0ustar00sergiosergio000000 000000 #include "GLideN64.h" #include "Debug.h" #include "F3D.h" #include "F3DDKR.h" #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gSP.h" #include "gDP.h" #include "GBI.h" void F3DDKR_DMA_Mtx( u32 w0, u32 w1 ) { if (_SHIFTR( w0, 0, 16 ) != 64) { #ifdef DEBUG DebugMsg( DEBUG_MEDIUM | DEBUG_HIGH | DEBUG_ERROR, "G_MTX: address = 0x%08X length = %i params = 0x%02X\n", w1, _SHIFTR( w0, 0, 16 ), _SHIFTR( w0, 16, 8 ) ); #endif return; } u32 index = _SHIFTR( w0, 16, 4 ); u32 multiply; if (index == 0) {// DKR index = _SHIFTR( w0, 22, 2 ); multiply = 0; } else { // JFG multiply = _SHIFTR( w0, 23, 1 ); } gSPDMAMatrix( w1, index, multiply ); } void F3DDKR_DMA_Vtx( u32 w0, u32 w1 ) { if ((w0 & F3DDKR_VTX_APPEND)) { if (gSP.matrix.billboard) gSP.vertexi = 1; } else gSP.vertexi = 0; u32 n = _SHIFTR( w0, 19, 5 ) + 1; gSPDMAVertex( w1, n, gSP.vertexi + _SHIFTR( w0, 9, 5 ) ); gSP.vertexi += n; } void F3DJFG_DMA_Vtx(u32 w0, u32 w1) { if ((w0 & F3DDKR_VTX_APPEND)) { if (gSP.matrix.billboard) gSP.vertexi = 1; } else gSP.vertexi = 0; u32 n = _SHIFTR(w0, 19, 5); gSPDMAVertex(w1, n, gSP.vertexi + _SHIFTR(w0, 9, 5)); gSP.vertexi += n; } void F3DDKR_DMA_Tri(u32 w0, u32 w1) { gSPDMATriangles( w1, _SHIFTR( w0, 4, 12 ) ); gSP.vertexi = 0; } void F3DDKR_DMA_DList( u32 w0, u32 w1 ) { gSPDlistCount(_SHIFTR(w0, 16, 8), w1); } void F3DDKR_DMA_Offsets( u32 w0, u32 w1 ) { gSPSetDMAOffsets( _SHIFTR( w0, 0, 24 ), _SHIFTR( w1, 0, 24 ) ); } void F3DDKR_DMA_Tex_Offset(u32 w0, u32 w1) { gSPSetDMATexOffset(w1); } void F3DDKR_MoveWord( u32 w0, u32 w1 ) { switch (_SHIFTR( w0, 0, 8 )) { case 0x02: gSP.matrix.billboard = w1 & 1; break; case 0x0A: gSP.matrix.modelViewi = _SHIFTR( w1, 6, 2 ); gSP.changed |= CHANGED_MATRIX; break; default: F3D_MoveWord( w0, w1 ); break; } } void F3DDKR_Init() { gSPSetupFunctions(); // Set GeometryMode flags GBI_InitFlags( F3D ); GBI.PCStackSize = 10; // GBI Command Command Value Command Function GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_DMA_MTX, F3DDKR_DMA_MTX, F3DDKR_DMA_Mtx ); GBI_SetGBI( G_DMA_TEX_OFFSET, F3DDKR_DMA_TEX_OFFSET, F3DDKR_DMA_Tex_Offset ); GBI_SetGBI( G_MOVEMEM, F3D_MOVEMEM, F3D_MoveMem ); GBI_SetGBI( G_DMA_VTX, F3DDKR_DMA_VTX, F3DDKR_DMA_Vtx ); GBI_SetGBI( G_DL, F3D_DL, F3D_DList ); GBI_SetGBI( G_DMA_DL, F3DDKR_DMA_DL, F3DDKR_DMA_DList ); GBI_SetGBI( G_DMA_TRI, F3DDKR_DMA_TRI, F3DDKR_DMA_Tri ); GBI_SetGBI( G_DMA_OFFSETS, F3DDKR_DMA_OFFSETS, F3DDKR_DMA_Offsets ); GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3D_CullDL ); GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3DDKR_MoveWord ); GBI_SetGBI( G_TEXTURE, F3D_TEXTURE, F3D_Texture ); GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L ); GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL ); GBI_SetGBI( G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, F3D_SetGeometryMode ); GBI_SetGBI( G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE, F3D_ClearGeometryMode ); GBI_SetGBI( G_QUAD, F3D_QUAD, F3D_Quad ); GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_RDPHALF_CONT, F3D_RDPHALF_CONT, F3D_RDPHalf_Cont ); GBI_SetGBI( G_TRI4, F3D_TRI4, F3D_Tri4 ); gSPSetDMAOffsets( 0, 0 ); } void F3DJFG_Init() { F3DDKR_Init(); GBI_SetGBI(G_DMA_VTX, F3DDKR_DMA_VTX, F3DJFG_DMA_Vtx); } mupen64plus-core/src/api/audio_backend.h000664 001750 001750 00000004066 12655644434 021336 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - audio_backend.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2015 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file contains the definitions for the audio backend functions which * will be called from other Core modules. */ #if !defined(M64P_API_AUDIO_BACKEND_H) #define M64P_API_AUDIO_BACKEND_H #include "m64p_types.h" #include /* Thin wrappers to ease usage of backend callbacks - used by ai_controller.c */ void set_audio_format(struct m64p_audio_backend* backend, unsigned int frequency, unsigned int bits); void push_audio_samples(struct m64p_audio_backend* backend, const void* buffer, size_t size); #endif /* M64P_API_AUDIO_BACKEND_H */ mupen64plus-video-gliden64/src/GLideNHQ/TextureFilters_hq2x.h000664 001750 001750 00000063255 12655644434 025100 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Copyright (C) 2007 Hiroshi Morii * Modified for the Texture Filtering library */ case 0 : case 1 : case 4 : case 5 : case 32 : case 33 : case 36 : case 37 : case 128 : case 129 : case 132 : case 133 : case 160 : case 161 : case 164 : case 165 : { P0 = I211(4, 1, 3); P1 = I211(4, 1, 5); P2 = I211(4, 3, 7); P3 = I211(4, 5, 7); } break; case 2 : case 34 : case 130 : case 162 : { P0 = I31(4, 0); P1 = I31(4, 2); P2 = I211(4, 3, 7); P3 = I211(4, 5, 7); } break; case 3 : case 35 : case 131 : case 163 : { P0 = I31(4, 3); P1 = I31(4, 2); P2 = I211(4, 3, 7); P3 = I211(4, 5, 7); } break; case 6 : case 38 : case 134 : case 166 : { P0 = I31(4, 0); P1 = I31(4, 5); P2 = I211(4, 3, 7); P3 = I211(4, 5, 7); } break; case 7 : case 39 : case 135 : case 167 : { P0 = I31(4, 3); P1 = I31(4, 5); P2 = I211(4, 3, 7); P3 = I211(4, 5, 7); } break; case 8 : case 12 : case 136 : case 140 : { P0 = I31(4, 0); P1 = I211(4, 1, 5); P2 = I31(4, 6); P3 = I211(4, 5, 7); } break; case 9 : case 13 : case 137 : case 141 : { P0 = I31(4, 1); P1 = I211(4, 1, 5); P2 = I31(4, 6); P3 = I211(4, 5, 7); } break; case 10 : case 138 : { P1 = I31(4, 2); P2 = I31(4, 6); P3 = I211(4, 5, 7); if (HQ2X_MUL) { P0 = I31(4, 0); } else { P0 = I211(4, 1, 3); } } break; case 11 : case 139 : { P1 = I31(4, 2); P2 = I31(4, 6); P3 = I211(4, 5, 7); if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I211(4, 1, 3); } } break; case 14 : case 142 : { P2 = I31(4, 6); P3 = I211(4, 5, 7); if (HQ2X_MUL) { P0 = I31(4, 0); P1 = I31(4, 5); } else { P0 = I332(1, 3, 4); P1 = I521(4, 1, 5); } } break; case 15 : case 143 : { P2 = I31(4, 6); P3 = I211(4, 5, 7); if (HQ2X_MUL) { P0 = IC(4); P1 = I31(4, 5); } else { P0 = I332(1, 3, 4); P1 = I521(4, 1, 5); } } break; case 16 : case 17 : case 48 : case 49 : { P0 = I211(4, 1, 3); P1 = I31(4, 2); P2 = I211(4, 3, 7); P3 = I31(4, 8); } break; case 18 : case 50 : { P0 = I31(4, 0); P2 = I211(4, 3, 7); P3 = I31(4, 8); if (HQ2X_MUR) { P1 = I31(4, 2); } else { P1 = I211(4, 1, 5); } } break; case 19 : case 51 : { P2 = I211(4, 3, 7); P3 = I31(4, 8); if (HQ2X_MUR) { P0 = I31(4, 3); P1 = I31(4, 2); } else { P0 = I521(4, 1, 3); P1 = I332(1, 5, 4); } } break; case 20 : case 21 : case 52 : case 53 : { P0 = I211(4, 1, 3); P1 = I31(4, 1); P2 = I211(4, 3, 7); P3 = I31(4, 8); } break; case 22 : case 54 : { P0 = I31(4, 0); P2 = I211(4, 3, 7); P3 = I31(4, 8); if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I211(4, 1, 5); } } break; case 23 : case 55 : { P2 = I211(4, 3, 7); P3 = I31(4, 8); if (HQ2X_MUR) { P0 = I31(4, 3); P1 = IC(4); } else { P0 = I521(4, 1, 3); P1 = I332(1, 5, 4); } } break; case 24 : case 66 : { P0 = I31(4, 0); P1 = I31(4, 2); P2 = I31(4, 6); P3 = I31(4, 8); } break; case 25 : { P0 = I31(4, 1); P1 = I31(4, 2); P2 = I31(4, 6); P3 = I31(4, 8); } break; case 26 : case 31 : case 95 : { P2 = I31(4, 6); P3 = I31(4, 8); if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I211(4, 1, 3); } if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I211(4, 1, 5); } } break; case 27 : case 75 : { P1 = I31(4, 2); P2 = I31(4, 6); P3 = I31(4, 8); if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I211(4, 1, 3); } } break; case 28 : { P0 = I31(4, 0); P1 = I31(4, 1); P2 = I31(4, 6); P3 = I31(4, 8); } break; case 29 : { P0 = I31(4, 1); P1 = I31(4, 1); P2 = I31(4, 6); P3 = I31(4, 8); } break; case 30 : case 86 : { P0 = I31(4, 0); P2 = I31(4, 6); P3 = I31(4, 8); if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I211(4, 1, 5); } } break; case 40 : case 44 : case 168 : case 172 : { P0 = I31(4, 0); P1 = I211(4, 1, 5); P2 = I31(4, 7); P3 = I211(4, 5, 7); } break; case 41 : case 45 : case 169 : case 173 : { P0 = I31(4, 1); P1 = I211(4, 1, 5); P2 = I31(4, 7); P3 = I211(4, 5, 7); } break; case 42 : case 170 : { P1 = I31(4, 2); P3 = I211(4, 5, 7); if (HQ2X_MUL) { P0 = I31(4, 0); P2 = I31(4, 7); } else { P0 = I332(1, 3, 4); P2 = I521(4, 3, 7); } } break; case 43 : case 171 : { P1 = I31(4, 2); P3 = I211(4, 5, 7); if (HQ2X_MUL) { P0 = IC(4); P2 = I31(4, 7); } else { P0 = I332(1, 3, 4); P2 = I521(4, 3, 7); } } break; case 46 : case 174 : { P1 = I31(4, 5); P2 = I31(4, 7); P3 = I211(4, 5, 7); if (HQ2X_MUL) { P0 = I31(4, 0); } else { P0 = I611(4, 1, 3); } } break; case 47 : case 175 : { P1 = I31(4, 5); P2 = I31(4, 7); P3 = I211(4, 5, 7); if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I1411(4, 1, 3); } } break; case 56 : { P0 = I31(4, 0); P1 = I31(4, 2); P2 = I31(4, 7); P3 = I31(4, 8); } break; case 57 : { P0 = I31(4, 1); P1 = I31(4, 2); P2 = I31(4, 7); P3 = I31(4, 8); } break; case 58 : { P2 = I31(4, 7); P3 = I31(4, 8); if (HQ2X_MUL) { P0 = I31(4, 0); } else { P0 = I611(4, 1, 3); } if (HQ2X_MUR) { P1 = I31(4, 2); } else { P1 = I611(4, 1, 5); } } break; case 59 : { P2 = I31(4, 7); P3 = I31(4, 8); if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I211(4, 1, 3); } if (HQ2X_MUR) { P1 = I31(4, 2); } else { P1 = I611(4, 1, 5); } } break; case 60 : { P0 = I31(4, 0); P1 = I31(4, 1); P2 = I31(4, 7); P3 = I31(4, 8); } break; case 61 : { P0 = I31(4, 1); P1 = I31(4, 1); P2 = I31(4, 7); P3 = I31(4, 8); } break; case 62 : { P0 = I31(4, 0); P2 = I31(4, 7); P3 = I31(4, 8); if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I211(4, 1, 5); } } break; case 63 : { P2 = I31(4, 7); P3 = I31(4, 8); if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I1411(4, 1, 3); } if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I211(4, 1, 5); } } break; case 64 : case 65 : case 68 : case 69 : { P0 = I211(4, 1, 3); P1 = I211(4, 1, 5); P2 = I31(4, 6); P3 = I31(4, 8); } break; case 67 : { P0 = I31(4, 3); P1 = I31(4, 2); P2 = I31(4, 6); P3 = I31(4, 8); } break; case 70 : { P0 = I31(4, 0); P1 = I31(4, 5); P2 = I31(4, 6); P3 = I31(4, 8); } break; case 71 : { P0 = I31(4, 3); P1 = I31(4, 5); P2 = I31(4, 6); P3 = I31(4, 8); } break; case 72 : case 76 : { P0 = I31(4, 0); P1 = I211(4, 1, 5); P3 = I31(4, 8); if (HQ2X_MDL) { P2 = I31(4, 6); } else { P2 = I211(4, 3, 7); } } break; case 73 : case 77 : { P1 = I211(4, 1, 5); P3 = I31(4, 8); if (HQ2X_MDL) { P0 = I31(4, 1); P2 = I31(4, 6); } else { P0 = I521(4, 3, 1); P2 = I332(3, 7, 4); } } break; case 74 : case 107 : case 123 : { P1 = I31(4, 2); P3 = I31(4, 8); if (HQ2X_MDL) { P2 = IC(4); } else { P2 = I211(4, 3, 7); } if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I211(4, 1, 3); } } break; case 78 : { P1 = I31(4, 5); P3 = I31(4, 8); if (HQ2X_MDL) { P2 = I31(4, 6); } else { P2 = I611(4, 3, 7); } if (HQ2X_MUL) { P0 = I31(4, 0); } else { P0 = I611(4, 1, 3); } } break; case 79 : { P1 = I31(4, 5); P3 = I31(4, 8); if (HQ2X_MDL) { P2 = I31(4, 6); } else { P2 = I611(4, 3, 7); } if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I211(4, 1, 3); } } break; case 80 : case 81 : { P0 = I211(4, 1, 3); P1 = I31(4, 2); P2 = I31(4, 6); if (HQ2X_MDR) { P3 = I31(4, 8); } else { P3 = I211(4, 5, 7); } } break; case 82 : case 214 : case 222 : { P0 = I31(4, 0); P2 = I31(4, 6); if (HQ2X_MDR) { P3 = IC(4); } else { P3 = I211(4, 5, 7); } if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I211(4, 1, 5); } } break; case 83 : { P0 = I31(4, 3); P2 = I31(4, 6); if (HQ2X_MDR) { P3 = I31(4, 8); } else { P3 = I611(4, 5, 7); } if (HQ2X_MUR) { P1 = I31(4, 2); } else { P1 = I611(4, 1, 5); } } break; case 84 : case 85 : { P0 = I211(4, 1, 3); P2 = I31(4, 6); if (HQ2X_MDR) { P1 = I31(4, 1); P3 = I31(4, 8); } else { P1 = I521(4, 5, 1); P3 = I332(5, 7, 4); } } break; case 87 : { P0 = I31(4, 3); P2 = I31(4, 6); if (HQ2X_MDR) { P3 = I31(4, 8); } else { P3 = I611(4, 5, 7); } if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I211(4, 1, 5); } } break; case 88 : case 248 : case 250 : { P0 = I31(4, 0); P1 = I31(4, 2); if (HQ2X_MDL) { P2 = IC(4); } else { P2 = I211(4, 3, 7); } if (HQ2X_MDR) { P3 = IC(4); } else { P3 = I211(4, 5, 7); } } break; case 89 : { P0 = I31(4, 1); P1 = I31(4, 2); if (HQ2X_MDL) { P2 = I31(4, 6); } else { P2 = I611(4, 3, 7); } if (HQ2X_MDR) { P3 = I31(4, 8); } else { P3 = I611(4, 5, 7); } } break; case 90 : { if (HQ2X_MDL) { P2 = I31(4, 6); } else { P2 = I611(4, 3, 7); } if (HQ2X_MDR) { P3 = I31(4, 8); } else { P3 = I611(4, 5, 7); } if (HQ2X_MUL) { P0 = I31(4, 0); } else { P0 = I611(4, 1, 3); } if (HQ2X_MUR) { P1 = I31(4, 2); } else { P1 = I611(4, 1, 5); } } break; case 91 : { if (HQ2X_MDL) { P2 = I31(4, 6); } else { P2 = I611(4, 3, 7); } if (HQ2X_MDR) { P3 = I31(4, 8); } else { P3 = I611(4, 5, 7); } if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I211(4, 1, 3); } if (HQ2X_MUR) { P1 = I31(4, 2); } else { P1 = I611(4, 1, 5); } } break; case 92 : { P0 = I31(4, 0); P1 = I31(4, 1); if (HQ2X_MDL) { P2 = I31(4, 6); } else { P2 = I611(4, 3, 7); } if (HQ2X_MDR) { P3 = I31(4, 8); } else { P3 = I611(4, 5, 7); } } break; case 93 : { P0 = I31(4, 1); P1 = I31(4, 1); if (HQ2X_MDL) { P2 = I31(4, 6); } else { P2 = I611(4, 3, 7); } if (HQ2X_MDR) { P3 = I31(4, 8); } else { P3 = I611(4, 5, 7); } } break; case 94 : { if (HQ2X_MDL) { P2 = I31(4, 6); } else { P2 = I611(4, 3, 7); } if (HQ2X_MDR) { P3 = I31(4, 8); } else { P3 = I611(4, 5, 7); } if (HQ2X_MUL) { P0 = I31(4, 0); } else { P0 = I611(4, 1, 3); } if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I211(4, 1, 5); } } break; case 96 : case 97 : case 100 : case 101 : { P0 = I211(4, 1, 3); P1 = I211(4, 1, 5); P2 = I31(4, 3); P3 = I31(4, 8); } break; case 98 : { P0 = I31(4, 0); P1 = I31(4, 2); P2 = I31(4, 3); P3 = I31(4, 8); } break; case 99 : { P0 = I31(4, 3); P1 = I31(4, 2); P2 = I31(4, 3); P3 = I31(4, 8); } break; case 102 : { P0 = I31(4, 0); P1 = I31(4, 5); P2 = I31(4, 3); P3 = I31(4, 8); } break; case 103 : { P0 = I31(4, 3); P1 = I31(4, 5); P2 = I31(4, 3); P3 = I31(4, 8); } break; case 104 : case 108 : { P0 = I31(4, 0); P1 = I211(4, 1, 5); P3 = I31(4, 8); if (HQ2X_MDL) { P2 = IC(4); } else { P2 = I211(4, 3, 7); } } break; case 105 : case 109 : { P1 = I211(4, 1, 5); P3 = I31(4, 8); if (HQ2X_MDL) { P0 = I31(4, 1); P2 = IC(4); } else { P0 = I521(4, 3, 1); P2 = I332(3, 7, 4); } } break; case 106 : case 120 : { P0 = I31(4, 0); P1 = I31(4, 2); P3 = I31(4, 8); if (HQ2X_MDL) { P2 = IC(4); } else { P2 = I211(4, 3, 7); } } break; case 110 : { P0 = I31(4, 0); P1 = I31(4, 5); P3 = I31(4, 8); if (HQ2X_MDL) { P2 = IC(4); } else { P2 = I211(4, 3, 7); } } break; case 111 : { P1 = I31(4, 5); P3 = I31(4, 8); if (HQ2X_MDL) { P2 = IC(4); } else { P2 = I211(4, 3, 7); } if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I1411(4, 1, 3); } } break; case 112 : case 113 : { P0 = I211(4, 1, 3); P1 = I31(4, 2); if (HQ2X_MDR) { P2 = I31(4, 3); P3 = I31(4, 8); } else { P2 = I521(4, 7, 3); P3 = I332(5, 7, 4); } } break; case 114 : { P0 = I31(4, 0); P2 = I31(4, 3); if (HQ2X_MDR) { P3 = I31(4, 8); } else { P3 = I611(4, 5, 7); } if (HQ2X_MUR) { P1 = I31(4, 2); } else { P1 = I611(4, 1, 5); } } break; case 115 : { P0 = I31(4, 3); P2 = I31(4, 3); if (HQ2X_MDR) { P3 = I31(4, 8); } else { P3 = I611(4, 5, 7); } if (HQ2X_MUR) { P1 = I31(4, 2); } else { P1 = I611(4, 1, 5); } } break; case 116 : case 117 : { P0 = I211(4, 1, 3); P1 = I31(4, 1); P2 = I31(4, 3); if (HQ2X_MDR) { P3 = I31(4, 8); } else { P3 = I611(4, 5, 7); } } break; case 118 : { P0 = I31(4, 0); P2 = I31(4, 3); P3 = I31(4, 8); if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I211(4, 1, 5); } } break; case 119 : { P2 = I31(4, 3); P3 = I31(4, 8); if (HQ2X_MUR) { P0 = I31(4, 3); P1 = IC(4); } else { P0 = I521(4, 1, 3); P1 = I332(1, 5, 4); } } break; case 121 : { P0 = I31(4, 1); P1 = I31(4, 2); if (HQ2X_MDL) { P2 = IC(4); } else { P2 = I211(4, 3, 7); } if (HQ2X_MDR) { P3 = I31(4, 8); } else { P3 = I611(4, 5, 7); } } break; case 122 : { if (HQ2X_MDL) { P2 = IC(4); } else { P2 = I211(4, 3, 7); } if (HQ2X_MDR) { P3 = I31(4, 8); } else { P3 = I611(4, 5, 7); } if (HQ2X_MUL) { P0 = I31(4, 0); } else { P0 = I611(4, 1, 3); } if (HQ2X_MUR) { P1 = I31(4, 2); } else { P1 = I611(4, 1, 5); } } break; case 124 : { P0 = I31(4, 0); P1 = I31(4, 1); P3 = I31(4, 8); if (HQ2X_MDL) { P2 = IC(4); } else { P2 = I211(4, 3, 7); } } break; case 125 : { P1 = I31(4, 1); P3 = I31(4, 8); if (HQ2X_MDL) { P0 = I31(4, 1); P2 = IC(4); } else { P0 = I521(4, 3, 1); P2 = I332(3, 7, 4); } } break; case 126 : { P0 = I31(4, 0); P3 = I31(4, 8); if (HQ2X_MDL) { P2 = IC(4); } else { P2 = I211(4, 3, 7); } if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I211(4, 1, 5); } } break; case 127 : { P3 = I31(4, 8); if (HQ2X_MDL) { P2 = IC(4); } else { P2 = I211(4, 3, 7); } if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I1411(4, 1, 3); } if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I211(4, 1, 5); } } break; case 144 : case 145 : case 176 : case 177 : { P0 = I211(4, 1, 3); P1 = I31(4, 2); P2 = I211(4, 3, 7); P3 = I31(4, 7); } break; case 146 : case 178 : { P0 = I31(4, 0); P2 = I211(4, 3, 7); if (HQ2X_MUR) { P1 = I31(4, 2); P3 = I31(4, 7); } else { P1 = I332(1, 5, 4); P3 = I521(4, 5, 7); } } break; case 147 : case 179 : { P0 = I31(4, 3); P2 = I211(4, 3, 7); P3 = I31(4, 7); if (HQ2X_MUR) { P1 = I31(4, 2); } else { P1 = I611(4, 1, 5); } } break; case 148 : case 149 : case 180 : case 181 : { P0 = I211(4, 1, 3); P1 = I31(4, 1); P2 = I211(4, 3, 7); P3 = I31(4, 7); } break; case 150 : case 182 : { P0 = I31(4, 0); P2 = I211(4, 3, 7); if (HQ2X_MUR) { P1 = IC(4); P3 = I31(4, 7); } else { P1 = I332(1, 5, 4); P3 = I521(4, 5, 7); } } break; case 151 : case 183 : { P0 = I31(4, 3); P2 = I211(4, 3, 7); P3 = I31(4, 7); if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I1411(4, 1, 5); } } break; case 152 : { P0 = I31(4, 0); P1 = I31(4, 2); P2 = I31(4, 6); P3 = I31(4, 7); } break; case 153 : { P0 = I31(4, 1); P1 = I31(4, 2); P2 = I31(4, 6); P3 = I31(4, 7); } break; case 154 : { P2 = I31(4, 6); P3 = I31(4, 7); if (HQ2X_MUL) { P0 = I31(4, 0); } else { P0 = I611(4, 1, 3); } if (HQ2X_MUR) { P1 = I31(4, 2); } else { P1 = I611(4, 1, 5); } } break; case 155 : { P1 = I31(4, 2); P2 = I31(4, 6); P3 = I31(4, 7); if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I211(4, 1, 3); } } break; case 156 : { P0 = I31(4, 0); P1 = I31(4, 1); P2 = I31(4, 6); P3 = I31(4, 7); } break; case 157 : { P0 = I31(4, 1); P1 = I31(4, 1); P2 = I31(4, 6); P3 = I31(4, 7); } break; case 158 : { P2 = I31(4, 6); P3 = I31(4, 7); if (HQ2X_MUL) { P0 = I31(4, 0); } else { P0 = I611(4, 1, 3); } if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I211(4, 1, 5); } } break; case 159 : { P2 = I31(4, 6); P3 = I31(4, 7); if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I211(4, 1, 3); } if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I1411(4, 1, 5); } } break; case 184 : { P0 = I31(4, 0); P1 = I31(4, 2); P2 = I31(4, 7); P3 = I31(4, 7); } break; case 185 : { P0 = I31(4, 1); P1 = I31(4, 2); P2 = I31(4, 7); P3 = I31(4, 7); } break; case 186 : { P2 = I31(4, 7); P3 = I31(4, 7); if (HQ2X_MUL) { P0 = I31(4, 0); } else { P0 = I611(4, 1, 3); } if (HQ2X_MUR) { P1 = I31(4, 2); } else { P1 = I611(4, 1, 5); } } break; case 187 : { P1 = I31(4, 2); P3 = I31(4, 7); if (HQ2X_MUL) { P0 = IC(4); P2 = I31(4, 7); } else { P0 = I332(1, 3, 4); P2 = I521(4, 3, 7); } } break; case 188 : { P0 = I31(4, 0); P1 = I31(4, 1); P2 = I31(4, 7); P3 = I31(4, 7); } break; case 189 : { P0 = I31(4, 1); P1 = I31(4, 1); P2 = I31(4, 7); P3 = I31(4, 7); } break; case 190 : { P0 = I31(4, 0); P2 = I31(4, 7); if (HQ2X_MUR) { P1 = IC(4); P3 = I31(4, 7); } else { P1 = I332(1, 5, 4); P3 = I521(4, 5, 7); } } break; case 191 : { P2 = I31(4, 7); P3 = I31(4, 7); if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I1411(4, 1, 3); } if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I1411(4, 1, 5); } } break; case 192 : case 193 : case 196 : case 197 : { P0 = I211(4, 1, 3); P1 = I211(4, 1, 5); P2 = I31(4, 6); P3 = I31(4, 5); } break; case 194 : { P0 = I31(4, 0); P1 = I31(4, 2); P2 = I31(4, 6); P3 = I31(4, 5); } break; case 195 : { P0 = I31(4, 3); P1 = I31(4, 2); P2 = I31(4, 6); P3 = I31(4, 5); } break; case 198 : { P0 = I31(4, 0); P1 = I31(4, 5); P2 = I31(4, 6); P3 = I31(4, 5); } break; case 199 : { P0 = I31(4, 3); P1 = I31(4, 5); P2 = I31(4, 6); P3 = I31(4, 5); } break; case 200 : case 204 : { P0 = I31(4, 0); P1 = I211(4, 1, 5); if (HQ2X_MDL) { P2 = I31(4, 6); P3 = I31(4, 5); } else { P2 = I332(3, 7, 4); P3 = I521(4, 7, 5); } } break; case 201 : case 205 : { P0 = I31(4, 1); P1 = I211(4, 1, 5); P3 = I31(4, 5); if (HQ2X_MDL) { P2 = I31(4, 6); } else { P2 = I611(4, 3, 7); } } break; case 202 : { P1 = I31(4, 2); P3 = I31(4, 5); if (HQ2X_MDL) { P2 = I31(4, 6); } else { P2 = I611(4, 3, 7); } if (HQ2X_MUL) { P0 = I31(4, 0); } else { P0 = I611(4, 1, 3); } } break; case 203 : { P1 = I31(4, 2); P2 = I31(4, 6); P3 = I31(4, 5); if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I211(4, 1, 3); } } break; case 206 : { P1 = I31(4, 5); P3 = I31(4, 5); if (HQ2X_MDL) { P2 = I31(4, 6); } else { P2 = I611(4, 3, 7); } if (HQ2X_MUL) { P0 = I31(4, 0); } else { P0 = I611(4, 1, 3); } } break; case 207 : { P2 = I31(4, 6); P3 = I31(4, 5); if (HQ2X_MUL) { P0 = IC(4); P1 = I31(4, 5); } else { P0 = I332(1, 3, 4); P1 = I521(4, 1, 5); } } break; case 208 : case 209 : { P0 = I211(4, 1, 3); P1 = I31(4, 2); P2 = I31(4, 6); if (HQ2X_MDR) { P3 = IC(4); } else { P3 = I211(4, 5, 7); } } break; case 210 : case 216 : { P0 = I31(4, 0); P1 = I31(4, 2); P2 = I31(4, 6); if (HQ2X_MDR) { P3 = IC(4); } else { P3 = I211(4, 5, 7); } } break; case 211 : { P0 = I31(4, 3); P1 = I31(4, 2); P2 = I31(4, 6); if (HQ2X_MDR) { P3 = IC(4); } else { P3 = I211(4, 5, 7); } } break; case 212 : case 213 : { P0 = I211(4, 1, 3); P2 = I31(4, 6); if (HQ2X_MDR) { P1 = I31(4, 1); P3 = IC(4); } else { P1 = I521(4, 5, 1); P3 = I332(5, 7, 4); } } break; case 215 : { P0 = I31(4, 3); P2 = I31(4, 6); if (HQ2X_MDR) { P3 = IC(4); } else { P3 = I211(4, 5, 7); } if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I1411(4, 1, 5); } } break; case 217 : { P0 = I31(4, 1); P1 = I31(4, 2); P2 = I31(4, 6); if (HQ2X_MDR) { P3 = IC(4); } else { P3 = I211(4, 5, 7); } } break; case 218 : { if (HQ2X_MDL) { P2 = I31(4, 6); } else { P2 = I611(4, 3, 7); } if (HQ2X_MDR) { P3 = IC(4); } else { P3 = I211(4, 5, 7); } if (HQ2X_MUL) { P0 = I31(4, 0); } else { P0 = I611(4, 1, 3); } if (HQ2X_MUR) { P1 = I31(4, 2); } else { P1 = I611(4, 1, 5); } } break; case 219 : { P1 = I31(4, 2); P2 = I31(4, 6); if (HQ2X_MDR) { P3 = IC(4); } else { P3 = I211(4, 5, 7); } if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I211(4, 1, 3); } } break; case 220 : { P0 = I31(4, 0); P1 = I31(4, 1); if (HQ2X_MDL) { P2 = I31(4, 6); } else { P2 = I611(4, 3, 7); } if (HQ2X_MDR) { P3 = IC(4); } else { P3 = I211(4, 5, 7); } } break; case 221 : { P0 = I31(4, 1); P2 = I31(4, 6); if (HQ2X_MDR) { P1 = I31(4, 1); P3 = IC(4); } else { P1 = I521(4, 5, 1); P3 = I332(5, 7, 4); } } break; case 223 : { P2 = I31(4, 6); if (HQ2X_MDR) { P3 = IC(4); } else { P3 = I211(4, 5, 7); } if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I211(4, 1, 3); } if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I1411(4, 1, 5); } } break; case 224 : case 225 : case 228 : case 229 : { P0 = I211(4, 1, 3); P1 = I211(4, 1, 5); P2 = I31(4, 3); P3 = I31(4, 5); } break; case 226 : { P0 = I31(4, 0); P1 = I31(4, 2); P2 = I31(4, 3); P3 = I31(4, 5); } break; case 227 : { P0 = I31(4, 3); P1 = I31(4, 2); P2 = I31(4, 3); P3 = I31(4, 5); } break; case 230 : { P0 = I31(4, 0); P1 = I31(4, 5); P2 = I31(4, 3); P3 = I31(4, 5); } break; case 231 : { P0 = I31(4, 3); P1 = I31(4, 5); P2 = I31(4, 3); P3 = I31(4, 5); } break; case 232 : case 236 : { P0 = I31(4, 0); P1 = I211(4, 1, 5); if (HQ2X_MDL) { P2 = IC(4); P3 = I31(4, 5); } else { P2 = I332(3, 7, 4); P3 = I521(4, 7, 5); } } break; case 233 : case 237 : { P0 = I31(4, 1); P1 = I211(4, 1, 5); P3 = I31(4, 5); if (HQ2X_MDL) { P2 = IC(4); } else { P2 = I1411(4, 3, 7); } } break; case 234 : { P1 = I31(4, 2); P3 = I31(4, 5); if (HQ2X_MDL) { P2 = IC(4); } else { P2 = I211(4, 3, 7); } if (HQ2X_MUL) { P0 = I31(4, 0); } else { P0 = I611(4, 1, 3); } } break; case 235 : { P1 = I31(4, 2); P3 = I31(4, 5); if (HQ2X_MDL) { P2 = IC(4); } else { P2 = I1411(4, 3, 7); } if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I211(4, 1, 3); } } break; case 238 : { P0 = I31(4, 0); P1 = I31(4, 5); if (HQ2X_MDL) { P2 = IC(4); P3 = I31(4, 5); } else { P2 = I332(3, 7, 4); P3 = I521(4, 7, 5); } } break; case 239 : { P1 = I31(4, 5); P3 = I31(4, 5); if (HQ2X_MDL) { P2 = IC(4); } else { P2 = I1411(4, 3, 7); } if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I1411(4, 1, 3); } } break; case 240 : case 241 : { P0 = I211(4, 1, 3); P1 = I31(4, 2); if (HQ2X_MDR) { P2 = I31(4, 3); P3 = IC(4); } else { P2 = I521(4, 7, 3); P3 = I332(5, 7, 4); } } break; case 242 : { P0 = I31(4, 0); P2 = I31(4, 3); if (HQ2X_MDR) { P3 = IC(4); } else { P3 = I211(4, 5, 7); } if (HQ2X_MUR) { P1 = I31(4, 2); } else { P1 = I611(4, 1, 5); } } break; case 243 : { P0 = I31(4, 3); P1 = I31(4, 2); if (HQ2X_MDR) { P2 = I31(4, 3); P3 = IC(4); } else { P2 = I521(4, 7, 3); P3 = I332(5, 7, 4); } } break; case 244 : case 245 : { P0 = I211(4, 1, 3); P1 = I31(4, 1); P2 = I31(4, 3); if (HQ2X_MDR) { P3 = IC(4); } else { P3 = I1411(4, 5, 7); } } break; case 246 : { P0 = I31(4, 0); P2 = I31(4, 3); if (HQ2X_MDR) { P3 = IC(4); } else { P3 = I1411(4, 5, 7); } if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I211(4, 1, 5); } } break; case 247 : { P0 = I31(4, 3); P2 = I31(4, 3); if (HQ2X_MDR) { P3 = IC(4); } else { P3 = I1411(4, 5, 7); } if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I1411(4, 1, 5); } } break; case 249 : { P0 = I31(4, 1); P1 = I31(4, 2); if (HQ2X_MDL) { P2 = IC(4); } else { P2 = I1411(4, 3, 7); } if (HQ2X_MDR) { P3 = IC(4); } else { P3 = I211(4, 5, 7); } } break; case 251 : { P1 = I31(4, 2); if (HQ2X_MDL) { P2 = IC(4); } else { P2 = I1411(4, 3, 7); } if (HQ2X_MDR) { P3 = IC(4); } else { P3 = I211(4, 5, 7); } if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I211(4, 1, 3); } } break; case 252 : { P0 = I31(4, 0); P1 = I31(4, 1); if (HQ2X_MDL) { P2 = IC(4); } else { P2 = I211(4, 3, 7); } if (HQ2X_MDR) { P3 = IC(4); } else { P3 = I1411(4, 5, 7); } } break; case 253 : { P0 = I31(4, 1); P1 = I31(4, 1); if (HQ2X_MDL) { P2 = IC(4); } else { P2 = I1411(4, 3, 7); } if (HQ2X_MDR) { P3 = IC(4); } else { P3 = I1411(4, 5, 7); } } break; case 254 : { P0 = I31(4, 0); if (HQ2X_MDL) { P2 = IC(4); } else { P2 = I211(4, 3, 7); } if (HQ2X_MDR) { P3 = IC(4); } else { P3 = I1411(4, 5, 7); } if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I211(4, 1, 5); } } break; case 255 : { if (HQ2X_MDL) { P2 = IC(4); } else { P2 = I1411(4, 3, 7); } if (HQ2X_MDR) { P3 = IC(4); } else { P3 = I1411(4, 5, 7); } if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I1411(4, 1, 3); } if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I1411(4, 1, 5); } } break; mupen64plus-video-gliden64/src/F3DWRUS.cpp000664 001750 001750 00000004773 12655644434 021242 0ustar00sergiosergio000000 000000 #include "GLideN64.h" #include "Debug.h" #include "F3D.h" #include "F3DEX.h" #include "F3DWRUS.h" #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gSP.h" #include "gDP.h" #include "GBI.h" void F3DWRUS_Vtx( u32 w0, u32 w1 ) { gSPVertex( w1, _SHIFTR( w0, 9, 7 ), _SHIFTR( w0, 16, 8 ) / 5 ); } void F3DWRUS_Tri1( u32 w0, u32 w1 ) { gSP1Triangle( _SHIFTR( w1, 16, 8 ) / 5, _SHIFTR( w1, 8, 8 ) / 5, _SHIFTR( w1, 0, 8 ) / 5); } void F3DWRUS_Tri2( u32 w0, u32 w1 ) { gSP2Triangles( _SHIFTR( w0, 16, 8 ) / 5, _SHIFTR( w0, 8, 8 ) / 5, _SHIFTR( w0, 0, 8 ) / 5, 0, _SHIFTR( w1, 16, 8 ) / 5, _SHIFTR( w1, 8, 8 ) / 5, _SHIFTR( w1, 0, 8 ) / 5, 0); } void F3DWRUS_Quad( u32 w0, u32 w1 ) { gSP1Quadrangle( _SHIFTR( w1, 24, 8 ) / 5, _SHIFTR( w1, 16, 8 ) / 5, _SHIFTR( w1, 8, 8 ) / 5, _SHIFTR( w1, 0, 8 ) / 5 ); } void F3DWRUS_Init() { gSPSetupFunctions(); // Set GeometryMode flags GBI_InitFlags( F3D ); GBI.PCStackSize = 10; // GBI Command Command Value Command Function GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_MTX, F3D_MTX, F3D_Mtx ); GBI_SetGBI( G_RESERVED0, F3D_RESERVED0, F3D_Reserved0 ); GBI_SetGBI( G_MOVEMEM, F3D_MOVEMEM, F3D_MoveMem ); GBI_SetGBI( G_VTX, F3D_VTX, F3DWRUS_Vtx ); GBI_SetGBI( G_RESERVED1, F3D_RESERVED1, F3D_Reserved1 ); GBI_SetGBI( G_DL, F3D_DL, F3D_DList ); GBI_SetGBI( G_RESERVED2, F3D_RESERVED2, F3D_Reserved2 ); GBI_SetGBI( G_RESERVED3, F3D_RESERVED3, F3D_Reserved3 ); GBI_SetGBI( G_SPRITE2D_BASE, F3D_SPRITE2D_BASE, F3D_Sprite2D_Base ); GBI_SetGBI( G_TRI1, F3D_TRI1, F3DWRUS_Tri1 ); GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3D_CullDL ); GBI_SetGBI( G_POPMTX, F3D_POPMTX, F3D_PopMtx ); GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3D_MoveWord ); GBI_SetGBI( G_TEXTURE, F3D_TEXTURE, F3D_Texture ); GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L ); GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL ); GBI_SetGBI( G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, F3D_SetGeometryMode ); GBI_SetGBI( G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE, F3D_ClearGeometryMode ); GBI_SetGBI( G_QUAD, F3D_QUAD, F3DWRUS_Quad ); GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_RDPHALF_CONT, F3D_RDPHALF_CONT, F3D_RDPHalf_Cont ); GBI_SetGBI( G_TRI2, F3DWRUS_TRI2, F3DWRUS_Tri2 ); } mupen64plus-video-gliden64/ini/000700 001750 001750 00000000000 12656647145 017405 5ustar00sergiosergio000000 000000 gles2rice/src/OGLCombiner.h000664 001750 001750 00000005125 12655644434 016641 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - OGLCombiner.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Rice1964 * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef _OGL_COMBINER_H_ #define _OGL_COMBINER_H_ #include "Blender.h" #include "Combiner.h" class OGLRender; class COGLColorCombiner : public CColorCombiner { public: bool Initialize(void); void InitCombinerBlenderForSimpleTextureDraw(uint32_t tile); protected: friend class OGLDeviceBuilder; void DisableCombiner(void); void InitCombinerCycleCopy(void); void InitCombinerCycleFill(void); void InitCombinerCycle12(void); COGLColorCombiner(CRender *pRender); ~COGLColorCombiner(); OGLRender *m_pOGLRender; bool m_bSupportAdd; bool m_bSupportSubtract; #ifdef DEBUGGER void DisplaySimpleMuxString(void); #endif }; class COGLBlender : public CBlender { public: void NormalAlphaBlender(void); void DisableAlphaBlender(void); void BlendFunc(uint32_t srcFunc, uint32_t desFunc); void Enable(); void Disable(); protected: friend class OGLDeviceBuilder; COGLBlender(CRender *pRender) : CBlender(pRender), m_pOGLRender((OGLRender*)pRender) {}; ~COGLBlender() {}; OGLRender *m_pOGLRender; }; #endif mupen64plus-video-gliden64/src/ZilmarPluginAPI.cpp000664 001750 001750 00000001475 12655644434 023110 0ustar00sergiosergio000000 000000 #ifdef OS_WINDOWS # include #else # include "winlnxdefs.h" #endif // OS_WINDOWS #include "PluginAPI.h" extern "C" { EXPORT void CALL RomOpen (void) { api().RomOpen(); } EXPORT void CALL CaptureScreen ( char * Directory ) { api().CaptureScreen(Directory); } EXPORT void CALL CloseDLL (void) { api().CloseDLL(); } EXPORT void CALL DllAbout ( HWND hParent ) { api().DllAbout(/*hParent*/); } EXPORT void CALL DllConfig ( HWND hParent ) { api().DllConfig(hParent); } EXPORT void CALL DllTest ( HWND hParent ) { api().DllTest(hParent); } EXPORT void CALL DrawScreen (void) { api().DrawScreen(); } EXPORT void CALL GetDllInfo ( PLUGIN_INFO * PluginInfo ) { api().GetDllInfo(PluginInfo); } EXPORT void CALL ReadScreen (void **dest, long *width, long *height) { api().ReadScreen(dest, width, height); } } gles2rice/src/OGLGraphicsContext.h000664 001750 001750 00000003517 12655644434 020213 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _OGL_CONTEXT_H_ #define _OGL_CONTEXT_H_ #include "typedefs.h" #include "GraphicsContext.h" class COGLGraphicsContext : public CGraphicsContext { friend class OGLRender; friend class COGLRenderTexture; public: virtual ~COGLGraphicsContext(); bool Initialize(uint32_t dwWidth, uint32_t dwHeight); bool ResizeInitialize(uint32_t dwWidth, uint32_t dwHeight); void CleanUp(); void Clear(ClearFlag dwFlags, uint32_t color, float depth); void UpdateFrame(bool swapOnly); bool IsExtensionSupported(const char* pExtName); bool IsWglExtensionSupported(const char* pExtName); static void InitDeviceParameters(); protected: friend class OGLDeviceBuilder; COGLGraphicsContext(); void InitState(void); void InitOGLExtension(void); // Optional OGL extension features; bool m_bSupportLODBias; // Nvidia OGL only features bool m_bSupportTextureLOD; const unsigned char* m_pVendorStr; const unsigned char* m_pRenderStr; const unsigned char* m_pExtensionStr; const char* m_pWglExtensionStr; const unsigned char* m_pVersionStr; }; #endif mupen64plus-core/src/plugin/audio_libretro/audio_backend_libretro.c000664 001750 001750 00000014440 12655644434 026760 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - audio_backend_compat.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "api/m64p_types.h" #include "api/libretro.h" #include "ai/ai_controller.h" #include "main/main.h" #include "main/rom.h" #include "plugin/plugin.h" #include "ri/ri_controller.h" #include #include #include #include #include #include extern retro_audio_sample_batch_t audio_batch_cb; #include "audio_resampler_driver.h" #include "audio_utils.h" static unsigned MAX_AUDIO_FRAMES = 2048; #define VI_INTR_TIME 500000 /* Read header for type definition */ static int GameFreq = 33600; static unsigned CountsPerSecond; static unsigned BytesPerSecond; static unsigned CountsPerByte; bool no_audio; static const rarch_resampler_t *resampler; static void *resampler_audio_data; static float *audio_in_buffer_float; static float *audio_out_buffer_float; static int16_t *audio_out_buffer_s16; void (*audio_convert_s16_to_float_arm)(float *out, const int16_t *in, size_t samples, float gain); void (*audio_convert_float_to_s16_arm)(int16_t *out, const float *in, size_t samples); void deinit_audio_libretro(void) { if (resampler && resampler_audio_data) { resampler->free(resampler_audio_data); resampler = NULL; resampler_audio_data = NULL; free(audio_in_buffer_float); free(audio_out_buffer_float); free(audio_out_buffer_s16); } } void init_audio_libretro(unsigned max_audio_frames) { rarch_resampler_realloc(&resampler_audio_data, &resampler, "CC", 1.0); MAX_AUDIO_FRAMES = max_audio_frames; audio_in_buffer_float = malloc(2 * MAX_AUDIO_FRAMES * sizeof(float)); audio_out_buffer_float = malloc(2 * MAX_AUDIO_FRAMES * sizeof(float)); audio_out_buffer_s16 = malloc(2 * MAX_AUDIO_FRAMES * sizeof(int16_t)); audio_convert_init_simd(); } /* A fully compliant implementation is not really possible with just the zilmar spec. * We assume bits == 16 (assumption compatible with audio-sdl plugin implementation) */ void set_audio_format_via_libretro(void* user_data, unsigned int frequency, unsigned int bits) { uint32_t saved_ai_dacrate = g_ai.regs[AI_DACRATE_REG]; /* notify plugin of the new frequency (can't do the same for bits) */ g_ai.regs[AI_DACRATE_REG] = (ROM_PARAMS.aidacrate / frequency) - 1; GameFreq = frequency; BytesPerSecond = frequency * 4; CountsPerSecond = VI_INTR_TIME * 60 /* TODO/FIXME - dehardcode */; CountsPerByte = CountsPerSecond / BytesPerSecond; #if 0 printf("CountsPerByte: %d, GameFreq: %d\n", CountsPerByte, GameFreq); #endif /* restore original registers values */ g_ai.regs[AI_DACRATE_REG] = saved_ai_dacrate; } /* Abuse core & audio plugin implementation details to obtain the desired effect. */ void push_audio_samples_via_libretro(void* user_data, const void* buffer, size_t size) { int16_t *out; size_t max_frames, remain_frames; uint32_t i; double ratio; struct resampler_data data = {0}; int16_t *raw_data = (int16_t*)buffer; size_t frames = size / 4; uint8_t *p = (uint8_t*)buffer; /* save registers values */ uint32_t saved_ai_length = g_ai.regs[AI_LEN_REG]; uint32_t saved_ai_dram = g_ai.regs[AI_DRAM_ADDR_REG]; /* notify plugin of new samples to play. * Exploit the fact that buffer points in g_rdram to retreive dram_addr_reg value */ g_ai.regs[AI_DRAM_ADDR_REG] = (uint8_t*)buffer - (uint8_t*)g_rdram; g_ai.regs[AI_LEN_REG] = size; for (i = 0; i < size; i += 4) { p[i ] ^= p[i + 2]; p[i + 2] ^= p[i ]; p[i ] ^= p[i + 2]; p[i + 1] ^= p[i + 3]; p[i + 3] ^= p[i + 1]; p[i + 1] ^= p[i + 3]; } audio_batch: out = NULL; ratio = 44100.0 / GameFreq; max_frames = (GameFreq > 44100) ? MAX_AUDIO_FRAMES : (size_t)(MAX_AUDIO_FRAMES / ratio - 1); remain_frames = 0; if (no_audio) return; if (frames > max_frames) { remain_frames = frames - max_frames; frames = max_frames; } data.data_in = audio_in_buffer_float; data.data_out = audio_out_buffer_float; data.input_frames = frames; data.ratio = ratio; audio_convert_s16_to_float(audio_in_buffer_float, raw_data, frames * 2, 1.0f); resampler->process(resampler_audio_data, &data); audio_convert_float_to_s16(audio_out_buffer_s16, audio_out_buffer_float, data.output_frames * 2); out = audio_out_buffer_s16; while (data.output_frames) { size_t ret = audio_batch_cb(out, data.output_frames); data.output_frames -= ret; out += ret * 2; } if (remain_frames) { raw_data = raw_data + frames * 2; frames = remain_frames; goto audio_batch; } /* restore original registers vlaues */ g_ai.regs[AI_LEN_REG] = saved_ai_length; g_ai.regs[AI_DRAM_ADDR_REG] = saved_ai_dram; } mupen64plus-core/src/osal/000700 001750 001750 00000000000 12656647145 016563 5ustar00sergiosergio000000 000000 mupen64plus-core/src/rdp/000700 001750 001750 00000000000 12656647145 016412 5ustar00sergiosergio000000 000000 libretro-common/libco/fiber.c000664 001750 001750 00000001710 12655644434 017351 0ustar00sergiosergio000000 000000 /* libco.win (2008-01-28) authors: Nach, byuu license: public domain */ #define LIBCO_C #include #define WINVER 0x0400 #define _WIN32_WINNT 0x0400 #define WIN32_LEAN_AND_MEAN #include #ifdef __cplusplus extern "C" { #endif static thread_local cothread_t co_active_ = 0; static void __stdcall co_thunk(void *coentry) { ((void (*)(void))coentry)(); } cothread_t co_active(void) { if(!co_active_) { ConvertThreadToFiber(0); co_active_ = GetCurrentFiber(); } return co_active_; } cothread_t co_create(unsigned int heapsize, void (*coentry)(void)) { if(!co_active_) { ConvertThreadToFiber(0); co_active_ = GetCurrentFiber(); } return (cothread_t)CreateFiber(heapsize, co_thunk, (void*)coentry); } void co_delete(cothread_t cothread) { DeleteFiber(cothread); } void co_switch(cothread_t cothread) { co_active_ = cothread; SwitchToFiber(cothread); } #ifdef __cplusplus } #endif mupen64plus-video-gliden64/src/PostProcessor.h000664 001750 001750 00000002442 12655644434 022426 0ustar00sergiosergio000000 000000 #ifndef POST_PROCESSOR_H #define POST_PROCESSOR_H #include "Types.h" #include "OpenGL.h" #include "Textures.h" class PostProcessor { public: void init(); void destroy(); void doBlur(FrameBuffer * _pBuffer); void doGammaCorrection(FrameBuffer * _pBuffer); static PostProcessor & get(); static const u32 postEffectBlur = 1U; static const u32 postEffectGammaCorrection = 2U; private: PostProcessor() : m_extractBloomProgram(0), m_seperableBlurProgram(0), m_glowProgram(0), m_bloomProgram(0), m_copyProgram(0), m_gammaCorrectionProgram(0), m_FBO_original(0), m_FBO_glowMap(0), m_FBO_blur(0), m_pTextureOriginal(NULL), m_pTextureGlowMap(NULL), m_pTextureBlur(NULL) {} PostProcessor(const PostProcessor & _other); void _initCommon(); void _destroyCommon(); void _initGammaCorrection(); void _destroyGammaCorrection(); void _initBlur(); void _destroyBlur(); void _preDraw(FrameBuffer * _pBuffer); void _postDraw(); GLuint m_extractBloomProgram; GLuint m_seperableBlurProgram; GLuint m_glowProgram; GLuint m_bloomProgram; GLuint m_copyProgram; GLuint m_gammaCorrectionProgram; GLuint m_FBO_original; GLuint m_FBO_glowMap; GLuint m_FBO_blur; CachedTexture * m_pTextureOriginal; CachedTexture * m_pTextureGlowMap; CachedTexture * m_pTextureBlur; }; #endif // POST_PROCESSOR_H mupen64plus-video-gliden64/src/GLideNHQ/TxImage.cpp000664 001750 001750 00000042702 12655644434 023030 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* use power of 2 texture size * (0:disable, 1:enable, 2:3dfx) */ #define POW2_TEXTURES 0 /* check 8 bytes. use a larger value if needed. */ #define PNG_CHK_BYTES 8 #include "TxImage.h" #include "TxReSample.h" #include "TxDbg.h" #include #include boolean TxImage::getPNGInfo(FILE *fp, png_structp *png_ptr, png_infop *info_ptr) { unsigned char sig[PNG_CHK_BYTES]; /* check for valid file pointer */ if (!fp) return 0; /* check if file is PNG */ if (fread(sig, 1, PNG_CHK_BYTES, fp) != PNG_CHK_BYTES) return 0; if (png_sig_cmp(sig, 0, PNG_CHK_BYTES) != 0) return 0; /* get PNG file info */ *png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!*png_ptr) return 0; *info_ptr = png_create_info_struct(*png_ptr); if (!*info_ptr) { png_destroy_read_struct(png_ptr, NULL, NULL); return 0; } if (setjmp(png_jmpbuf(*png_ptr))) { DBG_INFO(80, wst("error reading png!\n")); png_destroy_read_struct(png_ptr, info_ptr, NULL); return 0; } png_init_io(*png_ptr, fp); png_set_sig_bytes(*png_ptr, PNG_CHK_BYTES); png_read_info(*png_ptr, *info_ptr); return 1; } uint8* TxImage::readPNG(FILE* fp, int* width, int* height, uint16* format) { /* NOTE: returned image format is GR_TEXFMT_ARGB_8888 */ png_structp png_ptr; png_infop info_ptr; uint8 *image = NULL; int bit_depth, color_type, interlace_type, compression_type, filter_type, row_bytes, o_width, o_height, num_pas; /* initialize */ *width = 0; *height = 0; *format = 0; /* check if we have a valid png file */ if (!fp) return NULL; if (!getPNGInfo(fp, &png_ptr, &info_ptr)) { INFO(80, wst("error reading png file! png image is corrupt.\n")); return NULL; } png_get_IHDR(png_ptr, info_ptr, (png_uint_32*)&o_width, (png_uint_32*)&o_height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_type); DBG_INFO(80, wst("png format %d x %d bitdepth:%d color:%x interlace:%x compression:%x filter:%x\n"), o_width, o_height, bit_depth, color_type, interlace_type, compression_type, filter_type); /* transformations */ /* Rice hi-res textures * _all.png * _rgb.png, _a.png * _ciByRGBA.png * _allciByRGBA.png */ /* strip if color channel is larger than 8 bits */ if (bit_depth > 8) { png_set_strip_16(png_ptr); bit_depth = 8; } #if 1 /* These are not really required per Rice format spec, * but is done just in case someone uses them. */ /* convert palette color to rgb color */ if (color_type == PNG_COLOR_TYPE_PALETTE) { png_set_palette_to_rgb(png_ptr); color_type = PNG_COLOR_TYPE_RGB; } /* expand 1,2,4 bit gray scale to 8 bit gray scale */ if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png_ptr); /* convert gray scale or gray scale + alpha to rgb color */ if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { png_set_gray_to_rgb(png_ptr); color_type = PNG_COLOR_TYPE_RGB; } #endif /* add alpha channel if any */ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { png_set_tRNS_to_alpha(png_ptr); color_type = PNG_COLOR_TYPE_RGB_ALPHA; } /* convert rgb to rgba */ if (color_type == PNG_COLOR_TYPE_RGB) { png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); color_type = PNG_COLOR_TYPE_RGB_ALPHA; } /* punt invalid formats */ if (color_type != PNG_COLOR_TYPE_RGB_ALPHA) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); DBG_INFO(80, wst("Error: not PNG_COLOR_TYPE_RGB_ALPHA format!\n")); return NULL; } /*png_color_8p sig_bit; if (png_get_sBIT(png_ptr, info_ptr, &sig_bit)) png_set_shift(png_ptr, sig_bit);*/ /* convert rgba to bgra */ //png_set_bgr(png_ptr); // OpenGL does not need it /* turn on interlace handling to cope with the weirdness * of texture authors using interlaced format */ num_pas = png_set_interlace_handling(png_ptr); /* update info structure */ png_read_update_info(png_ptr, info_ptr); /* we only get here if RGBA8888 */ row_bytes = png_get_rowbytes(png_ptr, info_ptr); /* allocate memory to read in image */ image = (uint8*)malloc(row_bytes * o_height); /* read in image */ if (image) { int pas, i; uint8* tmpimage; for (pas = 0; pas < num_pas; pas++) { /* deal with interlacing */ tmpimage = image; for (i = 0; i < o_height; i++) { /* copy row */ png_read_rows(png_ptr, &tmpimage, NULL, 1); tmpimage += row_bytes; } } /* read rest of the info structure */ png_read_end(png_ptr, info_ptr); *width = (row_bytes >> 2); *height = o_height; *format = GL_RGBA8; #if POW2_TEXTURES /* next power of 2 size conversions */ /* NOTE: I can do this in the above loop for faster operations, but some * texture packs require a workaround. see HACKALERT in nextPow2(). */ TxReSample txReSample = new TxReSample; // XXX: temporary. move to a better place. #if (POW2_TEXTURES == 2) if (!txReSample->nextPow2(&image, width, height, 32, 1)) { #else if (!txReSample->nextPow2(&image, width, height, 32, 0)) { #endif if (image) { free(image); image = NULL; } *width = 0; *height = 0; *format = 0; } delete txReSample; #endif /* POW2_TEXTURES */ } /* clean up */ png_destroy_read_struct(&png_ptr, &info_ptr, NULL); #ifdef DEBUG if (!image) { DBG_INFO(80, wst("Error: failed to load png image!\n")); } #endif return image; } boolean TxImage::writePNG(uint8* src, FILE* fp, int width, int height, int rowStride, uint16 format, uint8 *palette) { png_structp png_ptr = NULL; png_infop info_ptr = NULL; png_color_8 sig_bit; png_colorp palette_ptr = NULL; png_bytep trans_ptr = NULL;//, tex_ptr; int bit_depth = 0, color_type = 0, row_bytes = 0, num_palette = 0; int i = 0; //uint16 srcfmt, destfmt; if (!src || !fp) return 0; png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) return 0; info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { png_destroy_write_struct(&png_ptr, NULL); return 0; } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); return 0; } png_init_io(png_ptr, fp); /* TODO: images must be converted to RGBA8888 or CI8, * palettes need to be separated to A and RGB. */ /* N64 formats * Format: 0 - RGBA, 1 - YUV, 2 - CI, 3 - IA, 4 - I * Size: 0 - 4bit, 1 - 8bit, 2 - 16bit, 3 - 32 bit * format = (Format << 8 | Size); */ /* each channel is saved in 8bits for consistency */ switch (format) { case 0x0002:/* RGBA5551 */ bit_depth = 8; sig_bit.red = 5; sig_bit.green = 5; sig_bit.blue = 5; sig_bit.alpha = 1; color_type = PNG_COLOR_TYPE_RGB_ALPHA; break; case 0x0003:/* RGBA8888 */ case 0x0302:/* IA88 */ bit_depth = 8; sig_bit.red = 8; sig_bit.green = 8; sig_bit.blue = 8; sig_bit.alpha = 8; color_type = PNG_COLOR_TYPE_RGB_ALPHA; break; case 0x0300:/* IA31 */ bit_depth = 8; sig_bit.red = 3; sig_bit.green = 3; sig_bit.blue = 3; sig_bit.alpha = 1; color_type = PNG_COLOR_TYPE_RGB_ALPHA; break; case 0x0301:/* IA44 */ bit_depth = 8; sig_bit.red = 4; sig_bit.green = 4; sig_bit.blue = 4; sig_bit.alpha = 4; color_type = PNG_COLOR_TYPE_RGB_ALPHA; break; case 0x0400:/* I4 */ bit_depth = 8; sig_bit.red = 4; sig_bit.green = 4; sig_bit.blue = 4; color_type = PNG_COLOR_TYPE_RGB; break; case 0x0401:/* I8 */ case 0x0402:/* I16 */ bit_depth = 8; sig_bit.red = 8; sig_bit.green = 8; sig_bit.blue = 8; color_type = PNG_COLOR_TYPE_RGB; break; case 0x0200:/* CI4 */ bit_depth = 8; num_palette = 16; color_type = PNG_COLOR_TYPE_PALETTE; break; case 0x0201:/* CI8 */ bit_depth = 8; num_palette = 256; color_type = PNG_COLOR_TYPE_PALETTE; break; case 0x0102:/* YUV ? */ case 0x0103: default: /* unsupported format */ png_destroy_write_struct(&png_ptr, &info_ptr); return 0; } switch (color_type) { case PNG_COLOR_TYPE_RGB_ALPHA: case PNG_COLOR_TYPE_RGB: //row_bytes = (bit_depth * width) >> 1; row_bytes = rowStride; //png_set_bgr(png_ptr); // OpenGL does not need it png_set_sBIT(png_ptr, info_ptr, &sig_bit); break; case PNG_COLOR_TYPE_PALETTE: //row_bytes = (bit_depth * width) >> 3; row_bytes = rowStride; png_set_PLTE(png_ptr, info_ptr, palette_ptr, num_palette); png_set_tRNS(png_ptr, info_ptr, trans_ptr, num_palette, 0); } //png_set_filter(png_ptr, 0, PNG_ALL_FILTERS); //if (bit_depth == 16) // png_set_swap(png_ptr); //if (bit_depth < 8) // png_set_packswap(png_ptr); png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); //png_set_gAMA(png_ptr, info_ptr, 1.0); png_write_info(png_ptr, info_ptr); for (i = 0; i < height; i++) { png_write_row(png_ptr, (png_bytep)src); src += row_bytes; } png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr); //if (tex_ptr) delete [] tex_ptr; return 1; } boolean TxImage::getBMPInfo(FILE* fp, BITMAPFILEHEADER* bmp_fhdr, BITMAPINFOHEADER* bmp_ihdr) { /* * read in BITMAPFILEHEADER */ /* is this a BMP file? */ if (fread(&bmp_fhdr->bfType, 2, 1, fp) != 1) return 0; if (memcmp(&bmp_fhdr->bfType, "BM", 2) != 0) return 0; /* get file size */ if (fread(&bmp_fhdr->bfSize, 4, 1, fp) != 1) return 0; /* reserved 1 */ if (fread(&bmp_fhdr->bfReserved1, 2, 1, fp) != 1) return 0; /* reserved 2 */ if (fread(&bmp_fhdr->bfReserved2, 2, 1, fp) != 1) return 0; /* offset to the image data */ if (fread(&bmp_fhdr->bfOffBits, 4, 1, fp) != 1) return 0; /* * read in BITMAPINFOHEADER */ /* size of BITMAPINFOHEADER */ if (fread(&bmp_ihdr->biSize, 4, 1, fp) != 1) return 0; /* is this a Windows BMP? */ if (bmp_ihdr->biSize != 40) return 0; /* width of the bitmap in pixels */ if (fread(&bmp_ihdr->biWidth, 4, 1, fp) != 1) return 0; /* height of the bitmap in pixels */ if (fread(&bmp_ihdr->biHeight, 4, 1, fp) != 1) return 0; /* number of planes (always 1) */ if (fread(&bmp_ihdr->biPlanes, 2, 1, fp) != 1) return 0; /* number of bits-per-pixel. (1, 4, 8, 16, 24, 32) */ if (fread(&bmp_ihdr->biBitCount, 2, 1, fp) != 1) return 0; /* compression for a compressed bottom-up bitmap * 0 : uncompressed format * 1 : run-length encoded 4 bpp format * 2 : run-length encoded 8 bpp format * 3 : bitfield */ if (fread(&bmp_ihdr->biCompression, 4, 1, fp) != 1) return 0; /* size of the image in bytes */ if (fread(&bmp_ihdr->biSizeImage, 4, 1, fp) != 1) return 0; /* horizontal resolution in pixels-per-meter */ if (fread(&bmp_ihdr->biXPelsPerMeter, 4, 1, fp) != 1) return 0; /* vertical resolution in pixels-per-meter */ if (fread(&bmp_ihdr->biYPelsPerMeter, 4, 1, fp) != 1) return 0; /* number of color indexes in the color table that are actually used */ if (fread(&bmp_ihdr->biClrUsed, 4, 1, fp) != 1) return 0; /* the number of color indexes that are required for displaying */ if (fread(&bmp_ihdr->biClrImportant, 4, 1, fp) != 1) return 0; return 1; } uint8* TxImage::readBMP(FILE* fp, int* width, int* height, uint16* format) { /* NOTE: returned image format; * 4, 8bit palette bmp -> GL_COLOR_INDEX8_EXT * 24, 32bit bmp -> GL_RGBA8 */ uint8 *image = NULL; uint8 *image_row = NULL; uint8 *tmpimage = NULL; int row_bytes, pos, i, j; /* Windows Bitmap */ BITMAPFILEHEADER bmp_fhdr; BITMAPINFOHEADER bmp_ihdr; /* initialize */ *width = 0; *height = 0; *format = 0; /* check if we have a valid bmp file */ if (!fp) return NULL; if (!getBMPInfo(fp, &bmp_fhdr, &bmp_ihdr)) { INFO(80, wst("error reading bitmap file! bitmap image is corrupt.\n")); return NULL; } DBG_INFO(80, wst("bmp format %d x %d bitdepth:%d compression:%x offset:%d\n"), bmp_ihdr.biWidth, bmp_ihdr.biHeight, bmp_ihdr.biBitCount, bmp_ihdr.biCompression, bmp_fhdr.bfOffBits); /* rowStride in bytes */ row_bytes = (bmp_ihdr.biWidth * bmp_ihdr.biBitCount) >> 3; /* align to 4bytes boundary */ row_bytes = (row_bytes + 3) & ~3; /* Rice hi-res textures */ if (!(bmp_ihdr.biBitCount == 8 || bmp_ihdr.biBitCount == 4 || bmp_ihdr.biBitCount == 32 || bmp_ihdr.biBitCount == 24) || bmp_ihdr.biCompression != 0) { DBG_INFO(80, wst("Error: incompatible bitmap format!\n")); return NULL; } switch (bmp_ihdr.biBitCount) { case 8: case 32: /* 8 bit, 32 bit bitmap */ image = (uint8*)malloc(row_bytes * bmp_ihdr.biHeight); if (image) { tmpimage = image; pos = bmp_fhdr.bfOffBits + row_bytes * (bmp_ihdr.biHeight - 1); for (i = 0; i < bmp_ihdr.biHeight; i++) { /* read in image */ fseek(fp, pos, SEEK_SET); fread(tmpimage, row_bytes, 1, fp); tmpimage += row_bytes; pos -= row_bytes; } } break; case 4: /* 4bit bitmap */ image = (uint8*)malloc((row_bytes * bmp_ihdr.biHeight) << 1); image_row = (uint8*)malloc(row_bytes); if (image && image_row) { tmpimage = image; pos = bmp_fhdr.bfOffBits + row_bytes * (bmp_ihdr.biHeight - 1); for (i = 0; i < bmp_ihdr.biHeight; i++) { /* read in image */ fseek(fp, pos, SEEK_SET); fread(image_row, row_bytes, 1, fp); /* expand 4bpp to 8bpp. stuff 4bit values into 8bit comps. */ for (j = 0; j < row_bytes; j++) { tmpimage[j << 1] = image_row[j] & 0x0f; tmpimage[(j << 1) + 1] = (image_row[j] & 0xf0) >> 4; } tmpimage += (row_bytes << 1); pos -= row_bytes; } free(image_row); } else { if (image_row) free(image_row); if (image) free(image); image = NULL; } break; case 24: /* 24 bit bitmap */ image = (uint8*)malloc((bmp_ihdr.biWidth * bmp_ihdr.biHeight) << 2); image_row = (uint8*)malloc(row_bytes); if (image && image_row) { tmpimage = image; pos = bmp_fhdr.bfOffBits + row_bytes * (bmp_ihdr.biHeight - 1); for (i = 0; i < bmp_ihdr.biHeight; i++) { /* read in image */ fseek(fp, pos, SEEK_SET); fread(image_row, row_bytes, 1, fp); /* convert 24bpp to 32bpp. */ for (j = 0; j < bmp_ihdr.biWidth; j++) { tmpimage[(j << 2)] = image_row[j * 3]; tmpimage[(j << 2) + 1] = image_row[j * 3 + 1]; tmpimage[(j << 2) + 2] = image_row[j * 3 + 2]; tmpimage[(j << 2) + 3] = 0xFF; } tmpimage += (bmp_ihdr.biWidth << 2); pos -= row_bytes; } free(image_row); } else { if (image_row) free(image_row); if (image) free(image); image = NULL; } } if (image) { *width = (row_bytes << 3) / bmp_ihdr.biBitCount; *height = bmp_ihdr.biHeight; switch (bmp_ihdr.biBitCount) { case 8: case 4: *format = GL_COLOR_INDEX8_EXT; break; case 32: case 24: *format = GL_RGBA8; } #if POW2_TEXTURES /* next power of 2 size conversions */ /* NOTE: I can do this in the above loop for faster operations, but some * texture packs require a workaround. see HACKALERT in nextPow2(). */ TxReSample txReSample = new TxReSample; // XXX: temporary. move to a better place. #if (POW2_TEXTURES == 2) if (!txReSample->nextPow2(&image, width, height, 8, 1)) { #else if (!txReSample->nextPow2(&image, width, height, 8, 0)) { #endif if (image) { free(image); image = NULL; } *width = 0; *height = 0; *format = 0; } delete txReSample; #endif /* POW2_TEXTURES */ } #ifdef DEBUG if (!image) { DBG_INFO(80, wst("Error: failed to load bmp image!\n")); } #endif return image; } boolean TxImage::getDDSInfo(FILE *fp, DDSFILEHEADER *dds_fhdr) { /* * read in DDSFILEHEADER */ /* is this a DDS file? */ if (fread(&dds_fhdr->dwMagic, 4, 1, fp) != 1) return 0; if (memcmp(&dds_fhdr->dwMagic, "DDS ", 4) != 0) return 0; if (fread(&dds_fhdr->dwSize, 4, 1, fp) != 1) return 0; /* get file flags */ if (fread(&dds_fhdr->dwFlags, 4, 1, fp) != 1) return 0; /* height of dds in pixels */ if (fread(&dds_fhdr->dwHeight, 4, 1, fp) != 1) return 0; /* width of dds in pixels */ if (fread(&dds_fhdr->dwWidth, 4, 1, fp) != 1) return 0; if (fread(&dds_fhdr->dwLinearSize, 4, 1, fp) != 1) return 0; if (fread(&dds_fhdr->dwDepth, 4, 1, fp) != 1) return 0; if (fread(&dds_fhdr->dwMipMapCount, 4, 1, fp) != 1) return 0; if (fread(&dds_fhdr->dwReserved1, 4 * 11, 1, fp) != 1) return 0; if (fread(&dds_fhdr->ddpf.dwSize, 4, 1, fp) != 1) return 0; if (fread(&dds_fhdr->ddpf.dwFlags, 4, 1, fp) != 1) return 0; if (fread(&dds_fhdr->ddpf.dwFourCC, 4, 1, fp) != 1) return 0; if (fread(&dds_fhdr->ddpf.dwRGBBitCount, 4, 1, fp) != 1) return 0; if (fread(&dds_fhdr->ddpf.dwRBitMask, 4, 1, fp) != 1) return 0; if (fread(&dds_fhdr->ddpf.dwGBitMask, 4, 1, fp) != 1) return 0; if (fread(&dds_fhdr->ddpf.dwBBitMask, 4, 1, fp) != 1) return 0; if (fread(&dds_fhdr->ddpf.dwRGBAlphaBitMask, 4, 1, fp) != 1) return 0; if (fread(&dds_fhdr->dwCaps1, 4, 1, fp) != 1) return 0; if (fread(&dds_fhdr->dwCaps2, 4, 1, fp) != 1) return 0; return 1; } mupen64plus-core/doc/emuwiki-api-doc/000700 001750 001750 00000000000 12656647145 020567 5ustar00sergiosergio000000 000000 gles2rice/.hgignore000664 001750 001750 00000000117 12655644434 015400 0ustar00sergiosergio000000 000000 syntax: regexp ^projects/unix/_obj/ ^projects/unix/mupen64plus-video-rice.so$ gles2rice/src/RSP_S2DEX.h000664 001750 001750 00000015461 12655644434 016116 0ustar00sergiosergio000000 000000 /* Copyright (C) 2002 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _RSP_S2DEX_H_ #define _RSP_S2DEX_H_ // GBI commands for S2DEX microcode. #define S2DEX_BG_1CYC 0x01 #define S2DEX_BG_COPY 0x02 #define S2DEX_OBJ_RECTANGLE 0x03 #define S2DEX_OBJ_SPRITE 0x04 #define S2DEX_OBJ_MOVEMEM 0x05 #define S2DEX_SELECT_DL 0xb0 #define S2DEX_OBJ_RENDERMODE 0xb1 #define S2DEX_OBJ_RECTANGLE_R 0xb2 #define S2DEX_OBJ_LOADTXTR 0xc1 #define S2DEX_OBJ_LDTX_SPRITE 0xc2 #define S2DEX_OBJ_LDTX_RECT 0xc3 #define S2DEX_OBJ_LDTX_RECT_R 0xc4 #define S2DEX_RDPHALF_0 0xe4 // Struct types #define S2DEX_OBJLT_TXTRBLOCK 0x00001033 #define S2DEX_OBJLT_TXTRTILE 0x00fc1034 #define S2DEX_OBJLT_TLUT 0x00000030 // Loaded types #define S2DEX_BGLT_LOADBLOCK 0x0033 #define S2DEX_BGLT_LOADTILE 0xfff4 typedef struct //Intel Format { uint32_t type; // Struct classification type. Should always be S2DEX_OBJLT_TXTRBLOCK (0x1033) uint32_t image; // Texture address within the DRAM. uint16_t tmem; // TMEM load address uint16_t tsize; // Texture size uint16_t tline; // Texture line width for one line. uint16_t sid; // State ID uint32_t flag; // State flag uint32_t mask; // State mask } uObjTxtrBlock; typedef struct //Intel Format { uint32_t type; // Struct classification type. Should always be S2DEX_OBJLT_TXTRTILE (0xfc1034) uint32_t image; // Texture address within the DRAM. uint16_t tmem; // TMEM load address uint16_t twidth; // Texture width uint16_t theight; // Texture height uint16_t sid; // State ID. Always a multiple of 4. Can be 0, 4, 8, or 12. uint32_t flag; // State flag uint32_t mask; // State mask } uObjTxtrTile; // 24 bytes typedef struct // Intel Format { uint32_t type; // Struct classification type, should always be S2DEX_OBJLT_TLUT (0x30) uint32_t image; // Texture address within the DRAM. uint16_t pnum; // Loaded palette number - 1 uint16_t phead; // Number indicating the first loaded palette (Between 256 - 511). uint16_t zero; // Always 0 uint16_t sid; // State ID. Always a multiple of 4. Can be 0, 4, 8, or 12. uint32_t flag; // State flag uint32_t mask; // State mask } uObjTxtrTLUT; // 24 bytes typedef union { uObjTxtrBlock block; uObjTxtrTile tile; uObjTxtrTLUT tlut; } uObjTxtr; typedef struct // Intel format { uint16_t scaleW; // X-axis scale factor. short objX; // X-coordinate of the upper-left position of the sprite. uint16_t paddingX; // Unused, always 0. uint16_t imageW; // Texture width uint16_t scaleH; // Y-axis scale factor. short objY; // Y-coordinate of the upper-left position of the sprite. uint16_t paddingY; // Unused, always 0. uint16_t imageH; // Texture height uint16_t imageAdrs; // Texture header position within the TMEM. uint16_t imageStride; // Number of bytes from one row of pixels in memory to the next row of pixels (ie. Stride) uint8_t imageFlags; // Flag used for image manipulations uint8_t imagePal; // Palette number. Can be from 0 - 7 uint8_t imageSiz; // Texel size uint8_t imageFmt; // Texel format } uObjSprite; typedef struct { uObjTxtr txtr; uObjSprite sprite; } uObjTxSprite; /* 48 bytes */ typedef struct // Intel format { int32_t A, B, C, D; short Y; short X; uint16_t BaseScaleY; uint16_t BaseScaleX; } uObjMtx; typedef struct //Intel format { float A, B, C, D; float X; float Y; float BaseScaleX; float BaseScaleY; } uObjMtxReal; typedef struct { short Y; short X; uint16_t BaseScaleY; uint16_t BaseScaleX; } uObjSubMtx; typedef struct // Intel Format { uint16_t imageW; // Texture width uint16_t imageX; // X-coordinate of the upper-left position of the texture. uint16_t frameW; // Width of the frame to be transferred. short frameX; // X-coordinate of the upper-left position of the frame to be transferred. uint16_t imageH; // Texture height uint16_t imageY; // Y-coordinate of the upper-left position of the texture. uint16_t frameH; // Height of the frame to be transferred. short frameY; // Y-coordinate of the upper-left position of the frame to be transferred. uint32_t imagePtr; // Texture address within the DRAM. uint8_t imageSiz; // Texel size uint8_t imageFmt; // Texel format uint16_t imageLoad; // Can either be S2DEX_BGLT_LOADBLOCK (0x0033) or #define S2DEX_BGLT_LOADTILE (0xfff4). uint16_t imageFlip; // Inverts the image if 0x01 is set. uint16_t imagePal; // Palette number // Set within initialization routines, should not need to be directly set. uint16_t tmemH; uint16_t tmemW; uint16_t tmemLoadTH; uint16_t tmemLoadSH; uint16_t tmemSize; uint16_t tmemSizeW; } uObjBg; // Intel Format typedef struct { uint16_t imageW; // Texture width uint16_t imageX; // X-coordinate of the upper-left position of the texture. uint16_t frameW; // Width of the frame to be transferred. short frameX; // X-coordinate of the upper-left position of the frame to be transferred. uint16_t imageH; // Texture height uint16_t imageY; // Y-coordinate of the upper-left position of the texture. uint16_t frameH; // Height of the frame to be transferred. short frameY; // Y-coordinate of the upper-left position of the frame to be transferred. uint32_t imagePtr; // Texture address within the DRAM. uint8_t imageSiz; // Texel size uint8_t imageFmt; // Texel format uint16_t imageLoad; // Can either be S2DEX_BGLT_LOADBLOCK (0x0033) or S2DEX_BGLT_LOADTILE (0xfff4) uint16_t imageFlip; // Inverts the image if 0x01 is set. uint16_t imagePal; // Palette number uint16_t scaleH; // Y-axis scale factor uint16_t scaleW; // X-axis scale factor int32_t imageYorig; // Starting point in the original image. uint8_t padding[4]; } uObjScaleBg; #endif gles2n64/src/gSP.h000664 001750 001750 00000012220 12655644434 014711 0ustar00sergiosergio000000 000000 #ifndef GSP_H #define GSP_H #include #include "Types.h" #include "GBI.h" #include "gDP.h" #define CHANGED_VIEWPORT 0x01 #define CHANGED_MATRIX 0x02 #define CHANGED_COLORBUFFER 0x04 #define CHANGED_GEOMETRYMODE 0x08 #define CHANGED_TEXTURE 0x10 #define CHANGED_FOGPOSITION 0x20 #define CHANGED_LIGHT 0x40 #define CHANGED_CPU_FB_WRITE 0x80 #define CLIP_X 0x03 #define CLIP_NEGX 0x01 #define CLIP_POSX 0x02 #define CLIP_Y 0x0C #define CLIP_NEGY 0x04 #define CLIP_POSY 0x08 #define CLIP_Z 0x10 #define CLIP_ALL 0x1F // CLIP_NEGX|CLIP_POSX|CLIP_NEGY|CLIP_POSY|CLIP_Z typedef struct { f32 x, y, z, w; f32 nx, ny, nz, __pad0; f32 r, g, b, a; f32 flat_r, flat_g, flat_b, flat_a; f32 s, t; u8 HWLight; s16 flag; u32 clip; } SPVertex; typedef struct SPLight { f32 r, g, b; f32 x, y, z; f32 posx, posy, posz, posw; f32 ca, la, qa; } SPLight; typedef struct { u32 segment[16]; struct { u32 modelViewi, stackSize, billboard; f32 modelView[32][4][4]; f32 projection[4][4]; f32 combined[4][4]; } matrix; struct { f32 A, B, C, D; f32 X, Y; f32 baseScaleX, baseScaleY; } objMatrix; u32 objRendermode; u32 vertexColorBase; u32 vertexi; struct SPLight lights[12]; SPLight lookat[2]; bool lookatEnable; struct { f32 scales, scalet; s32 level, on, tile; } texture; gDPTile *textureTile[2]; struct { f32 vscale[4]; f32 vtrans[4]; f32 x, y, width, height; f32 nearz, farz; } viewport; struct { s16 multiplier, offset; } fog; struct { u32 address, width, height, format, size, palette; f32 imageX, imageY, scaleW, scaleH; } bgImage; u32 geometryMode; s32 numLights; u32 changed; u32 status[4]; struct { u32 vtx, mtx, tex_offset, tex_shift, tex_count; } DMAOffsets; // CBFD u32 vertexNormalBase; f32 vertexCoordMod[16]; } gSPInfo; extern gSPInfo gSP; void gSPLoadUcodeEx( u32 uc_start, u32 uc_dstart, u16 uc_dsize ); void gSPNoOp(); void gSPMatrix( u32 matrix, u8 param ); void gSPDMAMatrix( u32 matrix, u8 index, u8 multiply ); void gSPViewport( u32 v ); void gSPForceMatrix( u32 mptr ); void gSPLight( u32 l, s32 n ); void gSPLightCBFD( u32 l, s32 n ); void gSPLookAt( u32 _l, u32 _n ); void gSPVertex( u32 v, u32 n, u32 v0 ); void gSPCIVertex( u32 v, u32 n, u32 v0 ); void gSPDMAVertex( u32 v, u32 n, u32 v0 ); void gSPCBFDVertex( u32 v, u32 n, u32 v0 ); void gSPDisplayList( u32 dl ); void gSPDMADisplayList( u32 dl, u32 n ); void gSPBranchList( u32 dl ); void gSPBranchLessZ( u32 branchdl, u32 vtx, f32 zval ); void gSPDlistCount(u32 count, u32 v); void gSPSprite2DBase( u32 base ); void gSPDMATriangles( u32 tris, u32 n ); void gSP1Quadrangle( s32 v0, s32 v1, s32 v2, s32 v3 ); void gSPCullDisplayList( u32 v0, u32 vn ); void gSPPopMatrix( u32 param ); void gSPPopMatrixN( u32 param, u32 num ); void gSPSegment( s32 seg, s32 base ); void gSPClipRatio( u32 r ); void gSPInsertMatrix( u32 where, u32 num ); void gSPModifyVertex( u32 vtx, u32 where, u32 val ); void gSPNumLights( s32 n ); void gSPLightColor( u32 lightNum, u32 packedColor ); void gSPFogFactor( s16 fm, s16 fo ); void gSPPerspNormalize( u16 scale ); void gSPTexture( f32 sc, f32 tc, s32 level, s32 tile, s32 on ); void gSPEndDisplayList(); void gSPGeometryMode( u32 clear, u32 set ); void gSPSetGeometryMode( u32 mode ); void gSPClearGeometryMode( u32 mode ); void gSPSetOtherMode_H(u32 _length, u32 _shift, u32 _data); void gSPSetOtherMode_L(u32 _length, u32 _shift, u32 _data); void gSPLine3D( s32 v0, s32 v1, s32 flag ); void gSPLineW3D( s32 v0, s32 v1, s32 wd, s32 flag ); void gSPObjRectangle( u32 sp ); void gSPObjRectangleR(u32 _sp); void gSPObjSprite( u32 sp ); void gSPObjLoadTxtr( u32 tx ); void gSPObjLoadTxSprite( u32 txsp ); void gSPObjLoadTxRectR( u32 txsp ); void gSPBgRect1Cyc( u32 bg ); void gSPBgRectCopy( u32 bg ); void gSPObjMatrix( u32 mtx ); void gSPObjSubMatrix( u32 mtx ); void gSPObjRendermode(u32 _mode); void gSPSetDMAOffsets( u32 mtxoffset, u32 vtxoffset ); void gSPSetVertexColorBase( u32 base ); void gSPSetVertexNormaleBase( u32 base ); void gSPProcessVertex(u32 v); void gSPCoordMod(u32 _w0, u32 _w1); void gSPTriangleUnknown(void); void gSPTriangle(s32 v0, s32 v1, s32 v2); void gSP1Triangle(s32 v0, s32 v1, s32 v2); void gSP2Triangles(const s32 v00, const s32 v01, const s32 v02, const s32 flag0, const s32 v10, const s32 v11, const s32 v12, const s32 flag1 ); void gSP4Triangles(const s32 v00, const s32 v01, const s32 v02, const s32 v10, const s32 v11, const s32 v12, const s32 v20, const s32 v21, const s32 v22, const s32 v30, const s32 v31, const s32 v32 ); extern void (*gSPTransformVertex)(float vtx[4], float mtx[4][4]); extern void (*gSPLightVertex)(SPVertex * _vtx); extern void (*gSPPointLightVertex)(SPVertex *_vtx, float * _vPos); extern void (*gSPBillboardVertex)(u32 v, u32 i); void gSPSetupFunctions(void); void gSPSetDMATexOffset(u32 _addr); #endif mupen64plus-video-gliden64/src/PostProcessor.cpp000664 001750 001750 00000062135 12655644434 022766 0ustar00sergiosergio000000 000000 #include #include "N64.h" #include "gSP.h" #include "PostProcessor.h" #include "FrameBuffer.h" #include "GLSLCombiner.h" #include "ShaderUtils.h" #include "Config.h" #if defined(GLES3_1) #define SHADER_VERSION "#version 310 es \n" #elif defined(GLES3) #define SHADER_VERSION "#version 300 es \n" #elif defined(GLES2) #define SHADER_VERSION "#version 100 \n" #else #define SHADER_VERSION "#version 330 core \n" #endif #ifdef GLES2 #define FRAGMENT_SHADER_END " gl_FragColor = fragColor; \n" #else #define FRAGMENT_SHADER_END "\n" #endif static const char * vertexShader = SHADER_VERSION "#if (__VERSION__ > 120) \n" "# define IN in \n" "# define OUT out \n" "#else \n" "# define IN attribute \n" "# define OUT varying \n" "#endif // __VERSION \n" "IN highp vec2 aPosition; \n" "IN highp vec2 aTexCoord; \n" "OUT mediump vec2 vTexCoord; \n" "void main(){ \n" "gl_Position = vec4(aPosition.x, aPosition.y, 0.0, 1.0);\n" "vTexCoord = aTexCoord; \n" "} \n" ; static const char* copyShader = SHADER_VERSION "#if (__VERSION__ > 120) \n" "# define IN in \n" "# define OUT out \n" "# define texture2D texture \n" "#else \n" "# define IN varying \n" "# define OUT \n" "#endif // __VERSION __ \n" "IN mediump vec2 vTexCoord; \n" "uniform sampler2D Sample0; \n" "OUT lowp vec4 fragColor; \n" " \n" "void main() \n" "{ \n" " fragColor = texture2D(Sample0, vTexCoord); \n" FRAGMENT_SHADER_END "} \n" ; static const char* extractBloomShader = SHADER_VERSION "#if (__VERSION__ > 120) \n" "# define IN in \n" "# define OUT out \n" "# define texture2D texture \n" "#else \n" "# define IN varying \n" "# define OUT \n" "#endif // __VERSION __ \n" "IN mediump vec2 vTexCoord; \n" "uniform sampler2D Sample0; \n" "OUT lowp vec4 fragColor; \n" " \n" "uniform lowp int ThresholdLevel; \n" " \n" "void main() \n" "{ \n" " lowp vec4 color = texture2D(Sample0, vTexCoord); \n" " \n" " mediump float lum = dot(vec4(0.30, 0.59, 0.11, 0.0), color);\n" " mediump float scale = lum; \n" " lowp int level = clamp(ThresholdLevel, 2, 6); \n" " for (int i = 1; i < level; ++i) \n" " scale *= lum; \n" " fragColor = scale*color; \n" " fragColor.a = 1.0; \n" FRAGMENT_SHADER_END "} \n" ; static const char* seperableBlurShader = /// Author: Nathaniel Meyer /// /// Copyright: Nutty Software /// http://www.nutty.ca /// /// Fragment shader for performing a seperable blur on the specified texture. SHADER_VERSION "#if (__VERSION__ > 120) \n" "# define IN in \n" "# define OUT out \n" "# define texture2D texture \n" "#else \n" "# define IN varying \n" "# define OUT \n" "#endif // __VERSION __ \n" // Uniform variables. "uniform sampler2D Sample0; \n" "uniform mediump vec2 TexelSize; \n" " \n" "uniform lowp int Orientation; \n" "uniform lowp int BlurAmount; \n" "uniform lowp float BlurScale; \n" "uniform lowp float BlurStrength; \n" " \n" "IN mediump vec2 vTexCoord; \n" "OUT lowp vec4 fragColor; \n" " \n" // Gets the Gaussian value in the first dimension. // "x" Distance from origin on the x-axis. // "deviation" Standard deviation. // returns The gaussian value on the x-axis. "mediump float Gaussian (in mediump float x, in mediump float deviation) \n" "{ \n" " return (1.0 / sqrt(2.0 * 3.141592 * deviation)) * exp(-((x * x) / (2.0 * deviation))); \n" "} \n" " \n" // Fragment shader entry. "void main () \n" "{ \n" " // Locals \n" " mediump float halfBlur = float(BlurAmount) * 0.5; \n" " mediump vec4 colour = vec4(0.0); \n" " \n" " // Gaussian deviation \n" " mediump float deviation = halfBlur * 0.35; \n" " deviation *= deviation; \n" " mediump float strength = 1.0 - BlurStrength; \n" " \n" " if ( Orientation == 0 ) \n" " { \n" " // Horizontal blur \n" " for (lowp int i = 0; i < BlurAmount; ++i) \n" " { \n" " mediump float offset = float(i) - halfBlur; \n" " colour += texture2D(Sample0, vTexCoord + vec2(offset * TexelSize.x * BlurScale, 0.0)) * Gaussian(offset * strength, deviation); \n" " } \n" " } \n" " else \n" " { \n" " // Vertical blur \n" " for (lowp int i = 0; i < BlurAmount; ++i) \n" " { \n" " mediump float offset = float(i) - halfBlur; \n" " colour += texture2D(Sample0, vTexCoord + vec2(0.0, offset * TexelSize.y * BlurScale)) * Gaussian(offset * strength, deviation); \n" " } \n" " } \n" " \n" " // Apply colour \n" " fragColor = clamp(colour, 0.0, 1.0); \n" " fragColor.a = 1.0; \n" FRAGMENT_SHADER_END "} \n" ; static const char* glowShader = /// Author: Nathaniel Meyer /// /// Copyright: Nutty Software /// http://www.nutty.ca /// /// Fragment shader for blending two textures using an algorithm that overlays the glowmap. SHADER_VERSION "#if (__VERSION__ > 120) \n" "# define IN in \n" "# define OUT out \n" "# define texture2D texture \n" "#else \n" "# define IN varying \n" "# define OUT \n" "#endif // __VERSION __ \n" // Uniform variables. "uniform sampler2D Sample0; \n" "uniform sampler2D Sample1; \n" "uniform lowp int BlendMode; \n" " \n" "IN mediump vec2 vTexCoord; \n" "OUT lowp vec4 fragColor; \n" " \n" // Fragment shader entry. "void main () \n" "{ \n" " lowp vec4 dst = texture2D(Sample0, vTexCoord); // rendered scene \n" " lowp vec4 src = texture2D(Sample1, vTexCoord); // glowmap \n" " \n" " if (BlendMode == 0) { \n" " // Additive blending (strong result, high overexposure) \n" " fragColor = min(src + dst, 1.0); \n" " fragColor.a = 1.0; \n" " } else if (BlendMode == 1) { \n" " fragColor = clamp((src + dst) - (src * dst), 0.0, 1.0); \n" " fragColor.a = 1.0; \n" " } else if (BlendMode == 2) { \n" " src = (src * 0.5) + 0.5; \n" " \n" " if (src.x <= 0.5) \n" " fragColor.x = dst.x - (1.0 - 2.0 * src.x) * dst.x * (1.0 - dst.x); \n" " else if ((src.x > 0.5) && (dst.x <= 0.25)) \n" " fragColor.x = dst.x + (2.0 * src.x - 1.0) * (4.0 * dst.x * (4.0 * dst.x + 1.0) * (dst.x - 1.0) + 7.0 * dst.x);\n" " else \n" " fragColor.x = dst.x + (2.0 * src.x - 1.0) * (sqrt(dst.x) - dst.x); \n" " if (src.y <= 0.5) \n" " fragColor.y = dst.y - (1.0 - 2.0 * src.y) * dst.y * (1.0 - dst.y); \n" " else if ((src.y > 0.5) && (dst.y <= 0.25)) \n" " fragColor.y = dst.y + (2.0 * src.y - 1.0) * (4.0 * dst.y * (4.0 * dst.y + 1.0) * (dst.y - 1.0) + 7.0 * dst.y);\n" " else \n" " fragColor.y = dst.y + (2.0 * src.y - 1.0) * (sqrt(dst.y) - dst.y); \n" " if (src.z <= 0.5) \n" " fragColor.z = dst.z - (1.0 - 2.0 * src.z) * dst.z * (1.0 - dst.z); \n" " else if ((src.z > 0.5) && (dst.z <= 0.25)) \n" " fragColor.z = dst.z + (2.0 * src.z - 1.0) * (4.0 * dst.z * (4.0 * dst.z + 1.0) * (dst.z - 1.0) + 7.0 * dst.z);\n" " else \n" " fragColor.z = dst.z + (2.0 * src.z - 1.0) * (sqrt(dst.z) - dst.z); \n" " fragColor.a = 1.0; \n" " } else { \n" " // Show just the glow map \n" " fragColor = src; \n" " } \n" FRAGMENT_SHADER_END "} \n" ; static const char* gammaCorrectionShader = SHADER_VERSION "#if (__VERSION__ > 120) \n" "# define IN in \n" "# define OUT out \n" "# define texture2D texture \n" "#else \n" "# define IN varying \n" "# define OUT \n" "#endif // __VERSION __ \n" "IN mediump vec2 vTexCoord; \n" "uniform sampler2D Sample0; \n" "uniform lowp float uGammaCorrectionLevel; \n" "OUT lowp vec4 fragColor; \n" " \n" "void main() \n" "{ \n" " fragColor = texture2D(Sample0, vTexCoord); \n" " fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / uGammaCorrectionLevel)); \n" FRAGMENT_SHADER_END "} \n" ; static GLuint _createShaderProgram(const char * _strVertex, const char * _strFragment) { GLuint vertex_shader_object = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex_shader_object, 1, &_strVertex, nullptr); glCompileShader(vertex_shader_object); assert(checkShaderCompileStatus(vertex_shader_object)); GLuint fragment_shader_object = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment_shader_object, 1, &_strFragment, nullptr); glCompileShader(fragment_shader_object); assert(checkShaderCompileStatus(fragment_shader_object)); GLuint program = glCreateProgram(); glBindAttribLocation(program, SC_POSITION, "aPosition"); glBindAttribLocation(program, SC_TEXCOORD0, "aTexCoord"); glAttachShader(program, vertex_shader_object); glAttachShader(program, fragment_shader_object); glLinkProgram(program); glDeleteShader(vertex_shader_object); glDeleteShader(fragment_shader_object); assert(checkProgramLinkStatus(program)); return program; } static CachedTexture * _createTexture() { CachedTexture * pTexture = textureCache().addFrameBufferTexture(); pTexture->format = G_IM_FMT_RGBA; pTexture->clampS = 1; pTexture->clampT = 1; pTexture->frameBufferTexture = CachedTexture::fbOneSample; pTexture->maskS = 0; pTexture->maskT = 0; pTexture->mirrorS = 0; pTexture->mirrorT = 0; pTexture->realWidth = video().getWidth(); pTexture->realHeight = video().getHeight(); pTexture->textureBytes = pTexture->realWidth * pTexture->realHeight * 4; textureCache().addFrameBufferTextureSize(pTexture->textureBytes); glBindTexture(GL_TEXTURE_2D, pTexture->glName); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pTexture->realWidth, pTexture->realHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glBindTexture(GL_TEXTURE_2D, 0); return pTexture; } static GLuint _createFBO(CachedTexture * _pTexture) { GLuint FBO; glGenFramebuffers(1, &FBO); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _pTexture->glName, 0); assert(checkFBO()); return FBO; } void PostProcessor::_initCommon() { m_pTextureOriginal = _createTexture(); m_FBO_original = _createFBO(m_pTextureOriginal); #ifdef GLES2 m_copyProgram = _createShaderProgram(vertexShader, copyShader); glUseProgram(m_copyProgram); int loc = glGetUniformLocation(m_copyProgram, "Sample0"); assert(loc >= 0); glUniform1i(loc, 0); glUseProgram(0); #endif glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); } void PostProcessor::_initGammaCorrection() { m_gammaCorrectionProgram = _createShaderProgram(vertexShader, gammaCorrectionShader); glUseProgram(m_gammaCorrectionProgram); int loc = glGetUniformLocation(m_gammaCorrectionProgram, "Sample0"); assert(loc >= 0); glUniform1i(loc, 0); loc = glGetUniformLocation(m_gammaCorrectionProgram, "uGammaCorrectionLevel"); assert(loc >= 0); const f32 gammaLevel = (config.gammaCorrection.force != 0) ? config.gammaCorrection.level : 2.0f; glUniform1f(loc, gammaLevel); glUseProgram(0); } void PostProcessor::_initBlur() { m_extractBloomProgram = _createShaderProgram(vertexShader, extractBloomShader); glUseProgram(m_extractBloomProgram); int loc = glGetUniformLocation(m_extractBloomProgram, "Sample0"); assert(loc >= 0); glUniform1i(loc, 0); loc = glGetUniformLocation(m_extractBloomProgram, "ThresholdLevel"); assert(loc >= 0); glUniform1i(loc, config.bloomFilter.thresholdLevel); m_seperableBlurProgram = _createShaderProgram(vertexShader, seperableBlurShader); glUseProgram(m_seperableBlurProgram); loc = glGetUniformLocation(m_seperableBlurProgram, "Sample0"); assert(loc >= 0); glUniform1i(loc, 0); loc = glGetUniformLocation(m_seperableBlurProgram, "TexelSize"); assert(loc >= 0); glUniform2f(loc, 1.0f / video().getWidth(), 1.0f / video().getHeight()); loc = glGetUniformLocation(m_seperableBlurProgram, "Orientation"); assert(loc >= 0); glUniform1i(loc, 0); loc = glGetUniformLocation(m_seperableBlurProgram, "BlurAmount"); assert(loc >= 0); glUniform1i(loc, config.bloomFilter.blurAmount); loc = glGetUniformLocation(m_seperableBlurProgram, "BlurScale"); assert(loc >= 0); glUniform1f(loc, 1.0f); loc = glGetUniformLocation(m_seperableBlurProgram, "BlurStrength"); assert(loc >= 0); glUniform1f(loc, config.bloomFilter.blurStrength/100.0f); m_glowProgram = _createShaderProgram(vertexShader, glowShader); glUseProgram(m_glowProgram); loc = glGetUniformLocation(m_glowProgram, "Sample0"); assert(loc >= 0); glUniform1i(loc, 0); loc = glGetUniformLocation(m_glowProgram, "Sample1"); assert(loc >= 0); glUniform1i(loc, 1); loc = glGetUniformLocation(m_glowProgram, "BlendMode"); assert(loc >= 0); glUniform1i(loc, config.bloomFilter.blendMode); m_pTextureGlowMap = _createTexture(); m_pTextureBlur = _createTexture(); m_FBO_glowMap = _createFBO(m_pTextureGlowMap); m_FBO_blur = _createFBO(m_pTextureBlur); glUseProgram(0); } void PostProcessor::init() { _initCommon(); _initGammaCorrection(); if (config.bloomFilter.enable != 0) _initBlur(); } void PostProcessor::_destroyCommon() { if (m_copyProgram != 0) glDeleteProgram(m_copyProgram); m_copyProgram = 0; if (m_FBO_original != 0) glDeleteFramebuffers(1, &m_FBO_original); m_FBO_original = 0; if (m_pTextureOriginal != nullptr) textureCache().removeFrameBufferTexture(m_pTextureOriginal); } void PostProcessor::_destroyGammaCorrection() { if (m_gammaCorrectionProgram != 0) glDeleteProgram(m_gammaCorrectionProgram); m_gammaCorrectionProgram = 0; } void PostProcessor::_destroyBlur() { if (m_extractBloomProgram != 0) glDeleteProgram(m_extractBloomProgram); m_extractBloomProgram = 0; if (m_seperableBlurProgram != 0) glDeleteProgram(m_seperableBlurProgram); m_seperableBlurProgram = 0; if (m_glowProgram != 0) glDeleteProgram(m_glowProgram); m_glowProgram = 0; if (m_bloomProgram != 0) glDeleteProgram(m_bloomProgram); m_bloomProgram = 0; if (m_FBO_glowMap != 0) glDeleteFramebuffers(1, &m_FBO_glowMap); m_FBO_glowMap = 0; if (m_FBO_blur != 0) glDeleteFramebuffers(1, &m_FBO_blur); m_FBO_blur = 0; m_pTextureOriginal = nullptr; if (m_pTextureGlowMap != nullptr) textureCache().removeFrameBufferTexture(m_pTextureGlowMap); m_pTextureGlowMap = nullptr; if (m_pTextureBlur != nullptr) textureCache().removeFrameBufferTexture(m_pTextureBlur); m_pTextureBlur = nullptr; } void PostProcessor::destroy() { _destroyBlur(); _destroyGammaCorrection(); _destroyCommon(); } PostProcessor & PostProcessor::get() { static PostProcessor processor; return processor; } void _setGLState() { glDisable(GL_DEPTH_TEST); glDisable(GL_BLEND); static const float vert[] = { -1.0, -1.0, +0.0, +0.0, +1.0, -1.0, +1.0, +0.0, -1.0, +1.0, +0.0, +1.0, +1.0, +1.0, +1.0, +1.0 }; glEnableVertexAttribArray(SC_POSITION); glVertexAttribPointer(SC_POSITION, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (float*)vert); glEnableVertexAttribArray(SC_TEXCOORD0); glVertexAttribPointer(SC_TEXCOORD0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (float*)vert + 2); glDisableVertexAttribArray(SC_COLOR); glDisableVertexAttribArray(SC_TEXCOORD1); glDisableVertexAttribArray(SC_NUMLIGHTS); glViewport(0, 0, video().getWidth(), video().getHeight()); gSP.changed |= CHANGED_VIEWPORT; gDP.changed |= CHANGED_RENDERMODE; } void PostProcessor::_preDraw(FrameBuffer * _pBuffer) { _setGLState(); OGLVideo & ogl = video(); #ifdef GLES2 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FBO_original); textureCache().activateTexture(0, _pBuffer->m_pTexture); glUseProgram(m_copyProgram); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); #else glBindFramebuffer(GL_READ_FRAMEBUFFER, _pBuffer->m_FBO); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FBO_original); glBlitFramebuffer( 0, 0, ogl.getWidth(), ogl.getHeight(), 0, 0, ogl.getWidth(), ogl.getHeight(), GL_COLOR_BUFFER_BIT, GL_LINEAR ); #endif glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); } void PostProcessor::_postDraw() { glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); video().getRender().dropRenderState(); glUseProgram(0); } void PostProcessor::doBlur(FrameBuffer * _pBuffer) { if (config.bloomFilter.enable == 0) return; if (_pBuffer == nullptr || (_pBuffer->m_postProcessed&PostProcessor::postEffectBlur) == PostProcessor::postEffectBlur) return; _pBuffer->m_postProcessed |= PostProcessor::postEffectBlur; _preDraw(_pBuffer); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FBO_glowMap); textureCache().activateTexture(0, m_pTextureOriginal); glUseProgram(m_extractBloomProgram); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FBO_blur); textureCache().activateTexture(0, m_pTextureGlowMap); glUseProgram(m_seperableBlurProgram); int loc = glGetUniformLocation(m_seperableBlurProgram, "Orientation"); assert(loc >= 0); glUniform1i(loc, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FBO_glowMap); textureCache().activateTexture(0, m_pTextureBlur); glUniform1i(loc, 1); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _pBuffer->m_FBO); textureCache().activateTexture(0, m_pTextureOriginal); textureCache().activateTexture(1, m_pTextureGlowMap); glUseProgram(m_glowProgram); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); _postDraw(); } void PostProcessor::doGammaCorrection(FrameBuffer * _pBuffer) { if (((*REG.VI_STATUS & 8)|config.gammaCorrection.force) == 0) return; if (_pBuffer == nullptr || (_pBuffer->m_postProcessed&PostProcessor::postEffectGammaCorrection) == PostProcessor::postEffectGammaCorrection) return; _pBuffer->m_postProcessed |= PostProcessor::postEffectGammaCorrection; _preDraw(_pBuffer); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _pBuffer->m_FBO); textureCache().activateTexture(0, m_pTextureOriginal); glUseProgram(m_gammaCorrectionProgram); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); _postDraw(); } gles2n64/000700 001750 001750 00000000000 12656647145 013252 5ustar00sergiosergio000000 000000 gles2n64/src/VI.h000664 001750 001750 00000000743 12655644434 014545 0ustar00sergiosergio000000 000000 #ifndef VI_H #define VI_H #include "Types.h" #include #ifdef __cplusplus extern "C" { #endif typedef struct { u32 width, widthPrev, height, real_height; f32 rwidth, rheight; u32 lastOrigin; u32 realWidth, realHeight; bool interlaced; bool PAL; struct{ u32 start, end; } display[16]; u32 displayNum; } VIInfo; extern VIInfo VI; void VI_UpdateSize(void); void VI_UpdateScreen(void); #ifdef __cplusplus } #endif #endif mupen64plus-rsp-cxd4/vu/000700 001750 001750 00000000000 12656647145 016204 5ustar00sergiosergio000000 000000 gles2n64/src/gSP.c000664 001750 001750 00000171030 12655644434 014711 0ustar00sergiosergio000000 000000 #include #include #include #include "Common.h" #include "gles2N64.h" #include "Debug.h" #include "Types.h" #include "RSP.h" #include "GBI.h" #include "gSP.h" #include "gDP.h" #include "3DMath.h" #include "OpenGL.h" #include "CRC.h" #include #include "convert.h" #include "S2DEX.h" #include "VI.h" #include "FrameBuffer.h" #include "DepthBuffer.h" #include "Config.h" //Note: 0xC0 is used by 1080 alot, its an unknown command. #ifdef DEBUG extern u32 uc_crc, uc_dcrc; extern char uc_str[256]; #endif void gSPCombineMatrices(void); static INLINE void gSPFlushTriangles(void) { if ((gSP.geometryMode & G_SHADING_SMOOTH) == 0) { OGL_DrawTriangles(); return; } if ( (__RSP.nextCmd != G_TRI1) && (__RSP.nextCmd != G_TRI2) && (__RSP.nextCmd != G_TRI4) && (__RSP.nextCmd != G_QUAD) ) OGL_DrawTriangles(); } void gSPCombineMatrices(void) { MultMatrix(gSP.matrix.projection, gSP.matrix.modelView[gSP.matrix.modelViewi], gSP.matrix.combined); gSP.changed &= ~CHANGED_MATRIX; } void gSPTriangle(s32 v0, s32 v1, s32 v2) { /* TODO/FIXME - update with gliden64 code */ if ((v0 < INDEXMAP_SIZE) && (v1 < INDEXMAP_SIZE) && (v2 < INDEXMAP_SIZE)) { OGL_AddTriangle(v0, v1, v2); } if (depthBuffer.current) depthBuffer.current->cleared = FALSE; gDP.colorImage.height = (u32)(max( gDP.colorImage.height, (u32)gDP.scissor.lry )); } void gSP1Triangle( s32 v0, s32 v1, s32 v2) { gSPTriangle( v0, v1, v2); gSPFlushTriangles(); } void gSP2Triangles(const s32 v00, const s32 v01, const s32 v02, const s32 flag0, const s32 v10, const s32 v11, const s32 v12, const s32 flag1 ) { gSPTriangle( v00, v01, v02); gSPTriangle( v10, v11, v12); gSPFlushTriangles(); } void gSP4Triangles(const s32 v00, const s32 v01, const s32 v02, const s32 v10, const s32 v11, const s32 v12, const s32 v20, const s32 v21, const s32 v22, const s32 v30, const s32 v31, const s32 v32 ) { gSPTriangle(v00, v01, v02); gSPTriangle(v10, v11, v12); gSPTriangle(v20, v21, v22); gSPTriangle(v30, v31, v32); gSPFlushTriangles(); } gSPInfo gSP; f32 identityMatrix[4][4] = { { 1.0f, 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 0.0f, 1.0f } }; static void gSPTransformVertex_default(float vtx[4], float mtx[4][4]) { float x, y, z, w; x = vtx[0]; y = vtx[1]; z = vtx[2]; w = vtx[3]; vtx[0] = x * mtx[0][0] + y * mtx[1][0] + z * mtx[2][0] + mtx[3][0]; vtx[1] = x * mtx[0][1] + y * mtx[1][1] + z * mtx[2][1] + mtx[3][1]; vtx[2] = x * mtx[0][2] + y * mtx[1][2] + z * mtx[2][2] + mtx[3][2]; vtx[3] = x * mtx[0][3] + y * mtx[1][3] + z * mtx[2][3] + mtx[3][3]; } static void gSPLightVertex_default(SPVertex * _vtx) { if (!config.generalEmulation.enableHWLighting) { unsigned i; _vtx->HWLight = 0; _vtx->r = gSP.lights[gSP.numLights].r; _vtx->g = gSP.lights[gSP.numLights].g; _vtx->b = gSP.lights[gSP.numLights].b; for (i = 0; i < gSP.numLights; i++) { f32 intensity = DotProduct( &_vtx->nx, &gSP.lights[i].x ); if (intensity < 0.0f) intensity = 0.0f; _vtx->r += gSP.lights[i].r * intensity; _vtx->g += gSP.lights[i].g * intensity; _vtx->b += gSP.lights[i].b * intensity; } _vtx->r = min(1.0f, _vtx->r); _vtx->g = min(1.0f, _vtx->g); _vtx->b = min(1.0f, _vtx->b); } else { /* TODO/FIXME - update with gliden64 code */ } } static void gSPPointLightVertex_default(SPVertex *_vtx, float * _vPos) { u32 l; float light_intensity = 0.0f; assert(_vPos != NULL); _vtx->HWLight = 0; _vtx->r = gSP.lights[gSP.numLights].r; _vtx->g = gSP.lights[gSP.numLights].g; _vtx->b = gSP.lights[gSP.numLights].b; for (l = 0; l < gSP.numLights; ++l) { float light_len2, light_len, at; float lvec[3] = {gSP.lights[l].posx, gSP.lights[l].posy, gSP.lights[l].posz}; lvec[0] -= _vPos[0]; lvec[1] -= _vPos[1]; lvec[2] -= _vPos[2]; light_len2 = lvec[0]*lvec[0] + lvec[1]*lvec[1] + lvec[2]*lvec[2]; light_len = sqrtf(light_len2); at = gSP.lights[l].ca + light_len/65535.0f*gSP.lights[l].la + light_len2/65535.0f*gSP.lights[l].qa; if (at > 0.0f) light_intensity = 1/at;//DotProduct (lvec, nvec) / (light_len * normal_len * at); else light_intensity = 0.0f; if (light_intensity > 0.0f) { _vtx->r += gSP.lights[l].r * light_intensity; _vtx->g += gSP.lights[l].g * light_intensity; _vtx->b += gSP.lights[l].b * light_intensity; } } if (_vtx->r > 1.0f) _vtx->r = 1.0f; if (_vtx->g > 1.0f) _vtx->g = 1.0f; if (_vtx->b > 1.0f) _vtx->b = 1.0f; } static void gSPLightVertex_CBFD(SPVertex *_vtx) { u32 l; f32 r = gSP.lights[gSP.numLights].r; f32 g = gSP.lights[gSP.numLights].g; f32 b = gSP.lights[gSP.numLights].b; for (l = 0; l < gSP.numLights; ++l) { const SPLight *light = (const SPLight*)&gSP.lights[l]; const f32 vx = (_vtx->x + gSP.vertexCoordMod[ 8])*gSP.vertexCoordMod[12] - light->posx; const f32 vy = (_vtx->y + gSP.vertexCoordMod[ 9])*gSP.vertexCoordMod[13] - light->posy; const f32 vz = (_vtx->z + gSP.vertexCoordMod[10])*gSP.vertexCoordMod[14] - light->posz; const f32 vw = (_vtx->w + gSP.vertexCoordMod[11])*gSP.vertexCoordMod[15] - light->posw; const f32 len = (vx*vx+vy*vy+vz*vz+vw*vw)/65536.0f; f32 intensity = light->ca / len; if (intensity > 1.0f) intensity = 1.0f; r += light->r * intensity; g += light->g * intensity; b += light->b * intensity; } r = min(1.0f, r); g = min(1.0f, g); b = min(1.0f, b); _vtx->r *= r; _vtx->g *= g; _vtx->b *= b; _vtx->HWLight = 0; } static void gSPPointLightVertex_CBFD(SPVertex *_vtx, float * _vPos) { u32 l; const SPLight *light = NULL; f32 r = gSP.lights[gSP.numLights].r; f32 g = gSP.lights[gSP.numLights].g; f32 b = gSP.lights[gSP.numLights].b; f32 intensity = 0.0f; for (l = 0; l < gSP.numLights-1; ++l) { light = (SPLight*)&gSP.lights[l]; intensity = DotProduct( &_vtx->nx, &light->x ); if (intensity < 0.0f) continue; if (light->ca > 0.0f) { const f32 vx = (_vtx->x + gSP.vertexCoordMod[ 8])*gSP.vertexCoordMod[12] - light->posx; const f32 vy = (_vtx->y + gSP.vertexCoordMod[ 9])*gSP.vertexCoordMod[13] - light->posy; const f32 vz = (_vtx->z + gSP.vertexCoordMod[10])*gSP.vertexCoordMod[14] - light->posz; const f32 vw = (_vtx->w + gSP.vertexCoordMod[11])*gSP.vertexCoordMod[15] - light->posw; const f32 len = (vx*vx+vy*vy+vz*vz+vw*vw)/65536.0f; float p_i = light->ca / len; if (p_i > 1.0f) p_i = 1.0f; intensity *= p_i; } r += light->r * intensity; g += light->g * intensity; b += light->b * intensity; } light = (SPLight*)&gSP.lights[gSP.numLights-1]; intensity = DotProduct( &_vtx->nx, &light->x ); if (intensity > 0.0f) { r += light->r * intensity; g += light->g * intensity; b += light->b * intensity; } r = min(1.0f, r); g = min(1.0f, g); b = min(1.0f, b); _vtx->r *= r; _vtx->g *= g; _vtx->b *= b; _vtx->HWLight = 0; } static void gSPBillboardVertex_default(u32 v, u32 i) { SPVertex *vtx0 = (SPVertex*)&OGL.triangles.vertices[i]; SPVertex *vtx = (SPVertex*)&OGL.triangles.vertices[v]; vtx->x += vtx0->x; vtx->y += vtx0->y; vtx->z += vtx0->z; vtx->w += vtx0->w; } void gSPClipVertex(u32 v) { SPVertex *vtx = &OGL.triangles.vertices[v]; vtx->clip = 0; if (vtx->x > +vtx->w) vtx->clip |= CLIP_POSX; if (vtx->x < -vtx->w) vtx->clip |= CLIP_NEGX; if (vtx->y > +vtx->w) vtx->clip |= CLIP_POSY; if (vtx->y < -vtx->w) vtx->clip |= CLIP_NEGY; if (vtx->w < 0.01f) vtx->clip |= CLIP_Z; } void gSPProcessVertex(u32 v) { float vPos[3]; f32 intensity, r, g, b; SPVertex *vtx = (SPVertex*)&OGL.triangles.vertices[v]; if (gSP.changed & CHANGED_MATRIX) gSPCombineMatrices(); vPos[0] = (float)vtx->x; vPos[1] = (float)vtx->y; vPos[2] = (float)vtx->z; gSPTransformVertex( &vtx->x, gSP.matrix.combined ); if (gSP.viewport.vscale[0] < 0) vtx->x = -vtx->x; if (gSP.matrix.billboard) { int i = 0; gSPBillboardVertex(v, i); } gSPClipVertex(v); if (gSP.geometryMode & G_LIGHTING) { TransformVectorNormalize( &vtx->nx, gSP.matrix.modelView[gSP.matrix.modelViewi] ); if (gSP.geometryMode & G_POINT_LIGHTING) gSPPointLightVertex(vtx, vPos); else gSPLightVertex(vtx); if (/* GBI.isTextureGen() && */ gSP.geometryMode & G_TEXTURE_GEN) { f32 fLightDir[3] = {vtx->nx, vtx->ny, vtx->nz}; f32 x, y; if (gSP.lookatEnable) { x = DotProduct(&gSP.lookat[0].x, fLightDir); y = DotProduct(&gSP.lookat[1].x, fLightDir); } else { x = fLightDir[0]; y = fLightDir[1]; } if (gSP.geometryMode & G_TEXTURE_GEN_LINEAR) { vtx->s = acosf(x) * 325.94931f; vtx->t = acosf(y) * 325.94931f; } else /* G_TEXTURE_GEN */ { vtx->s = (x + 1.0f) * 512.0f; vtx->t = (y + 1.0f) * 512.0f; } } } else vtx->HWLight = 0; } void gSPLoadUcodeEx( u32 uc_start, u32 uc_dstart, u16 uc_dsize ) { MicrocodeInfo *ucode; __RSP.PCi = 0; gSP.matrix.modelViewi = 0; gSP.changed |= CHANGED_MATRIX; gSP.status[0] = gSP.status[1] = gSP.status[2] = gSP.status[3] = 0; if ((((uc_start & 0x1FFFFFFF) + 4096) > RDRAMSize) || (((uc_dstart & 0x1FFFFFFF) + uc_dsize) > RDRAMSize)) return; ucode = (MicrocodeInfo*)GBI_DetectMicrocode( uc_start, uc_dstart, uc_dsize ); __RSP.uc_start = uc_start; __RSP.uc_dstart = uc_dstart; /* TODO/FIXME - remove this maybe? for gliden64 */ if (ucode->type != 0xFFFFFFFF) last_good_ucode = ucode->type; if (ucode->type != NONE) GBI_MakeCurrent( ucode ); else { LOG(LOG_WARNING, "Unknown Ucode\n"); } } void gSPNoOp(void) { gSPFlushTriangles(); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_IGNORED, "gSPNoOp();\n" ); #endif } void gSPMatrix( u32 matrix, u8 param ) { f32 mtx[4][4]; u32 address = RSP_SegmentToPhysical( matrix ); if (address + 64 > RDRAMSize) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR | DEBUG_MATRIX, "// Attempting to load matrix from invalid address\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_MATRIX, "gSPMatrix( 0x%08X, %s | %s | %s );\n", matrix, (param & G_MTX_PROJECTION) ? "G_MTX_PROJECTION" : "G_MTX_MODELVIEW", (param & G_MTX_LOAD) ? "G_MTX_LOAD" : "G_MTX_MUL", (param & G_MTX_PUSH) ? "G_MTX_PUSH" : "G_MTX_NOPUSH" ); #endif return; } RSP_LoadMatrix( mtx, address ); if (param & G_MTX_PROJECTION) { if (param & G_MTX_LOAD) CopyMatrix( gSP.matrix.projection, mtx ); else MultMatrix2( gSP.matrix.projection, mtx ); } else { if ((param & G_MTX_PUSH) && (gSP.matrix.modelViewi < (gSP.matrix.stackSize - 1))) { CopyMatrix( gSP.matrix.modelView[gSP.matrix.modelViewi + 1], gSP.matrix.modelView[gSP.matrix.modelViewi] ); gSP.matrix.modelViewi++; } if (param & G_MTX_LOAD) CopyMatrix( gSP.matrix.modelView[gSP.matrix.modelViewi], mtx ); else MultMatrix2( gSP.matrix.modelView[gSP.matrix.modelViewi], mtx ); } gSP.changed |= CHANGED_MATRIX; #ifdef DEBUG DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED | DEBUG_MATRIX, "// %12.6f %12.6f %12.6f %12.6f\n", mtx[0][0], mtx[0][1], mtx[0][2], mtx[0][3] ); DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED | DEBUG_MATRIX, "// %12.6f %12.6f %12.6f %12.6f\n", mtx[1][0], mtx[1][1], mtx[1][2], mtx[1][3] ); DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED | DEBUG_MATRIX, "// %12.6f %12.6f %12.6f %12.6f\n", mtx[2][0], mtx[2][1], mtx[2][2], mtx[2][3] ); DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED | DEBUG_MATRIX, "// %12.6f %12.6f %12.6f %12.6f\n", mtx[3][0], mtx[3][1], mtx[3][2], mtx[3][3] ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_MATRIX, "gSPMatrix( 0x%08X, %s | %s | %s );\n", matrix, (param & G_MTX_PROJECTION) ? "G_MTX_PROJECTION" : "G_MTX_MODELVIEW", (param & G_MTX_LOAD) ? "G_MTX_LOAD" : "G_MTX_MUL", (param & G_MTX_PUSH) ? "G_MTX_PUSH" : "G_MTX_NOPUSH" ); #endif } void gSPDMAMatrix( u32 matrix, u8 index, u8 multiply ) { f32 mtx[4][4]; u32 address = gSP.DMAOffsets.mtx + RSP_SegmentToPhysical( matrix ); if (address + 64 > RDRAMSize) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR | DEBUG_MATRIX, "// Attempting to load matrix from invalid address\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_MATRIX, "gSPDMAMatrix( 0x%08X, %i, %s );\n", matrix, index, multiply ? "TRUE" : "FALSE" ); #endif return; } RSP_LoadMatrix( mtx, address ); gSP.matrix.modelViewi = index; if (multiply) MultMatrix(gSP.matrix.modelView[0], mtx, gSP.matrix.modelView[gSP.matrix.modelViewi]); else CopyMatrix( gSP.matrix.modelView[gSP.matrix.modelViewi], mtx ); CopyMatrix( gSP.matrix.projection, identityMatrix ); gSP.changed |= CHANGED_MATRIX; #ifdef DEBUG DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED | DEBUG_MATRIX, "// %12.6f %12.6f %12.6f %12.6f\n", mtx[0][0], mtx[0][1], mtx[0][2], mtx[0][3] ); DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED | DEBUG_MATRIX, "// %12.6f %12.6f %12.6f %12.6f\n", mtx[1][0], mtx[1][1], mtx[1][2], mtx[1][3] ); DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED | DEBUG_MATRIX, "// %12.6f %12.6f %12.6f %12.6f\n", mtx[2][0], mtx[2][1], mtx[2][2], mtx[2][3] ); DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED | DEBUG_MATRIX, "// %12.6f %12.6f %12.6f %12.6f\n", mtx[3][0], mtx[3][1], mtx[3][2], mtx[3][3] ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_MATRIX, "gSPDMAMatrix( 0x%08X, %i, %s );\n", matrix, index, multiply ? "TRUE" : "FALSE" ); #endif } void gSPViewport(u32 v) { u32 address = RSP_SegmentToPhysical( v ); if ((address + 16) > RDRAMSize) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR, "// Attempting to load viewport from invalid address\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPViewport( 0x%08X );\n", v ); #endif return; } gSP.viewport.vscale[0] = _FIXED2FLOAT( *(s16*)&gfx_info.RDRAM[address + 2], 2 ); gSP.viewport.vscale[1] = _FIXED2FLOAT( *(s16*)&gfx_info.RDRAM[address ], 2 ); gSP.viewport.vscale[2] = _FIXED2FLOAT( *(s16*)&gfx_info.RDRAM[address + 6], 10 ); /* * 0.00097847357f; */ gSP.viewport.vscale[3] = *(s16*)&gfx_info.RDRAM[address + 4]; gSP.viewport.vtrans[0] = _FIXED2FLOAT( *(s16*)&gfx_info.RDRAM[address + 10], 2 ); gSP.viewport.vtrans[1] = _FIXED2FLOAT( *(s16*)&gfx_info.RDRAM[address + 8], 2 ); gSP.viewport.vtrans[2] = _FIXED2FLOAT( *(s16*)&gfx_info.RDRAM[address + 14], 10 ); /* * 0.00097847357f; */ gSP.viewport.vtrans[3] = *(s16*)&gfx_info.RDRAM[address + 12]; gSP.viewport.x = gSP.viewport.vtrans[0] - gSP.viewport.vscale[0]; gSP.viewport.y = gSP.viewport.vtrans[1] - gSP.viewport.vscale[1]; gSP.viewport.width = fabs(gSP.viewport.vscale[0]) * 2; gSP.viewport.height = fabs(gSP.viewport.vscale[1]) * 2; gSP.viewport.nearz = gSP.viewport.vtrans[2] - gSP.viewport.vscale[2]; gSP.viewport.farz = (gSP.viewport.vtrans[2] + gSP.viewport.vscale[2]) ; gSP.changed |= CHANGED_VIEWPORT; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPViewport( 0x%08X );\n", v ); #endif } void gSPForceMatrix( u32 mptr ) { u32 address = RSP_SegmentToPhysical( mptr ); if (address + 64 > RDRAMSize) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR | DEBUG_MATRIX, "// Attempting to load from invalid address" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_MATRIX, "gSPForceMatrix( 0x%08X );\n", mptr ); #endif return; } RSP_LoadMatrix( gSP.matrix.combined, address); gSP.changed &= ~CHANGED_MATRIX; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_MATRIX, "gSPForceMatrix( 0x%08X );\n", mptr ); #endif } void gSPLight( u32 l, s32 n ) { u32 addrByte; Light *light = NULL; --n; addrByte = RSP_SegmentToPhysical( l ); if ((addrByte + sizeof( Light )) > RDRAMSize) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR, "// Attempting to load light from invalid address\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPLight( 0x%08X, LIGHT_%i );\n", l, n ); #endif return; } light = (Light*)&gfx_info.RDRAM[addrByte]; if (n < 8) { u32 addrShort; gSP.lights[n].r = light->r * 0.0039215689f; gSP.lights[n].g = light->g * 0.0039215689f; gSP.lights[n].b = light->b * 0.0039215689f; gSP.lights[n].x = light->x; gSP.lights[n].y = light->y; gSP.lights[n].z = light->z; Normalize( &gSP.lights[n].x ); addrShort = addrByte >> 1; gSP.lights[n].posx = (float)(((short*)gfx_info.RDRAM)[(addrShort+4)^1]); gSP.lights[n].posy = (float)(((short*)gfx_info.RDRAM)[(addrShort+5)^1]); gSP.lights[n].posz = (float)(((short*)gfx_info.RDRAM)[(addrShort+6)^1]); gSP.lights[n].ca = (float)(gfx_info.RDRAM[(addrByte + 3) ^ 3]) / 16.0f; gSP.lights[n].la = (float)(gfx_info.RDRAM[(addrByte + 7) ^ 3]); gSP.lights[n].qa = (float)(gfx_info.RDRAM[(addrByte + 14) ^ 3]) / 8.0f; } if (config.generalEmulation.enableHWLighting != 0) gSP.changed |= CHANGED_LIGHT; #ifdef DEBUG DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED, "// x = %2.6f y = %2.6f z = %2.6f\n", _FIXED2FLOAT( light->x, 7 ), _FIXED2FLOAT( light->y, 7 ), _FIXED2FLOAT( light->z, 7 ) ); DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED, "// r = %3i g = %3i b = %3i\n", light->r, light->g, light->b ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPLight( 0x%08X, LIGHT_%i );\n", l, n ); #endif } void gSPLightCBFD( u32 l, s32 n ) { Light *light = NULL; u32 addrByte = RSP_SegmentToPhysical( l ); if ((addrByte + sizeof( Light )) > RDRAMSize) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR, "// Attempting to load light from invalid address\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPLight( 0x%08X, LIGHT_%i );\n", l, n ); #endif return; } light = (Light*)&gfx_info.RDRAM[addrByte]; if (n < 12) { gSP.lights[n].r = light->r * 0.0039215689f; gSP.lights[n].g = light->g * 0.0039215689f; gSP.lights[n].b = light->b * 0.0039215689f; gSP.lights[n].x = light->x; gSP.lights[n].y = light->y; gSP.lights[n].z = light->z; Normalize( &gSP.lights[n].x ); u32 addrShort = addrByte >> 1; gSP.lights[n].posx = (float)(((short*)gfx_info.RDRAM)[(addrShort+16)^1]); gSP.lights[n].posy = (float)(((short*)gfx_info.RDRAM)[(addrShort+17)^1]); gSP.lights[n].posz = (float)(((short*)gfx_info.RDRAM)[(addrShort+18)^1]); gSP.lights[n].posw = (float)(((short*)gfx_info.RDRAM)[(addrShort+19)^1]); gSP.lights[n].ca = (float)(gfx_info.RDRAM[(addrByte + 12) ^ 3]) / 16.0f; } if (config.generalEmulation.enableHWLighting != 0) gSP.changed |= CHANGED_LIGHT; #ifdef DEBUG DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED, "// x = %2.6f y = %2.6f z = %2.6f\n", _FIXED2FLOAT( light->x, 7 ), _FIXED2FLOAT( light->y, 7 ), _FIXED2FLOAT( light->z, 7 ) ); DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED, "// r = %3i g = %3i b = %3i\n", light->r, light->g, light->b ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPLight( 0x%08X, LIGHT_%i );\n", l, n ); #endif } void gSPLookAt( u32 _l, u32 _n ) { u32 address = RSP_SegmentToPhysical(_l); if ((address + sizeof(Light)) > RDRAMSize) { #ifdef DEBUG DebugMsg(DEBUG_HIGH | DEBUG_ERROR, "// Attempting to load light from invalid address\n"); DebugMsg(DEBUG_HIGH | DEBUG_HANDLED, "gSPLookAt( 0x%08X, LOOKAT_%i );\n", l, n); #endif return; } assert(_n < 2); Light *light = (Light*)&gfx_info.RDRAM[address]; gSP.lookat[_n].x = light->x; gSP.lookat[_n].y = light->y; gSP.lookat[_n].z = light->z; gSP.lookatEnable = (_n == 0) || (_n == 1 && (light->x != 0 || light->y != 0)); Normalize(&gSP.lookat[_n].x); } void gSPVertex( u32 v, u32 n, u32 v0 ) { unsigned int i; Vertex *vertex; u32 address = RSP_SegmentToPhysical( v ); if ((address + sizeof( Vertex ) * n) > RDRAMSize) return; vertex = (Vertex*)&gfx_info.RDRAM[address]; if ((n + v0) <= INDEXMAP_SIZE) { i = v0; for (; i < n + v0; i++) { u32 v = i; SPVertex *vtx = (SPVertex*)&OGL.triangles.vertices[v]; vtx->x = vertex->x; vtx->y = vertex->y; vtx->z = vertex->z; vtx->s = _FIXED2FLOAT( vertex->s, 5 ); vtx->t = _FIXED2FLOAT( vertex->t, 5 ); if (gSP.geometryMode & G_LIGHTING) { vtx->nx = vertex->normal.x; vtx->ny = vertex->normal.y; vtx->nz = vertex->normal.z; vtx->a = vertex->color.a * 0.0039215689f; } else { vtx->r = vertex->color.r * 0.0039215689f; vtx->g = vertex->color.g * 0.0039215689f; vtx->b = vertex->color.b * 0.0039215689f; vtx->a = vertex->color.a * 0.0039215689f; } gSPProcessVertex(v); vertex++; } } else { LOG(LOG_ERROR, "Using Vertex outside buffer v0=%i, n=%i\n", v0, n); } } void gSPCIVertex( u32 v, u32 n, u32 v0 ) { unsigned int i; PDVertex *vertex; u32 address = RSP_SegmentToPhysical( v ); if ((address + sizeof( PDVertex ) * n) > RDRAMSize) return; vertex = (PDVertex*)&gfx_info.RDRAM[address]; if ((n + v0) <= INDEXMAP_SIZE) { i = v0; for(; i < n + v0; i++) { u8 *color; u32 v = i; SPVertex *vtx = (SPVertex*)&OGL.triangles.vertices[v]; vtx->x = vertex->x; vtx->y = vertex->y; vtx->z = vertex->z; vtx->s = _FIXED2FLOAT( vertex->s, 5 ); vtx->t = _FIXED2FLOAT( vertex->t, 5 ); color = (u8*)&gfx_info.RDRAM[gSP.vertexColorBase + (vertex->ci & 0xff)]; if (gSP.geometryMode & G_LIGHTING) { vtx->nx = (s8)color[3]; vtx->ny = (s8)color[2]; vtx->nz = (s8)color[1]; vtx->a = color[0] * 0.0039215689f; } else { vtx->r = color[3] * 0.0039215689f; vtx->g = color[2] * 0.0039215689f; vtx->b = color[1] * 0.0039215689f; vtx->a = color[0] * 0.0039215689f; } gSPProcessVertex(v); vertex++; } } else { LOG(LOG_ERROR, "Using Vertex outside buffer v0=%i, n=%i\n", v0, n); } } void gSPDMAVertex( u32 v, u32 n, u32 v0 ) { unsigned int i; u32 address = gSP.DMAOffsets.vtx + RSP_SegmentToPhysical( v ); if ((address + 10 * n) > RDRAMSize) return; if ((n + v0) <= INDEXMAP_SIZE) { i = v0; for (; i < n + v0; i++) { u32 v = i; SPVertex *vtx = (SPVertex*)&OGL.triangles.vertices[v]; vtx->x = *(s16*)&gfx_info.RDRAM[address ^ 2]; vtx->y = *(s16*)&gfx_info.RDRAM[(address + 2) ^ 2]; vtx->z = *(s16*)&gfx_info.RDRAM[(address + 4) ^ 2]; if (gSP.geometryMode & G_LIGHTING) { vtx->nx = *(s8*)&gfx_info.RDRAM[(address + 6) ^ 3]; vtx->ny = *(s8*)&gfx_info.RDRAM[(address + 7) ^ 3]; vtx->nz = *(s8*)&gfx_info.RDRAM[(address + 8) ^ 3]; vtx->a = *(u8*)&gfx_info.RDRAM[(address + 9) ^ 3] * 0.0039215689f; } else { vtx->r = *(u8*)&gfx_info.RDRAM[(address + 6) ^ 3] * 0.0039215689f; vtx->g = *(u8*)&gfx_info.RDRAM[(address + 7) ^ 3] * 0.0039215689f; vtx->b = *(u8*)&gfx_info.RDRAM[(address + 8) ^ 3] * 0.0039215689f; vtx->a = *(u8*)&gfx_info.RDRAM[(address + 9) ^ 3] * 0.0039215689f; } gSPProcessVertex(v); address += 10; } } else { LOG(LOG_ERROR, "Using Vertex outside buffer v0=%i, n=%i\n", v0, n); } } void gSPCBFDVertex( u32 a, u32 n, u32 v0 ) { u32 address = RSP_SegmentToPhysical(a); if ((address + sizeof( Vertex ) * n) > RDRAMSize) return; Vertex *vertex = (Vertex*)&gfx_info.RDRAM[address]; if ((n + v0) <= INDEXMAP_SIZE) { unsigned int i = v0; for (; i < n + v0; ++i) { u32 v = i; SPVertex *vtx = (SPVertex*)&OGL.triangles.vertices[v]; vtx->x = vertex->x; vtx->y = vertex->y; vtx->z = vertex->z; vtx->s = _FIXED2FLOAT( vertex->s, 5 ); vtx->t = _FIXED2FLOAT( vertex->t, 5 ); if (gSP.geometryMode & G_LIGHTING) { const u32 normaleAddrOffset = (v<<1); vtx->nx = (float)(((s8*)gfx_info.RDRAM)[(gSP.vertexNormalBase + normaleAddrOffset + 0)^3]); vtx->ny = (float)(((s8*)gfx_info.RDRAM)[(gSP.vertexNormalBase + normaleAddrOffset + 1)^3]); vtx->nz = (float)((s8)(vertex->flag&0xFF)); } vtx->r = vertex->color.r * 0.0039215689f; vtx->g = vertex->color.g * 0.0039215689f; vtx->b = vertex->color.b * 0.0039215689f; vtx->a = vertex->color.a * 0.0039215689f; gSPProcessVertex(v); vertex++; } } else { LOG(LOG_ERROR, "Using Vertex outside buffer v0=%i, n=%i\n", v0, n); } } void gSPDisplayList( u32 dl ) { u32 address = RSP_SegmentToPhysical( dl ); if ((address + 8) > RDRAMSize) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR, "// Attempting to load display list from invalid address\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPDisplayList( 0x%08X );\n", dl ); #endif return; } if (__RSP.PCi < (GBI.PCStackSize - 1)) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPDisplayList( 0x%08X );\n", dl ); #endif __RSP.PCi++; __RSP.PC[__RSP.PCi] = address; __RSP.nextCmd = _SHIFTR( *(u32*)&gfx_info.RDRAM[address], 24, 8 ); } else { #ifdef DEBUG assert(false); DebugMsg( DEBUG_HIGH | DEBUG_ERROR, "// PC stack overflow\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPDisplayList( 0x%08X );\n", dl ); #endif } } void gSPBranchList( u32 dl ) { u32 address = RSP_SegmentToPhysical( dl ); if ((address + 8) > RDRAMSize) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR, "// Attempting to branch to display list at invalid address\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPBranchList( 0x%08X );\n", dl ); #endif return; } #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPBranchList( 0x%08X );\n", dl ); #endif __RSP.PC[__RSP.PCi] = address; __RSP.nextCmd = _SHIFTR( *(u32*)&gfx_info.RDRAM[address], 24, 8 ); } void gSPBranchLessZ( u32 branchdl, u32 vtx, f32 zval ) { float zTest; SPVertex *v = NULL; u32 address = RSP_SegmentToPhysical( branchdl ); if ((address + 8) > RDRAMSize) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR, "// Specified display list at invalid address\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPBranchLessZ( 0x%08X, %i, %i );\n", branchdl, vtx, zval ); #endif return; } v = (SPVertex*)&OGL.triangles.vertices[vtx]; zTest = v->z / v->w; if (zTest > 1.0f || zTest <= zval) __RSP.PC[__RSP.PCi] = address; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPBranchLessZ( 0x%08X, %i, %i );\n", branchdl, vtx, zval ); #endif } void gSPDlistCount(u32 count, u32 v) { u32 address = RSP_SegmentToPhysical( v ); if (address == 0 || (address + 8) > RDRAMSize) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR, "// Attempting to branch to display list at invalid address\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPDlistCnt(%d, 0x%08X );\n", count, v ); #endif return; } if (__RSP.PCi >= 9) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR, "// ** DL stack overflow **\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPDlistCnt(%d, 0x%08X );\n", count, v ); #endif return; } #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPDlistCnt(%d, 0x%08X );\n", count, v ); #endif ++__RSP.PCi; /* go to the next PC in the stack */ __RSP.PC[__RSP.PCi] = address; /* jump to the address */ __RSP.nextCmd = _SHIFTR( *(u32*)&gfx_info.RDRAM[address], 24, 8 ); __RSP.count = count + 1; } void gSPSetDMAOffsets( u32 mtxoffset, u32 vtxoffset ) { gSP.DMAOffsets.mtx = mtxoffset; gSP.DMAOffsets.vtx = vtxoffset; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPSetDMAOffsets( 0x%08X, 0x%08X );\n", mtxoffset, vtxoffset ); #endif } void gSPSetDMATexOffset(u32 _addr) { gSP.DMAOffsets.tex_offset = RSP_SegmentToPhysical(_addr); gSP.DMAOffsets.tex_shift = 0; gSP.DMAOffsets.tex_count = 0; } void gSPSetVertexColorBase( u32 base ) { gSP.vertexColorBase = RSP_SegmentToPhysical( base ); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPSetVertexColorBase( 0x%08X );\n", base ); #endif } void gSPSetVertexNormaleBase( u32 base ) { gSP.vertexNormalBase = RSP_SegmentToPhysical( base ); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPSetVertexNormaleBase( 0x%08X );\n", base ); #endif } void gSPDMATriangles( u32 tris, u32 n ) { unsigned int i; s32 v0, v1, v2; SPVertex *pVtx; DKRTriangle *triangles; u32 address = RSP_SegmentToPhysical( tris ); if (address + sizeof( DKRTriangle ) * n > RDRAMSize) return; triangles = (DKRTriangle*)&gfx_info.RDRAM[address]; for (i = 0; i < n; i++) { int mode = 0; if (!(triangles->flag & 0x40)) { if (gSP.viewport.vscale[0] > 0) mode |= G_CULL_BACK; else mode |= G_CULL_FRONT; } if ((gSP.geometryMode&G_CULL_BOTH) != mode) { gSP.geometryMode &= ~G_CULL_BOTH; gSP.geometryMode |= mode; gSP.changed |= CHANGED_GEOMETRYMODE; } v0 = triangles->v0; v1 = triangles->v1; v2 = triangles->v2; OGL.triangles.vertices[v0].s = _FIXED2FLOAT( triangles->s0, 5 ); OGL.triangles.vertices[v0].t = _FIXED2FLOAT( triangles->t0, 5 ); OGL.triangles.vertices[v1].s = _FIXED2FLOAT( triangles->s1, 5 ); OGL.triangles.vertices[v1].t = _FIXED2FLOAT( triangles->t1, 5 ); OGL.triangles.vertices[v2].s = _FIXED2FLOAT( triangles->s2, 5 ); OGL.triangles.vertices[v2].t = _FIXED2FLOAT( triangles->t2, 5 ); triangles++; } OGL_DrawTriangles(); } void gSP1Quadrangle( s32 v0, s32 v1, s32 v2, s32 v3) { gSPTriangle( v0, v1, v2); gSPTriangle( v0, v2, v3); gSPFlushTriangles(); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TRIANGLE, "gSP1Quadrangle( %i, %i, %i, %i );\n", v0, v1, v2, v3 ); #endif } bool gSPCullVertices( u32 v0, u32 vn ) { unsigned int i; u32 clip = 0; if (vn < v0) { // Aidyn Chronicles - The First Mage seems to pass parameters in reverse order. const u32 v = v0; v0 = vn; vn = v; } for (i = v0 + 1; i <= vn; i++) { clip |= (~OGL.triangles.vertices[i].clip) & CLIP_ALL; if (clip == CLIP_ALL) return FALSE; } return TRUE; } static void _loadSpriteImage(const struct uSprite *_pSprite) { gSP.bgImage.address = RSP_SegmentToPhysical( _pSprite->imagePtr ); gSP.bgImage.width = _pSprite->stride; gSP.bgImage.height = _pSprite->imageY + _pSprite->imageH; gSP.bgImage.format = _pSprite->imageFmt; gSP.bgImage.size = _pSprite->imageSiz; gSP.bgImage.palette = 0; gDP.tiles[0].textureMode = TEXTUREMODE_BGIMAGE; gSP.bgImage.imageX = _pSprite->imageX; gSP.bgImage.imageY = _pSprite->imageY; gSP.bgImage.scaleW = gSP.bgImage.scaleH = 1.0f; if (config.frameBufferEmulation.enable != 0) { struct FrameBuffer *pBuffer = FrameBuffer_FindBuffer(gSP.bgImage.address); if (pBuffer != NULL) { gDP.tiles[0].frameBuffer = pBuffer; gDP.tiles[0].textureMode = TEXTUREMODE_FRAMEBUFFER_BG; gDP.tiles[0].loadType = LOADTYPE_TILE; gDP.changed |= CHANGED_TMEM; } } } void gSPSprite2DBase( u32 _base ) { //assert(RSP.nextCmd == 0xBE); const u32 address = RSP_SegmentToPhysical( _base ); struct uSprite *pSprite = (struct uSprite*)&gfx_info.RDRAM[address]; if (pSprite->tlutPtr != 0) { gDPSetTextureImage( 0, 2, 1, pSprite->tlutPtr ); gDPSetTile( 0, 2, 0, 256, 7, 0, 0, 0, 0, 0, 0, 0 ); gDPLoadTLUT( 7, 0, 0, 1020, 0 ); if (pSprite->imageFmt != G_IM_FMT_RGBA) gDP.otherMode.textureLUT = G_TT_RGBA16; else gDP.otherMode.textureLUT = G_TT_NONE; } else gDP.otherMode.textureLUT = G_TT_NONE; _loadSpriteImage(pSprite); gSPTexture( 1.0f, 1.0f, 0, 0, TRUE ); gDP.otherMode.texturePersp = 1; const f32 z = (gDP.otherMode.depthSource == G_ZS_PRIM) ? gDP.primDepth.z : gSP.viewport.nearz; const f32 w = 1.0f; f32 scaleX = 1.0f, scaleY = 1.0f; u32 flipX = 0, flipY = 0; do { f32 ulx, uly, lrx, lry; f32 frameX, frameY, frameW, frameH; s32 v0 = 0, v1 = 1, v2 = 2, v3 = 3; SPVertex *vtx0, *vtx1, *vtx2, *vtx3; u32 w0 = *(u32*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi]]; u32 w1 = *(u32*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi] + 4]; __RSP.cmd = _SHIFTR( w0, 24, 8 ); __RSP.PC[__RSP.PCi] += 8; __RSP.nextCmd = _SHIFTR( *(u32*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi]], 24, 8 ); if (__RSP.cmd == 0xBE ) { /* gSPSprite2DScaleFlip */ scaleX = _FIXED2FLOAT( _SHIFTR(w1, 16, 16), 10 ); scaleY = _FIXED2FLOAT( _SHIFTR(w1, 0, 16), 10 ); flipX = _SHIFTR(w0, 8, 8); flipY = _SHIFTR(w0, 0, 8); continue; } /* gSPSprite2DDraw */ frameX = _FIXED2FLOAT(((s16)_SHIFTR(w1, 16, 16)), 2); frameY = _FIXED2FLOAT(((s16)_SHIFTR(w1, 0, 16)), 2); frameW = pSprite->imageW / scaleX; frameH = pSprite->imageH / scaleY; if (flipX != 0) { ulx = frameX + frameW; lrx = frameX; } else { ulx = frameX; lrx = frameX + frameW; } if (flipY != 0) { uly = frameY + frameH; lry = frameY; } else { uly = frameY; lry = frameY + frameH; } f32 uls = pSprite->imageX; f32 ult = pSprite->imageY; f32 lrs = uls + pSprite->imageW - 1; f32 lrt = ult + pSprite->imageH - 1; /* Hack for WCW Nitro. TODO : activate it later. if (WCW_NITRO) { gSP.bgImage.height /= scaleY; gSP.bgImage.imageY /= scaleY; ult /= scaleY; lrt /= scaleY; gSP.bgImage.width *= scaleY; } */ vtx0 = (SPVertex*)&OGL.triangles.vertices[v0]; vtx0->x = ulx; vtx0->y = uly; vtx0->z = z; vtx0->w = w; vtx0->s = uls; vtx0->t = ult; vtx1 = (SPVertex*)&OGL.triangles.vertices[v1]; vtx1->x = lrx; vtx1->y = uly; vtx1->z = z; vtx1->w = w; vtx1->s = lrs; vtx1->t = ult; vtx2 = (SPVertex*)&OGL.triangles.vertices[v2]; vtx2->x = ulx; vtx2->y = lry; vtx2->z = z; vtx2->w = w; vtx2->s = uls; vtx2->t = lrt; vtx3 = (SPVertex*)&OGL.triangles.vertices[v3]; vtx3->x = lrx; vtx3->y = lry; vtx3->z = z; vtx3->w = w; vtx3->s = lrs; vtx3->t = lrt; OGL_DrawLLETriangle(4); } while (__RSP.nextCmd == 0xBD || __RSP.nextCmd == 0xBE); } void gSPCullDisplayList( u32 v0, u32 vn ) { if (gSPCullVertices( v0, vn )) { if (__RSP.PCi > 0) __RSP.PCi--; else __RSP.halt = TRUE; } } void gSPPopMatrixN( u32 param, u32 num ) { if (gSP.matrix.modelViewi > num - 1) { gSP.matrix.modelViewi -= num; gSP.changed |= CHANGED_MATRIX; } } void gSPPopMatrix( u32 param ) { switch (param) { case 0: // modelview if (gSP.matrix.modelViewi > 0) { gSP.matrix.modelViewi--; gSP.changed |= CHANGED_MATRIX; } break; case 1: // projection, can't break; default: #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR | DEBUG_MATRIX, "// Attempting to pop matrix stack below 0\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_MATRIX, "gSPPopMatrix( %s );\n", (param == G_MTX_MODELVIEW) ? "G_MTX_MODELVIEW" : (param == G_MTX_PROJECTION) ? "G_MTX_PROJECTION" : "G_MTX_INVALID" ); #endif break; } } void gSPSegment( s32 seg, s32 base ) { gSP.segment[seg] = base; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPSegment( %s, 0x%08X );\n", SegmentText[seg], base ); #endif } void gSPClipRatio( u32 r ) { } void gSPInsertMatrix( u32 where, u32 num ) { f32 fraction, integer; if (gSP.changed & CHANGED_MATRIX) gSPCombineMatrices(); if ((where & 0x3) || (where > 0x3C)) return; if (where < 0x20) { fraction = modff( gSP.matrix.combined[0][where >> 1], &integer ); gSP.matrix.combined[0][where >> 1] = (f32)_SHIFTR( num, 16, 16 ) + abs( (int)fraction ); fraction = modff( gSP.matrix.combined[0][(where >> 1) + 1], &integer ); gSP.matrix.combined[0][(where >> 1) + 1] = (f32)_SHIFTR( num, 0, 16 ) + abs( (int)fraction ); } else { f32 newValue; fraction = modff( gSP.matrix.combined[0][(where - 0x20) >> 1], &integer ); newValue = integer + _FIXED2FLOAT( _SHIFTR( num, 16, 16 ), 16); // Make sure the sign isn't lost if ((integer == 0.0f) && (fraction != 0.0f)) newValue = newValue * (fraction / abs( (int)fraction )); gSP.matrix.combined[0][(where - 0x20) >> 1] = newValue; fraction = modff( gSP.matrix.combined[0][((where - 0x20) >> 1) + 1], &integer ); newValue = integer + _FIXED2FLOAT( _SHIFTR( num, 0, 16 ), 16 ); // Make sure the sign isn't lost if ((integer == 0.0f) && (fraction != 0.0f)) newValue = newValue * (fraction / abs( (int)fraction )); gSP.matrix.combined[0][((where - 0x20) >> 1) + 1] = newValue; } } void gSPModifyVertex( u32 vtx, u32 where, u32 val ) { s32 v = vtx; SPVertex *vtx0 = (SPVertex*)&OGL.triangles.vertices[v]; switch (where) { case G_MWO_POINT_RGBA: vtx0->r = _SHIFTR( val, 24, 8 ) * 0.0039215689f; vtx0->g = _SHIFTR( val, 16, 8 ) * 0.0039215689f; vtx0->b = _SHIFTR( val, 8, 8 ) * 0.0039215689f; vtx0->a = _SHIFTR( val, 0, 8 ) * 0.0039215689f; break; case G_MWO_POINT_ST: vtx0->s = _FIXED2FLOAT( (s16)_SHIFTR( val, 16, 16 ), 5 ) / gSP.texture.scales; vtx0->t = _FIXED2FLOAT( (s16)_SHIFTR( val, 0, 16 ), 5 ) / gSP.texture.scalet; break; case G_MWO_POINT_XYSCREEN: { f32 scrX = _FIXED2FLOAT( (s16)_SHIFTR( val, 16, 16 ), 2 ); f32 scrY = _FIXED2FLOAT( (s16)_SHIFTR( val, 0, 16 ), 2 ); vtx0->x = (scrX - gSP.viewport.vtrans[0]) / gSP.viewport.vscale[0]; vtx0->x *= vtx0->w; vtx0->y = -(scrY - gSP.viewport.vtrans[1]) / gSP.viewport.vscale[1]; vtx0->y *= vtx0->w; vtx0->clip &= ~(CLIP_POSX | CLIP_NEGX | CLIP_POSY | CLIP_NEGY); } break; case G_MWO_POINT_ZSCREEN: { f32 scrZ = _FIXED2FLOAT((s16)_SHIFTR(val, 16, 16), 15); vtx0->z = (scrZ - gSP.viewport.vtrans[2]) / (gSP.viewport.vscale[2]); vtx0->z *= vtx0->w; vtx0->clip &= ~CLIP_Z; } break; } } void gSPNumLights( s32 n ) { if (n <= 12) { gSP.numLights = n; if (config.generalEmulation.enableHWLighting != 0) gSP.changed |= CHANGED_LIGHT; } #ifdef DEBUG else DebugMsg( DEBUG_HIGH | DEBUG_ERROR, "// Setting an invalid number of lights\n" ); #endif #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPNumLights( %i );\n", n ); #endif } void gSPLightColor( u32 lightNum, u32 packedColor ) { lightNum--; if (lightNum < 8) { gSP.lights[lightNum].r = _SHIFTR( packedColor, 24, 8 ) * 0.0039215689f; gSP.lights[lightNum].g = _SHIFTR( packedColor, 16, 8 ) * 0.0039215689f; gSP.lights[lightNum].b = _SHIFTR( packedColor, 8, 8 ) * 0.0039215689f; if (config.generalEmulation.enableHWLighting != 0) gSP.changed |= CHANGED_LIGHT; } #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPLightColor( %i, 0x%08X );\n", lightNum, packedColor ); #endif } void gSPFogFactor( s16 fm, s16 fo ) { gSP.fog.multiplier = fm; gSP.fog.offset = fo; gSP.changed |= CHANGED_FOGPOSITION; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPFogFactor( %i, %i );\n", fm, fo ); #endif } void gSPPerspNormalize( u16 scale ) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_UNHANDLED, "gSPPerspNormalize( %i );\n", scale ); #endif } void gSPCoordMod(u32 _w0, u32 _w1) { u32 idx, pos; if ((_w0&8) != 0) return; idx = _SHIFTR(_w0, 1, 2); pos = _w0&0x30; if (pos == 0) { gSP.vertexCoordMod[0+idx] = (f32)(s16)_SHIFTR(_w1, 16, 16); gSP.vertexCoordMod[1+idx] = (f32)(s16)_SHIFTR(_w1, 0, 16); } else if (pos == 0x10) { assert(idx < 3); gSP.vertexCoordMod[4+idx] = _SHIFTR(_w1, 16, 16)/65536.0f; gSP.vertexCoordMod[5+idx] = _SHIFTR(_w1, 0, 16)/65536.0f; gSP.vertexCoordMod[12+idx] = gSP.vertexCoordMod[0+idx] + gSP.vertexCoordMod[4+idx]; gSP.vertexCoordMod[13+idx] = gSP.vertexCoordMod[1+idx] + gSP.vertexCoordMod[5+idx]; } else if (pos == 0x20) { gSP.vertexCoordMod[8+idx] = (f32)(s16)_SHIFTR(_w1, 16, 16); gSP.vertexCoordMod[9+idx] = (f32)(s16)_SHIFTR(_w1, 0, 16); } } void gSPTexture( f32 sc, f32 tc, s32 level, s32 tile, s32 on ) { gSP.texture.on = on; if (on == 0) return; gSP.texture.scales = sc; gSP.texture.scalet = tc; if (gSP.texture.scales == 0.0f) gSP.texture.scales = 1.0f; if (gSP.texture.scalet == 0.0f) gSP.texture.scalet = 1.0f; gSP.texture.level = level; gSP.texture.tile = tile; gSP.textureTile[0] = &gDP.tiles[tile]; gSP.textureTile[1] = &gDP.tiles[(tile + 1) & 7]; gSP.changed |= CHANGED_TEXTURE; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gSPTexture( %f, %f, %i, %i, %i );\n", sc, tc, level, tile, on ); #endif } void gSPEndDisplayList(void) { if (__RSP.PCi > 0) __RSP.PCi--; else { #ifdef DEBUG DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED, "// End of display list, halting execution\n" ); #endif __RSP.halt = TRUE; } #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPEndDisplayList();\n\n" ); #endif } void gSPGeometryMode( u32 clear, u32 set ) { gSP.geometryMode = (gSP.geometryMode & ~clear) | set; gSP.changed |= CHANGED_GEOMETRYMODE; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPGeometryMode( %s%s%s%s%s%s%s%s%s%s, %s%s%s%s%s%s%s%s%s%s );\n", clear & G_SHADE ? "G_SHADE | " : "", clear & G_LIGHTING ? "G_LIGHTING | " : "", clear & G_SHADING_SMOOTH ? "G_SHADING_SMOOTH | " : "", clear & G_ZBUFFER ? "G_ZBUFFER | " : "", clear & G_TEXTURE_GEN ? "G_TEXTURE_GEN | " : "", clear & G_TEXTURE_GEN_LINEAR ? "G_TEXTURE_GEN_LINEAR | " : "", clear & G_CULL_FRONT ? "G_CULL_FRONT | " : "", clear & G_CULL_BACK ? "G_CULL_BACK | " : "", clear & G_FOG ? "G_FOG | " : "", clear & G_CLIPPING ? "G_CLIPPING" : "", set & G_SHADE ? "G_SHADE | " : "", set & G_LIGHTING ? "G_LIGHTING | " : "", set & G_SHADING_SMOOTH ? "G_SHADING_SMOOTH | " : "", set & G_ZBUFFER ? "G_ZBUFFER | " : "", set & G_TEXTURE_GEN ? "G_TEXTURE_GEN | " : "", set & G_TEXTURE_GEN_LINEAR ? "G_TEXTURE_GEN_LINEAR | " : "", set & G_CULL_FRONT ? "G_CULL_FRONT | " : "", set & G_CULL_BACK ? "G_CULL_BACK | " : "", set & G_FOG ? "G_FOG | " : "", set & G_CLIPPING ? "G_CLIPPING" : "" ); #endif } void gSPSetGeometryMode( u32 mode ) { gSP.geometryMode |= mode; gSP.changed |= CHANGED_GEOMETRYMODE; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPSetGeometryMode( %s%s%s%s%s%s%s%s%s%s );\n", mode & G_SHADE ? "G_SHADE | " : "", mode & G_LIGHTING ? "G_LIGHTING | " : "", mode & G_SHADING_SMOOTH ? "G_SHADING_SMOOTH | " : "", mode & G_ZBUFFER ? "G_ZBUFFER | " : "", mode & G_TEXTURE_GEN ? "G_TEXTURE_GEN | " : "", mode & G_TEXTURE_GEN_LINEAR ? "G_TEXTURE_GEN_LINEAR | " : "", mode & G_CULL_FRONT ? "G_CULL_FRONT | " : "", mode & G_CULL_BACK ? "G_CULL_BACK | " : "", mode & G_FOG ? "G_FOG | " : "", mode & G_CLIPPING ? "G_CLIPPING" : "" ); #endif } void gSPClearGeometryMode( u32 mode ) { gSP.geometryMode &= ~mode; gSP.changed |= CHANGED_GEOMETRYMODE; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPClearGeometryMode( %s%s%s%s%s%s%s%s%s%s );\n", mode & G_SHADE ? "G_SHADE | " : "", mode & G_LIGHTING ? "G_LIGHTING | " : "", mode & G_SHADING_SMOOTH ? "G_SHADING_SMOOTH | " : "", mode & G_ZBUFFER ? "G_ZBUFFER | " : "", mode & G_TEXTURE_GEN ? "G_TEXTURE_GEN | " : "", mode & G_TEXTURE_GEN_LINEAR ? "G_TEXTURE_GEN_LINEAR | " : "", mode & G_CULL_FRONT ? "G_CULL_FRONT | " : "", mode & G_CULL_BACK ? "G_CULL_BACK | " : "", mode & G_FOG ? "G_FOG | " : "", mode & G_CLIPPING ? "G_CLIPPING" : "" ); #endif } void gSPSetOtherMode_H(u32 _length, u32 _shift, u32 _data) { const u32 mask = (((u64)1 << _length) - 1) << _shift; gDP.otherMode.h = (gDP.otherMode.h&(~mask)) | _data; if (mask & 0x00300000) // cycle type gDP.changed |= CHANGED_CYCLETYPE; } void gSPSetOtherMode_L(u32 _length, u32 _shift, u32 _data) { const u32 mask = (((u64)1 << _length) - 1) << _shift; gDP.otherMode.l = (gDP.otherMode.l&(~mask)) | _data; if (mask & 0xFFFFFFF8) // rendermode / blender bits gDP.changed |= CHANGED_RENDERMODE; } void gSPLine3D( s32 v0, s32 v1, s32 flag ) { OGL_DrawLine(v0, v1, 1.5f ); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_UNHANDLED, "gSPLine3D( %i, %i, %i );\n", v0, v1, flag ); #endif } void gSPLineW3D( s32 v0, s32 v1, s32 wd, s32 flag ) { OGL_DrawLine(v0, v1, 1.5f + wd * 0.5f ); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_UNHANDLED, "gSPLineW3D( %i, %i, %i, %i );\n", v0, v1, wd, flag ); #endif } static void _loadBGImage(const struct uObjScaleBg * _bgInfo, bool _loadScale) { gSP.bgImage.address = RSP_SegmentToPhysical( _bgInfo->imagePtr ); const u32 imageW = _bgInfo->imageW >> 2; gSP.bgImage.width = imageW - imageW%2; const u32 imageH = _bgInfo->imageH >> 2; gSP.bgImage.height = imageH - imageH%2; gSP.bgImage.format = _bgInfo->imageFmt; gSP.bgImage.size = _bgInfo->imageSiz; gSP.bgImage.palette = _bgInfo->imagePal; gDP.tiles[0].textureMode = TEXTUREMODE_BGIMAGE; gSP.bgImage.imageX = _FIXED2FLOAT( _bgInfo->imageX, 5 ); gSP.bgImage.imageY = _FIXED2FLOAT( _bgInfo->imageY, 5 ); if (_loadScale) { gSP.bgImage.scaleW = _FIXED2FLOAT( _bgInfo->scaleW, 10 ); gSP.bgImage.scaleH = _FIXED2FLOAT( _bgInfo->scaleH, 10 ); } else gSP.bgImage.scaleW = gSP.bgImage.scaleH = 1.0f; if (config.frameBufferEmulation.enable) { struct FrameBuffer *pBuffer = FrameBuffer_FindBuffer(gSP.bgImage.address); /* TODO/FIXME */ if ((pBuffer != NULL) && pBuffer->m_size == gSP.bgImage.size && (/* !pBuffer->m_isDepthBuffer || */ pBuffer->m_changed)) { gDP.tiles[0].frameBuffer = pBuffer; gDP.tiles[0].textureMode = TEXTUREMODE_FRAMEBUFFER_BG; gDP.tiles[0].loadType = LOADTYPE_TILE; gDP.changed |= CHANGED_TMEM; } } } struct ObjCoordinates { f32 ulx, uly, lrx, lry; f32 uls, ult, lrs, lrt; f32 z, w; }; struct ObjData { f32 scaleW; f32 scaleH; u32 imageW; u32 imageH; f32 X0; f32 X1; f32 Y0; f32 Y1; bool flipS, flipT; }; void ObjData_new(struct ObjData *obj, const struct uObjSprite *_pObjSprite) { obj->scaleW = _FIXED2FLOAT(_pObjSprite->scaleW, 10); obj->scaleH = _FIXED2FLOAT(_pObjSprite->scaleH, 10); obj->imageW = _pObjSprite->imageW >> 5; obj->imageH = _pObjSprite->imageH >> 5; obj->X0 = _FIXED2FLOAT(_pObjSprite->objX, 2); obj->X1 = obj->X0 + obj->imageW / obj->scaleW; obj->Y0 = _FIXED2FLOAT(_pObjSprite->objY, 2); obj->Y1 = obj->Y0 + obj->imageH / obj->scaleH; obj->flipS = (_pObjSprite->imageFlags & 0x01) != 0; obj->flipT = (_pObjSprite->imageFlags & 0x10) != 0; } void ObjCoordinates_new(struct ObjCoordinates *obj, const struct uObjSprite *_pObjSprite, bool _useMatrix) { struct ObjData data; ObjData_new(&data, _pObjSprite); obj->ulx = data.X0; obj->lrx = data.X1; obj->uly = data.Y0; obj->lry = data.Y1; if (_useMatrix) { obj->ulx = obj->ulx / gSP.objMatrix.baseScaleX + gSP.objMatrix.X; obj->lrx = obj->lrx / gSP.objMatrix.baseScaleX + gSP.objMatrix.X; obj->uly = obj->uly / gSP.objMatrix.baseScaleY + gSP.objMatrix.Y; obj->lry = obj->lry / gSP.objMatrix.baseScaleY + gSP.objMatrix.Y; } obj->uls = obj->ult = 0; obj->lrs = data.imageW - 1; obj->lrt = data.imageH - 1; if (data.flipS) { obj->uls = obj->lrs; obj->lrs = 0; } if (data.flipT) { obj->ult = obj->lrt; obj->lrt = 0; } obj->z = (gDP.otherMode.depthSource == G_ZS_PRIM) ? gDP.primDepth.z : gSP.viewport.nearz; obj->w = 1.0f; } void ObjCoordinates2_new(struct ObjCoordinates *obj, const struct uObjScaleBg * _pObjScaleBg) { const f32 frameX = _FIXED2FLOAT(_pObjScaleBg->frameX, 2); const f32 frameY = _FIXED2FLOAT(_pObjScaleBg->frameY, 2); const f32 frameW = _FIXED2FLOAT(_pObjScaleBg->frameW, 2); const f32 frameH = _FIXED2FLOAT(_pObjScaleBg->frameH, 2); const f32 imageX = gSP.bgImage.imageX; const f32 imageY = gSP.bgImage.imageY; const f32 imageW = (f32)(_pObjScaleBg->imageW>>2); const f32 imageH = (f32)(_pObjScaleBg->imageH >> 2); // const f32 imageW = (f32)gSP.bgImage.width; // const f32 imageH = (f32)gSP.bgImage.height; const f32 scaleW = gSP.bgImage.scaleW; const f32 scaleH = gSP.bgImage.scaleH; obj->ulx = frameX; obj->uly = frameY; obj->lrx = frameX + min(imageW/scaleW, frameW) - 1.0f; obj->lry = frameY + min(imageH/scaleH, frameH) - 1.0f; if (gDP.otherMode.cycleType == G_CYC_COPY) { obj->lrx += 1.0f; obj->lry += 1.0f;; } obj->uls = imageX; obj->ult = imageY; obj->lrs = obj->uls + (obj->lrx - obj->ulx) * scaleW; obj->lrt = obj->ult + (obj->lry - obj->uly) * scaleH; if (gDP.otherMode.cycleType != G_CYC_COPY) { if ((gSP.objRendermode&G_OBJRM_SHRINKSIZE_1) != 0) { obj->lrs -= 1.0f / scaleW; obj->lrt -= 1.0f / scaleH; } else if ((gSP.objRendermode&G_OBJRM_SHRINKSIZE_2) != 0) { obj->lrs -= 1.0f; obj->lrt -= 1.0f; } } if ((_pObjScaleBg->imageFlip & 0x01) != 0) { obj->ulx = obj->lrx; obj->lrx = frameX; } obj->z = (gDP.otherMode.depthSource == G_ZS_PRIM) ? gDP.primDepth.z : gSP.viewport.nearz; obj->w = 1.0f; } static void gSPDrawObjRect(const struct ObjCoordinates *_coords) { SPVertex *vtx0, *vtx1, *vtx2, *vtx3; u32 v0 = 0, v1 = 1, v2 = 2, v3 = 3; vtx0 = (SPVertex*)&OGL.triangles.vertices[v0]; vtx0->x = _coords->ulx; vtx0->y = _coords->uly; vtx0->z = _coords->z; vtx0->w = _coords->w; vtx0->s = _coords->uls; vtx0->t = _coords->ult; vtx1 = (SPVertex*)&OGL.triangles.vertices[v1]; vtx1->x = _coords->lrx; vtx1->y = _coords->uly; vtx1->z = _coords->z; vtx1->w = _coords->w; vtx1->s = _coords->lrs; vtx1->t = _coords->ult; vtx2 = (SPVertex*)&OGL.triangles.vertices[v2]; vtx2->x = _coords->ulx; vtx2->y = _coords->lry; vtx2->z = _coords->z; vtx2->w = _coords->w; vtx2->s = _coords->uls; vtx2->t = _coords->lrt; vtx3 = (SPVertex*)&OGL.triangles.vertices[v3]; vtx3->x = _coords->lrx; vtx3->y = _coords->lry; vtx3->z = _coords->z; vtx3->w = _coords->w; vtx3->s = _coords->lrs; vtx3->t = _coords->lrt; OGL_DrawLLETriangle(4); gDP.colorImage.height = (u32)(max(gDP.colorImage.height, (u32)gDP.scissor.lry)); } void gSPBgRect1Cyc( u32 _bg ) { struct ObjCoordinates objCoords; const u32 address = RSP_SegmentToPhysical( _bg ); struct uObjScaleBg *objScaleBg = (struct uObjScaleBg*)&gfx_info.RDRAM[address]; _loadBGImage(objScaleBg, true); #ifdef GL_IMAGE_TEXTURES_SUPPORT if (gSP.bgImage.address == gDP.depthImageAddress || depthBufferList().findBuffer(gSP.bgImage.address) != NULL) _copyDepthBuffer(); // Zelda MM uses depth buffer copy in LoT and in pause screen. // In later case depth buffer is used as temporal color buffer, and usual rendering must be used. // Since both situations are hard to distinguish, do the both depth buffer copy and bg rendering. #endif // GL_IMAGE_TEXTURES_SUPPORT gDP.otherMode.cycleType = G_CYC_1CYCLE; gDP.changed |= CHANGED_CYCLETYPE; gSPTexture(1.0f, 1.0f, 0, 0, TRUE); gDP.otherMode.texturePersp = 1; ObjCoordinates2_new(&objCoords, objScaleBg); gSPDrawObjRect(&objCoords); } void gSPBgRectCopy( u32 _bg ) { struct ObjCoordinates objCoords; const u32 address = RSP_SegmentToPhysical( _bg ); struct uObjScaleBg *objBg = (struct uObjScaleBg*)&gfx_info.RDRAM[address]; _loadBGImage(objBg, false); #ifdef GL_IMAGE_TEXTURES_SUPPORT if (gSP.bgImage.address == gDP.depthImageAddress || depthBufferList().findBuffer(gSP.bgImage.address) != NULL) _copyDepthBuffer(); // See comment to gSPBgRect1Cyc #endif // GL_IMAGE_TEXTURES_SUPPORT gSPTexture( 1.0f, 1.0f, 0, 0, TRUE ); gDP.otherMode.texturePersp = 1; ObjCoordinates2_new(&objCoords, objBg); gSPDrawObjRect(&objCoords); } void gSPObjLoadTxtr( u32 tx ) { u32 address = RSP_SegmentToPhysical( tx ); uObjTxtr *objTxtr = (uObjTxtr*)&gfx_info.RDRAM[address]; if ((gSP.status[objTxtr->block.sid >> 2] & objTxtr->block.mask) != objTxtr->block.flag) { switch (objTxtr->block.type) { case G_OBJLT_TXTRBLOCK: gDPSetTextureImage( 0, 1, 0, objTxtr->block.image ); gDPSetTile( 0, 1, 0, objTxtr->block.tmem, 7, 0, 0, 0, 0, 0, 0, 0 ); gDPLoadBlock( 7, 0, 0, ((objTxtr->block.tsize + 1) << 3) - 1, objTxtr->block.tline ); break; case G_OBJLT_TXTRTILE: gDPSetTextureImage( 0, 1, (objTxtr->tile.twidth + 1) << 1, objTxtr->tile.image ); gDPSetTile( 0, 1, (objTxtr->tile.twidth + 1) >> 2, objTxtr->tile.tmem, 7, 0, 0, 0, 0, 0, 0, 0 ); gDPLoadTile( 7, 0, 0, (((objTxtr->tile.twidth + 1) << 1) - 1) << 2, (((objTxtr->tile.theight + 1) >> 2) - 1) << 2 ); break; case G_OBJLT_TLUT: gDPSetTextureImage( 0, 2, 1, objTxtr->tlut.image ); gDPSetTile( 0, 2, 0, objTxtr->tlut.phead, 7, 0, 0, 0, 0, 0, 0, 0 ); gDPLoadTLUT( 7, 0, 0, objTxtr->tlut.pnum << 2, 0 ); break; } gSP.status[objTxtr->block.sid >> 2] = (gSP.status[objTxtr->block.sid >> 2] & ~objTxtr->block.mask) | (objTxtr->block.flag & objTxtr->block.mask); } } static void gSPSetSpriteTile(const struct uObjSprite *_pObjSprite) { const u32 w = max(_pObjSprite->imageW >> 5, 1); const u32 h = max(_pObjSprite->imageH >> 5, 1); gDPSetTile( _pObjSprite->imageFmt, _pObjSprite->imageSiz, _pObjSprite->imageStride, _pObjSprite->imageAdrs, 0, _pObjSprite->imagePal, G_TX_CLAMP, G_TX_CLAMP, 0, 0, 0, 0 ); gDPSetTileSize( 0, 0, 0, (w - 1) << 2, (h - 1) << 2 ); gSPTexture( 1.0f, 1.0f, 0, 0, TRUE ); gDP.otherMode.texturePersp = 1; } static u16 _YUVtoRGBA(u8 y, u8 u, u8 v) { float r = y + (1.370705f * (v - 128)); float g = y - (0.698001f * (v - 128)) - (0.337633f * (u - 128)); float b = y + (1.732446f * (u - 128)); r *= 0.125f; g *= 0.125f; b *= 0.125f; //clipping the result if (r > 32) r = 32; if (g > 32) g = 32; if (b > 32) b = 32; if (r < 0) r = 0; if (g < 0) g = 0; if (b < 0) b = 0; u16 c = (u16)(((u16)(r) << 11) | ((u16)(g) << 6) | ((u16)(b) << 1) | 1); return c; } static void _drawYUVImageToFrameBuffer(const struct ObjCoordinates *_objCoords) { u16 h, w; const u32 ulx = (u32)_objCoords->ulx; const u32 uly = (u32)_objCoords->uly; const u32 lrx = (u32)_objCoords->lrx; const u32 lry = (u32)_objCoords->lry; const u32 ci_width = gDP.colorImage.width; const u32 ci_height = gDP.colorImage.height; if (ulx >= ci_width) return; if (uly >= ci_height) return; u32 width = 16, height = 16; if (lrx > ci_width) width = ci_width - ulx; if (lry > ci_height) height = ci_height - uly; u32 * mb = (u32*)(gfx_info.RDRAM + gDP.textureImage.address); //pointer to the first macro block u16 * dst = (u16*)(gfx_info.RDRAM + gDP.colorImage.address); dst += ulx + uly * ci_width; /* YUV macro block contains 16x16 texture. * we need to put it in the proper place inside cimg */ for (h = 0; h < 16; h++) { for (w = 0; w < 16; w += 2) { u32 t = *(mb++); //each u32 contains 2 pixels if ((h < height) && (w < width)) //clipping. texture image may be larger than color image { u8 y0 = (u8)t & 0xFF; u8 v = (u8)(t >> 8) & 0xFF; u8 y1 = (u8)(t >> 16) & 0xFF; u8 u = (u8)(t >> 24) & 0xFF; *(dst++) = _YUVtoRGBA(y0, u, v); *(dst++) = _YUVtoRGBA(y1, u, v); } } dst += ci_width - 16; } struct FrameBuffer *pBuffer = FrameBuffer_GetCurrent(); if (pBuffer != NULL) { #if 0 pBuffer->m_isOBScreen = true; #endif } } void gSPObjRectangle(u32 _sp) { struct ObjCoordinates objCoords; const u32 address = RSP_SegmentToPhysical(_sp); struct uObjSprite *objSprite = (struct uObjSprite*)&gfx_info.RDRAM[address]; gSPSetSpriteTile(objSprite); ObjCoordinates_new(&objCoords, objSprite, false); gSPDrawObjRect(&objCoords); } void gSPObjRectangleR(u32 _sp) { const u32 address = RSP_SegmentToPhysical(_sp); const struct uObjSprite *objSprite = (struct uObjSprite*)&gfx_info.RDRAM[address]; gSPSetSpriteTile(objSprite); struct ObjCoordinates objCoords; ObjCoordinates_new(&objCoords, objSprite, true); if (objSprite->imageFmt == G_IM_FMT_YUV && (config.generalEmulation.hacks & hack_Ogre64)) //Ogre Battle needs to copy YUV texture to frame buffer _drawYUVImageToFrameBuffer(&objCoords); gSPDrawObjRect(&objCoords); } void gSPObjSprite( u32 _sp ) { SPVertex *vtx0, *vtx1, *vtx2, *vtx3; float uls, lrs, ult, lrt; f32 ulx, uly, lrx, lry; struct ObjData data; const u32 address = RSP_SegmentToPhysical( _sp ); struct uObjSprite *objSprite = (struct uObjSprite*)&gfx_info.RDRAM[address]; gSPSetSpriteTile(objSprite); ObjData_new(&data, objSprite); ulx = data.X0; uly = data.Y0; lrx = data.X1; lry = data.Y1; uls = 0; lrs = data.imageW - 1; ult = 0; lrt = data.imageH - 1; if (objSprite->imageFlags & 0x01) { // flipS uls = lrs; lrs = 0; } if (objSprite->imageFlags & 0x10) { // flipT ult = lrt; lrt = 0; } const float z = (gDP.otherMode.depthSource == G_ZS_PRIM) ? gDP.primDepth.z : gSP.viewport.nearz; s32 v0 = 0, v1 = 1, v2 = 2, v3 = 3; vtx0 = (SPVertex*)&OGL.triangles.vertices[v0]; vtx0->x = gSP.objMatrix.A * ulx + gSP.objMatrix.B * uly + gSP.objMatrix.X; vtx0->y = gSP.objMatrix.C * ulx + gSP.objMatrix.D * uly + gSP.objMatrix.Y; vtx0->z = z; vtx0->w = 1.0f; vtx0->s = uls; vtx0->t = ult; vtx1 = (SPVertex*)&OGL.triangles.vertices[v1]; vtx1->x = gSP.objMatrix.A * lrx + gSP.objMatrix.B * uly + gSP.objMatrix.X; vtx1->y = gSP.objMatrix.C * lrx + gSP.objMatrix.D * uly + gSP.objMatrix.Y; vtx1->z = z; vtx1->w = 1.0f; vtx1->s = lrs; vtx1->t = ult; vtx2 = (SPVertex*)&OGL.triangles.vertices[v2]; vtx2->x = gSP.objMatrix.A * ulx + gSP.objMatrix.B * lry + gSP.objMatrix.X; vtx2->y = gSP.objMatrix.C * ulx + gSP.objMatrix.D * lry + gSP.objMatrix.Y; vtx2->z = z; vtx2->w = 1.0f; vtx2->s = uls; vtx2->t = lrt; vtx3 = (SPVertex*)&OGL.triangles.vertices[v3]; vtx3->x = gSP.objMatrix.A * lrx + gSP.objMatrix.B * lry + gSP.objMatrix.X; vtx3->y = gSP.objMatrix.C * lrx + gSP.objMatrix.D * lry + gSP.objMatrix.Y; vtx3->z = z; vtx3->w = 1.0f; vtx3->s = lrs; vtx3->t = lrt; OGL_DrawLLETriangle(4); #ifdef NEW /* TODO/FIXME */ frameBufferList().setBufferChanged(); #endif gDP.colorImage.height = (u32)(max( gDP.colorImage.height, (u32)gDP.scissor.lry )); } void gSPObjLoadTxSprite( u32 txsp ) { gSPObjLoadTxtr( txsp ); gSPObjSprite( txsp + sizeof( uObjTxtr ) ); } void gSPObjLoadTxRect(u32 txsp) { gSPObjLoadTxtr(txsp); gSPObjRectangle(txsp + sizeof(uObjTxtr)); } void gSPObjLoadTxRectR( u32 txsp ) { gSPObjLoadTxtr( txsp ); gSPObjRectangleR( txsp + sizeof( uObjTxtr ) ); } void gSPObjMatrix( u32 mtx ) { u32 address = RSP_SegmentToPhysical( mtx ); uObjMtx *objMtx = (uObjMtx*)&gfx_info.RDRAM[address]; gSP.objMatrix.A = _FIXED2FLOAT( objMtx->A, 16 ); gSP.objMatrix.B = _FIXED2FLOAT( objMtx->B, 16 ); gSP.objMatrix.C = _FIXED2FLOAT( objMtx->C, 16 ); gSP.objMatrix.D = _FIXED2FLOAT( objMtx->D, 16 ); gSP.objMatrix.X = _FIXED2FLOAT( objMtx->X, 2 ); gSP.objMatrix.Y = _FIXED2FLOAT( objMtx->Y, 2 ); gSP.objMatrix.baseScaleX = _FIXED2FLOAT( objMtx->BaseScaleX, 10 ); gSP.objMatrix.baseScaleY = _FIXED2FLOAT( objMtx->BaseScaleY, 10 ); } void gSPObjSubMatrix( u32 mtx ) { u32 address = RSP_SegmentToPhysical(mtx); uObjSubMtx *objMtx = (uObjSubMtx*)&gfx_info.RDRAM[address]; gSP.objMatrix.X = _FIXED2FLOAT(objMtx->X, 2); gSP.objMatrix.Y = _FIXED2FLOAT(objMtx->Y, 2); gSP.objMatrix.baseScaleX = _FIXED2FLOAT(objMtx->BaseScaleX, 10); gSP.objMatrix.baseScaleY = _FIXED2FLOAT(objMtx->BaseScaleY, 10); } void gSPObjRendermode(u32 _mode) { gSP.objRendermode = _mode; } void (*gSPTransformVertex)(float vtx[4], float mtx[4][4]) = gSPTransformVertex_default; void (*gSPLightVertex)(SPVertex * _vtx) = gSPLightVertex_default; void (*gSPPointLightVertex)(SPVertex *_vtx, float * _vPos) = gSPPointLightVertex_default; void (*gSPBillboardVertex)(u32 v, u32 i) = gSPBillboardVertex_default; void gSPSetupFunctions(void) { if (GBI_GetCurrentMicrocodeType() != F3DEX2CBFD) { gSPLightVertex = gSPLightVertex_default; gSPPointLightVertex = gSPPointLightVertex_default; return; } gSPLightVertex = gSPLightVertex_CBFD; gSPPointLightVertex = gSPPointLightVertex_CBFD; } gles2rice/src/OGLES2FragmentShaders.cpp000664 001750 001750 00000073114 12655644434 021030 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "OGLDebug.h" #include "OGLES2FragmentShaders.h" #include "OGLRender.h" #include "OGLTexture.h" #define ALPHA_TEST " if(gl_FragColor.a < AlphaRef) discard; \n" //#define ALPHA_TEST #define ENABLE true #define DISABLE false GLuint vertexProgram = 9999; const char *vertexShader = "#version " GLSL_VERSION "\n" #if defined(__LIBRETRO__) && !defined(HAVE_OPENGLES2) "#define lowp \n" "#define mediump \n" #endif "attribute mediump vec4 aPosition; \n"\ "attribute lowp vec4 aColor; \n"\ "attribute lowp vec2 aTexCoord0; \n"\ "attribute lowp vec2 aTexCoord1; \n"\ "attribute lowp vec2 aAtlasTransform; \n"\ "attribute mediump float aFogCoord; \n"\ " \n"\ "uniform vec2 FogMinMax; \n"\ " \n"\ "varying lowp float vFactor; \n"\ "varying lowp vec4 vShadeColor; \n"\ "varying mediump vec2 vTexCoord0; \n"\ "varying lowp vec2 vTexCoord1; \n"\ "varying lowp float vFog; \n"\ " \n"\ "void main() \n"\ "{ \n"\ " gl_Position = aPosition; \n"\ " vShadeColor = aColor; \n"\ " vTexCoord0 = aTexCoord0; \n"\ " vTexCoord1 = aTexCoord1; \n"\ " vFog = (FogMinMax[1] - aFogCoord) / (FogMinMax[1] - FogMinMax[0]); \n"\ " vFog = clamp(vFog, 0.0, 1.0); \n"\ "} \n"\ " \n"; const char *fragmentHeader = "#define saturate(x) clamp( x, 0.0, 1.0 ) \n" #if defined(__LIBRETRO__) && !defined(HAVE_OPENGLES2) "#define lowp \n" "#define mediump \n" #else "precision lowp float; \n" #endif "#ifdef NEED_TEX0 \n"\ "uniform sampler2D uTex0; \n"\ "#endif \n"\ " \n"\ "#ifdef NEED_TEX1 \n"\ "uniform sampler2D uTex1; \n"\ "#endif \n"\ " \n"\ "uniform vec4 EnvColor; \n"\ "uniform vec4 PrimColor; \n"\ "uniform vec4 EnvFrac; \n"\ "uniform vec4 PrimFrac; \n"\ "uniform float AlphaRef; \n"\ "uniform vec4 FogColor; \n"\ " \n"\ "varying lowp vec4 vShadeColor; \n"\ "varying mediump vec2 vTexCoord0; \n"\ "varying lowp vec2 vTexCoord1; \n"\ "varying lowp float vFog; \n"\ " \n"\ "void main() \n"\ "{ \n"\ " vec4 comb,comb2; \n"\ " \n"\ "#ifdef NEED_TEX0 \n"\ " vec4 t0 = texture2D(uTex0,vTexCoord0); \n"\ "#endif \n"\ " \n"\ "#ifdef NEED_TEX1 \n"\ " vec4 t1 = texture2D(uTex1,vTexCoord1); \n"\ "#endif \n"; const char *fragmentFooter = " \n"\ "#ifdef FOG \n"\ " gl_FragColor.rgb = mix(FogColor.rgb, comb.rgb, vFog); \n"\ " gl_FragColor.a = comb.a; \n"\ "#else \n"\ " gl_FragColor = comb; \n"\ "#endif \n"\ " \n"\ "#ifdef ALPHA_TEST \n"\ ALPHA_TEST "#endif \n"\ "} \n"; //Fragment shader for InitCycleCopy const char *fragmentCopy = "#version " GLSL_VERSION "\n" #if defined(__LIBRETRO__) && !defined(HAVE_OPENGLES2) "#define lowp \n" "#define mediump \n" #else "precision lowp float; \n" #endif "uniform sampler2D uTex0; \n"\ "uniform float AlphaRef; \n"\ "varying lowp vec2 vTexCoord0; \n"\ "void main() \n"\ "{ \n"\ " gl_FragColor = texture2D(uTex0,vTexCoord0).bgra; \n"\ ALPHA_TEST "}"; GLuint copyProgram,copyAlphaLocation; //Fragment shader for InitCycleFill const char *fragmentFill = "#version " GLSL_VERSION "\n" #if defined(__LIBRETRO__) && !defined(HAVE_OPENGLES2) "#define lowp \n" "#define mediump \n" #else "precision lowp float; \n" #endif "uniform vec4 uColor; \n" "void main() \n" "{ \n" " gl_FragColor = uColor; \n" "}"; GLuint fillProgram,fillColorLocation; COGLFragmentShaderCombiner::COGLFragmentShaderCombiner(CRender *pRender) : COGLColorCombiner(pRender) { m_bShaderIsSupported = true; } COGLFragmentShaderCombiner::~COGLFragmentShaderCombiner() { } bool COGLFragmentShaderCombiner::Initialize(void) { if( !COGLColorCombiner::Initialize() ) return false; m_bShaderIsSupported = true; return true; } void COGLFragmentShaderCombiner::InitCombinerCycle12(void) { } void COGLFragmentShaderCombiner::DisableCombiner(void) { COGLColorCombiner::DisableCombiner(); } void COGLFragmentShaderCombiner::InitCombinerCycleCopy(void) { COGLColorCombiner::InitCombinerCycleCopy(); } void COGLFragmentShaderCombiner::InitCombinerCycleFill(void) { COGLColorCombiner::InitCombinerCycleFill(); } void COGLFragmentShaderCombiner::InitCombinerBlenderForSimpleTextureDraw(uint32_t tile) { COGLColorCombiner::InitCombinerBlenderForSimpleTextureDraw(tile); } #ifdef DEBUGGER void COGLFragmentShaderCombiner::DisplaySimpleMuxString(void) { COGLColorCombiner::DisplaySimpleMuxString(); } #endif COGL_FragmentProgramCombiner::COGL_FragmentProgramCombiner(CRender *pRender) : COGLColorCombiner4(pRender) { delete m_pDecodedMux; m_pDecodedMux = new DecodedMuxForPixelShader; m_bFragmentProgramIsSupported = true; m_AlphaRef = 0.0f; bAlphaTestState = false; bAlphaTestPreviousState = false; bFogState = false; bFogPreviousState = false; //Create shaders for fill and copy GLint success; GLuint vs,fs; copyProgram = glCreateProgram(); vs = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vs,1,&vertexShader,NULL); glCompileShader(vs); glGetShaderiv(vs,GL_COMPILE_STATUS,&success); if(!success) { char log[1024]; glGetShaderInfoLog(vs,1024,NULL,log); printf("%s\n",log); } fs = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fs,1,&fragmentCopy,NULL); glCompileShader(fs); glGetShaderiv(fs,GL_COMPILE_STATUS,&success); if(!success) { char log[1024]; glGetShaderInfoLog(fs,1024,NULL,log); printf("%s\n",log); } glAttachShader(copyProgram,vs); glAttachShader(copyProgram,fs); glBindAttribLocation(copyProgram,VS_TEXCOORD0,"aTexCoord0"); OPENGL_CHECK_ERRORS; glBindAttribLocation(copyProgram,VS_POSITION,"aPosition"); OPENGL_CHECK_ERRORS; glLinkProgram(copyProgram); copyAlphaLocation = glGetUniformLocation(copyProgram,"AlphaRef"); glGetProgramiv(copyProgram,GL_LINK_STATUS,&success); if(!success) { char log[1024]; glGetProgramInfoLog(copyProgram,1024,NULL,log); printf("%s\n",log); } glDeleteShader(fs); //Fill shader fs = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fs,1,&fragmentFill,NULL); glCompileShader(fs); glGetShaderiv(fs,GL_COMPILE_STATUS,&success); if(!success) { char log[1024]; glGetShaderInfoLog(fs,1024,NULL,log); printf("%s\n",log); } fillProgram = glCreateProgram(); glAttachShader(fillProgram,vs); glAttachShader(fillProgram,fs); glBindAttribLocation(fillProgram,VS_POSITION,"aPosition"); OPENGL_CHECK_ERRORS; glLinkProgram(fillProgram); fillColorLocation = glGetUniformLocation(fillProgram,"uColor"); glDeleteShader(fs); glDeleteShader(vs); } COGL_FragmentProgramCombiner::~COGL_FragmentProgramCombiner() { int size = m_vCompiledShaders.size(); for (int i=0; iDisableMultiTexture(); m_pOGLRender->EnableTexUnit(0, true); UseProgram(copyProgram); glUniform1f(copyAlphaLocation,m_AlphaRef); OPENGL_CHECK_ERRORS; glEnableVertexAttribArray(VS_POSITION); OPENGL_CHECK_ERRORS; glEnableVertexAttribArray(VS_TEXCOORD0); OPENGL_CHECK_ERRORS; glDisableVertexAttribArray(VS_COLOR); OPENGL_CHECK_ERRORS; glDisableVertexAttribArray(VS_TEXCOORD1); OPENGL_CHECK_ERRORS; glDisableVertexAttribArray(VS_FOG); OPENGL_CHECK_ERRORS; COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture; if( pTexture ) { m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0); m_pOGLRender->SetTexelRepeatFlags(gRSP.curTile); } } void COGL_FragmentProgramCombiner::InitCombinerCycleFill(void) { UseProgram(fillProgram); glUniform4f(fillColorLocation,((gRDP.fillColor>>16)&0xFF)/255.0f,((gRDP.fillColor>>8)&0xFF)/255.0f,((gRDP.fillColor)&0xFF)/255.0f,((gRDP.fillColor>>24)&0xFF)/255.0f); OPENGL_CHECK_ERRORS; } #ifdef BGR_SHADER const char *muxToFP_Maps[][2] = { //color -- alpha {"vec3(0.0)", "0.0"}, //MUX_0 = 0, {"vec3(1.0)", "1.0"}, //MUX_1, {"comb.rgb", "comb.a"}, //MUX_COMBINED, {"t0.rgb", "t0.a"}, //MUX_TEXEL0, {"t1.rgb", "t1.a"}, //MUX_TEXEL1, {"PrimColor.rgb", "PrimColor.a"}, //MUX_PRIM, {"vShadeColor.rgb", "vShadeColor.a"}, //MUX_SHADE, {"EnvColor.rgb", "EnvColor.a"}, //MUX_ENV, {"comb.rgb", "comb.a"}, //MUX_COMBALPHA, {"t0.rgb", "t0.a"}, //MUX_T0_ALPHA, {"t1.rgb", "t1.a"}, //MUX_T1_ALPHA, {"PrimColor.rgb", "PrimColor.a"}, //MUX_PRIM_ALPHA, {"vShadeColor.rgb", "vShadeColor.a"}, //MUX_SHADE_ALPHA, {"EnvColor.rgb", "EnvColor.a"}, //MUX_ENV_ALPHA, {"EnvFrac.a", "EnvFrac.a"}, //MUX_LODFRAC, {"PrimFrac.a", "PrimFrac.a"}, //MUX_PRIMLODFRAC, {"vec3(1.0)", "1.0"}, //MUX_K5, {"vec3(1.0)", "1.0"}, //MUX_UNK, // Should not be used }; #else const char *muxToFP_Maps[][2] = { //color -- alpha {"vec3(0.0)", "0.0"}, //MUX_0 = 0, {"vec3(1.0)", "1.0"}, //MUX_1, {"comb.rgb", "comb.a"}, //MUX_COMBINED, {"t0.bgr", "t0.a"}, //MUX_TEXEL0, {"t1.bgr", "t1.a"}, //MUX_TEXEL1, {"PrimColor.rgb", "PrimColor.a"}, //MUX_PRIM, {"vShadeColor.rgb", "vShadeColor.a"}, //MUX_SHADE, {"EnvColor.rgb", "EnvColor.a"}, //MUX_ENV, {"comb.rgb", "comb.a"}, //MUX_COMBALPHA, {"t0.bgr", "t0.a"}, //MUX_T0_ALPHA, {"t1.bgr", "t1.a"}, //MUX_T1_ALPHA, {"PrimColor.rgb", "PrimColor.a"}, //MUX_PRIM_ALPHA, {"vShadeColor.rgb", "vShadeColor.a"}, //MUX_SHADE_ALPHA, {"EnvColor.rgb", "EnvColor.a"}, //MUX_ENV_ALPHA, {"EnvFrac.a", "EnvFrac.a"}, //MUX_LODFRAC, {"PrimFrac.a", "PrimFrac.a"}, //MUX_PRIMLODFRAC, {"vec3(1.0)", "1.0"}, //MUX_K5, {"vec3(1.0)", "1.0"}, //MUX_UNK, // Should not be used }; #endif char oglNewFP[4092]; char* MuxToOC(uint8_t val) { // For color channel if( val&MUX_ALPHAREPLICATE ) return (char*)muxToFP_Maps[val&0x1F][1]; else return (char*)muxToFP_Maps[val&0x1F][0]; } char* MuxToOA(uint8_t val) { // For alpha channel return (char*)muxToFP_Maps[val&0x1F][1]; } static void CheckFpVars(uint8_t MuxVar, bool &bNeedT0, bool &bNeedT1) { MuxVar &= 0x1f; if (MuxVar == MUX_TEXEL0 || MuxVar == MUX_T0_ALPHA) bNeedT0 = true; if (MuxVar == MUX_TEXEL1 || MuxVar == MUX_T1_ALPHA) bNeedT1 = true; } void COGL_FragmentProgramCombiner::GenerateProgramStr() { DecodedMuxForPixelShader &mux = *(DecodedMuxForPixelShader*)m_pDecodedMux; mux.splitType[0] = mux.splitType[1] = mux.splitType[2] = mux.splitType[3] = CM_FMT_TYPE_NOT_CHECKED; m_pDecodedMux->Reformat(false); char tempstr[500], newFPBody[4092]; bool bNeedT0 = false, bNeedT1 = false, bNeedComb2 = false; newFPBody[0] = 0; for( int cycle=0; cycle<2; cycle++ ) { for( int channel=0; channel<2; channel++) { char* (*func)(uint8_t) = channel==0?MuxToOC:MuxToOA; char *dst = channel==0?(char*)"rgb":(char*)"a"; N64CombinerType &m = mux.m_n64Combiners[cycle*2+channel]; switch( mux.splitType[cycle*2+channel] ) { case CM_FMT_TYPE_NOT_USED: tempstr[0] = 0; break; case CM_FMT_TYPE_D: sprintf(tempstr, "comb.%s = %s;\n", dst, func(m.d)); CheckFpVars(m.d, bNeedT0, bNeedT1); break; case CM_FMT_TYPE_A_MOD_C: sprintf(tempstr, "comb.%s = %s * %s;\n", dst, func(m.a), func(m.c)); CheckFpVars(m.a, bNeedT0, bNeedT1); CheckFpVars(m.c, bNeedT0, bNeedT1); break; case CM_FMT_TYPE_A_ADD_D: sprintf(tempstr, "comb.%s = saturate(%s + %s);\n", dst, func(m.a), func(m.d)); CheckFpVars(m.a, bNeedT0, bNeedT1); CheckFpVars(m.d, bNeedT0, bNeedT1); break; case CM_FMT_TYPE_A_SUB_B: sprintf(tempstr, "comb.%s = %s - %s;\n", dst, func(m.a), func(m.b)); CheckFpVars(m.a, bNeedT0, bNeedT1); CheckFpVars(m.b, bNeedT0, bNeedT1); break; case CM_FMT_TYPE_A_MOD_C_ADD_D: sprintf(tempstr, "comb.%s = saturate(%s * %s + %s);\n", dst, func(m.a), func(m.c),func(m.d)); CheckFpVars(m.a, bNeedT0, bNeedT1); CheckFpVars(m.c, bNeedT0, bNeedT1); CheckFpVars(m.d, bNeedT0, bNeedT1); break; case CM_FMT_TYPE_A_LERP_B_C: //ARB ASM LERP and mix have different parameter ordering. //sprintf(tempstr, "comb.%s = saturate(mix(%s, %s, %s));\n", dst,func(m.a),func(m.b), func(m.c)); sprintf(tempstr, "comb.%s = (%s - %s) * %s + %s;\n", dst,func(m.a),func(m.b), func(m.c),func(m.b)); CheckFpVars(m.a, bNeedT0, bNeedT1); CheckFpVars(m.b, bNeedT0, bNeedT1); CheckFpVars(m.c, bNeedT0, bNeedT1); //sprintf(tempstr, "SUB comb.%s, %s, %s;\nMAD_SAT comb.%s, comb, %s, %s;\n", dst, func(m.a), func(m.b), dst, func(m.c), func(m.b)); break; default: sprintf(tempstr, "comb2.%s = %s - %s;\ncomb.%s = saturate(comb2.%s * %s + %s);\n", dst, func(m.a), func(m.b), dst,dst, func(m.c),func(m.d)); CheckFpVars(m.a, bNeedT0, bNeedT1); CheckFpVars(m.b, bNeedT0, bNeedT1); CheckFpVars(m.c, bNeedT0, bNeedT1); CheckFpVars(m.d, bNeedT0, bNeedT1); bNeedComb2 = true; break; } strcat(newFPBody, tempstr); } } oglNewFP[0] = 0; if (bNeedT0) strcat(oglNewFP, "#define NEED_TEX0\n"); if (bNeedT1) strcat(oglNewFP, "#define NEED_TEX1\n"); strcat(oglNewFP, fragmentHeader); strcat(oglNewFP, newFPBody); strcat(oglNewFP, fragmentFooter); } int COGL_FragmentProgramCombiner::ParseDecodedMux() { OGLShaderCombinerSaveType res; GLint success; if(vertexProgram == 9999) { vertexProgram = res.vertexShaderID = glCreateShader(GL_VERTEX_SHADER); glShaderSource(res.vertexShaderID, 1, &vertexShader,NULL); OPENGL_CHECK_ERRORS; glCompileShader(res.vertexShaderID); OPENGL_CHECK_ERRORS; } else { res.vertexShaderID = vertexProgram; } //Create 4 shaders, with and without alphatest + with and without fog GenerateProgramStr(); for(int alphaTest = 0;alphaTest < 2;alphaTest++) { for(int fog = 0; fog < 2; fog++) { res.fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); char* tmpShader = (char*)malloc(sizeof(char) * 4096); strcpy(tmpShader,"#version " GLSL_VERSION "\n"); if(alphaTest == 1) strcat(tmpShader,"#define ALPHA_TEST\n"); if(fog == 1) strcat(tmpShader,"#define FOG\n"); res.fogIsUsed = fog == 1; res.alphaTest = alphaTest == 1; strcat(tmpShader,oglNewFP); glShaderSource(res.fragmentShaderID, 1,(const char**) &tmpShader,NULL); free(tmpShader); OPENGL_CHECK_ERRORS; glCompileShader(res.fragmentShaderID); glGetShaderiv(res.fragmentShaderID, GL_COMPILE_STATUS, &success); if (!success) { char Log[1024]; GLint nLength; glGetShaderInfoLog(res.fragmentShaderID, 1024, &nLength, Log); printf("Error compiling shader!\n %s",oglNewFP); printf("%s", Log); } res.programID = glCreateProgram(); glAttachShader(res.programID,res.vertexShaderID); glAttachShader(res.programID,res.fragmentShaderID); //Bind Attributes glBindAttribLocation(res.programID,VS_COLOR,"aColor"); OPENGL_CHECK_ERRORS; glBindAttribLocation(res.programID,VS_TEXCOORD0,"aTexCoord0"); OPENGL_CHECK_ERRORS; glBindAttribLocation(res.programID,VS_TEXCOORD1,"aTexCoord1"); OPENGL_CHECK_ERRORS; glBindAttribLocation(res.programID,VS_POSITION,"aPosition"); OPENGL_CHECK_ERRORS; glBindAttribLocation(res.programID,VS_FOG,"aFogCoord"); OPENGL_CHECK_ERRORS; glLinkProgram(res.programID); OPENGL_CHECK_ERRORS; glGetProgramiv(res.programID, GL_LINK_STATUS, &success); if (!success) { char Log[1024]; GLint nLength; glGetShaderInfoLog(res.fragmentShaderID, 1024, &nLength, Log); printf("Error linking program!\n"); printf("%s\n",Log); } UseProgram(res.programID); OPENGL_CHECK_ERRORS; //Bind texture samplers GLint tex0 = glGetUniformLocation(res.programID,"uTex0"); GLint tex1 = glGetUniformLocation(res.programID,"uTex1"); if(tex0 != -1) glUniform1i(tex0,0); if(tex1 != -1) glUniform1i(tex1,1); //Bind Uniforms res.PrimColorLocation = glGetUniformLocation(res.programID,"PrimColor"); OPENGL_CHECK_ERRORS; res.EnvColorLocation = glGetUniformLocation(res.programID,"EnvColor"); OPENGL_CHECK_ERRORS; res.PrimFracLocation = glGetUniformLocation(res.programID,"PrimFrac"); OPENGL_CHECK_ERRORS; res.EnvFracLocation = glGetUniformLocation(res.programID,"EnvFrac"); OPENGL_CHECK_ERRORS; res.AlphaRefLocation = glGetUniformLocation(res.programID,"AlphaRef"); OPENGL_CHECK_ERRORS; res.FogColorLocation = glGetUniformLocation(res.programID,"FogColor"); OPENGL_CHECK_ERRORS; res.FogMinMaxLocation = glGetUniformLocation(res.programID,"FogMinMax"); OPENGL_CHECK_ERRORS; res.dwMux0 = m_pDecodedMux->m_dwMux0; res.dwMux1 = m_pDecodedMux->m_dwMux1; m_vCompiledShaders.push_back(res); } } m_lastIndex = m_vCompiledShaders.size()-4; return m_lastIndex; } void COGL_FragmentProgramCombiner::GenerateCombinerSetting(int index) { GLuint ID = m_vCompiledShaders[index].programID; UseProgram(ID); glEnableVertexAttribArray(VS_POSITION); OPENGL_CHECK_ERRORS; glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0])); OPENGL_CHECK_ERRORS; glEnableVertexAttribArray(VS_TEXCOORD0); OPENGL_CHECK_ERRORS; glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u)); OPENGL_CHECK_ERRORS; glEnableVertexAttribArray(VS_TEXCOORD1); OPENGL_CHECK_ERRORS; glVertexAttribPointer(VS_TEXCOORD1,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[1].u)); OPENGL_CHECK_ERRORS; glEnableVertexAttribArray(VS_COLOR); OPENGL_CHECK_ERRORS; glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8_t)*4, &(g_oglVtxColors[0][0]) ); OPENGL_CHECK_ERRORS; glEnableVertexAttribArray(VS_FOG); OPENGL_CHECK_ERRORS; glVertexAttribPointer(VS_FOG, 1, GL_FLOAT,GL_FALSE, sizeof(float)*5, &(g_vtxProjected5[0][4]) ); OPENGL_CHECK_ERRORS; } void COGL_FragmentProgramCombiner::GenerateCombinerSettingConstants(int index) { OGLShaderCombinerSaveType &prog = m_vCompiledShaders[index]; UseProgram(prog.programID); float *pf; if(prog.EnvColorLocation != -1) { pf = GetEnvColorfv(); if (memcmp(pf, prog.EnvColors, sizeof(prog.EnvColors))) { memcpy(prog.EnvColors, pf, sizeof(prog.EnvColors)); glUniform4fv(prog.EnvColorLocation, 1, pf); OPENGL_CHECK_ERRORS; } } if(prog.PrimColorLocation != -1) { pf = GetPrimitiveColorfv(); if (memcmp(pf, prog.PrimColors, sizeof(prog.PrimColors))) { memcpy(prog.PrimColors, pf, sizeof(prog.PrimColors)); glUniform4fv(prog.PrimColorLocation, 1, pf); OPENGL_CHECK_ERRORS; } } if(prog.EnvFracLocation != -1) { // avoid slow float compare.. if( *(int *)&gRDP.LODFrac != *(int *)&prog.EnvLODFrac ) { float frac = gRDP.LODFrac / 255.0f; float tempf[4] = {frac,frac,frac,frac}; prog.EnvLODFrac = (float)gRDP.LODFrac; glUniform4fv(prog.EnvFracLocation, 1, tempf); OPENGL_CHECK_ERRORS; } } if(prog.PrimFracLocation != -1) { if( *(int *)&gRDP.primLODFrac != *(int *)&prog.PrimLODFrac ) { float frac2 = gRDP.primLODFrac / 255.0f; float tempf2[4] = {frac2,frac2,frac2,frac2}; prog.PrimLODFrac = (float)gRDP.primLODFrac; glUniform4fv(prog.PrimFracLocation, 1, tempf2); OPENGL_CHECK_ERRORS; } } if(prog.FogColorLocation != -1) { pf = &gRDP.fvFogColor[0]; if (memcmp(pf, prog.FogColors, sizeof(prog.FogColors))) { memcpy(prog.FogColors, pf, sizeof(prog.FogColors)); glUniform4fv(prog.FogColorLocation, 1, pf); OPENGL_CHECK_ERRORS; } } if(prog.FogMinMaxLocation != -1) { if( gRSPfFogMin != prog.FogMin || gRSPfFogMax != prog.FogMax ) { prog.FogMin = gRSPfFogMin; prog.FogMax = gRSPfFogMax; glUniform2f(prog.FogMinMaxLocation,gRSPfFogMin,gRSPfFogMax); OPENGL_CHECK_ERRORS; } } if(prog.AlphaRefLocation != -1) { if( m_AlphaRef != prog.AlphaRef ) { prog.AlphaRef = m_AlphaRef; glUniform1f(prog.AlphaRefLocation, m_AlphaRef); OPENGL_CHECK_ERRORS; } } } int COGL_FragmentProgramCombiner::FindCompiledMux() { #ifdef DEBUGGER if( debuggerDropCombiners ) { m_vCompiledShaders.clear(); //m_dwLastMux0 = m_dwLastMux1 = 0; debuggerDropCombiners = false; } #endif for( uint32_t i=0; im_dwMux0 && m_vCompiledShaders[i].dwMux1 == m_pDecodedMux->m_dwMux1 && m_vCompiledShaders[i].fogIsUsed == bFogState && m_vCompiledShaders[i].alphaTest == bAlphaTestState) { return (int)i; } } return -1; } ////////////////////////////////////////////////////////////////////////// void COGL_FragmentProgramCombiner::InitCombinerCycle12(void) { #ifdef DEBUGGER if( debuggerDropCombiners ) { UpdateCombiner(m_pDecodedMux->m_dwMux0,m_pDecodedMux->m_dwMux1); m_vCompiledShaders.clear(); m_dwLastMux0 = m_dwLastMux1 = 0; debuggerDropCombiners = false; } #endif m_pOGLRender->EnableMultiTexture(); bool combinerIsChanged = false; if( m_pDecodedMux->m_dwMux0 != m_dwLastMux0 || m_pDecodedMux->m_dwMux1 != m_dwLastMux1 || bAlphaTestState != bAlphaTestPreviousState || bFogState != bFogPreviousState || m_lastIndex < 0 ) { combinerIsChanged = true; m_lastIndex = FindCompiledMux(); if( m_lastIndex < 0 ) // Can not found { m_lastIndex = ParseDecodedMux(); } m_dwLastMux0 = m_pDecodedMux->m_dwMux0; m_dwLastMux1 = m_pDecodedMux->m_dwMux1; bAlphaTestPreviousState = bAlphaTestState; bFogPreviousState = bFogState; m_AlphaRef = (float)(m_pOGLRender->m_dwAlpha) / 255.0f; } GenerateCombinerSettingConstants(m_lastIndex); if( m_bCycleChanged || combinerIsChanged || gRDP.texturesAreReloaded || gRDP.colorsAreReloaded ) { if( m_bCycleChanged || combinerIsChanged ) { GenerateCombinerSettingConstants(m_lastIndex); GenerateCombinerSetting(m_lastIndex); } else if( gRDP.colorsAreReloaded ) { GenerateCombinerSettingConstants(m_lastIndex); } m_pOGLRender->SetAllTexelRepeatFlag(); gRDP.colorsAreReloaded = false; gRDP.texturesAreReloaded = false; } else { m_pOGLRender->SetAllTexelRepeatFlag(); } } #ifdef DEBUGGER void COGL_FragmentProgramCombiner::DisplaySimpleMuxString(void) { COGLColorCombiner::DisplaySimpleMuxString(); DecodedMuxForPixelShader &mux = *(DecodedMuxForPixelShader*)m_pDecodedMux; mux.Reformat(false); GenerateProgramStr(); //sprintf(oglNewFP, oglFP, // MuxToOC(mux.aRGB0), MuxToOC(mux.bRGB0), MuxToOC(mux.cRGB0), MuxToOC(mux.dRGB0), // MuxToOA(mux.aA0), MuxToOA(mux.bA0), MuxToOA(mux.cA0), MuxToOA(mux.dA0), // MuxToOC(mux.aRGB1), MuxToOC(mux.bRGB1), MuxToOC(mux.cRGB1), MuxToOC(mux.dRGB1), // MuxToOA(mux.aA1), MuxToOA(mux.bA1), MuxToOA(mux.cA1), MuxToOA(mux.dA1) // ); TRACE0("OGL Fragment Program:"); TRACE0(oglNewFP); } #endif gles2n64/src/VI.c000664 001750 001750 00000011174 12655644434 014540 0ustar00sergiosergio000000 000000 #include #include "Common.h" #include "gles2N64.h" #include "Types.h" #include "VI.h" #include "OpenGL.h" #include "N64.h" #include "gSP.h" #include "gDP.h" #include "RSP.h" #include "Debug.h" #include "Config.h" #include "FrameBuffer.h" VIInfo VI; void VI_UpdateSize(void) { struct FrameBuffer *pBuffer, *pDepthBuffer; const bool interlacedPrev = VI.interlaced; f32 xScale = _FIXED2FLOAT( _SHIFTR( *gfx_info.VI_X_SCALE_REG, 0, 12 ), 10 ); u32 vScale = _SHIFTR(*gfx_info.VI_Y_SCALE_REG, 0, 12); u32 hEnd = _SHIFTR( *gfx_info.VI_H_START_REG, 0, 10 ); u32 hStart = _SHIFTR( *gfx_info.VI_H_START_REG, 16, 10 ); // These are in half-lines, so shift an extra bit u32 vEnd = _SHIFTR( *gfx_info.VI_V_START_REG, 0, 10 ); u32 vStart = _SHIFTR( *gfx_info.VI_V_START_REG, 16, 10 ); if (VI.width > 0) VI.widthPrev = VI.width; VI.real_height = vEnd > vStart ? (((vEnd - vStart) >> 1) * vScale) >> 10 : 0; VI.width = *gfx_info.VI_WIDTH_REG; VI.interlaced = (*gfx_info.VI_STATUS_REG & 0x40) != 0; if (VI.interlaced) { f32 fullWidth = 640.0f * xScale; if (*gfx_info.VI_WIDTH_REG > fullWidth) { const u32 scale = (u32)floorf(*gfx_info.VI_WIDTH_REG / fullWidth + 0.5f); VI.width /= scale; VI.real_height *= scale; } if (VI.real_height % 2 == 1) --VI.real_height; } VI.PAL = (*gfx_info.VI_V_SYNC_REG & 0x3ff) > 550; if (VI.PAL && (vEnd - vStart) > 478) { VI.height = (u32)(VI.real_height*1.0041841f); if (VI.height > 576) VI.height = VI.real_height = 576; } else { VI.height = (u32)(VI.real_height*1.0126582f); if (VI.height > 480) VI.height = VI.real_height = 480; } if (VI.height % 2 == 1) --VI.height; pBuffer = FrameBuffer_FindBuffer(VI.lastOrigin); pDepthBuffer = (pBuffer != NULL) ? NULL /* pBuffer->DepthBuffer */: NULL; if (config.frameBufferEmulation.enable && ((interlacedPrev != VI.interlaced) || (VI.width > 0 && VI.width != VI.widthPrev) || (!VI.interlaced && pDepthBuffer != NULL && pDepthBuffer->m_width != VI.width) || (pBuffer != NULL && pBuffer->m_height != VI.height)) ) { FrameBuffer_RemoveBuffer(VI.widthPrev); FrameBuffer_RemoveBuffer(VI.width); #ifdef NEW depthBufferList().destroy(); depthBufferList().init(); #endif } VI.rwidth = VI.width != 0 ? 1.0f / VI.width : 0.0f; VI.rheight = VI.height != 0 ? 1.0f / VI.height : 0.0f; } void VI_UpdateScreen(void) { static u32 uNumCurFrameIsShown = 0; bool bVIUpdated = false; if (*gfx_info.VI_ORIGIN_REG != VI.lastOrigin) { VI_UpdateSize(); bVIUpdated = true; OGL_UpdateScale(); } if (config.frameBufferEmulation.enable) { const bool bCFB = config.frameBufferEmulation.detectCFB != 0 && (gSP.changed&CHANGED_CPU_FB_WRITE) == CHANGED_CPU_FB_WRITE; const bool bNeedUpdate = gDP.colorImage.changed != 0 || (bCFB ? true : (*gfx_info.VI_ORIGIN_REG != VI.lastOrigin)); if (bNeedUpdate) { if ((gSP.changed&CHANGED_CPU_FB_WRITE) == CHANGED_CPU_FB_WRITE) { struct FrameBuffer * pBuffer = FrameBuffer_FindBuffer(*gfx_info.VI_ORIGIN_REG); if (pBuffer == NULL || pBuffer->m_width != VI.width) { u32 size; if (!bVIUpdated) { VI_UpdateSize(); OGL_UpdateScale(); bVIUpdated = true; } size = *gfx_info.VI_STATUS_REG & 3; if (VI.height > 0 && size > G_IM_SIZ_8b && VI.width > 0) FrameBuffer_SaveBuffer(*gfx_info.VI_ORIGIN_REG, G_IM_FMT_RGBA, size, VI.width, VI.height, true); } } if ((((*gfx_info.VI_STATUS_REG) & 3) > 0) && ((config.frameBufferEmulation.copyFromRDRAM && gDP.colorImage.changed) || bCFB)) { if (!bVIUpdated) { VI_UpdateSize(); bVIUpdated = true; } FrameBuffer_CopyFromRDRAM(*gfx_info.VI_ORIGIN_REG, config.frameBufferEmulation.copyFromRDRAM && !bCFB); } FrameBuffer_RenderBuffer(*gfx_info.VI_ORIGIN_REG); if (gDP.colorImage.changed) uNumCurFrameIsShown = 0; else { uNumCurFrameIsShown++; if (uNumCurFrameIsShown > 25) gSP.changed |= CHANGED_CPU_FB_WRITE; } #if 0 /* TODO/FIXME - implement */ frameBufferList().clearBuffersChanged(); #endif VI.lastOrigin = *gfx_info.VI_ORIGIN_REG; #ifdef DEBUG while (Debug.paused && !Debug.step); Debug.step = FALSE; #endif } else { uNumCurFrameIsShown++; if (uNumCurFrameIsShown > 25) gSP.changed |= CHANGED_CPU_FB_WRITE; } } else { if (gSP.changed & CHANGED_COLORBUFFER) { OGL_SwapBuffers(); gSP.changed &= ~CHANGED_COLORBUFFER; VI.lastOrigin = *gfx_info.VI_ORIGIN_REG; } } } libretro-common/glsym/glsym_es2.c000664 001750 001750 00000010153 12655644434 020232 0ustar00sergiosergio000000 000000 /* Copyright (C) 2010-2015 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this libretro SDK code part (glsym). * --------------------------------------------------------------------------------------- * * Permission is hereby granted, free of charge, * to any person obtaining a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include #define SYM(x) { "gl" #x, &(gl##x) } const struct rglgen_sym_map rglgen_symbol_map[] = { SYM(DebugMessageControlKHR), SYM(DebugMessageInsertKHR), SYM(DebugMessageCallbackKHR), SYM(GetDebugMessageLogKHR), SYM(PushDebugGroupKHR), SYM(PopDebugGroupKHR), SYM(ObjectLabelKHR), SYM(GetObjectLabelKHR), SYM(ObjectPtrLabelKHR), SYM(GetObjectPtrLabelKHR), SYM(GetPointervKHR), SYM(EGLImageTargetTexture2DOES), SYM(EGLImageTargetRenderbufferStorageOES), SYM(GetProgramBinaryOES), SYM(ProgramBinaryOES), SYM(MapBufferOES), SYM(UnmapBufferOES), SYM(GetBufferPointervOES), SYM(TexImage3DOES), SYM(TexSubImage3DOES), SYM(CopyTexSubImage3DOES), SYM(CompressedTexImage3DOES), SYM(CompressedTexSubImage3DOES), SYM(FramebufferTexture3DOES), SYM(BindVertexArrayOES), SYM(DeleteVertexArraysOES), SYM(GenVertexArraysOES), SYM(IsVertexArrayOES), { NULL, NULL }, }; RGLSYMGLDEBUGMESSAGECONTROLKHRPROC __rglgen_glDebugMessageControlKHR; RGLSYMGLDEBUGMESSAGEINSERTKHRPROC __rglgen_glDebugMessageInsertKHR; RGLSYMGLDEBUGMESSAGECALLBACKKHRPROC __rglgen_glDebugMessageCallbackKHR; RGLSYMGLGETDEBUGMESSAGELOGKHRPROC __rglgen_glGetDebugMessageLogKHR; RGLSYMGLPUSHDEBUGGROUPKHRPROC __rglgen_glPushDebugGroupKHR; RGLSYMGLPOPDEBUGGROUPKHRPROC __rglgen_glPopDebugGroupKHR; RGLSYMGLOBJECTLABELKHRPROC __rglgen_glObjectLabelKHR; RGLSYMGLGETOBJECTLABELKHRPROC __rglgen_glGetObjectLabelKHR; RGLSYMGLOBJECTPTRLABELKHRPROC __rglgen_glObjectPtrLabelKHR; RGLSYMGLGETOBJECTPTRLABELKHRPROC __rglgen_glGetObjectPtrLabelKHR; RGLSYMGLGETPOINTERVKHRPROC __rglgen_glGetPointervKHR; RGLSYMGLEGLIMAGETARGETTEXTURE2DOESPROC __rglgen_glEGLImageTargetTexture2DOES; RGLSYMGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC __rglgen_glEGLImageTargetRenderbufferStorageOES; RGLSYMGLGETPROGRAMBINARYOESPROC __rglgen_glGetProgramBinaryOES; RGLSYMGLPROGRAMBINARYOESPROC __rglgen_glProgramBinaryOES; RGLSYMGLMAPBUFFEROESPROC __rglgen_glMapBufferOES; RGLSYMGLUNMAPBUFFEROESPROC __rglgen_glUnmapBufferOES; RGLSYMGLGETBUFFERPOINTERVOESPROC __rglgen_glGetBufferPointervOES; RGLSYMGLTEXIMAGE3DOESPROC __rglgen_glTexImage3DOES; RGLSYMGLTEXSUBIMAGE3DOESPROC __rglgen_glTexSubImage3DOES; RGLSYMGLCOPYTEXSUBIMAGE3DOESPROC __rglgen_glCopyTexSubImage3DOES; RGLSYMGLCOMPRESSEDTEXIMAGE3DOESPROC __rglgen_glCompressedTexImage3DOES; RGLSYMGLCOMPRESSEDTEXSUBIMAGE3DOESPROC __rglgen_glCompressedTexSubImage3DOES; RGLSYMGLFRAMEBUFFERTEXTURE3DOESPROC __rglgen_glFramebufferTexture3DOES; RGLSYMGLBINDVERTEXARRAYOESPROC __rglgen_glBindVertexArrayOES; RGLSYMGLDELETEVERTEXARRAYSOESPROC __rglgen_glDeleteVertexArraysOES; RGLSYMGLGENVERTEXARRAYSOESPROC __rglgen_glGenVertexArraysOES; RGLSYMGLISVERTEXARRAYOESPROC __rglgen_glIsVertexArrayOES; gles2rice/src/FrameBuffer.cpp000664 001750 001750 00000205416 12655644434 017265 0ustar00sergiosergio000000 000000 /* Copyright (C) 2005 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // =========================================================================== #include #include "ConvertImage.h" #include "DeviceBuilder.h" #include "FrameBuffer.h" #include "UcodeDefs.h" #include "RSP_Parser.h" #include "Render.h" #ifndef min #define min(a,b) ((a) < (b) ? (a) : (b)) #endif extern TMEMLoadMapInfo g_tmemLoadAddrMap[0x200]; // Totally 4KB TMEM; // 0 keeps the most recent CI info // 1 keeps the frame buffer CI info which is being displayed now // 2 keeps the older frame buffer CI info. This can be used if we are using triple buffer /* Overview of framebuffer implementation 1) Check if backbuffer has changed, via different detection techniques 2) If changed, we copy the GFX card's backbuffer to main RAM 3) This is slow due to the reading process, not the writing */ RecentCIInfo g_RecentCIInfo[5]; RecentCIInfo *g_uRecentCIInfoPtrs[5] = { &g_RecentCIInfo[0], &g_RecentCIInfo[1], &g_RecentCIInfo[2], &g_RecentCIInfo[3], &g_RecentCIInfo[4], }; int numOfRecentCIInfos = 5; RecentViOriginInfo g_RecentVIOriginInfo[5]; uint32_t dwBackBufferSavedAtFrame=0; RenderTextureInfo gRenderTextureInfos[20]; int numOfTxtBufInfos = sizeof(gRenderTextureInfos)/sizeof(RenderTextureInfo); RenderTextureInfo *g_pRenderTextureInfo = NULL; FrameBufferManager* g_pFrameBufferManager = NULL; bool LastCIIsNewCI=false; FrameBufferManager::FrameBufferManager() : m_isRenderingToTexture(false), m_curRenderTextureIndex(-1), m_lastTextureBufferIndex(-1) { } FrameBufferManager::~FrameBufferManager() { } void FrameBufferManager::CloseUp() { for (int i=0; i=0x20?1:0; return ((r>>3)<>3)<>3)<>7); } uint16_t ConvertRGBATo555(uint32_t color32) { return (uint16_t)((((color32>>19)&0x1F)<>11)&0x1F)<>3)&0x1F)<>31)));; } void FrameBufferManager::UpdateRecentCIAddr(SetImgInfo &ciinfo) { if (ciinfo.dwAddr == g_uRecentCIInfoPtrs[0]->dwAddr) return; RecentCIInfo *temp; int i; for( i=1; idwAddr) { temp = g_uRecentCIInfoPtrs[i]; for (int j=i; j>0; j--) { g_uRecentCIInfoPtrs[j] = g_uRecentCIInfoPtrs[j-1]; } break; } } if (i >= numOfRecentCIInfos) { temp = g_uRecentCIInfoPtrs[4]; g_uRecentCIInfoPtrs[4] = g_uRecentCIInfoPtrs[3]; g_uRecentCIInfoPtrs[3] = g_uRecentCIInfoPtrs[2]; g_uRecentCIInfoPtrs[2] = g_uRecentCIInfoPtrs[1]; g_uRecentCIInfoPtrs[1] = g_uRecentCIInfoPtrs[0]; temp->dwCopiedAtFrame = 0; temp->bCopied = false; } g_uRecentCIInfoPtrs[0] = temp; // Fix me here for Mario Tennis temp->dwLastWidth = windowSetting.uViWidth; temp->dwLastHeight = windowSetting.uViHeight; temp->dwFormat = ciinfo.dwFormat; temp->dwAddr = ciinfo.dwAddr; temp->dwSize = ciinfo.dwSize; temp->dwWidth = ciinfo.dwWidth; temp->dwHeight = gRDP.scissor.bottom; temp->dwMemSize = (temp->dwWidth*temp->dwHeight/2)<dwSize; temp->bCopied = false; temp->lastUsedFrame = status.gDlistCount; temp->lastSetAtUcode = status.gUcodeCount; } /************************************************************************/ /* Mark the ciinfo entry that the ciinfo is used by VI origin register */ /* in another word, this is a real frame buffer, not a fake frame buffer*/ /* Fake frame buffers are never really used by VI origin */ /************************************************************************/ void FrameBufferManager::SetAddrBeDisplayed(uint32_t addr) { uint32_t viwidth = *gfx_info.VI_WIDTH_REG; addr &= (g_dwRamSize-1); for (int i=0; idwAddr+2*viwidth == addr) { g_uRecentCIInfoPtrs[i]->bUsedByVIAtFrame = status.gDlistCount; } else if (addr >= g_uRecentCIInfoPtrs[i]->dwAddr && addr < g_uRecentCIInfoPtrs[i]->dwAddr+0x1000) { g_uRecentCIInfoPtrs[i]->bUsedByVIAtFrame = status.gDlistCount; } } for (int i=0; idwAddr == 0) continue; if (g_uRecentCIInfoPtrs[i]->dwAddr == addr) { if (status.gDlistCount-g_uRecentCIInfoPtrs[i]->bUsedByVIAtFrame < 20) //if (g_uRecentCIInfoPtrs[i]->bUsedByVIAtFrame != 0) { return true; } else { TXTRBUF_DUMP(TRACE0("This is a new buffer address, the address is never a displayed buffer");); return false; } } } for (int i=0; i addr && (g_RecentVIOriginInfo[i].addr - addr)%width == 0 && (g_RecentVIOriginInfo[i].addr - addr)/width <= 4) { if (status.gDlistCount-g_RecentVIOriginInfo[i].FrameCount < 20) //if (g_RecentVIOriginInfo[i].FrameCount != 0) { return true; } else { TXTRBUF_DUMP(DebuggerAppendMsg("This is a new buffer address, the address is never a displayed buffer");); return false; } } } } if (status.gDlistCount > 20) { return false; } else { TXTRBUF_DUMP({DebuggerAppendMsg("This is a new buffer address, the address is never a displayed buffer");}); return true; } } int FrameBufferManager::FindRecentCIInfoIndex(uint32_t addr) { for (int i=0; idwAddr <= addr && addr < g_uRecentCIInfoPtrs[i]->dwAddr+g_uRecentCIInfoPtrs[i]->dwMemSize) { return i; } } return -1; } bool FrameBufferManager::IsDIaRenderTexture() { bool foundSetScissor=false; bool foundFillRect=false; bool foundSetFillColor=false; bool foundSetCImg=false; uint32_t newFillColor = 0; uint32_t dwPC = gDlistStack[gDlistStackPointer].pc; // This points to the next instruction for (int i=0; i<10; i++) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; uint32_t w0 = *(uint32_t *)(rdram_u8 + dwPC + i*8); uint32_t w1 = *(uint32_t *)(rdram_u8 + dwPC + 4 + i*8); if ((w0>>24) == RDP_SETSCISSOR) { foundSetScissor = true; continue; } if ((w0>>24) == RDP_SETFILLCOLOR) { foundSetFillColor = true; newFillColor = w1; continue; } if ((w0>>24) == RDP_FILLRECT) { uint32_t x0 = ((w1>>12)&0xFFF)/4; uint32_t y0 = ((w1>>0 )&0xFFF)/4; uint32_t x1 = ((w0>>12)&0xFFF)/4; if (x0 == 0 && y0 == 0) { if (x1 == g_CI.dwWidth) { foundFillRect = true; continue; } if (x1 == (unsigned int)(g_CI.dwWidth-1)) { foundFillRect = true; continue; } } } if ((w0>>24) == RDP_TEXRECT) { break; } if ((w0>>24) == RDP_SETCIMG) { foundSetCImg = true; break; } } /* bool foundSetScissor=false; bool foundFillRect=false; bool foundSetFillColor=false; bool foundSetCImg=false; bool foundTxtRect=false; int ucodeLength=10; uint32_t newFillColor; */ if (foundFillRect) { if (foundSetFillColor) { if (newFillColor != 0xFFFCFFFC) return true; // this is a render_texture else return false; } if (gRDP.fillColor != 0x00FFFFF7) return true; // this is a render_texture else return false; // this is a normal ZImg } else if (foundSetFillColor && newFillColor == 0xFFFCFFFC && foundSetCImg) { return false; } else { return true; } if (!foundSetCImg) return true; if (foundSetScissor) return true; } int FrameBufferManager::CheckAddrInBackBuffers(uint32_t addr, uint32_t memsize, bool copyToRDRAM) { int r = FindRecentCIInfoIndex(addr); if (r >= 0) { // Also check if the address is overwritten by a recent render_texture //int t = CheckAddrInRenderTextures(addr, false); int t = -1; for (int i=0; i=gRenderTextureInfos[i].CI_Info.dwAddr && addr < gRenderTextureInfos[i].CI_Info.dwAddr+bufMemSize) { if (g_uRecentCIInfoPtrs[r]->lastSetAtUcode < gRenderTextureInfos[i].updateAtUcodeCount) { t = i; break; } } } if (t >= 0) return -1; } if (r >= 0 && status.gDlistCount - g_uRecentCIInfoPtrs[r]->lastUsedFrame <= 3 && g_uRecentCIInfoPtrs[r]->bCopied == false) { DEBUGGER_IF_DUMP((logTextureBuffer&&r==1),TRACE2("Hit current front buffer at %08X, size=0x%X", addr, memsize)); DEBUGGER_IF_DUMP((logTextureBuffer&&r==0),TRACE2("Hit current back buffer at %08X, size=0x%X", addr, memsize)); DEBUGGER_IF_DUMP((logTextureBuffer&&r>1),TRACE2("Hit old back buffer at %08X, size=0x%X", addr, memsize)); SaveBackBuffer(r, NULL, true); } return r; } uint8_t CIFindIndex(uint16_t val) { for (int i=0; i<=0xFF; i++) { if (val == g_wRDPTlut[i]) { return (uint8_t)i; } } return 0; } void TexRectToFrameBuffer_8b(uint32_t dwXL, uint32_t dwYL, uint32_t dwXH, uint32_t dwYH, float t0u0, float t0v0, float t0u1, float t0v1, uint32_t dwTile) { // Copy the framebuffer texture into the N64 framebuffer memory // Used in Yoshi /* uint32_t maxW = g_pRenderTextureInfo->CI_Info.dwWidth; uint32_t maxH = maxW*3/4; if( status.dwTvSystem == TV_SYSTEM_PAL ) { maxH = maxW*9/11; } */ uint32_t maxW = g_pRenderTextureInfo->N64Width; uint32_t maxH = g_pRenderTextureInfo->N64Height; uint32_t maxOff = maxW*maxH; TMEMLoadMapInfo &info = g_tmemLoadAddrMap[gRDP.tiles[dwTile].dwTMem]; uint32_t dwWidth = dwXH-dwXL; uint32_t dwHeight = dwYH-dwYL; float xScale = (t0u1-t0u0)/dwWidth; float yScale = (t0v1-t0v0)/dwHeight; uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; uint8_t* dwSrc = rdram_u8 + info.dwLoadAddress; uint8_t* dwDst = rdram_u8 + g_pRenderTextureInfo->CI_Info.dwAddr; uint32_t dwSrcPitch = gRDP.tiles[dwTile].dwPitch; uint32_t dwDstPitch = g_pRenderTextureInfo->CI_Info.dwWidth; uint32_t dwSrcOffX = gRDP.tiles[dwTile].hilite_sl; uint32_t dwSrcOffY = gRDP.tiles[dwTile].hilite_tl; uint32_t dwLeft = dwXL; uint32_t dwTop = dwYL; dwWidth = min(dwWidth, maxW-dwLeft); dwHeight = min(dwHeight, maxH-dwTop); if (maxH <= dwTop) return; for (uint32_t y = 0; y < dwHeight; y++) { uint32_t dwByteOffset = (uint32_t)(((y*yScale+dwSrcOffY) * dwSrcPitch) + dwSrcOffX); for (uint32_t x = 0; x < dwWidth; x++) { if ((((y+dwTop)*dwDstPitch+x+dwLeft)^0x3) > maxOff) { #ifdef DEBUGGER TRACE0("Warning: Offset exceeds limit"); #endif continue; } dwDst[((y+dwTop)*dwDstPitch+x+dwLeft)^0x3] = dwSrc[(uint32_t)(dwByteOffset+x*xScale) ^ 0x3]; } } TXTRBUF_DUMP(DebuggerAppendMsg("TexRect To FrameBuffer: X0=%d, Y0=%d, X1=%d, Y1=%d,\n\t\tfS0=%f, fT0=%f, fS1=%f, fT1=%f ", dwXL, dwYL, dwXH, dwYH, t0v0, t0v0, t0u1, t0v1);); } void TexRectToN64FrameBuffer_16b(uint32_t x0, uint32_t y0, uint32_t width, uint32_t height, uint32_t dwTile) { // Copy the framebuffer texture into the N64 RDRAM framebuffer memory structure DrawInfo srcInfo; if (g_textures[dwTile].m_pCTexture->StartUpdate(&srcInfo) == false) { DebuggerAppendMsg("Fail to lock texture:TexRectToN64FrameBuffer_16b"); return; } uint32_t n64CIaddr = g_CI.dwAddr; uint32_t n64CIwidth = g_CI.dwWidth; for (uint32_t y = 0; y < height; y++) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; uint32_t* pSrc = (uint32_t*)((uint8_t*)srcInfo.lpSurface + y * srcInfo.lPitch); uint16_t* pN64Buffer = (uint16_t*)(rdram_u8 + (n64CIaddr&(g_dwRamSize-1)))+(y+y0)*n64CIwidth; for (uint32_t x = 0; x < width; x++) { pN64Buffer[x+x0] = ConvertRGBATo555(pSrc[x]); } } g_textures[dwTile].m_pCTexture->EndUpdate(&srcInfo); } #define FAST_CRC_CHECKING_INC_X 13 #define FAST_CRC_CHECKING_INC_Y 11 #define FAST_CRC_MIN_Y_INC 2 #define FAST_CRC_MIN_X_INC 2 #define FAST_CRC_MAX_X_INC 7 #define FAST_CRC_MAX_Y_INC 3 extern uint32_t dwAsmHeight; extern uint32_t dwAsmPitch; extern uint32_t dwAsmdwBytesPerLine; extern uint32_t dwAsmCRC; extern uint8_t* pAsmStart; uint32_t CalculateRDRAMCRC(void *pPhysicalAddress, uint32_t left, uint32_t top, uint32_t width, uint32_t height, uint32_t size, uint32_t pitchInBytes ) { dwAsmCRC = 0; dwAsmdwBytesPerLine = ((width<=32 || (dwAsmdwBytesPerLine>>2)>=16)) { uint32_t realWidthInDWORD = dwAsmdwBytesPerLine>>2; uint32_t xinc = realWidthInDWORD / FAST_CRC_CHECKING_INC_X; if (xinc < FAST_CRC_MIN_X_INC) { xinc = min(FAST_CRC_MIN_X_INC, width); } if (xinc > FAST_CRC_MAX_X_INC) { xinc = FAST_CRC_MAX_X_INC; } uint32_t yinc = height / FAST_CRC_CHECKING_INC_Y; if (yinc < FAST_CRC_MIN_Y_INC) { yinc = min(FAST_CRC_MIN_Y_INC, height); } if (yinc > FAST_CRC_MAX_Y_INC) { yinc = FAST_CRC_MAX_Y_INC; } uint32_t pitch = pitchInBytes>>2; register uint32_t *pStart = (uint32_t*)(pPhysicalAddress); pStart += (top * pitch) + (((left<>3); // The original assembly code had a bug in it (it incremented pStart by 'pitch' in bytes, not in dwords) // This C code implements the same algorithm as the ASM but without the bug uint32_t y = 0; while (y < height) { uint32_t x = 0; while (x < realWidthInDWORD) { dwAsmCRC = (dwAsmCRC << 4) + ((dwAsmCRC >> 28) & 15); dwAsmCRC += pStart[x]; x += xinc; dwAsmCRC += x; } dwAsmCRC ^= y; y += yinc; pStart += pitch; } } else { dwAsmdwBytesPerLine = ((width<>1); dwAsmHeight = height - 1; dwAsmPitch = pitchInBytes; uint32_t pitch = pitchInBytes>>2; uint32_t* pStart = (uint32_t*)pPhysicalAddress; pStart += (top * pitch) + (((left<>3); int y = dwAsmHeight; while (y >= 0) { uint32_t esi = 0; int x = dwAsmdwBytesPerLine - 4; while (x >= 0) { esi = *(uint32_t*)(pAsmStart + x); esi ^= x; dwAsmCRC = (dwAsmCRC << 4) + ((dwAsmCRC >> 28) & 15); dwAsmCRC += esi; x-=4; } esi ^= y; dwAsmCRC += esi; pAsmStart += dwAsmPitch; y--; } } return dwAsmCRC; } unsigned char CalculateMaxCI(void *pPhysicalAddress, uint32_t left, uint32_t top, uint32_t width, uint32_t height, uint32_t size, uint32_t pitchInBytes ) { unsigned char *buf; unsigned char val = 0; if (TXT_SIZE_8b == size) { for (uint32_t y = 0; y val) val = buf[x]; if (val == 0xFF) return 0xFF; } } } else { unsigned char val1,val2; left >>= 1; width >>= 1; for (uint32_t y = 0; y>4; val2 = buf[x]&0xF; if (val1 > val) val = val1; if (val2 > val) val = val2; if (val == 0xF) return 0xF; } } } return val; } bool FrameBufferManager::FrameBufferInRDRAMCheckCRC() { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; RecentCIInfo &p = *(g_uRecentCIInfoPtrs[0]); uint8_t *pFrameBufferBase = (uint8_t*)(rdram_u8 + p.dwAddr); uint32_t pitch = (p.dwWidth << p.dwSize ) >> 1; uint32_t crc = CalculateRDRAMCRC(pFrameBufferBase, 0, 0, p.dwWidth, p.dwHeight, p.dwSize, pitch); if (crc != p.dwCRC) { p.dwCRC = crc; TRACE0("Frame Buffer CRC mismatch, it was modified by the CPU"); return false; } else { return true; } } extern std::vector frameWriteRecord; void FrameBufferManager::FrameBufferWriteByCPU(uint32_t addr, uint32_t size) { if (!frameBufferOptions.bProcessCPUWrite) return; //WARNING(TRACE2("Frame Buffer Write, address=%08X, CI Address=%08X", addr, g_CI.dwAddr)); status.frameWriteByCPU = TRUE; frameWriteRecord.push_back(addr&(g_dwRamSize-1)); } extern M64P_RECT frameWriteByCPURect; extern std::vector frameWriteByCPURects; extern M64P_RECT frameWriteByCPURectArray[20][20]; extern bool frameWriteByCPURectFlag[20][20]; #define FRAMEBUFFER_IN_BLOCK bool FrameBufferManager::ProcessFrameWriteRecord() { int size = frameWriteRecord.size(); if (size == 0) return false; int index = FindRecentCIInfoIndex(frameWriteRecord[0]); if (index == -1) { LOG_TEXTURE(TRACE1("Frame Buffer Write to non-recorded address = %08X", frameWriteRecord[0])); frameWriteRecord.clear(); return false; } else { uint32_t base = g_uRecentCIInfoPtrs[index]->dwAddr; uint32_t uwidth = g_uRecentCIInfoPtrs[index]->dwWidth; uint32_t uheight = g_uRecentCIInfoPtrs[index]->dwHeight; uint32_t upitch = uwidth<<1; frameWriteByCPURect.left = uwidth-1; frameWriteByCPURect.top = uheight-1; frameWriteByCPURect.right = 0; frameWriteByCPURect.bottom = 0; for (int i=0; idwMemSize) { int y = off/upitch; int x = (off - y*upitch)>>1; #ifdef FRAMEBUFFER_IN_BLOCK int xidx=x/32; int yidx=y/24; M64P_RECT &rect = frameWriteByCPURectArray[xidx][yidx]; if (!frameWriteByCPURectFlag[xidx][yidx]) { rect.left=rect.right=x; rect.top=rect.bottom=y; frameWriteByCPURectFlag[xidx][yidx]=true; } else { if(x < rect.left) rect.left = x; if(x > rect.right) rect.right = x; if(y < rect.top) rect.top = y; if(y > rect.bottom) rect.bottom = y; } #else if (x < frameWriteByCPURect.left) frameWriteByCPURect.left = x; if (x > frameWriteByCPURect.right) frameWriteByCPURect.right = x; if (y < frameWriteByCPURect.top) frameWriteByCPURect.top = y; if (y > frameWriteByCPURect.bottom) frameWriteByCPURect.bottom = y; #endif } } frameWriteRecord.clear(); LOG_TEXTURE(TRACE4("Frame Buffer Write: Left=%d, Top=%d, Right=%d, Bottom=%d", frameWriteByCPURect.left, frameWriteByCPURect.top, frameWriteByCPURect.right, frameWriteByCPURect.bottom)); return true; } } void FrameBufferManager::FrameBufferReadByCPU( uint32_t addr ) { ///return; // it does not work very well anyway if (!frameBufferOptions.bProcessCPURead) return; addr &= (g_dwRamSize-1); int index = FindRecentCIInfoIndex(addr); if (index == -1) { // Check if this is the depth buffer uint32_t size = 2*g_RecentCIInfo[0].dwWidth*g_RecentCIInfo[0].dwHeight; addr &= 0x3FFFFFFF; if (addr >= g_ZI.dwAddr && addr < g_ZI.dwAddr + size) { TXTRBUF_OR_CI_DUMP(TRACE1("Depth Buffer read, reported by emulator, address=%08X", addr)); } else { return; } } if (status.gDlistCount - g_uRecentCIInfoPtrs[index]->lastUsedFrame > 3) { // Ok, we don't have this frame any more. return; } //TXTRBUF_OR_CI_DUMP(TRACE1("FB Read By CPU at %08X", addr)); if (g_uRecentCIInfoPtrs[index]->bCopied) return; //if (addr != g_uRecentCIInfoPtrs[index]->dwAddr) // return; TXTRBUF_OR_CI_DUMP(TRACE1("Frame Buffer read, reported by emulator, address=%08X", addr)); uint32_t size = 0x1000 - addr%0x1000; CheckAddrInBackBuffers(addr, size, true); DEBUGGER_IF_DUMP(pauseAtNext,{TRACE0("Frame Buffer read");}); DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_RENDER_TEXTURE, {DebuggerAppendMsg("Paused after setting Frame Buffer read:\n Cur CI Address: 0x%08x, Format: %s Size: %s Width: %d", g_CI.dwAddr, pszImgFormat[g_CI.dwFormat], pszImgSize[g_CI.dwSize], g_CI.dwWidth);}); } extern M64P_RECT frameWriteByCPURect; extern std::vector frameWriteByCPURects; extern M64P_RECT frameWriteByCPURectArray[20][20]; extern bool frameWriteByCPURectFlag[20][20]; #define FRAMEBUFFER_IN_BLOCK void FrameBufferManager::UpdateFrameBufferBeforeUpdateFrame() { if ((frameBufferOptions.bProcessCPUWrite && status.frameWriteByCPU ) || (frameBufferOptions.bLoadBackBufFromRDRAM && !FrameBufferInRDRAMCheckCRC() )) // Checks if frame buffer has been modified by CPU // Only happens to Dr. Mario { if (frameBufferOptions.bProcessCPUWrite) { if (ProcessFrameWriteRecord()) { #ifdef FRAMEBUFFER_IN_BLOCK for (int i=0; i<20; i++) { for (int j=0; j<20; j++) { if (frameWriteByCPURectFlag[i][j]) { CRender::GetRender()->DrawFrameBuffer(false, frameWriteByCPURectArray[i][j].left, frameWriteByCPURectArray[i][j].top, frameWriteByCPURectArray[i][j].right-frameWriteByCPURectArray[i][j].left+1, frameWriteByCPURectArray[i][j].bottom-frameWriteByCPURectArray[i][j].top+1); } } } for (int i=0; i<20; i++) { for (int j=0; j<20; j++) { if (frameWriteByCPURectFlag[i][j]) { ClearN64FrameBufferToBlack(frameWriteByCPURectArray[i][j].left, frameWriteByCPURectArray[i][j].top, frameWriteByCPURectArray[i][j].right-frameWriteByCPURectArray[i][j].left+1, frameWriteByCPURectArray[i][j].bottom-frameWriteByCPURectArray[i][j].top+1); frameWriteByCPURectFlag[i][j] = false; } } } //memset(frameWriteByCPURectArray, 0, sizeof(frameWriteByCPURectArray)); //memset(frameWriteByCPURectFlag, 0, sizeof(frameWriteByCPURectFlag)); #else CRender::GetRender()->DrawFrameBuffer(false, frameWriteByCPURect.left, frameWriteByCPURect.top, frameWriteByCPURect.right-frameWriteByCPURect.left, frameWriteByCPURect.bottom-frameWriteByCPURect.top); ClearN64FrameBufferToBlack(frameWriteByCPURect.left, frameWriteByCPURect.top, frameWriteByCPURect.right-frameWriteByCPURect.left+1, frameWriteByCPURect.bottom-frameWriteByCPURect.top+1); /* int size = frameWriteByCPURects.size(); for( int i=0; iDrawFrameBuffer(false, frameWriteByCPURects[i].left, frameWriteByCPURects[i].top, frameWriteByCPURects[i].right-frameWriteByCPURects[i].left, frameWriteByCPURects[i].bottom-frameWriteByCPURects[i].top); ClearN64FrameBufferToBlack(frameWriteByCPURects[i].left, frameWriteByCPURects[i].top, frameWriteByCPURects[i].right-frameWriteByCPURects[i].left+1, frameWriteByCPURects[i].bottom-frameWriteByCPURects[i].top+1); } frameWriteByCPURects.clear(); */ #endif } status.frameWriteByCPU = FALSE; } else { if (CRender::IsAvailable()) { RecentCIInfo &p = *(g_uRecentCIInfoPtrs[0]); CRender::GetRender()->DrawFrameBuffer(false, 0, 0, p.dwWidth, p.dwHeight); ClearN64FrameBufferToBlack(0, 0, 0, 0); } } } } uint32_t FrameBufferManager::ComputeCImgHeight(SetImgInfo &info, uint32_t &height) { uint32_t dwPC = gDlistStack[gDlistStackPointer].pc; // This points to the next instruction for (int i=0; i<10; i++) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; uint32_t w0 = *(uint32_t *)(rdram_u8 + dwPC + i*8); uint32_t w1 = *(uint32_t *)(rdram_u8 + dwPC + 4 + i*8); if ((w0>>24) == RDP_SETSCISSOR) { height = ((w1>>0 )&0xFFF)/4; TXTRBUF_DETAIL_DUMP(TRACE1("buffer height = %d", height)); return RDP_SETSCISSOR; } if ((w0>>24) == RDP_FILLRECT) { uint32_t x0 = ((w1>>12)&0xFFF)/4; uint32_t y0 = ((w1>>0 )&0xFFF)/4; uint32_t x1 = ((w0>>12)&0xFFF)/4; uint32_t y1 = ((w0>>0 )&0xFFF)/4; if (x0 == 0 && y0 == 0) { if (x1 == info.dwWidth) { height = y1; TXTRBUF_DETAIL_DUMP(TRACE1("buffer height = %d", height)); return RDP_FILLRECT; } if (x1 == (unsigned int)(info.dwWidth-1)) { height = y1+1; TXTRBUF_DETAIL_DUMP(TRACE1("buffer height = %d", height)); return RDP_FILLRECT; } } } if ((w0>>24) == RDP_SETCIMG) { goto step2; } if ((w0>>24) == RDP_SETCIMG) { goto step2; } } if (gRDP.scissor.left == 0 && gRDP.scissor.top == 0 && (unsigned int)gRDP.scissor.right == info.dwWidth) { height = gRDP.scissor.bottom; TXTRBUF_DETAIL_DUMP(TRACE1("buffer height = %d", height)); return RDP_SETSCISSOR+1; } step2: TXTRBUF_DETAIL_DUMP(TRACE0("Not sure about buffer height")); height = info.dwWidth*3/4; if (status.dwTvSystem == TV_SYSTEM_PAL) { height = info.dwWidth*9/11; } if (gRDP.scissor.bottom < (int)height && gRDP.scissor.bottom != 0) { height = gRDP.scissor.bottom; } if (info.dwAddr + height*info.dwWidth*info.dwSize >= g_dwRamSize) { height = info.dwWidth*3/4; if (status.dwTvSystem == TV_SYSTEM_PAL) { height = info.dwWidth*9/11; } if (gRDP.scissor.bottom < (int)height && gRDP.scissor.bottom != 0) { height = gRDP.scissor.bottom; } if (info.dwAddr + height*info.dwWidth*info.dwSize >= g_dwRamSize) { height = ( g_dwRamSize - info.dwAddr ) / info.dwWidth; } } TXTRBUF_DETAIL_DUMP(TRACE1("render_texture height = %d", height)); return 0; } int FrameBufferManager::CheckRenderTexturesWithNewCI(SetImgInfo &CIinfo, uint32_t height, bool byNewTxtrBuf) { int matchidx = -1; uint32_t memsize = ((height*CIinfo.dwWidth)>>1)<>1)< CIinfo.dwAddr && info.CI_Info.dwAddr < CIinfo.dwAddr + memsize) covered = true; else if (info.CI_Info.dwAddr+memsize2 > CIinfo.dwAddr && info.CI_Info.dwAddr+memsize2 < CIinfo.dwAddr + memsize) covered = true; else if (CIinfo.dwAddr > info.CI_Info.dwAddr && CIinfo.dwAddr < info.CI_Info.dwAddr + memsize2) covered = true; else if (CIinfo.dwAddr+ memsize > info.CI_Info.dwAddr && CIinfo.dwAddr+ memsize < info.CI_Info.dwAddr + memsize2) covered = true; } if (covered) { //SAFE_DELETE(info.psurf); if (info.pRenderTexture->IsBeingRendered()) { TRACE0("Error, covering a render_texture which is being rendered"); TRACE3("New address=%08X, width=%d, height=%d", CIinfo.dwAddr, CIinfo.dwWidth, height ); TRACE3("Old address=%08X, width=%d, height=%d", info.CI_Info.dwAddr, info.N64Width, info.N64Height ); } info.isUsed = false; TXTRBUF_DUMP(TRACE5("Delete texture buffer %d at %08X, covered by new CI at %08X, Width=%d, Height=%d", i, info.CI_Info.dwAddr, CIinfo.dwAddr, CIinfo.dwWidth, height )); SAFE_DELETE(info.pRenderTexture); info.txtEntry.pTexture = NULL; continue; } } return matchidx; } extern RecentCIInfo *g_uRecentCIInfoPtrs[5]; RenderTextureInfo newRenderTextureInfo; int FrameBufferManager::FindASlot(void) { int idx; // Find an empty slot bool found = false; for (int i=0; iN64Height);}); } int FrameBufferManager::SetBackBufferAsRenderTexture(SetImgInfo &CIinfo, int ciInfoIdx) { // MUDLORD: // OK, here's the drill! // // We set the graphics card's back buffer's contents as a render_texure // This is done due to how the current framebuffer implementation detects // changes to the backbuffer memory pointer and then we do a texture // copy. This might be slow since it doesn't use hardware auxiliary buffers RenderTextureInfo tempRenderTextureInfo; memcpy(&(tempRenderTextureInfo.CI_Info), &CIinfo, sizeof(SetImgInfo)); tempRenderTextureInfo.N64Width = g_uRecentCIInfoPtrs[ciInfoIdx]->dwLastWidth; tempRenderTextureInfo.N64Height = g_uRecentCIInfoPtrs[ciInfoIdx]->dwLastHeight; tempRenderTextureInfo.knownHeight = true; tempRenderTextureInfo.maxUsedHeight = 0; tempRenderTextureInfo.bufferWidth = windowSetting.uDisplayWidth; tempRenderTextureInfo.bufferHeight = windowSetting.uDisplayHeight; tempRenderTextureInfo.scaleX = tempRenderTextureInfo.bufferWidth / float(tempRenderTextureInfo.N64Width); tempRenderTextureInfo.scaleY = tempRenderTextureInfo.bufferHeight / float(tempRenderTextureInfo.N64Height); status.bFrameBufferIsDrawn = false; status.bFrameBufferDrawnByTriangles = false; tempRenderTextureInfo.updateAtFrame = status.gDlistCount; tempRenderTextureInfo.updateAtUcodeCount = status.gUcodeCount; // Checking against previous render_texture infos //uint32_t memsize = ((tempRenderTextureInfo.N64Height*tempRenderTextureInfo.N64Width)>>1)<= 0) ? matchidx : FindASlot(); if (gRenderTextureInfos[idxToUse].pRenderTexture == NULL || matchidx < 0) { gRenderTextureInfos[idxToUse].pRenderTexture = new COGLRenderTexture(tempRenderTextureInfo.bufferWidth, tempRenderTextureInfo.bufferHeight, &gRenderTextureInfos[idxToUse], AS_BACK_BUFFER_SAVE); } // Need to set all variables for gRenderTextureInfos[idxToUse] CRenderTexture *pRenderTexture = gRenderTextureInfos[idxToUse].pRenderTexture; memcpy(&gRenderTextureInfos[idxToUse], &tempRenderTextureInfo, sizeof(RenderTextureInfo) ); gRenderTextureInfos[idxToUse].pRenderTexture = pRenderTexture; gRenderTextureInfos[idxToUse].isUsed = true; gRenderTextureInfos[idxToUse].txtEntry.pTexture = pRenderTexture->m_pTexture; gRenderTextureInfos[idxToUse].txtEntry.txtrBufIdx = idxToUse+1; TXTRBUF_DUMP(TRACE2("Set back buffer as render_texture %d, addr=%08X", idxToUse, CIinfo.dwAddr)); DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_RENDER_TEXTURE, {DebuggerAppendMsg("Paused after setting render_texture:\nAddr: 0x%08x, Fmt: %s Size: %s Width: %d, Height:%d", CIinfo.dwAddr, pszImgFormat[CIinfo.dwFormat], pszImgSize[CIinfo.dwSize], CIinfo.dwWidth, g_pRenderTextureInfo->N64Height);}); return idxToUse; } void FrameBufferManager::CloseRenderTexture(bool toSave) { if (m_curRenderTextureIndex < 0) return; status.bHandleN64RenderTexture = false; if (status.bDirectWriteIntoRDRAM) { // TODO: Implement } else { RestoreNormalBackBuffer(); if (!toSave || !status.bFrameBufferIsDrawn || !status.bFrameBufferDrawnByTriangles) { TXTRBUF_DUMP(TRACE0("Closing render_texture without save");); SAFE_DELETE(gRenderTextureInfos[m_curRenderTextureIndex].pRenderTexture); gRenderTextureInfos[m_curRenderTextureIndex].isUsed = false; TXTRBUF_DUMP(TRACE1("Delete render_texture %d",m_curRenderTextureIndex);); } else { TXTRBUF_DUMP(TRACE1("Closing render_texture %d", m_curRenderTextureIndex);); StoreRenderTextureToRDRAM(-1); if (frameBufferOptions.bRenderTextureWriteBack) { SAFE_DELETE(gRenderTextureInfos[m_curRenderTextureIndex].pRenderTexture); gRenderTextureInfos[m_curRenderTextureIndex].isUsed = false; TXTRBUF_DUMP(TRACE1("Delete render_texture %d after writing back to RDRAM",m_curRenderTextureIndex);); } else { g_pRenderTextureInfo->crcInRDRAM = ComputeRenderTextureCRCInRDRAM(m_curRenderTextureIndex); g_pRenderTextureInfo->crcCheckedAtFrame = status.gDlistCount; } } } SetScreenMult(windowSetting.uDisplayWidth/windowSetting.fViWidth, windowSetting.uDisplayHeight/windowSetting.fViHeight); CRender::g_pRender->UpdateClipRectangle(); CRender::g_pRender->ApplyScissorWithClipRatio(false); DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_RENDER_TEXTURE, { DebuggerAppendMsg("Paused after saving render_texture %d:\nAddress: 0x%08x, Format: %s Size: %s Width: %d", m_curRenderTextureIndex, g_pRenderTextureInfo->CI_Info.dwAddr, pszImgFormat[g_pRenderTextureInfo->CI_Info.dwFormat], pszImgSize[g_pRenderTextureInfo->CI_Info.dwSize], g_pRenderTextureInfo->CI_Info.dwWidth); }); } void FrameBufferManager::ClearN64FrameBufferToBlack(uint32_t left, uint32_t top, uint32_t width, uint32_t height) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; RecentCIInfo &p = *(g_uRecentCIInfoPtrs[0]); uint16_t *frameBufferBase = (uint16_t*)(rdram_u8 + p.dwAddr); uint32_t pitch = p.dwWidth; if (width == 0 || height == 0) { uint32_t len = p.dwHeight*p.dwWidth*p.dwSize; if (p.dwSize == TXT_SIZE_4b) len = (p.dwHeight*p.dwWidth)>>1; memset(frameBufferBase, 0, len); } else { for (uint32_t y=0; yUpdateFrame(false); RecentCIInfo *info = g_uRecentCIInfoPtrs[i]; StoreBackBufferToRDRAM(info->dwAddr, info->dwFormat, info->dwSize, info->dwWidth, info->dwHeight, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight, addr, 0x1000-addr%0x1000, 0, SURFFMT_A8R8G8B8); TRACE1("Copy back for CI Address = %08X", info->dwAddr); } } // We do these checks to see if a render_texture operation is occurring... void FrameBufferManager::CheckRenderTextureCRCInRDRAM(void) { for (int i=0; iIsBeingRendered()) continue; if (gRenderTextureInfos[i].crcCheckedAtFrame < status.gDlistCount) { uint32_t crc = ComputeRenderTextureCRCInRDRAM(i); if (gRenderTextureInfos[i].crcInRDRAM != crc) { // RDRAM has been modified by CPU core TXTRBUF_DUMP(TRACE2("Delete texture buffer %d at %08X, CRC in RDRAM changed", i, gRenderTextureInfos[i].CI_Info.dwAddr )); SAFE_DELETE(gRenderTextureInfos[i].pRenderTexture); gRenderTextureInfos[i].isUsed = false; continue; } else { gRenderTextureInfos[i].crcCheckedAtFrame = status.gDlistCount; } } } } // Check render_texture memory addresses int FrameBufferManager::CheckAddrInRenderTextures(uint32_t addr, bool checkcrc) { for (int i=0; iIsBeingRendered()) continue; uint32_t bufHeight = gRenderTextureInfos[i].knownHeight ? gRenderTextureInfos[i].N64Height : gRenderTextureInfos[i].maxUsedHeight; uint32_t bufMemSize = gRenderTextureInfos[i].CI_Info.dwSize*gRenderTextureInfos[i].N64Width*bufHeight; if (addr >=gRenderTextureInfos[i].CI_Info.dwAddr && addr < gRenderTextureInfos[i].CI_Info.dwAddr+bufMemSize) { if (checkcrc) { // Check the CRC in RDRAM if( gRenderTextureInfos[i].crcCheckedAtFrame < status.gDlistCount ) { uint32_t crc = ComputeRenderTextureCRCInRDRAM(i); if (gRenderTextureInfos[i].crcInRDRAM != crc) { // RDRAM has been modified by CPU core TRACE3("Buffer %d CRC in RDRAM changed from %08X to %08X", i, gRenderTextureInfos[i].crcInRDRAM, crc ); TXTRBUF_DUMP(TRACE2("Delete texture buffer %d at %08X, crcInRDRAM failed.", i, gRenderTextureInfos[i].CI_Info.dwAddr )); SAFE_DELETE(gRenderTextureInfos[i].pRenderTexture); gRenderTextureInfos[i].isUsed = false; continue; } else { gRenderTextureInfos[i].crcCheckedAtFrame = status.gDlistCount; } } } TXTRBUF_DUMP(TRACE2("Loading texture address = %08X from texture buffer %d", addr, i)); return i; } } return -1; } // Load texture from render_texture buffer void FrameBufferManager::LoadTextureFromRenderTexture(TxtrCacheEntry* pEntry, int infoIdx) { if (infoIdx < 0 || infoIdx >= numOfTxtBufInfos) { infoIdx = CheckAddrInRenderTextures(pEntry->ti.Address, true); } if (infoIdx >= 0 && gRenderTextureInfos[infoIdx].isUsed && gRenderTextureInfos[infoIdx].pRenderTexture) { TXTRBUF_DUMP(TRACE1("Loading from render_texture %d", infoIdx)); gRenderTextureInfos[infoIdx].pRenderTexture->LoadTexture(pEntry); } } void FrameBufferManager::RestoreNormalBackBuffer() { if (m_curRenderTextureIndex >= 0 && m_curRenderTextureIndex < numOfTxtBufInfos) { if( gRenderTextureInfos[m_curRenderTextureIndex].pRenderTexture ) gRenderTextureInfos[m_curRenderTextureIndex].pRenderTexture->SetAsRenderTarget(false); m_isRenderingToTexture = false; m_lastTextureBufferIndex = m_curRenderTextureIndex; } if (!status.bFrameBufferIsDrawn || !status.bFrameBufferDrawnByTriangles) { gRenderTextureInfos[m_curRenderTextureIndex].isUsed = false; TXTRBUF_DUMP(TRACE2("Delete texture buffer %d at %08X, it is never rendered", m_curRenderTextureIndex, gRenderTextureInfos[m_curRenderTextureIndex].CI_Info.dwAddr )); SAFE_DELETE(gRenderTextureInfos[m_curRenderTextureIndex].pRenderTexture); } } uint32_t FrameBufferManager::ComputeRenderTextureCRCInRDRAM(int infoIdx) { if (infoIdx >= numOfTxtBufInfos || infoIdx < 0 || !gRenderTextureInfos[infoIdx].isUsed) return 0; uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; RenderTextureInfo &info = gRenderTextureInfos[infoIdx]; uint32_t height = info.knownHeight ? info.N64Height : info.maxUsedHeight; uint8_t *pAddr = (uint8_t*)(rdram_u8 + info.CI_Info.dwAddr); uint32_t pitch = (info.N64Width << info.CI_Info.dwSize ) >> 1; return CalculateRDRAMCRC(pAddr, 0, 0, info.N64Width, height, info.CI_Info.dwSize, pitch); } // Activates texture buffer for drawing void FrameBufferManager::ActiveTextureBuffer(void) { status.bCIBufferIsRendered = true; if (status.bHandleN64RenderTexture) { // Checking against previous render_texture infos int matchidx = -1; //uint32_t memsize = ((newRenderTextureInfo.N64Height*newRenderTextureInfo.N64Width)>>1)<= 0) { // Reuse the matched slot idxToUse = matchidx; } else { idxToUse = FindASlot(); } if (gRenderTextureInfos[idxToUse].pRenderTexture == NULL || matchidx < 0) { int w = newRenderTextureInfo.bufferWidth; if (newRenderTextureInfo.knownHeight == RDP_SETSCISSOR && newRenderTextureInfo.CI_Info.dwAddr == g_ZI.dwAddr) { w = gRDP.scissor.right; } gRenderTextureInfos[idxToUse].pRenderTexture = new COGLRenderTexture(w, newRenderTextureInfo.bufferHeight, &gRenderTextureInfos[idxToUse], AS_RENDER_TARGET); } // Need to set all variables for gRenderTextureInfos[idxToUse] CRenderTexture *pRenderTexture = gRenderTextureInfos[idxToUse].pRenderTexture; memcpy(&gRenderTextureInfos[idxToUse], &newRenderTextureInfo, sizeof(RenderTextureInfo) ); gRenderTextureInfos[idxToUse].pRenderTexture = pRenderTexture; gRenderTextureInfos[idxToUse].isUsed = true; gRenderTextureInfos[idxToUse].txtEntry.pTexture = pRenderTexture->m_pTexture; gRenderTextureInfos[idxToUse].txtEntry.txtrBufIdx = idxToUse+1; g_pRenderTextureInfo = &gRenderTextureInfos[idxToUse]; // Active the render_texture if (m_curRenderTextureIndex >= 0 && gRenderTextureInfos[m_curRenderTextureIndex].isUsed && gRenderTextureInfos[m_curRenderTextureIndex].pRenderTexture) { gRenderTextureInfos[m_curRenderTextureIndex].pRenderTexture->SetAsRenderTarget(false); m_isRenderingToTexture = false; } if (gRenderTextureInfos[idxToUse].pRenderTexture->SetAsRenderTarget(true)) { m_isRenderingToTexture = true; //Clear(CLEAR_COLOR_AND_DEPTH_BUFFER, 0x80808080, 1.0f); if (frameBufferOptions.bFillRectNextTextureBuffer) { CGraphicsContext::g_pGraphicsContext->Clear(CLEAR_COLOR_BUFFER, gRDP.fillColor, 1.0f); } else if( options.enableHackForGames == HACK_FOR_MARIO_TENNIS && g_pRenderTextureInfo->N64Width > 64 && g_pRenderTextureInfo->N64Width < 300 ) { CGraphicsContext::g_pGraphicsContext->Clear(CLEAR_COLOR_BUFFER, 0, 1.0f); } else if( options.enableHackForGames == HACK_FOR_MARIO_TENNIS && g_pRenderTextureInfo->N64Width < 64 && g_pRenderTextureInfo->N64Width > 32 ) { CGraphicsContext::g_pGraphicsContext->Clear(CLEAR_COLOR_BUFFER, 0, 1.0f); } m_curRenderTextureIndex = idxToUse; status.bDirectWriteIntoRDRAM = false; //SetScreenMult(1, 1); SetScreenMult(gRenderTextureInfos[m_curRenderTextureIndex].scaleX, gRenderTextureInfos[m_curRenderTextureIndex].scaleY); CRender::g_pRender->UpdateClipRectangle(); // If needed, draw RDRAM into the render_texture //if (frameBufferOptions.bLoadRDRAMIntoRenderTexture) //{ // CRender::GetRender()->LoadTxtrBufFromRDRAM(); //} } else { if (CDeviceBuilder::m_deviceGeneralType == DIRECTX_DEVICE) { TRACE1("Error to set Render Target: %d", idxToUse); TRACE1("Address = %08X", gRenderTextureInfos[idxToUse].CI_Info.dwAddr); TRACE2("Width = %d, Height=%d", gRenderTextureInfos[idxToUse].N64Width, gRenderTextureInfos[idxToUse].N64Height); } } TXTRBUF_DUMP(TRACE2("Rendering to render_texture %d, address=%08X", idxToUse, g_CI.dwAddr)); DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_RENDER_TEXTURE, {DebuggerAppendMsg("Paused after activating render_texture:\nAddr: 0x%08x, Format: %s Size: %s Width: %d, Height:%d", g_CI.dwAddr, pszImgFormat[g_CI.dwFormat], pszImgSize[g_CI.dwSize], g_CI.dwWidth, g_pRenderTextureInfo->N64Height);}); } else { UpdateRecentCIAddr(g_CI); CheckRenderTexturesWithNewCI(g_CI, gRDP.scissor.bottom, false); } } #define SAVE_CI {g_CI.dwAddr = newCI.dwAddr;g_CI.dwFormat = newCI.dwFormat;g_CI.dwSize = newCI.dwSize;g_CI.dwWidth = newCI.dwWidth;g_CI.bpl=newCI.bpl;} // Sets CI address for framebuffer copies void FrameBufferManager::Set_CI_addr(SetImgInfo &newCI) { bool wasDrawingTextureBuffer = status.bN64IsDrawingTextureBuffer; status.bN64IsDrawingTextureBuffer = ( newCI.dwSize != TXT_SIZE_16b || newCI.dwFormat != TXT_FMT_RGBA || newCI.dwWidth < 200 || ( newCI.dwAddr != g_ZI.dwAddr && newCI.dwWidth != 512 && !g_pFrameBufferManager->HasAddrBeenDisplayed(newCI.dwAddr, newCI.dwWidth)) ); status.bN64FrameBufferIsUsed = status.bN64IsDrawingTextureBuffer; if (!wasDrawingTextureBuffer && g_CI.dwAddr == g_ZI.dwAddr && status.bCIBufferIsRendered) { TXTRBUF_DUMP(TRACE0("ZI is rendered")); if (options.enableHackForGames != HACK_FOR_CONKER && g_uRecentCIInfoPtrs[0]->bCopied == false) { // Conker is not actually using a backbuffer g_pFrameBufferManager->UpdateRecentCIAddr(g_CI); if (status.leftRendered != -1 && status.topRendered != -1 && status.rightRendered != -1 && status.bottomRendered != -1) { M64P_RECT rect={status.leftRendered,status.topRendered,status.rightRendered,status.bottomRendered}; g_pFrameBufferManager->SaveBackBuffer(0, &rect, false); } else { g_pFrameBufferManager->SaveBackBuffer(0, NULL, false); } } } frameBufferOptions.bFillRectNextTextureBuffer = false; if (g_CI.dwAddr == newCI.dwAddr && status.bHandleN64RenderTexture && (g_CI.dwFormat != newCI.dwFormat || g_CI.dwSize != newCI.dwSize || g_CI.dwWidth != newCI.dwWidth)) { // Mario Tennis player shadow g_pFrameBufferManager->CloseRenderTexture(true); if (options.enableHackForGames == HACK_FOR_MARIO_TENNIS) frameBufferOptions.bFillRectNextTextureBuffer = true; // Hack for Mario Tennis } SAVE_CI; if (g_CI.dwAddr == g_ZI.dwAddr && !status.bN64IsDrawingTextureBuffer) { if (g_pFrameBufferManager->IsDIaRenderTexture()) { status.bN64IsDrawingTextureBuffer = true; status.bN64FrameBufferIsUsed = status.bN64IsDrawingTextureBuffer; } } status.bCIBufferIsRendered = false; status.leftRendered = status.topRendered = status.rightRendered = status.bottomRendered = -1; if (currentRomOptions.screenUpdateSetting==SCREEN_UPDATE_AT_CI_CHANGE && !status.bN64IsDrawingTextureBuffer) { if (status.curRenderBuffer == 0) { status.curRenderBuffer = g_CI.dwAddr; } else if (status.curRenderBuffer != g_CI.dwAddr) { status.curDisplayBuffer = status.curRenderBuffer; CGraphicsContext::Get()->UpdateFrame(false); status.curRenderBuffer = g_CI.dwAddr; DEBUGGER_IF_DUMP(pauseAtNext,{DebuggerAppendMsg("Screen Update because CI change to %08X, Display Buffer=%08X", status.curRenderBuffer, status.curDisplayBuffer);}); } } if (frameBufferOptions.bAtEachFrameUpdate && !status.bHandleN64RenderTexture) { if (status.curRenderBuffer != g_CI.dwAddr) { if (status.gDlistCount%(currentRomOptions.N64FrameBufferWriteBackControl+1) == 0) { g_pFrameBufferManager->StoreBackBufferToRDRAM(status.curRenderBuffer, newCI.dwFormat, newCI.dwSize, windowSetting.uViWidth, windowSetting.uViHeight, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight, 0xFFFFFFFF, 0xFFFFFFFF, 0, SURFFMT_A8R8G8B8); } } //status.curDisplayBuffer = status.curRenderBuffer; status.curRenderBuffer = g_CI.dwAddr; } switch (currentRomOptions.N64RenderToTextureEmuType) { case TXT_BUF_NONE: if (status.bHandleN64RenderTexture) g_pFrameBufferManager->CloseRenderTexture(false); status.bHandleN64RenderTexture = false; // Don't handle N64 render_texture stuffs if (!status.bN64IsDrawingTextureBuffer) g_pFrameBufferManager->UpdateRecentCIAddr(g_CI); break; default: if (status.bHandleN64RenderTexture) { #ifdef DEBUGGER if (pauseAtNext && eventToPause == NEXT_RENDER_TEXTURE) { pauseAtNext = TRUE; eventToPause = NEXT_RENDER_TEXTURE; } #endif g_pFrameBufferManager->CloseRenderTexture(true); } status.bHandleN64RenderTexture = status.bN64IsDrawingTextureBuffer; if (status.bHandleN64RenderTexture) { if (options.enableHackForGames != HACK_FOR_BANJO_TOOIE) { g_pFrameBufferManager->SetRenderTexture(); } } else { #ifdef DEBUGGER if (g_CI.dwWidth == 512 && pauseAtNext && (eventToPause==NEXT_OBJ_BG || eventToPause==NEXT_SET_CIMG)) { DebuggerAppendMsg("Warning SetCImg: new Address=0x%08X, Format:%s size=%sb, Width=%d\n", g_CI.dwAddr, pszImgFormat[newCI.dwFormat], pszImgSize[newCI.dwSize], newCI.dwWidth); } #endif //g_pFrameBufferManager->UpdateRecentCIAddr(g_CI); // Delay this until the CI buffer is actally drawn } break; } TXTRBUF_DUMP(TRACE4("SetCImg : Address=0x%08X, Format:%s-%sb, Width=%d\n", g_CI.dwAddr, pszImgFormat[newCI.dwFormat], pszImgSize[newCI.dwSize], newCI.dwWidth)); DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_SET_CIMG, { DebuggerAppendMsg("Pause after SetCImg: Address=0x%08X, Format:%s-%sb, Width=%d\n", g_CI.dwAddr, pszImgFormat[newCI.dwFormat], pszImgSize[newCI.dwSize], newCI.dwWidth); } ); } void FrameBufferManager::StoreRenderTextureToRDRAM(int infoIdx) { if (!frameBufferOptions.bRenderTextureWriteBack) return; if (infoIdx < 0) infoIdx = m_lastTextureBufferIndex; if (!gRenderTextureInfos[infoIdx].pRenderTexture) return; if (gRenderTextureInfos[infoIdx].pRenderTexture->IsBeingRendered()) { TXTRBUF_DUMP(TRACE1("Cannot SaveTextureBuffer %d, it is being rendered", infoIdx)); return; } gRenderTextureInfos[infoIdx].pRenderTexture->StoreToRDRAM(infoIdx); } //does FB copy to N64 RDAM structure void FrameBufferManager::CopyBufferToRDRAM(uint32_t addr, uint32_t fmt, uint32_t siz, uint32_t width, uint32_t height, uint32_t bufWidth, uint32_t bufHeight, uint32_t startaddr, uint32_t memsize, uint32_t pitch, TextureFmt bufFmt, void *buffer, uint32_t bufPitch) { uint32_t startline=0; if (startaddr == 0xFFFFFFFF) startaddr = addr; startline = (startaddr-addr)/siz/pitch; if (startline >= height) { //TRACE0("Warning: check me"); startline = height; } uint32_t endline = height; if (memsize != 0xFFFFFFFF) { endline = (startaddr+memsize-addr)/siz; if (endline % pitch == 0) endline /= pitch; else endline = endline/pitch+1; } if (endline > height) { endline = height; } if (memsize != 0xFFFFFFFF) { TXTRBUF_DUMP(DebuggerAppendMsg("Start at: 0x%X, from line %d to %d", startaddr-addr, startline, endline);); } int indexes[600]; { float ratio = bufWidth/(float)width; for (uint32_t j=0; jIsBeingRendered()) { TRACE1("Render texture %d is being rendered, cannot display", infoIdx); } else { TRACE1("Texture buffer %d:", infoIdx); TRACE1("Address=%08X", gRenderTextureInfos[infoIdx].CI_Info.dwAddr); TRACE2("Width=%d, Created Height=%d", gRenderTextureInfos[infoIdx].N64Width, gRenderTextureInfos[infoIdx].N64Height); TRACE2("Format=%d, Size=%d", gRenderTextureInfos[infoIdx].CI_Info.dwFormat, gRenderTextureInfos[infoIdx].CI_Info.dwSize); } } else { TRACE1("Texture buffer %d is not used", infoIdx); } } #endif // Saves backbuffer // this is the core to the current framebuffer code // We need to save backbuffer when changed by framebuffer // so that we can use it for framebuffer effects void FrameBufferManager::SaveBackBuffer(int ciInfoIdx, M64P_RECT* pSrcRect, bool forceToSaveToRDRAM) { RecentCIInfo &ciInfo = *g_uRecentCIInfoPtrs[ciInfoIdx]; if (ciInfoIdx == 1) // to save the current front buffer { CGraphicsContext::g_pGraphicsContext->UpdateFrame(true); } if (frameBufferOptions.bWriteBackBufToRDRAM || forceToSaveToRDRAM) { uint32_t width = ciInfo.dwWidth; uint32_t height = ciInfo.dwHeight; if (ciInfo.dwWidth == *gfx_info.VI_WIDTH_REG && ciInfo.dwWidth != windowSetting.uViWidth) { width = windowSetting.uViWidth; height = windowSetting.uViHeight; } StoreBackBufferToRDRAM( ciInfo.dwAddr, ciInfo.dwFormat, ciInfo.dwSize, width, height, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight, 0xFFFFFFFF, 0xFFFFFFFF, 0, SURFFMT_A8R8G8B8); g_uRecentCIInfoPtrs[ciInfoIdx]->bCopied = true; if (ciInfoIdx == 1) // to save the current front buffer { CGraphicsContext::g_pGraphicsContext->UpdateFrame(true); } return; } SetImgInfo tempinfo; tempinfo.dwAddr = ciInfo.dwAddr; tempinfo.dwFormat = ciInfo.dwFormat; tempinfo.dwSize = ciInfo.dwSize; tempinfo.dwWidth = ciInfo.dwWidth; int idx = SetBackBufferAsRenderTexture(tempinfo, ciInfoIdx); CopyBackBufferToRenderTexture(idx, ciInfo, pSrcRect); gRenderTextureInfos[idx].crcCheckedAtFrame = status.gDlistCount; gRenderTextureInfos[idx].crcInRDRAM = ComputeRenderTextureCRCInRDRAM(idx); DEBUGGER_IF_DUMP((logTextureBuffer && pSrcRect==NULL), TRACE1("SaveBackBuffer at 0x%08X", ciInfo.dwAddr)); DEBUGGER_IF_DUMP((logTextureBuffer && pSrcRect), TRACE5("SaveBackBuffer at 0x%08X, {%d,%d -%d,%d)", ciInfo.dwAddr, pSrcRect->left, pSrcRect->top, pSrcRect->right, pSrcRect->bottom)); DEBUGGER_IF_DUMP(( pauseAtNext && eventToPause == NEXT_RENDER_TEXTURE),{g_pFrameBufferManager->DisplayRenderTexture(idx);}); g_uRecentCIInfoPtrs[ciInfoIdx]->bCopied = true; } mupen64plus-video-gliden64/src/gSP.h000664 001750 001750 00000012223 12655644434 020270 0ustar00sergiosergio000000 000000 #ifndef GSP_H #define GSP_H #include "Types.h" #include "GBI.h" #include "gDP.h" #define CHANGED_VIEWPORT 0x01 #define CHANGED_MATRIX 0x02 #define CHANGED_GEOMETRYMODE 0x08 #define CHANGED_TEXTURE 0x10 #define CHANGED_FOGPOSITION 0x20 #define CHANGED_LIGHT 0x40 #define CHANGED_TEXTURESCALE 0x80 #define CLIP_X 0x03 #define CLIP_NEGX 0x01 #define CLIP_POSX 0x02 #define CLIP_Y 0x0C #define CLIP_NEGY 0x04 #define CLIP_POSY 0x08 #define CLIP_Z 0x10 #define CLIP_ALL 0x1F // CLIP_NEGX|CLIP_POSX|CLIP_NEGY|CLIP_POSY|CLIP_Z #define SC_POSITION 1 #define SC_COLOR 2 #define SC_TEXCOORD0 3 #define SC_TEXCOORD1 4 #define SC_NUMLIGHTS 5 struct SPVertex { f32 x, y, z, w; f32 nx, ny, nz, __pad0; f32 r, g, b, a; f32 flat_r, flat_g, flat_b, flat_a; f32 s, t; u8 HWLight; s16 flag; u32 clip; }; struct SPLight { f32 r, g, b; f32 x, y, z; f32 posx, posy, posz, posw; f32 ca, la, qa; }; struct gSPInfo { u32 segment[16]; struct { u32 modelViewi, stackSize, billboard; f32 modelView[32][4][4]; f32 projection[4][4]; f32 combined[4][4]; } matrix; struct { f32 A, B, C, D; f32 X, Y; f32 baseScaleX, baseScaleY; } objMatrix; u32 objRendermode; u32 vertexColorBase; u32 vertexi; SPLight lights[12]; SPLight lookat[2]; bool lookatEnable; struct { f32 scales, scalet; s32 level, on, tile; } texture; gDPTile *textureTile[2]; struct { f32 vscale[4]; f32 vtrans[4]; f32 x, y, width, height; f32 nearz, farz; } viewport; struct { s16 multiplier, offset; } fog; struct { u32 address, width, height, format, size, palette; f32 imageX, imageY, scaleW, scaleH; } bgImage; u32 geometryMode; s32 numLights; u32 changed; u32 status[4]; struct { u32 vtx, mtx, tex_offset, tex_shift, tex_count; } DMAOffsets; // CBFD u32 vertexNormalBase; f32 vertexCoordMod[16]; }; extern gSPInfo gSP; void gSPLoadUcodeEx( u32 uc_start, u32 uc_dstart, u16 uc_dsize ); void gSPNoOp(); void gSPMatrix( u32 matrix, u8 param ); void gSPDMAMatrix( u32 matrix, u8 index, u8 multiply ); void gSPViewport( u32 v ); void gSPForceMatrix( u32 mptr ); void gSPLight( u32 l, s32 n ); void gSPLightCBFD( u32 l, s32 n ); void gSPLookAt( u32 l, u32 n ); void gSPVertex( u32 v, u32 n, u32 v0 ); void gSPCIVertex( u32 v, u32 n, u32 v0 ); void gSPDMAVertex( u32 v, u32 n, u32 v0 ); void gSPCBFDVertex( u32 v, u32 n, u32 v0 ); void gSPDisplayList( u32 dl ); void gSPBranchList( u32 dl ); void gSPBranchLessZ( u32 branchdl, u32 vtx, f32 zval ); void gSPDlistCount(u32 count, u32 v); void gSPSprite2DBase(u32 _base ); void gSPDMATriangles( u32 tris, u32 n ); void gSP1Quadrangle( s32 v0, s32 v1, s32 v2, s32 v3 ); void gSPCullDisplayList( u32 v0, u32 vn ); void gSPPopMatrix( u32 param ); void gSPPopMatrixN( u32 param, u32 num ); void gSPSegment( s32 seg, s32 base ); void gSPClipRatio( u32 r ); void gSPInsertMatrix( u32 where, u32 num ); void gSPModifyVertex(u32 _vtx, u32 _where, u32 _val ); void gSPNumLights( s32 n ); void gSPLightColor( u32 lightNum, u32 packedColor ); void gSPFogFactor( s16 fm, s16 fo ); void gSPPerspNormalize( u16 scale ); void gSPTexture( f32 sc, f32 tc, s32 level, s32 tile, s32 on ); void gSPEndDisplayList(); void gSPGeometryMode( u32 clear, u32 set ); void gSPSetGeometryMode( u32 mode ); void gSPClearGeometryMode( u32 mode ); void gSPSetOtherMode_H(u32 _length, u32 _shift, u32 _data); void gSPSetOtherMode_L(u32 _length, u32 _shift, u32 _data); void gSPLine3D(s32 v0, s32 v1, s32 flag); void gSPLineW3D( s32 v0, s32 v1, s32 wd, s32 flag ); void gSPObjRectangle(u32 _sp ); void gSPObjRectangleR(u32 _sp); void gSPObjSprite(u32 _sp); void gSPObjLoadTxtr( u32 tx ); void gSPObjLoadTxSprite( u32 txsp ); void gSPObjLoadTxRect(u32 txsp); void gSPObjLoadTxRectR( u32 txsp ); void gSPBgRect1Cyc(u32 _bg ); void gSPBgRectCopy(u32 _bg ); void gSPObjMatrix( u32 mtx ); void gSPObjSubMatrix( u32 mtx ); void gSPObjRendermode(u32 _mode); void gSPSetDMAOffsets( u32 mtxoffset, u32 vtxoffset ); void gSPSetDMATexOffset(u32 _addr); void gSPSetVertexColorBase( u32 base ); void gSPSetVertexNormaleBase( u32 base ); void gSPProcessVertex(u32 v); void gSPCoordMod(u32 _w0, u32 _w1); void gSPTriangleUnknown(); void gSPTriangle(s32 v0, s32 v1, s32 v2); void gSP1Triangle(s32 v0, s32 v1, s32 v2); void gSP2Triangles(const s32 v00, const s32 v01, const s32 v02, const s32 flag0, const s32 v10, const s32 v11, const s32 v12, const s32 flag1 ); void gSP4Triangles(const s32 v00, const s32 v01, const s32 v02, const s32 v10, const s32 v11, const s32 v12, const s32 v20, const s32 v21, const s32 v22, const s32 v30, const s32 v31, const s32 v32 ); #ifdef __VEC4_OPT extern void (*gSPTransformVertex4)(u32 v, float mtx[4][4]); extern void (*gSPTransformNormal4)(u32 v, float mtx[4][4]); extern void (*gSPLightVertex4)(u32 v); extern void (*gSPPointLightVertex4)(u32 v, float _vPos[4][3]); extern void (*gSPBillboardVertex4)(u32 v); #endif extern void (*gSPTransformVertex)(float vtx[4], float mtx[4][4]); extern void (*gSPLightVertex)(SPVertex & _vtx); extern void (*gSPPointLightVertex)(SPVertex & _vtx, float * _vPos); extern void (*gSPBillboardVertex)(u32 v, u32 i); void gSPSetupFunctions(); #endif libretro-common/libco/libco.c000664 001750 001750 00000001143 12655644434 017352 0ustar00sergiosergio000000 000000 /* libco auto-selection module license: public domain */ #if defined(__GNUC__) && defined(__i386__) || (defined(_MSC_VER) && defined(_M_IX86)) #include "x86.c" #elif defined(__GNUC__) && defined(__amd64__) || (defined(_MSC_VER) && defined(_M_AMD64)) #include "amd64.c" #elif defined(__GNUC__) && defined(_ARCH_PPC) #include "ppc.c" #elif defined(__GNUC__) && (defined(__ARM_EABI__) || defined(__arm__)) #include "armeabi.c" #elif defined(__GNUC__) #include "sjlj.c" #elif defined(_MSC_VER) #include "fiber.c" #else #error "libco: unsupported processor, compiler or operating system" #endif mupen64plus-core/src/api/m64p_debugger.h000664 001750 001750 00000017471 12655644434 021224 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-core - m64p_debugger.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2009 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This header file defines typedefs for function pointers to Core Debugger * functions. */ #ifndef M64P_DEBUGGER_H #define M64P_DEBUGGER_H #include "m64p_types.h" #ifdef __cplusplus extern "C" { #endif /* DebugSetCallbacks() * * This function is called by the front-end to supply debugger callback * function pointers. If debugger is enabled and then later disabled within the * UI, this function may be called with NULL pointers in order to disable the * callbacks. */ typedef m64p_error (*ptr_DebugSetCallbacks)(void (*)(void), void (*)(unsigned int), void (*)(void)); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL DebugSetCallbacks(void (*)(void), void (*)(unsigned int), void (*)(void)); #endif /* DebugSetCoreCompare() * * This function is called by the front-end to supply callback function pointers * for the Core Comparison feature. */ typedef m64p_error (*ptr_DebugSetCoreCompare)(void (*)(unsigned int), void (*)(int, void *)); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL DebugSetCoreCompare(void (*)(unsigned int), void (*)(int, void *)); #endif /* DebugSetRunState() * * This function sets the run state of the R4300 CPU emulator. */ typedef m64p_error (*ptr_DebugSetRunState)(int); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL DebugSetRunState(int); #endif /* DebugGetState() * * This function reads and returns a debugger state variable, which are * enumerated in m64p_types.h. */ typedef int (*ptr_DebugGetState)(m64p_dbg_state); #if defined(M64P_CORE_PROTOTYPES) EXPORT int CALL DebugGetState(m64p_dbg_state); #endif /* DebugStep() * * This function signals the debugger to advance one instruction when in the * stepping mode. */ typedef m64p_error (*ptr_DebugStep)(void); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL DebugStep(void); #endif /* DebugDecodeOp() * * This is a helper function for the debugger front-end. This instruction takes * a PC value and an R4300 instruction opcode and writes the disassembled * instruction mnemonic and arguments into character buffers. This is intended * to be used to display disassembled code. */ typedef void (*ptr_DebugDecodeOp)(unsigned int, char *, char *, int); #if defined(M64P_CORE_PROTOTYPES) EXPORT void CALL DebugDecodeOp(unsigned int, char *, char *, int); #endif /* DebugMemGetRecompInfo() * * This function is used by the front-end to retrieve disassembly information * about recompiled code. For example, the dynamic recompiler may take a single * R4300 instruction and compile it into 10 x86 instructions. This function may * then be used to retrieve the disassembled code of the 10 x86 instructions. */ typedef void * (*ptr_DebugMemGetRecompInfo)(m64p_dbg_mem_info, unsigned int, int); #if defined(M64P_CORE_PROTOTYPES) EXPORT void * CALL DebugMemGetRecompInfo(m64p_dbg_mem_info, unsigned int, int); #endif /* DebugMemGetMemInfo() * * This function returns an integer value regarding the memory location address, * corresponding to the information requested by mem_info_type, which is a type * enumerated in m64p_types.h. */ typedef int (*ptr_DebugMemGetMemInfo)(m64p_dbg_mem_info, unsigned int); #if defined(M64P_CORE_PROTOTYPES) EXPORT int CALL DebugMemGetMemInfo(m64p_dbg_mem_info, unsigned int); #endif /* DebugMemGetPointer() * * This function returns a memory pointer (in x86 memory space) to a block of * emulated N64 memory. This may be used to retrieve a pointer to a special N64 * block (such as the serial, video, or audio registers) or the RDRAM. */ typedef void * (*ptr_DebugMemGetPointer)(m64p_dbg_memptr_type); #if defined(M64P_CORE_PROTOTYPES) EXPORT void * CALL DebugMemGetPointer(m64p_dbg_memptr_type); #endif /* DebugMemRead**() * * These functions retrieve a value from the emulated N64 memory. The returned * value will be correctly byte-swapped for the host architecture. */ typedef unsigned long long (*ptr_DebugMemRead64)(unsigned int); typedef unsigned int (*ptr_DebugMemRead32)(unsigned int); typedef unsigned short (*ptr_DebugMemRead16)(unsigned int); typedef unsigned char (*ptr_DebugMemRead8)(unsigned int); #if defined(M64P_CORE_PROTOTYPES) EXPORT unsigned long long CALL DebugMemRead64(unsigned int); EXPORT unsigned int CALL DebugMemRead32(unsigned int); EXPORT unsigned short CALL DebugMemRead16(unsigned int); EXPORT unsigned char CALL DebugMemRead8(unsigned int); #endif /* DebugMemWrite**() * * These functions write a value into the emulated N64 memory. The given value * will be correctly byte-swapped before storage. */ typedef void (*ptr_DebugMemWrite64)(unsigned int, unsigned long long); typedef void (*ptr_DebugMemWrite32)(unsigned int, unsigned int); typedef void (*ptr_DebugMemWrite16)(unsigned int, unsigned short); typedef void (*ptr_DebugMemWrite8)(unsigned int, unsigned char); #if defined(M64P_CORE_PROTOTYPES) EXPORT void CALL DebugMemWrite64(unsigned int, unsigned long long); EXPORT void CALL DebugMemWrite32(unsigned int, unsigned int); EXPORT void CALL DebugMemWrite16(unsigned int, unsigned short); EXPORT void CALL DebugMemWrite8(unsigned int, unsigned char); #endif /* DebugGetCPUDataPtr() * * This function returns a memory pointer (in x86 memory space) to a specific * register in the emulated R4300 CPU. */ typedef void * (*ptr_DebugGetCPUDataPtr)(m64p_dbg_cpu_data); #if defined(M64P_CORE_PROTOTYPES) EXPORT void * CALL DebugGetCPUDataPtr(m64p_dbg_cpu_data); #endif /* DebugBreakpointLookup() * * This function searches through all current breakpoints in the debugger to * find one that matches the given input parameters. If a matching breakpoint * is found, the index number is returned. If no breakpoints are found, -1 is * returned. */ typedef int (*ptr_DebugBreakpointLookup)(unsigned int, unsigned int, unsigned int); #if defined(M64P_CORE_PROTOTYPES) EXPORT int CALL DebugBreakpointLookup(unsigned int, unsigned int, unsigned int); #endif /* DebugBreakpointCommand() * * This function is used to process common breakpoint commands, such as adding, * removing, or searching the breakpoints. The meanings of the index and ptr * input parameters vary by command. */ typedef int (*ptr_DebugBreakpointCommand)(m64p_dbg_bkp_command, unsigned int, void *); #if defined(M64P_CORE_PROTOTYPES) EXPORT int CALL DebugBreakpointCommand(m64p_dbg_bkp_command, unsigned int, void *); #endif #ifdef __cplusplus } #endif #endif /* #define M64P_DEBUGGER_H */ gles2rice/src/OGLES2FragmentShaders.h000664 001750 001750 00000006135 12655644434 020474 0ustar00sergiosergio000000 000000 /* Copyright (C) 2005 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _OGL_FRAGMENT_SHADER_H_ #define _OGL_FRAGMENT_SHADER_H_ #include #include "osal_opengl.h" #include "OGLCombiner.h" #include "OGLExtCombiner.h" typedef struct { uint32_t dwMux0; uint32_t dwMux1; bool fogIsUsed; bool alphaTest; GLuint fragmentShaderID; GLuint vertexShaderID; GLuint programID; GLint PrimColorLocation; GLint EnvColorLocation; GLint PrimFracLocation; GLint EnvFracLocation; GLint AlphaRefLocation; GLint FogColorLocation; GLint FogMinMaxLocation; float PrimColors[4]; float EnvColors[4]; float PrimLODFrac; float EnvLODFrac; float AlphaRef; float FogColors[4]; float FogMin; float FogMax; } OGLShaderCombinerSaveType; class COGL_FragmentProgramCombiner : public COGLColorCombiner4 { public: bool Initialize(void); void SetFogState(bool bEnable) { bFogState = bEnable; } void SetAlphaTestState(bool bEnable) { bAlphaTestState = bEnable; } protected: friend class OGLDeviceBuilder; void DisableCombiner(void); void InitCombinerCycleCopy(void); void InitCombinerCycleFill(void); void InitCombinerCycle12(void); COGL_FragmentProgramCombiner(CRender *pRender); ~COGL_FragmentProgramCombiner(); bool m_bFragmentProgramIsSupported; std::vector m_vCompiledShaders; private: virtual int ParseDecodedMux(); virtual void GenerateProgramStr(); int FindCompiledMux(); virtual void GenerateCombinerSetting(int index); virtual void GenerateCombinerSettingConstants(int index); float m_AlphaRef; bool bAlphaTestState; bool bAlphaTestPreviousState; bool bFogState; bool bFogPreviousState; void UseProgram(GLuint program); GLuint currentProgram; #ifdef DEBUGGER void DisplaySimpleMuxString(void); #endif }; class COGLFragmentShaderCombiner : public COGLColorCombiner { public: bool Initialize(void); void InitCombinerBlenderForSimpleTextureDraw(uint32_t tile); protected: friend class OGLDeviceBuilder; void DisableCombiner(void); void InitCombinerCycleCopy(void); void InitCombinerCycleFill(void); void InitCombinerCycle12(void); COGLFragmentShaderCombiner(CRender *pRender); ~COGLFragmentShaderCombiner(); bool m_bShaderIsSupported; #ifdef DEBUGGER void DisplaySimpleMuxString(void); #endif }; #endif mupen64plus-core/src/r4300/hacktarux_dynarec/gcop1.c000664 001750 001750 00000015454 12655644434 023273 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - gcop1.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2007 Richard Goedeken (Richard42) * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include "assemble.h" #include "interpret.h" #include "r4300/recomph.h" #include "r4300/recomp.h" #include "r4300/r4300.h" #include "r4300/ops.h" #include "r4300/macros.h" #include "r4300/cp1_private.h" #include "memory/memory.h" /* These are constants with addresses so that FLDCW can read them. * They are declared 'extern' so that other files can do the same. */ const uint16_t trunc_mode = 0xF3F; const uint16_t round_mode = 0x33F; const uint16_t ceil_mode = 0xB3F; const uint16_t floor_mode = 0x73F; void genmfc1(void) { #ifdef INTERPRET_MFC1 gencallinterp((native_type)cached_interpreter_table.MFC1, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t*)(®_cop1_simple[dst->f.r.nrd])); mov_reg32_preg64(EBX, RAX); mov_m32rel_xreg32((uint32_t*)dst->f.r.rt, EBX); sar_reg32_imm8(EBX, 31); mov_m32rel_xreg32(((uint32_t*)dst->f.r.rt)+1, EBX); #else mov_eax_memoffs32((unsigned int*)(®_cop1_simple[dst->f.r.nrd])); mov_reg32_preg32(EBX, EAX); mov_m32_reg32((unsigned int*)dst->f.r.rt, EBX); sar_reg32_imm8(EBX, 31); mov_m32_reg32(((unsigned int*)dst->f.r.rt)+1, EBX); #endif #endif } void gendmfc1(void) { #ifdef INTERPRET_DMFC1 gencallinterp((native_type)cached_interpreter_table.DMFC1, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *) (®_cop1_double[dst->f.r.nrd])); mov_reg32_preg64(EBX, RAX); mov_reg32_preg64pimm32(ECX, RAX, 4); mov_m32rel_xreg32((unsigned int*)dst->f.r.rt, EBX); mov_m32rel_xreg32(((unsigned int*)dst->f.r.rt)+1, ECX); #else mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.r.nrd])); mov_reg32_preg32(EBX, EAX); mov_reg32_preg32pimm32(ECX, EAX, 4); mov_m32_reg32((unsigned int*)dst->f.r.rt, EBX); mov_m32_reg32(((unsigned int*)dst->f.r.rt)+1, ECX); #endif #endif } void gencfc1(void) { #ifdef INTERPRET_CFC1 gencallinterp((native_type)cached_interpreter_table.CFC1, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ if(dst->f.r.nrd == 31) mov_xreg32_m32rel(EAX, (unsigned int*)&FCR31); else mov_xreg32_m32rel(EAX, (unsigned int*)&FCR0); mov_m32rel_xreg32((unsigned int*)dst->f.r.rt, EAX); sar_reg32_imm8(EAX, 31); mov_m32rel_xreg32(((unsigned int*)dst->f.r.rt)+1, EAX); #else if(dst->f.r.nrd == 31) mov_eax_memoffs32((unsigned int*)&FCR31); else mov_eax_memoffs32((unsigned int*)&FCR0); mov_memoffs32_eax((unsigned int*)dst->f.r.rt); sar_reg32_imm8(EAX, 31); mov_memoffs32_eax(((unsigned int*)dst->f.r.rt)+1); #endif #endif } void genmtc1(void) { #ifdef INTERPRET_MTC1 gencallinterp((native_type)cached_interpreter_table.MTC1, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg32_m32rel(EAX, (unsigned int*)dst->f.r.rt); mov_xreg64_m64rel(RBX, (uint64_t *)(®_cop1_simple[dst->f.r.nrd])); mov_preg64_reg32(RBX, EAX); #else mov_eax_memoffs32((unsigned int*)dst->f.r.rt); mov_reg32_m32(EBX, (unsigned int*)(®_cop1_simple[dst->f.r.nrd])); mov_preg32_reg32(EBX, EAX); #endif #endif } void gendmtc1(void) { #ifdef INTERPRET_DMTC1 gencallinterp((native_type)cached_interpreter_table.DMTC1, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg32_m32rel(EAX, (unsigned int*)dst->f.r.rt); mov_xreg32_m32rel(EBX, ((unsigned int*)dst->f.r.rt)+1); mov_xreg64_m64rel(RDX, (uint64_t *)(®_cop1_double[dst->f.r.nrd])); mov_preg64_reg32(RDX, EAX); mov_preg64pimm32_reg32(RDX, 4, EBX); #else mov_eax_memoffs32((unsigned int*)dst->f.r.rt); mov_reg32_m32(EBX, ((unsigned int*)dst->f.r.rt)+1); mov_reg32_m32(EDX, (unsigned int*)(®_cop1_double[dst->f.r.nrd])); mov_preg32_reg32(EDX, EAX); mov_preg32pimm32_reg32(EDX, 4, EBX); #endif #endif } void genctc1(void) { #ifdef INTERPRET_CTC1 gencallinterp((native_type)cached_interpreter_table.CTC1, 0); #else gencheck_cop1_unusable(); if (dst->f.r.nrd != 31) return; #ifdef __x86_64__ mov_xreg32_m32rel(EAX, (unsigned int*)dst->f.r.rt); mov_m32rel_xreg32((unsigned int*)&FCR31, EAX); and_eax_imm32(3); cmp_eax_imm32(0); jne_rj(13); mov_m32rel_imm32((unsigned int*)&rounding_mode, 0x33F); // 11 jmp_imm_short(51); // 2 cmp_eax_imm32(1); // 5 jne_rj(13); // 2 mov_m32rel_imm32((unsigned int*)&rounding_mode, 0xF3F); // 11 jmp_imm_short(31); // 2 cmp_eax_imm32(2); // 5 jne_rj(13); // 2 mov_m32rel_imm32((unsigned int*)&rounding_mode, 0xB3F); // 11 jmp_imm_short(11); // 2 mov_m32rel_imm32((unsigned int*)&rounding_mode, 0x73F); // 11 fldcw_m16rel((uint16_t*)&rounding_mode); #else mov_eax_memoffs32((unsigned int*)dst->f.r.rt); mov_memoffs32_eax((unsigned int*)&FCR31); and_eax_imm32(3); cmp_eax_imm32(0); jne_rj(12); mov_m32_imm32((unsigned int*)&rounding_mode, 0x33F); // 10 jmp_imm_short(48); // 2 cmp_eax_imm32(1); // 5 jne_rj(12); // 2 mov_m32_imm32((unsigned int*)&rounding_mode, 0xF3F); // 10 jmp_imm_short(29); // 2 cmp_eax_imm32(2); // 5 jne_rj(12); // 2 mov_m32_imm32((unsigned int*)&rounding_mode, 0xB3F); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int*)&rounding_mode, 0x73F); // 10 fldcw_m16((uint16_t*)&rounding_mode); #endif #endif } mupen64plus-core/src/r4300/cp1.h000664 001750 001750 00000003664 12655644434 017253 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - cp1.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_R4300_CP1_H #define M64P_R4300_CP1_H #include int64_t* r4300_cp1_regs(void); float** r4300_cp1_regs_simple(void); double** r4300_cp1_regs_double(void); uint32_t* r4300_cp1_fcr0(void); uint32_t* r4300_cp1_fcr31(void); void shuffle_fpr_data(uint32_t oldStatus, uint32_t newStatus); void set_fpr_pointers(uint32_t newStatus); void update_x86_rounding_mode(uint32_t FCR31); #endif /* M64P_R4300_CP1_H */ mupen64plus-core/src/api/m64p_vidext.h000664 001750 001750 00000013100 12655644434 020724 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-core - m64p_vidext.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2009 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This header file defines typedefs for function pointers to the core's * video extension functions. */ #ifndef M64P_VIDEXT_H #define M64P_VIDEXT_H #include "m64p_types.h" #ifdef __cplusplus extern "C" { #endif /* VidExt_Init() * * This function should be called from within the InitiateGFX() video plugin * function call. The default SDL implementation of this function simply calls * SDL_InitSubSystem(SDL_INIT_VIDEO). It does not open a rendering window or * switch video modes. */ typedef m64p_error (*ptr_VidExt_Init)(void); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL VidExt_Init(void); #endif /* VidExt_Quit() * * This function closes any open rendering window and shuts down the video * system. The default SDL implementation of this function calls * SDL_QuitSubSystem(SDL_INIT_VIDEO). This function should be called from * within the RomClose() video plugin function. */ typedef m64p_error (*ptr_VidExt_Quit)(void); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL VidExt_Quit(void); #endif /* VidExt_ListFullscreenModes() * * This function is used to enumerate the available resolutions for fullscreen * video modes. A pointer to an array is passed into the function, which is * then filled with resolution sizes. */ typedef m64p_error (*ptr_VidExt_ListFullscreenModes)(m64p_2d_size *, int *); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL VidExt_ListFullscreenModes(m64p_2d_size *, int *); #endif /* VidExt_SetVideoMode() * * This function creates a rendering window or switches into a fullscreen * video mode. Any desired OpenGL attributes should be set before calling * this function. */ typedef m64p_error (*ptr_VidExt_SetVideoMode)(int, int, int, m64p_video_mode, m64p_video_flags); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL VidExt_SetVideoMode(int, int, int, m64p_video_mode, m64p_video_flags); #endif /* VidExt_ResizeWindow() * * This function resizes the opengl rendering window to match the given size. */ typedef m64p_error (*ptr_VidExt_ResizeWindow)(int, int); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL VidExt_ResizeWindow(int, int); #endif /* VidExt_SetCaption() * * This function sets the caption text of the emulator rendering window. */ typedef m64p_error (*ptr_VidExt_SetCaption)(const char *); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL VidExt_SetCaption(const char *); #endif /* VidExt_ToggleFullScreen() * * This function toggles between fullscreen and windowed rendering modes. */ typedef m64p_error (*ptr_VidExt_ToggleFullScreen)(void); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL VidExt_ToggleFullScreen(void); #endif /* VidExt_GL_GetProcAddress() * * This function is used to get a pointer to an OpenGL extension function. This * is only necessary on the Windows platform, because the OpenGL implementation * shipped with Windows only supports OpenGL version 1.1. */ typedef void * (*ptr_VidExt_GL_GetProcAddress)(const char *); #if defined(M64P_CORE_PROTOTYPES) EXPORT void * CALL VidExt_GL_GetProcAddress(const char *); #endif /* VidExt_GL_SetAttribute() * * This function is used to set certain OpenGL attributes which must be * specified before creating the rendering window with VidExt_SetVideoMode. */ typedef m64p_error (*ptr_VidExt_GL_SetAttribute)(m64p_GLattr, int); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL VidExt_GL_SetAttribute(m64p_GLattr, int); #endif /* VidExt_GL_GetAttribute() * * This function is used to get the value of OpenGL attributes. These values may * be changed when calling VidExt_SetVideoMode. */ typedef m64p_error (*ptr_VidExt_GL_GetAttribute)(m64p_GLattr, int *); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL VidExt_GL_GetAttribute(m64p_GLattr, int *); #endif /* VidExt_GL_SwapBuffers() * * This function is used to swap the front/back buffers after rendering an * output video frame. */ typedef m64p_error (*ptr_VidExt_GL_SwapBuffers)(void); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL VidExt_GL_SwapBuffers(void); #endif #ifdef __cplusplus } #endif #endif /* #define M64P_VIDEXT_H */ mupen64plus-video-gliden64/src/MupenPlusPluginAPI.cpp000664 001750 001750 00000002342 12655644434 023574 0ustar00sergiosergio000000 000000 #include "PluginAPI.h" #include "Types.h" extern "C" { EXPORT int CALL RomOpen(void) { api().RomOpen(); return 1; } EXPORT m64p_error CALL PluginGetVersion( m64p_plugin_type * _PluginType, int * _PluginVersion, int * _APIVersion, const char ** _PluginNamePtr, int * _Capabilities ) { return api().PluginGetVersion(_PluginType, _PluginVersion, _APIVersion, _PluginNamePtr, _Capabilities); } EXPORT m64p_error CALL PluginStartup( m64p_dynlib_handle CoreLibHandle, void *Context, void (*DebugCallback)(void *, int, const char *) ) { return api().PluginStartup(CoreLibHandle); } EXPORT m64p_error CALL PluginShutdown(void) { return api().PluginShutdown(); } EXPORT void CALL ReadScreen2(void *dest, int *width, int *height, int front) { api().ReadScreen2(dest, width, height, front); } EXPORT void CALL SetRenderingCallback(void (*callback)(int)) { api().SetRenderingCallback(callback); } EXPORT void CALL FBRead(u32 addr) { api().FBRead(addr); } EXPORT void CALL FBWrite(u32 addr, u32 size) { api().FBWrite(addr, size); } EXPORT void CALL FBGetFrameBufferInfo(void *p) { api().FBGetFrameBufferInfo(p); } EXPORT void CALL ResizeVideoOutput(int Width, int Height) { api().ResizeVideoOutput(Width, Height); } } // extern "C" mupen64plus-core/src/memory/m64p_memory.c000664 001750 001750 00000100243 12655644434 021470 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - memory.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "memory.h" #include "../api/m64p_types.h" #include "../api/callbacks.h" #include "../main/main.h" #include "../main/rom.h" #include "../r4300/new_dynarec/new_dynarec.h" #include "../r4300/r4300_core.h" #include "../rdp/rdp_core.h" #include "../rsp/rsp_core.h" #include "../ai/ai_controller.h" #include "../pi/pi_controller.h" #include "../ri/ri_controller.h" #include "../si/si_controller.h" #include "../vi/vi_controller.h" #include "../dd/dd_controller.h" #ifdef DBG #include "../debugger/dbg_types.h" #include "../debugger/dbg_memory.h" #include "../debugger/dbg_breakpoints.h" #include #endif #include #include extern int fast_memory; #if NEW_DYNAREC != NEW_DYNAREC_ARM // address : address of the read/write operation being done uint32_t address = 0; #endif // values that are being written are stored in these variables #if NEW_DYNAREC != NEW_DYNAREC_ARM uint32_t word; uint8_t cpu_byte; uint16_t hword; uint64_t dword; #endif // address where the read value will be stored uint64_t* rdword; // hash tables of read functions void (*readmem[0x10000])(void); void (*readmemb[0x10000])(void); void (*readmemh[0x10000])(void); void (*readmemd[0x10000])(void); // hash tables of write functions void (*writemem[0x10000])(void); void (*writememb[0x10000])(void); void (*writememd[0x10000])(void); void (*writememh[0x10000])(void); uint32_t VI_REFRESH = 1500; typedef int (*readfn)(void*,uint32_t,uint32_t*); typedef int (*writefn)(void*,uint32_t,uint32_t,uint32_t); #ifndef BYTE4_XOR_BE #ifdef MSB_FIRST #define BYTE4_XOR_BE(a) (a) #else #define BYTE4_XOR_BE(a) ((a) ^ 3) #endif #endif #ifndef BSHIFT #define BSHIFT(a) (BYTE4_XOR_BE((a & 3)) << 3) #endif #ifndef HSHIFT #define HSHIFT(a) (((a & 2) ^ 2) << 3) #endif static int readb(readfn read_word, void* opaque, uint32_t address, uint64_t* value) { uint32_t w; unsigned shift = BSHIFT(address); int result = read_word(opaque, address, &w); *value = (w >> shift) & 0xff; return result; } static int readh(readfn read_word, void* opaque, uint32_t address, uint64_t* value) { uint32_t w; unsigned shift = HSHIFT(address); int result = read_word(opaque, address, &w); *value = (w >> shift) & 0xffff; return result; } static int readw(readfn read_word, void* opaque, uint32_t address, uint64_t* value) { uint32_t w; int result = read_word(opaque, address, &w); *value = w; return result; } static int readd(readfn read_word, void* opaque, uint32_t address, uint64_t* value) { uint32_t w[2]; int result = read_word(opaque, address , &w[0]); read_word(opaque, address + 4, &w[1]); *value = ((uint64_t)w[0] << 32) | w[1]; return result; } static int writeb(writefn write_word, void *opaque, uint32_t address, uint8_t value) { unsigned int shift = BSHIFT(address); uint32_t w = (uint32_t)value << shift; uint32_t mask = (uint32_t)0xff << shift; return write_word(opaque, address, w, mask); } static int writeh(writefn write_word, void *opaque, uint32_t address, uint16_t value) { unsigned int shift = HSHIFT(address); uint32_t w = (uint32_t)value << shift; uint32_t mask = (uint32_t)0xffff << shift; return write_word(opaque, address, w, mask); } static int writew(writefn write_word, void *opaque, uint32_t address, uint32_t value) { return write_word(opaque, address, value, ~0U); } static int writed(writefn write_word, void *opaque, uint32_t address, uint64_t value) { int result; const uint64_t doubleword = (uint64_t)value; const uint32_t word_hi = (uint32_t)(doubleword >> 32); const uint32_t word_lo = (uint32_t)(doubleword >> 0); result = write_word(opaque, address + 0, word_hi, ~0U); write_word (opaque, address + 4, word_lo, ~0U); return result; } static void read_nothing(void) { *rdword = 0; } static void read_nothingb(void) { *rdword = 0; } static void read_nothingh(void) { *rdword = 0; } static void read_nothingd(void) { *rdword = 0; } static void write_nothing(void) { } static void write_nothingb(void) { } static void write_nothingh(void) { } static void write_nothingd(void) { } static void read_nomem(void) { address = virtual_to_physical_address(address,0); if (address == 0x00000000) return; read_word_in_memory(); } static void read_nomemb(void) { address = virtual_to_physical_address(address,0); if (address == 0x00000000) return; read_byte_in_memory(); } static void read_nomemh(void) { address = virtual_to_physical_address(address,0); if (address == 0x00000000) return; read_hword_in_memory(); } static void read_nomemd(void) { address = virtual_to_physical_address(address,0); if (address == 0x00000000) return; read_dword_in_memory(); } static void write_nomem(void) { invalidate_r4300_cached_code(address, 4); address = virtual_to_physical_address(address,1); if (address == 0x00000000) return; write_word_in_memory(); } static void write_nomemb(void) { invalidate_r4300_cached_code(address, 1); address = virtual_to_physical_address(address,1); if (address == 0x00000000) return; write_byte_in_memory(); } static void write_nomemh(void) { invalidate_r4300_cached_code(address, 2); address = virtual_to_physical_address(address,1); if (address == 0x00000000) return; write_hword_in_memory(); } static void write_nomemd(void) { invalidate_r4300_cached_code(address, 8); address = virtual_to_physical_address(address,1); if (address == 0x00000000) return; write_dword_in_memory(); } void read_rdram(void) { readw(read_rdram_dram, &g_ri, address, rdword); } void read_rdramb(void) { readb(read_rdram_dram, &g_ri, address, rdword); } void read_rdramh(void) { readh(read_rdram_dram, &g_ri, address, rdword); } void read_rdramd(void) { readd(read_rdram_dram, &g_ri, address, rdword); } void write_rdram(void) { writew(write_rdram_dram, &g_ri, address, word); } void write_rdramb(void) { writeb(write_rdram_dram, &g_ri, address, cpu_byte); } void write_rdramh(void) { writeh(write_rdram_dram, &g_ri, address, hword); } void write_rdramd(void) { writed(write_rdram_dram, &g_ri, address, dword); } void read_rdramFB(void) { readw(read_rdram_fb, &g_dp, address, rdword); } void read_rdramFBb(void) { readb(read_rdram_fb, &g_dp, address, rdword); } void read_rdramFBh(void) { readh(read_rdram_fb, &g_dp, address, rdword); } void read_rdramFBd(void) { readd(read_rdram_fb, &g_dp, address, rdword); } void write_rdramFB(void) { writew(write_rdram_fb, &g_dp, address, word); } void write_rdramFBb(void) { writeb(write_rdram_fb, &g_dp, address, cpu_byte); } void write_rdramFBh(void) { writeh(write_rdram_fb, &g_dp, address, hword); } void write_rdramFBd(void) { writed(write_rdram_fb, &g_dp, address, dword); } static void read_rdramreg(void) { readw(read_rdram_regs, &g_ri, address, rdword); } static void read_rdramregb(void) { readb(read_rdram_regs, &g_ri, address, rdword); } static void read_rdramregh(void) { readh(read_rdram_regs, &g_ri, address, rdword); } static void read_rdramregd(void) { readd(read_rdram_regs, &g_ri, address, rdword); } static void write_rdramreg(void) { writew(write_rdram_regs, &g_ri, address, word); } static void write_rdramregb(void) { writeb(write_rdram_regs, &g_ri, address, cpu_byte); } static void write_rdramregh(void) { writeh(write_rdram_regs, &g_ri, address, hword); } static void write_rdramregd(void) { writed(write_rdram_regs, &g_ri, address, dword); } static void read_rspmem(void) { readw(read_rsp_mem, &g_sp, address, rdword); } static void read_rspmemb(void) { readb(read_rsp_mem, &g_sp, address, rdword); } static void read_rspmemh(void) { readh(read_rsp_mem, &g_sp, address, rdword); } static void read_rspmemd(void) { readd(read_rsp_mem, &g_sp, address, rdword); } static void write_rspmem(void) { writew(write_rsp_mem, &g_sp, address, word); } static void write_rspmemb(void) { writeb(write_rsp_mem, &g_sp, address, cpu_byte); } static void write_rspmemh(void) { writeh(write_rsp_mem, &g_sp, address, hword); } static void write_rspmemd(void) { writed(write_rsp_mem, &g_sp, address, dword); } static void read_rspreg(void) { readw(read_rsp_regs, &g_sp, address, rdword); } static void read_rspregb(void) { readb(read_rsp_regs, &g_sp, address, rdword); } static void read_rspregh(void) { readh(read_rsp_regs, &g_sp, address, rdword); } static void read_rspregd(void) { readd(read_rsp_regs, &g_sp, address, rdword); } static void write_rspreg(void) { writew(write_rsp_regs, &g_sp, address, word); } static void write_rspregb(void) { writeb(write_rsp_regs, &g_sp, address, cpu_byte); } static void write_rspregh(void) { writeh(write_rsp_regs, &g_sp, address, hword); } static void write_rspregd(void) { writed(write_rsp_regs, &g_sp, address, dword); } static void read_rspreg2(void) { readw(read_rsp_regs2, &g_sp, address, rdword); } static void read_rspreg2b(void) { readb(read_rsp_regs2, &g_sp, address, rdword); } static void read_rspreg2h(void) { readh(read_rsp_regs2, &g_sp, address, rdword); } static void read_rspreg2d(void) { readd(read_rsp_regs2, &g_sp, address, rdword); } static void write_rspreg2(void) { writew(write_rsp_regs2, &g_sp, address, word); } static void write_rspreg2b(void) { writeb(write_rsp_regs2, &g_sp, address, cpu_byte); } static void write_rspreg2h(void) { writeh(write_rsp_regs2, &g_sp, address, hword); } static void write_rspreg2d(void) { writed(write_rsp_regs2, &g_sp, address, dword); } static void read_dp(void) { readw(read_dpc_regs, &g_dp, address, rdword); } static void read_dpb(void) { readb(read_dpc_regs, &g_dp, address, rdword); } static void read_dph(void) { readh(read_dpc_regs, &g_dp, address, rdword); } static void read_dpd(void) { readd(read_dpc_regs, &g_dp, address, rdword); } static void write_dp(void) { writew(write_dpc_regs, &g_dp, address, word); } static void write_dpb(void) { writeb(write_dpc_regs, &g_dp, address, cpu_byte); } static void write_dph(void) { writeh(write_dpc_regs, &g_dp, address, hword); } static void write_dpd(void) { writed(write_dpc_regs, &g_dp, address, dword); } static void read_dps(void) { readw(read_dps_regs, &g_dp, address, rdword); } static void read_dpsb(void) { readb(read_dps_regs, &g_dp, address, rdword); } static void read_dpsh(void) { readh(read_dps_regs, &g_dp, address, rdword); } static void read_dpsd(void) { readd(read_dps_regs, &g_dp, address, rdword); } static void write_dps(void) { writew(write_dps_regs, &g_dp, address, word); } static void write_dpsb(void) { writeb(write_dps_regs, &g_dp, address, cpu_byte); } static void write_dpsh(void) { writeh(write_dps_regs, &g_dp, address, hword); } static void write_dpsd(void) { writed(write_dps_regs, &g_dp, address, dword); } static void read_mi(void) { readw(read_mi_regs, &g_r4300, address, rdword); } static void read_mib(void) { readb(read_mi_regs, &g_r4300, address, rdword); } static void read_mih(void) { readh(read_mi_regs, &g_r4300, address, rdword); } static void read_mid(void) { readd(read_mi_regs, &g_r4300, address, rdword); } static void write_mi(void) { writew(write_mi_regs, &g_r4300, address, word); } static void write_mib(void) { writeb(write_mi_regs, &g_r4300, address, cpu_byte); } static void write_mih(void) { writeh(write_mi_regs, &g_r4300, address, hword); } static void write_mid(void) { writed(write_mi_regs, &g_r4300, address, dword); } static void read_vi(void) { readw(read_vi_regs, &g_vi, address, rdword); } static void read_vib(void) { readb(read_vi_regs, &g_vi, address, rdword); } static void read_vih(void) { readh(read_vi_regs, &g_vi, address, rdword); } static void read_vid(void) { readd(read_vi_regs, &g_vi, address, rdword); } static void write_vi(void) { writew(write_vi_regs, &g_vi, address, word); } static void write_vib(void) { writeb(write_vi_regs, &g_vi, address, cpu_byte); } static void write_vih(void) { writeh(write_vi_regs, &g_vi, address, hword); } static void write_vid(void) { writed(write_vi_regs, &g_vi, address, dword); } static void read_ai(void) { readw(read_ai_regs, &g_ai, address, rdword); } static void read_aib(void) { readb(read_ai_regs, &g_ai, address, rdword); } static void read_aih(void) { readh(read_ai_regs, &g_ai, address, rdword); } static void read_aid(void) { readd(read_ai_regs, &g_ai, address, rdword); } static void write_ai(void) { writew(write_ai_regs, &g_ai, address, word); } static void write_aib(void) { writeb(write_ai_regs, &g_ai, address, cpu_byte); } static void write_aih(void) { writeh(write_ai_regs, &g_ai, address, hword); } static void write_aid(void) { writed(write_ai_regs, &g_ai, address, dword); } static void read_pi(void) { readw(read_pi_regs, &g_pi, address, rdword); } static void read_pib(void) { readb(read_pi_regs, &g_pi, address, rdword); } static void read_pih(void) { readh(read_pi_regs, &g_pi, address, rdword); } static void read_pid(void) { readd(read_pi_regs, &g_pi, address, rdword); } static void write_pi(void) { writew(write_pi_regs, &g_pi, address, word); } static void write_pib(void) { writeb(write_pi_regs, &g_pi, address, cpu_byte); } static void write_pih(void) { writeh(write_pi_regs, &g_pi, address, hword); } static void write_pid(void) { writed(write_pi_regs, &g_pi, address, dword); } static void read_ri(void) { readw(read_ri_regs, &g_ri, address, rdword); } static void read_rib(void) { readb(read_ri_regs, &g_ri, address, rdword); } static void read_rih(void) { readh(read_ri_regs, &g_ri, address, rdword); } static void read_rid(void) { readd(read_ri_regs, &g_ri, address, rdword); } static void write_ri(void) { writew(write_ri_regs, &g_ri, address, word); } static void write_rib(void) { writeb(write_ri_regs, &g_ri, address, cpu_byte); } static void write_rih(void) { writeh(write_ri_regs, &g_ri, address, hword); } static void write_rid(void) { writed(write_ri_regs, &g_ri, address, dword); } static void read_si(void) { readw(read_si_regs, &g_si, address, rdword); } static void read_sib(void) { readb(read_si_regs, &g_si, address, rdword); } static void read_sih(void) { readh(read_si_regs, &g_si, address, rdword); } static void read_sid(void) { readd(read_si_regs, &g_si, address, rdword); } static void write_si(void) { writew(write_si_regs, &g_si, address, word); } static void write_sib(void) { writeb(write_si_regs, &g_si, address, cpu_byte); } static void write_sih(void) { writeh(write_si_regs, &g_si, address, hword); } static void write_sid(void) { writed(write_si_regs, &g_si, address, dword); } static void read_pi_flashram_status(void) { readw(read_flashram_status, &g_pi, address, rdword); } static void read_pi_flashram_statusb(void) { readb(read_flashram_status, &g_pi, address, rdword); } static void read_pi_flashram_statush(void) { readh(read_flashram_status, &g_pi, address, rdword); } static void read_pi_flashram_statusd(void) { readd(read_flashram_status, &g_pi, address, rdword); } static void write_pi_flashram_command(void) { writew(write_flashram_command, &g_pi, address, word); } static void write_pi_flashram_commandb(void) { writeb(write_flashram_command, &g_pi, address, cpu_byte); } static void write_pi_flashram_commandh(void) { writeh(write_flashram_command, &g_pi, address, hword); } static void write_pi_flashram_commandd(void) { writed(write_flashram_command, &g_pi, address, dword); } static void read_rom(void) { readw(read_cart_rom, &g_pi, address, rdword); } static void read_romb(void) { readb(read_cart_rom, &g_pi, address, rdword); } static void read_romh(void) { readh(read_cart_rom, &g_pi, address, rdword); } static void read_romd(void) { readd(read_cart_rom, &g_pi, address, rdword); } static void write_rom(void) { writew(write_cart_rom, &g_pi, address, word); } static void read_pif(void) { readw(read_pif_ram, &g_si, address, rdword); } static void read_pifb(void) { readb(read_pif_ram, &g_si, address, rdword); } static void read_pifh(void) { readh(read_pif_ram, &g_si, address, rdword); } static void read_pifd(void) { readd(read_pif_ram, &g_si, address, rdword); } static void write_pif(void) { writew(write_pif_ram, &g_si, address, word); } static void write_pifb(void) { writeb(write_pif_ram, &g_si, address, cpu_byte); } static void write_pifh(void) { writeh(write_pif_ram, &g_si, address, hword); } static void write_pifd(void) { writed(write_pif_ram, &g_si, address, dword); } static void read_dd(void) { readw(read_dd_regs, &g_dd, address, rdword); } static void read_ddb(void) { readb(read_dd_regs, &g_dd, address, rdword); } static void read_ddh(void) { readh(read_dd_regs, &g_dd, address, rdword); } static void read_ddd(void) { readd(read_dd_regs, &g_dd, address, rdword); } static void write_dd(void) { writew(write_dd_regs, &g_dd, address, word); } static void write_ddb(void) { writeb(write_dd_regs, &g_dd, address, cpu_byte); } static void write_ddh(void) { writeh(write_dd_regs, &g_dd, address, hword); } static void write_ddd(void) { writed(write_dd_regs, &g_dd, address, dword); } static void read_ddipl(void) { readw(read_dd_ipl, &g_pi, address, rdword); } static void read_ddiplb(void) { readb(read_dd_ipl, &g_pi, address, rdword); } static void read_ddiplh(void) { readh(read_dd_ipl, &g_pi, address, rdword); } static void read_ddipld(void) { readd(read_dd_ipl, &g_pi, address, rdword); } static void write_ddipl(void) { writew(write_dd_ipl, &g_pi, address, word); } #ifdef DBG static int memtype[0x10000]; static void (*saved_readmemb[0x10000])(void); static void (*saved_readmemh[0x10000])(void); static void (*saved_readmem [0x10000])(void); static void (*saved_readmemd[0x10000])(void); static void (*saved_writememb[0x10000])(void); static void (*saved_writememh[0x10000])(void); static void (*saved_writemem [0x10000])(void); static void (*saved_writememd[0x10000])(void); static void readmemb_with_bp_checks(void) { check_breakpoints_on_mem_access((*r4300_pc())-0x4, address, 1, M64P_BKP_FLAG_ENABLED | M64P_BKP_FLAG_READ); saved_readmemb[address>>16](); } static void readmemh_with_bp_checks(void) { check_breakpoints_on_mem_access((*r4300_pc())-0x4, address, 2, M64P_BKP_FLAG_ENABLED | M64P_BKP_FLAG_READ); saved_readmemh[address>>16](); } static void readmem_with_bp_checks(void) { check_breakpoints_on_mem_access((*r4300_pc())-0x4, address, 4, M64P_BKP_FLAG_ENABLED | M64P_BKP_FLAG_READ); saved_readmem[address>>16](); } static void readmemd_with_bp_checks(void) { check_breakpoints_on_mem_access((*r4300_pc())-0x4, address, 8, M64P_BKP_FLAG_ENABLED | M64P_BKP_FLAG_READ); saved_readmemd[address>>16](); } static void writememb_with_bp_checks(void) { check_breakpoints_on_mem_access((*r4300_pc())-0x4, address, 1, M64P_BKP_FLAG_ENABLED | M64P_BKP_FLAG_WRITE); return saved_writememb[address>>16](); } static void writememh_with_bp_checks(void) { check_breakpoints_on_mem_access((*r4300_pc())-0x4, address, 2, M64P_BKP_FLAG_ENABLED | M64P_BKP_FLAG_WRITE); return saved_writememh[address>>16](); } static void writemem_with_bp_checks(void) { check_breakpoints_on_mem_access((*r4300_pc())-0x4, address, 4, M64P_BKP_FLAG_ENABLED | M64P_BKP_FLAG_WRITE); return saved_writemem[address>>16](); } static void writememd_with_bp_checks(void) { check_breakpoints_on_mem_access((*r4300_pc())-0x4, address, 8, M64P_BKP_FLAG_ENABLED | M64P_BKP_FLAG_WRITE); return saved_writememd[address>>16](); } void activate_memory_break_read(uint32_t address) { uint16_t region = address >> 16; if (saved_readmem[region] != NULL) return; saved_readmemb[region] = readmemb[region]; saved_readmemh[region] = readmemh[region]; saved_readmem [region] = readmem [region]; saved_readmemd[region] = readmemd[region]; readmemb[region] = readmemb_with_bp_checks; readmemh[region] = readmemh_with_bp_checks; readmem [region] = readmem_with_bp_checks; readmemd[region] = readmemd_with_bp_checks; } void deactivate_memory_break_read(uint32_t address) { uint16_t region = address >> 16; if (saved_readmem[region] == NULL) return; readmemb[region] = saved_readmemb[region]; readmemh[region] = saved_readmemh[region]; readmem [region] = saved_readmem [region]; readmemd[region] = saved_readmemd[region]; saved_readmemb[region] = NULL; saved_readmemh[region] = NULL; saved_readmem [region] = NULL; saved_readmemd[region] = NULL; } void activate_memory_break_write(uint32_t address) { uint16_t region = address >> 16; if (saved_writemem[region] != NULL) return; saved_writememb[region] = writememb[region]; saved_writememh[region] = writememh[region]; saved_writemem [region] = writemem [region]; saved_writememd[region] = writememd[region]; writememb[region] = writememb_with_bp_checks; writememh[region] = writememh_with_bp_checks; writemem [region] = writemem_with_bp_checks; writememd[region] = writememd_with_bp_checks; } void deactivate_memory_break_write(uint32_t address) { uint16_t region = address >> 16; if (saved_writemem[region] == NULL) return; writememb[region] = saved_writememb[region]; writememh[region] = saved_writememh[region]; writemem [region] = saved_writemem [region]; writememd[region] = saved_writememd[region]; saved_writememb[region] = NULL; saved_writememh[region] = NULL; saved_writemem [region] = NULL; saved_writememd[region] = NULL; } int get_memory_type(uint32_t address) { return memtype[address >> 16]; } #endif #define R(x) read_ ## x ## b, read_ ## x ## h, read_ ## x, read_ ## x ## d #define W(x) write_ ## x ## b, write_ ## x ## h, write_ ## x, write_ ## x ## d #define RW(x) R(x), W(x) int init_memory(void) { int i; #ifdef DBG memset(saved_readmem, 0, 0x10000*sizeof(saved_readmem[0])); memset(saved_writemem, 0, 0x10000*sizeof(saved_writemem[0])); #endif /* clear mappings */ for (i = 0; i < 0x10000; ++i) { map_region(i, M64P_MEM_NOMEM, RW(nomem)); } /* map RDRAM */ for (i = 0; i< 0x80; ++i) { map_region(0x8000+i, M64P_MEM_RDRAM, RW(rdram)); map_region(0xa000+i, M64P_MEM_RDRAM, RW(rdram)); } for(i = 0x80; i < 0x3f0; ++i) { map_region(0x8000+i, M64P_MEM_NOTHING, RW(nothing)); map_region(0xa000+i, M64P_MEM_NOTHING, RW(nothing)); } /* map RDRAM registers */ map_region(0x83f0, M64P_MEM_RDRAMREG, RW(rdramreg)); map_region(0xa3f0, M64P_MEM_RDRAMREG, RW(rdramreg)); for(i = 1; i < 0x10; ++i) { map_region(0x83f0+i, M64P_MEM_NOTHING, RW(nothing)); map_region(0xa3f0+i, M64P_MEM_NOTHING, RW(nothing)); } /* map RSP memory */ map_region(0x8400, M64P_MEM_RSPMEM, RW(rspmem)); map_region(0xa400, M64P_MEM_RSPMEM, RW(rspmem)); for (i=0x1; i<0x4; i++) { map_region(0x8400+i, M64P_MEM_NOTHING, RW(nothing)); map_region(0xa400+i, M64P_MEM_NOTHING, RW(nothing)); } /* map RSP registers (1) */ map_region(0x8404, M64P_MEM_RSPREG, RW(rspreg)); map_region(0xa404, M64P_MEM_RSPREG, RW(rspreg)); for (i=0x5; i<0x8; i++) { map_region(0x8400+i, M64P_MEM_NOTHING, RW(nothing)); map_region(0xa400+i, M64P_MEM_NOTHING, RW(nothing)); } /* map RSP registers (2) */ map_region(0x8408, M64P_MEM_RSP, RW(rspreg2)); map_region(0xa408, M64P_MEM_RSP, RW(rspreg2)); for(i = 0x9; i < 0x10; ++i) { map_region(0x8400+i, M64P_MEM_NOTHING, RW(nothing)); map_region(0xa400+i, M64P_MEM_NOTHING, RW(nothing)); } /* map DPC registers */ map_region(0x8410, M64P_MEM_DP, RW(dp)); map_region(0xa410, M64P_MEM_DP, RW(dp)); for(i = 1; i < 0x10; ++i) { map_region(0x8410+i, M64P_MEM_NOTHING, RW(nothing)); map_region(0xa410+i, M64P_MEM_NOTHING, RW(nothing)); } map_region(0x8420, M64P_MEM_DPS, RW(dps)); map_region(0xa420, M64P_MEM_DPS, RW(dps)); for(i = 1; i < 0x10; ++i) { map_region(0x8420+i, M64P_MEM_NOTHING, RW(nothing)); map_region(0xa420+i, M64P_MEM_NOTHING, RW(nothing)); } /* map MI registers */ map_region(0x8430, M64P_MEM_MI, RW(mi)); map_region(0xa430, M64P_MEM_MI, RW(mi)); for(i = 1; i < 0x10; ++i) { map_region(0x8430+i, M64P_MEM_NOTHING, RW(nothing)); map_region(0xa430+i, M64P_MEM_NOTHING, RW(nothing)); } /* map VI registers */ map_region(0x8440, M64P_MEM_VI, RW(vi)); map_region(0xa440, M64P_MEM_VI, RW(vi)); for(i = 1; i < 0x10; ++i) { map_region(0x8440+i, M64P_MEM_NOTHING, RW(nothing)); map_region(0xa440+i, M64P_MEM_NOTHING, RW(nothing)); } /* map AI registers */ map_region(0x8450, M64P_MEM_AI, RW(ai)); map_region(0xa450, M64P_MEM_AI, RW(ai)); for(i = 1; i < 0x10; ++i) { map_region(0x8450+i, M64P_MEM_NOTHING, RW(nothing)); map_region(0xa450+i, M64P_MEM_NOTHING, RW(nothing)); } /* map PI registers */ map_region(0x8460, M64P_MEM_PI, RW(pi)); map_region(0xa460, M64P_MEM_PI, RW(pi)); for(i = 1; i < 0x10; ++i) { map_region(0x8460+i, M64P_MEM_NOTHING, RW(nothing)); map_region(0xa460+i, M64P_MEM_NOTHING, RW(nothing)); } /* map RI registers */ map_region(0x8470, M64P_MEM_RI, RW(ri)); map_region(0xa470, M64P_MEM_RI, RW(ri)); for(i = 1; i < 0x10; ++i) { map_region(0x8470+i, M64P_MEM_NOTHING, RW(nothing)); map_region(0xa470+i, M64P_MEM_NOTHING, RW(nothing)); } /* map SI registers */ map_region(0x8480, M64P_MEM_SI, RW(si)); map_region(0xa480, M64P_MEM_SI, RW(si)); for(i = 0x481; i < 0x500; ++i) { map_region(0x8000+i, M64P_MEM_NOTHING, RW(nothing)); map_region(0xa000+i, M64P_MEM_NOTHING, RW(nothing)); } /* map DD registers */ map_region(0x8500, M64P_MEM_DD, RW(dd)); map_region(0xa500, M64P_MEM_DD, RW(dd)); for(i = 0x501; i < 0x600; ++i) { map_region(0x8000+i, M64P_MEM_NOTHING, RW(nothing)); map_region(0xa000+i, M64P_MEM_NOTHING, RW(nothing)); } /* map DD IPL ROM */ for (i = 0x600; i < 0x640; ++i) { map_region(0x8000 + i, M64P_MEM_DD, R(ddipl), W(nothing)); map_region(0xa000 + i, M64P_MEM_DD, R(ddipl), W(nothing)); } for (i = 0x640; i < 0x800; ++i) { map_region(0x8000 + i, M64P_MEM_NOTHING, RW(nothing)); map_region(0xa000 + i, M64P_MEM_NOTHING, RW(nothing)); } /* map flashram/sram */ map_region(0x8800, M64P_MEM_FLASHRAMSTAT, R(pi_flashram_status), W(nothing)); map_region(0xa800, M64P_MEM_FLASHRAMSTAT, R(pi_flashram_status), W(nothing)); map_region(0x8801, M64P_MEM_NOTHING, R(nothing), W(pi_flashram_command)); map_region(0xa801, M64P_MEM_NOTHING, R(nothing), W(pi_flashram_command)); for(i = 0x802; i < 0x1000; ++i) { map_region(0x8000+i, M64P_MEM_NOTHING, RW(nothing)); map_region(0xa000+i, M64P_MEM_NOTHING, RW(nothing)); } /* map cart ROM */ for(i = 0; i < (g_rom_size >> 16); ++i) { map_region(0x9000+i, M64P_MEM_ROM, R(rom), W(nothing)); map_region(0xb000+i, M64P_MEM_ROM, R(rom), write_nothingb, write_nothingh, write_rom, write_nothingd); } for(i = (g_rom_size >> 16); i < 0xfc0; ++i) { map_region(0x9000+i, M64P_MEM_NOTHING, RW(nothing)); map_region(0xb000+i, M64P_MEM_NOTHING, RW(nothing)); } /* map PIF RAM */ map_region(0x9fc0, M64P_MEM_PIF, RW(pif)); map_region(0xbfc0, M64P_MEM_PIF, RW(pif)); for(i = 0xfc1; i < 0x1000; ++i) { map_region(0x9000+i, M64P_MEM_NOTHING, RW(nothing)); map_region(0xb000+i, M64P_MEM_NOTHING, RW(nothing)); } fast_memory = 1; init_cic_using_ipl3(&g_si.pif.cic, g_rom + 0x40); init_r4300(&g_r4300); init_rdp(&g_dp); init_rsp(&g_sp); init_ai(&g_ai); init_pi(&g_pi); init_ri(&g_ri); init_si(&g_si); init_vi(&g_vi); init_dd(&g_dd); DebugMessage(M64MSG_VERBOSE, "Memory initialized"); return 0; } static void map_region_t(uint16_t region, int type) { #ifdef DBG memtype[region] = type; #else (void)region; (void)type; #endif } static void map_region_r(uint16_t region, void (*read8)(void), void (*read16)(void), void (*read32)(void), void (*read64)(void)) { #ifdef DBG if (lookup_breakpoint(((uint32_t)region << 16), 0x10000, M64P_BKP_FLAG_ENABLED | M64P_BKP_FLAG_READ) != -1) { saved_readmemb[region] = read8; saved_readmemh[region] = read16; saved_readmem [region] = read32; saved_readmemd[region] = read64; readmemb[region] = readmemb_with_bp_checks; readmemh[region] = readmemh_with_bp_checks; readmem [region] = readmem_with_bp_checks; readmemd[region] = readmemd_with_bp_checks; } else #endif { readmemb[region] = read8; readmemh[region] = read16; readmem [region] = read32; readmemd[region] = read64; } } void map_region_w(uint16_t region, void (*write8)(void), void (*write16)(void), void (*write32)(void), void (*write64)(void)) { #ifdef DBG if (lookup_breakpoint(((uint32_t)region << 16), 0x10000, M64P_BKP_FLAG_ENABLED | M64P_BKP_FLAG_WRITE) != -1) { saved_writememb[region] = write8; saved_writememh[region] = write16; saved_writemem [region] = write32; saved_writememd[region] = write64; writememb[region] = writememb_with_bp_checks; writememh[region] = writememh_with_bp_checks; writemem [region] = writemem_with_bp_checks; writememd[region] = writememd_with_bp_checks; } else #endif { writememb[region] = write8; writememh[region] = write16; writemem [region] = write32; writememd[region] = write64; } } void map_region(uint16_t region, int type, void (*read8)(void), void (*read16)(void), void (*read32)(void), void (*read64)(void), void (*write8)(void), void (*write16)(void), void (*write32)(void), void (*write64)(void)) { map_region_t(region, type); map_region_r(region, read8, read16, read32, read64); map_region_w(region, write8, write16, write32, write64); } uint32_t *fast_mem_access(uint32_t address) { /* This code is performance critical, specially on pure interpreter mode. * Removing error checking saves some time, but the emulator may crash. */ if ((address & 0xc0000000) != 0x80000000) address = virtual_to_physical_address(address, 2); address &= UINT32_C(0x1ffffffc); if (address < RDRAM_MAX_SIZE) return (uint32_t*)((uint8_t*)g_rdram + address); else if (address >= UINT32_C(0x10000000)) return (uint32_t*)((uint8_t*)g_rom + address - UINT32_C(0x10000000)); else if ((address & UINT32_C(0xffffe000)) == UINT32_C(0x04000000)) return (uint32_t*)((uint8_t*)g_sp.mem + (address & UINT32_C(0x1ffc))); return NULL; } mupen64plus-core/src/main/savestates.h000664 001750 001750 00000004076 12655644434 021124 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - savestates.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2012 CasualJames * * Copyright (C) 2009 Olejl Tillin9 * * Copyright (C) 2008 Richard42 Tillin9 * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef __SAVESTAVES_H__ #define __SAVESTAVES_H__ typedef enum _savestates_job { savestates_job_nothing, savestates_job_load, savestates_job_save } savestates_job; int savestates_load_m64p(const unsigned char *data, size_t size); int savestates_save_m64p(unsigned char *data, size_t size); #endif /* __SAVESTAVES_H__ */ gles2n64/src/F3DPD.h000664 001750 001750 00000000254 12655644434 015024 0ustar00sergiosergio000000 000000 #ifndef F3DPD_H #define F3DPD_H #ifdef __cplusplus extern "C" { #endif #define F3DPD_VTXCOLORBASE 0x07 void F3DPD_Init(void); #ifdef __cplusplus } #endif #endif mupen64plus-core/src/r4300/cp1.c000664 001750 001750 00000014425 12655644434 017243 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - cp1.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include "new_dynarec/new_dynarec.h" #if NEW_DYNAREC != NEW_DYNAREC_ARM uint32_t FCR0, FCR31; float *reg_cop1_simple[32]; double *reg_cop1_double[32]; #else extern float *reg_cop1_simple[32]; extern double *reg_cop1_double[32]; extern uint32_t FCR0, FCR31; #endif int64_t reg_cop1_fgr_64[32]; /* This is the x86 version of the rounding mode contained in FCR31. * It should not really be here. Its size should also really be uint16_t, * because FLDCW (Floating-point LoaD Control Word) loads 16-bit control * words. However, x86/gcop1.c and x86-64/gcop1.c update this variable * using 32-bit stores. */ uint32_t rounding_mode = UINT32_C(0x33F); int64_t* r4300_cp1_regs(void) { return reg_cop1_fgr_64; } float** r4300_cp1_regs_simple(void) { return reg_cop1_simple; } double** r4300_cp1_regs_double(void) { return reg_cop1_double; } uint32_t* r4300_cp1_fcr0(void) { return &FCR0; } uint32_t *r4300_cp1_fcr31(void) { return &FCR31; } /* Refer to Figure 6-2 on page 155 and explanation on page B-11 of MIPS R4000 Microprocessor User's Manual (Second Edition) by Joe Heinrich. */ void shuffle_fpr_data(uint32_t oldStatus, uint32_t newStatus) { if ((newStatus & UINT32_C(0x04000000)) != (oldStatus & UINT32_C(0x04000000))) { int i; int32_t temp_fgr_32[32]; // pack or unpack the FGR register data if (newStatus & UINT32_C(0x04000000)) { // switching into 64-bit mode // retrieve 32 FPR values from packed 32-bit FGR registers for (i = 0; i < 32; i++) #ifdef MSB_FIRST temp_fgr_32[i] = *((int32_t*) ®_cop1_fgr_64[i>>1] + ((i & 1) ^ 1)); #else temp_fgr_32[i] = *((int32_t*) ®_cop1_fgr_64[i>>1] + ((i & 1))); #endif // unpack them into 32 64-bit registers, taking the high 32-bits from their temporary place in the upper 16 FGRs for (i = 0; i < 32; i++) { int32_t high32 = *((int32_t*) ®_cop1_fgr_64[(i>>1)+16] + (i & 1)); #ifdef MSB_FIRST *((int32_t*) ®_cop1_fgr_64[i] + 1) = temp_fgr_32[i]; *((int32_t*) ®_cop1_fgr_64[i] + (1^1)) = high32; #else *((int32_t*) ®_cop1_fgr_64[i]) = temp_fgr_32[i]; *((int32_t*) ®_cop1_fgr_64[i] + 1 ) = high32; #endif } } else { // switching into 32-bit mode // retrieve the high 32 bits from each 64-bit FGR register and store in temp array for (i = 0; i < 32; i++) { #ifdef MSB_FIRST temp_fgr_32[i] = *((int32_t*) ®_cop1_fgr_64[i]); #else temp_fgr_32[i] = *((int32_t*) ®_cop1_fgr_64[i] + 1); #endif } // take the low 32 bits from each register and pack them together into 64-bit pairs for (i = 0; i < 16; i++) { #ifdef MSB_FIRST uint32_t least32 = *((uint32_t*) ®_cop1_fgr_64[i*2] + 1); uint32_t most32 = *((uint32_t*) ®_cop1_fgr_64[i*2+1] + 1); #else uint32_t least32 = *((uint32_t*) ®_cop1_fgr_64[i*2]); uint32_t most32 = *((uint32_t*) ®_cop1_fgr_64[i*2+1]); #endif reg_cop1_fgr_64[i] = ((uint64_t) most32 << 32) | (uint64_t) least32; } // store the high bits in the upper 16 FGRs, which wont be accessible in 32-bit mode for (i = 0; i < 32; i++) { *((int32_t*) ®_cop1_fgr_64[(i>>1)+16] + (i & 1)) = temp_fgr_32[i]; } } } } void set_fpr_pointers(uint32_t newStatus) { int i; // update the FPR register pointers if (newStatus & UINT32_C(0x04000000)) { for (i = 0; i < 32; i++) { reg_cop1_double[i] = (double*) ®_cop1_fgr_64[i]; #ifdef MSB_FIRST reg_cop1_simple[i] = ((float*) ®_cop1_fgr_64[i]) + 1; #else reg_cop1_simple[i] = ((float*) ®_cop1_fgr_64[i]); #endif } } else { for (i = 0; i < 32; i++) { reg_cop1_double[i] = (double*) ®_cop1_fgr_64[i>>1]; #ifdef MSB_FIRST reg_cop1_simple[i] = ((float*) ®_cop1_fgr_64[i>>1]) + ((i & 1) ^ 1); #else reg_cop1_simple[i] = ((float*) ®_cop1_fgr_64[i>>1]) + ((i & 1)); #endif } } } /* XXX: This shouldn't really be here, but rounding_mode is used by the * Hacktarux JIT and updated by CTC1 and saved states. Figure out a better * place for this. */ void update_x86_rounding_mode(uint32_t FCR31) { switch (FCR31 & 3) { case 0: /* Round to nearest, or to even if equidistant */ rounding_mode = UINT32_C(0x33F); break; case 1: /* Truncate (toward 0) */ rounding_mode = UINT32_C(0xF3F); break; case 2: /* Round up (toward +Inf) */ rounding_mode = UINT32_C(0xB3F); break; case 3: /* Round down (toward -Inf) */ rounding_mode = UINT32_C(0x73F); break; } } glide2gl/src/Glide64/FBtoScreen.h000664 001750 001750 00000004565 12655644434 017552 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** // // Render N64 frame buffer to screen // Created by Gonetz, 2007 // //**************************************************************** #ifndef FBtoSCREEN_H #define FBtoSCREEN_H typedef struct { uint32_t addr; //color image address uint32_t size; uint32_t width; uint32_t height; uint32_t ul_x; uint32_t ul_y; uint32_t lr_x; uint32_t lr_y; uint32_t opaque; } FB_TO_SCREEN_INFO; bool DrawFrameBufferToScreen(FB_TO_SCREEN_INFO *fb_info); void DrawDepthBufferToScreen(FB_TO_SCREEN_INFO *fb_info); #endif // #ifndef FBtoSCREEN_H mupen64plus-video-gliden64/src/F3D.cpp000664 001750 001750 00000015125 12655644434 020512 0ustar00sergiosergio000000 000000 #include "GLideN64.h" #include "Debug.h" #include "F3D.h" #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gSP.h" #include "gDP.h" #include "GBI.h" void F3D_SPNoOp( u32 w0, u32 w1 ) { gSPNoOp(); } void F3D_Mtx( u32 w0, u32 w1 ) { if (_SHIFTR( w0, 0, 16 ) != 64) { #ifdef DEBUG DebugMsg( DEBUG_MEDIUM | DEBUG_HIGH | DEBUG_ERROR, "G_MTX: address = 0x%08X length = %i params = 0x%02X\n", w1, _SHIFTR( w0, 0, 16 ), _SHIFTR( w0, 16, 8 ) ); #endif return; } gSPMatrix( w1, _SHIFTR( w0, 16, 8 ) ); } void F3D_Reserved0( u32 w0, u32 w1 ) { #ifdef DEBUG DebugMsg( DEBUG_MEDIUM | DEBUG_IGNORED | DEBUG_UNKNOWN, "G_RESERVED0: w0=0x%08lX w1=0x%08lX\n", w0, w1 ); #endif } void F3D_MoveMem( u32 w0, u32 w1 ) { switch (_SHIFTR( w0, 16, 8 )) { case F3D_MV_VIEWPORT: gSPViewport( w1 ); break; case G_MV_MATRIX_1: gSPForceMatrix( w1 ); // force matrix takes four commands __RSP.PC[__RSP.PCi] += 24; break; case G_MV_L0: gSPLight( w1, LIGHT_1 ); break; case G_MV_L1: gSPLight( w1, LIGHT_2 ); break; case G_MV_L2: gSPLight( w1, LIGHT_3 ); break; case G_MV_L3: gSPLight( w1, LIGHT_4 ); break; case G_MV_L4: gSPLight( w1, LIGHT_5 ); break; case G_MV_L5: gSPLight( w1, LIGHT_6 ); break; case G_MV_L6: gSPLight( w1, LIGHT_7 ); break; case G_MV_L7: gSPLight( w1, LIGHT_8 ); break; case G_MV_LOOKATX: gSPLookAt(w1, 0); break; case G_MV_LOOKATY: gSPLookAt(w1, 1); break; } } void F3D_Vtx( u32 w0, u32 w1 ) { gSPVertex( w1, _SHIFTR( w0, 20, 4 ) + 1, _SHIFTR( w0, 16, 4 ) ); } void F3D_Reserved1( u32 w0, u32 w1 ) { } void F3D_DList( u32 w0, u32 w1 ) { switch (_SHIFTR( w0, 16, 8 )) { case G_DL_PUSH: gSPDisplayList( w1 ); break; case G_DL_NOPUSH: gSPBranchList( w1 ); break; } } void F3D_Reserved2( u32 w0, u32 w1 ) { } void F3D_Reserved3( u32 w0, u32 w1 ) { } void F3D_Sprite2D_Base( u32 w0, u32 w1 ) { gSPSprite2DBase( w1 ); } void F3D_Tri1( u32 w0, u32 w1 ) { gSP1Triangle( _SHIFTR( w1, 16, 8 ) / 10, _SHIFTR( w1, 8, 8 ) / 10, _SHIFTR( w1, 0, 8 ) / 10); } void F3D_CullDL( u32 w0, u32 w1 ) { gSPCullDisplayList( _SHIFTR( w0, 0, 24 ) / 40, (w1 / 40) - 1 ); } void F3D_PopMtx( u32 w0, u32 w1 ) { gSPPopMatrix( w1 ); } void F3D_MoveWord( u32 w0, u32 w1 ) { switch (_SHIFTR( w0, 0, 8 )) { case G_MW_MATRIX: gSPInsertMatrix( _SHIFTR( w0, 8, 16 ), w1 ); break; case G_MW_NUMLIGHT: gSPNumLights( ((w1 - 0x80000000) >> 5) - 1 ); break; case G_MW_CLIP: gSPClipRatio( w1 ); break; case G_MW_SEGMENT: gSPSegment( _SHIFTR( w0, 10, 4 ), w1 & 0x00FFFFFF ); break; case G_MW_FOG: gSPFogFactor( (s16)_SHIFTR( w1, 16, 16 ), (s16)_SHIFTR( w1, 0, 16 ) ); break; case G_MW_LIGHTCOL: switch (_SHIFTR( w0, 8, 16 )) { case F3D_MWO_aLIGHT_1: gSPLightColor( LIGHT_1, w1 ); break; case F3D_MWO_aLIGHT_2: gSPLightColor( LIGHT_2, w1 ); break; case F3D_MWO_aLIGHT_3: gSPLightColor( LIGHT_3, w1 ); break; case F3D_MWO_aLIGHT_4: gSPLightColor( LIGHT_4, w1 ); break; case F3D_MWO_aLIGHT_5: gSPLightColor( LIGHT_5, w1 ); break; case F3D_MWO_aLIGHT_6: gSPLightColor( LIGHT_6, w1 ); break; case F3D_MWO_aLIGHT_7: gSPLightColor( LIGHT_7, w1 ); break; case F3D_MWO_aLIGHT_8: gSPLightColor( LIGHT_8, w1 ); break; } break; case G_MW_POINTS: { const u32 val = _SHIFTR(w0, 8, 16); gSPModifyVertex(val / 40, val % 40, w1); } break; case G_MW_PERSPNORM: gSPPerspNormalize( w1 ); break; } } void F3D_Texture( u32 w0, u32 w1 ) { gSPTexture( _FIXED2FLOAT( _SHIFTR( w1, 16, 16 ), 16 ), _FIXED2FLOAT( _SHIFTR( w1, 0, 16 ), 16 ), _SHIFTR( w0, 11, 3 ), _SHIFTR( w0, 8, 3 ), _SHIFTR( w0, 0, 8 ) ); } void F3D_SetOtherMode_H( u32 w0, u32 w1 ) { const u32 length = _SHIFTR(w0, 0, 8); const u32 shift = _SHIFTR(w0, 8, 8); gSPSetOtherMode_H(length, shift, w1); } void F3D_SetOtherMode_L( u32 w0, u32 w1 ) { const u32 length = _SHIFTR(w0, 0, 8); const u32 shift = _SHIFTR(w0, 8, 8); gSPSetOtherMode_L(length, shift, w1); } void F3D_EndDL( u32 w0, u32 w1 ) { gSPEndDisplayList(); } void F3D_SetGeometryMode( u32 w0, u32 w1 ) { gSPSetGeometryMode( w1 ); } void F3D_ClearGeometryMode( u32 w0, u32 w1 ) { gSPClearGeometryMode( w1 ); } void F3D_Quad( u32 w0, u32 w1 ) { gSP1Quadrangle( _SHIFTR( w1, 24, 8 ) / 10, _SHIFTR( w1, 16, 8 ) / 10, _SHIFTR( w1, 8, 8 ) / 10, _SHIFTR( w1, 0, 8 ) / 10 ); } void F3D_RDPHalf_1( u32 w0, u32 w1 ) { gDP.half_1 = w1; RDP_Half_1(w1); } void F3D_RDPHalf_2( u32 w0, u32 w1 ) { gDP.half_2 = w1; } void F3D_RDPHalf_Cont( u32 w0, u32 w1 ) { } void F3D_Tri4( u32 w0, u32 w1 ) { gSP4Triangles( _SHIFTR( w1, 28, 4 ), _SHIFTR( w0, 12, 4 ), _SHIFTR( w1, 24, 4 ), _SHIFTR( w1, 20, 4 ), _SHIFTR( w0, 8, 4 ), _SHIFTR( w1, 16, 4 ), _SHIFTR( w1, 12, 4 ), _SHIFTR( w0, 4, 4 ), _SHIFTR( w1, 8, 4 ), _SHIFTR( w1, 4, 4 ), _SHIFTR( w0, 0, 4 ), _SHIFTR( w1, 0, 4 ) ); } void F3D_Init() { gSPSetupFunctions(); // Set GeometryMode flags GBI_InitFlags( F3D ); GBI.PCStackSize = 10; // GBI Command Command Value Command Function GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_MTX, F3D_MTX, F3D_Mtx ); GBI_SetGBI( G_RESERVED0, F3D_RESERVED0, F3D_Reserved0 ); GBI_SetGBI( G_MOVEMEM, F3D_MOVEMEM, F3D_MoveMem ); GBI_SetGBI( G_VTX, F3D_VTX, F3D_Vtx ); GBI_SetGBI( G_RESERVED1, F3D_RESERVED1, F3D_Reserved1 ); GBI_SetGBI( G_DL, F3D_DL, F3D_DList ); GBI_SetGBI( G_RESERVED2, F3D_RESERVED2, F3D_Reserved2 ); GBI_SetGBI( G_RESERVED3, F3D_RESERVED3, F3D_Reserved3 ); GBI_SetGBI( G_SPRITE2D_BASE, F3D_SPRITE2D_BASE, F3D_Sprite2D_Base ); GBI_SetGBI( G_TRI1, F3D_TRI1, F3D_Tri1 ); GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3D_CullDL ); GBI_SetGBI( G_POPMTX, F3D_POPMTX, F3D_PopMtx ); GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3D_MoveWord ); GBI_SetGBI( G_TEXTURE, F3D_TEXTURE, F3D_Texture ); GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L ); GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL ); GBI_SetGBI( G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, F3D_SetGeometryMode ); GBI_SetGBI( G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE, F3D_ClearGeometryMode ); GBI_SetGBI( G_QUAD, F3D_QUAD, F3D_Quad ); GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_RDPHALF_CONT, F3D_RDPHALF_CONT, F3D_RDPHalf_Cont ); GBI_SetGBI( G_TRI4, F3D_TRI4, F3D_Tri4 ); } mupen64plus-core/src/main/savestates.c000664 001750 001750 00000056653 12655644434 021127 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - savestates.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2012 CasualJames * * Copyright (C) 2009 Olejl Tillin9 * * Copyright (C) 2008 Richard42 Tillin9 * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #define M64P_CORE_PROTOTYPES 1 #include "api/m64p_types.h" #include "api/callbacks.h" #include "api/m64p_config.h" #include "api/config.h" #include "savestates.h" #include "main.h" #include "rom.h" #include "util.h" #include "../ai/ai_controller.h" #include "../memory/memory.h" #include "../r4300/cp1.h" #include "../pi/pi_controller.h" #include "../plugin/plugin.h" #include "../r4300/r4300_core.h" #include "../rdp/rdp_core.h" #include "../ri/ri_controller.h" #include "../rsp/rsp_core.h" #include "../si/si_controller.h" #include "../vi/vi_controller.h" #include "osal/preproc.h" static const char* savestate_magic = "M64+SAVE"; static const int savestate_latest_version = 0x00010000; /* 1.0 */ #define GETARRAY(buff, type, count) \ (to_little_endian_buffer(buff, sizeof(type),count), \ buff += count*sizeof(type), \ (type *)(buff-count*sizeof(type))) #define COPYARRAY(dst, buff, type, count) \ memcpy(dst, GETARRAY(buff, type, count), sizeof(type)*count) #define GETDATA(buff, type) *GETARRAY(buff, type, 1) #define PUTARRAY(src, buff, type, count) \ memcpy(buff, src, sizeof(type)*count); \ to_little_endian_buffer(buff, sizeof(type), count); \ buff += count*sizeof(type); #define PUTDATA(buff, type, value) \ do { type x = value; PUTARRAY(&x, buff, type, 1); } while(0) int savestates_load_m64p(const unsigned char *data, size_t size) { char queue[1024]; int version; int i; uint32_t FCR31; uint32_t* cp0_regs = r4300_cp0_regs(); unsigned char *curr = (unsigned char*)data; // < HACK /* Read and check Mupen64Plus magic number. */ if(strncmp((char *)curr, savestate_magic, 8)!=0) return 0; curr += 8; version = *curr++; version = (version << 8) | *curr++; version = (version << 8) | *curr++; version = (version << 8) | *curr++; if(version != 0x00010000) return 0; if(memcmp((char *)curr, ROM_SETTINGS.MD5, 32)) return 0; curr += 32; /* Parse savestate */ g_ri.rdram.regs[RDRAM_CONFIG_REG] = GETDATA(curr, uint32_t); g_ri.rdram.regs[RDRAM_DEVICE_ID_REG] = GETDATA(curr, uint32_t); g_ri.rdram.regs[RDRAM_DELAY_REG] = GETDATA(curr, uint32_t); g_ri.rdram.regs[RDRAM_MODE_REG] = GETDATA(curr, uint32_t); g_ri.rdram.regs[RDRAM_REF_INTERVAL_REG] = GETDATA(curr, uint32_t); g_ri.rdram.regs[RDRAM_REF_ROW_REG] = GETDATA(curr, uint32_t); g_ri.rdram.regs[RDRAM_RAS_INTERVAL_REG] = GETDATA(curr, uint32_t); g_ri.rdram.regs[RDRAM_MIN_INTERVAL_REG] = GETDATA(curr, uint32_t); g_ri.rdram.regs[RDRAM_ADDR_SELECT_REG] = GETDATA(curr, uint32_t); g_ri.rdram.regs[RDRAM_DEVICE_MANUF_REG] = GETDATA(curr, uint32_t); curr += 4; /* Padding from old implementation */ g_r4300.mi.regs[MI_INIT_MODE_REG] = GETDATA(curr, uint32_t); curr += 4; // Duplicate MI init mode flags from old implementation g_r4300.mi.regs[MI_VERSION_REG] = GETDATA(curr, uint32_t); g_r4300.mi.regs[MI_INTR_REG] = GETDATA(curr, uint32_t); g_r4300.mi.regs[MI_INTR_MASK_REG] = GETDATA(curr, uint32_t); curr += 4; /* Padding from old implementation. */ curr += 8; // Duplicated MI intr flags and padding from old implementation g_pi.regs[PI_DRAM_ADDR_REG] = GETDATA(curr, uint32_t); g_pi.regs[PI_CART_ADDR_REG] = GETDATA(curr, uint32_t); g_pi.regs[PI_RD_LEN_REG] = GETDATA(curr, uint32_t); g_pi.regs[PI_WR_LEN_REG] = GETDATA(curr, uint32_t); g_pi.regs[PI_STATUS_REG] = GETDATA(curr, uint32_t); g_pi.regs[PI_BSD_DOM1_LAT_REG] = GETDATA(curr, uint32_t); g_pi.regs[PI_BSD_DOM1_PWD_REG] = GETDATA(curr, uint32_t); g_pi.regs[PI_BSD_DOM1_PGS_REG] = GETDATA(curr, uint32_t); g_pi.regs[PI_BSD_DOM1_RLS_REG] = GETDATA(curr, uint32_t); g_pi.regs[PI_BSD_DOM2_LAT_REG] = GETDATA(curr, uint32_t); g_pi.regs[PI_BSD_DOM2_PWD_REG] = GETDATA(curr, uint32_t); g_pi.regs[PI_BSD_DOM2_PGS_REG] = GETDATA(curr, uint32_t); g_pi.regs[PI_BSD_DOM2_RLS_REG] = GETDATA(curr, uint32_t); g_sp.regs[SP_MEM_ADDR_REG] = GETDATA(curr, uint32_t); g_sp.regs[SP_DRAM_ADDR_REG] = GETDATA(curr, uint32_t); g_sp.regs[SP_RD_LEN_REG] = GETDATA(curr, uint32_t); g_sp.regs[SP_WR_LEN_REG] = GETDATA(curr, uint32_t); curr += 4; /* Padding from old implementation. */ g_sp.regs[SP_STATUS_REG] = GETDATA(curr, uint32_t); curr += 16; // Duplicated SP flags and padding from old implementation g_sp.regs[SP_DMA_FULL_REG] = GETDATA(curr, uint32_t); g_sp.regs[SP_DMA_BUSY_REG] = GETDATA(curr, uint32_t); g_sp.regs[SP_SEMAPHORE_REG] = GETDATA(curr, uint32_t); g_sp.regs2[SP_PC_REG] = GETDATA(curr, uint32_t); g_sp.regs2[SP_IBIST_REG] = GETDATA(curr, uint32_t); g_si.regs[SI_DRAM_ADDR_REG] = GETDATA(curr, uint32_t); g_si.regs[SI_PIF_ADDR_RD64B_REG] = GETDATA(curr, uint32_t); g_si.regs[SI_PIF_ADDR_WR64B_REG] = GETDATA(curr, uint32_t); g_si.regs[SI_STATUS_REG] = GETDATA(curr, uint32_t); g_vi.regs[VI_STATUS_REG] = GETDATA(curr, uint32_t); g_vi.regs[VI_ORIGIN_REG] = GETDATA(curr, uint32_t); g_vi.regs[VI_WIDTH_REG] = GETDATA(curr, uint32_t); g_vi.regs[VI_V_INTR_REG] = GETDATA(curr, uint32_t); g_vi.regs[VI_CURRENT_REG] = GETDATA(curr, uint32_t); g_vi.regs[VI_BURST_REG] = GETDATA(curr, uint32_t); g_vi.regs[VI_V_SYNC_REG] = GETDATA(curr, uint32_t); g_vi.regs[VI_H_SYNC_REG] = GETDATA(curr, uint32_t); g_vi.regs[VI_LEAP_REG] = GETDATA(curr, uint32_t); g_vi.regs[VI_H_START_REG] = GETDATA(curr, uint32_t); g_vi.regs[VI_V_START_REG] = GETDATA(curr, uint32_t); g_vi.regs[VI_V_BURST_REG] = GETDATA(curr, uint32_t); g_vi.regs[VI_X_SCALE_REG] = GETDATA(curr, uint32_t); g_vi.regs[VI_Y_SCALE_REG] = GETDATA(curr, uint32_t); g_vi.delay = GETDATA(curr, unsigned int); gfx.viStatusChanged(); gfx.viWidthChanged(); g_ri.regs[RI_MODE_REG] = GETDATA(curr, uint32_t); g_ri.regs[RI_CONFIG_REG] = GETDATA(curr, uint32_t); g_ri.regs[RI_CURRENT_LOAD_REG] = GETDATA(curr, uint32_t); g_ri.regs[RI_SELECT_REG] = GETDATA(curr, uint32_t); g_ri.regs[RI_REFRESH_REG] = GETDATA(curr, uint32_t); g_ri.regs[RI_LATENCY_REG] = GETDATA(curr, uint32_t); g_ri.regs[RI_ERROR_REG] = GETDATA(curr, uint32_t); g_ri.regs[RI_WERROR_REG] = GETDATA(curr, uint32_t); g_ai.regs[AI_DRAM_ADDR_REG] = GETDATA(curr, uint32_t); g_ai.regs[AI_LEN_REG] = GETDATA(curr, uint32_t); g_ai.regs[AI_CONTROL_REG] = GETDATA(curr, uint32_t); g_ai.regs[AI_STATUS_REG] = GETDATA(curr, uint32_t); g_ai.regs[AI_DACRATE_REG] = GETDATA(curr, uint32_t); g_ai.regs[AI_BITRATE_REG] = GETDATA(curr, uint32_t); g_ai.fifo[1].duration = GETDATA(curr, unsigned int); g_ai.fifo[1].length = GETDATA(curr, uint32_t); g_ai.fifo[0].duration = GETDATA(curr, unsigned int); g_ai.fifo[0].length = GETDATA(curr, uint32_t); /* best effort initialization of fifo addresses... * You might get a small sound "pop" because address might be wrong. * Proper initialization requires changes to savestate format */ g_ai.fifo[0].address = g_ai.regs[AI_DRAM_ADDR_REG]; g_ai.fifo[1].address = g_ai.regs[AI_DRAM_ADDR_REG]; g_ai.samples_format_changed = 1; g_dp.dpc_regs[DPC_START_REG] = GETDATA(curr, uint32_t); g_dp.dpc_regs[DPC_END_REG] = GETDATA(curr, uint32_t); g_dp.dpc_regs[DPC_CURRENT_REG] = GETDATA(curr, uint32_t); curr += 4; /* Padding from old implementation. */ g_dp.dpc_regs[DPC_STATUS_REG] = GETDATA(curr, uint32_t); curr += 12; // Duplicated DPC flags and padding from old implementation g_dp.dpc_regs[DPC_CLOCK_REG] = GETDATA(curr, uint32_t); g_dp.dpc_regs[DPC_BUFBUSY_REG] = GETDATA(curr, uint32_t); g_dp.dpc_regs[DPC_PIPEBUSY_REG] = GETDATA(curr, uint32_t); g_dp.dpc_regs[DPC_TMEM_REG] = GETDATA(curr, uint32_t); g_dp.dps_regs[DPS_TBIST_REG] = GETDATA(curr, uint32_t); g_dp.dps_regs[DPS_TEST_MODE_REG] = GETDATA(curr, uint32_t); g_dp.dps_regs[DPS_BUFTEST_ADDR_REG] = GETDATA(curr, uint32_t); g_dp.dps_regs[DPS_BUFTEST_DATA_REG] = GETDATA(curr, uint32_t); COPYARRAY(g_rdram, curr, uint32_t, RDRAM_MAX_SIZE/4); COPYARRAY(g_sp.mem, curr, uint32_t, SP_MEM_SIZE/4); COPYARRAY(g_si.pif.ram, curr, uint8_t, PIF_RAM_SIZE); g_pi.use_flashram = GETDATA(curr, int); g_pi.flashram.mode = GETDATA(curr, int); g_pi.flashram.status = GETDATA(curr, unsigned long long); g_pi.flashram.erase_offset = GETDATA(curr, unsigned int); g_pi.flashram.write_pointer = GETDATA(curr, unsigned int); COPYARRAY(tlb_LUT_r, curr, unsigned int, 0x100000); COPYARRAY(tlb_LUT_w, curr, unsigned int, 0x100000); *r4300_llbit() = GETDATA(curr, unsigned int); COPYARRAY(r4300_regs(), curr, int64_t, 32); COPYARRAY(cp0_regs, curr, uint32_t, 32); set_fpr_pointers(cp0_regs[CP0_STATUS_REG]); *r4300_mult_lo() = GETDATA(curr, int64_t); *r4300_mult_hi() = GETDATA(curr, int64_t); COPYARRAY(r4300_cp1_regs(), curr, int64_t, 32); /* 32-bit FPR mode requires data shuffling because * 64-bit layout is always stored in savestate file */ if ((cp0_regs[CP0_STATUS_REG] & UINT32_C(0x04000000)) == 0) shuffle_fpr_data(UINT32_C(0x04000000), 0); *r4300_cp1_fcr0() = GETDATA(curr, uint32_t); FCR31 = GETDATA(curr, uint32_t); *r4300_cp1_fcr31() = FCR31; update_x86_rounding_mode(FCR31); for (i = 0; i < 32; i++) { tlb_e[i].mask = GETDATA(curr, short); curr += 2; tlb_e[i].vpn2 = GETDATA(curr, int); tlb_e[i].g = GETDATA(curr, char); tlb_e[i].asid = GETDATA(curr, unsigned char); curr += 2; tlb_e[i].pfn_even = GETDATA(curr, int); tlb_e[i].c_even = GETDATA(curr, char); tlb_e[i].d_even = GETDATA(curr, char); tlb_e[i].v_even = GETDATA(curr, char); curr++; tlb_e[i].pfn_odd = GETDATA(curr, int); tlb_e[i].c_odd = GETDATA(curr, char); tlb_e[i].d_odd = GETDATA(curr, char); tlb_e[i].v_odd = GETDATA(curr, char); tlb_e[i].r = GETDATA(curr, char); tlb_e[i].start_even = GETDATA(curr, unsigned int); tlb_e[i].end_even = GETDATA(curr, unsigned int); tlb_e[i].phys_even = GETDATA(curr, unsigned int); tlb_e[i].start_odd = GETDATA(curr, unsigned int); tlb_e[i].end_odd = GETDATA(curr, unsigned int); tlb_e[i].phys_odd = GETDATA(curr, unsigned int); } savestates_load_set_pc(GETDATA(curr, uint32_t)); *r4300_next_interrupt() = GETDATA(curr, unsigned int); g_vi.next_vi = GETDATA(curr, unsigned int); g_vi.field = GETDATA(curr, unsigned int); memcpy(queue, curr, sizeof(queue)); to_little_endian_buffer(queue, 4, 256); load_eventqueue_infos(queue); *r4300_last_addr() = *r4300_pc(); /* deliver callback to indicate * completion of state loading operation */ StateChanged(M64CORE_STATE_LOADCOMPLETE, 1); return 1; } int savestates_save_m64p(unsigned char *data, size_t size) { unsigned char outbuf[4]; int i, queuelength; char queue[1024]; uint32_t* cp0_regs = r4300_cp0_regs(); unsigned char *curr = (unsigned char*)data; if (!curr) return 0; queuelength = save_eventqueue_infos(queue); // Write the save state data to memory PUTARRAY(savestate_magic, curr, unsigned char, 8); outbuf[0] = (savestate_latest_version >> 24) & 0xff; outbuf[1] = (savestate_latest_version >> 16) & 0xff; outbuf[2] = (savestate_latest_version >> 8) & 0xff; outbuf[3] = (savestate_latest_version >> 0) & 0xff; PUTARRAY(outbuf, curr, unsigned char, 4); PUTARRAY(ROM_SETTINGS.MD5, curr, char, 32); PUTDATA(curr, uint32_t, g_ri.rdram.regs[RDRAM_CONFIG_REG]); PUTDATA(curr, uint32_t, g_ri.rdram.regs[RDRAM_DEVICE_ID_REG]); PUTDATA(curr, uint32_t, g_ri.rdram.regs[RDRAM_DELAY_REG]); PUTDATA(curr, uint32_t, g_ri.rdram.regs[RDRAM_MODE_REG]); PUTDATA(curr, uint32_t, g_ri.rdram.regs[RDRAM_REF_INTERVAL_REG]); PUTDATA(curr, uint32_t, g_ri.rdram.regs[RDRAM_REF_ROW_REG]); PUTDATA(curr, uint32_t, g_ri.rdram.regs[RDRAM_RAS_INTERVAL_REG]); PUTDATA(curr, uint32_t, g_ri.rdram.regs[RDRAM_MIN_INTERVAL_REG]); PUTDATA(curr, uint32_t, g_ri.rdram.regs[RDRAM_ADDR_SELECT_REG]); PUTDATA(curr, uint32_t, g_ri.rdram.regs[RDRAM_DEVICE_MANUF_REG]); PUTDATA(curr, uint32_t, 0); PUTDATA(curr, uint32_t, g_r4300.mi.regs[MI_INIT_MODE_REG]); PUTDATA(curr, uint8_t, g_r4300.mi.regs[MI_INIT_MODE_REG] & 0x7F); PUTDATA(curr, uint8_t, (g_r4300.mi.regs[MI_INIT_MODE_REG] & 0x80) != 0); PUTDATA(curr, uint8_t, (g_r4300.mi.regs[MI_INIT_MODE_REG] & 0x100) != 0); PUTDATA(curr, uint8_t, (g_r4300.mi.regs[MI_INIT_MODE_REG] & 0x200) != 0); PUTDATA(curr, uint32_t, g_r4300.mi.regs[MI_VERSION_REG]); PUTDATA(curr, uint32_t, g_r4300.mi.regs[MI_INTR_REG]); PUTDATA(curr, uint32_t, g_r4300.mi.regs[MI_INTR_MASK_REG]); PUTDATA(curr, uint32_t, 0); /* Padding from old implementation */ PUTDATA(curr, uint8_t, (g_r4300.mi.regs[MI_INTR_MASK_REG] & 0x1) != 0); PUTDATA(curr, uint8_t, (g_r4300.mi.regs[MI_INTR_MASK_REG] & 0x2) != 0); PUTDATA(curr, uint8_t, (g_r4300.mi.regs[MI_INTR_MASK_REG] & 0x4) != 0); PUTDATA(curr, uint8_t, (g_r4300.mi.regs[MI_INTR_MASK_REG] & 0x8) != 0); PUTDATA(curr, uint8_t, (g_r4300.mi.regs[MI_INTR_MASK_REG] & 0x10) != 0); PUTDATA(curr, uint8_t, (g_r4300.mi.regs[MI_INTR_MASK_REG] & 0x20) != 0); PUTDATA(curr, uint16_t, 0); // Padding from old implementation PUTDATA(curr, uint32_t, g_pi.regs[PI_DRAM_ADDR_REG]); PUTDATA(curr, uint32_t, g_pi.regs[PI_CART_ADDR_REG]); PUTDATA(curr, uint32_t, g_pi.regs[PI_RD_LEN_REG]); PUTDATA(curr, uint32_t, g_pi.regs[PI_WR_LEN_REG]); PUTDATA(curr, uint32_t, g_pi.regs[PI_STATUS_REG]); PUTDATA(curr, uint32_t, g_pi.regs[PI_BSD_DOM1_LAT_REG]); PUTDATA(curr, uint32_t, g_pi.regs[PI_BSD_DOM1_PWD_REG]); PUTDATA(curr, uint32_t, g_pi.regs[PI_BSD_DOM1_PGS_REG]); PUTDATA(curr, uint32_t, g_pi.regs[PI_BSD_DOM1_RLS_REG]); PUTDATA(curr, uint32_t, g_pi.regs[PI_BSD_DOM1_LAT_REG]); PUTDATA(curr, uint32_t, g_pi.regs[PI_BSD_DOM1_PWD_REG]); PUTDATA(curr, uint32_t, g_pi.regs[PI_BSD_DOM1_PGS_REG]); PUTDATA(curr, uint32_t, g_pi.regs[PI_BSD_DOM1_RLS_REG]); PUTDATA(curr, uint32_t, g_sp.regs[SP_MEM_ADDR_REG]); PUTDATA(curr, uint32_t, g_sp.regs[SP_DRAM_ADDR_REG]); PUTDATA(curr, uint32_t, g_sp.regs[SP_RD_LEN_REG]); PUTDATA(curr, uint32_t, g_sp.regs[SP_WR_LEN_REG]); PUTDATA(curr, uint32_t, 0); /* Padding from old implementation */ PUTDATA(curr, uint32_t, g_sp.regs[SP_STATUS_REG]); PUTDATA(curr, uint8_t, (g_sp.regs[SP_STATUS_REG] & 0x1) != 0); PUTDATA(curr, uint8_t, (g_sp.regs[SP_STATUS_REG] & 0x2) != 0); PUTDATA(curr, uint8_t, (g_sp.regs[SP_STATUS_REG] & 0x4) != 0); PUTDATA(curr, uint8_t, (g_sp.regs[SP_STATUS_REG] & 0x8) != 0); PUTDATA(curr, uint8_t, (g_sp.regs[SP_STATUS_REG] & 0x10) != 0); PUTDATA(curr, uint8_t, (g_sp.regs[SP_STATUS_REG] & 0x20) != 0); PUTDATA(curr, uint8_t, (g_sp.regs[SP_STATUS_REG] & 0x40) != 0); PUTDATA(curr, uint8_t, (g_sp.regs[SP_STATUS_REG] & 0x80) != 0); PUTDATA(curr, uint8_t, (g_sp.regs[SP_STATUS_REG] & 0x100) != 0); PUTDATA(curr, uint8_t, (g_sp.regs[SP_STATUS_REG] & 0x200) != 0); PUTDATA(curr, uint8_t, (g_sp.regs[SP_STATUS_REG] & 0x400) != 0); PUTDATA(curr, uint8_t, (g_sp.regs[SP_STATUS_REG] & 0x800) != 0); PUTDATA(curr, uint8_t, (g_sp.regs[SP_STATUS_REG] & 0x1000) != 0); PUTDATA(curr, uint8_t, (g_sp.regs[SP_STATUS_REG] & 0x2000) != 0); PUTDATA(curr, uint8_t, (g_sp.regs[SP_STATUS_REG] & 0x4000) != 0); PUTDATA(curr, uint8_t, 0); PUTDATA(curr, uint32_t, g_sp.regs[SP_DMA_FULL_REG]); PUTDATA(curr, uint32_t, g_sp.regs[SP_DMA_BUSY_REG]); PUTDATA(curr, uint32_t, g_sp.regs[SP_SEMAPHORE_REG]); PUTDATA(curr, uint32_t, g_sp.regs2[SP_PC_REG]); PUTDATA(curr, uint32_t, g_sp.regs2[SP_IBIST_REG]); PUTDATA(curr, uint32_t, g_si.regs[SI_DRAM_ADDR_REG]); PUTDATA(curr, uint32_t, g_si.regs[SI_PIF_ADDR_RD64B_REG]); PUTDATA(curr, uint32_t, g_si.regs[SI_PIF_ADDR_WR64B_REG]); PUTDATA(curr, uint32_t, g_si.regs[SI_STATUS_REG]); PUTDATA(curr, uint32_t, g_vi.regs[VI_STATUS_REG]); PUTDATA(curr, uint32_t, g_vi.regs[VI_ORIGIN_REG]); PUTDATA(curr, uint32_t, g_vi.regs[VI_WIDTH_REG]); PUTDATA(curr, uint32_t, g_vi.regs[VI_V_INTR_REG]); PUTDATA(curr, uint32_t, g_vi.regs[VI_CURRENT_REG]); PUTDATA(curr, uint32_t, g_vi.regs[VI_BURST_REG]); PUTDATA(curr, uint32_t, g_vi.regs[VI_V_SYNC_REG]); PUTDATA(curr, uint32_t, g_vi.regs[VI_H_SYNC_REG]); PUTDATA(curr, uint32_t, g_vi.regs[VI_LEAP_REG]); PUTDATA(curr, uint32_t, g_vi.regs[VI_H_START_REG]); PUTDATA(curr, uint32_t, g_vi.regs[VI_V_START_REG]); PUTDATA(curr, uint32_t, g_vi.regs[VI_V_BURST_REG]); PUTDATA(curr, uint32_t, g_vi.regs[VI_X_SCALE_REG]); PUTDATA(curr, uint32_t, g_vi.regs[VI_Y_SCALE_REG]); PUTDATA(curr, unsigned int, g_vi.delay); PUTDATA(curr, uint32_t, g_ri.regs[RI_MODE_REG]); PUTDATA(curr, uint32_t, g_ri.regs[RI_CONFIG_REG]); PUTDATA(curr, uint32_t, g_ri.regs[RI_CURRENT_LOAD_REG]); PUTDATA(curr, uint32_t, g_ri.regs[RI_SELECT_REG]); PUTDATA(curr, uint32_t, g_ri.regs[RI_REFRESH_REG]); PUTDATA(curr, uint32_t, g_ri.regs[RI_LATENCY_REG]); PUTDATA(curr, uint32_t, g_ri.regs[RI_ERROR_REG]); PUTDATA(curr, uint32_t, g_ri.regs[RI_WERROR_REG]); PUTDATA(curr, uint32_t, g_ai.regs[AI_DRAM_ADDR_REG]); PUTDATA(curr, uint32_t, g_ai.regs[AI_LEN_REG]); PUTDATA(curr, uint32_t, g_ai.regs[AI_CONTROL_REG]); PUTDATA(curr, uint32_t, g_ai.regs[AI_STATUS_REG]); PUTDATA(curr, uint32_t, g_ai.regs[AI_DACRATE_REG]); PUTDATA(curr, uint32_t, g_ai.regs[AI_BITRATE_REG]); PUTDATA(curr, unsigned int, g_ai.fifo[1].duration); PUTDATA(curr, uint32_t, g_ai.fifo[1].length); PUTDATA(curr, unsigned int, g_ai.fifo[0].duration); PUTDATA(curr, uint32_t, g_ai.fifo[0].length); PUTDATA(curr, uint32_t, g_dp.dpc_regs[DPC_START_REG]); PUTDATA(curr, uint32_t, g_dp.dpc_regs[DPC_END_REG]); PUTDATA(curr, uint32_t, g_dp.dpc_regs[DPC_CURRENT_REG]); PUTDATA(curr, uint32_t, 0); /* Padding from oold implementation */ PUTDATA(curr, uint32_t, g_dp.dpc_regs[DPC_STATUS_REG]); PUTDATA(curr, uint8_t, (g_dp.dpc_regs[DPC_STATUS_REG] & 0x1) != 0); PUTDATA(curr, uint8_t, (g_dp.dpc_regs[DPC_STATUS_REG] & 0x2) != 0); PUTDATA(curr, uint8_t, (g_dp.dpc_regs[DPC_STATUS_REG] & 0x4) != 0); PUTDATA(curr, uint8_t, (g_dp.dpc_regs[DPC_STATUS_REG] & 0x8) != 0); PUTDATA(curr, uint8_t, (g_dp.dpc_regs[DPC_STATUS_REG] & 0x10) != 0); PUTDATA(curr, uint8_t, (g_dp.dpc_regs[DPC_STATUS_REG] & 0x20) != 0); PUTDATA(curr, uint8_t, (g_dp.dpc_regs[DPC_STATUS_REG] & 0x40) != 0); PUTDATA(curr, uint8_t, (g_dp.dpc_regs[DPC_STATUS_REG] & 0x80) != 0); PUTDATA(curr, uint8_t, (g_dp.dpc_regs[DPC_STATUS_REG] & 0x100) != 0); PUTDATA(curr, uint8_t, (g_dp.dpc_regs[DPC_STATUS_REG] & 0x200) != 0); PUTDATA(curr, uint8_t, (g_dp.dpc_regs[DPC_STATUS_REG] & 0x400) != 0); PUTDATA(curr, uint8_t, 0); PUTDATA(curr, uint32_t, g_dp.dpc_regs[DPC_CLOCK_REG]); PUTDATA(curr, uint32_t, g_dp.dpc_regs[DPC_BUFBUSY_REG]); PUTDATA(curr, uint32_t, g_dp.dpc_regs[DPC_PIPEBUSY_REG]); PUTDATA(curr, uint32_t, g_dp.dpc_regs[DPC_TMEM_REG]); PUTDATA(curr, uint32_t, g_dp.dps_regs[DPS_TBIST_REG]); PUTDATA(curr, uint32_t, g_dp.dps_regs[DPS_TEST_MODE_REG]); PUTDATA(curr, uint32_t, g_dp.dps_regs[DPS_BUFTEST_ADDR_REG]); PUTDATA(curr, uint32_t, g_dp.dps_regs[DPS_BUFTEST_DATA_REG]); PUTARRAY(g_rdram, curr, uint32_t, RDRAM_MAX_SIZE/4); PUTARRAY(g_sp.mem, curr, uint32_t, SP_MEM_SIZE/4); PUTARRAY(g_si.pif.ram, curr, uint8_t, PIF_RAM_SIZE); PUTDATA(curr, int, g_pi.use_flashram); PUTDATA(curr, int, g_pi.flashram.mode); PUTDATA(curr, unsigned long long, g_pi.flashram.status); PUTDATA(curr, unsigned int, g_pi.flashram.erase_offset); PUTDATA(curr, unsigned int, g_pi.flashram.write_pointer); PUTARRAY(tlb_LUT_r, curr, unsigned int, 0x100000); PUTARRAY(tlb_LUT_w, curr, unsigned int, 0x100000); PUTDATA(curr, unsigned int, *r4300_llbit()); PUTARRAY(r4300_regs(), curr, int64_t, 32); PUTARRAY(cp0_regs, curr, uint32_t, 32); PUTDATA(curr, int64_t, *r4300_mult_lo()); PUTDATA(curr, int64_t, *r4300_mult_hi()); if ((cp0_regs[CP0_STATUS_REG] & UINT32_C(0x04000000)) == 0) // FR bit == 0 means 32-bit (MIPS I) FGR mode shuffle_fpr_data(0, UINT32_C(0x04000000)); // shuffle data into 64-bit register format for storage PUTARRAY(r4300_cp1_regs(), curr, int64_t, 32); if ((cp0_regs[CP0_STATUS_REG] & UINT32_C(0x04000000)) == 0) shuffle_fpr_data(UINT32_C(0x04000000), 0); // put it back in 32-bit mode PUTDATA(curr, uint32_t, *r4300_cp1_fcr0()); PUTDATA(curr, uint32_t, *r4300_cp1_fcr31()); for (i = 0; i < 32; i++) { PUTDATA(curr, short, tlb_e[i].mask); PUTDATA(curr, short, 0); PUTDATA(curr, int, tlb_e[i].vpn2); PUTDATA(curr, char, tlb_e[i].g); PUTDATA(curr, unsigned char, tlb_e[i].asid); PUTDATA(curr, short, 0); PUTDATA(curr, int, tlb_e[i].pfn_even); PUTDATA(curr, char, tlb_e[i].c_even); PUTDATA(curr, char, tlb_e[i].d_even); PUTDATA(curr, char, tlb_e[i].v_even); PUTDATA(curr, char, 0); PUTDATA(curr, int, tlb_e[i].pfn_odd); PUTDATA(curr, char, tlb_e[i].c_odd); PUTDATA(curr, char, tlb_e[i].d_odd); PUTDATA(curr, char, tlb_e[i].v_odd); PUTDATA(curr, char, tlb_e[i].r); PUTDATA(curr, unsigned int, tlb_e[i].start_even); PUTDATA(curr, unsigned int, tlb_e[i].end_even); PUTDATA(curr, unsigned int, tlb_e[i].phys_even); PUTDATA(curr, unsigned int, tlb_e[i].start_odd); PUTDATA(curr, unsigned int, tlb_e[i].end_odd); PUTDATA(curr, unsigned int, tlb_e[i].phys_odd); } PUTDATA(curr, uint32_t, *r4300_pc()); PUTDATA(curr, unsigned int, *r4300_next_interrupt()); PUTDATA(curr, unsigned int, g_vi.next_vi); PUTDATA(curr, unsigned int, g_vi.field); to_little_endian_buffer(queue, 4, queuelength/4); PUTARRAY(queue, curr, char, queuelength); /* Deliver callback to indicate completion * of state saving operation */ StateChanged(M64CORE_STATE_SAVECOMPLETE, 1); return 1; } gles2n64/src/F3DPD.c000664 001750 001750 00000005044 12655644434 015021 0ustar00sergiosergio000000 000000 #include "gles2N64.h" #include "Debug.h" #include "F3D.h" #include "F3DPD.h" #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gSP.h" #include "gDP.h" #include "GBI.h" void F3DPD_Vtx( u32 w0, u32 w1 ) { gSPCIVertex( w1, _SHIFTR( w0, 20, 4 ) + 1, _SHIFTR( w0, 16, 4 ) ); } void F3DPD_VtxColorBase( u32 w0, u32 w1 ) { gSPSetVertexColorBase( w1 ); } void F3DPD_Init(void) { gSPSetupFunctions(); // Set GeometryMode flags GBI_InitFlags( F3D ); GBI.PCStackSize = 10; // GBI Command Command Value Command Function GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_MTX, F3D_MTX, F3D_Mtx ); GBI_SetGBI( G_RESERVED0, F3D_RESERVED0, F3D_Reserved0 ); GBI_SetGBI( G_MOVEMEM, F3D_MOVEMEM, F3D_MoveMem ); GBI_SetGBI( G_VTX, F3D_VTX, F3DPD_Vtx ); GBI_SetGBI( G_RESERVED1, F3D_RESERVED1, F3D_Reserved1 ); GBI_SetGBI( G_DL, F3D_DL, F3D_DList ); GBI_SetGBI( G_VTXCOLORBASE, F3DPD_VTXCOLORBASE, F3DPD_VtxColorBase ); GBI_SetGBI( G_RESERVED3, F3D_RESERVED3, F3D_Reserved3 ); GBI_SetGBI( G_SPRITE2D_BASE, F3D_SPRITE2D_BASE, F3D_Sprite2D_Base ); GBI_SetGBI( G_TRI1, F3D_TRI1, F3D_Tri1 ); GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3D_CullDL ); GBI_SetGBI( G_POPMTX, F3D_POPMTX, F3D_PopMtx ); GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3D_MoveWord ); GBI_SetGBI( G_TEXTURE, F3D_TEXTURE, F3D_Texture ); GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L ); GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL ); GBI_SetGBI( G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, F3D_SetGeometryMode ); GBI_SetGBI( G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE, F3D_ClearGeometryMode ); GBI_SetGBI( G_QUAD, F3D_QUAD, F3D_Quad ); GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_RDPHALF_CONT, F3D_RDPHALF_CONT, F3D_RDPHalf_Cont ); GBI_SetGBI( G_TRI4, F3D_TRI4, F3D_Tri4 ); gSPSetDMAOffsets( 0, 0 ); } gles2n64/src/000700 001750 001750 00000000000 12656647145 014041 5ustar00sergiosergio000000 000000 gles2rice/src/COLOR.h000664 001750 001750 00000005422 12655644434 015417 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - COLOR.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Rice1964 * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef XCOLOR_H #define XCOLOR_H typedef struct _COLORVALUE { float r; float g; float b; float a; } COLORVALUE; typedef struct XCOLOR { float r, g, b, a; #ifdef __cplusplus public: XCOLOR() { } XCOLOR( unsigned int argb ); XCOLOR( const float * ); XCOLOR( const COLORVALUE& ); XCOLOR( float r, float g, float b, float a ); // casting operator unsigned int () const; operator float* (); operator const float* () const; operator COLORVALUE* (); operator const COLORVALUE* () const; operator COLORVALUE& (); operator const COLORVALUE& () const; // assignment operators XCOLOR& operator += ( const XCOLOR& ); XCOLOR& operator -= ( const XCOLOR& ); XCOLOR& operator *= ( float ); XCOLOR& operator /= ( float ); // unary operators XCOLOR operator + () const; XCOLOR operator - () const; // binary operators XCOLOR operator + ( const XCOLOR& ) const; XCOLOR operator - ( const XCOLOR& ) const; XCOLOR operator * ( float ) const; XCOLOR operator / ( float ) const; friend XCOLOR operator * (float, const XCOLOR& ); bool operator == ( const XCOLOR& ) const; bool operator != ( const XCOLOR& ) const; #endif //__cplusplus } XCOLOR; #endif glide2gl/src/Glide64/FBtoScreen.c000664 001750 001750 00000044337 12655644434 017546 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** // // Draw N64 frame buffer to screen. // Created by Gonetz, 2007 // //**************************************************************** #include "Gfx_1.3.h" #include "FBtoScreen.h" #include "TexCache.h" static void glide64_draw_fb(float ul_x, float ul_y, float lr_x, float lr_y, float lr_u, float lr_v, float zero) { VERTEX v[4], vout[4]; /* Make the vertices */ v[0].x = ul_x; v[0].y = ul_y; v[0].z = 1.0f; v[0].q = 1.0f; v[0].u[0] = zero; v[0].v[0] = zero; v[0].u[1] = zero; v[0].v[1] = zero; v[0].coord[0] = zero; v[0].coord[1] = zero; v[0].coord[2] = zero; v[0].coord[3] = zero; v[1].x = lr_x; v[1].y = ul_y; v[1].z = 1.0f; v[1].q = 1.0f; v[1].u[0] = lr_u; v[1].v[0] = zero; v[1].u[1] = lr_u; v[1].v[1] = zero; v[1].coord[0] = lr_u; v[1].coord[1] = zero; v[1].coord[2] = lr_u; v[1].coord[3] = zero; v[2].x = ul_x; v[2].y = lr_y; v[2].z = 1.0f; v[2].q = 1.0f; v[2].u[0] = zero; v[2].v[0] = lr_v; v[2].u[1] = zero; v[2].v[1] = lr_v; v[2].coord[0] = zero; v[2].coord[1] = lr_v; v[2].coord[2] = zero; v[2].coord[3] = lr_v; v[3].x = lr_x; v[3].y = lr_y; v[3].z = 1.0f; v[3].q = 1.0f; v[3].u[0] = lr_u; v[3].v[0] = lr_v; v[3].u[1] = lr_u; v[3].v[1] = lr_v; v[3].coord[0] = lr_u; v[3].coord[1] = lr_v; v[3].coord[2] = lr_u; v[3].coord[3] = lr_v; vout[0] = v[0]; vout[1] = v[2]; vout[2] = v[1]; vout[3] = v[3]; grDrawVertexArrayContiguous(GR_TRIANGLE_STRIP, 4, &vout[0]); } static int SetupFBtoScreenCombiner(uint32_t texture_size, uint32_t opaque) { int tmu, filter; if (voodoo.tmem_ptr[GR_TMU0]+texture_size < voodoo.tex_max_addr) { tmu = GR_TMU0; grTexCombine( GR_TMU1, GR_COMBINE_FUNCTION_NONE, GR_COMBINE_FACTOR_NONE, GR_COMBINE_FUNCTION_NONE, GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE ); grTexCombine( GR_TMU0, GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE ); } else { if (voodoo.tmem_ptr[GR_TMU1]+texture_size >= voodoo.tex_max_addr) ClearCache (); tmu = GR_TMU1; grTexCombine( GR_TMU1, GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE ); grTexCombine( GR_TMU0, GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE ); } filter = (rdp.filter_mode != 2) ? GR_TEXTUREFILTER_POINT_SAMPLED : GR_TEXTUREFILTER_BILINEAR; grTexFilterClampMode (tmu, GR_TEXTURECLAMP_CLAMP, GR_TEXTURECLAMP_CLAMP, filter, filter); grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE, // GR_COMBINE_OTHER_CONSTANT, FXFALSE); grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE, FXFALSE); if (opaque) { grAlphaTestFunction (GR_CMP_ALWAYS, 0x00, 0); grAlphaBlendFunction( GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_ONE, GR_BLEND_ZERO); } else { grAlphaBlendFunction( GR_BLEND_SRC_ALPHA, GR_BLEND_ONE_MINUS_SRC_ALPHA, GR_BLEND_ONE, GR_BLEND_ZERO); } grDepthBufferFunction (GR_CMP_ALWAYS); grCullMode(GR_CULL_DISABLE); grDepthMask (FXFALSE); g_gdp.flags |= UPDATE_COMBINE | UPDATE_ZBUF_ENABLED | UPDATE_CULL_MODE; return tmu; } static void DrawRE2Video(FB_TO_SCREEN_INFO *fb_info, float scale) { float scale_y = (float)fb_info->width / rdp.vi_height; float height = settings.scr_res_x / scale_y; float ul_x = 0.5f; float ul_y = (settings.scr_res_y - height) / 2.0f; float lr_y = settings.scr_res_y - ul_y - 1.0f; float lr_x = settings.scr_res_x - 1.0f; float lr_u = (fb_info->width - 1) * scale; float lr_v = (fb_info->height - 1) * scale; glide64_draw_fb(ul_x, ul_y, lr_x, lr_y, lr_u, lr_v, 0.5f); } static void DrawRE2Video256(FB_TO_SCREEN_INFO *fb_info) { uint32_t h, w; int tmu; GrTexInfo t_info; uint32_t *src = (uint32_t*)(gfx_info.RDRAM + fb_info->addr); uint16_t *tex = (uint16_t*)texture_buffer; uint16_t *dst = (uint16_t*)tex; t_info.smallLodLog2 = GR_LOD_LOG2_256; t_info.largeLodLog2 = GR_LOD_LOG2_256; t_info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; fb_info->height = min(256, fb_info->height); for (h = 0; h < fb_info->height; h++) { for (w = 0; w < 256; w++) { uint8_t r, g, b; uint32_t col = *(src++); r = (uint8_t)((col >> 24)&0xFF); r = (uint8_t)((float)r / 255.0f * 31.0f); g = (uint8_t)((col >> 16)&0xFF); g = (uint8_t)((float)g / 255.0f * 63.0f); b = (uint8_t)((col >> 8)&0xFF); b = (uint8_t)((float)b / 255.0f * 31.0f); *(dst++) = (r << 11) | (g << 5) | b; } src += (fb_info->width - 256); } t_info.format = GR_TEXFMT_RGB_565; t_info.data = tex; tmu = SetupFBtoScreenCombiner(grTexCalcMemRequired(t_info.largeLodLog2, t_info.aspectRatioLog2, t_info.format), fb_info->opaque); grTexSource (tmu, voodoo.tmem_ptr[tmu], GR_MIPMAPLEVELMASK_BOTH, &t_info, true); DrawRE2Video(fb_info, 1.0f); } static void DrawFrameBufferToScreen256(FB_TO_SCREEN_INFO *fb_info) { uint32_t w, h, x, y, width, height, width256, height256, tex_size, *src32; uint32_t tex_adr, w_tail, h_tail, bound, c32, idx; uint8_t r, g, b, a, *image; uint16_t *tex, *src, c; float ul_x, ul_y, lr_x, lr_y, lr_u, lr_v; int tmu; GrTexInfo t_info; if (settings.hacks & hack_RE2) { DrawRE2Video256(fb_info); return; } width = fb_info->lr_x - fb_info->ul_x + 1; height = fb_info->lr_y - fb_info->ul_y + 1; image = (uint8_t*)(gfx_info.RDRAM + fb_info->addr); width256 = ((width - 1) >> 8) + 1; height256 = ((height - 1) >> 8) + 1; t_info.smallLodLog2 = t_info.largeLodLog2 = GR_LOD_LOG2_256; t_info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; t_info.format = GR_TEXFMT_ARGB_1555; tex = (uint16_t*)texture_buffer; t_info.data = tex; tex_size = grTexCalcMemRequired(t_info.largeLodLog2, t_info.aspectRatioLog2, t_info.format); tmu = SetupFBtoScreenCombiner(tex_size * width256 * height256, fb_info->opaque); src = (uint16_t*)(image + fb_info->ul_x + fb_info->ul_y * fb_info->width); src32 = (uint32_t*)(image + fb_info->ul_x + fb_info->ul_y * fb_info->width); w_tail = width % 256; h_tail = height % 256; bound = (BMASK + 1) - fb_info->addr; bound = fb_info->size == 2 ? (bound >> 1) : (bound >> 2); tex_adr = voodoo.tmem_ptr[tmu]; for (h = 0; h < height256; h++) { for (w = 0; w < width256; w++) { uint32_t cur_width = (256 * (w + 1) < width) ? 256 : w_tail; uint32_t cur_height = (256 * (h + 1) < height) ? 256 : h_tail; uint32_t cur_tail = 256 - cur_width; uint16_t *dst = (uint16_t*)tex; if (fb_info->size == 2) { for (y=0; y < cur_height; y++) { for (x=0; x < cur_width; x++) { idx = (x + 256 * w + (y + 256 * h) * fb_info->width) ^ 1; if (idx >= bound) break; c = src[idx]; *(dst++) = (c >> 1) | ((c&1)<<15); } dst += cur_tail; } } else { for (y=0; y < cur_height; y++) { for (x=0; x < cur_width; x++) { idx = (x+256*w+(y+256*h)*fb_info->width); if (idx >= bound) break; c32 = src32[idx]; r = (uint8_t)((c32 >> 24) & 0xFF); r = (uint8_t)((float)r / 255.0f * 31.0f); g = (uint8_t)((c32 >> 16) & 0xFF); g = (uint8_t)((float)g / 255.0f * 63.0f); b = (uint8_t)((c32 >> 8) & 0xFF); b = (uint8_t)((float)b / 255.0f * 31.0f); a = (c32 & 0xFF) ? 1 : 0; *(dst++) = (a<<15) | (r << 10) | (g << 5) | b; } dst += cur_tail; } } grTexSource (tmu, tex_adr, GR_MIPMAPLEVELMASK_BOTH, &t_info, true); tex_adr += tex_size; ul_x = (fb_info->ul_x + 256 * w) * rdp.scale_x + rdp.offset_x; ul_y = (fb_info->ul_y + 256 * h) * rdp.scale_y + rdp.offset_y; lr_x = (ul_x + (float)(cur_width)) * rdp.scale_x + rdp.offset_x; lr_y = (ul_y + (float)(cur_height)) * rdp.scale_y + rdp.offset_y; lr_u = (float)(cur_width - 1); lr_v = (float)(cur_height - 1); glide64_draw_fb(ul_x, ul_y, lr_x, lr_y, lr_u, lr_v, 0.5f); } } } bool DrawFrameBufferToScreen(FB_TO_SCREEN_INFO *fb_info) { uint32_t x, y, width, height, texwidth; uint8_t *image; int tmu; float scale; GrTexInfo t_info; if (fb_info->width < 200 || fb_info->size < 2) return false; width = fb_info->lr_x - fb_info->ul_x + 1; height = fb_info->lr_y - fb_info->ul_y + 1; if (width > 512 || height > 512) { DrawFrameBufferToScreen256(fb_info); return true; } image = (uint8_t*)(gfx_info.RDRAM + fb_info->addr); texwidth = 512; scale = 0.5f; t_info.smallLodLog2 = GR_LOD_LOG2_512; t_info.largeLodLog2 = GR_LOD_LOG2_512; t_info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; if (width <= 256) { texwidth = 256; scale = 1.0f; t_info.smallLodLog2 = t_info.largeLodLog2 = GR_LOD_LOG2_256; } if (height <= (texwidth>>1)) t_info.aspectRatioLog2 = GR_ASPECT_LOG2_2x1; if (fb_info->size == 2) { uint16_t c; uint32_t idx; uint16_t *tex = (uint16_t*)texture_buffer; uint16_t *dst = (uint16_t*)tex; uint16_t *src = (uint16_t*)(image + fb_info->ul_x + fb_info->ul_y * fb_info->width); uint32_t bound = (BMASK+1 - fb_info->addr) >> 1; bool empty = true; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { idx = (x + y * fb_info->width) ^ 1; if (idx >= bound) break; c = src[idx]; if (c) empty = false; *(dst++) = (c >> 1) | ((c & 1) << 15); } dst += texwidth-width; } if (empty) return false; t_info.format = GR_TEXFMT_ARGB_1555; t_info.data = tex; } else { uint32_t col, idx; uint32_t *tex = (uint32_t*)texture_buffer; uint32_t *dst = (uint32_t*)tex; uint32_t *src = (uint32_t*)(image + fb_info->ul_x + fb_info->ul_y * fb_info->width); uint32_t bound = (BMASK + 1 - fb_info->addr) >> 2; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { idx = x + y * fb_info->width; if (idx >= bound) break; col = src[idx]; *(dst++) = (col >> 8) | 0xFF000000; } dst += texwidth-width; } t_info.format = GR_TEXFMT_ARGB_8888; t_info.data = tex; } tmu = SetupFBtoScreenCombiner(grTexCalcMemRequired(t_info.largeLodLog2, t_info.aspectRatioLog2, t_info.format), fb_info->opaque); grTexSource (tmu, voodoo.tmem_ptr[tmu], GR_MIPMAPLEVELMASK_BOTH, &t_info, true); if (settings.hacks&hack_RE2) DrawRE2Video(fb_info, scale); else { float ul_x = fb_info->ul_x * rdp.scale_x + rdp.offset_x; float ul_y = fb_info->ul_y * rdp.scale_y + rdp.offset_y; float lr_x = fb_info->lr_x * rdp.scale_x + rdp.offset_x; float lr_y = fb_info->lr_y * rdp.scale_y + rdp.offset_y; float lr_u = (width - 1) * scale; float lr_v = (height - 1) * scale; glide64_draw_fb(ul_x, ul_y, lr_x, lr_y, lr_u, lr_v, 0.5f); } return true; } static void DrawDepthBufferToScreen256(FB_TO_SCREEN_INFO *fb_info) { uint32_t h, w, x, y, tex_size; uint32_t w_tail, h_tail, tex_adr; int tmu; GrTexInfo t_info; uint32_t width = fb_info->lr_x - fb_info->ul_x + 1; uint32_t height = fb_info->lr_y - fb_info->ul_y + 1; uint8_t *image = (uint8_t*)(gfx_info.RDRAM + fb_info->addr); uint32_t width256 = ((width-1) >> 8) + 1; uint32_t height256 = ((height-1) >> 8) + 1; uint16_t *tex = (uint16_t*)texture_buffer; uint16_t *src = (uint16_t*)(image + fb_info->ul_x + fb_info->ul_y * fb_info->width); t_info.smallLodLog2 = t_info.largeLodLog2 = GR_LOD_LOG2_256; t_info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; t_info.format = GR_TEXFMT_ALPHA_INTENSITY_88; t_info.data = tex; tex_size = grTexCalcMemRequired(t_info.largeLodLog2, t_info.aspectRatioLog2, t_info.format); tmu = SetupFBtoScreenCombiner(tex_size*width256*height256, fb_info->opaque); grConstantColorValue (g_gdp.fog_color.total); grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_CONSTANT, FXFALSE); w_tail = width % 256; h_tail = height % 256; tex_adr = voodoo.tmem_ptr[tmu]; for (h = 0; h < height256; h++) { for (w = 0; w < width256; w++) { float ul_x, ul_y, lr_x, lr_y, lr_u, lr_v; uint32_t cur_width = (256 * (w + 1) < width) ? 256 : w_tail; uint32_t cur_height = (256 * (h + 1) < height) ? 256 : h_tail; uint32_t cur_tail = 256 - cur_width; uint16_t *dst = tex; for (y=0; y < cur_height; y++) { for (x=0; x < cur_width; x++) *(dst++) = rdp.pal_8[src[(x + 256 * w + (y + 256 * h) * fb_info->width) ^ 1]>>8]; dst += cur_tail; } grTexSource (tmu, tex_adr, GR_MIPMAPLEVELMASK_BOTH, &t_info, true); tex_adr += tex_size; ul_x = (float)(fb_info->ul_x + 256 * w); ul_y = (float)(fb_info->ul_y + 256 * h); lr_x = (ul_x + (float)(cur_width)) * rdp.scale_x + rdp.offset_x; lr_y = (ul_y + (float)(cur_height)) * rdp.scale_y + rdp.offset_y; ul_x = ul_x * rdp.scale_x + rdp.offset_x; ul_y = ul_y * rdp.scale_y + rdp.offset_y; lr_u = (float)(cur_width-1); lr_v = (float)(cur_height-1); glide64_draw_fb(ul_x, ul_y, lr_x, lr_y, lr_u, lr_v, 0.5f); } } } void DrawDepthBufferToScreen(FB_TO_SCREEN_INFO *fb_info) { uint32_t x, y; int tmu; float ul_x, ul_y, lr_x, lr_y, lr_u, lr_v, zero; GrTexInfo t_info; uint32_t width = fb_info->lr_x - fb_info->ul_x + 1; uint32_t height = fb_info->lr_y - fb_info->ul_y + 1; uint8_t *image = (uint8_t*)(gfx_info.RDRAM + fb_info->addr); uint32_t texwidth = 512; float scale = 0.5f; uint16_t *tex = (uint16_t*)texture_buffer; uint16_t *dst = (uint16_t*)tex; uint16_t *src = (uint16_t*)(image + fb_info->ul_x + fb_info->ul_y * fb_info->width); if (width > 512) { DrawDepthBufferToScreen256(fb_info); return; } t_info.smallLodLog2 = t_info.largeLodLog2 = GR_LOD_LOG2_512; t_info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; if (width <= 256) { texwidth = 256; scale = 1.0f; t_info.smallLodLog2 = t_info.largeLodLog2 = GR_LOD_LOG2_256; } if (height <= (texwidth>>1)) t_info.aspectRatioLog2 = GR_ASPECT_LOG2_2x1; for (y=0; y < height; y++) { for (x = 0; x < width; x++) *(dst++) = rdp.pal_8[src[(x+y*fb_info->width)^1]>>8]; dst += texwidth-width; } t_info.format = GR_TEXFMT_ALPHA_INTENSITY_88; t_info.data = tex; tmu = SetupFBtoScreenCombiner(grTexCalcMemRequired(t_info.largeLodLog2, t_info.aspectRatioLog2, t_info.format), fb_info->opaque); grConstantColorValue (g_gdp.fog_color.total); grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_CONSTANT, FXFALSE); grTexSource (tmu, voodoo.tmem_ptr[tmu], GR_MIPMAPLEVELMASK_BOTH, &t_info, true); ul_x = fb_info->ul_x * rdp.scale_x + rdp.offset_x; ul_y = fb_info->ul_y * rdp.scale_y + rdp.offset_y; lr_x = fb_info->lr_x * rdp.scale_x + rdp.offset_x; lr_y = fb_info->lr_y * rdp.scale_y + rdp.offset_y; lr_u = (width - 1) * scale; lr_v = (height - 1) * scale; zero = scale * 0.5f; glide64_draw_fb(ul_x, ul_y, lr_x, lr_y, lr_u, lr_v, zero); } README.md000664 001750 001750 00000000301 12655644434 013170 0ustar00sergiosergio000000 000000 mupen64plus-libretro ==================== To enable a dynarec CPU core you must pass the WITH_DYNAREC value to make: * make WITH_DYNAREC=x86 * make WITH_DYNAREC=x86_64 * make WITH_DYNAREC=arm libretro/msvc/msvc-2010/msvc-2010.suo000664 001750 001750 00000021000 12655644434 020112 0ustar00sergiosergio000000 000000 ÐÏࡱá>þÿ þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿþÿÿÿ  þÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿRoot Entryÿÿÿÿÿÿÿÿðá‹GcXÏ@ ProjInfoExÿÿÿÿÿÿÿÿÿÿÿÿTaskListUserTasks$ÿÿÿÿTipPersistenceÿÿÿÿþÿÿÿþÿÿÿ þÿÿÿþÿÿÿ þÿÿÿþÿÿÿþÿÿÿþÿÿÿþÿÿÿþÿÿÿ !"#$%&'þÿÿÿþÿÿÿ*+,-.þÿÿÿþÿÿÿ1þÿÿÿþÿÿÿþÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿB†œh£è8O¸ qùQ²ØðC ÿÿÿÿ ^VsDebugPresentationPackage, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3auMicrosoft.VisualStudio.Debugger.DebuggerToolWindows.DataTips.PinnableTips.Extensibility.Persistence+ListenerDataStore ÿÿÿÿ ^VsDebugPresentationPackage, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3anMicrosoft.VisualStudio.Debugger.DebuggerToolWindows.DataTips.PinnableTips.Persistence.PersistableTipCollectionTips  ”D:\libretro-super\libretro-mupen64plus\libretro\msvc\msvc-2010\msvc-2010\DebuggerWatches ÿÿÿÿÿÿÿÿ DebuggerBreakpoints(ÿÿÿÿÿÿÿÿ  DebuggerExceptions& ÿÿÿÿDebuggerFindSource&ÿÿÿÿÿÿÿÿN€C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\crt\src\ŽC:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\atlmfc\src\mfc\ŽC:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\atlmfc\src\atl\ŽC:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\atlmfc\include\ MultiStartupProj=;4{62F97835-3567-4EF3-ACDC-46F2CDECAF40}DebuggerFindSymbol&ÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿDebuggerMemoryWindows,ÿÿÿÿTDebuggerBreakpointsWindow4ÿÿÿÿ ÿÿÿÿExternalFilesProjectContents:ÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿDocumentWindowPositions0ÿÿÿÿÿÿÿÿDocumentWindowUserData. ÿÿÿÿþÿÿÿSolutionConfiguration,ÿÿÿÿÿÿÿÿÿÿÿÿjObjMgrContentsV8"ÿÿÿÿ(.dwStartupOpt=;StartupProject=&{62F97835-3567-4EF3-ACDC-46F2CDECAF40};?{62F97835-3567-4EF3-ACDC-46F2CDECAF40}.Release|Win32.fBatchBld=;={62F97835-3567-4EF3-ACDC-46F2CDECAF40}.Debug|Win32.fBatchBld=; ActiveCfg= Debug|Win32;Q ¶D:\libretro-super\libretro-mupen64plus\libretro\msvc\msvc-2010\msvc-2010\msvc-2010.vcxproj¶D:\libretro-super\libretro-mupen64plus\libretro\msvc\msvc-2010\msvc-2010\msvc-2010.vcxproj 5xùbg5óN¬ÜFòÍì¯@ClassViewContents$ÿÿÿÿþÿÿÿProjExplorerState$ÿÿÿÿ)€UnloadedProjects"ÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿHiddenSlnFolders"ÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿBackgroundLoadData&ÿÿÿÿÿÿÿÿÿÿÿÿ/<ProjectTrustInformation0ÿÿÿÿ ÿÿÿÿþÿÿÿVC Projectÿÿÿÿ0rOutliningStateDir$ÿÿÿÿÿÿÿÿÿÿÿÿ2f{62F97835-3567-4EF3-ACDC-46F2CDECAF40}=Debug|Win32$Bookmarks V001.01XÏ BookmarkStateÿÿÿÿÿÿÿÿÿÿÿÿ3(TaskListShortcuts$ÿÿÿÿÿÿÿÿÿÿÿÿ4ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿlibretro-common/include/glsym/rglgen.h000664 001750 001750 00000003514 12655644434 021237 0ustar00sergiosergio000000 000000 /* Copyright (C) 2010-2015 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this libretro SDK code part (glsym). * --------------------------------------------------------------------------------------- * * Permission is hereby granted, free of charge, * to any person obtaining a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef RGLGEN_H__ #define RGLGEN_H__ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "rglgen_headers.h" #ifdef __cplusplus extern "C" { #endif struct rglgen_sym_map; typedef void (*rglgen_func_t)(void); typedef rglgen_func_t (*rglgen_proc_address_t)(const char*); void rglgen_resolve_symbols(rglgen_proc_address_t proc); void rglgen_resolve_symbols_custom(rglgen_proc_address_t proc, const struct rglgen_sym_map *map); #ifdef __cplusplus } #endif #endif mupen64plus-video-gliden64/src/GLideNHQ/txWidestringWrapper.h000664 001750 001750 00000002424 12655644434 025170 0ustar00sergiosergio000000 000000 #ifndef ___TXWIDESCREENWRAPPER_H__ #define ___TXWIDESCREENWRAPPER_H__ #include #ifdef ANDROID int tx_swprintf(wchar_t* ws, size_t len, const wchar_t* format, ...); bool wccmp(const wchar_t* w1, const wchar_t* w2); #define BUF_SIZE 2048 class tx_wstring { public: tx_wstring() {} tx_wstring(const wchar_t * wstr); tx_wstring(const tx_wstring & other); void assign(const wchar_t * wstr); void assign(const tx_wstring & wstr); void append(const tx_wstring & wstr); tx_wstring & operator=(const tx_wstring & other); tx_wstring & operator+=(const tx_wstring & other); tx_wstring & operator+=(const wchar_t * wstr); tx_wstring operator+(const tx_wstring & wstr); tx_wstring operator+(const wchar_t * wstr); const wchar_t * c_str() const; bool empty() const; int compare(const wchar_t * wstr); private: std::wstring _wstring; std::string _astring; char cbuf[BUF_SIZE]; wchar_t wbuf[BUF_SIZE]; }; class dummyWString { public: dummyWString(const char * _str); const wchar_t * c_str() const { return _wstr.c_str(); } private: std::wstring _wstr; }; #define wst(A) dummyWString(A).c_str() #else #define tx_wstring std::wstring #define tx_swprintf swprintf #define wst(A) L##A #define wccmp(A, B) A[0] == B[0] #endif // ANDROID #endif // ___TXWIDESCREENWRAPPER_H__ mupen64plus-rsp-hle/src/arithmetics.h000664 001750 001750 00000003521 12655644434 020746 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-rsp-hle - arithmetics.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef ARITHMETICS_H #define ARITHMETICS_H #include static INLINE int16_t clamp_s16(int_fast32_t x) { x = (x < INT16_MIN) ? INT16_MIN: x; x = (x > INT16_MAX) ? INT16_MAX: x; return x; } static INLINE int32_t vmulf(int16_t x, int16_t y) { return (((int32_t)(x))*((int32_t)(y))+0x4000)>>15; } #endif mupen64plus-video-gliden64/src/Turbo3D.cpp000664 001750 001750 00000006503 12655644434 021420 0ustar00sergiosergio000000 000000 #include "Turbo3D.h" #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gSP.h" #include "gDP.h" #include "OpenGL.h" /******************Turbo3D microcode*************************/ struct T3DGlobState { u16 pad0; u16 perspNorm; u32 flag; u32 othermode0; u32 othermode1; u32 segBases[16]; /* the viewport to use */ s16 vsacle1; s16 vsacle0; s16 vsacle3; s16 vsacle2; s16 vtrans1; s16 vtrans0; s16 vtrans3; s16 vtrans2; u32 rdpCmds; }; struct T3DState { u32 renderState; /* render state */ u32 textureState; /* texture state */ u8 flag; u8 triCount; /* how many tris? */ u8 vtxV0; /* where to load verts? */ u8 vtxCount; /* how many verts? */ u32 rdpCmds; /* ptr (segment address) to RDP DL */ u32 othermode0; u32 othermode1; }; struct T3DTriN { u8 flag, v2, v1, v0; /* flag is which one for flat shade */ }; static void Turbo3D_ProcessRDP(u32 _cmds) { u32 addr = RSP_SegmentToPhysical(_cmds) >> 2; if (addr != 0) { RSP.bLLE = true; u32 w0 = ((u32*)RDRAM)[addr++]; u32 w1 = ((u32*)RDRAM)[addr++]; RSP.cmd = _SHIFTR( w0, 24, 8 ); while (w0 + w1 != 0) { GBI.cmd[RSP.cmd]( w0, w1 ); w0 = ((u32*)RDRAM)[addr++]; w1 = ((u32*)RDRAM)[addr++]; RSP.cmd = _SHIFTR( w0, 24, 8 ); if (RSP.cmd == 0xE4 || RSP.cmd == 0xE5) { RDP.w2 = ((u32*)RDRAM)[addr++]; RDP.w3 = ((u32*)RDRAM)[addr++]; } } RSP.bLLE = false; } } static void Turbo3D_LoadGlobState(u32 pgstate) { const u32 addr = RSP_SegmentToPhysical(pgstate); T3DGlobState *gstate = (T3DGlobState*)&RDRAM[addr]; const u32 w0 = gstate->othermode0; const u32 w1 = gstate->othermode1; gDPSetOtherMode( _SHIFTR( w0, 0, 24 ), // mode0 w1 ); // mode1 for (int s = 0; s < 16; ++s) gSPSegment(s, gstate->segBases[s] & 0x00FFFFFF); gSPViewport(pgstate + 80); Turbo3D_ProcessRDP(gstate->rdpCmds); } static void Turbo3D_LoadObject(u32 pstate, u32 pvtx, u32 ptri) { u32 addr = RSP_SegmentToPhysical(pstate); T3DState *ostate = (T3DState*)&RDRAM[addr]; const u32 tile = (ostate->textureState)&7; gSP.texture.tile = tile; gSP.textureTile[0] = &gDP.tiles[tile]; gSP.textureTile[1] = &gDP.tiles[(tile + 1) & 7]; gSP.texture.scales = 1.0f; gSP.texture.scalet = 1.0f; const u32 w0 = ostate->othermode0; const u32 w1 = ostate->othermode1; gDPSetOtherMode( _SHIFTR( w0, 0, 24 ), // mode0 w1 ); // mode1 gSPSetGeometryMode(ostate->renderState); if ((ostate->flag&1) == 0) //load matrix gSPForceMatrix(pstate + sizeof(T3DState)); gSPClearGeometryMode(G_LIGHTING); gSPSetGeometryMode(G_SHADING_SMOOTH); if (pvtx != 0) //load vtx gSPVertex(pvtx, ostate->vtxCount, ostate->vtxV0); Turbo3D_ProcessRDP(ostate->rdpCmds); if (ptri != 0) { addr = RSP_SegmentToPhysical(ptri); for (int t = 0; t < ostate->triCount; ++t) { T3DTriN * tri = (T3DTriN*)&RDRAM[addr]; addr += 4; gSPTriangle(tri->v0, tri->v1, tri->v2); } video().getRender().drawTriangles(); } } void RunTurbo3D() { u32 pstate; do { u32 addr = RSP.PC[RSP.PCi] >> 2; const u32 pgstate = ((u32*)RDRAM)[addr++]; pstate = ((u32*)RDRAM)[addr++]; const u32 pvtx = ((u32*)RDRAM)[addr++]; const u32 ptri = ((u32*)RDRAM)[addr]; if (pstate == 0) { RSP.halt = 1; break; } if (pgstate != 0) Turbo3D_LoadGlobState(pgstate); Turbo3D_LoadObject(pstate, pvtx, ptri); // Go to the next instruction RSP.PC[RSP.PCi] += 16; } while (pstate != 0); } mupen64plus-video-gliden64/src/S2DEX2.h000664 001750 001750 00000000757 12655644434 020517 0ustar00sergiosergio000000 000000 #ifndef S2DEX2_H #define S2DEX2_H void S2DEX2_Init(); #define S2DEX2_OBJ_RECTANGLE_R 0xDA #define S2DEX2_OBJ_MOVEMEM 0xDC #define S2DEX2_RDPHALF_0 0xE4 #define S2DEX2_OBJ_RECTANGLE 0x01 #define S2DEX2_OBJ_SPRITE 0x02 #define S2DEX2_SELECT_DL 0x04 #define S2DEX2_OBJ_LOADTXTR 0x05 #define S2DEX2_OBJ_LDTX_SPRITE 0x06 #define S2DEX2_OBJ_LDTX_RECT 0x07 #define S2DEX2_OBJ_LDTX_RECT_R 0x08 #define S2DEX2_BG_1CYC 0x09 #define S2DEX2_BG_COPY 0x0A #define S2DEX2_OBJ_RENDERMODE 0x0B #endif mupen64plus-video-gliden64/src/L3DEX2.cpp000664 001750 001750 00000004443 12655644434 021040 0ustar00sergiosergio000000 000000 #include "GLideN64.h" #include "Debug.h" #include "F3D.h" #include "F3DEX.h" #include "F3DEX2.h" #include "L3DEX2.h" #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gSP.h" #include "gDP.h" #include "GBI.h" void L3DEX2_Line3D( u32 w0, u32 w1 ) { u32 wd = _SHIFTR( (w0 + 1), 0, 8 ); if (wd == 0) gSPLine3D( _SHIFTR( w0, 17, 7 ), _SHIFTR( w0, 9, 7 ), 0 ); else gSPLineW3D( _SHIFTR( w0, 17, 7 ), _SHIFTR( w0, 9, 7 ), wd, 0 ); } void L3DEX2_Init() { gSPSetupFunctions(); // Set GeometryMode flags GBI_InitFlags( F3DEX2 ); GBI.PCStackSize = 18; // GBI Command Command Value Command Function // GBI_SetGBI( G_BG_COPY, 0x0A, S2DEX_BG_Copy ); GBI_SetGBI( G_RDPHALF_2, F3DEX2_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_SETOTHERMODE_H, F3DEX2_SETOTHERMODE_H, F3DEX2_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3DEX2_SETOTHERMODE_L, F3DEX2_SetOtherMode_L ); GBI_SetGBI( G_RDPHALF_1, F3DEX2_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_SPNOOP, F3DEX2_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_ENDDL, F3DEX2_ENDDL, F3D_EndDL ); GBI_SetGBI( G_DL, F3DEX2_DL, F3D_DList ); GBI_SetGBI( G_LOAD_UCODE, F3DEX2_LOAD_UCODE, F3DEX_Load_uCode ); GBI_SetGBI( G_MOVEMEM, F3DEX2_MOVEMEM, F3DEX2_MoveMem ); GBI_SetGBI( G_MOVEWORD, F3DEX2_MOVEWORD, F3DEX2_MoveWord ); GBI_SetGBI( G_MTX, F3DEX2_MTX, F3DEX2_Mtx ); GBI_SetGBI( G_GEOMETRYMODE, F3DEX2_GEOMETRYMODE, F3DEX2_GeometryMode ); GBI_SetGBI( G_POPMTX, F3DEX2_POPMTX, F3DEX2_PopMtx ); GBI_SetGBI( G_TEXTURE, F3DEX2_TEXTURE, F3DEX2_Texture ); GBI_SetGBI( G_DMA_IO, F3DEX2_DMA_IO, F3DEX2_DMAIO ); GBI_SetGBI( G_SPECIAL_1, F3DEX2_SPECIAL_1, F3DEX2_Special_1 ); GBI_SetGBI( G_SPECIAL_2, F3DEX2_SPECIAL_2, F3DEX2_Special_2 ); GBI_SetGBI( G_SPECIAL_3, F3DEX2_SPECIAL_3, F3DEX2_Special_3 ); GBI_SetGBI( G_VTX, F3DEX2_VTX, F3DEX2_Vtx ); GBI_SetGBI( G_MODIFYVTX, F3DEX2_MODIFYVTX, F3DEX_ModifyVtx ); GBI_SetGBI( G_CULLDL, F3DEX2_CULLDL, F3DEX_CullDL ); GBI_SetGBI( G_BRANCH_Z, F3DEX2_BRANCH_Z, F3DEX_Branch_Z ); // GBI_SetGBI( G_TRI1, F3DEX2_TRI1, F3DEX2_Tri1 ); // GBI_SetGBI( G_TRI2, F3DEX2_TRI2, F3DEX_Tri2 ); // GBI_SetGBI( G_QUAD, F3DEX2_QUAD, F3DEX2_Quad ); GBI_SetGBI( G_LINE3D, L3DEX2_LINE3D, L3DEX2_Line3D ); } mupen64plus-video-gliden64/src/F3DEX2.cpp000664 001750 001750 00000012110 12655644434 021020 0ustar00sergiosergio000000 000000 #include #include "GLideN64.h" #include "Debug.h" #include "F3D.h" #include "F3DEX.h" #include "F3DEX2.h" #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gSP.h" #include "gDP.h" #include "GBI.h" #include "OpenGL.h" using namespace std; void F3DEX2_Mtx( u32 w0, u32 w1 ) { gSPMatrix( w1, _SHIFTR( w0, 0, 8 ) ^ G_MTX_PUSH ); } void F3DEX2_MoveMem( u32 w0, u32 w1 ) { switch (_SHIFTR( w0, 0, 8 )) { case F3DEX2_MV_VIEWPORT: gSPViewport( w1 ); break; case G_MV_MATRIX: gSPForceMatrix( w1 ); // force matrix takes two commands RSP.PC[RSP.PCi] += 8; break; case G_MV_LIGHT: { const u32 offset = (_SHIFTR(w0, 5, 11))&0x7F8; const u32 n = offset / 24; if (n < 2) gSPLookAt(w1, n); else gSPLight(w1, n - 1); } break; } } void F3DEX2_Vtx( u32 w0, u32 w1 ) { u32 n = _SHIFTR( w0, 12, 8 ); gSPVertex( w1, n, _SHIFTR( w0, 1, 7 ) - n ); } void F3DEX2_Reserved1( u32 w0, u32 w1 ) { } void F3DEX2_Tri1( u32 w0, u32 w1 ) { gSP1Triangle( _SHIFTR( w0, 17, 7 ), _SHIFTR( w0, 9, 7 ), _SHIFTR( w0, 1, 7 )); } void F3DEX2_Line3D( u32 w0, u32 w1 ) { assert(false); } void F3DEX2_PopMtx( u32 w0, u32 w1 ) { gSPPopMatrixN( 0, w1 >> 6 ); } void F3DEX2_MoveWord( u32 w0, u32 w1 ) { switch (_SHIFTR( w0, 16, 8 )) { case G_MW_FORCEMTX: // Handled in movemem break; case G_MW_MATRIX: gSPInsertMatrix( _SHIFTR( w0, 0, 16 ), w1 ); break; case G_MW_NUMLIGHT: gSPNumLights( w1 / 24 ); break; case G_MW_CLIP: gSPClipRatio( w1 ); break; case G_MW_SEGMENT: gSPSegment( _SHIFTR( w0, 2, 4 ) , w1 & 0x00FFFFFF ); break; case G_MW_FOG: gSPFogFactor( (s16)_SHIFTR( w1, 16, 16 ), (s16)_SHIFTR( w1, 0, 16 ) ); //offset must be 0 for move_fog, but it can be non zero in Nushi Zuri 64 - Shiokaze ni Notte //low-level display list has setothermode commands in this place, so this is obviously not move_fog. if (_SHIFTR(w0, 0, 16) == 0x04) gDPSetTextureLUT((w1 == 0xffffffff) ? G_TT_NONE : G_TT_RGBA16); break; case G_MW_LIGHTCOL: gSPLightColor((_SHIFTR( w0, 0, 16 ) / 24) + 1, w1 ); break; case G_MW_PERSPNORM: gSPPerspNormalize( w1 ); break; } } void F3DEX2_Texture( u32 w0, u32 w1 ) { gSPTexture( _FIXED2FLOAT( _SHIFTR( w1, 16, 16 ), 16 ), _FIXED2FLOAT( _SHIFTR( w1, 0, 16 ), 16 ), _SHIFTR( w0, 11, 3 ), _SHIFTR( w0, 8, 3 ), _SHIFTR( w0, 1, 7 ) ); } void F3DEX2_SetOtherMode_H( u32 w0, u32 w1 ) { const u32 length = _SHIFTR(w0, 0, 8) + 1; const u32 shift = max(0, (s32)(32 - _SHIFTR(w0, 8, 8) - length)); gSPSetOtherMode_H(length, shift, w1); } void F3DEX2_SetOtherMode_L( u32 w0, u32 w1 ) { const u32 length = _SHIFTR(w0, 0, 8) + 1; const u32 shift = max(0, (s32)(32 - _SHIFTR(w0, 8, 8) - length)); gSPSetOtherMode_L(length, shift, w1); } void F3DEX2_GeometryMode( u32 w0, u32 w1 ) { gSPGeometryMode( ~_SHIFTR( w0, 0, 24 ), w1 ); } void F3DEX2_DMAIO( u32 w0, u32 w1 ) { } void F3DEX2_Special_1( u32 w0, u32 w1 ) { gSPDlistCount(_SHIFTR( w0, 0, 8 ), w1); } void F3DEX2_Special_2( u32 w0, u32 w1 ) { } void F3DEX2_Special_3( u32 w0, u32 w1 ) { } void F3DEX2_Quad( u32 w0, u32 w1 ) { gSP2Triangles( _SHIFTR( w0, 17, 7 ), _SHIFTR( w0, 9, 7 ), _SHIFTR( w0, 1, 7 ), 0, _SHIFTR( w1, 17, 7 ), _SHIFTR( w1, 9, 7 ), _SHIFTR( w1, 1, 7 ), 0 ); } void F3DEX2_Init() { gSPSetupFunctions(); // Set GeometryMode flags GBI_InitFlags( F3DEX2 ); GBI.PCStackSize = 18; // GBI Command Command Value Command Function GBI_SetGBI( G_RDPHALF_2, F3DEX2_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_SETOTHERMODE_H, F3DEX2_SETOTHERMODE_H, F3DEX2_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3DEX2_SETOTHERMODE_L, F3DEX2_SetOtherMode_L ); GBI_SetGBI( G_RDPHALF_1, F3DEX2_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_SPNOOP, F3DEX2_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_ENDDL, F3DEX2_ENDDL, F3D_EndDL ); GBI_SetGBI( G_DL, F3DEX2_DL, F3D_DList ); GBI_SetGBI( G_LOAD_UCODE, F3DEX2_LOAD_UCODE, F3DEX_Load_uCode ); GBI_SetGBI( G_MOVEMEM, F3DEX2_MOVEMEM, F3DEX2_MoveMem ); GBI_SetGBI( G_MOVEWORD, F3DEX2_MOVEWORD, F3DEX2_MoveWord ); GBI_SetGBI( G_MTX, F3DEX2_MTX, F3DEX2_Mtx ); GBI_SetGBI( G_GEOMETRYMODE, F3DEX2_GEOMETRYMODE, F3DEX2_GeometryMode ); GBI_SetGBI( G_POPMTX, F3DEX2_POPMTX, F3DEX2_PopMtx ); GBI_SetGBI( G_TEXTURE, F3DEX2_TEXTURE, F3DEX2_Texture ); GBI_SetGBI( G_DMA_IO, F3DEX2_DMA_IO, F3DEX2_DMAIO ); GBI_SetGBI( G_SPECIAL_1, F3DEX2_SPECIAL_1, F3DEX2_Special_1 ); GBI_SetGBI( G_SPECIAL_2, F3DEX2_SPECIAL_2, F3DEX2_Special_2 ); GBI_SetGBI( G_SPECIAL_3, F3DEX2_SPECIAL_3, F3DEX2_Special_3 ); GBI_SetGBI( G_VTX, F3DEX2_VTX, F3DEX2_Vtx ); GBI_SetGBI( G_MODIFYVTX, F3DEX2_MODIFYVTX, F3DEX_ModifyVtx ); GBI_SetGBI( G_CULLDL, F3DEX2_CULLDL, F3DEX_CullDL ); GBI_SetGBI( G_BRANCH_Z, F3DEX2_BRANCH_Z, F3DEX_Branch_Z ); GBI_SetGBI( G_TRI1, F3DEX2_TRI1, F3DEX2_Tri1 ); GBI_SetGBI( G_TRI2, F3DEX2_TRI2, F3DEX_Tri2 ); GBI_SetGBI( G_QUAD, F3DEX2_QUAD, F3DEX2_Quad ); GBI_SetGBI( G_LINE3D, F3DEX2_LINE3D, F3DEX2_Line3D ); } gles2rice/src/RSP_GBI2_ext.h000664 001750 001750 00000002566 12655644434 016636 0ustar00sergiosergio000000 000000 /* Copyright (C) 2002 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // Some new GBI2 extension ucodes void RSP_GBI2_DL_Count(Gfx *gfx) { SP_Timing(DP_Minimal); DP_Timing(DP_Minimal); // This cmd is likely to execute number of ucode at the given address uint32_t dwAddr = RSPSegmentAddr((gfx->words.w1)); { gDlistStackPointer++; gDlistStack[gDlistStackPointer].pc = dwAddr; gDlistStack[gDlistStackPointer].countdown = ((gfx->words.w0)&0xFFFF); } } void RSP_GBI2_0x8(Gfx *gfx) { if( ((gfx->words.w0)&0x00FFFFFF) == 0x2F && ((gfx->words.w1)&0xFF000000) == 0x80000000 ) { // V-Rally 64 RSP_S2DEX_SPObjLoadTxRectR(gfx); } else { RSP_RDP_Nothing(gfx); } } mupen64plus-core/src/si/eeprom.h000664 001750 001750 00000004036 12655644434 017714 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - eeprom.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_SI_EEPROM_H #define M64P_SI_EEPROM_H #include #include struct eeprom { /* external eep storage */ void* user_data; void (*save)(void*); uint8_t* data; size_t size; uint16_t id; }; void eeprom_save(struct eeprom* eeprom); void format_eeprom(uint8_t* eeprom, size_t size); void eeprom_status_command(struct eeprom* eeprom, uint8_t* cmd); void eeprom_read_command(struct eeprom* eeprom, uint8_t* cmd); void eeprom_write_command(struct eeprom* eeprom, uint8_t* cmd); #endif mupen64plus-core/src/main/list.h000664 001750 001750 00000010142 12655644434 017704 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - util.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2012 Mupen64plus development team * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef __LIST_H__ #define __LIST_H__ #ifdef __cplusplus extern "C" { #endif #include #include "osal/preproc.h" struct list_head { struct list_head *prev; struct list_head *next; }; #define LIST_HEAD(list) \ struct list_head list = { &(list), &(list) } static osal_inline void INIT_LIST_HEAD(struct list_head *head) { head->next = head; head->prev = head; } static osal_inline void list_add(struct list_head *new_item, struct list_head *head) { struct list_head *next = head->next; next->prev = new_item; new_item->next = next; new_item->prev = head; head->next = new_item; } static osal_inline void list_add_tail(struct list_head *new_item, struct list_head *head) { struct list_head *prev = head->prev; prev->next = new_item; new_item->next = head; new_item->prev = prev; head->prev = new_item; } static osal_inline void list_del(struct list_head *entry) { struct list_head *next = entry->next; struct list_head *prev = entry->prev; next->prev = prev; prev->next = next; } static osal_inline void list_del_init(struct list_head *entry) { list_del(entry); INIT_LIST_HEAD(entry); } static osal_inline int list_empty(const struct list_head *head) { return (head->next == head); } #ifdef __GNUC__ #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) #else #define container_of(ptr, type, member) \ ((type *)((char *)(ptr) - offsetof(type, member))) #endif #define list_entry(ptr, type, member) container_of(ptr, type, member) #define list_first_entry(ptr, type, member) \ list_entry((ptr)->next, type, member) #define list_for_each_t(pos, head) \ for (pos = (head)->next; pos != (head); pos = pos->next) #define list_for_each_entry_t(pos, head, type, member) \ for (pos = list_entry((head)->next, type, member); \ &pos->member != (head); \ pos = list_entry(pos->member.next, type, member)) #define list_for_each_safe_t(pos, safe, head) \ for (pos = (head)->next, safe = pos->next; pos != (head); \ pos = safe, safe = pos->next) #define list_for_each_entry_safe_t(pos, safe, head, type, member) \ for (pos = list_entry((head)->next, type, member), \ safe = list_entry(pos->member.next, type, member); \ &pos->member != (head); \ pos = safe, \ safe = list_entry(safe->member.next, type, member)) #ifdef __cplusplus } #endif #endif mupen64plus-video-gliden64/src/GLideNHQ/TxQuantize.cpp000664 001750 001750 00000061362 12655644434 023611 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef __MSC__ #pragma warning(disable: 4786) #endif /* NOTE: The codes are not optimized. They can be made faster. */ #include #include #include "TxQuantize.h" TxQuantize::TxQuantize() { _txUtil = new TxUtil(); /* get number of CPU cores. */ _numcore = _txUtil->getNumberofProcessors(); } TxQuantize::~TxQuantize() { delete _txUtil; } const volatile unsigned char Five2Eight[32] = { 0, // 00000 = 00000000 8, // 00001 = 00001000 16, // 00010 = 00010000 25, // 00011 = 00011001 33, // 00100 = 00100001 41, // 00101 = 00101001 49, // 00110 = 00110001 58, // 00111 = 00111010 66, // 01000 = 01000010 74, // 01001 = 01001010 82, // 01010 = 01010010 90, // 01011 = 01011010 99, // 01100 = 01100011 107, // 01101 = 01101011 115, // 01110 = 01110011 123, // 01111 = 01111011 132, // 10000 = 10000100 140, // 10001 = 10001100 148, // 10010 = 10010100 156, // 10011 = 10011100 165, // 10100 = 10100101 173, // 10101 = 10101101 181, // 10110 = 10110101 189, // 10111 = 10111101 197, // 11000 = 11000101 206, // 11001 = 11001110 214, // 11010 = 11010110 222, // 11011 = 11011110 230, // 11100 = 11100110 239, // 11101 = 11101111 247, // 11110 = 11110111 255 // 11111 = 11111111 }; const volatile unsigned char One2Eight[2] = { 0, // 0 = 00000000 255, // 1 = 11111111 }; void TxQuantize::ARGB1555_ARGB8888(uint32* src, uint32* dest, int width, int height) { const int siz = (width * height) >> 1; uint8 r, g, b, a; uint32 color; for (int i = 0; i < siz; ++i) { color = (*src) & 0xffff; r = Five2Eight[color >> 11]; g = Five2Eight[(color >> 6) & 0x001f]; b = Five2Eight[(color >> 1) & 0x001f]; a = One2Eight [(color ) & 0x0001]; *dest = (a << 24) | (b << 16) | (g << 8) | r; ++dest; color = (*src) >> 16; r = Five2Eight[color >> 11]; g = Five2Eight[(color >> 6) & 0x001f]; b = Five2Eight[(color >> 1) & 0x001f]; a = One2Eight [(color ) & 0x0001]; *dest = (a << 24) | (b << 16) | (g << 8) | r; ++dest; ++src; } } void TxQuantize::ARGB4444_ARGB8888(uint32* src, uint32* dest, int width, int height) { int siz = (width * height) >> 1; int i; for (i = 0; i < siz; i++) { *dest = ((*src & 0x0000f000) << 12) | ((*src & 0x00000f00) << 8) | ((*src & 0x000000f0) << 4) | (*src & 0x0000000f); *dest |= (*dest << 4); dest++; *dest = ((*src & 0xf0000000) | ((*src & 0x0f000000) >> 4) | ((*src & 0x00f00000) >> 8) | ((*src & 0x000f0000) >> 12)); *dest |= (*dest >> 4); dest++; src++; } } void TxQuantize::RGB565_ARGB8888(uint32* src, uint32* dest, int width, int height) { int siz = (width * height) >> 1; int i; for (i = 0; i < siz; i++) { *dest = (0xff000000 | ((*src & 0x0000f800) << 8) | ((*src & 0x0000e000) << 3) | ((*src & 0x000007e0) << 5) | ((*src & 0x00000600) >> 1) | ((*src & 0x0000001f) << 3) | ((*src & 0x0000001c) >> 2)); dest++; *dest = (0xff000000 | ((*src & 0xf8000000) >> 8) | ((*src & 0xe0000000) >> 13) | ((*src & 0x07e00000) >> 11) | ((*src & 0x06000000) >> 17) | ((*src & 0x001f0000) >> 13) | ((*src & 0x001c0000) >> 18)); dest++; src++; } } void TxQuantize::A8_ARGB8888(uint32* src, uint32* dest, int width, int height) { int siz = (width * height) >> 2; int i; for (i = 0; i < siz; i++) { *dest = (*src & 0x000000ff); *dest |= (*dest << 8); *dest |= (*dest << 16); dest++; *dest = (*src & 0x0000ff00); *dest |= (*dest >> 8); *dest |= (*dest << 16); dest++; *dest = (*src & 0x00ff0000); *dest |= (*dest << 8); *dest |= (*dest >> 16); dest++; *dest = (*src & 0xff000000); *dest |= (*dest >> 8); *dest |= (*dest >> 16); dest++; src++; } } void TxQuantize::AI44_ARGB8888(uint32* src, uint32* dest, int width, int height) { int siz = (width * height) >> 2; int i; for (i = 0; i < siz; i++) { *dest = (*src & 0x0000000f); *dest |= ((*dest << 8) | (*dest << 16)); *dest |= ((*src & 0x000000f0) << 20); *dest |= (*dest << 4); dest++; *dest = (*src & 0x00000f00); *dest |= ((*dest << 8) | (*dest >> 8)); *dest |= ((*src & 0x0000f000) << 12); *dest |= (*dest << 4); dest++; *dest = (*src & 0x000f0000); *dest |= ((*dest >> 8) | (*dest >> 16)); *dest |= ((*src & 0x00f00000) << 4); *dest |= (*dest << 4); dest++; *dest = ((*src & 0x0f000000) >> 4); *dest |= ((*dest >> 8) | (*dest >> 16)); *dest |= (*src & 0xf0000000); *dest |= (*dest >> 4); dest++; src++; } } void TxQuantize::AI88_ARGB8888(uint32* src, uint32* dest, int width, int height) { int siz = (width * height) >> 1; int i; for (i = 0; i < siz; i++) { *dest = (*src & 0x000000ff); *dest |= ((*dest << 8) | (*dest << 16)); *dest |= ((*src & 0x0000ff00) << 16); dest++; *dest = (*src & 0x00ff0000); *dest |= ((*dest >> 8) | (*dest >> 16)); *dest |= (*src & 0xff000000); dest++; src++; } } void TxQuantize::ARGB8888_ARGB1555(uint32* src, uint32* dest, int width, int height) { const int siz = (width * height) >> 1; uint32 color; uint32 r, g, b; for (int i = 0; i < siz; i++) { color = *src; *dest = ((color & 0xff000000) ? 0x0001 : 0x0000); r = (color & 0x000000FF) >> 3; g = (color & 0x0000FF00) >> 11; b = (color & 0x00FF0000) >> 19; *dest |= (r<<11)|(g<<6)|(b<<1); src++; color = *src; *dest |= ((color & 0xff000000) ? 0x00010000 : 0x0000); r = (color & 0x000000FF) >> 3; g = (color & 0x0000FF00) >> 11; b = (color & 0x00FF0000) >> 19; *dest |= (r<<27)|(g<<22)|(b<<17); src++; dest++; } } void TxQuantize::ARGB8888_ARGB4444(uint32* src, uint32* dest, int width, int height) { int siz = (width * height) >> 1; int i; for (i = 0; i < siz; i++) { *dest = (((*src & 0xf0000000) >> 16) | ((*src & 0x00f00000) >> 12) | ((*src & 0x0000f000) >> 8) | ((*src & 0x000000f0) >> 4)); src++; *dest |= ((*src & 0xf0000000) | ((*src & 0x00f00000) << 4) | ((*src & 0x0000f000) << 8) | ((*src & 0x000000f0) << 12)); src++; dest++; } } void TxQuantize::ARGB8888_RGB565(uint32* src, uint32* dest, int width, int height) { int siz = (width * height) >> 1; int i; for (i = 0; i < siz; i++) { *dest = (((*src & 0x000000f8) >> 3) | ((*src & 0x0000fc00) >> 5) | ((*src & 0x00f80000) >> 8)); src++; *dest |= (((*src & 0x000000f8) << 13) | ((*src & 0x0000fc00) << 11) | ((*src & 0x00f80000) << 8)); src++; dest++; } } void TxQuantize::ARGB8888_A8(uint32* src, uint32* dest, int width, int height) { int siz = (width * height) >> 2; int i; for (i = 0; i < siz; i++) { *dest = (*src & 0x0000ff00) >> 8; src++; *dest |= (*src & 0x0000ff00); src++; *dest |= ((*src & 0x0000ff00) << 8); src++; *dest |= ((*src & 0x0000ff00) << 16); src++; dest++; } } void TxQuantize::ARGB8888_AI44(uint32* src, uint32* dest, int width, int height) { int siz = (width * height) >> 2; int i; for (i = 0; i < siz; i++) { *dest = (((*src & 0xf0000000) >> 24) | ((*src & 0x0000f000) >> 12)); src++; *dest |= (((*src & 0xf0000000) >> 16) | ((*src & 0x0000f000) >> 4)); src++; *dest |= (((*src & 0xf0000000) >> 8) | ((*src & 0x0000f000) << 4)); src++; *dest |= ((*src & 0xf0000000) | ((*src & 0x0000f000) << 12)); src++; dest++; } } void TxQuantize::ARGB8888_AI88(uint32* src, uint32* dest, int width, int height) { int siz = (width * height) >> 1; int i; for (i = 0; i < siz; i++) { *dest = (((*src & 0xff000000) >> 16) | ((*src & 0x0000ff00) >> 8)); src++; *dest |= ((*src & 0xff000000) | ((*src & 0x0000ff00) << 8)); src++; dest++; } } /* R.W. Floyd and L. Steinberg, An adaptive algorithm * for spatial grey scale, Proceedings of the Society * of Information Display 17, pp75-77, 1976 */ void TxQuantize::ARGB8888_RGB565_ErrD(uint32* src, uint32* dst, int width, int height) { /* Floyd-Steinberg error-diffusion halftoning */ int i, x, y; int qr, qg, qb; /* quantized incoming values */ int ir, ig, ib; /* incoming values */ int t; int *errR = new int[width]; int *errG = new int[width]; int *errB = new int[width]; uint16 *dest = (uint16 *)dst; for (i = 0; i < width; i++) errR[i] = errG[i] = errB[i] = 0; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { /* incoming pixel values */ ir = ((*src >> 16) & 0xFF) * 10000; ig = ((*src >> 8) & 0xFF) * 10000; ib = ((*src ) & 0xFF) * 10000; if (x == 0) qr = qg = qb = 0; /* quantize pixel values. * qr * 0.4375 is the error from the pixel to the left, * errR is the error from the pixel to the top, top left, and top right */ /* qr * 0.4375 is the error distribution to the EAST in * the previous loop */ ir += errR[x] + qr * 4375 / 10000; ig += errG[x] + qg * 4375 / 10000; ib += errB[x] + qb * 4375 / 10000; /* error distribution to the SOUTH-EAST in the previous loop * can't calculate in the previous loop because it steps on * the above quantization */ errR[x] = qr * 625 / 10000; errG[x] = qg * 625 / 10000; errB[x] = qb * 625 / 10000; qr = ir; qg = ig; qb = ib; /* clamp */ if (qr < 0) qr = 0; else if (qr > 2550000) qr = 2550000; if (qg < 0) qg = 0; else if (qg > 2550000) qg = 2550000; if (qb < 0) qb = 0; else if (qb > 2550000) qb = 2550000; /* convert to RGB565 */ qr = qr * 0x1F / 2550000; qg = qg * 0x3F / 2550000; qb = qb * 0x1F / 2550000; /* this is the dithered pixel */ t = (qr << 11) | (qg << 5) | qb; /* compute the errors */ qr = ((qr << 3) | (qr >> 2)) * 10000; qg = ((qg << 2) | (qg >> 4)) * 10000; qb = ((qb << 3) | (qb >> 2)) * 10000; qr = ir - qr; qg = ig - qg; qb = ib - qb; /* compute the error distributions */ /* Floyd-Steinberg filter * 7/16 (=0.4375) to the EAST * 5/16 (=0.3125) to the SOUTH * 1/16 (=0.0625) to the SOUTH-EAST * 3/16 (=0.1875) to the SOUTH-WEST * * x 7/16 * 3/16 5/16 1/16 */ /* SOUTH-WEST */ if (x > 1) { errR[x - 1] += qr * 1875 / 10000; errG[x - 1] += qg * 1875 / 10000; errB[x - 1] += qb * 1875 / 10000; } /* SOUTH */ errR[x] += qr * 3125 / 10000; errG[x] += qg * 3125 / 10000; errB[x] += qb * 3125 / 10000; *dest = (t & 0xFFFF); dest++; src++; } } delete [] errR; delete [] errG; delete [] errB; } void TxQuantize::ARGB8888_ARGB1555_ErrD(uint32* src, uint32* dst, int width, int height) { /* Floyd-Steinberg error-diffusion halftoning */ int i, x, y; int qr, qg, qb; /* quantized incoming values */ int ir, ig, ib; /* incoming values */ int t; int *errR = new int[width]; int *errG = new int[width]; int *errB = new int[width]; uint16 *dest = (uint16 *)dst; for (i = 0; i < width; i++) errR[i] = errG[i] = errB[i] = 0; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { /* incoming pixel values */ ir = ((*src >> 16) & 0xFF) * 10000; ig = ((*src >> 8) & 0xFF) * 10000; ib = ((*src ) & 0xFF) * 10000; if (x == 0) qr = qg = qb = 0; /* quantize pixel values. * qr * 0.4375 is the error from the pixel to the left, * errR is the error from the pixel to the top, top left, and top right */ /* qr * 0.4375 is the error distribution to the EAST in * the previous loop */ ir += errR[x] + qr * 4375 / 10000; ig += errG[x] + qg * 4375 / 10000; ib += errB[x] + qb * 4375 / 10000; /* error distribution to the SOUTH-EAST of the previous loop. * cannot calculate in the previous loop because it steps on * the above quantization */ errR[x] = qr * 625 / 10000; errG[x] = qg * 625 / 10000; errB[x] = qb * 625 / 10000; qr = ir; qg = ig; qb = ib; /* clamp */ if (qr < 0) qr = 0; else if (qr > 2550000) qr = 2550000; if (qg < 0) qg = 0; else if (qg > 2550000) qg = 2550000; if (qb < 0) qb = 0; else if (qb > 2550000) qb = 2550000; /* convert to RGB555 */ qr = qr * 0x1F / 2550000; qg = qg * 0x1F / 2550000; qb = qb * 0x1F / 2550000; /* this is the dithered pixel */ t = (qr << 10) | (qg << 5) | qb; t |= ((*src >> 24) ? 0x8000 : 0); /* compute the errors */ qr = ((qr << 3) | (qr >> 2)) * 10000; qg = ((qg << 3) | (qg >> 2)) * 10000; qb = ((qb << 3) | (qb >> 2)) * 10000; qr = ir - qr; qg = ig - qg; qb = ib - qb; /* compute the error distributions */ /* Floyd-Steinberg filter * 7/16 (=0.4375) to the EAST * 5/16 (=0.3125) to the SOUTH * 1/16 (=0.0625) to the SOUTH-EAST * 3/16 (=0.1875) to the SOUTH-WEST * * x 7/16 * 3/16 5/16 1/16 */ /* SOUTH-WEST */ if (x > 1) { errR[x - 1] += qr * 1875 / 10000; errG[x - 1] += qg * 1875 / 10000; errB[x - 1] += qb * 1875 / 10000; } /* SOUTH */ errR[x] += qr * 3125 / 10000; errG[x] += qg * 3125 / 10000; errB[x] += qb * 3125 / 10000; *dest = (t & 0xFFFF); dest++; src++; } } delete [] errR; delete [] errG; delete [] errB; } void TxQuantize::ARGB8888_ARGB4444_ErrD(uint32* src, uint32* dst, int width, int height) { /* Floyd-Steinberg error-diffusion halftoning */ /* NOTE: alpha dithering looks better for alpha gradients, but are prone * to producing noisy speckles for constant or step level alpha. Output * results should always be checked. */ boolean ditherAlpha = 0; int i, x, y; int qr, qg, qb, qa; /* quantized incoming values */ int ir, ig, ib, ia; /* incoming values */ int t; int *errR = new int[width]; int *errG = new int[width]; int *errB = new int[width]; int *errA = new int[width]; uint16 *dest = (uint16 *)dst; for (i = 0; i < width; i++) errR[i] = errG[i] = errB[i] = errA[i] = 0; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { /* incoming pixel values */ ir = ((*src >> 16) & 0xFF) * 10000; ig = ((*src >> 8) & 0xFF) * 10000; ib = ((*src ) & 0xFF) * 10000; ia = ((*src >> 24) & 0xFF) * 10000; if (x == 0) qr = qg = qb = qa = 0; /* quantize pixel values. * qr * 0.4375 is the error from the pixel to the left, * errR is the error from the pixel to the top, top left, and top right */ /* qr * 0.4375 is the error distribution to the EAST in * the previous loop */ ir += errR[x] + qr * 4375 / 10000; ig += errG[x] + qg * 4375 / 10000; ib += errB[x] + qb * 4375 / 10000; ia += errA[x] + qa * 4375 / 10000; /* error distribution to the SOUTH-EAST of the previous loop. * cannot calculate in the previous loop because it steps on * the above quantization */ errR[x] = qr * 625 / 10000; errG[x] = qg * 625 / 10000; errB[x] = qb * 625 / 10000; errA[x] = qa * 625 / 10000; qr = ir; qg = ig; qb = ib; qa = ia; /* clamp */ if (qr < 0) qr = 0; else if (qr > 2550000) qr = 2550000; if (qg < 0) qg = 0; else if (qg > 2550000) qg = 2550000; if (qb < 0) qb = 0; else if (qb > 2550000) qb = 2550000; if (qa < 0) qa = 0; else if (qa > 2550000) qa = 2550000; /* convert to RGB444 */ qr = qr * 0xF / 2550000; qg = qg * 0xF / 2550000; qb = qb * 0xF / 2550000; qa = qa * 0xF / 2550000; /* this is the value to be returned */ if (ditherAlpha) { t = (qa << 12) | (qr << 8) | (qg << 4) | qb; } else { t = (qr << 8) | (qg << 4) | qb; t |= (*src >> 16) & 0xF000; } /* compute the errors */ qr = ((qr << 4) | qr) * 10000; qg = ((qg << 4) | qg) * 10000; qb = ((qb << 4) | qb) * 10000; qa = ((qa << 4) | qa) * 10000; qr = ir - qr; qg = ig - qg; qb = ib - qb; qa = ia - qa; /* compute the error distributions */ /* Floyd-Steinberg filter * 7/16 (=0.4375) to the EAST * 5/16 (=0.3125) to the SOUTH * 1/16 (=0.0625) to the SOUTH-EAST * 3/16 (=0.1875) to the SOUTH-WEST * * x 7/16 * 3/16 5/16 1/16 */ /* SOUTH-WEST */ if (x > 1) { errR[x - 1] += qr * 1875 / 10000; errG[x - 1] += qg * 1875 / 10000; errB[x - 1] += qb * 1875 / 10000; errA[x - 1] += qa * 1875 / 10000; } /* SOUTH */ errR[x] += qr * 3125 / 10000; errG[x] += qg * 3125 / 10000; errB[x] += qb * 3125 / 10000; errA[x] += qa * 3125 / 10000; *dest = (t & 0xFFFF); dest++; src++; } } delete [] errR; delete [] errG; delete [] errB; delete [] errA; } void TxQuantize::ARGB8888_AI44_ErrD(uint32* src, uint32* dst, int width, int height) { /* Floyd-Steinberg error-diffusion halftoning */ /* NOTE: alpha dithering looks better for alpha gradients, but are prone * to producing noisy speckles for constant or step level alpha. Output * results should always be checked. */ boolean ditherAlpha = 0; int i, x, y; int qi, qa; /* quantized incoming values */ int ii, ia; /* incoming values */ int t; int *errI = new int[width]; int *errA = new int[width]; uint8 *dest = (uint8 *)dst; for (i = 0; i < width; i++) errI[i] = errA[i] = 0; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { /* 3dfx style Intensity = R * 0.299 + G * 0.587 + B * 0.114 */ ii = ((*src >> 16) & 0xFF) * 2990 + ((*src >> 8) & 0xFF) * 5870 + ((*src ) & 0xFF) * 1140; ia = ((*src >> 24) & 0xFF) * 10000; if (x == 0) qi = qa = 0; /* quantize pixel values. * qi * 0.4375 is the error from the pixel to the left, * errI is the error from the pixel to the top, top left, and top right */ /* qi * 0.4375 is the error distrtibution to the EAST in * the previous loop */ ii += errI[x] + qi * 4375 / 10000; ia += errA[x] + qa * 4375 / 10000; /* error distribution to the SOUTH-EAST in the previous loop. * cannot calculate in the previous loop because it steps on * the above quantization */ errI[x] = qi * 625 / 10000; errA[x] = qa * 625 / 10000; qi = ii; qa = ia; /* clamp */ if (qi < 0) qi = 0; else if (qi > 2550000) qi = 2550000; if (qa < 0) qa = 0; else if (qa > 2550000) qa = 2550000; /* convert to I4 */ qi = qi * 0xF / 2550000; qa = qa * 0xF / 2550000; /* this is the value to be returned */ if (ditherAlpha) { t = (qa << 4) | qi; } else { t = qi; t |= ((*src >> 24) & 0xF0); } /* compute the errors */ qi = ((qi << 4) | qi) * 10000; qa = ((qa << 4) | qa) * 10000; qi = ii - qi; qa = ia - qa; /* compute the error distributions */ /* Floyd-Steinberg filter * 7/16 (=0.4375) to the EAST * 5/16 (=0.3125) to the SOUTH * 1/16 (=0.0625) to the SOUTH-EAST * 3/16 (=0.1875) to the SOUTH-WEST * * x 7/16 * 3/16 5/16 1/16 */ /* SOUTH-WEST */ if (x > 1) { errI[x - 1] += qi * 1875 / 10000; errA[x - 1] += qa * 1875 / 10000; } /* SOUTH */ errI[x] += qi * 3125 / 10000; errA[x] += qa * 3125 / 10000; *dest = t & 0xFF; dest++; src++; } } delete [] errI; delete [] errA; } void TxQuantize::ARGB8888_AI88_Slow(uint32* src, uint32* dst, int width, int height) { int x, y; uint16 *dest = (uint16 *)dst; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { #if 1 /* libpng style grayscale conversion. * Reduce RGB files to grayscale with or without alpha * using the equation given in Poynton's ColorFAQ at * * Copyright (c) 1998-01-04 Charles Poynton poynton at inforamp.net * * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B * * We approximate this with * * Y = 0.21268 * R + 0.7151 * G + 0.07217 * B * * which can be expressed with integers as * * Y = (6969 * R + 23434 * G + 2365 * B)/32768 * * The calculation is to be done in a linear colorspace. */ *dest = (((int)((((*src >> 16) & 0xFF) * 6969 + ((*src >> 8) & 0xFF) * 23434 + ((*src ) & 0xFF) * 2365) / 32768) & 0xFF) | (uint16)((*src >> 16) & 0xFF00)); #else /* 3dfx style Intensity = R * 0.299 + G * 0.587 + B * 0.114 * this is same as the standard NTSC gray scale conversion. */ *dest = (((int)((((*src >> 16) & 0xFF) * 299 + ((*src >> 8) & 0xFF) * 587 + ((*src ) & 0xFF) * 114) / 1000) & 0xFF) | (uint16)((*src >> 16) & 0xFF00)); #endif dest++; src++; } } } void TxQuantize::ARGB8888_I8_Slow(uint32* src, uint32* dst, int width, int height) { int x, y; uint8 *dest = (uint8 *)dst; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { #if 1 /* libpng style Intensity = (6969 * R + 23434 * G + 2365 * B)/32768 */ *dest = (int)((((*src >> 16) & 0xFF) * 6969 + ((*src >> 8) & 0xFF) * 23434 + ((*src ) & 0xFF) * 2365) / 32768) & 0xFF; #else /* 3dfx style Intensity = R * 0.299 + G * 0.587 + B * 0.114 * this is same as the standard NTSC gray scale conversion. */ *dest = (int)((((*src >>16) & 0xFF) * 299 + ((*src >> 8) & 0xFF) * 587 + ((*src ) & 0xFF) * 114) / 1000) & 0xFF; #endif dest++; src++; } } } void TxQuantize::P8_16BPP(uint32* src, uint32* dest, int width, int height, uint32* palette) { /* passed in palette is RGBA5551 format */ int i; int size = width * height; for (i = 0; i < size; i++) { ((uint16*)dest)[i] = ((uint16*)palette)[(int)(((uint8*)src)[i])]; ((uint16*)dest)[i] = ((((uint16*)dest)[i] << 15) | (((uint16*)dest)[i] >> 1)); } } boolean TxQuantize::quantize(uint8* src, uint8* dest, int width, int height, uint16 srcformat, uint16 destformat, boolean fastQuantizer) { typedef void (TxQuantize::*quantizerFunc)(uint32* src, uint32* dest, int width, int height); quantizerFunc quantizer; int bpp_shift = 0; if (destformat == GL_RGBA8 || destformat == GL_RGBA) { switch (srcformat) { case GL_RGB5_A1: quantizer = &TxQuantize::ARGB1555_ARGB8888; bpp_shift = 1; break; case GL_RGBA4: quantizer = &TxQuantize::ARGB4444_ARGB8888; bpp_shift = 1; break; case GL_RGB: quantizer = &TxQuantize::RGB565_ARGB8888; bpp_shift = 1; break; default: return 0; } unsigned int numcore = _numcore; unsigned int blkrow = 0; while (numcore > 1 && blkrow == 0) { blkrow = (height >> 2) / numcore; numcore--; } if (blkrow > 0 && numcore > 1) { std::thread *thrd[MAX_NUMCORE]; unsigned int i; int blkheight = blkrow << 2; unsigned int srcStride = (width * blkheight) << (2 - bpp_shift); unsigned int destStride = srcStride << bpp_shift; for (i = 0; i < numcore - 1; i++) { thrd[i] = new std::thread(std::bind(quantizer, this, (uint32*)src, (uint32*)dest, width, blkheight)); src += srcStride; dest += destStride; } thrd[i] = new std::thread(std::bind(quantizer, this, (uint32*)src, (uint32*)dest, width, height - blkheight * i)); for (i = 0; i < numcore; i++) { thrd[i]->join(); delete thrd[i]; } } else { (*this.*quantizer)((uint32*)src, (uint32*)dest, width, height); } } else if (srcformat == GL_RGBA8 || srcformat == GL_RGBA) { switch (destformat) { case GL_RGB5_A1: quantizer = fastQuantizer ? &TxQuantize::ARGB8888_ARGB1555 : &TxQuantize::ARGB8888_ARGB1555_ErrD; bpp_shift = 1; break; case GL_RGBA4: quantizer = fastQuantizer ? &TxQuantize::ARGB8888_ARGB4444 : &TxQuantize::ARGB8888_ARGB4444_ErrD; bpp_shift = 1; break; case GL_RGB: quantizer = fastQuantizer ? &TxQuantize::ARGB8888_RGB565 : &TxQuantize::ARGB8888_RGB565_ErrD; bpp_shift = 1; break; default: return 0; } unsigned int numcore = _numcore; unsigned int blkrow = 0; while (numcore > 1 && blkrow == 0) { blkrow = (height >> 2) / numcore; numcore--; } if (blkrow > 0 && numcore > 1) { std::thread *thrd[MAX_NUMCORE]; unsigned int i; int blkheight = blkrow << 2; unsigned int srcStride = (width * blkheight) << 2; unsigned int destStride = srcStride >> bpp_shift; for (i = 0; i < numcore - 1; i++) { thrd[i] = new std::thread(std::bind(quantizer, this, (uint32*)src, (uint32*)dest, width, blkheight)); src += srcStride; dest += destStride; } thrd[i] = new std::thread(std::bind(quantizer, this, (uint32*)src, (uint32*)dest, width, height - blkheight * i)); for (i = 0; i < numcore; i++) { thrd[i]->join(); delete thrd[i]; } } else { (*this.*quantizer)((uint32*)src, (uint32*)dest, width, height); } } else { return 0; } return 1; } mupen64plus-video-gliden64/src/GLideNHQ/TxTexCache.h000664 001750 001750 00000002367 12655644434 023142 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __TXTEXCACHE_H__ #define __TXTEXCACHE_H__ #include "TxCache.h" class TxTexCache : public TxCache { public: ~TxTexCache(); TxTexCache(int options, int cachesize, const wchar_t *path, const wchar_t *ident, dispInfoFuncExt callback); boolean add(uint64 checksum, /* checksum hi:palette low:texture */ GHQTexInfo *info); }; #endif /* __TXTEXCACHE_H__ */ mupen64plus-core/src/si/eeprom.c000664 001750 001750 00000005632 12655644434 017712 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - eeprom.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "eeprom.h" #include "../api/m64p_types.h" #include "../api/callbacks.h" #include void eeprom_save(struct eeprom* eeprom) { eeprom->save(eeprom->user_data); } void format_eeprom(uint8_t* eeprom, size_t size) { memset(eeprom, 0xff, size); } void eeprom_status_command(struct eeprom* eeprom, uint8_t* cmd) { /* check size */ if (cmd[1] != 3) { cmd[1] |= 0x40; if ((cmd[1] & 3) > 0) cmd[3] = (eeprom->id & 0xff); if ((cmd[1] & 3) > 1) cmd[4] = (eeprom->id >> 8); if ((cmd[1] & 3) > 2) cmd[5] = 0; } else { cmd[3] = (eeprom->id & 0xff); cmd[4] = (eeprom->id >> 8); cmd[5] = 0; } } void eeprom_read_command(struct eeprom* eeprom, uint8_t* cmd) { uint16_t address = cmd[3] * 8; uint8_t* data = &cmd[4]; /* read 8-byte block */ if (address < eeprom->size) { memcpy(data, &eeprom->data[address], 8); } else { DebugMessage(M64MSG_WARNING, "Invalid access to eeprom address=%04x", address); } } void eeprom_write_command(struct eeprom* eeprom, uint8_t* cmd) { uint16_t address = cmd[3] * 8; const uint8_t* data = &cmd[4]; /* write 8-byte block */ if (address < eeprom->size) { memcpy(&eeprom->data[address], data, 8); eeprom_save(eeprom); } else { DebugMessage(M64MSG_WARNING, "Invalid access to eeprom address=%04x", address); } } mupen64plus-core/src/r4300/cp0_private.h000664 001750 001750 00000003322 12655644434 020773 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - cp0_private.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_R4300_CP0_PRIVATE_H #define M64P_R4300_CP0_PRIVATE_H #include "cp0.h" extern unsigned int g_cp0_regs[CP0_REGS_COUNT]; int check_cop1_unusable(void); #endif /* M64P_R4300_CP0_PRIVATE_H */ mupen64plus-core/doc/emuwiki-api-doc/Mupen64Plus_v2.0_Plugin_API.txt000664 001750 001750 00000025502 12655644434 026223 0ustar00sergiosergio000000 000000 [[Mupen64Plus v2.0 Core API v1.0|Mupen64Plus v2.0 API]] = Mupen64Plus v2.0 Plugin API = This section lists all of the functions which are exported by the plugins. The front-end application should only use the PluginStartup, PluginShutdown, and PluginGetVersion functions. All other functions will only be called from the core. == Common Plugin API == These functions are present in all of the plugins. {| border="1" |Prototype |'''m64p_error PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context, void (*DebugCallback)(void *Context, int level, const char *Message))''' |- |Input Parameters |'''CoreLibHandle''' Dynamic library handle (defined in [[Mupen64Plus v2.0 headers#m64p_types.h|m64p_types.h]]) corresponding with the core mupen64plus library.
'''Context''' Pointer which will be passed back to the '''DebugCallback''' function. Can be NULL.
'''DebugCallback''' Pointer to function in front-end for receiving debug information and warnings from the plugin. This function must be thread-safe. Can be NULL. |- |Requirements |This function must be called before any other plugin functions. The Core library must already be started before calling this function. This function must be called before attaching the plugin to the core. |- |Usage |This function initializes plugin for use by allocating memory, creating data structures, and loading the configuration data. This function may return M64ERR_INCOMPATIBLE if an older core library is used with a newer plugin. |}
{| border="1" |Prototype |'''m64p_error PluginShutdown(void)''' |- |Requirements |This plugin should be detached from the core before calling this function. |- |Usage |This function destroys data structures and releases memory allocated by the plugin library. |}
{| border="1" |Prototype |'''m64p_error PluginGetVersion(m64p_plugin_type *PluginType, int *PluginVersion, int *APIVersion, const char **PluginNamePtr, int *Capabilities)''' |- |Input Parameters |'''PluginType''' Pointer to an enumerated type to store the plugin type of this plugin.
'''PluginVersion''' Pointer to an integer to store the version number of this plugin. Version number 2.1.3 would be stored as 0x00020103.
'''APIVersion''' Pointer to an integer to store the version number of the Core-Plugin API for this type of plugin used by this plugin.
'''PluginNamePtr''' Pointer to a const character pointer to receive the name of this plugin. The const char * which is returned must point to a persistent string (ie, not stored on the stack).
'''Capabilities''' Pointer to an integer to store a logically-or'd set of flags which specify the capabilities of the plugin which were built into the library during compilation. These are currently only defined for the core, so this will always return 0 for a plugin. |- |Usage |This function retrieves version information from the plugin. This function is the same for the core library and the plugins, so that a front-end may examine all shared libraries in a directory and determine their types. Any of the input parameters may be set to NULL and this function will succeed but won't return the corresponding information. |} == Video Plugin API == === Mupen64Plus v2.0 Video Plugin API === {| |void ChangeWindow(void); |Toggle Fullscreen/Windowed mode |- |BOOL InitiateGFX(GFX_INFO Gfx_Info); |Called during CoreAttachPlugin to send info about the emulator core to the graphics plugin and start up the graphics sub-system. This should create the rendering window and the OpenGL context. |- |void MoveScreen(int xpos, int ypos); |This function is called in response to the emulator receiving a WM_MOVE, passing the xpos and ypos from that message. |- |void ProcessDList(void); |Process high-level graphics D-list. (not currently used) |- |void ProcessRDPList(void); |Process low-level graphics D-list. |- |void RomClosed(void); |Called after the emulator is stopped. |- |int RomOpen(void); |Called just before the emulator begins executing a ROM. '''***changed*** - this function now returns an int (boolean)''' |- |void ShowCFB (void); |Called from the RSP plugin to signal a condition to the video plugin. |- |void UpdateScreen(void); |This function is called in response to a VSync condition if the VI bit in MI_INTR_REG is set |- |void ViStatusChanged(void); |This function is called to notify the video plugin that the ViStatus registers value has been changed. |- |void ViWidthChanged(void); |This function is called to notify the video plugin that the ViWidth registers value has been changed. |- |void ReadScreen2(void *dest, int *width, int *height, int front); |This function reads the pixels of the frame buffer that is either currently displayed (front != 0) or being drawn (front == 0) |- |void SetRenderingCallback(void (*callback)(int bScreenRedrawn)); |Allows the core to register a callback function that will be called by the graphics plugin just before the the frame buffers are swapped. '''***changed*** - as of video api v2.1.0, the callback function must take a single int (boolean) parameter, which tells the core whether or not the screen has been redrawn since the last time the callback was called. This is used to prevent screenshots from containing OSD text.''' |- |void ResizeVideoOutput(int width, int height); |'''***new*** function added in video api v2.2.0''' This function notifies the video plugin that the output video window has changed size. If resizing is supported, the video plugin should update its internal state to reflect the new window size, and then call the ResizeWindow function in the Video Extension API. |- |void FBRead(unsigned int addr) |Read data from frame buffer into emulated RAM space |- |void FBWrite(unsigned int addr, unsigned int size) |Write data from emulated RAM space into frame buffer |- |void FBGetFrameBufferInfo(void *p) |Get some information about the frame buffer |} === Remove From Older Video API === {| |- |void CaptureScreen (char * Directory); |- |void CloseDLL(void); |- |void DllAbout(HWND hParent); |- |void DllConfig(HWND hParent); |- |void DllTest(HWND hParent); |- |void DrawScreen(void); |- |void GetDllInfo(PLUGIN_INFO *PluginInfo); |- |void ReadScreen(void **dest, int *width, int *height); |- |void SetConfigDir(char *configDir); |- |
typedef struct {...} PLUGIN_INFO |} == Audio Plugin API == === Mupen64Plus v2.0 Audio Plugin API === {| |void AiDacrateChanged(int SystemType); |This function is called to notify the audio plugin that the AiDacrate register's value has been changed. |- |void AiLenChanged(void); |This function is called to notify the audio plugin that the AiLen register's value has been changed. |- |BOOL InitiateAudio(AUDIO_INFO Audio_Info); |Called during CoreAttachPlugin to send info about the emulator core to the audio plugin. |- |void ProcessAList(void); |Signal that there is an A-list to be processed. (not currently used) |- |int RomOpen(void); |Called just before the emulator begins executing a ROM. '''***changed*** - this function now returns an int (boolean)''' |- |void RomClosed(void); |Called after the emulator is stopped. |- |void SetSpeedFactor(int percent); |Called when the emulator playback speed changes. |- |void VolumeUp(void);
void VolumeDown(void); |Increase or decrease volume level |- |int VolumeGetLevel(void); |Get current volume level in percentage, between 0 and 100. '''***NEW***''' |- |void VolumeSetLevel(int level); |Set current volume level. level must be between 0 and 100. '''***NEW***''' |- |void VolumeMute(void); |Toggle between audio muted and un-muted |- |const char * VolumeGetString(void); |Return a string describing the current volume level |} === Remove From Older Audio API === {| |- |DWORD AiReadLength(void); |- |void AiUpdate(BOOL Wait); |- |void CloseDLL(void); |- |void DllAbout(HWND hParent); |- |void DllConfig(HWND hParent); |- |void DllTest(HWND hParent); |- |void GetDllInfo(PLUGIN_INFO *PluginInfo); |- |BOOL PauseAudio(BOOL Pause); |- |void SetConfigDir(char *configDir); |- |
typedef struct {...} PLUGIN_INFO |} == Input Plugin API == === Mupen64Plus v2.0 Input Plugin API === {| |void ControllerCommand(int Control, BYTE * Command); |Process the raw data that has just been sent to a specific controller. |- |void GetKeys(int Control, BUTTONS * Keys); |Get the current state of the controller's buttons |- |void InitiateControllers(CONTROL_INFO ControlInfo); |Setup controller data structures |- |void ReadController(int Control, BYTE *Command); |Process the raw data in the pif ram that is about to be read. (not currently used) |- |int RomOpen(void); |Called just before the emulator begins executing a ROM. '''***changed*** - this function now returns an int (boolean)''' |- |void RomClosed(void); |Called after the emulator is stopped. |- |void SDL_KeyDown(int keymod, int keysym); |Pass a SDL_KEYDOWN-style message to the input plugin |- |void SDL_KeyUp(int keymod, int keysym); |Pass a SDL_KEYUP-style message to the input plugin |} === Remove From Older Input API === {| |- |void CloseDLL(void); |- |void DllAbout(HWND hParent); |- |void DllConfig(HWND hParent); |- |void DllTest(HWND hParent); |- |void GetDllInfo(PLUGIN_INFO *PluginInfo); |- |void SetConfigDir(char *configDir); |- |void WM_KeyDown(WPARAM wParam, LPARAM lParam); |- |void WM_KeyUp(WPARAM wParam, LPARAM lParam); |- |
typedef struct {...} PLUGIN_INFO |} == RSP Plugin API == === Mupen64Plus v2.0 RSP Plugin API === {| |DWORD DoRspCycles(DWORD Cycles); |Process pending RSP tasks. |- |void InitiateRSP(RSP_INFO Rsp_Info, DWORD *CycleCount); |Called during CoreAttachPlugin to send info about the emulator core to the audio plugin. |- |void RomClosed(void); |Called after the emulator is stopped. |} === Remove From Older RSP API === {| |- |void CloseDLL(void); |- |void DllAbout(HWND hParent); |- |void DllConfig(HWND hParent); |- |void DllTest(HWND hParent); |- |void GetDllInfo(PLUGIN_INFO *PluginInfo); |- |void GetRspDebugInfo(RSPDEBUG_INFO * RSPDebugInfo); |- |void InitiateRSPDebugger(DEBUG_INFO DebugInfo); |- |
typedef struct {...} PLUGIN_INFO
typedef struct {...} RSPDEBUG_INFO
typedef struct {...} DEBUG_INFO |} gles2n64/src/FrameBuffer.h000664 001750 001750 00000003211 12655644434 016404 0ustar00sergiosergio000000 000000 #ifndef FRAMEBUFFER_H #define FRAMEBUFFER_H #include "Types.h" #include "DepthBuffer.h" #include "Textures.h" struct FrameBuffer { struct FrameBuffer *higher, *lower; CachedTexture *texture; u32 m_startAddress, m_endAddress; u32 m_size, m_width, m_height, m_fillcolor, m_validityChecked; float m_scaleX, m_scaleY; bool m_copiedToRdram; bool m_cleared; bool m_changed; bool m_cfb; bool m_isDepthBuffer; bool m_isPauseScreen; bool m_isOBScreen; bool m_needHeightCorrection; bool m_postProcessed; GLuint m_FBO; struct gDPTile *m_pLoadTile; CachedTexture *m_pTexture; struct DepthBuffer *m_pDepthBuffer; // multisampling CachedTexture *m_pResolveTexture; GLuint m_resolveFBO; bool m_resolved; }; struct FrameBufferInfo { struct FrameBuffer *top, *bottom, *current; int numBuffers; }; extern struct FrameBufferInfo frameBuffer; void FrameBuffer_Init(void); void FrameBuffer_Destroy(void); void FrameBuffer_CopyToRDRAM( u32 _address ); void FrameBuffer_CopyFromRDRAM( u32 _address, bool _bUseAlpha ); void FrameBuffer_CopyDepthBuffer( u32 _address ); void FrameBuffer_ActivateBufferTexture( s16 t, struct FrameBuffer *buffer); void FrameBuffer_ActivateBufferTextureBG(s16 t, struct FrameBuffer *buffer); void FrameBuffer_SaveBuffer( u32 address, u16 format, u16 size, u16 width, u16 height, bool unknown ); void FrameBuffer_RenderBuffer( u32 address ); void FrameBuffer_RestoreBuffer( u32 address, u16 size, u16 width ); void FrameBuffer_RemoveBuffer( u32 address ); struct FrameBuffer *FrameBuffer_FindBuffer( u32 address ); struct FrameBuffer *FrameBuffer_GetCurrent(void); #endif mupen64plus-video-gliden64/src/GLideN64.h000664 001750 001750 00000000165 12655644434 021055 0ustar00sergiosergio000000 000000 #ifndef GLIDEN64_H #define GLIDEN64_H extern char pluginName[]; extern wchar_t pluginNameW[]; #endif // GLIDEN64_H gles2n64/src/FrameBuffer.c000664 001750 001750 00000022641 12655644434 016407 0ustar00sergiosergio000000 000000 #include #include "OpenGL.h" #include "FrameBuffer.h" #include "RSP.h" #include "RDP.h" #include "Textures.h" #include "ShaderCombiner.h" #include "Types.h" #include "VI.h" struct FrameBufferInfo frameBuffer; CachedTexture *g_RDRAMtoFB; void FrameBuffer_Init(void) { frameBuffer.current = NULL; frameBuffer.top = NULL; frameBuffer.bottom = NULL; frameBuffer.numBuffers = 0; } void FrameBuffer_RemoveBottom(void) { struct FrameBuffer *newBottom = (struct FrameBuffer*) frameBuffer.bottom->higher; TextureCache_Remove( frameBuffer.bottom->texture ); if (frameBuffer.bottom == frameBuffer.top) frameBuffer.top = NULL; free( frameBuffer.bottom ); frameBuffer.bottom = newBottom; if (frameBuffer.bottom != NULL) frameBuffer.bottom->lower = NULL; frameBuffer.numBuffers--; } void FrameBuffer_Remove( struct FrameBuffer *buffer ) { if ((buffer == frameBuffer.bottom) && (buffer == frameBuffer.top)) { frameBuffer.top = NULL; frameBuffer.bottom = NULL; } else if (buffer == frameBuffer.bottom) { frameBuffer.bottom = buffer->higher; if (frameBuffer.bottom) frameBuffer.bottom->lower = NULL; } else if (buffer == frameBuffer.top) { frameBuffer.top = buffer->lower; if (frameBuffer.top) frameBuffer.top->higher = NULL; } else { buffer->higher->lower = buffer->lower; buffer->lower->higher = buffer->higher; } if (buffer->texture) TextureCache_Remove( buffer->texture ); free( buffer ); frameBuffer.numBuffers--; } void FrameBuffer_RemoveBuffer( u32 address ) { struct FrameBuffer *current = (struct FrameBuffer*)frameBuffer.bottom; while (current != NULL) { if (current->m_startAddress == address) { current->texture = NULL; FrameBuffer_Remove( current ); return; } current = current->higher; } } struct FrameBuffer *FrameBuffer_AddTop(void) { struct FrameBuffer *newtop = (struct FrameBuffer*)malloc( sizeof(struct FrameBuffer ) ); newtop->texture = TextureCache_AddTop(); newtop->lower = frameBuffer.top; newtop->higher = NULL; if (frameBuffer.top) frameBuffer.top->higher = newtop; if (!frameBuffer.bottom) frameBuffer.bottom = newtop; frameBuffer.top = newtop; frameBuffer.numBuffers++; return newtop; } void FrameBuffer_MoveToTop( struct FrameBuffer *newtop ) { if (newtop == frameBuffer.top) return; if (newtop == frameBuffer.bottom) { frameBuffer.bottom = newtop->higher; frameBuffer.bottom->lower = NULL; } else { newtop->higher->lower = newtop->lower; newtop->lower->higher = newtop->higher; } newtop->higher = NULL; newtop->lower = frameBuffer.top; frameBuffer.top->higher = newtop; frameBuffer.top = newtop; TextureCache_MoveToTop( newtop->texture ); } void FrameBuffer_Destroy(void) { while (frameBuffer.bottom) FrameBuffer_RemoveBottom(); } void FrameBuffer_SaveBuffer( u32 address, u16 format, u16 size, u16 width, u16 height, bool unknown) { struct FrameBuffer *current = frameBuffer.top; if (width != VI.width && height == 0) return; (void)format; (void)unknown; /* Search through saved frame buffers */ while (current != NULL) { if ((current->m_startAddress == address) && (current->m_width == width) && (current->m_height == height) && (current->m_size == size)) { if ((current->m_scaleX != OGL.scaleX) || (current->m_scaleY != OGL.scaleY)) { FrameBuffer_Remove( current ); break; } /* code goes here */ *(u32*)&gfx_info.RDRAM[current->m_startAddress] = current->m_startAddress; current->m_changed = TRUE; FrameBuffer_MoveToTop( current ); gSP.changed |= CHANGED_TEXTURE; return; } current = current->lower; } /* Wasn't found, create a new one */ current = FrameBuffer_AddTop(); current->m_startAddress = address; current->m_endAddress = address + ((width * height << size >> 1) - 1); current->m_width = width; current->m_height = height; current->m_size = size; current->m_scaleX = OGL.scaleX; current->m_scaleY = OGL.scaleY; current->texture->width = current->m_width * OGL.scaleX; current->texture->height = current->m_height * OGL.scaleY; current->texture->clampS = 1; current->texture->clampT = 1; current->texture->address = current->m_startAddress; current->texture->clampWidth = current->m_width; current->texture->clampHeight = current->m_height; current->texture->frameBufferTexture = TRUE; current->texture->maskS = 0; current->texture->maskT = 0; current->texture->mirrorS = 0; current->texture->mirrorT = 0; current->texture->realWidth = pow2( current->m_width * OGL.scaleX ); current->texture->realHeight = pow2( current->m_height * OGL.scaleY ); current->texture->textureBytes = current->texture->realWidth * current->texture->realHeight * 4; cache.cachedBytes += current->texture->textureBytes; /* code goes here - just bind texture and copy it over */ *(u32*)&gfx_info.RDRAM[current->m_startAddress] = current->m_startAddress; current->m_changed = TRUE; gSP.changed |= CHANGED_TEXTURE; } struct FrameBuffer *FrameBuffer_GetCurrent(void) { return (struct FrameBuffer*)frameBuffer.top; } void FrameBuffer_RenderBuffer( u32 address ) { struct FrameBuffer *current = (struct FrameBuffer*)frameBuffer.top; while (current != NULL) { if ((current->m_startAddress <= address) && (current->m_endAddress >= address)) { /* code goes here */ current->m_changed = FALSE; FrameBuffer_MoveToTop( current ); gSP.changed |= CHANGED_TEXTURE | CHANGED_VIEWPORT; gDP.changed |= CHANGED_COMBINE; return; } current = current->lower; } } void FrameBuffer_RestoreBuffer( u32 address, u16 size, u16 width ) { struct FrameBuffer *current = (struct FrameBuffer*)frameBuffer.top; while (current != NULL) { if ((current->m_startAddress == address) && (current->m_width == width) && (current->m_size == size)) { /* code goes here */ FrameBuffer_MoveToTop( current ); gSP.changed |= CHANGED_TEXTURE | CHANGED_VIEWPORT; gDP.changed |= CHANGED_COMBINE; return; } current = current->lower; } } struct FrameBuffer *FrameBuffer_FindBuffer( u32 address ) { struct FrameBuffer *current = (struct FrameBuffer*)frameBuffer.top; while (current) { if ((current->m_startAddress <= address) && (current->m_endAddress >= address)) return current; current = current->lower; } return NULL; } void FrameBuffer_ActivateBufferTexture( s16 t, struct FrameBuffer *buffer ) { buffer->texture->scaleS = OGL.scaleX / (float)buffer->texture->realWidth; buffer->texture->scaleT = OGL.scaleY / (float)buffer->texture->realHeight; if (gSP.textureTile[t]->shifts > 10) buffer->texture->shiftScaleS = (float)(1 << (16 - gSP.textureTile[t]->shifts)); else if (gSP.textureTile[t]->shifts > 0) buffer->texture->shiftScaleS = 1.0f / (float)(1 << gSP.textureTile[t]->shifts); else buffer->texture->shiftScaleS = 1.0f; if (gSP.textureTile[t]->shiftt > 10) buffer->texture->shiftScaleT = (float)(1 << (16 - gSP.textureTile[t]->shiftt)); else if (gSP.textureTile[t]->shiftt > 0) buffer->texture->shiftScaleT = 1.0f / (float)(1 << gSP.textureTile[t]->shiftt); else buffer->texture->shiftScaleT = 1.0f; if (gDP.loadTile->loadType == LOADTYPE_TILE) { buffer->texture->offsetS = gDP.loadTile->uls; buffer->texture->offsetT = (float)buffer->m_height - (gDP.loadTile->ult + (gDP.textureImage.address - buffer->m_startAddress) / (buffer->m_width << buffer->m_size >> 1)); } else { buffer->texture->offsetS = 0.0f; buffer->texture->offsetT = (float)buffer->m_height - (gDP.textureImage.address - buffer->m_startAddress) / (buffer->m_width << buffer->m_size >> 1); } FrameBuffer_MoveToTop( buffer ); TextureCache_ActivateTexture( t, buffer->texture ); gDP.changed |= CHANGED_FB_TEXTURE; } void FrameBuffer_ActivateBufferTextureBG(s16 t, struct FrameBuffer *buffer ) { if (buffer == NULL || buffer->texture == NULL) return; buffer->texture->scaleS = OGL.scaleX / (float)buffer->texture->realWidth; buffer->texture->scaleT = OGL.scaleY / (float)buffer->texture->realHeight; buffer->texture->shiftScaleS = 1.0f; buffer->texture->shiftScaleT = 1.0f; buffer->texture->offsetS = gSP.bgImage.imageX; buffer->texture->offsetT = (float)buffer->m_height - gSP.bgImage.imageY; FrameBuffer_MoveToTop( buffer ); TextureCache_ActivateTexture( t, buffer->texture ); gDP.changed |= CHANGED_FB_TEXTURE; } void FrameBuffer_CopyFromRDRAM( u32 _address, bool _bUseAlpha ) { /* stub */ } void FrameBuffer_CopyToRDRAM( u32 _address ) { /* stub */ } void FrameBuffer_CopyDepthBuffer( u32 _address ) { /* stub */ } mupen64plus-video-gliden64/src/glState.h000664 001750 001750 00000020542 12655644434 021205 0ustar00sergiosergio000000 000000 #ifndef GLSTATE_H #define GLSTATE_H #ifdef __cplusplus extern "C" { #endif struct GLState { GLState() { reset(); } void reset(); GLenum cached_ActiveTexture_texture; GLenum cached_BlendFunc_sfactor; GLenum cached_BlendFunc_dfactor; GLenum cached_ReadBufferMode; GLenum cached_glPixelStorei_target; GLint cached_glPixelStorei_param; GLclampf cached_ClearColor_red; GLclampf cached_ClearColor_green; GLclampf cached_ClearColor_blue; GLclampf cached_ClearColor_alpha; GLenum cached_DepthFunc_func; GLboolean cached_DepthMask_flag; bool cached_BLEND; bool cached_CULL_FACE; bool cached_DEPTH_TEST; bool cached_DEPTH_CLAMP; bool cached_CLIP_DISTANCE0; bool cached_DITHER; bool cached_POLYGON_OFFSET_FILL; bool cached_SAMPLE_ALPHA_TO_COVERAGE; bool cached_SAMPLE_COVERAGE; bool cached_SCISSOR_TEST; GLenum cached_FrontFace_mode; GLenum cached_CullFace_mode; GLfloat cached_PolygonOffset_factor; GLfloat cached_PolygonOffset_units; GLint cached_Scissor_x; GLint cached_Scissor_y; GLsizei cached_Scissor_width; GLsizei cached_Scissor_height; GLuint cached_UseProgram_program; GLint cached_Viewport_x; GLint cached_Viewport_y; GLsizei cached_Viewport_width; GLsizei cached_Viewport_height; }; extern GLState glState; void inline cache_glActiveTexture (GLenum texture) { if (texture != glState.cached_ActiveTexture_texture) { glActiveTexture(texture); glState.cached_ActiveTexture_texture = texture; } } #define glActiveTexture(texture) cache_glActiveTexture(texture) void inline cache_glBlendFunc (GLenum sfactor, GLenum dfactor) { if (sfactor != glState.cached_BlendFunc_sfactor || dfactor != glState.cached_BlendFunc_dfactor) { glBlendFunc(sfactor, dfactor); glState.cached_BlendFunc_sfactor = sfactor; glState.cached_BlendFunc_dfactor = dfactor; } } #define glBlendFunc(sfactor, dfactor) cache_glBlendFunc(sfactor, dfactor) void inline cache_glReadBuffer(GLenum mode) { if (mode != glState.cached_ReadBufferMode) glState.cached_ReadBufferMode = mode; } #define glReadBuffer(mode) cache_glReadBuffer(mode) void inline cache_glPixelStorei(GLenum target, GLint param) { if (target != glState.cached_glPixelStorei_target || param != glState.cached_glPixelStorei_param) { glPixelStorei(target, param); glState.cached_glPixelStorei_target = target; glState.cached_glPixelStorei_param = param; } } #define glPixelStorei(target, param) cache_glPixelStorei(target, param) void inline cache_glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { if (red != glState.cached_ClearColor_red || green != glState.cached_ClearColor_green || blue != glState.cached_ClearColor_blue || alpha != glState.cached_ClearColor_alpha) { glClearColor(red, green, blue, alpha); glState.cached_ClearColor_red = red; glState.cached_ClearColor_green = green; glState.cached_ClearColor_blue = blue; glState.cached_ClearColor_alpha = alpha; } } #define glClearColor(red, green, blue, alpha) cache_glClearColor(red, green, blue, alpha) void inline cache_glCullFace (GLenum mode) { if (mode != glState.cached_CullFace_mode) { glCullFace(mode); glState.cached_CullFace_mode = mode; } } #define glCullFace(mode) cache_glCullFace(mode) void inline cache_glDepthFunc (GLenum func) { if (func != glState.cached_DepthFunc_func) { glDepthFunc(func); glState.cached_DepthFunc_func = func; } } #define glDepthFunc(func) cache_glDepthFunc(func) void inline cache_glDepthMask (GLboolean flag) { if (flag != glState.cached_DepthMask_flag) { glDepthMask(flag); glState.cached_DepthMask_flag = flag; } } #define glDepthMask(flag) cache_glDepthMask(flag) void inline cache_glDisable (GLenum cap) { switch (cap) { case GL_BLEND: if (glState.cached_BLEND) { glDisable(GL_BLEND); glState.cached_BLEND = false; } break; case GL_CULL_FACE: if (glState.cached_CULL_FACE) { glDisable(GL_CULL_FACE); glState.cached_CULL_FACE = false; } break; case GL_DEPTH_TEST: if (glState.cached_DEPTH_TEST) { glDisable(GL_DEPTH_TEST); glState.cached_DEPTH_TEST = false; } break; #ifndef GLESX case GL_DEPTH_CLAMP: if (glState.cached_DEPTH_CLAMP) { glDisable(GL_DEPTH_CLAMP); glState.cached_DEPTH_CLAMP = false; } break; case GL_CLIP_DISTANCE0: if (glState.cached_CLIP_DISTANCE0) { glDisable(GL_CLIP_DISTANCE0); glState.cached_CLIP_DISTANCE0 = false; } break; #endif case GL_DITHER: if (glState.cached_DITHER) { glDisable(GL_DITHER); glState.cached_DITHER = false; } break; case GL_POLYGON_OFFSET_FILL: if (glState.cached_POLYGON_OFFSET_FILL) { glDisable(GL_POLYGON_OFFSET_FILL); glState.cached_POLYGON_OFFSET_FILL = false; } break; case GL_SAMPLE_ALPHA_TO_COVERAGE: if (glState.cached_SAMPLE_ALPHA_TO_COVERAGE) { glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); glState.cached_SAMPLE_ALPHA_TO_COVERAGE = false; } break; case GL_SAMPLE_COVERAGE: if (glState.cached_SAMPLE_COVERAGE) { glDisable(GL_SAMPLE_COVERAGE); glState.cached_SAMPLE_COVERAGE = false; } break; case GL_SCISSOR_TEST: if (glState.cached_SCISSOR_TEST) { glDisable(GL_SCISSOR_TEST); glState.cached_SCISSOR_TEST = false; } break; default: glDisable(cap); break; } } #define glDisable(cap) cache_glDisable(cap) void inline cache_glEnable(GLenum cap) { switch (cap) { case GL_BLEND: if (!glState.cached_BLEND) { glEnable(GL_BLEND); glState.cached_BLEND = true; } break; case GL_CULL_FACE: if (!glState.cached_CULL_FACE) { glEnable(GL_CULL_FACE); glState.cached_CULL_FACE = true; } break; case GL_DEPTH_TEST: if (!glState.cached_DEPTH_TEST) { glEnable(GL_DEPTH_TEST); glState.cached_DEPTH_TEST = true; } break; #ifndef GLESX case GL_DEPTH_CLAMP: if (!glState.cached_DEPTH_CLAMP) { glEnable(GL_DEPTH_CLAMP); glState.cached_DEPTH_CLAMP = true; } break; case GL_CLIP_DISTANCE0: if (!glState.cached_CLIP_DISTANCE0) { glEnable(GL_CLIP_DISTANCE0); glState.cached_CLIP_DISTANCE0 = true; } break; #endif case GL_DITHER: if (!glState.cached_DITHER) { glEnable(GL_DITHER); glState.cached_DITHER = true; } break; case GL_POLYGON_OFFSET_FILL: if (!glState.cached_POLYGON_OFFSET_FILL) { glEnable(GL_POLYGON_OFFSET_FILL); glState.cached_POLYGON_OFFSET_FILL = true; } break; case GL_SAMPLE_ALPHA_TO_COVERAGE: if (!glState.cached_SAMPLE_ALPHA_TO_COVERAGE) { glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE); glState.cached_SAMPLE_ALPHA_TO_COVERAGE = true; } break; case GL_SAMPLE_COVERAGE: if (!glState.cached_SAMPLE_COVERAGE) { glEnable(GL_SAMPLE_COVERAGE); glState.cached_SAMPLE_COVERAGE = true; } break; case GL_SCISSOR_TEST: if (!glState.cached_SCISSOR_TEST) { glEnable(GL_SCISSOR_TEST); glState.cached_SCISSOR_TEST = true; } break; default: glEnable(cap); break; } } #define glEnable(cap) cache_glEnable(cap) void inline cache_glPolygonOffset (GLfloat factor, GLfloat units) { if (factor != glState.cached_PolygonOffset_factor || units != glState.cached_PolygonOffset_units) { glPolygonOffset(factor, units); glState.cached_PolygonOffset_factor = factor; glState.cached_PolygonOffset_units = units; } } #define glPolygonOffset(factor, units) cache_glPolygonOffset(factor, units) void inline cache_glScissor (GLint x, GLint y, GLsizei width, GLsizei height) { if (x != glState.cached_Scissor_x || y != glState.cached_Scissor_y || width != glState.cached_Scissor_width || height != glState.cached_Scissor_height) { glScissor(x, y, width, height); glState.cached_Scissor_x = x; glState.cached_Scissor_y = y; glState.cached_Scissor_width = width; glState.cached_Scissor_height = height; } } #define glScissor(x, y, width, height) cache_glScissor(x, y, width, height) void inline cache_glUseProgram (GLuint program) { if (program != glState.cached_UseProgram_program) { glUseProgram(program); glState.cached_UseProgram_program = program; } } #define glUseProgram(program) cache_glUseProgram(program) void inline cache_glViewport (GLint x, GLint y, GLsizei width, GLsizei height) { if (x != glState.cached_Viewport_x || y != glState.cached_Viewport_y || width != glState.cached_Viewport_width || height != glState.cached_Viewport_height) { glViewport(x, y, width, height); glState.cached_Viewport_x = x; glState.cached_Viewport_y = y; glState.cached_Viewport_width = width; glState.cached_Viewport_height = height; } } #define glViewport(x, y, width, height) cache_glViewport(x, y, width, height) #ifdef __cplusplus } #endif #endif //GLSTATE_H mupen64plus-video-gliden64/src/DepthBuffer.cpp000664 001750 001750 00000030202 12655644434 022325 0ustar00sergiosergio000000 000000 #ifdef OS_MAC_OS_X #include #else #include #endif #include #include "OpenGL.h" #include "Combiner.h" #include "FrameBuffer.h" #include "DepthBuffer.h" #include "VI.h" #include "Config.h" #include "Debug.h" const GLuint ZlutImageUnit = 0; const GLuint TlutImageUnit = 1; const GLuint depthImageUnit = 2; DepthBuffer::DepthBuffer() : m_address(0), m_width(0), m_uly(0), m_lry(0), m_FBO(0), m_pDepthImageTexture(NULL), m_pDepthBufferTexture(NULL), m_cleared(false), m_pResolveDepthBufferTexture(NULL), m_resolved(false) { glGenFramebuffers(1, &m_FBO); } DepthBuffer::DepthBuffer(DepthBuffer && _other) : m_address(_other.m_address), m_width(_other.m_width), m_uly(_other.m_uly), m_lry(_other.m_lry), m_FBO(_other.m_FBO), m_pDepthImageTexture(_other.m_pDepthImageTexture), m_pDepthBufferTexture(_other.m_pDepthBufferTexture), m_cleared(_other.m_cleared), m_pResolveDepthBufferTexture(_other.m_pResolveDepthBufferTexture), m_resolved(_other.m_resolved) { _other.m_FBO = 0; _other.m_pDepthImageTexture = NULL; _other.m_pDepthBufferTexture = NULL; _other.m_pResolveDepthBufferTexture = NULL; _other.m_resolved = false; } DepthBuffer::~DepthBuffer() { if (m_FBO != 0) glDeleteFramebuffers(1, &m_FBO); if (m_pDepthImageTexture != NULL) textureCache().removeFrameBufferTexture(m_pDepthImageTexture); if (m_pDepthBufferTexture != NULL) textureCache().removeFrameBufferTexture(m_pDepthBufferTexture); if (m_pResolveDepthBufferTexture != NULL) textureCache().removeFrameBufferTexture(m_pResolveDepthBufferTexture); } void DepthBuffer::initDepthImageTexture(FrameBuffer * _pBuffer) { #ifdef GL_IMAGE_TEXTURES_SUPPORT if (!video().getRender().isImageTexturesSupported() || config.frameBufferEmulation.N64DepthCompare == 0 || m_pDepthImageTexture != NULL) return; m_pDepthImageTexture = textureCache().addFrameBufferTexture(); m_pDepthImageTexture->width = (u32)(_pBuffer->m_pTexture->width); m_pDepthImageTexture->height = (u32)(_pBuffer->m_pTexture->height); m_pDepthImageTexture->format = 0; m_pDepthImageTexture->size = 2; m_pDepthImageTexture->clampS = 1; m_pDepthImageTexture->clampT = 1; m_pDepthImageTexture->address = _pBuffer->m_startAddress; m_pDepthImageTexture->clampWidth = _pBuffer->m_width; m_pDepthImageTexture->clampHeight = _pBuffer->m_height; m_pDepthImageTexture->frameBufferTexture = CachedTexture::fbOneSample; m_pDepthImageTexture->maskS = 0; m_pDepthImageTexture->maskT = 0; m_pDepthImageTexture->mirrorS = 0; m_pDepthImageTexture->mirrorT = 0; m_pDepthImageTexture->realWidth = m_pDepthImageTexture->width; m_pDepthImageTexture->realHeight = m_pDepthImageTexture->height; m_pDepthImageTexture->textureBytes = m_pDepthImageTexture->realWidth * m_pDepthImageTexture->realHeight * fboFormats.depthImageFormatBytes; textureCache().addFrameBufferTextureSize(m_pDepthImageTexture->textureBytes); glBindTexture(GL_TEXTURE_2D, m_pDepthImageTexture->glName); glTexImage2D(GL_TEXTURE_2D, 0, fboFormats.depthImageInternalFormat, m_pDepthImageTexture->realWidth, m_pDepthImageTexture->realHeight, 0, fboFormats.depthImageFormat, fboFormats.depthImageType, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glBindTexture(GL_TEXTURE_2D, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FBO); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_pDepthImageTexture->glName, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _pBuffer->m_FBO); depthBufferList().clearBuffer(0, VI.height); #endif // GL_IMAGE_TEXTURES_SUPPORT } void DepthBuffer::_initDepthBufferTexture(FrameBuffer * _pBuffer, CachedTexture * _pTexture, bool _multisample) { if (_pBuffer != NULL) { _pTexture->width = (u32)(_pBuffer->m_pTexture->width); _pTexture->height = (u32)(_pBuffer->m_pTexture->height); _pTexture->address = _pBuffer->m_startAddress; _pTexture->clampWidth = _pBuffer->m_width; _pTexture->clampHeight = _pBuffer->m_height; } else { _pTexture->width = video().getWidth(); _pTexture->height = video().getHeight(); _pTexture->address = gDP.depthImageAddress; _pTexture->clampWidth = VI.width; _pTexture->clampHeight = VI.height; } _pTexture->format = 0; _pTexture->size = 2; _pTexture->clampS = 1; _pTexture->clampT = 1; _pTexture->frameBufferTexture = CachedTexture::fbOneSample; _pTexture->maskS = 0; _pTexture->maskT = 0; _pTexture->mirrorS = 0; _pTexture->mirrorT = 0; _pTexture->realWidth = _pTexture->width; _pTexture->realHeight = _pTexture->height; _pTexture->textureBytes = _pTexture->realWidth * _pTexture->realHeight * fboFormats.depthFormatBytes; textureCache().addFrameBufferTextureSize(_pTexture->textureBytes); #ifdef GL_MULTISAMPLING_SUPPORT if (_multisample) { glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _pTexture->glName); #if defined(GLES3_1) if (_pBuffer != NULL) glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, config.video.multisampling, GL_DEPTH_COMPONENT, _pBuffer->m_pTexture->realWidth, _pBuffer->m_pTexture->realHeight, false); else glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, config.video.multisampling, GL_DEPTH_COMPONENT, video().getWidth(), video().getHeight(), false); #else if (_pBuffer != NULL) glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, config.video.multisampling, GL_DEPTH_COMPONENT, _pBuffer->m_pTexture->realWidth, _pBuffer->m_pTexture->realHeight, false); else glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, config.video.multisampling, GL_DEPTH_COMPONENT, video().getWidth(), video().getHeight(), false); #endif _pTexture->frameBufferTexture = CachedTexture::fbMultiSample; } else #endif // GL_MULTISAMPLING_SUPPORT { glBindTexture(GL_TEXTURE_2D, _pTexture->glName); if (_pBuffer != NULL) glTexImage2D(GL_TEXTURE_2D, 0, fboFormats.depthInternalFormat, _pBuffer->m_pTexture->realWidth, _pBuffer->m_pTexture->realHeight, 0, GL_DEPTH_COMPONENT, fboFormats.depthType, NULL); else glTexImage2D(GL_TEXTURE_2D, 0, fboFormats.depthInternalFormat, video().getWidth(), video().getHeight(), 0, GL_DEPTH_COMPONENT, fboFormats.depthType, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } glBindTexture(GL_TEXTURE_2D, 0); } void DepthBuffer::setDepthAttachment(GLenum _target) { #ifdef GL_MULTISAMPLING_SUPPORT if (config.video.multisampling != 0) glFramebufferTexture2D(_target, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE, m_pDepthBufferTexture->glName, 0); else #endif glFramebufferTexture2D(_target, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_pDepthBufferTexture->glName, 0); m_resolved = false; } void DepthBuffer::initDepthBufferTexture(FrameBuffer * _pBuffer) { if (m_pDepthBufferTexture == NULL) { m_pDepthBufferTexture = textureCache().addFrameBufferTexture(); _initDepthBufferTexture(_pBuffer, m_pDepthBufferTexture, config.video.multisampling != 0); } #ifdef GL_MULTISAMPLING_SUPPORT if (config.video.multisampling != 0 && m_pResolveDepthBufferTexture == NULL) { m_pResolveDepthBufferTexture = textureCache().addFrameBufferTexture(); _initDepthBufferTexture(_pBuffer, m_pResolveDepthBufferTexture, false); } #endif } CachedTexture * DepthBuffer::resolveDepthBufferTexture(FrameBuffer * _pBuffer) { #ifdef GL_MULTISAMPLING_SUPPORT if (config.video.multisampling == 0) return m_pDepthBufferTexture; if (m_resolved) return m_pResolveDepthBufferTexture; glScissor(0, 0, m_pDepthBufferTexture->realWidth, m_pDepthBufferTexture->realHeight); glBindFramebuffer(GL_READ_FRAMEBUFFER, _pBuffer->m_FBO); glReadBuffer(GL_COLOR_ATTACHMENT0); GLuint attachment = GL_COLOR_ATTACHMENT0; glDrawBuffers(1, &attachment); assert(checkFBO()); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _pBuffer->m_resolveFBO); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_pResolveDepthBufferTexture->glName, 0); assert(checkFBO()); glBlitFramebuffer( 0, 0, m_pDepthBufferTexture->realWidth, m_pDepthBufferTexture->realHeight, 0, 0, m_pResolveDepthBufferTexture->realWidth, m_pResolveDepthBufferTexture->realHeight, GL_DEPTH_BUFFER_BIT, GL_NEAREST ); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _pBuffer->m_FBO); m_resolved = true; gDP.changed |= CHANGED_SCISSOR; return m_pResolveDepthBufferTexture; #else return m_pDepthBufferTexture; #endif } void DepthBuffer::activateDepthBufferTexture(FrameBuffer * _pBuffer) { textureCache().activateTexture(0, resolveDepthBufferTexture(_pBuffer)); } void DepthBuffer::bindDepthImageTexture() { #ifdef GL_IMAGE_TEXTURES_SUPPORT glBindImageTexture(depthImageUnit, m_pDepthImageTexture->glName, 0, GL_FALSE, 0, GL_READ_WRITE, fboFormats.depthImageInternalFormat); #endif } DepthBufferList::DepthBufferList() : m_pCurrent(NULL), m_pzLUT(NULL) { m_pzLUT = new u16[0x40000]; for (int i = 0; i<0x40000; i++) { u32 exponent = 0; u32 testbit = 1 << 17; while ((i & testbit) && (exponent < 7)) { exponent++; testbit = 1 << (17 - exponent); } const u32 mantissa = (i >> (6 - (6 < exponent ? 6 : exponent))) & 0x7ff; m_pzLUT[i] = (u16)(((exponent << 11) | mantissa) << 2); } } DepthBufferList::~DepthBufferList() { delete[] m_pzLUT; m_pzLUT = NULL; m_list.clear(); } DepthBufferList & DepthBufferList::get() { static DepthBufferList depthBufferList; return depthBufferList; } void DepthBufferList::init() { m_pCurrent = NULL; } void DepthBufferList::destroy() { m_pCurrent = NULL; m_list.clear(); } void DepthBufferList::setNotCleared() { for (DepthBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter) iter->m_cleared = false; } DepthBuffer * DepthBufferList::findBuffer(u32 _address) { for (DepthBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter) if (iter->m_address == _address) return &(*iter); return NULL; } void DepthBufferList::removeBuffer(u32 _address ) { for (DepthBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter) if (iter->m_address == _address) { m_list.erase(iter); return; } } void DepthBufferList::saveBuffer(u32 _address) { if (!config.frameBufferEmulation.enable) return; FrameBuffer * pFrameBuffer = frameBufferList().findBuffer(_address); if (pFrameBuffer != NULL) pFrameBuffer->m_isDepthBuffer = true; if (m_pCurrent == NULL || m_pCurrent->m_address != _address) m_pCurrent = findBuffer(_address); if (m_pCurrent != NULL && pFrameBuffer != NULL && m_pCurrent->m_width != pFrameBuffer->m_width) { removeBuffer(_address); m_pCurrent = NULL; } if (m_pCurrent == NULL) { m_list.emplace_front(); DepthBuffer & buffer = m_list.front(); buffer.m_address = _address; buffer.m_width = pFrameBuffer != NULL ? pFrameBuffer->m_width : VI.width; buffer.initDepthBufferTexture(pFrameBuffer); m_pCurrent = &buffer; } frameBufferList().attachDepthBuffer(); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "DepthBuffer_SetBuffer( 0x%08X ); color buffer is 0x%08X\n", address, ( pFrameBuffer != NULL && pFrameBuffer->m_FBO > 0) ? pFrameBuffer->m_startAddress : 0 ); #endif } void DepthBufferList::clearBuffer(u32 _uly, u32 _lry) { if (m_pCurrent == NULL) return; m_pCurrent->m_cleared = true; m_pCurrent->m_uly = _uly; m_pCurrent->m_lry = _lry; #ifdef GL_IMAGE_TEXTURES_SUPPORT if (m_pCurrent->m_FBO == 0 || !video().getRender().isImageTexturesSupported() || config.frameBufferEmulation.N64DepthCompare == 0) return; float color[4] = {1.0f, 1.0f, 0.0f, 1.0f}; glBindImageTexture(depthImageUnit, 0, 0, GL_FALSE, 0, GL_READ_WRITE, fboFormats.depthImageInternalFormat); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_pCurrent->m_FBO); const u32 cycleType = gDP.otherMode.cycleType; gDP.otherMode.cycleType = G_CYC_FILL; video().getRender().drawRect(0,0,VI.width, VI.height, color); gDP.otherMode.cycleType = cycleType; glBindImageTexture(depthImageUnit, m_pCurrent->m_pDepthImageTexture->glName, 0, GL_FALSE, 0, GL_READ_WRITE, fboFormats.depthImageInternalFormat); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferList().getCurrent()->m_FBO); #endif // GL_IMAGE_TEXTURES_SUPPORT } void DepthBuffer_Init() { depthBufferList().init(); } void DepthBuffer_Destroy() { depthBufferList().destroy(); } mupen64plus-video-gliden64/src/FrameBuffer.cpp000664 001750 001750 00000134141 12655644434 022322 0ustar00sergiosergio000000 000000 #include #include #include "OpenGL.h" #include "FrameBuffer.h" #include "DepthBuffer.h" #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gDP.h" #include "VI.h" #include "Textures.h" #include "Combiner.h" #include "GLSLCombiner.h" #include "Types.h" #include "Config.h" #include "Debug.h" #include "PostProcessor.h" using namespace std; #ifndef GLES2 class FrameBufferToRDRAM { public: FrameBufferToRDRAM() : m_FBO(0), m_pTexture(NULL), m_curIndex(0) { m_PBO[0] = m_PBO[1] = m_PBO[2] = 0; } void Init(); void Destroy(); void CopyToRDRAM(u32 _address, bool _sync); private: union RGBA { struct { u8 r, g, b, a; }; u32 raw; }; GLuint m_FBO; CachedTexture * m_pTexture; u32 m_curIndex; GLuint m_PBO[3]; }; class DepthBufferToRDRAM { public: DepthBufferToRDRAM() : m_FBO(0), m_PBO(0), m_pColorTexture(NULL), m_pDepthTexture(NULL) {} void Init(); void Destroy(); bool CopyToRDRAM( u32 address ); private: GLuint m_FBO; GLuint m_PBO; CachedTexture * m_pColorTexture; CachedTexture * m_pDepthTexture; }; #endif // GLES2 class RDRAMtoFrameBuffer { public: RDRAMtoFrameBuffer() : m_pTexture(NULL), m_PBO(0) {} void Init(); void Destroy(); void CopyFromRDRAM( u32 _address, bool _bUseAlpha); private: CachedTexture * m_pTexture; #ifndef GLES2 GLuint m_PBO; #else GLubyte* m_PBO; #endif }; #ifndef GLES2 FrameBufferToRDRAM g_fbToRDRAM; DepthBufferToRDRAM g_dbToRDRAM; #endif RDRAMtoFrameBuffer g_RDRAMtoFB; FrameBuffer::FrameBuffer() : m_startAddress(0), m_endAddress(0), m_size(0), m_width(0), m_height(0), m_fillcolor(0), m_validityChecked(0), m_scaleX(0), m_scaleY(0), m_copiedToRdram(false), m_fingerprint(false), m_cleared(false), m_changed(false), m_cfb(false), m_isDepthBuffer(false), m_isPauseScreen(false), m_isOBScreen(false), m_needHeightCorrection(false), m_postProcessed(0), m_pLoadTile(NULL), m_pDepthBuffer(NULL), m_pResolveTexture(NULL), m_resolveFBO(0), m_resolved(false) { m_pTexture = textureCache().addFrameBufferTexture(); glGenFramebuffers(1, &m_FBO); } FrameBuffer::FrameBuffer(FrameBuffer && _other) : m_startAddress(_other.m_startAddress), m_endAddress(_other.m_endAddress), m_size(_other.m_size), m_width(_other.m_width), m_height(_other.m_height), m_fillcolor(_other.m_fillcolor), m_validityChecked(_other.m_validityChecked), m_scaleX(_other.m_scaleX), m_scaleY(_other.m_scaleY), m_copiedToRdram(_other.m_copiedToRdram), m_fingerprint(_other.m_fingerprint), m_cleared(_other.m_cleared), m_changed(_other.m_changed), m_cfb(_other.m_cfb), m_isDepthBuffer(_other.m_isDepthBuffer), m_isPauseScreen(_other.m_isPauseScreen), m_isOBScreen(_other.m_isOBScreen), m_needHeightCorrection(_other.m_needHeightCorrection), m_postProcessed(_other.m_postProcessed), m_FBO(_other.m_FBO), m_pLoadTile(_other.m_pLoadTile), m_pTexture(_other.m_pTexture), m_pDepthBuffer(_other.m_pDepthBuffer), m_pResolveTexture(_other.m_pResolveTexture), m_resolveFBO(_other.m_resolveFBO), m_resolved(_other.m_resolved), m_RdramCopy(_other.m_RdramCopy) { _other.m_FBO = 0; _other.m_pTexture = NULL; _other.m_pLoadTile = NULL; _other.m_pDepthBuffer = NULL; _other.m_pResolveTexture = NULL; _other.m_resolveFBO = 0; _other.m_RdramCopy.clear(); } FrameBuffer::~FrameBuffer() { if (m_FBO != 0) glDeleteFramebuffers(1, &m_FBO); if (m_pTexture != NULL) textureCache().removeFrameBufferTexture(m_pTexture); if (m_resolveFBO != 0) glDeleteFramebuffers(1, &m_resolveFBO); if (m_pResolveTexture != NULL) textureCache().removeFrameBufferTexture(m_pResolveTexture); } void FrameBuffer::_initTexture(u16 _format, u16 _size, CachedTexture *_pTexture) { _pTexture->width = (u32)(m_width * m_scaleX); _pTexture->height = (u32)(m_height * m_scaleY); _pTexture->format = _format; _pTexture->size = _size; _pTexture->clampS = 1; _pTexture->clampT = 1; _pTexture->address = m_startAddress; _pTexture->clampWidth = m_width; _pTexture->clampHeight = m_height; _pTexture->frameBufferTexture = CachedTexture::fbOneSample; _pTexture->maskS = 0; _pTexture->maskT = 0; _pTexture->mirrorS = 0; _pTexture->mirrorT = 0; _pTexture->realWidth = _pTexture->width; _pTexture->realHeight = _pTexture->height; _pTexture->textureBytes = _pTexture->realWidth * _pTexture->realHeight; if (_size > G_IM_SIZ_8b) _pTexture->textureBytes *= fboFormats.colorFormatBytes; else _pTexture->textureBytes *= fboFormats.monochromeFormatBytes; textureCache().addFrameBufferTextureSize(_pTexture->textureBytes); } void FrameBuffer::_setAndAttachTexture(u16 _size, CachedTexture *_pTexture) { glBindTexture(GL_TEXTURE_2D, _pTexture->glName); if (_size > G_IM_SIZ_8b) glTexImage2D(GL_TEXTURE_2D, 0, fboFormats.colorInternalFormat, _pTexture->realWidth, _pTexture->realHeight, 0, fboFormats.colorFormat, fboFormats.colorType, NULL); else glTexImage2D(GL_TEXTURE_2D, 0, fboFormats.monochromeInternalFormat, _pTexture->realWidth, _pTexture->realHeight, 0, fboFormats.monochromeFormat, fboFormats.monochromeType, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _pTexture->glName, 0); } bool FrameBuffer::_isMarioTennisScoreboard() const { if ((config.generalEmulation.hacks&hack_scoreboard) != 0) { if (VI.PAL) return m_startAddress == 0x13b480 || m_startAddress == 0x26a530; else return m_startAddress == 0x13ba50 || m_startAddress == 0x264430; } return (config.generalEmulation.hacks&hack_scoreboardJ) != 0 && (m_startAddress == 0x134080 || m_startAddress == 0x1332f8); } void FrameBuffer::init(u32 _address, u32 _endAddress, u16 _format, u16 _size, u16 _width, u16 _height, bool _cfb) { OGLVideo & ogl = video(); m_startAddress = _address; m_endAddress = _endAddress; m_width = _width; m_height = _height; m_size = _size; if (m_width != VI.width && config.frameBufferEmulation.copyAuxToRDRAM != 0) { m_scaleX = 1.0f; m_scaleY = 1.0f; } else { m_scaleX = ogl.getScaleX(); m_scaleY = ogl.getScaleY(); } m_fillcolor = 0; m_cfb = _cfb; m_needHeightCorrection = _width != VI.width && _width != *REG.VI_WIDTH; m_cleared = false; m_fingerprint = false; _initTexture(_format, _size, m_pTexture); glBindFramebuffer(GL_FRAMEBUFFER, m_FBO); #ifdef GL_MULTISAMPLING_SUPPORT if (config.video.multisampling != 0) { glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_pTexture->glName); #if defined(GLES3_1) if (_size > G_IM_SIZ_8b) glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, config.video.multisampling, GL_RGBA8, m_pTexture->realWidth, m_pTexture->realHeight, false); else glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, config.video.multisampling, fboFormats.monochromeInternalFormat, m_pTexture->realWidth, m_pTexture->realHeight, false); #else if (_size > G_IM_SIZ_8b) glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, config.video.multisampling, GL_RGBA8, m_pTexture->realWidth, m_pTexture->realHeight, false); else glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, config.video.multisampling, fboFormats.monochromeInternalFormat, m_pTexture->realWidth, m_pTexture->realHeight, false); #endif m_pTexture->frameBufferTexture = CachedTexture::fbMultiSample; glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, m_pTexture->glName, 0); m_pResolveTexture = textureCache().addFrameBufferTexture(); _initTexture(_format, _size, m_pResolveTexture); glGenFramebuffers(1, &m_resolveFBO); glBindFramebuffer(GL_FRAMEBUFFER, m_resolveFBO); _setAndAttachTexture(_size, m_pResolveTexture); assert(checkFBO()); glBindFramebuffer(GL_FRAMEBUFFER, m_FBO); } else #endif // GL_MULTISAMPLING_SUPPORT _setAndAttachTexture(_size, m_pTexture); } void FrameBuffer::reinit(u16 _height) { const u16 format = m_pTexture->format; const u32 endAddress = m_startAddress + ((m_width * _height) << m_size >> 1) - 1; if (m_pTexture != NULL) textureCache().removeFrameBufferTexture(m_pTexture); if (m_resolveFBO != 0) glDeleteFramebuffers(1, &m_resolveFBO); if (m_pResolveTexture != NULL) textureCache().removeFrameBufferTexture(m_pResolveTexture); m_pTexture = textureCache().addFrameBufferTexture(); init(m_startAddress, endAddress, format, m_size, m_width, _height, m_cfb); } inline u32 _cutHeight(u32 _address, u32 _height, u32 _stride) { if (_address > RDRAMSize) return 0; if (_address + _stride * _height > RDRAMSize) return (RDRAMSize - _address) / _stride; return _height; } void FrameBuffer::copyRdram() { const u32 stride = m_width << m_size >> 1; const u32 height = _cutHeight(m_startAddress, m_height, stride); if (height == 0) return; const u32 dataSize = stride * height; // Auxiliary frame buffer if (m_width != VI.width && config.frameBufferEmulation.copyAuxToRDRAM == 0) { // Write small amount of data to the start of the buffer. // This is necessary for auxilary buffers: game can restore content of RDRAM when buffer is not needed anymore // Thus content of RDRAM on moment of buffer creation will be the same as when buffer becomes obsolete. // Validity check will see that the RDRAM is the same and thus the buffer is valid, which is false. const u32 twoPercent = dataSize / 200; u32 start = m_startAddress >> 2; u32 * pData = (u32*)RDRAM; for (u32 i = 0; i < twoPercent; ++i) { if (i < 4) pData[start++] = fingerprint[i]; else pData[start++] = 0; } m_cleared = false; m_fingerprint = true; return; } m_RdramCopy.resize(dataSize); memcpy(m_RdramCopy.data(), RDRAM + m_startAddress, dataSize); } bool FrameBuffer::isValid() const { if (m_validityChecked == video().getBuffersSwapCount()) return true; // Already checked const u32 * const pData = (const u32*)RDRAM; if (m_cleared) { const u32 color = m_fillcolor & 0xFFFEFFFE; const u32 start = m_startAddress >> 2; const u32 end = m_endAddress >> 2; u32 wrongPixels = 0; for (u32 i = start; i < end; ++i) { if ((pData[i] & 0xFFFEFFFE) != color) ++wrongPixels; } return wrongPixels < (m_endAddress - m_startAddress) / 400; // threshold level 1% of dwords } else if (m_fingerprint) { //check if our fingerprint is still there u32 start = m_startAddress >> 2; for (u32 i = 0; i < 4; ++i) if ((pData[start++] & 0xFFFEFFFE) != (fingerprint[i] & 0xFFFEFFFE)) return false; return true; } else if (!m_RdramCopy.empty()) { const u32 * const pCopy = (const u32*)m_RdramCopy.data(); const u32 size = m_RdramCopy.size(); const u32 size_dwords = size >> 2; u32 start = m_startAddress >> 2; u32 wrongPixels = 0; for (u32 i = 0; i < size_dwords; ++i) { if ((pData[start++] & 0xFFFEFFFE) != (pCopy[i] & 0xFFFEFFFE)) ++wrongPixels; } return wrongPixels < size / 400; // threshold level 1% of dwords } return true; // No data to decide } void FrameBuffer::resolveMultisampledTexture() { #ifdef GL_MULTISAMPLING_SUPPORT if (m_resolved) return; glScissor(0, 0, m_pTexture->realWidth, m_pTexture->realHeight); glBindFramebuffer(GL_READ_FRAMEBUFFER, m_FBO); glReadBuffer(GL_COLOR_ATTACHMENT0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_resolveFBO); glBlitFramebuffer( 0, 0, m_pTexture->realWidth, m_pTexture->realHeight, 0, 0, m_pResolveTexture->realWidth, m_pResolveTexture->realHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST ); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferList().getCurrent()->m_FBO); gDP.changed |= CHANGED_SCISSOR; m_resolved = true; #endif } CachedTexture * FrameBuffer::getTexture() { if (config.video.multisampling == 0) return m_pTexture; if (m_resolved) return m_pResolveTexture; resolveMultisampledTexture(); return m_pResolveTexture; } FrameBufferList & FrameBufferList::get() { static FrameBufferList frameBufferList; return frameBufferList; } void FrameBufferList::init() { m_pCurrent = NULL; m_pCopy = NULL; glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); } void FrameBufferList::destroy() { m_list.clear(); m_pCurrent = NULL; m_pCopy = NULL; glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); } void FrameBufferList::setBufferChanged() { gDP.colorImage.changed = TRUE; if (m_pCurrent != NULL) { m_pCurrent->m_changed = true; m_pCurrent->m_copiedToRdram = false; } } void FrameBufferList::correctHeight() { if (m_pCurrent == NULL) return; if (m_pCurrent->m_changed) { m_pCurrent->m_needHeightCorrection = false; return; } if (m_pCurrent->m_needHeightCorrection && m_pCurrent->m_width == gDP.scissor.lrx) { if (m_pCurrent->m_height != gDP.scissor.lry) { m_pCurrent->reinit((u32)gDP.scissor.lry); if (m_pCurrent->_isMarioTennisScoreboard()) g_RDRAMtoFB.CopyFromRDRAM(m_pCurrent->m_startAddress + 4, false); gSP.changed |= CHANGED_VIEWPORT; } m_pCurrent->m_needHeightCorrection = false; } } void FrameBufferList::clearBuffersChanged() { gDP.colorImage.changed = FALSE; FrameBuffer * pBuffer = frameBufferList().findBuffer(*REG.VI_ORIGIN); if (pBuffer != NULL) pBuffer->m_changed = false; } FrameBuffer * FrameBufferList::findBuffer(u32 _startAddress) { for (FrameBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter) if (iter->m_startAddress <= _startAddress && iter->m_endAddress >= _startAddress) // [ { ] return &(*iter); return NULL; } FrameBuffer * FrameBufferList::_findBuffer(u32 _startAddress, u32 _endAddress, u32 _width) { if (m_list.empty()) return NULL; FrameBuffers::iterator iter = m_list.end(); do { --iter; if ((iter->m_startAddress <= _startAddress && iter->m_endAddress >= _startAddress) || // [ { ] (_startAddress <= iter->m_startAddress && _endAddress >= iter->m_startAddress)) { // { [ } if (_startAddress != iter->m_startAddress || _width != iter->m_width) { m_list.erase(iter); return _findBuffer(_startAddress, _endAddress, _width); } return &(*iter); } } while (iter != m_list.begin()); return NULL; } FrameBuffer * FrameBufferList::findTmpBuffer(u32 _address) { for (FrameBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter) if (iter->m_startAddress > _address || iter->m_endAddress < _address) return &(*iter); return NULL; } void FrameBufferList::saveBuffer(u32 _address, u16 _format, u16 _size, u16 _width, u16 _height, bool _cfb) { if (m_pCurrent != NULL && config.frameBufferEmulation.copyAuxToRDRAM != 0) { if (m_pCurrent->m_width != VI.width) { FrameBuffer_CopyToRDRAM(m_pCurrent->m_startAddress, true); removeBuffer(m_pCurrent->m_startAddress); } } if (VI.width == 0 || _height == 0) { m_pCurrent = NULL; glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); return; } OGLVideo & ogl = video(); if (m_pCurrent != NULL) { if (gDP.colorImage.height > 0) { if (m_pCurrent->m_width == VI.width || m_pCurrent->m_needHeightCorrection) { gDP.colorImage.height = min(gDP.colorImage.height, VI.height); m_pCurrent->m_endAddress = min(RDRAMSize, m_pCurrent->m_startAddress + (((m_pCurrent->m_width * gDP.colorImage.height) << m_pCurrent->m_size >> 1) - 1)); } if (!m_pCurrent->_isMarioTennisScoreboard() && !m_pCurrent->m_isDepthBuffer && !m_pCurrent->m_copiedToRdram && !m_pCurrent->m_cfb && !m_pCurrent->m_cleared && m_pCurrent->m_RdramCopy.empty() && gDP.colorImage.height > 1) { m_pCurrent->copyRdram(); } } m_pCurrent = _findBuffer(m_pCurrent->m_startAddress, m_pCurrent->m_endAddress, m_pCurrent->m_width); } const u32 endAddress = _address + ((_width * _height) << _size >> 1) - 1; if (m_pCurrent == NULL || m_pCurrent->m_startAddress != _address || m_pCurrent->m_width != _width) m_pCurrent = findBuffer(_address); if (m_pCurrent != NULL) { if ((m_pCurrent->m_startAddress != _address) || (m_pCurrent->m_width != _width) || //(current->height != height) || //(current->size != size) || // TODO FIX ME (m_pCurrent->m_scaleX != ogl.getScaleX()) || (m_pCurrent->m_scaleY != ogl.getScaleY())) { removeBuffer(m_pCurrent->m_startAddress); m_pCurrent = NULL; } else { m_pCurrent->m_resolved = false; glBindFramebuffer(GL_FRAMEBUFFER, m_pCurrent->m_FBO); if (m_pCurrent->m_size != _size) { f32 fillColor[4]; gDPGetFillColor(fillColor); ogl.getRender().clearColorBuffer(fillColor); m_pCurrent->m_size = _size; m_pCurrent->m_pTexture->format = _format; m_pCurrent->m_pTexture->size = _size; if (m_pCurrent->m_pResolveTexture != NULL) { m_pCurrent->m_pResolveTexture->format = _format; m_pCurrent->m_pResolveTexture->size = _size; } if (m_pCurrent->m_copiedToRdram) m_pCurrent->copyRdram(); } } } const bool bNew = m_pCurrent == NULL; if (bNew) { // Wasn't found or removed, create a new one m_list.emplace_front(); FrameBuffer & buffer = m_list.front(); buffer.init(_address, endAddress, _format, _size, _width, _height, _cfb); m_pCurrent = &buffer; if (m_pCurrent->_isMarioTennisScoreboard()) g_RDRAMtoFB.CopyFromRDRAM(m_pCurrent->m_startAddress + 4, false); } if (_address == gDP.depthImageAddress) depthBufferList().saveBuffer(_address); else attachDepthBuffer(); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "FrameBuffer_SaveBuffer( 0x%08X ); depth buffer is 0x%08X\n", address, (depthBuffer.top != NULL && depthBuffer.top->renderbuf > 0) ? depthBuffer.top->address : 0 ); #endif m_pCurrent->m_isDepthBuffer = _address == gDP.depthImageAddress; m_pCurrent->m_isPauseScreen = m_pCurrent->m_isOBScreen = false; m_pCurrent->m_postProcessed = 0; } void FrameBufferList::copyAux() { for (FrameBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter) { if (iter->m_width != VI.width && iter->m_height != VI.height) FrameBuffer_CopyToRDRAM(iter->m_startAddress, true); } } void FrameBufferList::removeAux() { for (FrameBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter) { while (iter->m_width != VI.width && iter->m_height != VI.height) { if (&(*iter) == m_pCurrent) { m_pCurrent = NULL; glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); } iter = m_list.erase(iter); if (iter == m_list.end()) return; } } } void FrameBufferList::removeBuffer(u32 _address ) { for (FrameBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter) if (iter->m_startAddress == _address) { if (&(*iter) == m_pCurrent) { m_pCurrent = NULL; glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); } m_list.erase(iter); return; } } void FrameBufferList::removeBuffers(u32 _width) { m_pCurrent = NULL; for (FrameBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter) { while (iter->m_width == _width) { if (&(*iter) == m_pCurrent) { m_pCurrent = NULL; glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); } iter = m_list.erase(iter); if (iter == m_list.end()) return; } } } void FrameBufferList::attachDepthBuffer() { if (m_pCurrent == NULL) return; DepthBuffer * pDepthBuffer = depthBufferList().getCurrent(); if (m_pCurrent->m_FBO > 0 && pDepthBuffer != NULL) { pDepthBuffer->initDepthImageTexture(m_pCurrent); pDepthBuffer->initDepthBufferTexture(m_pCurrent); #ifdef GLES2 if (pDepthBuffer->m_pDepthBufferTexture->realWidth == m_pCurrent->m_pTexture->realWidth) { #else if (pDepthBuffer->m_pDepthBufferTexture->realWidth >= m_pCurrent->m_pTexture->realWidth) { #endif m_pCurrent->m_pDepthBuffer = pDepthBuffer; pDepthBuffer->setDepthAttachment(GL_DRAW_FRAMEBUFFER); if (video().getRender().isImageTexturesSupported() && config.frameBufferEmulation.N64DepthCompare != 0) pDepthBuffer->bindDepthImageTexture(); } else m_pCurrent->m_pDepthBuffer = NULL; } else m_pCurrent->m_pDepthBuffer = NULL; #ifndef GLES2 GLuint attachments[1] = { GL_COLOR_ATTACHMENT0 }; glDrawBuffers(1, attachments); #endif assert(checkFBO()); } void FrameBuffer_Init() { frameBufferList().init(); if (config.frameBufferEmulation.enable != 0) { #ifndef GLES2 g_fbToRDRAM.Init(); g_dbToRDRAM.Init(); #endif g_RDRAMtoFB.Init(); } } void FrameBuffer_Destroy() { g_RDRAMtoFB.Destroy(); #ifndef GLES2 g_dbToRDRAM.Destroy(); g_fbToRDRAM.Destroy(); #endif frameBufferList().destroy(); } #ifndef GLES2 void FrameBufferList::renderBuffer(u32 _address) { static s32 vStartPrev = 0; if (VI.width == 0 || *REG.VI_WIDTH == 0 || *REG.VI_H_START == 0) // H width is zero. Don't draw return; FrameBuffer *pBuffer = findBuffer(_address); if (pBuffer == NULL) return; OGLVideo & ogl = video(); OGLRender & render = ogl.getRender(); GLint srcY0, srcY1, dstY0, dstY1; GLint X0, X1, Xwidth; GLint srcPartHeight = 0; GLint dstPartHeight = 0; const f32 yScale = _FIXED2FLOAT(_SHIFTR(*REG.VI_Y_SCALE, 0, 12), 10); s32 vEnd = _SHIFTR(*REG.VI_V_START, 0, 10); s32 vStart = _SHIFTR(*REG.VI_V_START, 16, 10); const s32 hEnd = _SHIFTR(*REG.VI_H_START, 0, 10); const s32 hStart = _SHIFTR(*REG.VI_H_START, 16, 10); const s32 vSync = (*REG.VI_V_SYNC) & 0x03FF; const bool interlaced = (*REG.VI_STATUS & 0x40) != 0; const bool isPAL = vSync > 550; const s32 vShift = (isPAL ? 47 : 37); dstY0 = vStart - vShift; dstY0 >>= 1; dstY0 &= -(dstY0 >= 0); vStart >>= 1; vEnd >>= 1; const u32 vFullHeight = isPAL ? 288 : 240; const u32 vCurrentHeight = vEnd - vStart; const float dstScaleY = (float)ogl.getHeight() / float(vFullHeight); bool isLowerField = false; if (interlaced) isLowerField = vStart > vStartPrev; vStartPrev = vStart; srcY0 = ((_address - pBuffer->m_startAddress) << 1 >> pBuffer->m_size) / (*REG.VI_WIDTH); if (isLowerField) { if (srcY0 > 0) --srcY0; if (dstY0 > 0) --dstY0; } if (srcY0 + vCurrentHeight > vFullHeight) { dstPartHeight = srcY0; srcY0 = (GLint)(srcY0*yScale); srcPartHeight = srcY0; srcY1 = VI.real_height; dstY1 = dstY0 + vCurrentHeight - dstPartHeight; } else { dstY0 += srcY0; dstY1 = dstY0 + vCurrentHeight; srcY0 = (GLint)(srcY0*yScale); srcY1 = srcY0 + VI.real_height; } const f32 scaleX = _FIXED2FLOAT(_SHIFTR(*REG.VI_X_SCALE, 0, 12), 10); const s32 h0 = (isPAL ? 128 : 108); const s32 hx0 = max(0, hStart - h0); const s32 hx1 = max(0, h0 + 640 - hEnd); X0 = (GLint)(hx0 * scaleX * ogl.getScaleX()); Xwidth = (GLint)((min((f32)VI.width, (hEnd - hStart)*scaleX)) * ogl.getScaleX()); X1 = ogl.getWidth() - (GLint)(hx1 *scaleX * ogl.getScaleX()); const float srcScaleY = ogl.getScaleY(); const GLint hOffset = (ogl.getScreenWidth() - ogl.getWidth()) / 2; const GLint vOffset = (ogl.getScreenHeight() - ogl.getHeight()) / 2 + ogl.getHeightOffset(); CachedTexture * pBufferTexture = pBuffer->m_pTexture; GLint srcCoord[4] = { 0, (GLint)(srcY0*srcScaleY), Xwidth, min((GLint)(srcY1*srcScaleY), (GLint)pBufferTexture->realHeight) }; if (srcCoord[2] > pBufferTexture->realWidth || srcCoord[3] > pBufferTexture->realHeight) { removeBuffer(pBuffer->m_startAddress); return; } GLint dstCoord[4] = { X0 + hOffset, vOffset + (GLint)(dstY0*dstScaleY), hOffset + X1, vOffset + (GLint)(dstY1*dstScaleY) }; #ifdef GLESX if (render.getRenderer() == OGLRender::glrAdreno) dstCoord[0] += 1; // workaround for Adreno's issue with glBindFramebuffer; #endif // GLESX render.updateScissor(pBuffer); PostProcessor::get().doGammaCorrection(pBuffer); PostProcessor::get().doBlur(pBuffer); // glDisable(GL_SCISSOR_TEST) does not affect glBlitFramebuffer, at least on AMD glScissor(0, 0, ogl.getScreenWidth(), ogl.getScreenHeight() + ogl.getHeightOffset()); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); //glDrawBuffer( GL_BACK ); float clearColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; render.clearColorBuffer(clearColor); GLenum filter = GL_LINEAR; if (config.video.multisampling != 0) { if (X0 > 0 || dstPartHeight > 0 || (srcCoord[2] - srcCoord[0]) != (dstCoord[2] - dstCoord[0]) || (srcCoord[3] - srcCoord[1]) != (dstCoord[3] - dstCoord[1])) { pBuffer->resolveMultisampledTexture(); glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_resolveFBO); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); } else { glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_FBO); filter = GL_NEAREST; } } else glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_FBO); glBlitFramebuffer( srcCoord[0], srcCoord[1], srcCoord[2], srcCoord[3], dstCoord[0], dstCoord[1], dstCoord[2], dstCoord[3], GL_COLOR_BUFFER_BIT, filter ); if (dstPartHeight > 0) { const u32 size = *REG.VI_STATUS & 3; pBuffer = findBuffer(_address + (((*REG.VI_WIDTH)*VI.height)<>1)); if (pBuffer != NULL) { srcY0 = 0; srcY1 = srcPartHeight; dstY0 = dstY1; dstY1 = dstY0 + dstPartHeight; glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_FBO); glBlitFramebuffer( 0, (GLint)(srcY0*srcScaleY), ogl.getWidth(), min((GLint)(srcY1*srcScaleY), (GLint)pBuffer->m_pTexture->realHeight), hOffset, vOffset + (GLint)(dstY0*dstScaleY), hOffset + ogl.getWidth(), vOffset + (GLint)(dstY1*dstScaleY), GL_COLOR_BUFFER_BIT, filter ); } } glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); if (m_pCurrent != NULL) glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_pCurrent->m_FBO); ogl.swapBuffers(); gDP.changed |= CHANGED_SCISSOR; } #else void FrameBufferList::renderBuffer(u32 _address) { if (VI.width == 0 || *REG.VI_WIDTH == 0 || *REG.VI_H_START == 0) // H width is zero. Don't draw return; FrameBuffer *pBuffer = findBuffer(_address); if (pBuffer == NULL) return; OGLVideo & ogl = video(); ogl.getRender().updateScissor(pBuffer); PostProcessor::get().doGammaCorrection(pBuffer); PostProcessor::get().doBlur(pBuffer); ogl.getRender().dropRenderState(); gSP.changed = gDP.changed = 0; CombinerInfo::get().setCombine(EncodeCombineMode(0, 0, 0, TEXEL0, 0, 0, 0, 1, 0, 0, 0, TEXEL0, 0, 0, 0, 1)); glDisable( GL_BLEND ); glDisable(GL_DEPTH_TEST); glDisable( GL_CULL_FACE ); glDisable( GL_POLYGON_OFFSET_FILL ); const u32 width = pBuffer->m_width; const u32 height = pBuffer->m_height; pBuffer->m_pTexture->scaleS = ogl.getScaleX() / (float)pBuffer->m_pTexture->realWidth; pBuffer->m_pTexture->scaleT = ogl.getScaleY() / (float)pBuffer->m_pTexture->realHeight; pBuffer->m_pTexture->shiftScaleS = 1.0f; pBuffer->m_pTexture->shiftScaleT = 1.0f; pBuffer->m_pTexture->offsetS = 0; pBuffer->m_pTexture->offsetT = (float)height; textureCache().activateTexture(0, pBuffer->m_pTexture); gSP.textureTile[0]->fuls = gSP.textureTile[0]->fult = 0.0f; gSP.textureTile[0]->shifts = gSP.textureTile[0]->shiftt = 0; currentCombiner()->updateTextureInfo(true); CombinerInfo::get().updateParameters(OGLRender::rsTexRect); glScissor(0, 0, ogl.getScreenWidth(), ogl.getScreenHeight() + ogl.getHeightOffset()); glBindFramebuffer(GL_FRAMEBUFFER, 0); FrameBuffer * pCurrent = m_pCurrent; m_pCurrent = pBuffer; OGLRender::TexturedRectParams params(0.0f, 0.0f, width, height, 0.0f, 0.0f, width - 1.0f, height - 1.0f, false); ogl.getRender().drawTexturedRect(params); m_pCurrent = pCurrent; glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); if (m_pCurrent != NULL) glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_pCurrent->m_FBO); ogl.swapBuffers(); gSP.changed |= CHANGED_VIEWPORT; gDP.changed |= CHANGED_COMBINE | CHANGED_SCISSOR; } #endif void FrameBuffer_ActivateBufferTexture(s16 t, FrameBuffer *pBuffer) { if (pBuffer == NULL || pBuffer->m_pTexture == NULL) return; CachedTexture *pTexture = pBuffer->m_pTexture; pTexture->scaleS = pBuffer->m_scaleX / (float)pTexture->realWidth; pTexture->scaleT = pBuffer->m_scaleY / (float)pTexture->realHeight; if (gSP.textureTile[t]->shifts > 10) pTexture->shiftScaleS = (float)(1 << (16 - gSP.textureTile[t]->shifts)); else if (gSP.textureTile[t]->shifts > 0) pTexture->shiftScaleS = 1.0f / (float)(1 << gSP.textureTile[t]->shifts); else pTexture->shiftScaleS = 1.0f; if (gSP.textureTile[t]->shiftt > 10) pTexture->shiftScaleT = (float)(1 << (16 - gSP.textureTile[t]->shiftt)); else if (gSP.textureTile[t]->shiftt > 0) pTexture->shiftScaleT = 1.0f / (float)(1 << gSP.textureTile[t]->shiftt); else pTexture->shiftScaleT = 1.0f; const u32 shift = gSP.textureTile[t]->imageAddress - pBuffer->m_startAddress; const u32 factor = pBuffer->m_width << pBuffer->m_size >> 1; if (gSP.textureTile[t]->loadType == LOADTYPE_TILE) { pTexture->offsetS = (float)pBuffer->m_pLoadTile->uls; pTexture->offsetT = (float)(pBuffer->m_height - (pBuffer->m_pLoadTile->ult + shift/factor)); } else { pTexture->offsetS = (float)((shift % factor) >> pBuffer->m_size << 1); pTexture->offsetT = (float)(pBuffer->m_height - shift/factor); } // frameBufferList().renderBuffer(pBuffer->m_startAddress); textureCache().activateTexture(t, pTexture); gDP.changed |= CHANGED_FB_TEXTURE; } void FrameBuffer_ActivateBufferTextureBG(s16 t, FrameBuffer *pBuffer ) { if (pBuffer == NULL || pBuffer->m_pTexture == NULL) return; CachedTexture *pTexture = pBuffer->m_pTexture; pTexture->scaleS = video().getScaleX() / (float)pTexture->realWidth; pTexture->scaleT = video().getScaleY() / (float)pTexture->realHeight; pTexture->shiftScaleS = 1.0f; pTexture->shiftScaleT = 1.0f; pTexture->offsetS = gSP.bgImage.imageX; pTexture->offsetT = (float)pBuffer->m_height - gSP.bgImage.imageY; // FrameBuffer_RenderBuffer(buffer->startAddress); textureCache().activateTexture(t, pTexture); gDP.changed |= CHANGED_FB_TEXTURE; } static void copyWhiteToRDRAM(FrameBuffer * _pBuffer) { if (_pBuffer->m_size == G_IM_SIZ_32b) { u32 *ptr_dst = (u32*)(RDRAM + _pBuffer->m_startAddress); for (u32 y = 0; y < VI.height; ++y) { for (u32 x = 0; x < VI.width; ++x) ptr_dst[x + y*VI.width] = 0xFFFFFFFF; } } else { u16 *ptr_dst = (u16*)(RDRAM + _pBuffer->m_startAddress); for (u32 y = 0; y < VI.height; ++y) { for (u32 x = 0; x < VI.width; ++x) { ptr_dst[(x + y*VI.width) ^ 1] = 0xFFFF; } } } _pBuffer->m_copiedToRdram = true; _pBuffer->copyRdram(); _pBuffer->m_cleared = false; } #ifndef GLES2 void FrameBufferToRDRAM::Init() { // generate a framebuffer glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glGenFramebuffers(1, &m_FBO); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FBO); m_pTexture = textureCache().addFrameBufferTexture(); m_pTexture->format = G_IM_FMT_RGBA; m_pTexture->clampS = 1; m_pTexture->clampT = 1; m_pTexture->frameBufferTexture = CachedTexture::fbOneSample; m_pTexture->maskS = 0; m_pTexture->maskT = 0; m_pTexture->mirrorS = 0; m_pTexture->mirrorT = 0; m_pTexture->realWidth = 640; m_pTexture->realHeight = 580; m_pTexture->textureBytes = m_pTexture->realWidth * m_pTexture->realHeight * 4; textureCache().addFrameBufferTextureSize(m_pTexture->textureBytes); glBindTexture( GL_TEXTURE_2D, m_pTexture->glName ); glTexImage2D(GL_TEXTURE_2D, 0, fboFormats.colorInternalFormat, m_pTexture->realWidth, m_pTexture->realHeight, 0, fboFormats.colorFormat, fboFormats.colorType, NULL); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glBindTexture(GL_TEXTURE_2D, 0); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_pTexture->glName, 0); // check if everything is OK assert(checkFBO()); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); // Generate and initialize Pixel Buffer Objects glGenBuffers(3, m_PBO); for (u32 i = 0; i < 3; ++i) { glBindBuffer(GL_PIXEL_PACK_BUFFER, m_PBO[i]); glBufferData(GL_PIXEL_PACK_BUFFER, m_pTexture->textureBytes, NULL, GL_DYNAMIC_READ); } glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); m_curIndex = 0; } void FrameBufferToRDRAM::Destroy() { glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); if (m_FBO != 0) { glDeleteFramebuffers(1, &m_FBO); m_FBO = 0; } if (m_pTexture != NULL) { textureCache().removeFrameBufferTexture(m_pTexture); m_pTexture = NULL; } glDeleteBuffers(3, m_PBO); m_PBO[0] = m_PBO[1] = m_PBO[2] = 0; } void FrameBufferToRDRAM::CopyToRDRAM(u32 _address, bool _sync) { if (VI.width == 0 || frameBufferList().getCurrent() == NULL) return; FrameBuffer *pBuffer = frameBufferList().findBuffer(_address); if (pBuffer == NULL || pBuffer->m_isOBScreen) return; const u32 numPixels = pBuffer->m_width * pBuffer->m_height; if (numPixels == 0) return; const u32 stride = pBuffer->m_width << pBuffer->m_size >> 1; const u32 height = _cutHeight(_address, pBuffer->m_height, stride); if (height == 0) return; if ((config.generalEmulation.hacks & hack_subscreen) != 0 && pBuffer->m_width == VI.width && pBuffer->m_height == VI.height) { copyWhiteToRDRAM(pBuffer); return; } _address = pBuffer->m_startAddress; if (config.video.multisampling != 0) { pBuffer->resolveMultisampledTexture(); glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_resolveFBO); } else glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_FBO); if (pBuffer->m_scaleX > 1.0f) { glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FBO); glScissor(0, 0, pBuffer->m_pTexture->realWidth, pBuffer->m_pTexture->realHeight); glBlitFramebuffer( 0, 0, video().getWidth(), video().getHeight(), 0, 0, VI.width, VI.height, GL_COLOR_BUFFER_BIT, GL_NEAREST ); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferList().getCurrent()->m_FBO); glBindFramebuffer(GL_READ_FRAMEBUFFER, m_FBO); } #ifndef GLES2 // If Sync, read pixels from the buffer, copy them to RDRAM. // If not Sync, read pixels from the buffer, copy pixels from the previous buffer to RDRAM. if (!_sync) { m_curIndex ^= 1; const u32 nextIndex = m_curIndex^1; glBindBuffer(GL_PIXEL_PACK_BUFFER, m_PBO[m_curIndex]); glReadPixels(0, 0, pBuffer->m_width, pBuffer->m_height, GL_RGBA, GL_UNSIGNED_BYTE, 0); glBindBuffer(GL_PIXEL_PACK_BUFFER, m_PBO[nextIndex]); } else { glBindBuffer(GL_PIXEL_PACK_BUFFER, m_PBO[2]); glReadPixels(0, 0, pBuffer->m_width, pBuffer->m_height, GL_RGBA, GL_UNSIGNED_BYTE, 0); } GLubyte* pixelData = (GLubyte*)glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, numPixels * 4, GL_MAP_READ_BIT); if (pixelData == NULL) return; #else GLubyte* pixelData = (GLubyte* )malloc(numPixels * 4); if (pixelData == NULL) return; glReadPixels(0, 0, VI.width, VI.height, GL_RGBA, GL_UNSIGNED_BYTE, pixelData); #endif // GLES2 if (pBuffer->m_size == G_IM_SIZ_32b) { u32 *ptr_dst = (u32*)(RDRAM + _address); u32 *ptr_src = (u32*)pixelData; RGBA c; for (u32 y = 0; y < height; ++y) { for (u32 x = 0; x < pBuffer->m_width; ++x) { c.raw = ptr_src[x + (height - y - 1)*pBuffer->m_width]; if (c.raw != 0) ptr_dst[(x + y*pBuffer->m_width)] = (c.r << 24) | (c.g << 16) | (c.b << 8) | c.a; } } } else if (pBuffer->m_size == G_IM_SIZ_16b) { u16 *ptr_dst = (u16*)(RDRAM + _address); u32 * ptr_src = (u32*)pixelData; RGBA c; for (u32 y = 0; y < height; ++y) { for (u32 x = 0; x < pBuffer->m_width; ++x) { c.raw = ptr_src[x + (height - y - 1)*pBuffer->m_width]; if (c.raw != 0) ptr_dst[(x + y*pBuffer->m_width) ^ 1] = ((c.r >> 3) << 11) | ((c.g >> 3) << 6) | ((c.b >> 3) << 1) | (c.a == 0 ? 0 : 1); } } } pBuffer->m_copiedToRdram = true; pBuffer->copyRdram(); pBuffer->m_cleared = false; #ifndef GLES2 glUnmapBuffer(GL_PIXEL_PACK_BUFFER); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); #else free(pixelData); #endif glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); gDP.changed |= CHANGED_SCISSOR; } #endif // GLES2 void FrameBuffer_CopyToRDRAM(u32 _address, bool _sync) { #ifndef GLES2 g_fbToRDRAM.CopyToRDRAM(_address, _sync); #else if ((config.generalEmulation.hacks & hack_subscreen) == 0) return; if (VI.width == 0 || frameBufferList().getCurrent() == NULL) return; FrameBuffer *pBuffer = frameBufferList().findBuffer(_address); if (pBuffer == NULL || pBuffer->m_width < VI.width || pBuffer->m_isOBScreen) return; copyWhiteToRDRAM(pBuffer); #endif } #ifndef GLES2 void DepthBufferToRDRAM::Init() { // generate a framebuffer glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glGenFramebuffers(1, &m_FBO); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FBO); m_pColorTexture = textureCache().addFrameBufferTexture(); m_pColorTexture->format = G_IM_FMT_I; m_pColorTexture->clampS = 1; m_pColorTexture->clampT = 1; m_pColorTexture->frameBufferTexture = CachedTexture::fbOneSample; m_pColorTexture->maskS = 0; m_pColorTexture->maskT = 0; m_pColorTexture->mirrorS = 0; m_pColorTexture->mirrorT = 0; m_pColorTexture->realWidth = 640; m_pColorTexture->realHeight = 580; m_pColorTexture->textureBytes = m_pColorTexture->realWidth * m_pColorTexture->realHeight; textureCache().addFrameBufferTextureSize(m_pColorTexture->textureBytes); m_pDepthTexture = textureCache().addFrameBufferTexture(); m_pDepthTexture->format = G_IM_FMT_I; m_pDepthTexture->clampS = 1; m_pDepthTexture->clampT = 1; m_pDepthTexture->frameBufferTexture = CachedTexture::fbOneSample; m_pDepthTexture->maskS = 0; m_pDepthTexture->maskT = 0; m_pDepthTexture->mirrorS = 0; m_pDepthTexture->mirrorT = 0; m_pDepthTexture->realWidth = 640; m_pDepthTexture->realHeight = 580; m_pDepthTexture->textureBytes = m_pDepthTexture->realWidth * m_pDepthTexture->realHeight * sizeof(float); textureCache().addFrameBufferTextureSize(m_pDepthTexture->textureBytes); glBindTexture( GL_TEXTURE_2D, m_pColorTexture->glName ); glTexImage2D(GL_TEXTURE_2D, 0, fboFormats.monochromeInternalFormat, m_pColorTexture->realWidth, m_pColorTexture->realHeight, 0, fboFormats.monochromeFormat, fboFormats.monochromeType, NULL); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glBindTexture( GL_TEXTURE_2D, m_pDepthTexture->glName ); glTexImage2D(GL_TEXTURE_2D, 0, fboFormats.depthInternalFormat, m_pDepthTexture->realWidth, m_pDepthTexture->realHeight, 0, GL_DEPTH_COMPONENT, fboFormats.depthType, NULL); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glBindTexture(GL_TEXTURE_2D, 0); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_pColorTexture->glName, 0); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_pDepthTexture->glName, 0); // check if everything is OK assert(checkFBO()); assert(!isGLError()); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); // Generate and initialize Pixel Buffer Objects glGenBuffers(1, &m_PBO); glBindBuffer(GL_PIXEL_PACK_BUFFER, m_PBO); glBufferData(GL_PIXEL_PACK_BUFFER, m_pDepthTexture->realWidth * m_pDepthTexture->realHeight * sizeof(float), NULL, GL_DYNAMIC_READ); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); } void DepthBufferToRDRAM::Destroy() { glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glDeleteFramebuffers(1, &m_FBO); m_FBO = 0; if (m_pColorTexture != NULL) { textureCache().removeFrameBufferTexture(m_pColorTexture); m_pColorTexture = NULL; } if (m_pDepthTexture != NULL) { textureCache().removeFrameBufferTexture(m_pDepthTexture); m_pDepthTexture = NULL; } if (m_PBO != 0) { glDeleteBuffers(1, &m_PBO); m_PBO = 0; } } bool DepthBufferToRDRAM::CopyToRDRAM( u32 _address) { const u32 numPixels = VI.width * VI.height; if (numPixels == 0) // Incorrect buffer size. Don't copy return false; FrameBuffer *pBuffer = frameBufferList().findBuffer(_address); if (pBuffer == NULL || pBuffer->m_width < VI.width || pBuffer->m_pDepthBuffer == NULL || !pBuffer->m_pDepthBuffer->m_cleared) return false; DepthBuffer * pDepthBuffer = pBuffer->m_pDepthBuffer; const u32 address = pDepthBuffer->m_address; if (address + numPixels * 2 > RDRAMSize) return false; const u32 height = _cutHeight(address, min(VI.height, pDepthBuffer->m_lry), pBuffer->m_width * 2); if (height == 0) return false; if (config.video.multisampling == 0) glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_FBO); else { pDepthBuffer->resolveDepthBufferTexture(pBuffer); glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_resolveFBO); } glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FBO); glScissor(0, 0, pBuffer->m_pTexture->realWidth, pBuffer->m_pTexture->realHeight); glBlitFramebuffer( 0, 0, video().getWidth(), video().getHeight(), 0, 0, pBuffer->m_width, pBuffer->m_height, GL_DEPTH_BUFFER_BIT, GL_NEAREST ); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferList().getCurrent()->m_FBO); PBOBinder binder(GL_PIXEL_PACK_BUFFER, m_PBO); glBindFramebuffer(GL_READ_FRAMEBUFFER, m_FBO); glReadPixels(0, 0, VI.width, VI.height, GL_DEPTH_COMPONENT, GL_FLOAT, 0); GLubyte* pixelData = (GLubyte*)glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, numPixels * 4, GL_MAP_READ_BIT); if(pixelData == NULL) return false; f32 * ptr_src = (f32*)pixelData; u16 *ptr_dst = (u16*)(RDRAM + address); const u16 * const zLUT = depthBufferList().getZLUT(); for (u32 y = pDepthBuffer->m_uly; y < height; ++y) { for (u32 x = 0; x < VI.width; ++x) { f32 z = ptr_src[x + (height - y - 1)*VI.width]; u32 idx = 0x3FFFF; if (z < 1.0f) { z *= 262144.0f; idx = min(0x3FFFFU, u32(floorf(z + 0.5f))); } ptr_dst[(x + y*VI.width) ^ 1] = zLUT[idx]; } } pDepthBuffer->m_cleared = false; pBuffer = frameBufferList().findBuffer(pDepthBuffer->m_address); if (pBuffer != NULL) pBuffer->m_cleared = false; glUnmapBuffer(GL_PIXEL_PACK_BUFFER); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); gDP.changed |= CHANGED_SCISSOR; return true; } #endif // GLES2 bool FrameBuffer_CopyDepthBuffer( u32 address ) { #ifndef GLES2 FrameBuffer * pCopyBuffer = frameBufferList().getCopyBuffer(); if (pCopyBuffer != NULL) { // This code is mainly to emulate Zelda MM camera. g_fbToRDRAM.CopyToRDRAM(pCopyBuffer->m_startAddress, true); pCopyBuffer->m_RdramCopy.resize(0); // To disable validity check by RDRAM content. CPU may change content of the buffer for some unknown reason. frameBufferList().setCopyBuffer(NULL); return true; } else return g_dbToRDRAM.CopyToRDRAM(address); #else return false; #endif } void RDRAMtoFrameBuffer::Init() { m_pTexture = textureCache().addFrameBufferTexture(); m_pTexture->format = G_IM_FMT_RGBA; m_pTexture->clampS = 1; m_pTexture->clampT = 1; m_pTexture->frameBufferTexture = CachedTexture::fbOneSample; m_pTexture->maskS = 0; m_pTexture->maskT = 0; m_pTexture->mirrorS = 0; m_pTexture->mirrorT = 0; m_pTexture->realWidth = 640; m_pTexture->realHeight = 580; m_pTexture->textureBytes = m_pTexture->realWidth * m_pTexture->realHeight * 4; textureCache().addFrameBufferTextureSize(m_pTexture->textureBytes); glBindTexture( GL_TEXTURE_2D, m_pTexture->glName ); glTexImage2D(GL_TEXTURE_2D, 0, fboFormats.colorInternalFormat, m_pTexture->realWidth, m_pTexture->realHeight, 0, fboFormats.colorFormat, fboFormats.colorType, NULL); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glBindTexture(GL_TEXTURE_2D, 0); // Generate Pixel Buffer Object. Initialize it later #ifndef GLES2 glGenBuffers(1, &m_PBO); #endif } void RDRAMtoFrameBuffer::Destroy() { if (m_pTexture != NULL) { textureCache().removeFrameBufferTexture(m_pTexture); m_pTexture = NULL; } #ifndef GLES2 if (m_PBO != 0) { glDeleteBuffers(1, &m_PBO); m_PBO = 0; } #endif } void RDRAMtoFrameBuffer::CopyFromRDRAM( u32 _address, bool _bUseAlpha) { FrameBuffer *pBuffer = frameBufferList().findBuffer(_address); if (pBuffer == NULL || pBuffer->m_size < G_IM_SIZ_16b) return; if (pBuffer->m_startAddress == _address && gDP.colorImage.changed != 0) return; const bool bUseAlpha = _bUseAlpha && pBuffer->m_changed; const u32 address = pBuffer->m_startAddress; const u32 width = pBuffer->m_width; const u32 height = _cutHeight(address, pBuffer->m_startAddress == _address ? VI.real_height : pBuffer->m_height, pBuffer->m_width * 2); if (height == 0) return; m_pTexture->width = width; m_pTexture->height = height; const u32 dataSize = width*height*4; #ifndef GLES2 PBOBinder binder(GL_PIXEL_UNPACK_BUFFER, m_PBO); glBufferData(GL_PIXEL_UNPACK_BUFFER, dataSize, NULL, GL_DYNAMIC_DRAW); GLubyte* ptr = (GLubyte*)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, dataSize, GL_MAP_WRITE_BIT); #else m_PBO = (GLubyte*)malloc(dataSize); GLubyte* ptr = m_PBO; PBOBinder binder(m_PBO); #endif // GLES2 if (ptr == NULL) return; u8 * image = RDRAM + address; u32 * dst = (u32*)ptr; u32 empty = 0; u32 r, g, b, a, idx; if (pBuffer->m_size == G_IM_SIZ_16b) { u16 * src = (u16*)image; u16 col; const u32 bound = (RDRAMSize + 1 - address) >> 1; for (u32 y = 0; y < height; y++) { for (u32 x = 0; x < width; x++) { idx = (x + (height - y - 1)*width)^1; if (idx >= bound) break; col = src[idx]; if (bUseAlpha) src[idx] = 0; empty |= col; r = ((col >> 11)&31)<<3; g = ((col >> 6)&31)<<3; b = ((col >> 1)&31)<<3; a = (col&1) > 0 && (r|g|b) > 0 ? 0xff : 0U; dst[x + y*width] = (a << 24) | (b << 16) | (g << 8) | r; } } } else { // 32 bit u32 * src = (u32*)image; u32 col; const u32 bound = (RDRAMSize + 1 - address) >> 2; for (u32 y=0; y < height; y++) { for (u32 x=0; x < width; x++) { idx = x + (height - y - 1)*width; if (idx >= bound) break; col = src[idx]; if (bUseAlpha) src[idx] = 0; empty |= col; r = (col >> 24) & 0xff; g = (col >> 16) & 0xff; b = (col >> 8) & 0xff; a = (r|g|b) > 0 ? col & 0xff : 0U; dst[x + y*width] = (a<<24)|(b<<16)|(g<<8)|r; } } } #ifndef GLES2 glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); // release the mapped buffer #endif if (empty == 0) return; glBindTexture(GL_TEXTURE_2D, m_pTexture->glName); #ifndef GLES2 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, 0); #else glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, m_PBO); #endif m_pTexture->scaleS = 1.0f / (float)m_pTexture->realWidth; m_pTexture->scaleT = 1.0f / (float)m_pTexture->realHeight; m_pTexture->shiftScaleS = 1.0f; m_pTexture->shiftScaleT = 1.0f; m_pTexture->offsetS = 0; m_pTexture->offsetT = (float)m_pTexture->height; textureCache().activateTexture(0, m_pTexture); gDPTile tile0; tile0.fuls = tile0.fult = 0.0f; gDPTile * pTile0 = gSP.textureTile[0]; gSP.textureTile[0] = &tile0; if (_bUseAlpha) { CombinerInfo::get().setCombine(EncodeCombineMode(0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0)); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } else { CombinerInfo::get().setCombine(EncodeCombineMode(0, 0, 0, TEXEL0, 0, 0, 0, 1, 0, 0, 0, TEXEL0, 0, 0, 0, 1)); glDisable(GL_BLEND); } currentCombiner()->updateFBInfo(); glDisable(GL_DEPTH_TEST); const u32 gdpChanged = gDP.changed & CHANGED_CPU_FB_WRITE; gSP.changed = gDP.changed = 0; glBindFramebuffer(GL_DRAW_FRAMEBUFFER, pBuffer->m_FBO); OGLRender::TexturedRectParams params(0.0f, 0.0f, (float)width, (float)height, 0.0f, 0.0f, width - 1.0f, height - 1.0f, false); video().getRender().drawTexturedRect(params); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferList().getCurrent()->m_FBO); gSP.textureTile[0] = pTile0; gDP.changed |= gdpChanged | CHANGED_RENDERMODE | CHANGED_COMBINE; } void FrameBuffer_CopyFromRDRAM( u32 address, bool bUseAlpha ) { g_RDRAMtoFB.CopyFromRDRAM(address, bUseAlpha); } gles2n64/src/RDP.h000664 001750 001750 00000001002 12655644434 014641 0ustar00sergiosergio000000 000000 #ifndef _GLN64_RDP_H #define _GLN64_RDP_H #include "Types.h" #ifndef MAXCMD #define MAXCMD 0x100000 #endif #ifndef maxCMDMask #define maxCMDMask (MAXCMD - 1) #endif #ifdef __cplusplus extern "C" { #endif typedef struct { u32 w2, w3; u32 cmd_ptr; u32 cmd_cur; u32 cmd_data[MAXCMD + 32]; } RDPInfo; extern RDPInfo __RDP; void RDP_Init(void); void RDP_Half_1(u32 _c); void RDP_ProcessRDPList(); void RDP_RepeatLastLoadBlock(void); void RDP_SetScissor(u32 w0, u32 w1); #ifdef __cplusplus } #endif #endif mupen64plus-core/doc/emuwiki-api-doc/Mupen64Plus_v2.0_Core_Basic.txt000664 001750 001750 00000006320 12655644434 026262 0ustar00sergiosergio000000 000000 [[Mupen64Plus v2.0 Core API v1.0|Mupen64Plus v2.0 API]] = Mupen64Plus v2.0 Basic Core API = Most libmupen64plus functions return an m64p_error return code, which is an enumerated type defined in [[Mupen64Plus v2.0 headers#m64p_types.h|m64p_types.h]]. Front-end code should check the return value of each call to a libmupen64plus function. {| border="1" |Prototype |'''m64p_error PluginGetVersion(m64p_plugin_type *PluginType, int *PluginVersion, int *APIVersion, const char **PluginNamePtr, int *Capabilities)''' |- |Input Parameters |'''PluginType''' Pointer to an enumerated type to store the plugin type. The value M64PLUGIN_CORE will always be stored.
'''PluginVersion''' Pointer to an integer to store the version number of the Mupen64Plus core. Version number 2.1.3 would be stored as 0x00020103.
'''APIVersion''' Pointer to an integer to store the version number of the Core--Front-end API used by the Mupen64plus core library.
'''PluginNamePtr''' Pointer to a const character pointer to receive the name of the core library. The const char * which is returned must point to a persistent string (ie, not stored on the stack).
'''Capabilities''' Pointer to an integer to store a logically-or'd set of flags which specify the capabilities of the core which were built into the library during compilation. These are defined in the m64p_core_caps enumerated type, defined in [[Mupen64Plus v2.0 headers#m64p_types.h|m64p_types.h]]. |- |Usage |This function retrieves version information from the core library. This function is the same for the core library and the plugins, so that a front-end may examine all shared libraries in a directory and determine their types. Any of the input parameters may be set to NULL and this function will succeed but won't return the corresponding information. |}
{| border="1" |Prototype |'''m64p_error CoreGetAPIVersions(int *ConfigVersion, int *DebugVersion, int *VidextVersion, int *ExtraVersion)''' |- |Input Parameters |'''ConfigVersion''' Pointer to an integer to store the version number of the Config API exported by the Mupen64plus core library.
'''DebugVersion''' Pointer to an integer to store the version number of the Debug API exported by the Mupen64plus core library.
'''VidextVersion''' Pointer to an integer to store the version number of the Video Extension API exported by the Mupen64plus core library.
'''ExtraVersion''' Pointer to an integer to store an API version number for future use. Currently set to 0.
|- |Usage |This function retrieves API version information from the core library. This function may be used by either the front-end application or any plugin modules. Any of the input parameters may be set to NULL and this function will succeed but won't return the corresponding information. |}
{| border="1" |Prototype |'''const char * CoreErrorMessage(m64p_error ReturnCode)''' |- |Input Parameters |'''ReturnCode''' Enumerated type containing an error code. |- |Usage |This function returns a pointer to a NULL-terminated string giving a human-readable description of the error. |}
mupen64plus-video-gliden64/src/3DMath.cpp000664 001750 001750 00000002373 12655644434 021217 0ustar00sergiosergio000000 000000 #include #include "3DMath.h" void MultMatrix(float m0[4][4], float m1[4][4], float dest[4][4]) { int i; for (i = 0; i < 4; i++) { dest[0][i] = m0[0][i]*m1[0][0] + m0[1][i]*m1[0][1] + m0[2][i]*m1[0][2] + m0[3][i]*m1[0][3]; dest[1][i] = m0[0][i]*m1[1][0] + m0[1][i]*m1[1][1] + m0[2][i]*m1[1][2] + m0[3][i]*m1[1][3]; dest[2][i] = m0[0][i]*m1[2][0] + m0[1][i]*m1[2][1] + m0[2][i]*m1[2][2] + m0[3][i]*m1[2][3]; dest[3][i] = m0[3][i]*m1[3][3] + m0[2][i]*m1[3][2] + m0[1][i]*m1[3][1] + m0[0][i]*m1[3][0]; } } void MultMatrix2(float m0[4][4], float m1[4][4]) { float dst[4][4]; MultMatrix(m0, m1, dst); memcpy( m0, dst, sizeof(float) * 16 ); } void TransformVectorNormalize(float vec[3], float mtx[4][4]) { float len; float vres[3]; vres[0] = mtx[0][0] * vec[0] + mtx[1][0] * vec[1] + mtx[2][0] * vec[2]; vres[1] = mtx[0][1] * vec[0] + mtx[1][1] * vec[1] + mtx[2][1] * vec[2]; vres[2] = mtx[0][2] * vec[0] + mtx[1][2] * vec[1] + mtx[2][2] * vec[2]; memcpy(vec, vres, sizeof(float)*3); len = vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]; if (len != 0.0) { len = sqrtf(len); vec[0] /= len; vec[1] /= len; vec[2] /= len; } } gles2n64/src/RDP.c000664 001750 001750 00000044460 12655644434 014653 0ustar00sergiosergio000000 000000 #include "N64.h" #include "RSP.h" #include "GBI.h" #include "gDP.h" #include "Types.h" #include "Debug.h" #include "Common.h" #include "gSP.h" #include "RDP.h" #include RDPInfo __RDP; enum { gspTexRect = 0, gdpTexRect, halfTexRect }; void RDP_Unknown( u32 w0, u32 w1 ) { #ifdef DEBUG DebugMsg( DEBUG_UNKNOWN, "RDP_Unknown\r\n" ); DebugMsg( DEBUG_UNKNOWN, "\tUnknown RDP opcode %02X\r\n", _SHIFTR( w0, 24, 8 ) ); #endif } void RDP_NoOp( u32 w0, u32 w1 ) { gSPNoOp(); } void RDP_SetCImg( u32 w0, u32 w1 ) { gDPSetColorImage( _SHIFTR( w0, 21, 3 ), // fmt _SHIFTR( w0, 19, 2 ), // siz _SHIFTR( w0, 0, 12 ) + 1, // width w1 ); // img } void RDP_SetZImg( u32 w0, u32 w1 ) { gDPSetDepthImage( w1 ); // img } void RDP_SetTImg( u32 w0, u32 w1 ) { gDPSetTextureImage( _SHIFTR( w0, 21, 3), // fmt _SHIFTR( w0, 19, 2 ), // siz _SHIFTR( w0, 0, 12 ) + 1, // width w1 ); // img } void RDP_SetCombine( u32 w0, u32 w1 ) { gDPSetCombine( _SHIFTR( w0, 0, 24 ), // muxs0 w1 ); // muxs1 } void RDP_SetEnvColor( u32 w0, u32 w1 ) { gDPSetEnvColor( _SHIFTR( w1, 24, 8 ), // r _SHIFTR( w1, 16, 8 ), // g _SHIFTR( w1, 8, 8 ), // b _SHIFTR( w1, 0, 8 ) ); // a } void RDP_SetPrimColor( u32 w0, u32 w1 ) { gDPSetPrimColor( _SHIFTL( w0, 8, 5 ), // m _SHIFTL( w0, 0, 8 ), // l _SHIFTR( w1, 24, 8 ), // r _SHIFTR( w1, 16, 8 ), // g _SHIFTR( w1, 8, 8 ), // b _SHIFTR( w1, 0, 8 ) ); // a } void RDP_SetBlendColor( u32 w0, u32 w1 ) { gDPSetBlendColor( _SHIFTR( w1, 24, 8 ), // r _SHIFTR( w1, 16, 8 ), // g _SHIFTR( w1, 8, 8 ), // b _SHIFTR( w1, 0, 8 ) ); // a } void RDP_SetFogColor( u32 w0, u32 w1 ) { gDPSetFogColor( _SHIFTR( w1, 24, 8 ), // r _SHIFTR( w1, 16, 8 ), // g _SHIFTR( w1, 8, 8 ), // b _SHIFTR( w1, 0, 8 ) ); // a } void RDP_SetFillColor( u32 w0, u32 w1 ) { gDPSetFillColor( w1 ); } void RDP_FillRect( u32 w0, u32 w1 ) { const u32 ulx = _SHIFTR(w1, 14, 10); const u32 uly = _SHIFTR(w1, 2, 10); const u32 lrx = _SHIFTR(w0, 14, 10); const u32 lry = _SHIFTR(w0, 2, 10); if (lrx < ulx || lry < uly) return; gDPFillRectangle(ulx, uly, lrx, lry); } void RDP_SetTile( u32 w0, u32 w1 ) { gDPSetTile( _SHIFTR( w0, 21, 3 ), // fmt _SHIFTR( w0, 19, 2 ), // siz _SHIFTR( w0, 9, 9 ), // line _SHIFTR( w0, 0, 9 ), // tmem _SHIFTR( w1, 24, 3 ), // tile _SHIFTR( w1, 20, 4 ), // palette _SHIFTR( w1, 18, 2 ), // cmt _SHIFTR( w1, 8, 2 ), // cms _SHIFTR( w1, 14, 4 ), // maskt _SHIFTR( w1, 4, 4 ), // masks _SHIFTR( w1, 10, 4 ), // shiftt _SHIFTR( w1, 0, 4 ) ); // shifts } void RDP_LoadTile( u32 w0, u32 w1 ) { gDPLoadTile( _SHIFTR( w1, 24, 3 ), // tile _SHIFTR( w0, 12, 12 ), // uls _SHIFTR( w0, 0, 12 ), // ult _SHIFTR( w1, 12, 12 ), // lrs _SHIFTR( w1, 0, 12 ) ); // lrt } static u32 lbw0, lbw1; void RDP_LoadBlock( u32 w0, u32 w1 ) { lbw0 = w0; lbw1 = w1; gDPLoadBlock( _SHIFTR( w1, 24, 3 ), // tile _SHIFTR( w0, 12, 12 ), // uls _SHIFTR( w0, 0, 12 ), // ult _SHIFTR( w1, 12, 12 ), // lrs _SHIFTR( w1, 0, 12 ) ); // dxt } void RDP_RepeatLastLoadBlock() { RDP_LoadBlock(lbw0, lbw1); } void RDP_SetTileSize( u32 w0, u32 w1 ) { gDPSetTileSize( _SHIFTR( w1, 24, 3 ), // tile _SHIFTR( w0, 12, 12 ), // uls _SHIFTR( w0, 0, 12 ), // ult _SHIFTR( w1, 12, 12 ), // lrs _SHIFTR( w1, 0, 12 ) ); // lrt } void RDP_LoadTLUT( u32 w0, u32 w1 ) { gDPLoadTLUT( _SHIFTR( w1, 24, 3 ), // tile _SHIFTR( w0, 12, 12 ), // uls _SHIFTR( w0, 0, 12 ), // ult _SHIFTR( w1, 12, 12 ), // lrs _SHIFTR( w1, 0, 12 ) ); // lrt } void RDP_SetOtherMode( u32 w0, u32 w1 ) { gDPSetOtherMode( _SHIFTR( w0, 0, 24 ), // mode0 w1 ); // mode1 } void RDP_SetPrimDepth( u32 w0, u32 w1 ) { gDPSetPrimDepth( _SHIFTR( w1, 16, 16 ), // z _SHIFTR( w1, 0, 16 ) ); // dz } void RDP_SetScissor( u32 w0, u32 w1 ) { gDPSetScissor( _SHIFTR( w1, 24, 2 ), // mode _FIXED2FLOAT( _SHIFTR( w0, 12, 12 ), 2 ), // ulx _FIXED2FLOAT( _SHIFTR( w0, 0, 12 ), 2 ), // uly _FIXED2FLOAT( _SHIFTR( w1, 12, 12 ), 2 ), // lrx _FIXED2FLOAT( _SHIFTR( w1, 0, 12 ), 2 ) ); // lry } void RDP_SetConvert( u32 w0, u32 w1 ) { gDPSetConvert( _SHIFTR( w0, 13, 9 ), // k0 _SHIFTR( w0, 4, 9 ), // k1 _SHIFTL( w0, 5, 4 ) | _SHIFTR( w1, 27, 5 ), // k2 _SHIFTR( w1, 18, 9 ), // k3 _SHIFTR( w1, 9, 9 ), // k4 _SHIFTR( w1, 0, 9 ) ); // k5 } void RDP_SetKeyR( u32 w0, u32 w1 ) { gDPSetKeyR( _SHIFTR( w1, 8, 8 ), // cR _SHIFTR( w1, 0, 8 ), // sR _SHIFTR( w1, 16, 12 ) ); // wR } void RDP_SetKeyGB( u32 w0, u32 w1 ) { gDPSetKeyGB( _SHIFTR( w1, 24, 8 ), // cG _SHIFTR( w1, 16, 8 ), // sG _SHIFTR( w0, 12, 12 ), // wG _SHIFTR( w1, 8, 8 ), // cB _SHIFTR( w1, 0, 8 ), // SB _SHIFTR( w0, 0, 12 ) ); // wB } void RDP_FullSync( u32 w0, u32 w1 ) { gDPFullSync(); } void RDP_TileSync( u32 w0, u32 w1 ) { gDPTileSync(); } void RDP_PipeSync( u32 w0, u32 w1 ) { gDPPipeSync(); } void RDP_LoadSync( u32 w0, u32 w1 ) { gDPLoadSync(); } static void _getTexRectParams(u32 *w2, u32 *w3) { unsigned texRectMode; u32 cmd1, cmd2; if (__RSP.bLLE) { *w2 = __RDP.w2; *w3 = __RDP.w3; return; } texRectMode = gdpTexRect; cmd1 = (*(u32*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi] + 0]) >> 24; cmd2 = (*(u32*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi] + 8]) >> 24; if (cmd1 == G_RDPHALF_1) { if (cmd2 == G_RDPHALF_2) texRectMode = gspTexRect; } else if (cmd1 == 0xB3) { if (cmd2 == 0xB2) texRectMode = gspTexRect; else texRectMode = halfTexRect; } else if (cmd1 == 0xF1) texRectMode = halfTexRect; switch (texRectMode) { case gspTexRect: *w2 = *(u32*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi] + 4]; __RSP.PC[__RSP.PCi] += 8; *w3 = *(u32*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi] + 4]; __RSP.PC[__RSP.PCi] += 8; break; case gdpTexRect: *w2 = *(u32*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi] + 0]; *w3 = *(u32*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi] + 4]; __RSP.PC[__RSP.PCi] += 8; break; case halfTexRect: *w2 = 0; *w3 = *(u32*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi] + 4]; __RSP.PC[__RSP.PCi] += 8; break; default: #if 0 assert(false && "Unknown texrect mode"); #endif break; } } void RDP_TexRectFlip( u32 w0, u32 w1 ) { u32 ulx, uly, lrx, lry; u32 w2, w3; _getTexRectParams(&w2, &w3); ulx = _SHIFTR(w1, 12, 12); uly = _SHIFTR(w1, 0, 12); lrx = _SHIFTR(w0, 12, 12); lry = _SHIFTR(w0, 0, 12); if ((lrx >> 2) < (ulx >> 2) || (lry >> 2) < (uly >> 2)) return; gDPTextureRectangleFlip( _FIXED2FLOAT(ulx, 2), _FIXED2FLOAT(uly, 2), _FIXED2FLOAT(lrx, 2), _FIXED2FLOAT(lry, 2), _SHIFTR(w1, 24, 3), // tile _FIXED2FLOAT((s16)_SHIFTR(w2, 16, 16), 5), // s _FIXED2FLOAT((s16)_SHIFTR(w2, 0, 16), 5), // t _FIXED2FLOAT((s16)_SHIFTR(w3, 16, 16), 10), // dsdx _FIXED2FLOAT((s16)_SHIFTR(w3, 0, 16), 10)); // dsdy } void RDP_TexRect( u32 w0, u32 w1 ) { u32 ulx, uly, lrx, lry; u32 w2, w3; _getTexRectParams(&w2, &w3); ulx = _SHIFTR(w1, 12, 12); uly = _SHIFTR(w1, 0, 12); lrx = _SHIFTR(w0, 12, 12); lry = _SHIFTR(w0, 0, 12); if ((lrx >> 2) < (ulx >> 2) || (lry >> 2) < (uly >> 2)) return; gDPTextureRectangle( _FIXED2FLOAT(ulx, 2), _FIXED2FLOAT(uly, 2), _FIXED2FLOAT(lrx, 2), _FIXED2FLOAT(lry, 2), _SHIFTR(w1, 24, 3), // tile _FIXED2FLOAT((s16)_SHIFTR(w2, 16, 16), 5), // s _FIXED2FLOAT((s16)_SHIFTR(w2, 0, 16), 5), // t _FIXED2FLOAT((s16)_SHIFTR(w3, 16, 16), 10), // dsdx _FIXED2FLOAT((s16)_SHIFTR(w3, 0, 16), 10)); // dsdy } //Low Level RDP Drawing Commands: void RDP_TriFill(u32 _w0, u32 _w1) { gDPTriFill(_w0, _w1); } void RDP_TriTxtr(u32 _w0, u32 _w1) { gDPTriTxtr(_w0, _w1); } void RDP_TriTxtrZBuff(u32 w0, u32 w1) { LOG(LOG_VERBOSE, "RSP_TRI_TXTR_ZBUFF Command\n"); } void RDP_TriShade(u32 _w0, u32 _w1) { gDPTriShadeZ(_w0, _w1); } void RDP_TriShadeZBuff(u32 w0, u32 w1) { LOG(LOG_VERBOSE, "RSP_TRI_SHADE_ZBUFF Command\n"); } void RDP_TriShadeTxtr(u32 _w0, u32 _w1) { gDPTriShadeTxtr(_w0, _w1); } void RDP_TriFillZ( u32 _w0, u32 _w1 ) { gDPTriFillZ(_w0, _w1); } void RDP_TriShadeTxtrZBuff(u32 _w0, u32 _w1) { gDPTriShadeTxtrZ(_w0, _w1); } void RDP_TriShadeZ( u32 _w0, u32 _w1 ) { gDPTriShadeZ(_w0, _w1); } void RDP_TriTxtrZ( u32 _w0, u32 _w1 ) { gDPTriTxtrZ(_w0, _w1); } void RDP_TriShadeTxtrZ( u32 _w0, u32 _w1 ) { gDPTriShadeTxtrZ(_w0, _w1); } void RDP_Init(void) { int i; // Initialize RDP commands to RDP_UNKNOWN for (i = 0xC8; i <= 0xCF; i++) GBI.cmd[i] = RDP_Unknown; // Initialize RDP commands to RDP_UNKNOWN for (i = 0xE4; i <= 0xFF; i++) GBI.cmd[i] = RDP_Unknown; // Set known GBI commands GBI.cmd[G_NOOP] = RDP_NoOp; GBI.cmd[G_SETCIMG] = RDP_SetCImg; GBI.cmd[G_SETZIMG] = RDP_SetZImg; GBI.cmd[G_SETTIMG] = RDP_SetTImg; GBI.cmd[G_SETCOMBINE] = RDP_SetCombine; GBI.cmd[G_SETENVCOLOR] = RDP_SetEnvColor; GBI.cmd[G_SETPRIMCOLOR] = RDP_SetPrimColor; GBI.cmd[G_SETBLENDCOLOR] = RDP_SetBlendColor; GBI.cmd[G_SETFOGCOLOR] = RDP_SetFogColor; GBI.cmd[G_SETFILLCOLOR] = RDP_SetFillColor; GBI.cmd[G_FILLRECT] = RDP_FillRect; GBI.cmd[G_SETTILE] = RDP_SetTile; GBI.cmd[G_LOADTILE] = RDP_LoadTile; GBI.cmd[G_LOADBLOCK] = RDP_LoadBlock; GBI.cmd[G_SETTILESIZE] = RDP_SetTileSize; GBI.cmd[G_LOADTLUT] = RDP_LoadTLUT; GBI.cmd[G_RDPSETOTHERMODE] = RDP_SetOtherMode; GBI.cmd[G_SETPRIMDEPTH] = RDP_SetPrimDepth; GBI.cmd[G_SETSCISSOR] = RDP_SetScissor; GBI.cmd[G_SETCONVERT] = RDP_SetConvert; GBI.cmd[G_SETKEYR] = RDP_SetKeyR; GBI.cmd[G_SETKEYGB] = RDP_SetKeyGB; GBI.cmd[G_RDPFULLSYNC] = RDP_FullSync; GBI.cmd[G_RDPTILESYNC] = RDP_TileSync; GBI.cmd[G_RDPPIPESYNC] = RDP_PipeSync; GBI.cmd[G_RDPLOADSYNC] = RDP_LoadSync; GBI.cmd[G_TEXRECTFLIP] = RDP_TexRectFlip; GBI.cmd[G_TEXRECT] = RDP_TexRect; __RDP.w2 = __RDP.w3 = 0; __RDP.cmd_ptr = __RDP.cmd_cur = 0; } static GBIFunc LLEcmd[64] = { /* 0x00 */ RDP_NoOp, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_TriFill, RDP_TriFillZ, RDP_TriTxtr, RDP_TriTxtrZ, RDP_TriShade, RDP_TriShadeZ, RDP_TriShadeTxtr, RDP_TriShadeTxtrZ, /* 0x10 */ RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, /* 0x20 */ RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_TexRect, RDP_TexRectFlip, RDP_LoadSync, RDP_PipeSync, RDP_TileSync, RDP_FullSync, RDP_SetKeyGB, RDP_SetKeyR, RDP_SetConvert, RDP_SetScissor, RDP_SetPrimDepth, RDP_SetOtherMode, /* 0x30 */ RDP_LoadTLUT, RDP_Unknown, RDP_SetTileSize, RDP_LoadBlock, RDP_LoadTile, RDP_SetTile, RDP_FillRect, RDP_SetFillColor, RDP_SetFogColor, RDP_SetBlendColor, RDP_SetPrimColor, RDP_SetEnvColor, RDP_SetCombine, RDP_SetTImg, RDP_SetZImg, RDP_SetCImg }; static const u32 CmdLength[64] = { 8, // 0x00, No Op 8, // 0x01, ??? 8, // 0x02, ??? 8, // 0x03, ??? 8, // 0x04, ??? 8, // 0x05, ??? 8, // 0x06, ??? 8, // 0x07, ??? 32, // 0x08, Non-Shaded Triangle 32+16, // 0x09, Non-Shaded, Z-Buffered Triangle 32+64, // 0x0a, Textured Triangle 32+64+16, // 0x0b, Textured, Z-Buffered Triangle 32+64, // 0x0c, Shaded Triangle 32+64+16, // 0x0d, Shaded, Z-Buffered Triangle 32+64+64, // 0x0e, Shaded+Textured Triangle 32+64+64+16,// 0x0f, Shaded+Textured, Z-Buffered Triangle 8, // 0x10, ??? 8, // 0x11, ??? 8, // 0x12, ??? 8, // 0x13, ??? 8, // 0x14, ??? 8, // 0x15, ??? 8, // 0x16, ??? 8, // 0x17, ??? 8, // 0x18, ??? 8, // 0x19, ??? 8, // 0x1a, ??? 8, // 0x1b, ??? 8, // 0x1c, ??? 8, // 0x1d, ??? 8, // 0x1e, ??? 8, // 0x1f, ??? 8, // 0x20, ??? 8, // 0x21, ??? 8, // 0x22, ??? 8, // 0x23, ??? 16, // 0x24, Texture_Rectangle 16, // 0x25, Texture_Rectangle_Flip 8, // 0x26, Sync_Load 8, // 0x27, Sync_Pipe 8, // 0x28, Sync_Tile 8, // 0x29, Sync_Full 8, // 0x2a, Set_Key_GB 8, // 0x2b, Set_Key_R 8, // 0x2c, Set_Convert 8, // 0x2d, Set_Scissor 8, // 0x2e, Set_Prim_Depth 8, // 0x2f, Set_Other_Modes 8, // 0x30, Load_TLUT 8, // 0x31, ??? 8, // 0x32, Set_Tile_Size 8, // 0x33, Load_Block 8, // 0x34, Load_Tile 8, // 0x35, Set_Tile 8, // 0x36, Fill_Rectangle 8, // 0x37, Set_Fill_Color 8, // 0x38, Set_Fog_Color 8, // 0x39, Set_Blend_Color 8, // 0x3a, Set_Prim_Color 8, // 0x3b, Set_Env_Color 8, // 0x3c, Set_Combine 8, // 0x3d, Set_Texture_Image 8, // 0x3e, Set_Mask_Image 8 // 0x3f, Set_Color_Image }; void RDP_Half_1( u32 _c ) { u32 w0 = 0, w1 = _c; u32 cmd = _SHIFTR( _c, 24, 8 ); if (cmd >= 0xc8 && cmd <=0xcf) { /* triangle command */ #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPHalf_1 LLE Triangle\n"); #endif __RDP.cmd_ptr = 0; __RDP.cmd_cur = 0; do { __RDP.cmd_data[__RDP.cmd_ptr++] = w1; RSP_CheckDLCounter(); w0 = *(u32*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi]]; w1 = *(u32*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi] + 4]; __RSP.cmd = _SHIFTR( w0, 24, 8 ); #ifdef DEBUG DebugRSPState( __RSP.PCi, __RSP.PC[__RSP.PCi], _SHIFTR( w0, 24, 8 ), w0, w1 ); DebugMsg( DEBUG_LOW | DEBUG_HANDLED, "0x%08lX: CMD=0x%02lX W0=0x%08lX W1=0x%08lX\n", RSP.PC[RSP.PCi], _SHIFTR( w0, 24, 8 ), w0, w1 ); #endif __RSP.PC[__RSP.PCi] += 8; // RSP.nextCmd = _SHIFTR( *(u32*)&gfx_info.RDRAM[RSP.PC[RSP.PCi]], 24, 8 ); } while (__RSP.cmd != 0xb3); __RDP.cmd_data[__RDP.cmd_ptr++] = w1; __RSP.cmd = (__RDP.cmd_data[__RDP.cmd_cur] >> 24) & 0x3f; w0 = __RDP.cmd_data[__RDP.cmd_cur+0]; w1 = __RDP.cmd_data[__RDP.cmd_cur+1]; LLEcmd[__RSP.cmd](w0, w1); } #ifdef DEBUG else { DebugMsg( DEBUG_HIGH | DEBUG_IGNORED, "gDPHalf_1()\n" ); } #endif } static INLINE u32 GLN64_READ_RDP_DATA(u32 address) { if ((*(u32*)gfx_info.DPC_STATUS_REG) & 0x1) // XBUS_DMEM_DMA enabled return gfx_info.DMEM[(address & 0xfff)>>2]; return gfx_info.RDRAM[address>>2]; } EXPORT void CALL gln64ProcessRDPList(void) { u32 i; bool setZero = true; const u32 length = gfx_info.DPC_END_REG - gfx_info.DPC_CURRENT_REG; #ifdef DEBUG DebugMsg(DEBUG_HIGH | DEBUG_HANDLED, "ProcessRDPList()\n"); #endif (*(u32*)gfx_info.DPC_STATUS_REG) &= ~0x0002; if (gfx_info.DPC_END_REG <= gfx_info.DPC_CURRENT_REG) return; __RSP.bLLE = true; /* load command data */ for (i = 0; i < length; i += 4) { __RDP.cmd_data[__RDP.cmd_ptr] = GLN64_READ_RDP_DATA(*gfx_info.DPC_CURRENT_REG + i); __RDP.cmd_ptr = (__RDP.cmd_ptr + 1) & maxCMDMask; } while (__RDP.cmd_cur != __RDP.cmd_ptr) { u32 w0, w1; u32 cmd = (__RDP.cmd_data[__RDP.cmd_cur] >> 24) & 0x3f; if ((((__RDP.cmd_ptr - __RDP.cmd_cur)&maxCMDMask) * 4) < CmdLength[cmd]) { setZero = false; break; } if (__RDP.cmd_cur + CmdLength[cmd] / 4 > MAXCMD) memcpy(__RDP.cmd_data + MAXCMD, __RDP.cmd_data, CmdLength[cmd] - (MAXCMD - __RDP.cmd_cur) * 4); // execute the command w0 = __RDP.cmd_data[__RDP.cmd_cur+0]; w1 = __RDP.cmd_data[__RDP.cmd_cur+1]; __RDP.w2 = __RDP.cmd_data[__RDP.cmd_cur+2]; __RDP.w3 = __RDP.cmd_data[__RDP.cmd_cur + 3]; __RSP.cmd = cmd; LLEcmd[cmd](w0, w1); __RDP.cmd_cur = (__RDP.cmd_cur + CmdLength[cmd] / 4) & maxCMDMask; } if (setZero) { __RDP.cmd_ptr = 0; __RDP.cmd_cur = 0; } __RSP.bLLE = false; gSP.changed |= CHANGED_COLORBUFFER; gfx_info.DPC_START_REG = gfx_info.DPC_CURRENT_REG = gfx_info.DPC_END_REG; } mupen64plus-core/src/r4300/hacktarux_dynarec/gcop0.c000664 001750 001750 00000003667 12655644434 023275 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - gcop0.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2007 Richard Goedeken (Richard42) * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include "assemble.h" #include "r4300/cached_interp.h" #include "r4300/recomp.h" #include "r4300/recomph.h" #include "r4300/r4300.h" #include "r4300/ops.h" void genmfc0(void) { gencallinterp((native_type)cached_interpreter_table.MFC0, 0); } void genmtc0(void) { gencallinterp((native_type)cached_interpreter_table.MTC0, 0); } mupen64plus-core/src/r4300/cp0.h000664 001750 001750 00000004356 12655644434 017251 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - cp0.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_R4300_CP0_H #define M64P_R4300_CP0_H #include enum r4300_cp0_registers { CP0_INDEX_REG, CP0_RANDOM_REG, CP0_ENTRYLO0_REG, CP0_ENTRYLO1_REG, CP0_CONTEXT_REG, CP0_PAGEMASK_REG, CP0_WIRED_REG, /* 7 is unused */ CP0_BADVADDR_REG = 8, CP0_COUNT_REG, CP0_ENTRYHI_REG, CP0_COMPARE_REG, CP0_STATUS_REG, CP0_CAUSE_REG, CP0_EPC_REG, CP0_PREVID_REG, CP0_CONFIG_REG, CP0_LLADDR_REG, CP0_WATCHLO_REG, CP0_WATCHHI_REG, CP0_XCONTEXT_REG, /* 21 - 27 are unused */ CP0_TAGLO_REG = 28, CP0_TAGHI_REG, CP0_ERROREPC_REG, /* 31 is unused */ CP0_REGS_COUNT = 32 }; uint32_t *r4300_cp0_regs(void); void cp0_update_count(void); #endif /* M64P_R4300_CP0_H */ mupen64plus-video-gliden64/src/RDP.h000664 001750 001750 00000000566 12655644434 020233 0ustar00sergiosergio000000 000000 #ifndef RDP_H #define RDP_H #define MAXCMD 0x100000 const unsigned int maxCMDMask = MAXCMD - 1; typedef struct { u32 w2, w3; u32 cmd_ptr; u32 cmd_cur; u32 cmd_data[MAXCMD + 32]; } RDPInfo; extern RDPInfo __RDP; void RDP_Init(void); void RDP_Half_1(u32 _c); void RDP_ProcessRDPList(void); void RDP_RepeatLastLoadBlock(); void RDP_SetScissor(u32 w0, u32 w1); #endif mupen64plus-core/src/r4300/cp0.c000664 001750 001750 00000005245 12655644434 017242 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - cp0.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include "r4300.h" #include "cp0_private.h" #include "exception.h" #include "new_dynarec/new_dynarec.h" #ifdef COMPARE_CORE #include "api/debugger.h" #endif #ifdef DBG #include "debugger/dbg_types.h" #include "debugger/debugger.h" #endif /* global variable */ #if NEW_DYNAREC != NEW_DYNAREC_ARM /* ARM backend requires a different memory layout * and therefore manually allocate that variable */ uint32_t g_cp0_regs[32]; #endif uint32_t* r4300_cp0_regs(void) { return g_cp0_regs; } /* global functions */ int check_cop1_unusable(void) { if (!(g_cp0_regs[CP0_STATUS_REG] & UINT32_C(0x20000000))) { g_cp0_regs[CP0_CAUSE_REG] = (UINT32_C(11) << 2) | UINT32_C(0x10000000); exception_general(); return 1; } return 0; } void cp0_update_count(void) { #ifdef NEW_DYNAREC if (r4300emu != CORE_DYNAREC) { #endif g_cp0_regs[CP0_COUNT_REG] += ((PC->addr - last_addr) >> 2) * count_per_op; last_addr = PC->addr; #ifdef NEW_DYNAREC } #endif #ifdef COMPARE_CORE if (delay_slot) CoreCompareCallback(); #endif /*#ifdef DBG if (g_DebuggerActive && !delay_slot) update_debugger(PC->addr); #endif */ } mupen64plus-rsp-cxd4/vu/add.h000664 001750 001750 00000020710 12655644434 017116 0ustar00sergiosergio000000 000000 /******************************************************************************\ * Authors: Iconoclast * * Release: 2013.11.26 * * License: CC0 Public Domain Dedication * * * * To the extent possible under law, the author(s) have dedicated all copyright * * and related and neighboring rights to this software to the public domain * * worldwide. This software is distributed without any warranty. * * * * You should have received a copy of the CC0 Public Domain Dedication along * * with this software. * * If not, see . * \******************************************************************************/ #ifdef ARCH_MIN_SSE2 static INLINE void SIGNED_CLAMP_ADD(short* VD, short* VS, short* VT) { __m128i src = _mm_load_si128((__m128i *)VS); __m128i dst = _mm_load_si128((__m128i *)VT); __m128i vco = _mm_load_si128((__m128i *)co); /* * Due to premature clamping in between adds, sometimes we need to add the * LESSER of two integers, either VS or VT, to the carry-in flag matching the * current vector register slice, BEFORE finally adding the greater integer. */ __m128i max = _mm_max_epi16(dst, src); __m128i min = _mm_min_epi16(dst, src); min = _mm_adds_epi16(min, vco); max = _mm_adds_epi16(max, min); _mm_store_si128((__m128i *)VD, max); } static INLINE void SIGNED_CLAMP_SUB(short* VD, short* VS, short* VT) { __m128i xmm; __m128i src = _mm_load_si128((__m128i *)VS); __m128i dst = _mm_load_si128((__m128i *)VT); __m128i vco = _mm_load_si128((__m128i *)co); __m128i res = _mm_subs_epi16(src, dst); /* * Due to premature clamps in-between subtracting two of the three operands, * we must be careful not to offset the result accidentally when subtracting * the corresponding VCO flag AFTER the saturation from doing (VS - VT). */ __m128i dif = _mm_add_epi16(res, vco); dif = _mm_xor_si128(dif, res); /* Adding one suddenly inverts the sign? */ dif = _mm_and_si128(dif, dst); /* Sign change due to subtracting a neg. */ xmm = _mm_sub_epi16(src, dst); src = _mm_andnot_si128(src, dif); /* VS must be >= 0x0000 for overflow. */ xmm = _mm_and_si128(xmm, src); /* VS + VT != INT16_MIN; VS + VT >= +32768 */ xmm = _mm_srli_epi16(xmm, 15); /* src = (INT16_MAX + 1 === INT16_MIN) ? */ xmm = _mm_andnot_si128(xmm, vco); /* If it's NOT overflow, keep flag. */ res = _mm_subs_epi16(res, xmm); _mm_store_si128((__m128i *)VD, res); } #else static INLINE void SIGNED_CLAMP_ADD(short* VD, short* VS, short* VT) { int32_t sum[N]; short hi[N], lo[N]; register int i; for (i = 0; i < N; i++) sum[i] = VS[i] + VT[i] + co[i]; for (i = 0; i < N; i++) lo[i] = (sum[i] + 0x8000) >> 31; for (i = 0; i < N; i++) hi[i] = (0x7FFF - sum[i]) >> 31; vector_copy(VD, VACC_L); for (i = 0; i < N; i++) VD[i] &= ~lo[i]; for (i = 0; i < N; i++) VD[i] |= hi[i]; for (i = 0; i < N; i++) VD[i] ^= 0x8000 & (hi[i] | lo[i]); } static INLINE void SIGNED_CLAMP_SUB(short* VD, short* VS, short* VT) { int32_t dif[N]; short hi[N], lo[N]; register int i; for (i = 0; i < N; i++) dif[i] = VS[i] - VT[i] - co[i]; for (i = 0; i < N; i++) lo[i] = (dif[i] + 0x8000) >> 31; for (i = 0; i < N; i++) hi[i] = (0x7FFF - dif[i]) >> 31; vector_copy(VD, VACC_L); for (i = 0; i < N; i++) VD[i] &= ~lo[i]; for (i = 0; i < N; i++) VD[i] |= hi[i]; for (i = 0; i < N; i++) VD[i] ^= 0x8000 & (hi[i] | lo[i]); } #endif static INLINE void set_bo(short* VD, short* VS, short* VT) { /* set CARRY and borrow out from difference */ int32_t dif[N]; register int i; for (i = 0; i < N; i++) dif[i] = (unsigned short)(VS[i]) - (unsigned short)(VT[i]); for (i = 0; i < N; i++) VACC_L[i] = VS[i] - VT[i]; vector_copy(VD, VACC_L); for (i = 0; i < N; i++) ne[i] = (VS[i] != VT[i]); for (i = 0; i < N; i++) co[i] = (dif[i] < 0); } static INLINE void set_co(short* VD, short* VS, short* VT) { /* set CARRY and carry out from sum */ int32_t sum[N]; register int i; for (i = 0; i < N; i++) sum[i] = (unsigned short)(VS[i]) + (unsigned short)(VT[i]); for (i = 0; i < N; i++) VACC_L[i] = VS[i] + VT[i]; vector_copy(VD, VACC_L); for (i = 0; i < N; i++) ne[i] = 0; for (i = 0; i < N; i++) co[i] = sum[i] >> 16; /* native: (sum[i] > +65535) */ } /* * -1: VT *= -1, because VS < 0 // VT ^= -2 if even, or ^= -1, += 1 * 0: VT *= 0, because VS = 0 // VT ^= VT * +1: VT *= +1, because VS > 0 // VT ^= 0 * VT ^= -1, "negate" -32768 as ~+32767 (corner case hack for N64 SP) */ INLINE static void do_abs(short* VD, short* VS, short* VT) { short neg[N], pos[N]; short nez[N], cch[N]; /* corner case hack -- abs(-32768) == +32767 */ short res[N]; register int i; vector_copy(res, VT); for (i = 0; i < N; i++) neg[i] = (VS[i] < 0x0000); for (i = 0; i < N; i++) pos[i] = (VS[i] > 0x0000); for (i = 0; i < N; i++) nez[i] = 0; for (i = 0; i < N; i++) nez[i] -= neg[i]; for (i = 0; i < N; i++) nez[i] += pos[i]; for (i = 0; i < N; i++) res[i] *= nez[i]; for (i = 0; i < N; i++) cch[i] = (res[i] == -32768); for (i = 0; i < N; i++) res[i] -= cch[i]; vector_copy(VACC_L, res); vector_copy(VD, VACC_L); } static INLINE void clr_bi(short* VD, short* VS, short* VT) { /* clear CARRY and borrow in to accumulators */ register int i; for (i = 0; i < N; i++) VACC_L[i] = VS[i] - VT[i] - co[i]; SIGNED_CLAMP_SUB(VD, VS, VT); for (i = 0; i < N; i++) ne[i] = 0; for (i = 0; i < N; i++) co[i] = 0; } static INLINE void clr_ci(short* VD, short* VS, short* VT) { /* clear CARRY and carry in to accumulators */ register int i; for (i = 0; i < N; i++) VACC_L[i] = VS[i] + VT[i] + co[i]; SIGNED_CLAMP_ADD(VD, VS, VT); for (i = 0; i < N; i++) ne[i] = 0; for (i = 0; i < N; i++) co[i] = 0; } static INLINE void VADD(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); clr_ci(VR[vd], VR[vs], ST); } static INLINE void VSUB(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); clr_bi(VR[vd], VR[vs], ST); } static void VABS(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_abs(VR[vd], VR[vs], ST); } static void VADDC(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); set_co(VR[vd], VR[vs], ST); } static void VSUBC(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); set_bo(VR[vd], VR[vs], ST); } #ifdef VU_EMULATE_SCALAR_ACCUMULATOR_READ static void VSAR(int vd, int vs, int vt, int e) { short oldval[N]; register int i; for (i = 0; i < N; i++) oldval[i] = VR[vs][i]; vt = 0; /* Even though VT is ignored in VSAR, according to official sources as well * as reversing, lots of games seem to specify it as non-zero, possibly to * avoid register stalling or other VU hazards. Not really certain why yet. */ e ^= 0x8; /* Or, for exception overrides, should this be `e &= 0x7;` ? * Currently this code is safer because &= is less likely to catch oddities. * Either way, documentation shows that the switch range is 0:2, not 8:A. */ if (e > 2) /* VSAR, invalid mask */ { for (i = 0; i < N; i++) VR[vd][i] = 0x0000; /* override behavior (zilmar) */ } else for (i = 0; i < N; i++) VR[vd][i] = VACC[e][i]; for (i = 0; i < N; i++) VACC[e][i] = oldval[i]; /* ... = VS */ } #endif static void VSAW(int vd, int vs, int vt, int e) { vs = 0; /* unused--old VSAR algorithm */ vt = 0; /* unused but mysteriously set many times */ if (vs | vt) return; e ^= 0x8; /* &= 7 */ if (e > 0x2) { /* VSAW, illegal mask */ /* branch very unlikely...never seen a game do VSAW illegally */ register int i; for (i = 0; i < N; i++) VR[vd][i] = 0x0000; /* override behavior (zilmar) */ return; } vector_copy(VR[vd], VACC[e]); } gles2rice/src/OGLRenderExt.cpp000664 001750 001750 00000011154 12655644434 017335 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "osal_opengl.h" #include "OGLRender.h" extern Matrix g_MtxReal; extern uObjMtxReal gObjMtxReal; //======================================================================== void OGLRender::DrawText(const char* str, M64P_RECT *rect) { } void OGLRender::DrawSpriteR_Render() // With Rotation { glViewportWrapper(0, 0, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight, true); GLboolean cullface = glIsEnabled(GL_CULL_FACE); glDisable(GL_CULL_FACE); GLfloat colour[] = { gRDP.fvPrimitiveColor[0], gRDP.fvPrimitiveColor[1], gRDP.fvPrimitiveColor[2], gRDP.fvPrimitiveColor[3], gRDP.fvPrimitiveColor[0], gRDP.fvPrimitiveColor[1], gRDP.fvPrimitiveColor[2], gRDP.fvPrimitiveColor[3], gRDP.fvPrimitiveColor[0], gRDP.fvPrimitiveColor[1], gRDP.fvPrimitiveColor[2], gRDP.fvPrimitiveColor[3], gRDP.fvPrimitiveColor[0], gRDP.fvPrimitiveColor[1], gRDP.fvPrimitiveColor[2], gRDP.fvPrimitiveColor[3], gRDP.fvPrimitiveColor[0], gRDP.fvPrimitiveColor[1], gRDP.fvPrimitiveColor[2], gRDP.fvPrimitiveColor[3], gRDP.fvPrimitiveColor[0], gRDP.fvPrimitiveColor[1], gRDP.fvPrimitiveColor[2], gRDP.fvPrimitiveColor[3], }; GLfloat tex[] = { g_texRectTVtx[0].tcord[0].u,g_texRectTVtx[0].tcord[0].v, g_texRectTVtx[1].tcord[0].u,g_texRectTVtx[1].tcord[0].v, g_texRectTVtx[2].tcord[0].u,g_texRectTVtx[2].tcord[0].v, g_texRectTVtx[0].tcord[0].u,g_texRectTVtx[0].tcord[0].v, g_texRectTVtx[2].tcord[0].u,g_texRectTVtx[2].tcord[0].v, g_texRectTVtx[3].tcord[0].u,g_texRectTVtx[3].tcord[0].v, }; GLfloat tex2[] = { g_texRectTVtx[0].tcord[1].u,g_texRectTVtx[0].tcord[1].v, g_texRectTVtx[1].tcord[1].u,g_texRectTVtx[1].tcord[1].v, g_texRectTVtx[2].tcord[1].u,g_texRectTVtx[2].tcord[1].v, g_texRectTVtx[0].tcord[1].u,g_texRectTVtx[0].tcord[1].v, g_texRectTVtx[2].tcord[1].u,g_texRectTVtx[2].tcord[1].v, g_texRectTVtx[3].tcord[1].u,g_texRectTVtx[3].tcord[1].v, }; float w = windowSetting.uDisplayWidth / 2.0f, h = windowSetting.uDisplayHeight / 2.0f, inv = 1.0f; GLfloat vertices[] = { -inv + g_texRectTVtx[0].x/ w, inv - g_texRectTVtx[0].y/ h, -g_texRectTVtx[0].z,1, -inv + g_texRectTVtx[1].x/ w, inv - g_texRectTVtx[1].y/ h, -g_texRectTVtx[1].z,1, -inv + g_texRectTVtx[2].x/ w, inv - g_texRectTVtx[2].y/ h, -g_texRectTVtx[2].z,1, -inv + g_texRectTVtx[0].x/ w, inv - g_texRectTVtx[0].y/ h, -g_texRectTVtx[0].z,1, -inv + g_texRectTVtx[2].x/ w, inv - g_texRectTVtx[2].y/ h, -g_texRectTVtx[2].z,1, -inv + g_texRectTVtx[3].x/ w, inv - g_texRectTVtx[3].y/ h, -g_texRectTVtx[3].z,1 }; glVertexAttribPointer(VS_COLOR, 4, GL_FLOAT,GL_FALSE, 0, &colour ); glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,0,&vertices); glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, 0, &tex); glVertexAttribPointer(VS_TEXCOORD1,2,GL_FLOAT,GL_FALSE, 0, &tex2); //OPENGL_CHECK_ERRORS; glDrawArrays(GL_TRIANGLES,0,6); //OPENGL_CHECK_ERRORS; //Restore old pointers glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8_t)*4, &(g_oglVtxColors[0][0]) ); glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0])); glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u)); glVertexAttribPointer(VS_TEXCOORD1,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[1].u)); if( cullface ) glEnable(GL_CULL_FACE); } void OGLRender::DrawObjBGCopy(uObjBg &info) { if( IsUsedAsDI(g_CI.dwAddr) ) { DebugMessage(M64MSG_WARNING, "Unimplemented: write into Z buffer. Was mostly commented out in Rice Video 6.1.0"); return; } else { CRender::LoadObjBGCopy(info); CRender::DrawObjBGCopy(info); } } mupen64plus-core/doc/emuwiki-api-doc/Mupen64Plus_Core_Parameters.txt000664 001750 001750 00000014560 12655644434 026604 0ustar00sergiosergio000000 000000 [[Mupen64Plus v2.0 Core API v1.0|Mupen64Plus v2.0 API]] = Core Parameters = These are standard parameters which are used by the Mupen64Plus Core library. They are stored in a configuration section called "Core" and may be altered by the front-end in order to adjust the behaviour of the emulator. These may be adjusted at any time and the effect of the change should occur immediately. {| border="1" !Parameter Name!!Type!!Usage |- |Version |M64TYPE_FLOAT |Mupen64Plus Core config parameter set version number. Please don't change. |- |OnScreenDisplay |M64TYPE_BOOL |Draw on-screen display if True, otherwise don't draw OSD |- |R4300Emulator |M64TYPE_INT |Use Pure Interpreter if 0, Cached Interpreter if 1, or Dynamic Recompiler if 2 or more |- |NoCompiledJump |M64TYPE_BOOL |Disable compiled jump commands in dynamic recompiler (should be set to False) |- |DisableExtraMem |M64TYPE_BOOL |Disable 4MB expansion RAM pack. May be necessary for some games. |- |AutoStateSlotIncrement |M64TYPE_BOOL |Increment the save state slot after each save operation. |- |EnableDebugger |M64TYPE_BOOL |Activate the R4300 debugger when ROM execution begins, if core was built with Debugger support. |- |CurrentStateSlot |M64TYPE_INT |Save state slot (0-9) to use when saving/loading the emulator state |- |ScreenshotPath |M64TYPE_STRING |Path to directory where screenshots are saved. If this is blank, the default value of "GetConfigUserDataPath()"/screenshot will be used. |- |SaveStatePath |M64TYPE_STRING |Path to directory where emulator save states (snapshots) are saved. If this is blank, the default value of "GetConfigUserDataPath()"/save will be used. |- |SaveSRAMPath |M64TYPE_STRING |Path to directory where SRAM/EEPROM data (in-game saves) are stored. If this is blank, the default value of "GetConfigUserDataPath()"/save will be used. |- |SharedDataPath |M64TYPE_STRING |Path to a directory to search when looking for shared data files in the ConfigGetSharedDataFilepath() function. |- |CountPerOp |M64TYPE_INT |Force number of cycles per emulated instruction when set greater than 0. |- |DelaySI |M64TYPE_BOOL |Delay interrupt after DMA SI read/write. |- |} These configuration parameters are used in the Core's event loop to detect keyboard and joystick commands. They are stored in a configuration section called "CoreEvents" and may be altered by the front-end in order to adjust the behaviour of the emulator. These may be adjusted at any time and the effect of the change should occur immediately. The Keysym value stored is actually (SDLMod << 16) || SDLKey, so that keypresses with modifiers like shift, control, or alt may be used. {| border="1" !Parameter Name!!Type!!Usage |- |Kbd Mapping Stop |M64TYPE_INT |SDL keysym for stopping the emulator |- |Kbd Mapping Fullscreen |M64TYPE_INT |SDL keysym for switching between fullscreen/windowed modes |- |Kbd Mapping Save State |M64TYPE_INT |SDL keysym for saving the emulator state |- |Kbd Mapping Load State |M64TYPE_INT |SDL keysym for loading the emulator state |- |Kbd Mapping Increment Slot |M64TYPE_INT |SDL keysym for advancing the save state slot |- |Kbd Mapping Reset |M64TYPE_INT |SDL keysym for resetting the emulator |- |Kbd Mapping Speed Down |M64TYPE_INT |SDL keysym for slowing down the emulator |- |Kbd Mapping Speed Up |M64TYPE_INT |SDL keysym for speeding up the emulator |- |Kbd Mapping Screenshot |M64TYPE_INT |SDL keysym for taking a screenshot |- |Kbd Mapping Pause |M64TYPE_INT |SDL keysym for pausing the emulator |- |Kbd Mapping Mute |M64TYPE_INT |SDL keysym for muting/unmuting the sound |- |Kbd Mapping Increase Volume |M64TYPE_INT |SDL keysym for increasing the volume |- |Kbd Mapping Decrease Volume |M64TYPE_INT |SDL keysym for decreasing the volume |- |Kbd Mapping Fast Forward |M64TYPE_INT |SDL keysym for temporarily going really fast |- |Kbd Mapping Frame Advance |M64TYPE_INT |SDL keysym for advancing by one frame when paused |- |Kbd Mapping Gameshark |M64TYPE_INT |SDL keysym for pressing the game shark button |- |} These configuration parameters are used in the Core's event loop to detect joystick commands. The command strings use a simple format described here. For commands activated by pressing a joystick axis, the format is "J'''x'''A'''y'''+" or "J'''x'''A'''y'''-", where '''x''' is the SDL joystick number (must be between 0 and 9) and '''y''' is the axis number. For the last character, '''+''' represents movement in the positive direction, while '''-''' represents movement in the negative direction. For commands activated by pressing a button, the format is "J'''x'''B'''y'''", where '''x''' is the SDL joystick number (must be between 0 and 9) and '''y''' is the button number. For commands activated by pressing a ''hat'' (a directional switch) on the joystick, the format is "J'''x'''H'''y'''V'''z'''", where '''x''' is the SDL joystick number (must be between 0 and 9), '''y''' is the hat number, and '''z''' is the hat value. The hat value corresponds with the SDL_HAT_ enumerated types: Up is 1, Right is 2, Down is 4, and Left is 8. For diagonal directions, these values may be ''or''d together. {| border="1" !Parameter Name!!Type!!Usage |- |Version |M64TYPE_FLOAT |Mupen64Plus CoreEvents config parameter set version number. Please don't change. |- |Joy Mapping Stop |M64TYPE_STRING |Joystick event string for stopping the emulator |- |Joy Mapping Fullscreen |M64TYPE_STRING |Joystick event string for switching between fullscreen/windowed modes |- |Joy Mapping Save State |M64TYPE_STRING |Joystick event string for saving the emulator state |- |Joy Mapping Load State |M64TYPE_STRING |Joystick event string for loading the emulator state |- |Joy Mapping Increment Slot |M64TYPE_STRING |Joystick event string for advancing the save state slot |- |Joy Mapping Screenshot |M64TYPE_STRING |Joystick event string for taking a screenshot |- |Joy Mapping Pause |M64TYPE_STRING |Joystick event string for pausing or resuming the emulator |- |Joy Mapping Mute |M64TYPE_STRING |Joystick event string for muting/unmuting the sound |- |Joy Mapping Increase Volume |M64TYPE_STRING |Joystick event string for increasing the volume |- |Joy Mapping Decrease Volume |M64TYPE_STRING |Joystick event string for decreasing the volume |- |Joy Mapping Fast Forward |M64TYPE_STRING |Joystick event string for temporarily going really fast |- |Joy Mapping Gameshark |M64TYPE_STRING |Joystick event string for pressing the game shark button |- |} mupen64plus-core/src/debugger/dbg_breakpoints.h000664 001750 001750 00000004374 12655644434 022740 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - dbg_breakpoints.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2008 DarkJeztr HyperHacker * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef __BREAKPOINTS_H__ #define __BREAKPOINTS_H__ #include "../api/m64p_types.h" extern int g_NumBreakpoints; extern breakpoint g_Breakpoints[]; int add_breakpoint( uint32 address ); int add_breakpoint_struct(breakpoint* newbp); void remove_breakpoint_by_address( uint32 address ); void remove_breakpoint_by_num( int bpt ); void enable_breakpoint( int breakpoint ); void disable_breakpoint( int breakpoint ); int check_breakpoints( uint32 address ); int check_breakpoints_on_mem_access( uint32 pc, uint32 address, uint32 size, uint32 flags ); int lookup_breakpoint( uint32 address, uint32 size, uint32 flags ); int log_breakpoint(uint32 PC, uint32 Flag, uint32 Access); void replace_breakpoint_num( int, breakpoint* ); #endif /* __BREAKPOINTS_H__ */ mupen64plus-video-gliden64/src/Config.cpp000664 001750 001750 00000005152 12655644434 021342 0ustar00sergiosergio000000 000000 #ifdef OS_WINDOWS # include #else # include "winlnxdefs.h" #endif // OS_WINDOWS #include "RSP.h" #include "PluginAPI.h" #include "Config.h" #include "wst.h" void Config::resetToDefaults() { version = CONFIG_VERSION_CURRENT; #if defined(PANDORA) || defined(VC) video.fullscreen = 1; video.fullscreenWidth = video.windowedWidth = 800; #else video.fullscreen = 0; video.fullscreenWidth = video.windowedWidth = 640; #endif video.fullscreenHeight = video.windowedHeight = 480; video.fullscreenRefresh = 60; video.multisampling = 0; video.verticalSync = 0; texture.maxAnisotropy = 0; texture.bilinearMode = BILINEAR_STANDARD; texture.maxBytes = 500 * gc_uMegabyte; texture.screenShotFormat = 0; generalEmulation.enableFog = 1; generalEmulation.enableLOD = 1; generalEmulation.enableNoise = 1; generalEmulation.enableHWLighting = 0; generalEmulation.enableCustomSettings = 1; generalEmulation.enableShadersStorage = 1; generalEmulation.hacks = 0; #ifdef ANDROID generalEmulation.forcePolygonOffset = 0; generalEmulation.polygonOffsetFactor = 0.0f; generalEmulation.polygonOffsetUnits = 0.0f; #endif #ifdef VC frameBufferEmulation.enable = 0; #else frameBufferEmulation.enable = 1; #endif frameBufferEmulation.copyDepthToRDRAM = ctDisable; frameBufferEmulation.copyFromRDRAM = 0; frameBufferEmulation.copyAuxToRDRAM = 0; frameBufferEmulation.copyToRDRAM = ctAsync; frameBufferEmulation.N64DepthCompare = 0; frameBufferEmulation.aspect = 1; frameBufferEmulation.bufferSwapMode = bsOnVerticalInterrupt; textureFilter.txCacheSize = 100 * gc_uMegabyte; textureFilter.txDump = 0; textureFilter.txEnhancementMode = 0; textureFilter.txFilterIgnoreBG = 0; textureFilter.txFilterMode = 0; textureFilter.txHiresEnable = 0; textureFilter.txHiresFullAlphaChannel = 0; textureFilter.txHresAltCRC = 0; textureFilter.txCacheCompression = 1; textureFilter.txForce16bpp = 0; textureFilter.txSaveCache = 1; api().GetUserDataPath(textureFilter.txPath); gln_wcscat(textureFilter.txPath, wst("/hires_texture")); #ifdef OS_WINDOWS font.name.assign("arial.ttf"); #elif defined (ANDROID) font.name.assign("DroidSans.ttf"); #elif defined (PANDORA) font.name.assign("LiberationMono-Regular.ttf"); #else font.name = "FreeSans.ttf"; #endif font.size = 18; font.color[0] = 0xB5; font.color[1] = 0xE6; font.color[2] = 0x1D; font.color[3] = 0xFF; for (int i = 0; i < 4; ++i) font.colorf[i] = font.color[i] / 255.0f; bloomFilter.enable = 0; bloomFilter.thresholdLevel = 4; bloomFilter.blendMode = 0; bloomFilter.blurAmount = 10; bloomFilter.blurStrength = 20; gammaCorrection.force = 0; gammaCorrection.level = 2.0f; } gles2rice/src/ConvertImage.cpp000664 001750 001750 00000134547 12655644434 017472 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "Config.h" #include "ConvertImage.h" #include "RenderBase.h" ConvertFunction gConvertFunctions_FullTMEM[ 8 ][ 4 ] = { // 4bpp 8bpp 16bpp 32bpp { Convert4b, Convert8b, Convert16b, ConvertRGBA32 }, // RGBA { NULL, NULL, ConvertYUV, NULL }, // YUV { Convert4b, Convert8b, NULL, NULL }, // CI { Convert4b, Convert8b, Convert16b, NULL }, // IA { Convert4b, Convert8b, Convert16b, NULL }, // I { NULL, NULL, NULL, NULL }, // ? { NULL, NULL, NULL, NULL }, // ? { NULL, NULL, NULL, NULL } // ? }; ConvertFunction gConvertFunctions[ 8 ][ 4 ] = { // 4bpp 8bpp 16bpp 32bpp { ConvertCI4, ConvertCI8, ConvertRGBA16, ConvertRGBA32 }, // RGBA { NULL, NULL, ConvertYUV, NULL }, // YUV { ConvertCI4, ConvertCI8, NULL, NULL }, // CI { ConvertIA4, ConvertIA8, ConvertIA16, NULL }, // IA { ConvertI4, ConvertI8, ConvertIA16, NULL }, // I { NULL, NULL, NULL, NULL }, // ? { NULL, NULL, NULL, NULL }, // ? { NULL, NULL, NULL, NULL } // ? }; ConvertFunction gConvertTlutFunctions[ 8 ][ 4 ] = { // 4bpp 8bpp 16bpp 32bpp { ConvertCI4, ConvertCI8, ConvertRGBA16, ConvertRGBA32 }, // RGBA { NULL, NULL, ConvertYUV, NULL }, // YUV { ConvertCI4, ConvertCI8, NULL, NULL }, // CI { ConvertCI4, ConvertCI8, ConvertIA16, NULL }, // IA { ConvertCI4, ConvertCI8, ConvertIA16, NULL }, // I { NULL, NULL, NULL, NULL }, // ? { NULL, NULL, NULL, NULL }, // ? { NULL, NULL, NULL, NULL } // ? }; extern bool conkerSwapHack; void ConvertRGBA16(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; // Copy of the base pointer uint16_t * pSrc = (uint16_t*)(tinfo.pPhysicalAddress); uint8_t * pByteSrc = (uint8_t *)pSrc; if (!pTexture->StartUpdate(&dInfo)) return; uint32_t nFiddle; if (tinfo.bSwapped) { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { if ((y&1) == 0) nFiddle = 0x2; else nFiddle = 0x2 | 0x4; // dwDst points to start of destination row uint32_t * dwDst = (uint32_t *)((uint8_t *)dInfo.lpSurface + y*dInfo.lPitch); // DWordOffset points to the current dword we're looking at // (process 2 pixels at a time). May be a problem if we don't start on even pixel uint32_t dwWordOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + (tinfo.LeftToLoad * 2); for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { uint16_t w = *(uint16_t *)&pByteSrc[dwWordOffset ^ nFiddle]; dwDst[x] = Convert555ToRGBA(w); // Increment word offset to point to the next two pixels dwWordOffset += 2; } } } else { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { // dwDst points to start of destination row uint32_t * dwDst = (uint32_t *)((uint8_t *)dInfo.lpSurface + y*dInfo.lPitch); // DWordOffset points to the current dword we're looking at // (process 2 pixels at a time). May be a problem if we don't start on even pixel uint32_t dwWordOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + (tinfo.LeftToLoad * 2); for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { uint16_t w = *(uint16_t *)&pByteSrc[dwWordOffset ^ 0x2]; dwDst[x] = Convert555ToRGBA(w); // Increment word offset to point to the next two pixels dwWordOffset += 2; } } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } void ConvertRGBA32(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; if (!pTexture->StartUpdate(&dInfo)) return; uint32_t * pSrc = (uint32_t*)(tinfo.pPhysicalAddress); if( options.bUseFullTMEM ) { Tile &tile = gRDP.tiles[tinfo.tileNo]; uint32_t *pWordSrc; if( tinfo.tileNo >= 0 ) { pWordSrc = (uint32_t*)&g_Tmem.g_Tmem64bit[tile.dwTMem]; for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint32_t * dwDst = (uint32_t *)((uint8_t *)dInfo.lpSurface + y*dInfo.lPitch); uint32_t nFiddle = ( y&1 )? 0x2 : 0; int idx = tile.dwLine*4*y; for (uint32_t x = 0; x < tinfo.WidthToLoad; x++, idx++) { uint32_t w = pWordSrc[idx^nFiddle]; uint8_t* psw = (uint8_t*)&w; uint8_t* pdw = (uint8_t*)&dwDst[x]; pdw[0] = psw[2]; // Blue pdw[1] = psw[1]; // Green pdw[2] = psw[0]; // Red pdw[3] = psw[3]; // Alpha } } } } else { if (tinfo.bSwapped) { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { if ((y%2) == 0) { uint8_t *pDst = (uint8_t *)dInfo.lpSurface + y * dInfo.lPitch; uint8_t *pS = (uint8_t *)pSrc + (y+tinfo.TopToLoad) * tinfo.Pitch + (tinfo.LeftToLoad*4); for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { pDst[0] = pS[1]; // Blue pDst[1] = pS[2]; // Green pDst[2] = pS[3]; // Red pDst[3] = pS[0]; // Alpha pS+=4; pDst+=4; } } else { uint32_t *pDst = (uint32_t *)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); uint8_t *pS = (uint8_t *)pSrc; int n; n = (y+tinfo.TopToLoad) * tinfo.Pitch + (tinfo.LeftToLoad*4); for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { *pDst++ = COLOR_RGBA(pS[(n+3)^0x8], pS[(n+2)^0x8], pS[(n+1)^0x8], pS[(n+0)^0x8]); n += 4; } } } } else { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint8_t *pDst = (uint8_t *)dInfo.lpSurface + y * dInfo.lPitch; uint8_t *pS = (uint8_t *)pSrc + (y+tinfo.TopToLoad) * tinfo.Pitch + (tinfo.LeftToLoad*4); for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { pDst[0] = pS[1]; // Blue pDst[1] = pS[2]; // Green pDst[2] = pS[3]; // Red pDst[3] = pS[0]; // Alpha pS+=4; pDst+=4; } } } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } // E.g. Dear Mario text // Copy, Score etc void ConvertIA4(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; uint32_t nFiddle; uint8_t * pSrc = (uint8_t*)(tinfo.pPhysicalAddress); #ifdef DEBUGGER if (((int64_t)pSrc) % 4) TRACE0("Texture src addr is not aligned to 4 bytes, check me"); #endif if (!pTexture->StartUpdate(&dInfo)) return; if (tinfo.bSwapped) { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint8_t *pDst = (uint8_t *)dInfo.lpSurface + y * dInfo.lPitch; // For odd lines, swap words too if ((y%2) == 0) nFiddle = 0x3; else nFiddle = 0x7; // This may not work if X is not even? uint32_t dwByteOffset = (y+tinfo.TopToLoad) * tinfo.Pitch + (tinfo.LeftToLoad/2); if (tinfo.WidthToLoad == 1) { // corner case uint8_t b = pSrc[dwByteOffset ^ nFiddle]; *pDst++ = ThreeToEight[(b & 0xE0) >> 5]; *pDst++ = ThreeToEight[(b & 0xE0) >> 5]; *pDst++ = ThreeToEight[(b & 0xE0) >> 5]; *pDst++ = OneToEight[(b & 0x10) >> 4]; } else for (uint32_t x = 0; x < tinfo.WidthToLoad; x+=2) { // Do two pixels at a time uint8_t b = pSrc[dwByteOffset ^ nFiddle]; // Even *pDst++ = ThreeToEight[(b & 0xE0) >> 5]; *pDst++ = ThreeToEight[(b & 0xE0) >> 5]; *pDst++ = ThreeToEight[(b & 0xE0) >> 5]; *pDst++ = OneToEight[(b & 0x10) >> 4]; // Odd *pDst++ = ThreeToEight[(b & 0x0E) >> 1]; *pDst++ = ThreeToEight[(b & 0x0E) >> 1]; *pDst++ = ThreeToEight[(b & 0x0E) >> 1]; *pDst++ = OneToEight[(b & 0x01) ]; dwByteOffset++; } } } else { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint8_t *pDst = (uint8_t *)dInfo.lpSurface + (y * dInfo.lPitch); // This may not work if X is not even? uint32_t dwByteOffset = (y+tinfo.TopToLoad) * tinfo.Pitch + (tinfo.LeftToLoad/2); if (tinfo.WidthToLoad == 1) { // corner case uint8_t b = pSrc[dwByteOffset ^ 0x3]; *pDst++ = ThreeToEight[(b & 0xE0) >> 5]; *pDst++ = ThreeToEight[(b & 0xE0) >> 5]; *pDst++ = ThreeToEight[(b & 0xE0) >> 5]; *pDst++ = OneToEight[(b & 0x10) >> 4]; } else for (uint32_t x = 0; x < tinfo.WidthToLoad; x+=2) { // Do two pixels at a time uint8_t b = pSrc[dwByteOffset ^ 0x3]; // Even *pDst++ = ThreeToEight[(b & 0xE0) >> 5]; *pDst++ = ThreeToEight[(b & 0xE0) >> 5]; *pDst++ = ThreeToEight[(b & 0xE0) >> 5]; *pDst++ = OneToEight[(b & 0x10) >> 4]; // Odd *pDst++ = ThreeToEight[(b & 0x0E) >> 1]; *pDst++ = ThreeToEight[(b & 0x0E) >> 1]; *pDst++ = ThreeToEight[(b & 0x0E) >> 1]; *pDst++ = OneToEight[(b & 0x01) ]; dwByteOffset++; } } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } // E.g Mario's head textures void ConvertIA8(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; uint32_t nFiddle; uint8_t * pSrc = (uint8_t*)(tinfo.pPhysicalAddress); #ifdef DEBUGGER if (((int64_t)pSrc) % 4) TRACE0("Texture src addr is not aligned to 4 bytes, check me"); #endif if (!pTexture->StartUpdate(&dInfo)) return; if (tinfo.bSwapped) { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { // For odd lines, swap words too if ((y%2) == 0) nFiddle = 0x3; else nFiddle = 0x7; uint8_t *pDst = (uint8_t *)dInfo.lpSurface + y * dInfo.lPitch; // Points to current byte uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + tinfo.LeftToLoad; for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { uint8_t b = pSrc[dwByteOffset ^ nFiddle]; uint8_t I = FourToEight[(b & 0xf0)>>4]; *pDst++ = I; *pDst++ = I; *pDst++ = I; *pDst++ = FourToEight[(b & 0x0f) ]; dwByteOffset++; } } } else { register const uint8_t* FourToEightArray = &FourToEight[0]; for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint8_t *pDst = (uint8_t *)dInfo.lpSurface + y * dInfo.lPitch; // Points to current byte uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + tinfo.LeftToLoad; for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { register uint8_t b = pSrc[(dwByteOffset++) ^ 0x3]; uint8_t I = *(FourToEightArray+(b>>4)); *pDst++ = I; *pDst++ = I; *pDst++ = I; *pDst++ = *(FourToEightArray+(b&0xF)); } } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } // E.g. camera's clouds, shadows void ConvertIA16(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; uint32_t nFiddle; uint16_t * pSrc = (uint16_t*)(tinfo.pPhysicalAddress); uint8_t * pByteSrc = (uint8_t *)pSrc; if (!pTexture->StartUpdate(&dInfo)) return; if (tinfo.bSwapped) { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint8_t *pDst = (uint8_t *)dInfo.lpSurface + y * dInfo.lPitch; if ((y%2) == 0) nFiddle = 0x2; else nFiddle = 0x4 | 0x2; // Points to current word uint32_t dwWordOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + (tinfo.LeftToLoad * 2); for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { uint16_t w = *(uint16_t *)&pByteSrc[dwWordOffset^nFiddle]; *pDst++ = (uint8_t)(w >> 8); *pDst++ = (uint8_t)(w >> 8); *pDst++ = (uint8_t)(w >> 8); *pDst++ = (uint8_t)(w & 0xFF); dwWordOffset += 2; } } } else { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint8_t *pDst = (uint8_t *)dInfo.lpSurface + y * dInfo.lPitch; // Points to current word uint32_t dwWordOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + (tinfo.LeftToLoad * 2); for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { uint16_t w = *(uint16_t *)&pByteSrc[dwWordOffset^0x2]; *pDst++ = (uint8_t)(w >> 8); *pDst++ = (uint8_t)(w >> 8); *pDst++ = (uint8_t)(w >> 8); *pDst++ = (uint8_t)(w & 0xFF); dwWordOffset += 2; } } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } // Used by MarioKart void ConvertI4(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; uint32_t nFiddle; uint8_t * pSrc = (uint8_t*)(tinfo.pPhysicalAddress); #ifdef DEBUGGER if (((int64_t) pSrc) % 4) TRACE0("Texture src addr is not aligned to 4 bytes, check me"); #endif if (!pTexture->StartUpdate(&dInfo)) return; if (tinfo.bSwapped) { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint8_t *pDst = (uint8_t *)dInfo.lpSurface + y * dInfo.lPitch; // Might not work with non-even starting X uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + (tinfo.LeftToLoad / 2); // For odd lines, swap words too if( !conkerSwapHack || (y&4) == 0 ) { if ((y%2) == 0) nFiddle = 0x3; else nFiddle = 0x7; } else { if ((y%2) == 1) nFiddle = 0x3; else nFiddle = 0x7; } if (tinfo.WidthToLoad == 1) { // corner case uint8_t b = pSrc[dwByteOffset ^ nFiddle]; *pDst++ = FourToEight[(b & 0xF0)>>4]; *pDst++ = FourToEight[(b & 0xF0)>>4]; *pDst++ = FourToEight[(b & 0xF0)>>4]; *pDst++ = FourToEight[(b & 0xF0)>>4]; } else for (uint32_t x = 0; x < tinfo.WidthToLoad; x+=2) { // two pixels at a time uint8_t b = pSrc[dwByteOffset ^ nFiddle]; // Even *pDst++ = FourToEight[(b & 0xF0)>>4]; // Other implementations seem to or in (b&0xF0)>>4 *pDst++ = FourToEight[(b & 0xF0)>>4]; // why? *pDst++ = FourToEight[(b & 0xF0)>>4]; *pDst++ = FourToEight[(b & 0xF0)>>4]; // Odd *pDst++ = FourToEight[(b & 0x0F)]; *pDst++ = FourToEight[(b & 0x0F)]; *pDst++ = FourToEight[(b & 0x0F)]; *pDst++ = FourToEight[(b & 0x0F)]; dwByteOffset++; } } conkerSwapHack = false; } else { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint8_t *pDst = (uint8_t *)dInfo.lpSurface + y * dInfo.lPitch; // Might not work with non-even starting X uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + (tinfo.LeftToLoad / 2); if (tinfo.WidthToLoad == 1) { // corner case uint8_t b = pSrc[dwByteOffset ^ 0x3]; *pDst++ = FourToEight[(b & 0xF0)>>4]; *pDst++ = FourToEight[(b & 0xF0)>>4]; *pDst++ = FourToEight[(b & 0xF0)>>4]; *pDst++ = FourToEight[(b & 0xF0)>>4]; } else for (uint32_t x = 0; x < tinfo.WidthToLoad; x+=2) { // two pixels at a time uint8_t b = pSrc[dwByteOffset ^ 0x3]; // Even *pDst++ = FourToEight[(b & 0xF0)>>4]; // Other implementations seem to or in (b&0xF0)>>4 *pDst++ = FourToEight[(b & 0xF0)>>4]; // why? *pDst++ = FourToEight[(b & 0xF0)>>4]; *pDst++ = FourToEight[(b & 0xF0)>>4]; // Odd *pDst++ = FourToEight[(b & 0x0F)]; *pDst++ = FourToEight[(b & 0x0F)]; *pDst++ = FourToEight[(b & 0x0F)]; *pDst++ = FourToEight[(b & 0x0F)]; dwByteOffset++; } } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } // Used by MarioKart void ConvertI8(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; uint32_t nFiddle; int64_t pSrc = (int64_t) tinfo.pPhysicalAddress; if (!pTexture->StartUpdate(&dInfo)) return; if (tinfo.bSwapped) { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { if ((y%2) == 0) nFiddle = 0x3; else nFiddle = 0x7; uint8_t *pDst = (uint8_t *)dInfo.lpSurface + y * dInfo.lPitch; uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + tinfo.LeftToLoad; for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { uint8_t b = *(uint8_t*)((pSrc+dwByteOffset)^nFiddle); *pDst++ = b; *pDst++ = b; *pDst++ = b; *pDst++ = b; // Alpha not 255? dwByteOffset++; } } } else { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint8_t *pDst = (uint8_t *)dInfo.lpSurface + y * dInfo.lPitch; uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + tinfo.LeftToLoad; for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { uint8_t b = *(uint8_t*)((pSrc+dwByteOffset)^0x3); *pDst++ = b; *pDst++ = b; *pDst++ = b; *pDst++ = b; // Alpha not 255? dwByteOffset++; } } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } //***************************************************************************** // Convert CI4 images. We need to switch on the palette type //***************************************************************************** void ConvertCI4( CTexture * p_texture, const TxtrInfo & tinfo ) { if ( tinfo.TLutFmt == TLUT_FMT_RGBA16 ) { ConvertCI4_RGBA16( p_texture, tinfo ); } else if ( tinfo.TLutFmt == TLUT_FMT_IA16 ) { ConvertCI4_IA16( p_texture, tinfo ); } } //***************************************************************************** // Convert CI8 images. We need to switch on the palette type //***************************************************************************** void ConvertCI8( CTexture * p_texture, const TxtrInfo & tinfo ) { if ( tinfo.TLutFmt == TLUT_FMT_RGBA16 ) { ConvertCI8_RGBA16( p_texture, tinfo ); } else if ( tinfo.TLutFmt == TLUT_FMT_IA16 ) { ConvertCI8_IA16( p_texture, tinfo ); } } // Used by Starfox intro void ConvertCI4_RGBA16(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; uint32_t nFiddle; uint8_t * pSrc = (uint8_t*)(tinfo.pPhysicalAddress); uint16_t * pPal = (uint16_t *)tinfo.PalAddress; bool bIgnoreAlpha = (tinfo.TLutFmt==TLUT_FMT_NONE); if (!pTexture->StartUpdate(&dInfo)) return; if (tinfo.bSwapped) { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { if ((y%2) == 0) nFiddle = 0x3; else nFiddle = 0x7; uint32_t * pDst = (uint32_t *)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch); if (tinfo.WidthToLoad == 1) { // corner case uint8_t b = pSrc[dwByteOffset ^ nFiddle]; uint8_t bhi = (b&0xf0)>>4; *pDst = Convert555ToRGBA(pPal[bhi^1]); // Remember palette is in different endian order! if( bIgnoreAlpha ) { *pDst |= 0xFF000000; } } else for (uint32_t x = 0; x < tinfo.WidthToLoad; x+=2) { // two at a time uint8_t b = pSrc[dwByteOffset ^ nFiddle]; uint8_t bhi = (b&0xf0)>>4; uint8_t blo = (b&0x0f); pDst[0] = Convert555ToRGBA(pPal[bhi^1]); // Remember palette is in different endian order! pDst[1] = Convert555ToRGBA(pPal[blo^1]); // Remember palette is in different endian order! if( bIgnoreAlpha ) { pDst[0] |= 0xFF000000; pDst[1] |= 0xFF000000; } pDst+=2; dwByteOffset++; } } } else { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint32_t * pDst = (uint32_t *)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + (tinfo.LeftToLoad / 2); if (tinfo.WidthToLoad == 1) { // corner case uint8_t b = pSrc[dwByteOffset ^ 0x3]; uint8_t bhi = (b&0xf0)>>4; *pDst = Convert555ToRGBA(pPal[bhi^1]); // Remember palette is in different endian order! if( bIgnoreAlpha ) { *pDst |= 0xFF000000; } } else for (uint32_t x = 0; x < tinfo.WidthToLoad; x+=2) { // two at a time uint8_t b = pSrc[dwByteOffset ^ 0x3]; uint8_t bhi = (b&0xf0)>>4; uint8_t blo = (b&0x0f); pDst[0] = Convert555ToRGBA(pPal[bhi^1]); // Remember palette is in different endian order! pDst[1] = Convert555ToRGBA(pPal[blo^1]); // Remember palette is in different endian order! if( bIgnoreAlpha ) { pDst[0] |= 0xFF000000; pDst[1] |= 0xFF000000; } pDst+=2; dwByteOffset++; } } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } // Used by Starfox intro void ConvertCI4_IA16(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; uint32_t nFiddle; uint8_t * pSrc = (uint8_t*)(tinfo.pPhysicalAddress); #ifdef DEBUGGER if (((int64_t) pSrc) % 4) TRACE0("Texture src addr is not aligned to 4 bytes, check me"); #endif uint16_t * pPal = (uint16_t *)tinfo.PalAddress; bool bIgnoreAlpha = (tinfo.TLutFmt==TLUT_FMT_UNKNOWN); if (!pTexture->StartUpdate(&dInfo)) return; if (tinfo.bSwapped) { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { if ((y%2) == 0) nFiddle = 0x3; else nFiddle = 0x7; uint32_t * pDst = (uint32_t *)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + (tinfo.LeftToLoad / 2); if (tinfo.WidthToLoad == 1) { // corner case uint8_t b = pSrc[dwByteOffset ^ nFiddle]; uint8_t bhi = (b&0xf0)>>4; *pDst = ConvertIA16ToRGBA(pPal[bhi^1]); // Remember palette is in different endian order! if( bIgnoreAlpha ) *pDst |= 0xFF000000; } else for (uint32_t x = 0; x < tinfo.WidthToLoad; x+=2) { // two at a time uint8_t b = pSrc[dwByteOffset ^ nFiddle]; uint8_t bhi = (b&0xf0)>>4; uint8_t blo = (b&0x0f); pDst[0] = ConvertIA16ToRGBA(pPal[bhi^1]); // Remember palette is in different endian order! pDst[1] = ConvertIA16ToRGBA(pPal[blo^1]); // Remember palette is in different endian order! if( bIgnoreAlpha ) { pDst[0] |= 0xFF000000; pDst[1] |= 0xFF000000; } pDst+=2; dwByteOffset++; } } } else { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint32_t * pDst = (uint32_t *)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + (tinfo.LeftToLoad / 2); if (tinfo.WidthToLoad == 1) { // corner case uint8_t b = pSrc[dwByteOffset ^ 0x3]; uint8_t bhi = (b&0xf0)>>4; *pDst = ConvertIA16ToRGBA(pPal[bhi^1]); // Remember palette is in different endian order! if( bIgnoreAlpha ) *pDst |= 0xFF000000; } else for (uint32_t x = 0; x < tinfo.WidthToLoad; x+=2) { // two pixels at a time uint8_t b = pSrc[dwByteOffset ^ 0x3]; uint8_t bhi = (b&0xf0)>>4; uint8_t blo = (b&0x0f); pDst[0] = ConvertIA16ToRGBA(pPal[bhi^1]); // Remember palette is in different endian order! pDst[1] = ConvertIA16ToRGBA(pPal[blo^1]); // Remember palette is in different endian order! if( bIgnoreAlpha ) { pDst[0] |= 0xFF000000; pDst[1] |= 0xFF000000; } pDst+=2; dwByteOffset++; } } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } // Used by MarioKart for Cars etc void ConvertCI8_RGBA16(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; uint32_t nFiddle; uint8_t * pSrc = (uint8_t*)(tinfo.pPhysicalAddress); #ifdef DEBUGGER if (((int64_t) pSrc) % 4) TRACE0("Texture src addr is not aligned to 4 bytes, check me"); #endif uint16_t * pPal = (uint16_t *)tinfo.PalAddress; bool bIgnoreAlpha = (tinfo.TLutFmt==TLUT_FMT_NONE); if (!pTexture->StartUpdate(&dInfo)) return; if (tinfo.bSwapped) { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { if ((y%2) == 0) nFiddle = 0x3; else nFiddle = 0x7; uint32_t *pDst = (uint32_t *)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + tinfo.LeftToLoad; for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { uint8_t b = pSrc[dwByteOffset ^ nFiddle]; *pDst++ = Convert555ToRGBA(pPal[b^1]); // Remember palette is in different endian order! if( bIgnoreAlpha ) { *(pDst-1) |= 0xFF000000; } dwByteOffset++; } } } else { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint32_t *pDst = (uint32_t *)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); int dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + tinfo.LeftToLoad; for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { uint8_t b = pSrc[dwByteOffset ^ 0x3]; *pDst++ = Convert555ToRGBA(pPal[b^1]); // Remember palette is in different endian order! if( bIgnoreAlpha ) { *(pDst-1) |= 0xFF000000; } dwByteOffset++; } } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } // Used by MarioKart for Cars etc void ConvertCI8_IA16(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; uint32_t nFiddle; uint8_t * pSrc = (uint8_t*)(tinfo.pPhysicalAddress); #ifdef DEBUGGER if (((int64_t) pSrc) % 4) TRACE0("Texture src addr is not aligned to 4 bytes, check me"); #endif uint16_t * pPal = (uint16_t *)tinfo.PalAddress; bool bIgnoreAlpha = (tinfo.TLutFmt==TLUT_FMT_UNKNOWN); if (!pTexture->StartUpdate(&dInfo)) return; if (tinfo.bSwapped) { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { if ((y%2) == 0) nFiddle = 0x3; else nFiddle = 0x7; uint32_t *pDst = (uint32_t *)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + tinfo.LeftToLoad; for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { uint8_t b = pSrc[dwByteOffset ^ nFiddle]; *pDst++ = ConvertIA16ToRGBA(pPal[b^1]); // Remember palette is in different endian order! if( bIgnoreAlpha ) { *(pDst-1) |= 0xFF000000; } dwByteOffset++; } } } else { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint32_t *pDst = (uint32_t *)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + tinfo.LeftToLoad; for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { uint8_t b = pSrc[dwByteOffset ^ 0x3]; *pDst++ = ConvertIA16ToRGBA(pPal[b^1]); // Remember palette is in different endian order! if( bIgnoreAlpha ) { *(pDst-1) |= 0xFF000000; } dwByteOffset++; } } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } void ConvertYUV(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; if (!pTexture->StartUpdate(&dInfo)) return; uint32_t x, y; uint32_t nFiddle; if( options.bUseFullTMEM ) { Tile &tile = gRDP.tiles[tinfo.tileNo]; uint16_t * pSrc; if( tinfo.tileNo >= 0 ) pSrc = (uint16_t*)&g_Tmem.g_Tmem64bit[tile.dwTMem]; else pSrc = (uint16_t*)(tinfo.pPhysicalAddress); uint8_t * pByteSrc = (uint8_t *)pSrc; for (y = 0; y < tinfo.HeightToLoad; y++) { nFiddle = ( y&1 )? 0x4 : 0; int dwWordOffset = tinfo.tileNo>=0? tile.dwLine*8*y : ((y+tinfo.TopToLoad) * tinfo.Pitch) + (tinfo.LeftToLoad * 2); uint32_t * dwDst = (uint32_t *)((uint8_t *)dInfo.lpSurface + y*dInfo.lPitch); for (x = 0; x < tinfo.WidthToLoad/2; x++) { int y0 = *(uint8_t*)&pByteSrc[(dwWordOffset+1)^nFiddle]; int y1 = *(uint8_t*)&pByteSrc[(dwWordOffset+3)^nFiddle]; int u0 = *(uint8_t*)&pByteSrc[(dwWordOffset )^nFiddle]; int v0 = *(uint8_t*)&pByteSrc[(dwWordOffset+2)^nFiddle]; dwDst[x*2+0] = ConvertYUV16ToR8G8B8(y0,u0,v0); dwDst[x*2+1] = ConvertYUV16ToR8G8B8(y1,u0,v0); dwWordOffset += 4; } } } else { uint16_t * pSrc = (uint16_t*)(tinfo.pPhysicalAddress); uint8_t * pByteSrc = (uint8_t *)pSrc; if (tinfo.bSwapped) { for (y = 0; y < tinfo.HeightToLoad; y++) { if ((y&1) == 0) nFiddle = 0x3; else nFiddle = 0x7; // dwDst points to start of destination row uint32_t * dwDst = (uint32_t *)((uint8_t *)dInfo.lpSurface + y*dInfo.lPitch); // DWordOffset points to the current dword we're looking at // (process 2 pixels at a time). May be a problem if we don't start on even pixel uint32_t dwWordOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + (tinfo.LeftToLoad * 2); for (x = 0; x < tinfo.WidthToLoad/2; x++) { int y0 = *(uint8_t*)&pByteSrc[(dwWordOffset+2)^nFiddle]; int v0 = *(uint8_t*)&pByteSrc[(dwWordOffset+1)^nFiddle]; int y1 = *(uint8_t*)&pByteSrc[(dwWordOffset )^nFiddle]; int u0 = *(uint8_t*)&pByteSrc[(dwWordOffset+3)^nFiddle]; dwDst[x*2+0] = ConvertYUV16ToR8G8B8(y0,u0,v0); dwDst[x*2+1] = ConvertYUV16ToR8G8B8(y1,u0,v0); dwWordOffset += 4; } } } else { for (y = 0; y < tinfo.HeightToLoad; y++) { // dwDst points to start of destination row uint32_t * dwDst = (uint32_t *)((uint8_t *)dInfo.lpSurface + y*dInfo.lPitch); uint32_t dwByteOffset = y * 32; for (x = 0; x < tinfo.WidthToLoad/2; x++) { int y0 = *(uint8_t*)&pByteSrc[(dwByteOffset+2)]; int v0 = *(uint8_t*)&pByteSrc[(dwByteOffset+1)]; int y1 = *(uint8_t*)&pByteSrc[(dwByteOffset )]; int u0 = *(uint8_t*)&pByteSrc[(dwByteOffset+3)]; dwDst[x*2+0] = ConvertYUV16ToR8G8B8(y0,u0,v0); dwDst[x*2+1] = ConvertYUV16ToR8G8B8(y1,u0,v0); // Increment word offset to point to the next two pixels dwByteOffset += 4; } } } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } uint32_t ConvertYUV16ToR8G8B8(int Y, int U, int V) { /* int R = int(g_convc0 *(Y-16) + g_convc1 * V); int G = int(g_convc0 *(Y-16) + g_convc2 * U - g_convc3 * V); int B = int(g_convc0 *(Y-16) + g_convc4 * U); */ Y += 80; int R = int(Y + (1.370705f * (V-128))); int G = int(Y - (0.698001f * (V-128)) - (0.337633f * (U-128))); int B = int(Y + (1.732446f * (U-128))); R = R < 0 ? 0 : (R>255 ? 255 : R); G = G < 0 ? 0 : (G>255 ? 255 : G); B = B < 0 ? 0 : (B>255 ? 255 : B); return COLOR_RGBA(R, G, B, 0xFF); } // Used by Starfox intro void Convert4b(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; if (!pTexture->StartUpdate(&dInfo)) return; uint16_t * pPal = (uint16_t *)tinfo.PalAddress; bool bIgnoreAlpha = (tinfo.TLutFmt==TLUT_FMT_UNKNOWN); if( tinfo.Format <= TXT_FMT_CI ) bIgnoreAlpha = (tinfo.TLutFmt==TLUT_FMT_NONE); Tile &tile = gRDP.tiles[tinfo.tileNo]; uint8_t *pByteSrc = tinfo.tileNo >= 0 ? (uint8_t*)&g_Tmem.g_Tmem64bit[tile.dwTMem] : (uint8_t*)(tinfo.pPhysicalAddress); for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint32_t nFiddle; if( tinfo.tileNo < 0 ) { if (tinfo.bSwapped) { if ((y%2) == 0) nFiddle = 0x3; else nFiddle = 0x7; } else { nFiddle = 3; } } else { nFiddle = ( y&1 )? 0x4 : 0; } uint32_t * pDst = (uint32_t *)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); int idx = tinfo.tileNo>=0 ? tile.dwLine*8*y : ((y+tinfo.TopToLoad) * tinfo.Pitch) + (tinfo.LeftToLoad / 2); if (tinfo.WidthToLoad == 1) { // corner case uint8_t b = pByteSrc[idx^nFiddle]; uint8_t bhi = (b&0xf0)>>4; if( gRDP.otherMode.text_tlut>=2 || ( tinfo.Format != TXT_FMT_IA && tinfo.Format != TXT_FMT_I) ) { if( tinfo.TLutFmt == TLUT_FMT_IA16 ) { if( tinfo.tileNo>=0 ) *pDst = ConvertIA16ToRGBA(g_Tmem.g_Tmem16bit[0x400+tinfo.Palette*0x40+(bhi<<2)]); else *pDst = ConvertIA16ToRGBA(pPal[bhi^1]); } else { if( tinfo.tileNo>=0 ) *pDst = Convert555ToRGBA(g_Tmem.g_Tmem16bit[0x400+tinfo.Palette*0x40+(bhi<<2)]); else *pDst = Convert555ToRGBA(pPal[bhi^1]); } } else if( tinfo.Format == TXT_FMT_IA ) *pDst = ConvertIA4ToRGBA(b>>4); else // if( tinfo.Format == TXT_FMT_I ) *pDst = ConvertI4ToRGBA(b>>4); if( bIgnoreAlpha ) *pDst |= 0xFF000000; } else for (uint32_t x = 0; x < tinfo.WidthToLoad; x+=2, idx++) { // two pixels at a time uint8_t b = pByteSrc[idx^nFiddle]; uint8_t bhi = (b&0xf0)>>4; uint8_t blo = (b&0x0f); if( gRDP.otherMode.text_tlut>=2 || ( tinfo.Format != TXT_FMT_IA && tinfo.Format != TXT_FMT_I) ) { if( tinfo.TLutFmt == TLUT_FMT_IA16 ) { if( tinfo.tileNo>=0 ) { pDst[0] = ConvertIA16ToRGBA(g_Tmem.g_Tmem16bit[0x400+tinfo.Palette*0x40+(bhi<<2)]); pDst[1] = ConvertIA16ToRGBA(g_Tmem.g_Tmem16bit[0x400+tinfo.Palette*0x40+(blo<<2)]); } else { pDst[0] = ConvertIA16ToRGBA(pPal[bhi^1]); pDst[1] = ConvertIA16ToRGBA(pPal[blo^1]); } } else { if( tinfo.tileNo>=0 ) { pDst[0] = Convert555ToRGBA(g_Tmem.g_Tmem16bit[0x400+tinfo.Palette*0x40+(bhi<<2)]); pDst[1] = Convert555ToRGBA(g_Tmem.g_Tmem16bit[0x400+tinfo.Palette*0x40+(blo<<2)]); } else { pDst[0] = Convert555ToRGBA(pPal[bhi^1]); pDst[1] = Convert555ToRGBA(pPal[blo^1]); } } } else if( tinfo.Format == TXT_FMT_IA ) { pDst[0] = ConvertIA4ToRGBA(b>>4); pDst[1] = ConvertIA4ToRGBA(b&0xF); } else // if( tinfo.Format == TXT_FMT_I ) { pDst[0] = ConvertI4ToRGBA(b>>4); pDst[1] = ConvertI4ToRGBA(b&0xF); } if( bIgnoreAlpha ) { pDst[0] |= 0xFF000000; pDst[1] |= 0xFF000000; } pDst+=2; } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } void Convert8b(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; if (!pTexture->StartUpdate(&dInfo)) return; uint16_t * pPal = (uint16_t *)tinfo.PalAddress; bool bIgnoreAlpha = (tinfo.TLutFmt==TLUT_FMT_UNKNOWN); if( tinfo.Format <= TXT_FMT_CI ) bIgnoreAlpha = (tinfo.TLutFmt==TLUT_FMT_NONE); Tile &tile = gRDP.tiles[tinfo.tileNo]; uint8_t *pByteSrc; if( tinfo.tileNo >= 0 ) { pByteSrc = (uint8_t*)&g_Tmem.g_Tmem64bit[tile.dwTMem]; } else { pByteSrc = (uint8_t*)(tinfo.pPhysicalAddress); } for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint32_t * pDst = (uint32_t *)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); uint32_t nFiddle; if( tinfo.tileNo < 0 ) { if (tinfo.bSwapped) { if ((y%2) == 0) nFiddle = 0x3; else nFiddle = 0x7; } else { nFiddle = 3; } } else { nFiddle = ( y&1 )? 0x4 : 0; } int idx = tinfo.tileNo>=0? tile.dwLine*8*y : ((y+tinfo.TopToLoad) * tinfo.Pitch) + tinfo.LeftToLoad; for (uint32_t x = 0; x < tinfo.WidthToLoad; x++, idx++) { uint8_t b = pByteSrc[idx^nFiddle]; if( gRDP.otherMode.text_tlut>=2 || ( tinfo.Format != TXT_FMT_IA && tinfo.Format != TXT_FMT_I) ) { if( tinfo.TLutFmt == TLUT_FMT_IA16 ) { if( tinfo.tileNo>=0 ) *pDst = ConvertIA16ToRGBA(g_Tmem.g_Tmem16bit[0x400+(b<<2)]); else *pDst = ConvertIA16ToRGBA(pPal[b^1]); } else { if( tinfo.tileNo>=0 ) *pDst = Convert555ToRGBA(g_Tmem.g_Tmem16bit[0x400+(b<<2)]); else *pDst = Convert555ToRGBA(pPal[b^1]); } } else if( tinfo.Format == TXT_FMT_IA ) { uint8_t I = FourToEight[(b & 0xf0)>>4]; uint8_t * pByteDst = (uint8_t*)pDst; pByteDst[0] = I; pByteDst[1] = I; pByteDst[2] = I; pByteDst[3] = FourToEight[(b & 0x0f) ]; } else // if( tinfo.Format == TXT_FMT_I ) { uint8_t * pByteDst = (uint8_t*)pDst; pByteDst[0] = b; pByteDst[1] = b; pByteDst[2] = b; pByteDst[3] = b; } if( bIgnoreAlpha ) { *pDst |= 0xFF000000; } pDst++; } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } void Convert16b(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; if (!pTexture->StartUpdate(&dInfo)) return; Tile &tile = gRDP.tiles[tinfo.tileNo]; uint16_t *pWordSrc; if( tinfo.tileNo >= 0 ) pWordSrc = (uint16_t*)&g_Tmem.g_Tmem64bit[tile.dwTMem]; else pWordSrc = (uint16_t*)(tinfo.pPhysicalAddress); for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint32_t * dwDst = (uint32_t *)((uint8_t *)dInfo.lpSurface + y*dInfo.lPitch); uint32_t nFiddle; if( tinfo.tileNo < 0 ) { if (tinfo.bSwapped) { if ((y&1) == 0) nFiddle = 0x1; else nFiddle = 0x3; } else { nFiddle = 0x1; } } else { nFiddle = ( y&1 )? 0x2 : 0; } int idx = tinfo.tileNo>=0? tile.dwLine*4*y : (((y+tinfo.TopToLoad) * tinfo.Pitch)>>1) + tinfo.LeftToLoad; for (uint32_t x = 0; x < tinfo.WidthToLoad; x++, idx++) { uint16_t w = pWordSrc[idx^nFiddle]; uint16_t w2 = tinfo.tileNo>=0? ((w>>8)|(w<<8)) : w; if( tinfo.Format == TXT_FMT_RGBA ) { dwDst[x] = Convert555ToRGBA(w2); } else if( tinfo.Format == TXT_FMT_YUV ) { } else if( tinfo.Format >= TXT_FMT_IA ) { uint8_t * pByteDst = (uint8_t*)&dwDst[x]; *pByteDst++ = (uint8_t)(w2 >> 8); *pByteDst++ = (uint8_t)(w2 >> 8); *pByteDst++ = (uint8_t)(w2 >> 8); *pByteDst++ = (uint8_t)(w2 & 0xFF); } } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } mupen64plus-core/src/r4300/profile.c000664 001750 001750 00000007617 12655644434 020225 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - profile.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2012 CasualJames * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifdef PROFILE #include "r4300.h" #include "api/m64p_types.h" #include "api/callbacks.h" static long long int time_in_section[5]; static long long int last_start[5]; #if defined(WIN32) && !defined(__MINGW32__) // timing #include static long long int get_time(void) { LARGE_INTEGER counter; QueryPerformanceCounter(&counter); return counter.QuadPart; } static long long int time_to_nsec(long long int time) { static LARGE_INTEGER freq = { 0 }; if (freq.QuadPart == 0) QueryPerformanceFrequency(&freq); return time * 1000000000 / freq.QuadPart; } #else /* Not WIN32 */ // timing #include static long long int get_time(void) { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); return (long long int)ts.tv_sec * 1000000000 + ts.tv_nsec; } static long long int time_to_nsec(long long int time) { return time; } #endif void start_section(int section_type) { last_start[section_type] = get_time(); } void end_section(int section_type) { long long int end = get_time(); time_in_section[section_type] += end - last_start[section_type]; } void refresh_stat() { long long int curr_time = get_time(); if(time_to_nsec(curr_time - last_start[ALL_SECTION]) >= 2000000000) { time_in_section[ALL_SECTION] = curr_time - last_start[ALL_SECTION]; DebugMessage(M64MSG_INFO, "gfx=%f%% - audio=%f%% - compiler=%f%%, idle=%f%%", 100.0 * (double)time_in_section[GFX_SECTION] / time_in_section[ALL_SECTION], 100.0 * (double)time_in_section[AUDIO_SECTION] / time_in_section[ALL_SECTION], 100.0 * (double)time_in_section[COMPILER_SECTION] / time_in_section[ALL_SECTION], 100.0 * (double)time_in_section[IDLE_SECTION] / time_in_section[ALL_SECTION]); DebugMessage(M64MSG_INFO, "gfx=%llins - audio=%llins - compiler %llins - idle=%llins", time_to_nsec(time_in_section[GFX_SECTION]), time_to_nsec(time_in_section[AUDIO_SECTION]), time_to_nsec(time_in_section[COMPILER_SECTION]), time_to_nsec(time_in_section[IDLE_SECTION])); time_in_section[GFX_SECTION] = 0; time_in_section[AUDIO_SECTION] = 0; time_in_section[COMPILER_SECTION] = 0; time_in_section[IDLE_SECTION] = 0; last_start[ALL_SECTION] = curr_time; } } #endif mupen64plus-core/src/r4300/instr_counters.h000664 001750 001750 00000003363 12655644434 021645 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - instr_counters.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_R4300_INSTR_COUNTERS_H #define M64P_R4300_INSTR_COUNTERS_H #if defined(COUNT_INSTR) extern unsigned int instr_count[132]; void instr_counters_print(void); #endif /* COUNT_INSTR */ #endif /* M64P_R4300_INSTR_COUNTERS_H */ mupen64plus-core/src/debugger/dbg_breakpoints.c000664 001750 001750 00000016604 12655644434 022732 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - dbg_breakpoints.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2008 DarkJeztr HyperHacker * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include "dbg_types.h" #include "debugger.h" #include "dbg_breakpoints.h" #include "api/m64p_types.h" #include "api/callbacks.h" #include "memory/memory.h" int g_NumBreakpoints=0; breakpoint g_Breakpoints[BREAKPOINTS_MAX_NUMBER]; int add_breakpoint( uint32 address ) { if( g_NumBreakpoints == BREAKPOINTS_MAX_NUMBER ) { DebugMessage(M64MSG_ERROR, "BREAKPOINTS_MAX_NUMBER have been reached."); return -1; } g_Breakpoints[g_NumBreakpoints].address=address; g_Breakpoints[g_NumBreakpoints].endaddr=address; BPT_SET_FLAG(g_Breakpoints[g_NumBreakpoints], BPT_FLAG_EXEC); enable_breakpoint(g_NumBreakpoints); return g_NumBreakpoints++; } int add_breakpoint_struct(breakpoint* newbp) { if( g_NumBreakpoints == BREAKPOINTS_MAX_NUMBER ) { DebugMessage(M64MSG_ERROR, "BREAKPOINTS_MAX_NUMBER have been reached."); return -1; } memcpy(&g_Breakpoints[g_NumBreakpoints], newbp, sizeof(breakpoint)); if(BPT_CHECK_FLAG(g_Breakpoints[g_NumBreakpoints], BPT_FLAG_ENABLED)) { BPT_CLEAR_FLAG(g_Breakpoints[g_NumBreakpoints], BPT_FLAG_ENABLED); enable_breakpoint( g_NumBreakpoints ); } return g_NumBreakpoints++; } void enable_breakpoint( int bpt) { breakpoint *curBpt = g_Breakpoints + bpt; uint64 bptAddr; if(BPT_CHECK_FLAG((*curBpt), BPT_FLAG_READ)) { for(bptAddr = curBpt->address; bptAddr <= (curBpt->endaddr | 0xFFFF); bptAddr+=0x10000) if(lookup_breakpoint((uint32) bptAddr & 0xFFFF0000, 0x10000, BPT_FLAG_ENABLED | BPT_FLAG_READ) == -1) activate_memory_break_read((uint32) bptAddr); } if(BPT_CHECK_FLAG((*curBpt), BPT_FLAG_WRITE)) { for(bptAddr = curBpt->address; bptAddr <= (curBpt->endaddr | 0xFFFF); bptAddr+=0x10000) if(lookup_breakpoint((uint32) bptAddr & 0xFFFF0000, 0x10000, BPT_FLAG_ENABLED | BPT_FLAG_WRITE) == -1) activate_memory_break_write((uint32) bptAddr); } BPT_SET_FLAG(g_Breakpoints[bpt], BPT_FLAG_ENABLED); } void disable_breakpoint( int bpt ) { breakpoint *curBpt = g_Breakpoints + bpt; uint64 bptAddr; BPT_CLEAR_FLAG(g_Breakpoints[bpt], BPT_FLAG_ENABLED); if(BPT_CHECK_FLAG((*curBpt), BPT_FLAG_READ)) { for(bptAddr = curBpt->address; bptAddr <= ((unsigned long)(curBpt->endaddr | 0xFFFF)); bptAddr+=0x10000) if(lookup_breakpoint((uint32) bptAddr & 0xFFFF0000, 0x10000, BPT_FLAG_ENABLED | BPT_FLAG_READ) == -1) deactivate_memory_break_read((uint32) bptAddr); } if(BPT_CHECK_FLAG((*curBpt), BPT_FLAG_WRITE)) { for(bptAddr = curBpt->address; bptAddr <= ((unsigned long)(curBpt->endaddr | 0xFFFF)); bptAddr+=0x10000) if(lookup_breakpoint((uint32) bptAddr & 0xFFFF0000, 0x10000, BPT_FLAG_ENABLED | BPT_FLAG_WRITE) == -1) deactivate_memory_break_write((uint32) bptAddr); } BPT_CLEAR_FLAG(g_Breakpoints[bpt], BPT_FLAG_ENABLED); } void remove_breakpoint_by_num( int bpt ) { int curBpt; if(BPT_CHECK_FLAG(g_Breakpoints[bpt], BPT_FLAG_ENABLED)) disable_breakpoint( bpt ); for(curBpt=bpt+1; curBpt= g_Breakpoints[i].address) || (address <= g_Breakpoints[i].endaddr)) return i; } else // endaddr >= address { if((endaddr >= g_Breakpoints[i].address) && (address <= g_Breakpoints[i].endaddr)) return i; } } } return -1; } int check_breakpoints( uint32 address ) { return lookup_breakpoint( address, 1, BPT_FLAG_ENABLED | BPT_FLAG_EXEC ); } int check_breakpoints_on_mem_access( uint32 pc, uint32 address, uint32 size, uint32 flags ) { //This function handles memory read/write breakpoints. size specifies the address //range to check, flags specifies the flags that all need to be set. //It automatically stops and updates the debugger on hit, so the memory access //functions only need to call it and can discard the result. int bpt; if(run == 2) { bpt=lookup_breakpoint( address, size, flags ); if(bpt != -1) { if(BPT_CHECK_FLAG(g_Breakpoints[bpt], BPT_FLAG_LOG)) log_breakpoint(pc, flags, address); run = 0; update_debugger(pc); return bpt; } } return -1; } int log_breakpoint(uint32 PC, uint32 Flag, uint32 Access) { char msg[32]; if(Flag & BPT_FLAG_READ) sprintf(msg, "0x%08X read 0x%08X", PC, Access); else if(Flag & BPT_FLAG_WRITE) sprintf(msg, "0x%08X wrote 0x%08X", PC, Access); else sprintf(msg, "0x%08X executed", PC); DebugMessage(M64MSG_INFO, "BPT: %s", msg); return 0; } mupen64plus-rsp-cxd4/vu/logical.h000664 001750 001750 00000005622 12655644434 020005 0ustar00sergiosergio000000 000000 /******************************************************************************\ * Authors: Iconoclast * * Release: 2013.11.26 * * License: CC0 Public Domain Dedication * * * * To the extent possible under law, the author(s) have dedicated all copyright * * and related and neighboring rights to this software to the public domain * * worldwide. This software is distributed without any warranty. * * * * You should have received a copy of the CC0 Public Domain Dedication along * * with this software. * * If not, see . * \******************************************************************************/ static INLINE void do_and(short* VD, short* VS, short* VT) { register int i; for (i = 0; i < N; i++) VACC_L[i] = VS[i] & VT[i]; vector_copy(VD, VACC_L); } static INLINE void do_nand(short* VD, short* VS, short* VT) { register int i; for (i = 0; i < N; i++) VACC_L[i] = ~(VS[i] & VT[i]); vector_copy(VD, VACC_L); } static INLINE void do_nor(short* VD, short* VS, short* VT) { register int i; for (i = 0; i < N; i++) VACC_L[i] = ~(VS[i] | VT[i]); vector_copy(VD, VACC_L); } static INLINE void do_nxor(short* VD, short* VS, short* VT) { register int i; for (i = 0; i < N; i++) VACC_L[i] = ~(VS[i] ^ VT[i]); vector_copy(VD, VACC_L); } static INLINE void VNXOR(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_nxor(VR[vd], VR[vs], ST); } static INLINE void VNOR(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_nor(VR[vd], VR[vs], ST); } static INLINE void do_or(short* VD, short* VS, short* VT) { register int i; for (i = 0; i < N; i++) VACC_L[i] = VS[i] | VT[i]; vector_copy(VD, VACC_L); } static INLINE void do_xor(short* VD, short* VS, short* VT) { register int i; for (i = 0; i < N; i++) VACC_L[i] = VS[i] ^ VT[i]; vector_copy(VD, VACC_L); } static INLINE void VXOR(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_xor(VR[vd], VR[vs], ST); } static INLINE void VOR(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_or(VR[vd], VR[vs], ST); } static INLINE void VAND(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_and(VR[vd], VR[vs], ST); } static INLINE void VNAND(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_nand(VR[vd], VR[vs], ST); } mupen64plus-core/src/r4300/instr_counters.c000664 001750 001750 00000011372 12655644434 021637 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - instr_counters.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #if defined(COUNT_INSTR) #include #include #include "api/m64p_types.h" #include "api/callbacks.h" /* various constants */ static char instr_name[][10] = { "reserved", "NI", "J", "JAL", "BEQ", "BNE", "BLEZ", "BGTZ", "ADDI", "ADDIU", "SLTI", "SLTIU", "ANDI", "ORI", "XORI", "LUI", "BEQL", "BNEL", "BLEZL", "BGTZL", "DADDI", "DADDIU", "LDL", "LDR", "LB", "LH", "LW", "LWL", "LBU", "LHU", "LWU", "LWR", "SB", "SH", "SW", "SWL", "SWR", "SDL", "SDR", "LWC1", "LDC1", "LD", "LL", "SWC1", "SDC1", "SD", "SC", "BLTZ", "BGEZ", "BLTZL", "BGEZL", "BLTZAL", "BGEZAL", "BLTZALL", "BGEZALL", "SLL", "SRL", "SRA", "SLLV", "SRLV", "SRAV", "JR", "JALR", "SYSCALL", "MFHI", "MTHI", "MFLO", "MTLO", "DSLLV", "DSRLV", "DSRAV", "MULT", "MULTU", "DIV", "DIVU", "DMULT", "DMULTU", "DDIV", "DDIVU", "ADD", "ADDU", "SUB", "SUBU", "AND", "OR", "XOR", "NOR", "SLT", "SLTU", "DADD", "DADDU", "DSUB", "DSUBU", "DSLL", "DSRL", "DSRA", "TEQ", "DSLL32", "DSRL32", "DSRA32", "BC1F", "BC1T", "BC1FL", "BC1TL", "TLBWI", "TLBP", "TLBR", "TLBWR", "ERET", "MFC0", "MTC0", "MFC1", "DMFC1", "CFC1", "MTC1", "DMTC1", "CTC1", "f.CVT", "f.CMP", "f.ADD", "f.SUB", "f.MUL", "f.DIV", "f.SQRT", "f.ABS", "f.MOV", "f.NEG", "f.ROUND", "f.TRUNC", "f.CEIL", "f.FLOOR" }; static unsigned int instr_type[131] = { 9, 10, 6, 6, 7, 7, 7, 7, 3, 3, 4, 4, 3, 4, 4, 0, 7, 7, 7, 7, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 7, 7, 7, 7, 7, 7, 7, 7, 3, 3, 3, 3, 3, 3, 6, 6, 10, 2, 2, 2, 2, 4, 4, 4, 3, 3, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 7, 7, 7, 7, 10, 10, 10, 10, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5 }; static char instr_typename[][20] = { "Load", "Store", "Data move/convert", "32-bit math", "64-bit math", "Float Math", "Jump", "Branch", "Exceptions", "Reserved", "Other" }; /* global variable */ unsigned int instr_count[132]; /* global function */ void instr_counters_print(void) { size_t i; unsigned int iTypeCount[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned int iTotal = 0; char line[128], param[24]; DebugMessage(M64MSG_INFO, "Instruction counters:"); line[0] = 0; for (i = 0; i < 131; i++) { sprintf(param, "%8s: %08i ", instr_name[i], instr_count[i]); strcat(line, param); if (i % 5 == 4) { DebugMessage(M64MSG_INFO, "%s", line); line[0] = 0; } iTypeCount[instr_type[i]] += instr_count[i]; iTotal += instr_count[i]; } DebugMessage(M64MSG_INFO, "Instruction type summary (total instructions = %i)", iTotal); for (i = 0; i < 11; i++) { DebugMessage(M64MSG_INFO, "%20s: %04.1f%% (%i)", instr_typename[i], (float) iTypeCount[i] * 100.0 / iTotal, iTypeCount[i]); } } #endif /* COUNT_INSTR */ mupen64plus-video-gliden64/src/common/CommonAPIImpl_common.cpp000664 001750 001750 00000010015 12655644434 025373 0ustar00sergiosergio000000 000000 #ifdef OS_WINDOWS # include #else # include "../winlnxdefs.h" #endif // OS_WINDOWS #include #include "../PluginAPI.h" #include "../N64.h" #include "../GLideN64.h" #include "../OpenGL.h" #include "../RSP.h" #include "../RDP.h" #include "../VI.h" #include "../Config.h" #include "../Debug.h" #include "../Log.h" PluginAPI & PluginAPI::get() { static PluginAPI api; return api; } #ifdef RSPTHREAD void RSP_ThreadProc(std::mutex * _pRspThreadMtx, std::mutex * _pPluginThreadMtx, std::condition_variable_any * _pRspThreadCv, std::condition_variable_any * _pPluginThreadCv, API_COMMAND * _pCommand) { _pRspThreadMtx->lock(); RSP_Init(); GBI.init(); Config_LoadConfig(); video().start(); assert(!isGLError()); while (true) { _pPluginThreadMtx->lock(); _pPluginThreadCv->notify_one(); _pPluginThreadMtx->unlock(); _pRspThreadCv->wait(*_pRspThreadMtx); switch (*_pCommand) { case acProcessDList: RSP_ProcessDList(); break; case acProcessRDPList: RDP_ProcessRDPList(); break; case acUpdateScreen: VI_UpdateScreen(); break; case acRomClosed: TFH.shutdown(); video().stop(); GBI.destroy(); *_pCommand = acNone; _pRspThreadMtx->unlock(); _pPluginThreadMtx->lock(); _pPluginThreadCv->notify_one(); _pPluginThreadMtx->unlock(); return; } assert(!isGLError()); *_pCommand = acNone; } } void PluginAPI::_callAPICommand(API_COMMAND _command) { m_command = _command; m_pluginThreadMtx.lock(); m_rspThreadMtx.lock(); m_rspThreadCv.notify_one(); m_rspThreadMtx.unlock(); m_pluginThreadCv.wait(m_pluginThreadMtx); m_pluginThreadMtx.unlock(); } #endif void PluginAPI::ProcessDList() { LOG(LOG_APIFUNC, "ProcessDList\n"); #ifdef RSPTHREAD _callAPICommand(acProcessDList); #else RSP_ProcessDList(); #endif } void PluginAPI::ProcessRDPList() { LOG(LOG_APIFUNC, "ProcessRDPList\n"); #ifdef RSPTHREAD _callAPICommand(acProcessRDPList); #else RDP_ProcessRDPList(); #endif } void PluginAPI::RomClosed() { LOG(LOG_APIFUNC, "RomClosed\n"); #ifdef RSPTHREAD _callAPICommand(acRomClosed); delete m_pRspThread; m_pRspThread = NULL; #else TFH.shutdown(); video().stop(); GBI.destroy(); #endif #ifdef DEBUG CloseDebugDlg(); #endif } void PluginAPI::RomOpen() { LOG(LOG_APIFUNC, "RomOpen\n"); #ifdef RSPTHREAD m_pluginThreadMtx.lock(); m_pRspThread = new std::thread(RSP_ThreadProc, &m_rspThreadMtx, &m_pluginThreadMtx, &m_rspThreadCv, &m_pluginThreadCv, &m_command); m_pRspThread->detach(); m_pluginThreadCv.wait(m_pluginThreadMtx); m_pluginThreadMtx.unlock(); #else RSP_Init(); GBI.init(); Config_LoadConfig(); video().start(); #endif #ifdef DEBUG OpenDebugDlg(); #endif } void PluginAPI::ShowCFB() { gDP.changed |= CHANGED_CPU_FB_WRITE; } void PluginAPI::UpdateScreen() { LOG(LOG_APIFUNC, "UpdateScreen\n"); #ifdef RSPTHREAD _callAPICommand(acUpdateScreen); #else VI_UpdateScreen(); #endif } void PluginAPI::_initiateGFX(const GFX_INFO & _gfxInfo) const { HEADER = _gfxInfo.HEADER; DMEM = _gfxInfo.DMEM; IMEM = _gfxInfo.IMEM; RDRAM = _gfxInfo.RDRAM; REG.MI_INTR = _gfxInfo.MI_INTR_REG; REG.DPC_START = _gfxInfo.DPC_START_REG; REG.DPC_END = _gfxInfo.DPC_END_REG; REG.DPC_CURRENT = _gfxInfo.DPC_CURRENT_REG; REG.DPC_STATUS = _gfxInfo.DPC_STATUS_REG; REG.DPC_CLOCK = _gfxInfo.DPC_CLOCK_REG; REG.DPC_BUFBUSY = _gfxInfo.DPC_BUFBUSY_REG; REG.DPC_PIPEBUSY = _gfxInfo.DPC_PIPEBUSY_REG; REG.DPC_TMEM = _gfxInfo.DPC_TMEM_REG; REG.VI_STATUS = _gfxInfo.VI_STATUS_REG; REG.VI_ORIGIN = _gfxInfo.VI_ORIGIN_REG; REG.VI_WIDTH = _gfxInfo.VI_WIDTH_REG; REG.VI_INTR = _gfxInfo.VI_INTR_REG; REG.VI_V_CURRENT_LINE = _gfxInfo.VI_V_CURRENT_LINE_REG; REG.VI_TIMING = _gfxInfo.VI_TIMING_REG; REG.VI_V_SYNC = _gfxInfo.VI_V_SYNC_REG; REG.VI_H_SYNC = _gfxInfo.VI_H_SYNC_REG; REG.VI_LEAP = _gfxInfo.VI_LEAP_REG; REG.VI_H_START = _gfxInfo.VI_H_START_REG; REG.VI_V_START = _gfxInfo.VI_V_START_REG; REG.VI_V_BURST = _gfxInfo.VI_V_BURST_REG; REG.VI_X_SCALE = _gfxInfo.VI_X_SCALE_REG; REG.VI_Y_SCALE = _gfxInfo.VI_Y_SCALE_REG; } void PluginAPI::ChangeWindow() { video().setToggleFullscreen(); } gles2n64/src/CRC.h000664 001750 001750 00000000465 12655644434 014637 0ustar00sergiosergio000000 000000 #include "Types.h" #ifdef __cplusplus extern "C" { #endif void CRC_BuildTable(void); uint32_t CRC_Calculate(void *buffer, uint32_t count); uint32_t Hash_CalculatePalette(void *buffer, uint32_t count); uint32_t Hash_Calculate(uint32_t hash, const void *buffer, uint32_t count); #ifdef __cplusplus } #endif mupen64plus-video-gliden64/src/common/000700 001750 001750 00000000000 12656647145 020705 5ustar00sergiosergio000000 000000 gles2n64/src/RSP.h000664 001750 001750 00000001531 12655644434 014667 0ustar00sergiosergio000000 000000 #ifndef RSP_H #define RSP_H #include #include "N64.h" #include "GBI.h" //#include "gSP.h" #include "Types.h" #ifdef __cplusplus extern "C" { #endif #define RSPMSG_CLOSE 0 #define RSPMSG_UPDATESCREEN 1 #define RSPMSG_PROCESSDLIST 2 #define RSPMSG_CAPTURESCREEN 3 #define RSPMSG_DESTROYTEXTURES 4 #define RSPMSG_INITTEXTURES 5 typedef struct { u32 PC[18], PCi, busy, halt, close, DList, uc_start, uc_dstart, cmd, nextCmd; s32 count; bool bLLE; char romname[21]; } RSPInfo; extern RSPInfo __RSP; extern u32 DepthClearColor; #define RSP_SegmentToPhysical( segaddr ) ((gSP.segment[(segaddr >> 24) & 0x0F] + (segaddr & 0x00FFFFFF)) & 0x00FFFFFF) void RSP_Init(void); void RSP_ProcessDList(void); void RSP_LoadMatrix( f32 mtx[4][4], u32 address ); void RSP_CheckDLCounter(); #ifdef __cplusplus } #endif #endif gles2n64/src/CRC.c000664 001750 001750 00000003076 12655644434 014633 0ustar00sergiosergio000000 000000 #include "Types.h" #define CRC32_POLYNOMIAL 0x04C11DB7 unsigned int CRCTable[ 256 ]; uint32_t Reflect(uint32_t ref, char ch ) { int i; uint32_t value = 0; // Swap bit 0 for bit 7 // bit 1 for bit 6, etc. for (i = 1; i < (ch + 1); i++) { if(ref & 1) value |= 1 << (ch - i); ref >>= 1; } return value; } void CRC_BuildTable(void) { int i, j; uint32_t crc; for (i = 0; i < 256; i++) { crc = Reflect( i, 8 ) << 24; for (j = 0; j < 8; j++) crc = (crc << 1) ^ (crc & (1 << 31) ? CRC32_POLYNOMIAL : 0); CRCTable[i] = Reflect( crc, 32 ); } } uint32_t CRC_Calculate(void *buffer, uint32_t count) { uint8_t *p; uint32_t crc = 0xffffffff; p = (uint8_t*) buffer; while (count--) crc = (crc >> 8) ^ CRCTable[(crc & 0xFF) ^ *p++]; return ~crc; } uint32_t Hash_CalculatePalette(void *buffer, uint32_t count) { unsigned int i; uint16_t *data = (uint16_t *) buffer; uint32_t hash = 0xffffffff; count /= 4; for(i = 0; i < count; ++i) { hash += data[i << 2]; hash += (hash << 10); hash ^= (hash >> 6); } hash += (hash << 3); hash ^= (hash >> 11); hash += (hash << 15); return hash; } uint32_t Hash_Calculate(uint32_t hash, const void *buffer, uint32_t count) { unsigned int i; const uint32_t *data = (const uint32_t *)buffer; count /= 4; for(i = 0; i < count; ++i) { hash += data[i]; hash += (hash << 10); hash ^= (hash >> 6); } hash += (hash << 3); hash ^= (hash >> 11); hash += (hash << 15); return hash; } mupen64plus-core/src/api/m64p_config.h000664 001750 001750 00000023776 12655644434 020712 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-core - m64p_config.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2009 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This header file defines typedefs for function pointers to the Core's * configuration handling functions. */ #ifndef M64P_CONFIG_H #define M64P_CONFIG_H #include "m64p_types.h" #ifdef __cplusplus extern "C" { #endif /* ConfigListSections() * * This function is called to enumerate the list of Sections in the Mupen64Plus * configuration file. It is expected that there will be a section named "Core" * for core-specific configuration data, "Graphics" for common graphics options, * and one or more sections for each plugin library. */ typedef m64p_error (*ptr_ConfigListSections)(void *, void (*)(void *, const char *)); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL ConfigListSections(void *, void (*)(void *, const char *)); #endif /* ConfigOpenSection() * * This function is used to give a configuration section handle to the front-end * which may be used to read or write configuration parameter values in a given * section of the configuration file. */ typedef m64p_error (*ptr_ConfigOpenSection)(const char *, m64p_handle *); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL ConfigOpenSection(const char *, m64p_handle *); #endif /* ConfigListParameters() * * This function is called to enumerate the list of Parameters in a given * Section of the Mupen64Plus configuration file. */ typedef m64p_error (*ptr_ConfigListParameters)(m64p_handle, void *, void (*)(void *, const char *, m64p_type)); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL ConfigListParameters(m64p_handle, void *, void (*)(void *, const char *, m64p_type)); #endif /* ConfigSaveFile() * * This function saves the entire current Mupen64Plus configuration to disk. */ typedef m64p_error (*ptr_ConfigSaveFile)(void); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL ConfigSaveFile(void); #endif /* ConfigSaveSection() * * This function saves one section of the current Mupen64Plus configuration to disk. */ typedef m64p_error (*ptr_ConfigSaveSection)(const char *); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL ConfigSaveSection(const char *); #endif /* ConfigHasUnsavedChanges() * * This function determines if a given Section (or all sections) of the Mupen64Plus Core configuration file has been modified since it was last saved or loaded. */ typedef int (*ptr_ConfigHasUnsavedChanges)(const char *); #if defined(M64P_CORE_PROTOTYPES) EXPORT int CALL ConfigHasUnsavedChanges(const char *); #endif /* ConfigDeleteSection() * * This function deletes a section from the Mupen64Plus configuration data. */ typedef m64p_error (*ptr_ConfigDeleteSection)(const char *SectionName); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL ConfigDeleteSection(const char *SectionName); #endif /* ConfigRevertChanges() * * This function reverts changes previously made to one section of the configuration file, so that it will match with the configuration at the last time that it was loaded from or saved to disk. */ typedef m64p_error (*ptr_ConfigRevertChanges)(const char *SectionName); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL ConfigRevertChanges(const char *SectionName); #endif /* ConfigSetParameter() * * This function sets the value of one of the emulator's configuration * parameters. */ typedef m64p_error (*ptr_ConfigSetParameter)(m64p_handle, const char *, m64p_type, const void *); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL ConfigSetParameter(m64p_handle, const char *, m64p_type, const void *); #endif /* ConfigGetParameter() * * This function retrieves the value of one of the emulator's parameters. */ typedef m64p_error (*ptr_ConfigGetParameter)(m64p_handle, const char *, m64p_type, void *, int); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL ConfigGetParameter(m64p_handle, const char *, m64p_type, void *, int); #endif /* ConfigGetParameterType() * * This function retrieves the type of one of the emulator's parameters. */ typedef m64p_error (*ptr_ConfigGetParameterType)(m64p_handle, const char *, m64p_type *); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL ConfigGetParameterType(m64p_handle, const char *, m64p_type *); #endif /* ConfigGetParameterHelp() * * This function retrieves the help information about one of the emulator's * parameters. */ typedef const char * (*ptr_ConfigGetParameterHelp)(m64p_handle, const char *); #if defined(M64P_CORE_PROTOTYPES) EXPORT const char * CALL ConfigGetParameterHelp(m64p_handle, const char *); #endif /* ConfigSetDefault***() * * These functions are used to set the value of a configuration parameter if it * is not already present in the configuration file. This may happen if a new * user runs the emulator, or an upgraded module uses a new parameter, or the * user deletes his or her configuration file. If the parameter is already * present in the given section of the configuration file, then no action will * be taken and this function will return successfully. */ typedef m64p_error (*ptr_ConfigSetDefaultInt)(m64p_handle, const char *, int, const char *); typedef m64p_error (*ptr_ConfigSetDefaultFloat)(m64p_handle, const char *, float, const char *); typedef m64p_error (*ptr_ConfigSetDefaultBool)(m64p_handle, const char *, int, const char *); typedef m64p_error (*ptr_ConfigSetDefaultString)(m64p_handle, const char *, const char *, const char *); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL ConfigSetDefaultInt(m64p_handle, const char *, int, const char *); EXPORT m64p_error CALL ConfigSetDefaultFloat(m64p_handle, const char *, float, const char *); EXPORT m64p_error CALL ConfigSetDefaultBool(m64p_handle, const char *, int, const char *); EXPORT m64p_error CALL ConfigSetDefaultString(m64p_handle, const char *, const char *, const char *); #endif /* ConfigGetParam***() * * These functions retrieve the value of one of the emulator's parameters in * the given section, and return the value directly to the calling function. If * an errors occurs (such as an invalid Section handle, or invalid * configuration parameter name), then an error will be sent to the front-end * via the DebugCallback() function, and either a 0 (zero) or an empty string * will be returned. */ typedef int (*ptr_ConfigGetParamInt)(m64p_handle, const char *); typedef float (*ptr_ConfigGetParamFloat)(m64p_handle, const char *); typedef int (*ptr_ConfigGetParamBool)(m64p_handle, const char *); typedef const char * (*ptr_ConfigGetParamString)(m64p_handle, const char *); #if defined(M64P_CORE_PROTOTYPES) EXPORT int CALL ConfigGetParamInt(m64p_handle, const char *); EXPORT float CALL ConfigGetParamFloat(m64p_handle, const char *); EXPORT int CALL ConfigGetParamBool(m64p_handle, const char *); EXPORT const char * CALL ConfigGetParamString(m64p_handle, const char *); #endif /* ConfigGetSharedDataFilepath() * * This function is provided to allow a plugin to retrieve a full pathname to a * given shared data file. This type of file is intended to be shared among * multiple users on a system, so it is likely to be read-only. */ typedef const char * (*ptr_ConfigGetSharedDataFilepath)(const char *); #if defined(M64P_CORE_PROTOTYPES) EXPORT const char * CALL ConfigGetSharedDataFilepath(const char *); #endif /* ConfigGetUserConfigPath() * * This function may be used by the plugins or front-end to get a path to the * directory for storing user-specific configuration files. This will be the * directory where "mupen64plus.cfg" is located. */ typedef const char * (*ptr_ConfigGetUserConfigPath)(void); #if defined(M64P_CORE_PROTOTYPES) EXPORT const char * CALL ConfigGetUserConfigPath(void); #endif /* ConfigGetUserDataPath() * * This function may be used by the plugins or front-end to get a path to the * directory for storing user-specific data files. This may be used to store * files such as screenshots, saved game states, or hi-res textures. */ typedef const char * (*ptr_ConfigGetUserDataPath)(void); #if defined(M64P_CORE_PROTOTYPES) EXPORT const char * CALL ConfigGetUserDataPath(void); #endif /* ConfigGetUserCachePath() * * This function may be used by the plugins or front-end to get a path to the * directory for storing cached user-specific data files. Files in this * directory may be deleted by the user to save space, so critical information * should not be stored here. This directory may be used to store files such * as the ROM browser cache. */ typedef const char * (*ptr_ConfigGetUserCachePath)(void); #if defined(M64P_CORE_PROTOTYPES) EXPORT const char * CALL ConfigGetUserCachePath(void); #endif #ifdef __cplusplus } #endif #endif /* #define M64P_CONFIG_H */ Makefile.common000664 001750 001750 00000025002 12655644434 014645 0ustar00sergiosergio000000 000000 RSPDIR = $(ROOT_DIR)/mupen64plus-rsp-hle CXD4DIR = $(ROOT_DIR)/mupen64plus-rsp-cxd4 CORE_DIR = $(ROOT_DIR)/mupen64plus-core LIBRETRO_COMM_DIR = $(ROOT_DIR)/libretro-common AUDIO_LIBRETRO_DIR = $(CORE_DIR)/src/plugin/audio_libretro VIDEODIR_RICE = $(ROOT_DIR)/gles2rice/src VIDEODIR_GLN64 = $(ROOT_DIR)/gles2n64/src VIDEODIR_ANGRYLION = $(ROOT_DIR)/mupen64plus-video-angrylion VIDEODIR_GLIDE = $(ROOT_DIR)/glide2gl/src VIDEODIR_GLIDEN64 = $(ROOT_DIR)/mupen64plus-video-gliden64 DYNAREC_USED := 0 INCFLAGS += \ -I$(CORE_DIR)/src \ -I$(CORE_DIR)/src/api \ -I$(AUDIO_LIBRETRO_DIR) \ -I$(VIDEODIR_GLIDE)/Glitch64/inc \ -I$(LIBRETRO_COMM_DIR)/include \ -I$(LIBRETRO_DIR) # libco SOURCES_C += $(LIBRETRO_COMM_DIR)/libco/libco.c SOURCES_C += $(RSPDIR)/src/alist.c \ $(RSPDIR)/src/alist_audio.c \ $(RSPDIR)/src/alist_naudio.c \ $(RSPDIR)/src/alist_nead.c \ $(RSPDIR)/src/audio.c \ $(RSPDIR)/src/cicx105.c \ $(RSPDIR)/src/hle.c \ $(RSPDIR)/src/jpeg.c \ $(RSPDIR)/src/hle_memory.c \ $(RSPDIR)/src/mp3.c \ $(RSPDIR)/src/musyx.c \ $(RSPDIR)/src/hle_plugin.c SOURCES_C += $(CXD4DIR)/rsp.c # Core SOURCES_C += \ $(CORE_DIR)/src/api/callbacks.c \ $(CORE_DIR)/src/api/common.c \ $(CORE_DIR)/src/api/config.c \ $(CORE_DIR)/src/api/frontend.c \ $(CORE_DIR)/src/api/vidext_libretro.c \ $(CORE_DIR)/src/main/cheat.c \ $(CORE_DIR)/src/main/eventloop.c \ $(CORE_DIR)/src/main/main.c \ $(CORE_DIR)/src/main/profile.c \ $(CORE_DIR)/src/main/md5.c \ $(CORE_DIR)/src/main/rom.c \ $(CORE_DIR)/src/main/savestates.c \ $(CORE_DIR)/src/main/util.c \ $(CORE_DIR)/src/memory/m64p_memory.c \ $(CORE_DIR)/src/si/n64_cic_nus_6105.c \ $(CORE_DIR)/src/si/pif.c \ $(CORE_DIR)/src/si/af_rtc.c \ $(CORE_DIR)/src/si/cic.c \ $(CORE_DIR)/src/si/eeprom.c \ $(CORE_DIR)/src/si/game_controller.c \ $(CORE_DIR)/src/si/mempak.c \ $(CORE_DIR)/src/si/rumblepak.c \ $(CORE_DIR)/src/plugin/plugin.c \ $(CORE_DIR)/src/plugin/get_time_using_C_localtime.c \ $(CORE_DIR)/src/plugin/rumble_via_input_plugin.c \ $(CORE_DIR)/src/r4300/mi_controller.c \ $(CORE_DIR)/src/r4300/profile.c \ $(CORE_DIR)/src/r4300/recomp.c \ $(CORE_DIR)/src/r4300/exception.c \ $(CORE_DIR)/src/r4300/cached_interp.c \ $(CORE_DIR)/src/r4300/pure_interp.c \ $(CORE_DIR)/src/r4300/reset.c \ $(CORE_DIR)/src/dd/dd_controller.c \ $(CORE_DIR)/src/dd/dd_rom.c \ $(CORE_DIR)/src/dd/dd_disk.c \ $(CORE_DIR)/src/ri/ri_controller.c \ $(CORE_DIR)/src/ri/rdram.c \ $(CORE_DIR)/src/ri/rdram_detection_hack.c \ $(CORE_DIR)/src/si/si_controller.c \ $(CORE_DIR)/src/vi/vi_controller.c \ $(CORE_DIR)/src/rdp/rdp_core.c \ $(CORE_DIR)/src/rdp/fb.c \ $(CORE_DIR)/src/rdp_common/gdp.c \ $(CORE_DIR)/src/rsp/rsp_core.c \ $(CORE_DIR)/src/ai/ai_controller.c \ $(CORE_DIR)/src/pi/pi_controller.c \ $(CORE_DIR)/src/pi/sram.c \ $(CORE_DIR)/src/pi/flashram.c \ $(CORE_DIR)/src/pi/cart_rom.c \ $(CORE_DIR)/src/r4300/interupt.c \ $(CORE_DIR)/src/r4300/tlb.c \ $(CORE_DIR)/src/r4300/cp0.c \ $(CORE_DIR)/src/r4300/cp1.c \ $(CORE_DIR)/src/r4300/r4300_core.c \ $(CORE_DIR)/src/r4300/r4300.c # $(CORE_DIR)/src/api/debugger.c \ # $(CORE_DIR)/src/main/ini_reader.c \ ### DYNAREC ### ifdef WITH_DYNAREC ifeq ($(WITH_DYNAREC), arm) DYNAFLAGS += -DNEW_DYNAREC=3 endif ifeq ($(WITH_DYNAREC), x86) DYNAFLAGS += -D_M_IX86 endif ifeq ($(WITH_DYNAREC), x86_64) DYNAFLAGS += -D_M_X64 endif ifeq ($(WITH_DYNAREC), arm) DYNAREC_USED = 1 SOURCES_C += $(CORE_DIR)/src/r4300/new_dynarec/new_dynarec.c \ $(CORE_DIR)/src/r4300/empty_dynarec.c \ $(CORE_DIR)/src/r4300/instr_counters.c SOURCES_ASM += \ $(CORE_DIR)/src/r4300/new_dynarec/linkage_$(WITH_DYNAREC).S endif ifeq ($(WITH_DYNAREC), $(filter $(WITH_DYNAREC), i386 i686 x86 x86_64 x64)) DYNAREC_USED = 1 CPUFLAGS += -msse -msse2 -DUSE_MMX_DECODES -DUSE_SSE_SUPPORT SOURCES_C += $(CORE_DIR)/src/r4300/hacktarux_dynarec/assemble.c \ $(CORE_DIR)/src/r4300/hacktarux_dynarec/gbc.c \ $(CORE_DIR)/src/r4300/hacktarux_dynarec/gtlb.c \ $(CORE_DIR)/src/r4300/hacktarux_dynarec/gcop0.c \ $(CORE_DIR)/src/r4300/hacktarux_dynarec/gcop1.c \ $(CORE_DIR)/src/r4300/hacktarux_dynarec/gcop1_d.c \ $(CORE_DIR)/src/r4300/hacktarux_dynarec/gcop1_l.c \ $(CORE_DIR)/src/r4300/hacktarux_dynarec/gcop1_s.c \ $(CORE_DIR)/src/r4300/hacktarux_dynarec/gcop1_w.c \ $(CORE_DIR)/src/r4300/hacktarux_dynarec/gr4300.c \ $(CORE_DIR)/src/r4300/hacktarux_dynarec/grspecial.c \ $(CORE_DIR)/src/r4300/hacktarux_dynarec/gregimm.c \ $(CORE_DIR)/src/r4300/hacktarux_dynarec/regcache.c \ $(CORE_DIR)/src/r4300/hacktarux_dynarec/rjump.c endif ifeq ($(DYNAREC_USED), 0) SOURCES_C += $(CORE_DIR)/src/r4300/empty_dynarec.c else DYNAFLAGS += -DDYNAREC endif endif ### VIDEO PLUGINS ### # Rice SOURCES_CXX += $(VIDEODIR_RICE)/Blender.cpp \ $(VIDEODIR_RICE)/Combiner.cpp \ $(VIDEODIR_RICE)/RiceConfig.cpp \ $(VIDEODIR_RICE)/ConvertImage16.cpp \ $(VIDEODIR_RICE)/ConvertImage.cpp \ $(VIDEODIR_RICE)/RiceDebugger.cpp \ $(VIDEODIR_RICE)/DecodedMux.cpp \ $(VIDEODIR_RICE)/DeviceBuilder.cpp \ $(VIDEODIR_RICE)/FrameBuffer.cpp \ $(VIDEODIR_RICE)/GraphicsContext.cpp \ $(VIDEODIR_RICE)/OGLCombiner.cpp \ $(VIDEODIR_RICE)/OGLDecodedMux.cpp \ $(VIDEODIR_RICE)/OGLES2FragmentShaders.cpp \ $(VIDEODIR_RICE)/OGLExtCombiner.cpp \ $(VIDEODIR_RICE)/OGLExtRender.cpp \ $(VIDEODIR_RICE)/OGLGraphicsContext.cpp \ $(VIDEODIR_RICE)/OGLRender.cpp \ $(VIDEODIR_RICE)/OGLRenderExt.cpp \ $(VIDEODIR_RICE)/OGLTexture.cpp \ $(VIDEODIR_RICE)/RenderBase.cpp \ $(VIDEODIR_RICE)/Render.cpp \ $(VIDEODIR_RICE)/RenderExt.cpp \ $(VIDEODIR_RICE)/RenderTexture.cpp \ $(VIDEODIR_RICE)/RSP_Parser.cpp \ $(VIDEODIR_RICE)/RSP_S2DEX.cpp \ $(VIDEODIR_RICE)/Texture.cpp \ $(VIDEODIR_RICE)/TextureManager.cpp \ $(VIDEODIR_RICE)/VectorMath.cpp \ $(VIDEODIR_RICE)/Video.cpp ifeq ($(HAVE_NEON), 1) SOURCES_ASM += $(VIDEODIR_RICE)/RenderBase_neon.S endif # Libretro SOURCES_C += $(LIBRETRO_DIR)/libretro.c \ $(LIBRETRO_DIR)/opengl_state_machine.c \ $(CORE_DIR)/src/plugin/emulate_game_controller_via_libretro.c \ $(AUDIO_LIBRETRO_DIR)/audio_backend_libretro.c \ $(AUDIO_LIBRETRO_DIR)/audio_resampler_driver.c \ $(AUDIO_LIBRETRO_DIR)/drivers_resampler/sinc.c \ $(AUDIO_LIBRETRO_DIR)/drivers_resampler/nearest.c \ $(AUDIO_LIBRETRO_DIR)/drivers_resampler/cc_resampler.c \ $(AUDIO_LIBRETRO_DIR)/audio_utils.c ifeq ($(WITH_CRC),brumme) SOURCES_C += $(LIBRETRO_DIR)/brumme_crc.c else SOURCES_C += $(LIBRETRO_DIR)/libretro_crc.c endif ifeq ($(GLIDEN64), 1) #SOURCES_CXX += $(VIDEODIR_GLIDEN64)/src/3DMath.cpp \ $(VIDEODIR_GLIDEN64)/src/Combiner.cpp SOURCES_CXX += $(VIDEODIR_GLIDEN64)/src/CRC.cpp #SOURCES_CXX += $(VIDEODIR_GLIDEN64)/src/DepthBuffer.cpp SOURCES_CXX += $(VIDEODIR_GLIDEN64)/src/F3D.cpp \ $(VIDEODIR_GLIDEN64)/src/F3DDKR.cpp \ $(VIDEODIR_GLIDEN64)/src/F3DEX.cpp \ $(VIDEODIR_GLIDEN64)/src/F3DPD.cpp \ $(VIDEODIR_GLIDEN64)/src/F3DSWSE.cpp \ $(VIDEODIR_GLIDEN64)/src/F3DWRUS.cpp #SOURCES_CXX += $(VIDEODIR_GLIDEN64)/src/FrameBuffer.cpp #SOURCES_CXX += $(VIDEODIR_GLIDEN64)/src/F3DEX2.cpp #SOURCES_CXX += $(VIDEODIR_GLIDEN64)/src/F3DEX2CBFD.cpp #SOURCES_CXX += $(VIDEODIR_GLIDEN64)/src/ZSort.cpp #SOURCES_CXX += $(VIDEODIR_GLIDEN64)/src/VI.cpp else SOURCES_C += $(VIDEODIR_GLN64)/3DMath.c \ $(VIDEODIR_GLN64)/glN64Config.c \ $(VIDEODIR_GLN64)/FrameBuffer.c \ $(VIDEODIR_GLN64)/Hash.c \ $(VIDEODIR_GLN64)/DepthBuffer.c \ $(VIDEODIR_GLN64)/F3DEX2CBFD.c \ $(VIDEODIR_GLN64)/F3D.c \ $(VIDEODIR_GLN64)/F3DDKR.c \ $(VIDEODIR_GLN64)/F3DEX2.c \ $(VIDEODIR_GLN64)/F3DEX.c \ $(VIDEODIR_GLN64)/F3DPD.c \ $(VIDEODIR_GLN64)/F3DSWSE.c \ $(VIDEODIR_GLN64)/F3DWRUS.c \ $(VIDEODIR_GLN64)/GBI.c \ $(VIDEODIR_GLN64)/gDP.c \ $(VIDEODIR_GLN64)/gles2N64.c \ $(VIDEODIR_GLN64)/gSP.c \ $(VIDEODIR_GLN64)/L3D.c \ $(VIDEODIR_GLN64)/L3DEX2.c \ $(VIDEODIR_GLN64)/L3DEX.c \ $(VIDEODIR_GLN64)/N64.c \ $(VIDEODIR_GLN64)/OpenGL.c \ $(VIDEODIR_GLN64)/RDP.c \ $(VIDEODIR_GLN64)/gles2n64_rsp.c \ $(VIDEODIR_GLN64)/S2DEX2.c \ $(VIDEODIR_GLN64)/S2DEX.c \ $(VIDEODIR_GLN64)/ShaderCombiner.c \ $(VIDEODIR_GLN64)/Textures.c \ $(VIDEODIR_GLN64)/Turbo3D.c \ $(VIDEODIR_GLN64)/ZSort.c \ $(VIDEODIR_GLN64)/VI.c ifeq ($(HAVE_NEON), 1) SOURCES_C += $(VIDEODIR_GLN64)/3DMathNeon.c endif endif ifeq ($(HAVE_NEON), 1) SOURCES_ASM += $(AUDIO_LIBRETRO_DIR)/audio_utils_neon.S \ $(AUDIO_LIBRETRO_DIR)/drivers_resampler/sinc_neon.S \ $(AUDIO_LIBRETRO_DIR)/drivers_resampler/cc_resampler_neon.S endif #Glide 64 SOURCES_C += $(VIDEODIR_GLIDE)/Glide64/glide64_3dmath.c \ $(VIDEODIR_GLIDE)/Glide64/FBtoScreen.c \ $(VIDEODIR_GLIDE)/Glide64/Glide64_Ini.c \ $(VIDEODIR_GLIDE)/Glide64/glidemain.c \ $(VIDEODIR_GLIDE)/Glide64/glide64_util.c \ $(VIDEODIR_GLIDE)/Glide64/Glide64_UCode.c \ $(VIDEODIR_GLIDE)/Glide64/glide64_rdp.c \ $(VIDEODIR_GLIDE)/Glide64/Combine.c \ $(VIDEODIR_GLIDE)/Glide64/DepthBufferRender.c \ $(VIDEODIR_GLIDE)/Glide64/TexCache.c \ $(VIDEODIR_GLIDE)/Glide64/MiClWr.c \ $(VIDEODIR_GLIDE)/Glide64/TexLoad.c # Glitch64 SOURCES_C += $(VIDEODIR_GLIDE)/Glitch64/glitch64_combiner.c \ $(VIDEODIR_GLIDE)/Glitch64/geometry.c \ $(VIDEODIR_GLIDE)/Glitch64/glitchmain.c \ $(VIDEODIR_GLIDE)/Glitch64/glitch64_textures.c ### Angrylion's renderer ### SOURCES_C += $(VIDEODIR_ANGRYLION)/n64video_main.c \ $(VIDEODIR_ANGRYLION)/n64video_vi.c \ $(VIDEODIR_ANGRYLION)/n64video_rdp.c \ $(VIDEODIR_ANGRYLION)/n64video.c ifeq ($(GLES), 1) GLFLAGS += -DGLES -DHAVE_OPENGLES2 -DDISABLE_3POINT -DUSE_GLES SOURCES_C += $(LIBRETRO_COMM_DIR)/glsym/glsym_es2.c else #Texture sampling enhancements. GLFLAGS += -DENABLE_3POINT -DENABLE_TEXTURE_SAMPLING GLFLAGS += -DHAVE_OPENGL SOURCES_C += $(LIBRETRO_COMM_DIR)/glsym/glsym_gl.c endif SOURCES_C += $(LIBRETRO_COMM_DIR)/glsym/rglgen.c gles2rice/src/Render.cpp000664 001750 001750 00000156641 12655644434 016325 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define M64P_PLUGIN_PROTOTYPES 1 #include #include "osal_preproc.h" #include "m64p_plugin.h" #include "ConvertImage.h" #include "DeviceBuilder.h" #include "FrameBuffer.h" #include "Render.h" #include extern FiddledVtx * g_pVtxBase; CRender * CRender::g_pRender=NULL; int CRender::gRenderReferenceCount=0; XMATRIX reverseXY(-1,0,0,0,0,-1,0,0,0,0,1,0,0,0,0,1); XMATRIX reverseY(1,0,0,0,0,-1,0,0,0,0,1,0,0,0,0,1); extern char* right (const char * src, int nchars); #if defined(WIN32) #define strcasecmp _stricmp #endif #ifdef min #undef min #endif #ifdef max #undef max #endif //======================================================================== CRender * CRender::GetRender(void) { return CRender::g_pRender; } bool CRender::IsAvailable() { return CRender::g_pRender != NULL; } CRender::CRender() : m_fScreenViewportMultX(2.0f), m_fScreenViewportMultY(2.0f), m_dwTexturePerspective(FALSE), m_bAlphaTestEnable(FALSE), m_bZUpdate(FALSE), m_bZCompare(FALSE), m_dwZBias(0), m_dwMinFilter(FILTER_POINT), m_dwMagFilter(FILTER_POINT), m_dwAlpha(0xFF), m_Mux(0), m_bBlendModeValid(FALSE) { InitRenderBase(); for( int i=0; iCreateColorCombiner(this); m_pColorCombiner->Initialize(); m_pAlphaBlender = CDeviceBuilder::GetBuilder()->CreateAlphaBlender(this); } CRender::~CRender() { if( m_pColorCombiner != NULL ) { CDeviceBuilder::GetBuilder()->DeleteColorCombiner(); m_pColorCombiner = NULL; } if( m_pAlphaBlender != NULL ) { CDeviceBuilder::GetBuilder()->DeleteAlphaBlender(); m_pAlphaBlender = NULL; } } void CRender::ResetMatrices() { Matrix mat; mat.m[0][1] = mat.m[0][2] = mat.m[0][3] = mat.m[1][0] = mat.m[1][2] = mat.m[1][3] = mat.m[2][0] = mat.m[2][1] = mat.m[2][3] = mat.m[3][0] = mat.m[3][1] = mat.m[3][2] = 0.0f; mat.m[0][0] = mat.m[1][1] = mat.m[2][2] = mat.m[3][3] = 1.0f; gRSP.projectionMtxTop = 0; gRSP.modelViewMtxTop = 0; gRSP.projectionMtxs[0] = mat; gRSP.modelviewMtxs[0] = mat; gRSP.bMatrixIsUpdated = true; gRSP.bWorldMatrixIsUpdated = true; UpdateCombinedMatrix(); } void CRender::SetProjection(const Matrix & mat, bool bPush, bool bReplace) { if (bPush) { if (gRSP.projectionMtxTop >= (RICE_MATRIX_STACK-1)) { TRACE0("Pushing past proj stack limits!"); } else gRSP.projectionMtxTop++; if (bReplace) { // Load projection matrix gRSP.projectionMtxs[gRSP.projectionMtxTop] = mat; } else { gRSP.projectionMtxs[gRSP.projectionMtxTop] = mat * gRSP.projectionMtxs[gRSP.projectionMtxTop-1]; } } else { if (bReplace) { // Load projection matrix gRSP.projectionMtxs[gRSP.projectionMtxTop] = mat; } else { gRSP.projectionMtxs[gRSP.projectionMtxTop] = mat * gRSP.projectionMtxs[gRSP.projectionMtxTop]; } } gRSP.bMatrixIsUpdated = true; DumpMatrix(mat,"Set Projection Matrix"); } bool mtxPopUpError = false; void CRender::SetWorldView(const Matrix & mat, bool bPush, bool bReplace) { if (bPush) { if (gRSP.modelViewMtxTop >= (RICE_MATRIX_STACK-1)) DebuggerAppendMsg("Pushing past modelview stack limits! %s", bReplace?"Load":"Mul"); else gRSP.modelViewMtxTop++; // We should store the current projection matrix... if (bReplace) { // Load projection matrix gRSP.modelviewMtxs[gRSP.modelViewMtxTop] = mat; //GSI: Hack needed to show heart in OOT & MM //it renders at Z coordinate = 0.0f that gets clipped away. //so we translate them a bit along Z to make them stick if( options.enableHackForGames == HACK_FOR_ZELDA || options.enableHackForGames == HACK_FOR_ZELDA_MM) { if(gRSP.modelviewMtxs[gRSP.modelViewMtxTop]._43 == 0.0f && gRSP.modelviewMtxs[gRSP.modelViewMtxTop]._42 != 0.0f && gRSP.modelviewMtxs[gRSP.modelViewMtxTop]._42 <= 94.5f && gRSP.modelviewMtxs[gRSP.modelViewMtxTop]._42 >= -94.5f) { gRSP.modelviewMtxs[gRSP.modelViewMtxTop]._43 -= 10.1f; } } } else // Multiply projection matrix { gRSP.modelviewMtxs[gRSP.modelViewMtxTop] = mat * gRSP.modelviewMtxs[gRSP.modelViewMtxTop-1]; } } else // NoPush { if (bReplace) { // Load projection matrix gRSP.modelviewMtxs[gRSP.modelViewMtxTop] = mat; } else { // Multiply projection matrix gRSP.modelviewMtxs[gRSP.modelViewMtxTop] = mat * gRSP.modelviewMtxs[gRSP.modelViewMtxTop]; } } gRSPmodelViewTop = gRSP.modelviewMtxs[gRSP.modelViewMtxTop]; if( options.enableHackForGames == HACK_REVERSE_XY_COOR ) { gRSPmodelViewTop = gRSPmodelViewTop * reverseXY; } if( options.enableHackForGames == HACK_REVERSE_Y_COOR ) { gRSPmodelViewTop = gRSPmodelViewTop * reverseY; } MatrixTranspose(&gRSPmodelViewTopTranspose, &gRSPmodelViewTop); gRSP.bMatrixIsUpdated = true; gRSP.bWorldMatrixIsUpdated = true; DumpMatrix(mat,"Set WorldView Matrix"); } void CRender::PopWorldView() { if (gRSP.modelViewMtxTop > 0) { gRSP.modelViewMtxTop--; gRSPmodelViewTop = gRSP.modelviewMtxs[gRSP.modelViewMtxTop]; if( options.enableHackForGames == HACK_REVERSE_XY_COOR ) { gRSPmodelViewTop = gRSPmodelViewTop * reverseXY; } if( options.enableHackForGames == HACK_REVERSE_Y_COOR ) { gRSPmodelViewTop = gRSPmodelViewTop * reverseY; } MatrixTranspose(&gRSPmodelViewTopTranspose, &gRSPmodelViewTop); gRSP.bMatrixIsUpdated = true; gRSP.bWorldMatrixIsUpdated = true; } else { #ifdef DEBUGGER if( pauseAtNext ) TRACE0("Popping past worldview stack limits"); #endif mtxPopUpError = true; } } Matrix & CRender::GetWorldProjectMatrix(void) { return gRSPworldProject; } void CRender::SetWorldProjectMatrix(Matrix &mtx) { #ifdef DEBUGGER if( pauseAtNext && (eventToPause == NEXT_TRIANGLE || eventToPause == NEXT_FLUSH_TRI || eventToPause == NEXT_MATRIX_CMD ) ) { uint32_t dwPC = gDlistStack[gDlistStackPointer].pc-8; DebuggerAppendMsg("Force Matrix: pc=%08X", dwPC); DumpMatrix(mtx, "Force Matrix, loading new world-project matrix"); } #endif gRSPworldProject = mtx; gRSP.bMatrixIsUpdated = false; gRSP.bCombinedMatrixIsUpdated = true; } void CRender::SetMux(uint32_t dwMux0, uint32_t dwMux1) { uint64_t tempmux = (((uint64_t)dwMux0) << 32) | (uint64_t)dwMux1; if( m_Mux != tempmux ) { m_Mux = tempmux; m_bBlendModeValid = FALSE; m_pColorCombiner->UpdateCombiner(dwMux0, dwMux1); } } void CRender::SetCombinerAndBlender() { InitOtherModes(); if( g_curRomInfo.bDisableBlender ) m_pAlphaBlender->DisableAlphaBlender(); else if( currentRomOptions.bNormalBlender ) m_pAlphaBlender->NormalAlphaBlender(); else m_pAlphaBlender->InitBlenderMode(); m_pColorCombiner->InitCombinerMode(); } void CRender::RenderReset() { UpdateClipRectangle(); ResetMatrices(); SetZBias(0); gRSP.numVertices = 0; gRSP.maxVertexID = 0; gRSP.curTile = 0; gRSP.fTexScaleX = 1/32.0f;; gRSP.fTexScaleY = 1/32.0f; } bool CRender::FillRect(int nX0, int nY0, int nX1, int nY1, uint32_t dwColor) { LOG_UCODE("FillRect: X0=%d, Y0=%d, X1=%d, Y1=%d, Color=0x%8X", nX0, nY0, nX1, nY1, dwColor); if (g_CI.dwSize != TXT_SIZE_16b && frameBufferOptions.bIgnore) return true; if (status.bHandleN64RenderTexture && !status.bDirectWriteIntoRDRAM) status.bFrameBufferIsDrawn = true; if(status.bVIOriginIsUpdated == true && currentRomOptions.screenUpdateSetting==SCREEN_UPDATE_AT_1ST_PRIMITIVE) { status.bVIOriginIsUpdated=false; CGraphicsContext::Get()->UpdateFrame(false); DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_SET_CIMG, {DebuggerAppendMsg("Screen Update at 1st FillRectangle");}); } if (status.bCIBufferIsRendered && status.bVIOriginIsUpdated == true && currentRomOptions.screenUpdateSetting==SCREEN_UPDATE_BEFORE_SCREEN_CLEAR ) { if ((nX0==0 && nY0 == 0 && (nX1 == (int) g_CI.dwWidth || nX1 == (int) g_CI.dwWidth-1)) || (nX0==gRDP.scissor.left && nY0 == gRDP.scissor.top && (nX1 == gRDP.scissor.right || nX1 == gRDP.scissor.right-1)) || ((nX0+nX1 == (int)g_CI.dwWidth || nX0+nX1 == (int)g_CI.dwWidth-1 || nX0+nX1 == gRDP.scissor.left+gRDP.scissor.right || nX0+nX1 == gRDP.scissor.left+gRDP.scissor.right-1) && (nY0 == gRDP.scissor.top || nY0 == 0 || nY0+nY1 == gRDP.scissor.top+gRDP.scissor.bottom || nY0+nY1 == gRDP.scissor.top+gRDP.scissor.bottom-1))) { status.bVIOriginIsUpdated=false; CGraphicsContext::Get()->UpdateFrame(false); DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_SET_CIMG,{DebuggerAppendMsg("Screen Update Before Screen Clear");}); } } SetFillMode(RICE_FILLMODE_SOLID); bool res=true; /* // I don't know why this does not work for OpenGL if( gRDP.otherMode.cycle_type == CYCLE_TYPE_FILL && nX0 == 0 && nY0 == 0 && ((nX1==windowSetting.uViWidth && nY1==windowSetting.uViHeight)||(nX1==windowSetting.uViWidth-1 && nY1==windowSetting.uViHeight-1)) ) { CGraphicsContext::g_pGraphicsContext->Clear(CLEAR_COLOR_BUFFER,dwColor, 0xFF000000, 1.0f); } else */ { //bool m_savedZBufferFlag = gRSP.bZBufferEnabled; // Save ZBuffer state ZBufferEnable( FALSE ); m_fillRectVtx[0].x = ViewPortTranslatei_x(nX0); m_fillRectVtx[0].y = ViewPortTranslatei_y(nY0); m_fillRectVtx[1].x = ViewPortTranslatei_x(nX1); m_fillRectVtx[1].y = ViewPortTranslatei_y(nY1); SetCombinerAndBlender(); if( gRDP.otherMode.cycle_type >= CYCLE_TYPE_COPY ) { ZBufferEnable(FALSE); } else { //dwColor = PostProcessDiffuseColor(0); dwColor = PostProcessDiffuseColor(gRDP.primitiveColor); } float depth = (gRDP.otherMode.depth_source == 1 ? gRDP.fPrimitiveDepth : 0 ); ApplyRDPScissor(false); TurnFogOnOff(false); res = RenderFillRect(dwColor, depth); TurnFogOnOff(gRSP.bFogEnabled); if( gRDP.otherMode.cycle_type >= CYCLE_TYPE_COPY ) { ZBufferEnable(gRSP.bZBufferEnabled); } } if( options.bWinFrameMode ) SetFillMode(RICE_FILLMODE_WINFRAME); DEBUGGER_PAUSE_AND_DUMP_COUNT_N( NEXT_FILLRECT, {DebuggerAppendMsg("FillRect: X0=%d, Y0=%d, X1=%d, Y1=%d, Color=0x%08X", nX0, nY0, nX1, nY1, dwColor); DebuggerAppendMsg("Pause after FillRect: Color=%08X\n", dwColor);if( logCombiners ) m_pColorCombiner->DisplayMuxString();}); DEBUGGER_PAUSE_AND_DUMP_COUNT_N( NEXT_FLUSH_TRI, {DebuggerAppendMsg("FillRect: X0=%d, Y0=%d, X1=%d, Y1=%d, Color=0x%08X", nX0, nY0, nX1, nY1, dwColor); DebuggerAppendMsg("Pause after FillRect: Color=%08X\n", dwColor);if( logCombiners ) m_pColorCombiner->DisplayMuxString();}); return res; } bool CRender::Line3D(uint32_t dwV0, uint32_t dwV1, uint32_t dwWidth) { LOG_UCODE("Line3D: Vtx0=%d, Vtx1=%d, Width=%d", dwV0, dwV1, dwWidth); if( !status.bCIBufferIsRendered ) g_pFrameBufferManager->ActiveTextureBuffer(); m_line3DVtx[0].z = (g_vecProjected[dwV0].z + 1.0f) * 0.5f; m_line3DVtx[1].z = (g_vecProjected[dwV1].z + 1.0f) * 0.5f; if( m_line3DVtx[0].z != m_line3DVtx[1].z ) return false; if( status.bHandleN64RenderTexture && !status.bDirectWriteIntoRDRAM ) status.bFrameBufferIsDrawn = true; if( status.bHandleN64RenderTexture ) { g_pRenderTextureInfo->maxUsedHeight = g_pRenderTextureInfo->N64Height; if( status.bHandleN64RenderTexture && !status.bDirectWriteIntoRDRAM ) { status.bFrameBufferIsDrawn = true; status.bFrameBufferDrawnByTriangles = true; } } m_line3DVtx[0].x = ViewPortTranslatef_x(g_vecProjected[dwV0].x); m_line3DVtx[0].y = ViewPortTranslatef_y(g_vecProjected[dwV0].y); m_line3DVtx[0].rhw = g_vecProjected[dwV0].w; m_line3DVtx[0].dcDiffuse = PostProcessDiffuseColor(g_dwVtxDifColor[dwV0]); m_line3DVtx[0].dcSpecular = PostProcessSpecularColor(); m_line3DVtx[1].x = ViewPortTranslatef_x(g_vecProjected[dwV1].x); m_line3DVtx[1].y = ViewPortTranslatef_y(g_vecProjected[dwV1].y); m_line3DVtx[1].rhw = g_vecProjected[dwV1].w; m_line3DVtx[1].dcDiffuse = PostProcessDiffuseColor(g_dwVtxDifColor[dwV1]); m_line3DVtx[1].dcSpecular = m_line3DVtx[0].dcSpecular; float width = dwWidth*0.5f+1.5f; if( m_line3DVtx[0].y == m_line3DVtx[1].y ) { m_line3DVector[0].x = m_line3DVector[1].x = m_line3DVtx[0].x; m_line3DVector[2].x = m_line3DVector[3].x = m_line3DVtx[1].x; m_line3DVector[0].y = m_line3DVector[2].y = m_line3DVtx[0].y-width/2*windowSetting.fMultY; m_line3DVector[1].y = m_line3DVector[3].y = m_line3DVtx[0].y+width/2*windowSetting.fMultY; } else { m_line3DVector[0].y = m_line3DVector[1].y = m_line3DVtx[0].y; m_line3DVector[2].y = m_line3DVector[3].y = m_line3DVtx[1].y; m_line3DVector[0].x = m_line3DVector[2].x = m_line3DVtx[0].x-width/2*windowSetting.fMultX; m_line3DVector[1].x = m_line3DVector[3].x = m_line3DVtx[0].x+width/2*windowSetting.fMultX; } SetCombinerAndBlender(); bool res=RenderLine3D(); DEBUGGER_PAUSE_AND_DUMP_COUNT_N(NEXT_FLUSH_TRI, { DebuggerAppendMsg("Pause after Line3D: v%d(%f,%f,%f), v%d(%f,%f,%f), Width=%d\n", dwV0, m_line3DVtx[0].x, m_line3DVtx[0].y, m_line3DVtx[0].z, dwV1, m_line3DVtx[1].x, m_line3DVtx[1].y, m_line3DVtx[1].z, dwWidth); }); DEBUGGER_PAUSE_AND_DUMP_COUNT_N(NEXT_OBJ_TXT_CMD, { DebuggerAppendMsg("Pause after Line3D: v%d(%f,%f,%f), v%d(%f,%f,%f), Width=%d\n", dwV0, m_line3DVtx[0].x, m_line3DVtx[0].y, m_line3DVtx[0].z, dwV1, m_line3DVtx[1].x, m_line3DVtx[1].y, m_line3DVtx[1].z, dwWidth); }); return res; } bool CRender::RemapTextureCoordinate (float t0, float t1, uint32_t tileWidth, uint32_t mask, float textureWidth, float &u0, float &u1) { int s0 = (int)t0; int s1 = (int)t1; int width = mask>0 ? (1< s0 ) divs0--; int divs1 = s1/width; if( divs1*width > s1 ) divs1--; if( divs0 == divs1 ) { s0 -= divs0*width; s1 -= divs1*width; //if( s0 > s1 ) // s0++; //else if( s1 > s0 ) // s1++; u0 = s0/textureWidth; u1 = s1/textureWidth; return true; } else if( divs0+1 == divs1 && s0%width==0 && s1%width == 0 ) { u0 = 0; u1 = tileWidth/textureWidth; return true; } else if( divs0 == divs1+1 && s0%width==0 && s1%width == 0 ) { u1 = 0; u0 = tileWidth/textureWidth; return true; } else { //if( s0 > s1 ) //{ //s0++; // u0 = s0/textureWidth; //} //else if( s1 > s0 ) //{ //s1++; // u1 = s1/textureWidth; //} return false; } } bool CRender::TexRect(int nX0, int nY0, int nX1, int nY1, float fS0, float fT0, float fScaleS, float fScaleT, bool colorFlag, uint32_t diffuseColor) { if( options.enableHackForGames == HACK_FOR_DUKE_NUKEM ) { colorFlag = true; diffuseColor = 0; } if( status.bVIOriginIsUpdated == true && currentRomOptions.screenUpdateSetting==SCREEN_UPDATE_AT_1ST_PRIMITIVE ) { status.bVIOriginIsUpdated=false; CGraphicsContext::Get()->UpdateFrame(false); DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_SET_CIMG,{DebuggerAppendMsg("Screen Update at 1st textRect");}); } if( options.enableHackForGames == HACK_FOR_BANJO_TOOIE ) { // Hack for Banjo shadow in Banjo Tooie if( g_TI.dwWidth == g_CI.dwWidth && g_TI.dwFormat == TXT_FMT_CI && g_TI.dwSize == TXT_SIZE_8b ) { if( nX0 == fS0 && nY0 == fT0 )//&& nX0 > 90 && nY0 > 130 && nX1-nX0 > 80 && nY1-nY0 > 20 ) { // Skip the text rect return true; } } } if( status.bN64IsDrawingTextureBuffer ) { if( frameBufferOptions.bIgnore || ( frameBufferOptions.bIgnoreRenderTextureIfHeightUnknown && newRenderTextureInfo.knownHeight == 0 ) ) { return true; } } PrepareTextures(); if( status.bHandleN64RenderTexture && g_pRenderTextureInfo->CI_Info.dwSize == TXT_SIZE_8b ) { return true; } if( !IsTextureEnabled() && gRDP.otherMode.cycle_type != CYCLE_TYPE_COPY ) { FillRect(nX0, nY0, nX1, nY1, gRDP.primitiveColor); return true; } if( IsUsedAsDI(g_CI.dwAddr) && !status.bHandleN64RenderTexture ) { status.bFrameBufferIsDrawn = true; } if( status.bHandleN64RenderTexture && !status.bDirectWriteIntoRDRAM ) status.bFrameBufferIsDrawn = true; LOG_UCODE("TexRect: X0=%d, Y0=%d, X1=%d, Y1=%d,\n\t\tfS0=%f, fT0=%f, ScaleS=%f, ScaleT=%f ", nX0, nY0, nX1, nY1, fS0, fT0, fScaleS, fScaleT); if( options.bEnableHacks ) { // Goldeneye HACK if( nY1 - nY0 < 2 ) nY1 = nY1+2; //// Text edge hack else if( gRDP.otherMode.cycle_type == CYCLE_TYPE_1 && fScaleS == 1 && fScaleT == 1 && (int)g_textures[gRSP.curTile].m_dwTileWidth == nX1-nX0+1 && (int)g_textures[gRSP.curTile].m_dwTileHeight == nY1-nY0+1 && g_textures[gRSP.curTile].m_dwTileWidth%2 == 0 && g_textures[gRSP.curTile].m_dwTileHeight%2 == 0 ) { nY1++; nX1++; } else if( g_curRomInfo.bIncTexRectEdge ) { nX1++; nY1++; } } // Scale to Actual texture coords // The two cases are to handle the oversized textures hack on voodoos SetCombinerAndBlender(); if( gRDP.otherMode.cycle_type >= CYCLE_TYPE_COPY || !gRDP.otherMode.z_cmp ) { ZBufferEnable(FALSE); } bool accurate = currentRomOptions.bAccurateTextureMapping; RenderTexture &tex0 = g_textures[gRSP.curTile]; Tile &tile0 = gRDP.tiles[gRSP.curTile]; float widthDiv = tex0.m_fTexWidth; float heightDiv = tex0.m_fTexHeight; float t0u0; if( options.enableHackForGames == HACK_FOR_ALL_STAR_BASEBALL || options.enableHackForGames == HACK_FOR_MLB ) { t0u0 = (fS0 -tile0.fhilite_sl); } else { t0u0 = (fS0 * tile0.fShiftScaleS -tile0.fhilite_sl); } float t0u1; if( accurate && gRDP.otherMode.cycle_type >= CYCLE_TYPE_COPY ) { t0u1 = t0u0 + (fScaleS * (nX1 - nX0 - 1))*tile0.fShiftScaleS; } else { t0u1 = t0u0 + (fScaleS * (nX1 - nX0))*tile0.fShiftScaleS; } if( status.UseLargerTile[0] ) { m_texRectTex1UV[0].u = (t0u0+status.LargerTileRealLeft[0])/widthDiv; m_texRectTex1UV[1].u = (t0u1+status.LargerTileRealLeft[0])/widthDiv; } else { m_texRectTex1UV[0].u = t0u0/widthDiv; m_texRectTex1UV[1].u = t0u1/widthDiv; if( accurate && !tile0.bMirrorS && RemapTextureCoordinate(t0u0, t0u1, tex0.m_dwTileWidth, tile0.dwMaskS, widthDiv, m_texRectTex1UV[0].u, m_texRectTex1UV[1].u) ) SetTextureUFlag(TEXTURE_UV_FLAG_CLAMP, gRSP.curTile); } float t0v0; if( options.enableHackForGames == HACK_FOR_ALL_STAR_BASEBALL || options.enableHackForGames == HACK_FOR_MLB ) { t0v0 = (fT0 -tile0.fhilite_tl); } else { t0v0 = (fT0 * tile0.fShiftScaleT -tile0.fhilite_tl); } float t0v1; if ( accurate && gRDP.otherMode.cycle_type >= CYCLE_TYPE_COPY) { t0v1 = t0v0 + (fScaleT * (nY1 - nY0-1))*tile0.fShiftScaleT; } else { t0v1 = t0v0 + (fScaleT * (nY1 - nY0))*tile0.fShiftScaleT; } m_texRectTex1UV[0].v = t0v0/heightDiv; m_texRectTex1UV[1].v = t0v1/heightDiv; if( accurate && !tile0.bMirrorT && RemapTextureCoordinate(t0v0, t0v1, tex0.m_dwTileHeight, tile0.dwMaskT, heightDiv, m_texRectTex1UV[0].v, m_texRectTex1UV[1].v) ) SetTextureVFlag(TEXTURE_UV_FLAG_CLAMP, gRSP.curTile); COLOR speColor = PostProcessSpecularColor(); COLOR difColor; if( colorFlag ) difColor = PostProcessDiffuseColor(diffuseColor); else //difColor = PostProcessDiffuseColor(0); difColor = PostProcessDiffuseColor(gRDP.primitiveColor); g_texRectTVtx[0].x = ViewPortTranslatei_x(nX0); g_texRectTVtx[0].y = ViewPortTranslatei_y(nY0); g_texRectTVtx[0].dcDiffuse = difColor; g_texRectTVtx[0].dcSpecular = speColor; g_texRectTVtx[1].x = ViewPortTranslatei_x(nX1); g_texRectTVtx[1].y = ViewPortTranslatei_y(nY0); g_texRectTVtx[1].dcDiffuse = difColor; g_texRectTVtx[1].dcSpecular = speColor; g_texRectTVtx[2].x = ViewPortTranslatei_x(nX1); g_texRectTVtx[2].y = ViewPortTranslatei_y(nY1); g_texRectTVtx[2].dcDiffuse = difColor; g_texRectTVtx[2].dcSpecular = speColor; g_texRectTVtx[3].x = ViewPortTranslatei_x(nX0); g_texRectTVtx[3].y = ViewPortTranslatei_y(nY1); g_texRectTVtx[3].dcDiffuse = difColor; g_texRectTVtx[3].dcSpecular = speColor; float depth = (gRDP.otherMode.depth_source == 1 ? gRDP.fPrimitiveDepth : 0 ); g_texRectTVtx[0].z = g_texRectTVtx[1].z = g_texRectTVtx[2].z = g_texRectTVtx[3].z = depth; g_texRectTVtx[0].rhw = g_texRectTVtx[1].rhw = g_texRectTVtx[2].rhw = g_texRectTVtx[3].rhw = 1; if( IsTexel1Enable() ) { RenderTexture &tex1 = g_textures[(gRSP.curTile+1)&7]; Tile &tile1 = gRDP.tiles[(gRSP.curTile+1)&7]; widthDiv = tex1.m_fTexWidth; heightDiv = tex1.m_fTexHeight; //if( tile1.dwMaskS == 0 ) widthDiv = tile1.dwWidth; //if( tile1.dwMaskT == 0 ) heightDiv = tile1.dwHeight; float t0u0 = fS0 * tile1.fShiftScaleS -tile1.fhilite_sl; float t0v0 = fT0 * tile1.fShiftScaleT -tile1.fhilite_tl; float t0u1; float t0v1; if ( accurate && gRDP.otherMode.cycle_type >= CYCLE_TYPE_COPY) { t0u1 = t0u0 + (fScaleS * (nX1 - nX0 - 1))*tile1.fShiftScaleS; t0v1 = t0v0 + (fScaleT * (nY1 - nY0 - 1))*tile1.fShiftScaleT; } else { t0u1 = t0u0 + (fScaleS * (nX1 - nX0))*tile1.fShiftScaleS; t0v1 = t0v0 + (fScaleT * (nY1 - nY0))*tile1.fShiftScaleT; } if( status.UseLargerTile[1] ) { m_texRectTex2UV[0].u = (t0u0+status.LargerTileRealLeft[1])/widthDiv; m_texRectTex2UV[1].u = (t0u1+status.LargerTileRealLeft[1])/widthDiv; } else { m_texRectTex2UV[0].u = t0u0/widthDiv; m_texRectTex2UV[1].u = t0u1/widthDiv; if( accurate && !tile1.bMirrorS && RemapTextureCoordinate(t0u0, t0u1, tex1.m_dwTileWidth, tile1.dwMaskS, widthDiv, m_texRectTex2UV[0].u, m_texRectTex2UV[1].u) ) SetTextureUFlag(TEXTURE_UV_FLAG_CLAMP, (gRSP.curTile+1)&7); } m_texRectTex2UV[0].v = t0v0/heightDiv; m_texRectTex2UV[1].v = t0v1/heightDiv; if( accurate && !tile1.bMirrorT && RemapTextureCoordinate(t0v0, t0v1, tex1.m_dwTileHeight, tile1.dwMaskT, heightDiv, m_texRectTex2UV[0].v, m_texRectTex2UV[1].v) ) SetTextureVFlag(TEXTURE_UV_FLAG_CLAMP, (gRSP.curTile+1)&7); SetVertexTextureUVCoord(g_texRectTVtx[0], m_texRectTex1UV[0].u, m_texRectTex1UV[0].v, m_texRectTex2UV[0].u, m_texRectTex2UV[0].v); SetVertexTextureUVCoord(g_texRectTVtx[1], m_texRectTex1UV[1].u, m_texRectTex1UV[0].v, m_texRectTex2UV[1].u, m_texRectTex2UV[0].v); SetVertexTextureUVCoord(g_texRectTVtx[2], m_texRectTex1UV[1].u, m_texRectTex1UV[1].v, m_texRectTex2UV[1].u, m_texRectTex2UV[1].v); SetVertexTextureUVCoord(g_texRectTVtx[3], m_texRectTex1UV[0].u, m_texRectTex1UV[1].v, m_texRectTex2UV[0].u, m_texRectTex2UV[1].v); } else { SetVertexTextureUVCoord(g_texRectTVtx[0], m_texRectTex1UV[0].u, m_texRectTex1UV[0].v); SetVertexTextureUVCoord(g_texRectTVtx[1], m_texRectTex1UV[1].u, m_texRectTex1UV[0].v); SetVertexTextureUVCoord(g_texRectTVtx[2], m_texRectTex1UV[1].u, m_texRectTex1UV[1].v); SetVertexTextureUVCoord(g_texRectTVtx[3], m_texRectTex1UV[0].u, m_texRectTex1UV[1].v); } bool res; TurnFogOnOff(false); if( TileUFlags[gRSP.curTile]==TEXTURE_UV_FLAG_CLAMP && TileVFlags[gRSP.curTile]==TEXTURE_UV_FLAG_CLAMP && options.forceTextureFilter == FORCE_DEFAULT_FILTER ) { TextureFilter dwFilter = m_dwMagFilter; m_dwMagFilter = m_dwMinFilter = FILTER_LINEAR; ApplyTextureFilter(); ApplyRDPScissor(false); res = RenderTexRect(); m_dwMagFilter = m_dwMinFilter = dwFilter; ApplyTextureFilter(); } else if( fScaleS >= 1 && fScaleT >= 1 && options.forceTextureFilter == FORCE_DEFAULT_FILTER ) { TextureFilter dwFilter = m_dwMagFilter; m_dwMagFilter = m_dwMinFilter = FILTER_POINT; ApplyTextureFilter(); ApplyRDPScissor(false); res = RenderTexRect(); m_dwMagFilter = m_dwMinFilter = dwFilter; ApplyTextureFilter(); } else { ApplyRDPScissor(false); res = RenderTexRect(); } TurnFogOnOff(gRSP.bFogEnabled); if( gRDP.otherMode.cycle_type >= CYCLE_TYPE_COPY || !gRDP.otherMode.z_cmp ) { ZBufferEnable(gRSP.bZBufferEnabled); } DEBUGGER_PAUSE_AT_COND_AND_DUMP_COUNT_N((eventToPause == NEXT_FLUSH_TRI || eventToPause == NEXT_TEXTRECT), { DebuggerAppendMsg("TexRect: tile=%d, X0=%d, Y0=%d, X1=%d, Y1=%d,\nfS0=%f, fT0=%f, ScaleS=%f, ScaleT=%f\n", gRSP.curTile, nX0, nY0, nX1, nY1, fS0, fT0, fScaleS, fScaleT); DebuggerAppendMsg(" : x0=%f, y0=%f, x1=%f, y1=%f\n", g_texRectTVtx[0].x, g_texRectTVtx[0].y, g_texRectTVtx[2].x, g_texRectTVtx[2].y); DebuggerAppendMsg(" Tex0: u0=%f, v0=%f, u1=%f, v1=%f\n", m_texRectTex1UV[0].u, m_texRectTex1UV[0].v, m_texRectTex1UV[1].u, m_texRectTex1UV[1].v); if( IsTexel1Enable() ) { DebuggerAppendMsg(" Tex1: u0=%f, v0=%f, u1=%f, v1=%f\n", m_texRectTex2UV[0].u, m_texRectTex2UV[0].v, m_texRectTex2UV[1].u, m_texRectTex2UV[1].v); } DebuggerAppendMsg("color=%08X, %08X\n", g_texRectTVtx[0].dcDiffuse, g_texRectTVtx[0].dcSpecular); DebuggerAppendMsg("Pause after TexRect\n"); if( logCombiners ) m_pColorCombiner->DisplayMuxString(); }); return res; } bool CRender::TexRectFlip(int nX0, int nY0, int nX1, int nY1, float fS0, float fT0, float fS1, float fT1) { LOG_UCODE("TexRectFlip: X0=%d, Y0=%d, X1=%d, Y1=%d,\n\t\tfS0=%f, fT0=%f, fS1=%f, fT1=%f ", nX0, nY0, nX1, nY1, fS0, fT0, fS1, fT1); if( status.bHandleN64RenderTexture && !status.bDirectWriteIntoRDRAM ) { status.bFrameBufferIsDrawn = true; status.bFrameBufferDrawnByTriangles = true; } PrepareTextures(); // Save ZBuffer state m_savedZBufferFlag = gRSP.bZBufferEnabled; if( gRDP.otherMode.depth_source == 0 ) ZBufferEnable( FALSE ); float widthDiv = g_textures[gRSP.curTile].m_fTexWidth; float heightDiv = g_textures[gRSP.curTile].m_fTexHeight; //Tile &tile0 = gRDP.tiles[gRSP.curTile]; float t0u0 = fS0 / widthDiv; float t0v0 = fT0 / heightDiv; float t0u1 = (fS1 - fS0)/ widthDiv + t0u0; float t0v1 = (fT1 - fT0)/ heightDiv + t0v0; float depth = (gRDP.otherMode.depth_source == 1 ? gRDP.fPrimitiveDepth : 0 ); if( t0u0 >= 0 && t0u1 <= 1 && t0u1 >= t0u0 ) SetTextureUFlag(TEXTURE_UV_FLAG_CLAMP, gRSP.curTile); if( t0v0 >= 0 && t0v1 <= 1 && t0v1 >= t0v0 ) SetTextureVFlag(TEXTURE_UV_FLAG_CLAMP, gRSP.curTile); SetCombinerAndBlender(); COLOR speColor = PostProcessSpecularColor(); COLOR difColor = PostProcessDiffuseColor(gRDP.primitiveColor); // Same as TexRect, but with texcoords 0,2 swapped g_texRectTVtx[0].x = ViewPortTranslatei_x(nX0); g_texRectTVtx[0].y = ViewPortTranslatei_y(nY0); g_texRectTVtx[0].dcDiffuse = difColor; g_texRectTVtx[0].dcSpecular = speColor; g_texRectTVtx[1].x = ViewPortTranslatei_x(nX1); g_texRectTVtx[1].y = ViewPortTranslatei_y(nY0); g_texRectTVtx[1].dcDiffuse = difColor; g_texRectTVtx[1].dcSpecular = speColor; g_texRectTVtx[2].x = ViewPortTranslatei_x(nX1); g_texRectTVtx[2].y = ViewPortTranslatei_y(nY1); g_texRectTVtx[2].dcDiffuse = difColor; g_texRectTVtx[2].dcSpecular = speColor; g_texRectTVtx[3].x = ViewPortTranslatei_x(nX0); g_texRectTVtx[3].y = ViewPortTranslatei_y(nY1); g_texRectTVtx[3].dcDiffuse = difColor; g_texRectTVtx[3].dcSpecular = speColor; g_texRectTVtx[0].z = g_texRectTVtx[1].z = g_texRectTVtx[2].z = g_texRectTVtx[3].z = depth; g_texRectTVtx[0].rhw = g_texRectTVtx[1].rhw = g_texRectTVtx[2].rhw = g_texRectTVtx[3].rhw = 1.0f; SetVertexTextureUVCoord(g_texRectTVtx[0], t0u0, t0v0); SetVertexTextureUVCoord(g_texRectTVtx[1], t0u0, t0v1); SetVertexTextureUVCoord(g_texRectTVtx[2], t0u1, t0v1); SetVertexTextureUVCoord(g_texRectTVtx[3], t0u1, t0v0); TurnFogOnOff(false); ApplyRDPScissor(false); bool res = RenderTexRect(); TurnFogOnOff(gRSP.bFogEnabled); // Restore state ZBufferEnable( m_savedZBufferFlag ); DEBUGGER_PAUSE_AT_COND_AND_DUMP_COUNT_N((eventToPause == NEXT_FLUSH_TRI || eventToPause == NEXT_TEXTRECT), { DebuggerAppendMsg("TexRectFlip: tile=%d, X0=%d, Y0=%d, X1=%d, Y1=%d,\nfS0=%f, fT0=%f, nfS1=%f, fT1=%f\n", gRSP.curTile, nX0, nY0, nX1, nY1, fS0, fT0, fS1, fT1); DebuggerAppendMsg(" : x0=%f, y0=%f, x1=%f, y1=%f\n", g_texRectTVtx[0].x, g_texRectTVtx[0].y, g_texRectTVtx[2].x, g_texRectTVtx[2].y); DebuggerAppendMsg(" Tex0: u0=%f, v0=%f, u1=%f, v1=%f\n", g_texRectTVtx[0].tcord[0].u, g_texRectTVtx[0].tcord[0].v, g_texRectTVtx[2].tcord[0].u, g_texRectTVtx[2].tcord[0].v); TRACE0("Pause after TexRectFlip\n"); if( logCombiners ) m_pColorCombiner->DisplayMuxString(); }); return res; } void CRender::StartDrawSimple2DTexture(float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, COLOR dif, COLOR spe, float z, float rhw) { g_texRectTVtx[0].x = ViewPortTranslatei_x(x0); // << Error here, shouldn't divid by 4 g_texRectTVtx[0].y = ViewPortTranslatei_y(y0); g_texRectTVtx[0].dcDiffuse = dif; g_texRectTVtx[0].dcSpecular = spe; g_texRectTVtx[0].tcord[0].u = u0; g_texRectTVtx[0].tcord[0].v = v0; g_texRectTVtx[1].x = ViewPortTranslatei_x(x1); g_texRectTVtx[1].y = ViewPortTranslatei_y(y0); g_texRectTVtx[1].dcDiffuse = dif; g_texRectTVtx[1].dcSpecular = spe; g_texRectTVtx[1].tcord[0].u = u1; g_texRectTVtx[1].tcord[0].v = v0; g_texRectTVtx[2].x = ViewPortTranslatei_x(x1); g_texRectTVtx[2].y = ViewPortTranslatei_y(y1); g_texRectTVtx[2].dcDiffuse = dif; g_texRectTVtx[2].dcSpecular = spe; g_texRectTVtx[2].tcord[0].u = u1; g_texRectTVtx[2].tcord[0].v = v1; g_texRectTVtx[3].x = ViewPortTranslatei_x(x0); g_texRectTVtx[3].y = ViewPortTranslatei_y(y1); g_texRectTVtx[3].dcDiffuse = dif; g_texRectTVtx[3].dcSpecular = spe; g_texRectTVtx[3].tcord[0].u = u0; g_texRectTVtx[3].tcord[0].v = v1; RenderTexture &txtr = g_textures[0]; if( txtr.pTextureEntry && txtr.pTextureEntry->txtrBufIdx > 0 ) { RenderTextureInfo &info = gRenderTextureInfos[txtr.pTextureEntry->txtrBufIdx-1]; g_texRectTVtx[0].tcord[0].u *= info.scaleX; g_texRectTVtx[0].tcord[0].v *= info.scaleY; g_texRectTVtx[1].tcord[0].u *= info.scaleX; g_texRectTVtx[1].tcord[0].v *= info.scaleY; g_texRectTVtx[2].tcord[0].u *= info.scaleX; g_texRectTVtx[2].tcord[0].v *= info.scaleY; g_texRectTVtx[3].tcord[0].u *= info.scaleX; g_texRectTVtx[3].tcord[0].v *= info.scaleY; } g_texRectTVtx[0].z = g_texRectTVtx[1].z = g_texRectTVtx[2].z = g_texRectTVtx[3].z = z; g_texRectTVtx[0].rhw = g_texRectTVtx[1].rhw = g_texRectTVtx[2].rhw = g_texRectTVtx[3].rhw = rhw; } void CRender::StartDrawSimpleRect(int nX0, int nY0, int nX1, int nY1, uint32_t dwColor, float depth, float rhw) { m_simpleRectVtx[0].x = ViewPortTranslatei_x(nX0); m_simpleRectVtx[1].x = ViewPortTranslatei_x(nX1); m_simpleRectVtx[0].y = ViewPortTranslatei_y(nY0); m_simpleRectVtx[1].y = ViewPortTranslatei_y(nY1); } void CRender::SetAddressUAllStages(uint32_t dwTile, TextureUVFlag dwFlag) { } void CRender::SetAddressVAllStages(uint32_t dwTile, TextureUVFlag dwFlag) { } void CRender::SetAllTexelRepeatFlag() { if( IsTextureEnabled() ) { if( IsTexel0Enable() || gRDP.otherMode.cycle_type == CYCLE_TYPE_COPY ) SetTexelRepeatFlags(gRSP.curTile); if( IsTexel1Enable() ) SetTexelRepeatFlags((gRSP.curTile+1)&7); } } void CRender::SetTexelRepeatFlags(uint32_t dwTile) { Tile &tile = gRDP.tiles[dwTile]; if( tile.bForceClampS ) SetTextureUFlag(TEXTURE_UV_FLAG_CLAMP, dwTile); else if( tile.bForceWrapS ) SetTextureUFlag(TEXTURE_UV_FLAG_WRAP, dwTile); else if( tile.dwMaskS == 0 || tile.bClampS ) { if( gRDP.otherMode.cycle_type >= CYCLE_TYPE_COPY ) SetTextureUFlag(TEXTURE_UV_FLAG_WRAP, dwTile); // Can not clamp in COPY/FILL mode else SetTextureUFlag(TEXTURE_UV_FLAG_CLAMP, dwTile); } else if (tile.bMirrorS ) SetTextureUFlag(TEXTURE_UV_FLAG_MIRROR, dwTile); else SetTextureUFlag(TEXTURE_UV_FLAG_WRAP, dwTile); if( tile.bForceClampT ) SetTextureVFlag(TEXTURE_UV_FLAG_CLAMP, dwTile); else if( tile.bForceWrapT ) SetTextureVFlag(TEXTURE_UV_FLAG_WRAP, dwTile); else if( tile.dwMaskT == 0 || tile.bClampT) { if( gRDP.otherMode.cycle_type >= CYCLE_TYPE_COPY ) SetTextureVFlag(TEXTURE_UV_FLAG_WRAP, dwTile); // Can not clamp in COPY/FILL mode else SetTextureVFlag(TEXTURE_UV_FLAG_CLAMP, dwTile); } else if (tile.bMirrorT ) SetTextureVFlag(TEXTURE_UV_FLAG_MIRROR, dwTile); else SetTextureVFlag(TEXTURE_UV_FLAG_WRAP, dwTile); } void CRender::Initialize(void) { ClearDeviceObjects(); InitDeviceObjects(); } void CRender::CleanUp(void) { m_pColorCombiner->CleanUp(); ClearDeviceObjects(); } void myVec3Transform(float *vecout, float *vecin, float* m) { float w = m[3]*vecin[0]+m[7]*vecin[1]+m[11]*vecin[2]+m[15]; vecout[0] = (m[0]*vecin[0]+m[4]*vecin[1]+m[8]*vecin[2]+m[12])/w; vecout[1] = (m[1]*vecin[0]+m[5]*vecin[1]+m[9]*vecin[2]+m[13])/w; vecout[2] = (m[2]*vecin[0]+m[6]*vecin[1]+m[10]*vecin[2]+m[14])/w; } void CRender::SetTextureEnableAndScale(int dwTile, bool bEnable, float fScaleX, float fScaleY) { gRSP.bTextureEnabled = bEnable; if( bEnable ) { if( gRSP.curTile != (unsigned int)dwTile ) gRDP.textureIsChanged = true; gRSP.curTile = dwTile; gRSP.fTexScaleX = fScaleX; gRSP.fTexScaleY = fScaleY; if( fScaleX == 0 || fScaleY == 0 ) { gRSP.fTexScaleX = 1/32.0f; gRSP.fTexScaleY = 1/32.0f; } } } void CRender::SetViewport(int nLeft, int nTop, int nRight, int nBottom, int maxZ) { if( status.bHandleN64RenderTexture ) return; static float MultX=0, MultY=0; if( gRSP.nVPLeftN == nLeft && gRSP.nVPTopN == nTop && gRSP.nVPRightN == nRight && gRSP.nVPBottomN == nBottom && MultX==windowSetting.fMultX && MultY==windowSetting.fMultY) { // no changes return; } MultX=windowSetting.fMultX; MultY=windowSetting.fMultY; gRSP.maxZ = maxZ; gRSP.nVPLeftN = nLeft; gRSP.nVPTopN = nTop; gRSP.nVPRightN = nRight; gRSP.nVPBottomN = nBottom; gRSP.nVPWidthN = nRight - nLeft + 1; gRSP.nVPHeightN = nBottom - nTop + 1; UpdateClipRectangle(); SetViewportRender(); LOG_UCODE("SetViewport (%d,%d - %d,%d)",gRSP.nVPLeftN, gRSP.nVPTopN, gRSP.nVPRightN, gRSP.nVPBottomN); } extern bool bHalfTxtScale; bool CRender::DrawTriangles() { if( !status.bCIBufferIsRendered ) g_pFrameBufferManager->ActiveTextureBuffer(); DEBUGGER_ONLY_IF( (!debuggerEnableZBuffer), {ZBufferEnable( FALSE );} ); if( status.bVIOriginIsUpdated == true && currentRomOptions.screenUpdateSetting==SCREEN_UPDATE_AT_1ST_PRIMITIVE ) { status.bVIOriginIsUpdated=false; CGraphicsContext::Get()->UpdateFrame(false); DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_SET_CIMG,{DebuggerAppendMsg("Screen Update at 1st triangle");}); } // Hack for Pilotwings 64 (U) [!].v64 static bool skipNext=false; if( options.enableHackForGames == HACK_FOR_PILOT_WINGS ) { if( IsUsedAsDI(g_CI.dwAddr) && gRDP.otherMode.z_cmp+gRDP.otherMode.z_upd > 0 ) { TRACE0("Warning: using Flushtris to write Z-Buffer" ); gRSP.numVertices = 0; gRSP.maxVertexID = 0; skipNext = true; return true; } else if( skipNext ) { skipNext = false; gRSP.numVertices = 0; gRSP.maxVertexID = 0; return true; } } if( status.bN64IsDrawingTextureBuffer && frameBufferOptions.bIgnore ) { gRSP.numVertices = 0; gRSP.maxVertexID = 0; return true; } extern bool bConkerHideShadow; if( options.enableHackForGames == HACK_FOR_CONKER && bConkerHideShadow ) { gRSP.numVertices = 0; gRSP.maxVertexID = 0; return true; } if( IsUsedAsDI(g_CI.dwAddr) && !status.bHandleN64RenderTexture ) { status.bFrameBufferIsDrawn = true; } /* if( status.bHandleN64RenderTexture && g_pRenderTextureInfo->CI_Info.dwSize == TXT_SIZE_8b ) { gRSP.numVertices = 0; gRSP.maxVertexID = 0; return true; } */ if (gRSP.numVertices == 0) return true; if( status.bHandleN64RenderTexture ) { g_pRenderTextureInfo->maxUsedHeight = g_pRenderTextureInfo->N64Height; if( !status.bDirectWriteIntoRDRAM ) { status.bFrameBufferIsDrawn = true; status.bFrameBufferDrawnByTriangles = true; } } if( !gRDP.bFogEnableInBlender && gRSP.bFogEnabled ) { TurnFogOnOff(false); } for( int t=0; t<2; t++ ) { float halfscaleS = 1; // This will get rid of the thin black lines if( t==0 && !(m_pColorCombiner->m_bTex0Enabled) ) { continue; } else { if( ( gRDP.tiles[gRSP.curTile].dwSize == TXT_SIZE_32b && options.enableHackForGames == HACK_FOR_RUMBLE ) || (bHalfTxtScale && g_curRomInfo.bTextureScaleHack ) || (options.enableHackForGames == HACK_FOR_POLARISSNOCROSS && gRDP.tiles[7].dwFormat == TXT_FMT_CI && gRDP.tiles[7].dwSize == TXT_SIZE_8b && gRDP.tiles[0].dwFormat == TXT_FMT_CI && gRDP.tiles[0].dwSize == TXT_SIZE_8b && gRSP.curTile == 0 )) { halfscaleS = 0.5; } } if( t==1 && !(m_pColorCombiner->m_bTex1Enabled) ) break; if( halfscaleS < 1 ) { for( uint32_t i=0; i 1.0 || g_vtxBuffer[i].tcord[t].u < 0.0 ) { clampS = false; break; } } for( uint32_t i=0; i 1.0 || g_vtxBuffer[i].tcord[t].v < 0.0 ) { clampT = false; break; } } if( clampS ) { SetTextureUFlag(TEXTURE_UV_FLAG_CLAMP, gRSP.curTile+t); } if( clampT ) { SetTextureVFlag(TEXTURE_UV_FLAG_CLAMP, gRSP.curTile+t); } */ } if( status.bHandleN64RenderTexture && g_pRenderTextureInfo->CI_Info.dwSize == TXT_SIZE_8b ) { ZBufferEnable(FALSE); } ApplyScissorWithClipRatio(false); if( g_curRomInfo.bZHack ) { extern void HackZAll(); HackZAll(); } bool res = RenderFlushTris(); g_clippedVtxCount = 0; LOG_UCODE("DrawTriangles: Draw %d Triangles", gRSP.numVertices/3); gRSP.numVertices = 0; // Reset index gRSP.maxVertexID = 0; DEBUGGER_PAUSE_AND_DUMP_COUNT_N(NEXT_FLUSH_TRI, { TRACE0("Pause after DrawTriangles\n"); if( logCombiners ) m_pColorCombiner->DisplayMuxString(); }); if( !gRDP.bFogEnableInBlender && gRSP.bFogEnabled ) { TurnFogOnOff(true); } return res; } inline int ReverseCITableLookup(uint32_t *pTable, int size, uint32_t val) { for( int i=0; itxtrBufIdx-1]; float s = src.u; float t = src.v; uint32_t addrOffset = g_TI.dwAddr-info.CI_Info.dwAddr; uint32_t extraTop = (addrOffset>>(info.CI_Info.dwSize-1)) /info.CI_Info.dwWidth; uint32_t extraLeft = (addrOffset>>(info.CI_Info.dwSize-1))%info.CI_Info.dwWidth; if( pEntry->txtrBufIdx > 0 ) { // Loading from render_texture or back buffer s += (extraLeft+pEntry->ti.LeftToLoad)/txtr.m_fTexWidth; t += (extraTop+pEntry->ti.TopToLoad)/txtr.m_fTexHeight; s *= info.scaleX; t *= info.scaleY; } dst.u = s; dst.v = t; } void CRender::SetVertexTextureUVCoord(TLITVERTEX &v, const TexCord &fTex0) { RenderTexture &txtr = g_textures[0]; if( txtr.pTextureEntry && txtr.pTextureEntry->txtrBufIdx > 0 ) { ::SetVertexTextureUVCoord(v.tcord[0], fTex0, 0, txtr.pTextureEntry); } else { v.tcord[0] = fTex0; } } void CRender::SetVertexTextureUVCoord(TLITVERTEX &v, float fTex0S, float fTex0T) { TexCord t = { fTex0S, fTex0T }; SetVertexTextureUVCoord(v, t); } void CRender::SetVertexTextureUVCoord(TLITVERTEX &v, const TexCord &fTex0_, const TexCord &fTex1_) { TexCord fTex0 = fTex0_; TexCord fTex1 = fTex1_; if( (options.enableHackForGames == HACK_FOR_ZELDA||options.enableHackForGames == HACK_FOR_ZELDA_MM) && m_Mux == 0x00262a60150c937fLL && gRSP.curTile == 0 ) { // Hack for Zelda Sun Tile &t0 = gRDP.tiles[0]; Tile &t1 = gRDP.tiles[1]; if( t0.dwFormat == TXT_FMT_I && t0.dwSize == TXT_SIZE_8b && t0.dwWidth == 64 && t1.dwFormat == TXT_FMT_I && t1.dwSize == TXT_SIZE_8b && t1.dwWidth == 64 && t0.dwHeight == t1.dwHeight ) { fTex0.u /= 2; fTex0.v /= 2; fTex1.u /= 2; fTex1.v /= 2; } } RenderTexture &txtr0 = g_textures[0]; if( txtr0.pTextureEntry && txtr0.pTextureEntry->txtrBufIdx > 0 ) { ::SetVertexTextureUVCoord(v.tcord[0], fTex0, 0, txtr0.pTextureEntry); } else { v.tcord[0] = fTex0; } RenderTexture &txtr1 = g_textures[1]; if( txtr1.pTextureEntry && txtr1.pTextureEntry->txtrBufIdx > 0 ) { ::SetVertexTextureUVCoord(v.tcord[1], fTex1, 1, txtr1.pTextureEntry); } else { v.tcord[1] = fTex1; } } void CRender::SetVertexTextureUVCoord(TLITVERTEX &v, float fTex0S, float fTex0T, float fTex1S, float fTex1T) { TexCord t0 = { fTex0S, fTex0T }; TexCord t1 = { fTex1S, fTex1T }; SetVertexTextureUVCoord(v, t0, t1); } void CRender::SetClipRatio(uint32_t type, uint32_t w1) { bool modified = false; switch(type) { case RSP_MV_WORD_OFFSET_CLIP_RNX: LOG_UCODE(" RSP_MOVE_WORD_CLIP NegX: %d", (int)(short)w1); if( gRSP.clip_ratio_negx != (short)w1 ) { gRSP.clip_ratio_negx = (short)w1; modified = true; } break; case RSP_MV_WORD_OFFSET_CLIP_RNY: LOG_UCODE(" RSP_MOVE_WORD_CLIP NegY: %d", (int)(short)w1); if( gRSP.clip_ratio_negy != (short)w1 ) { gRSP.clip_ratio_negy = (short)w1; modified = true; } break; case RSP_MV_WORD_OFFSET_CLIP_RPX: LOG_UCODE(" RSP_MOVE_WORD_CLIP PosX: %d", (int)(short)w1); if( gRSP.clip_ratio_posx != -(short)w1 ) { gRSP.clip_ratio_posx = -(short)w1; modified = true; } break; case RSP_MV_WORD_OFFSET_CLIP_RPY: LOG_UCODE(" RSP_MOVE_WORD_CLIP PosY: %d", (int)(short)w1); if( gRSP.clip_ratio_posy != -(short)w1 ) { gRSP.clip_ratio_posy = -(short)w1; modified = true; } break; } if( modified ) { UpdateClipRectangle(); } } void CRender::UpdateClipRectangle() { if( status.bHandleN64RenderTexture ) { //windowSetting.fMultX = windowSetting.fMultY = 1; windowSetting.vpLeftW = 0; windowSetting.vpTopW = 0; windowSetting.vpRightW = newRenderTextureInfo.bufferWidth; windowSetting.vpBottomW = newRenderTextureInfo.bufferHeight; windowSetting.vpWidthW = newRenderTextureInfo.bufferWidth; windowSetting.vpHeightW = newRenderTextureInfo.bufferHeight; gRSP.vtxXMul = windowSetting.vpWidthW/2.0f; gRSP.vtxXAdd = gRSP.vtxXMul + windowSetting.vpLeftW; gRSP.vtxYMul = -windowSetting.vpHeightW/2.0f; gRSP.vtxYAdd = windowSetting.vpHeightW/2.0f + windowSetting.vpTopW; // Update clip rectangle by setting scissor int halfx = newRenderTextureInfo.bufferWidth/2; int halfy = newRenderTextureInfo.bufferHeight/2; int centerx = halfx; int centery = halfy; gRSP.clip_ratio_left = centerx - halfx * gRSP.clip_ratio_negx; gRSP.clip_ratio_top = centery - halfy * gRSP.clip_ratio_negy; gRSP.clip_ratio_right = centerx + halfx * gRSP.clip_ratio_posx; gRSP.clip_ratio_bottom = centery + halfy * gRSP.clip_ratio_posy; } else { windowSetting.vpLeftW = int(gRSP.nVPLeftN * windowSetting.fMultX); windowSetting.vpTopW = int(gRSP.nVPTopN * windowSetting.fMultY); windowSetting.vpRightW = int(gRSP.nVPRightN* windowSetting.fMultX); windowSetting.vpBottomW = int(gRSP.nVPBottomN* windowSetting.fMultY); windowSetting.vpWidthW = int((gRSP.nVPRightN - gRSP.nVPLeftN + 1) * windowSetting.fMultX); windowSetting.vpHeightW = int((gRSP.nVPBottomN - gRSP.nVPTopN + 1) * windowSetting.fMultY); gRSP.vtxXMul = windowSetting.vpWidthW/2.0f; gRSP.vtxXAdd = gRSP.vtxXMul + windowSetting.vpLeftW; gRSP.vtxYMul = -windowSetting.vpHeightW/2.0f; gRSP.vtxYAdd = windowSetting.vpHeightW/2.0f + windowSetting.vpTopW; // Update clip rectangle by setting scissor int halfx = gRSP.nVPWidthN/2; int halfy = gRSP.nVPHeightN/2; int centerx = gRSP.nVPLeftN+halfx; int centery = gRSP.nVPTopN+halfy; gRSP.clip_ratio_left = centerx - halfx * gRSP.clip_ratio_negx; gRSP.clip_ratio_top = centery - halfy * gRSP.clip_ratio_negy; gRSP.clip_ratio_right = centerx + halfx * gRSP.clip_ratio_posx; gRSP.clip_ratio_bottom = centery + halfy * gRSP.clip_ratio_posy; } UpdateScissorWithClipRatio(); } void CRender::UpdateScissorWithClipRatio() { gRSP.real_clip_scissor_left = std::max(gRDP.scissor.left, gRSP.clip_ratio_left); gRSP.real_clip_scissor_top = std::max(gRDP.scissor.top, gRSP.clip_ratio_top); gRSP.real_clip_scissor_right = std::min(gRDP.scissor.right,gRSP.clip_ratio_right); gRSP.real_clip_scissor_bottom = std::min(gRDP.scissor.bottom, gRSP.clip_ratio_bottom); gRSP.real_clip_scissor_left = std::max(gRSP.real_clip_scissor_left, 0); gRSP.real_clip_scissor_top = std::max(gRSP.real_clip_scissor_top, 0); gRSP.real_clip_scissor_right = std::min(gRSP.real_clip_scissor_right,windowSetting.uViWidth-1); gRSP.real_clip_scissor_bottom = std::min(gRSP.real_clip_scissor_bottom, windowSetting.uViHeight-1); WindowSettingStruct &w = windowSetting; w.clipping.left = (uint32_t)(gRSP.real_clip_scissor_left*windowSetting.fMultX); w.clipping.top = (uint32_t)(gRSP.real_clip_scissor_top*windowSetting.fMultY); w.clipping.bottom = (uint32_t)(gRSP.real_clip_scissor_bottom*windowSetting.fMultY); w.clipping.right = (uint32_t)(gRSP.real_clip_scissor_right*windowSetting.fMultX); if( w.clipping.left > 0 || w.clipping.top > 0 || w.clipping.right < (uint32_t)windowSetting.uDisplayWidth-1 || w.clipping.bottom < (uint32_t)windowSetting.uDisplayHeight-1 ) { w.clipping.needToClip = true; } else { w.clipping.needToClip = false; } w.clipping.width = (uint32_t)((gRSP.real_clip_scissor_right-gRSP.real_clip_scissor_left+1)*windowSetting.fMultX); w.clipping.height = (uint32_t)((gRSP.real_clip_scissor_bottom-gRSP.real_clip_scissor_top+1)*windowSetting.fMultY); float halfx = gRSP.nVPWidthN/2.0f; float halfy = gRSP.nVPHeightN/2.0f; float centerx = gRSP.nVPLeftN+halfx; float centery = gRSP.nVPTopN+halfy; gRSP.real_clip_ratio_negx = (gRSP.real_clip_scissor_left - centerx)/halfx; gRSP.real_clip_ratio_negy = (gRSP.real_clip_scissor_top - centery)/halfy; gRSP.real_clip_ratio_posx = (gRSP.real_clip_scissor_right - centerx)/halfx; gRSP.real_clip_ratio_posy = (gRSP.real_clip_scissor_bottom - centery)/halfy; ApplyScissorWithClipRatio(true); } // Set other modes not covered by color combiner or alpha blender void CRender::InitOtherModes(void) { ApplyTextureFilter(); // // I can't think why the hand in Mario's menu screen is rendered with an opaque rendermode, // and no alpha threshold. We set the alpha reference to 1 to ensure that the transparent pixels // don't get rendered. I hope this doesn't fuck anything else up. // if ( gRDP.otherMode.alpha_compare == 0 ) { if ( gRDP.otherMode.cvg_x_alpha && (gRDP.otherMode.alpha_cvg_sel || gRDP.otherMode.aa_en ) ) { ForceAlphaRef(128); // Strange, I have to use value=2 for pixel shader combiner for Nvidia FX5200 // for other video cards, value=1 is good enough. SetAlphaTestEnable(TRUE); } else { SetAlphaTestEnable(FALSE); } } else if ( gRDP.otherMode.alpha_compare == 3 ) { //RDP_ALPHA_COMPARE_DITHER SetAlphaTestEnable(FALSE); } else { if( (gRDP.otherMode.alpha_cvg_sel ) && !gRDP.otherMode.cvg_x_alpha ) { // Use CVG for pixel alpha SetAlphaTestEnable(FALSE); } else { // RDP_ALPHA_COMPARE_THRESHOLD || RDP_ALPHA_COMPARE_DITHER if( m_dwAlpha==0 ) ForceAlphaRef(1); else ForceAlphaRef(m_dwAlpha); SetAlphaTestEnable(TRUE); } } if( options.enableHackForGames == HACK_FOR_SOUTH_PARK_RALLY && m_Mux == 0x00121824ff33ffffLL && gRSP.bCullFront && gRDP.otherMode.aa_en && gRDP.otherMode.z_cmp && gRDP.otherMode.z_upd ) { SetZCompare(FALSE); } if( gRDP.otherMode.cycle_type >= CYCLE_TYPE_COPY ) { // Disable zbuffer for COPY and FILL mode SetZCompare(FALSE); } else { SetZCompare(gRDP.otherMode.z_cmp); SetZUpdate(gRDP.otherMode.z_upd); } /* if( options.enableHackForGames == HACK_FOR_SOUTH_PARK_RALLY && m_Mux == 0x00121824ff33ffff && gRSP.bCullFront && gRDP.otherMode.z_cmp && gRDP.otherMode.z_upd )//&& gRDP.otherMode.aa_en ) { SetZCompare(FALSE); SetZUpdate(FALSE); } */ } void CRender::SetTextureFilter(uint32_t dwFilter) { if( options.forceTextureFilter == FORCE_DEFAULT_FILTER ) { switch(dwFilter) { case RDP_TFILTER_AVERAGE: //? case RDP_TFILTER_BILERP: m_dwMinFilter = m_dwMagFilter = FILTER_LINEAR; break; default: m_dwMinFilter = m_dwMagFilter = FILTER_POINT; break; } } else { switch( options.forceTextureFilter ) { case FORCE_POINT_FILTER: m_dwMinFilter = m_dwMagFilter = FILTER_POINT; break; case FORCE_LINEAR_FILTER: m_dwMinFilter = m_dwMagFilter = FILTER_LINEAR; break; } } ApplyTextureFilter(); } bool SaveRGBBufferToFile(char *filename, unsigned char *buf, int width, int height, int pitch) { return false; } bool SaveRGBABufferToPNGFile(char *filename, unsigned char *buf, int width, int height, int pitch) { return false; } mupen64plus-video-gliden64/src/mupenplus/000700 001750 001750 00000000000 12656647145 021445 5ustar00sergiosergio000000 000000 mupen64plus-video-gliden64/src/CRC.h000664 001750 001750 00000000423 12655644434 020205 0ustar00sergiosergio000000 000000 #include "Types.h" void CRC_BuildTable(); // CRC32 u32 CRC_Calculate( u32 crc, const void *buffer, u32 count ); u32 CRC_CalculatePalette( u32 crc, const void *buffer, u32 count ); // Fast checksum calculation from Glide64 u32 textureCRC(u8 * addr, u32 height, u32 stride); mupen64plus-core/src/rdp/rdp_core.h000664 001750 001750 00000005563 12655644434 020402 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - rdp_core.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_RDP_RDP_CORE_H #define M64P_RDP_RDP_CORE_H #include #include "fb.h" #ifndef DPC_REG #define DPC_REG(a) ((a & 0xffff) >> 2) #endif #ifndef DPS_REG #define DPS_REG(a) ((a & 0xffff) >> 2) #endif struct r4300_core; struct rsp_core; struct ri_controller; enum dpc_registers { DPC_START_REG, DPC_END_REG, DPC_CURRENT_REG, DPC_STATUS_REG, DPC_CLOCK_REG, DPC_BUFBUSY_REG, DPC_PIPEBUSY_REG, DPC_TMEM_REG, DPC_REGS_COUNT }; enum dps_registers { DPS_TBIST_REG, DPS_TEST_MODE_REG, DPS_BUFTEST_ADDR_REG, DPS_BUFTEST_DATA_REG, DPS_REGS_COUNT }; struct rdp_core { uint32_t dpc_regs[DPC_REGS_COUNT]; uint32_t dps_regs[DPS_REGS_COUNT]; struct fb fb; struct r4300_core* r4300; struct rsp_core* sp; struct ri_controller* ri; }; void connect_rdp(struct rdp_core* dp, struct r4300_core* r4300, struct rsp_core* sp, struct ri_controller* ri); void init_rdp(struct rdp_core* dp); int read_dpc_regs(void* opaque, uint32_t address, uint32_t* value); int write_dpc_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask); int read_dps_regs(void* opaque, uint32_t address, uint32_t* value); int write_dps_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask); void rdp_interrupt_event(struct rdp_core* dp); #endif mupen64plus-video-gliden64/src/RSP.h000664 001750 001750 00000001036 12655644434 020243 0ustar00sergiosergio000000 000000 #ifndef RSP_H #define RSP_H #include "Types.h" typedef struct { u32 PC[18], PCi, busy, halt, close, uc_start, uc_dstart, cmd, nextCmd; s32 count; bool bLLE; char romname[21]; wchar_t pluginpath[PLUGIN_PATH_SIZE]; } RSPInfo; extern RSPInfo __RSP; extern u32 DepthClearColor; #define RSP_SegmentToPhysical( segaddr ) ((gSP.segment[(segaddr >> 24) & 0x0F] + (segaddr & RDRAMSize)) & RDRAMSize) void RSP_Init(void); void RSP_ProcessDList(void); void RSP_LoadMatrix( f32 mtx[4][4], u32 address ); void RSP_CheckDLCounter(void); #endif mupen64plus-video-gliden64/src/GLideNHQ/TxImage.h000664 001750 001750 00000006446 12655644434 022502 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __TXIMAGE_H__ #define __TXIMAGE_H__ #include #include #include "TxInternal.h" #ifndef WIN32 typedef struct tagBITMAPFILEHEADER { unsigned short bfType; unsigned long bfSize; unsigned short bfReserved1; unsigned short bfReserved2; unsigned long bfOffBits; } BITMAPFILEHEADER; typedef struct tagBITMAPINFOHEADER { unsigned long biSize; long biWidth; long biHeight; unsigned short biPlanes; unsigned short biBitCount; unsigned long biCompression; unsigned long biSizeImage; long biXPelsPerMeter; long biYPelsPerMeter; unsigned long biClrUsed; unsigned long biClrImportant; } BITMAPINFOHEADER; #else typedef struct tagBITMAPFILEHEADER BITMAPFILEHEADER; typedef struct tagBITMAPINFOHEADER BITMAPINFOHEADER; #endif #define DDSD_CAPS 0x00000001 #define DDSD_HEIGHT 0x00000002 #define DDSD_WIDTH 0x00000004 #define DDSD_PITCH 0x00000008 #define DDSD_PIXELFORMAT 0x00001000 #define DDSD_MIPMAPCOUNT 0x00020000 #define DDSD_LINEARSIZE 0x00080000 #define DDSD_DEPTH 0x00800000 #define DDPF_ALPHAPIXELS 0x00000001 #define DDPF_FOURCC 0x00000004 #define DDPF_RGB 0x00000040 #define DDSCAPS_COMPLEX 0x00000008 #define DDSCAPS_TEXTURE 0x00001000 #define DDSCAPS_MIPMAP 0x00400000 typedef struct tagDDSPIXELFORMAT { unsigned long dwSize; unsigned long dwFlags; unsigned long dwFourCC; unsigned long dwRGBBitCount; unsigned long dwRBitMask; unsigned long dwGBitMask; unsigned long dwBBitMask; unsigned long dwRGBAlphaBitMask; } DDSPIXELFORMAT; typedef struct tagDDSFILEHEADER { unsigned long dwMagic; unsigned long dwSize; unsigned long dwFlags; unsigned long dwHeight; unsigned long dwWidth; unsigned long dwLinearSize; unsigned long dwDepth; unsigned long dwMipMapCount; unsigned long dwReserved1[11]; DDSPIXELFORMAT ddpf; unsigned long dwCaps1; unsigned long dwCaps2; } DDSFILEHEADER; class TxImage { private: boolean getPNGInfo(FILE *fp, png_structp *png_ptr, png_infop *info_ptr); boolean getBMPInfo(FILE *fp, BITMAPFILEHEADER *bmp_fhdr, BITMAPINFOHEADER *bmp_ihdr); boolean getDDSInfo(FILE *fp, DDSFILEHEADER *dds_fhdr); public: TxImage() {} ~TxImage() {} uint8* readPNG(FILE* fp, int* width, int* height, uint16* format); boolean writePNG(uint8* src, FILE* fp, int width, int height, int rowStride, uint16 format, uint8 *palette); uint8* readBMP(FILE* fp, int* width, int* height, uint16* format); }; #endif /* __TXIMAGE_H__ */ gles2n64/src/glN64Config.c000664 001750 001750 00000017265 12655644434 016251 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - Config_nogui.cpp * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2008 Tillin9 * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #ifdef _MSC_VER #include #else #include #endif #include "Config.h" #include "gles2N64.h" #include "RSP.h" #include "Textures.h" #include "OpenGL.h" #include "../../libretro/SDL.h" #include "Config.h" #include "Common.h" Config config; typedef struct { const char* name; int* data; const int initial; } Option; #define CONFIG_VERSION 2 static Option configOptions[] = { {"#gles2n64 Graphics Plugin for N64", NULL, 0}, {"#by Orkin / glN64 developers and Adventus.", NULL, 0}, {"config version", &config.version, 0}, {"", NULL, 0}, {"#VI Settings:", NULL, 0}, {"video width", &config.video.width, 320}, {"video height", &config.video.height, 240}, {"", NULL, 0}, {"#Render Settings:", NULL, 0}, {"enable noise", &config.enableNoise, 1}, {"enable lod", &config.generalEmulation.enableLOD, 1}, {"", NULL, 0}, {"#Texture Settings:", NULL, 0}, {"texture max anisotropy", &config.texture.maxAnisotropy, 0}, {"texture use IA", &config.texture.useIA, 0}, {"texture fast CRC", &config.texture.fastCRC, 1}, {"bilinear mode", &config.texture.bilinearMode, 1}, {"", NULL, 0}, {"#Other Settings:", NULL, 0}, {"", NULL, 0}, {"#Hack Settings:", NULL, 0}, {"hack alpha", &config.hackAlpha, 0}, {"hack z", &config.zHack, 0}, }; static const int configOptionsSize = sizeof(configOptions) / sizeof(Option); static void Config_WriteConfig(const char *filename) { FILE *f; int i; config.version = CONFIG_VERSION; f = (FILE*)fopen(filename, "w"); if (!f && log_cb) log_cb(RETRO_LOG_ERROR, "Could Not Open %s for writing\n", filename); for(i = 0; i < configOptionsSize; i++) { Option *o = &configOptions[i]; fprintf(f, "%s", o->name); // __LIBRETRO__: Fix warning if (o->data) fprintf(f,"=%i", *(o->data)); fprintf(f, "\n"); } fclose(f); } static void Config_SetDefault(void) { int i; for(i = 0; i < configOptionsSize; i++) { Option *o = &configOptions[i]; if (o->data) *(o->data) = o->initial; } } static void Config_SetOption(char* line, char* val) { int i; for(i = 0; i < configOptionsSize; i++) { Option *o = &configOptions[i]; if (strcasecmp(line, o->name) == 0) { if (o->data) { int v = atoi(val); *(o->data) = v; if (log_cb) log_cb(RETRO_LOG_INFO, "Config Option: %s = %i\n", o->name, v); } break; } } } void Config_gln64_LoadRomConfig(unsigned char* header) { char line[4096]; int i; FILE *f; // get the name of the ROM for (i = 0; i < 20; i++) config.romName[i] = header[0x20+i]; config.romName[20] = '\0'; while (config.romName[strlen(config.romName)-1] == ' ') { config.romName[strlen(config.romName)-1] = '\0'; } switch(header[0x3e]) { // PAL codes case 0x44: case 0x46: case 0x49: case 0x50: case 0x53: case 0x55: case 0x58: case 0x59: config.romPAL = true; break; // NTSC codes case 0x37: case 0x41: case 0x45: case 0x4a: config.romPAL = false; break; // Fallback for unknown codes default: config.romPAL = false; } if (log_cb) log_cb(RETRO_LOG_INFO, "Rom is %s\n", config.romPAL ? "PAL" : "NTSC"); f = (FILE*)fopen(ConfigGetSharedDataFilepath("gles2n64rom.conf"),"r"); if (!f) { if (log_cb) log_cb(RETRO_LOG_INFO, "Could not find Rom settings file, using global.\n"); return; } else { bool isRom = false; if (log_cb) log_cb(RETRO_LOG_INFO, "[gles2N64]: Searching Database for \"%s\" ROM\n", config.romName); while (!feof(f)) { if (fgets(line, sizeof(line), f) == NULL) fputs("glN64 ROM config stream read error.\n", stderr); if (line[0] == '\n') continue; if (strncmp(line,"rom name=", 9) == 0) { //Depending on the editor, end lines could be terminated by "LF" or "CRLF" char* lf = strchr(line, '\n'); //Line Feed char* cr = strchr(line, '\r'); //Carriage Return if (lf) *lf='\0'; if (cr) *cr='\0'; isRom = (strcasecmp(config.romName, line+9) == 0); } else { if (isRom) { char* val = strchr(line, '='); if (!val) continue; *val++ = '\0'; Config_SetOption(line,val); if (log_cb) log_cb(RETRO_LOG_INFO, "%s = %s", line, val); } } } } fclose(f); } extern uint32_t screen_width; extern uint32_t screen_height; void Config_gln64_LoadConfig(void) { FILE *f; char line[4096]; const char *filename = ConfigGetSharedDataFilepath("gles2n64.conf"); // default configuration Config_SetDefault(); // __LIBRETRO__: Get screen size config.screen.width = screen_width; config.screen.height = screen_height; // read configuration f = (FILE*)fopen(filename, "r"); if (!f) { if (log_cb) { log_cb(RETRO_LOG_WARN, "[gles2N64]: Couldn't open config file '%s' for reading: %s\n", filename, strerror( errno ) ); log_cb(RETRO_LOG_WARN, "[gles2N64]: Attempting to write new Config \n"); } Config_WriteConfig(filename); } else { if (log_cb) log_cb(RETRO_LOG_INFO, "[gles2n64]: Loading Config from %s \n", filename); while (!feof( f )) { char *val; if (fgets(line, sizeof(line), f) == NULL) fputs("glN64 config stream read error.\n", stderr); if (line[0] == '#' || line[0] == '\n') continue; val = strchr( line, '=' ); if (!val) continue; *val++ = '\0'; Config_SetOption(line,val); } if (config.version < CONFIG_VERSION) { if (log_cb) log_cb(RETRO_LOG_WARN, "[gles2N64]: Wrong config version, rewriting config with defaults\n"); Config_SetDefault(); Config_WriteConfig(filename); } fclose(f); } } mupen64plus-core/tools/000700 001750 001750 00000000000 12656647145 016176 5ustar00sergiosergio000000 000000 mupen64plus-core/src/rdp/rdp_core.c000664 001750 001750 00000010755 12655644434 020374 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - rdp_core.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "rdp_core.h" #include "../memory/memory.h" #include "../plugin/plugin.h" #include "../r4300/r4300_core.h" #include "../rsp/rsp_core.h" #include static int update_dpc_status(struct rdp_core* dp, uint32_t w) { /* see do_SP_Task for more info */ int do_sp_task_on_unfreeze = 0; /* clear / set xbus_dmem_dma */ if (w & 0x1) dp->dpc_regs[DPC_STATUS_REG] &= ~0x1; if (w & 0x2) dp->dpc_regs[DPC_STATUS_REG] |= 0x1; /* clear / set freeze */ if (w & 0x4) { dp->dpc_regs[DPC_STATUS_REG] &= ~0x2; if (!(dp->sp->regs[SP_STATUS_REG] & 0x3)) // !halt && !broke do_sp_task_on_unfreeze = 1; } if (w & 0x8) dp->dpc_regs[DPC_STATUS_REG] |= 0x2; /* clear / set flush */ if (w & 0x10) dp->dpc_regs[DPC_STATUS_REG] &= ~0x4; if (w & 0x20) dp->dpc_regs[DPC_STATUS_REG] |= 0x4; return do_sp_task_on_unfreeze; } void connect_rdp(struct rdp_core* dp, struct r4300_core* r4300, struct rsp_core* sp, struct ri_controller *ri) { dp->r4300 = r4300; dp->sp = sp; dp->ri = ri; } void init_rdp(struct rdp_core* dp) { memset(dp->dpc_regs, 0, DPC_REGS_COUNT*sizeof(uint32_t)); memset(dp->dps_regs, 0, DPS_REGS_COUNT*sizeof(uint32_t)); init_fb(&dp->fb); } int read_dpc_regs(void* opaque, uint32_t address, uint32_t* value) { struct rdp_core* dp = (struct rdp_core*)opaque; uint32_t reg = DPC_REG(address); *value = dp->dpc_regs[reg]; return 0; } int write_dpc_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask) { struct rdp_core* dp = (struct rdp_core*)opaque; uint32_t reg = DPC_REG(address); switch(reg) { case DPC_STATUS_REG: if (update_dpc_status(dp, value & mask) != 0) do_SP_Task(dp->sp); case DPC_CURRENT_REG: case DPC_CLOCK_REG: case DPC_BUFBUSY_REG: case DPC_PIPEBUSY_REG: case DPC_TMEM_REG: return 0; } dp->dpc_regs[reg] = MASKED_WRITE(&dp->dpc_regs[reg], value, mask); switch(reg) { case DPC_START_REG: dp->dpc_regs[DPC_CURRENT_REG] = dp->dpc_regs[DPC_START_REG]; break; case DPC_END_REG: gfx.processRDPList(); signal_rcp_interrupt(dp->r4300, MI_INTR_DP); break; } return 0; } int read_dps_regs(void* opaque, uint32_t address, uint32_t* value) { struct rdp_core* dp = (struct rdp_core*)opaque; uint32_t reg = DPS_REG(address); *value = dp->dps_regs[reg]; return 0; } int write_dps_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask) { struct rdp_core* dp = (struct rdp_core*)opaque; uint32_t reg = DPS_REG(address); dp->dps_regs[reg] = MASKED_WRITE(&dp->dps_regs[reg], value, mask); return 0; } void rdp_interrupt_event(struct rdp_core* dp) { dp->dpc_regs[DPC_STATUS_REG] &= ~2; dp->dpc_regs[DPC_STATUS_REG] |= 0x81; raise_rcp_interrupt(dp->r4300, MI_INTR_DP); } glide2gl/src/Glide64/ucode09.h000664 001750 001750 00000053643 12655644434 017031 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** // // December 2008 Created by Gonetz (Gonetz@ngs.ru) // //**************************************************************** typedef float M44[4][4]; typedef struct { float view_scale[2]; float view_trans[2]; float scale_x; float scale_y; } ZSORTRDP; ZSORTRDP zSortRdp = {{0, 0}, {0, 0}, 0, 0}; //RSP command VRCPL static int Calc_invw (int w) { int count, neg; union { int32_t W; uint32_t UW; int16_t HW[2]; uint16_t UHW[2]; } Result; Result.W = w; if (Result.UW == 0) Result.UW = 0x7FFFFFFF; else { if (Result.W < 0) { neg = true; if (Result.UHW[1] == 0xFFFF && Result.HW[0] < 0) Result.W = ~Result.W + 1; else Result.W = ~Result.W; } else neg = false; for (count = 31; count > 0; count--) { if ((Result.W & (1 << count))) { Result.W &= (0xFFC00000 >> (31 - count) ); count = 0; } } Result.W = 0x7FFFFFFF / Result.W; for (count = 31; count > 0; count--) { if ((Result.W & (1 << count))) { Result.W &= (0xFFFF8000 >> (31 - count) ); count = 0; } } if (neg == true) Result.W = ~Result.W; } return Result.W; } static void uc9_draw_object (uint8_t * addr, uint32_t type) { uint32_t i, textured, vnum, vsize; VERTEX vtx[4], *pV[4]; switch (type) { case 0: //null textured = vnum = vsize = 0; break; case 1: //sh tri textured = 0; vnum = 3; vsize = 8; break; case 2: //tx tri textured = 1; vnum = 3; vsize = 16; break; case 3: //sh quad textured = 0; vnum = 4; vsize = 8; break; case 4: //tx quad textured = 1; vnum = 4; vsize = 16; break; } for (i = 0; i < vnum; i++) { VERTEX *v = (VERTEX*)&vtx[i]; v->sx = zSortRdp.scale_x * ((int16_t*)addr)[0^1]; v->sy = zSortRdp.scale_y * ((int16_t*)addr)[1^1]; v->sz = 1.0f; v->r = addr[4^3]; v->g = addr[5^3]; v->b = addr[6^3]; v->a = addr[7^3]; v->flags = 0; v->uv_scaled = 0; v->uv_calculated = 0xFFFFFFFF; v->shade_mod = 0; v->scr_off = 0; v->screen_translated = 2; if (textured) { v->ou = ((int16_t*)addr)[4^1]; v->ov = ((int16_t*)addr)[5^1]; v->w = Calc_invw(((int*)addr)[3]) / 31.0f; v->oow = 1.0f / v->w; //FRDP ("v%d - sx: %f, sy: %f ou: %f, ov: %f, w: %f, r=%d, g=%d, b=%d, a=%d\n", i, v->sx/rdp.scale_x, v->sy/rdp.scale_y, v->ou*rdp.tiles[rdp.cur_tile].s_scale, v->ov*rdp.tiles[rdp.cur_tile].t_scale, v->w, v->r, v->g, v->b, v->a); } else { v->oow = v->w = 1.0f; //FRDP ("v%d - sx: %f, sy: %f r=%d, g=%d, b=%d, a=%d\n", i, v->sx/rdp.scale_x, v->sy/rdp.scale_y, v->r, v->g, v->b, v->a); } addr += vsize; } //* pV[0] = &vtx[0]; pV[1] = &vtx[1]; pV[2] = &vtx[2]; pV[3] = &vtx[3]; cull_trianglefaces(pV, 1, false, false, 0); if (vnum != 3) cull_trianglefaces(pV + 1, 1, false, false, 0); } static uint32_t uc9_load_object (uint32_t zHeader, uint32_t * rdpcmds) { uint32_t type, w0, w1; uint8_t *addr; w0 = rdp.cmd0; w1 = rdp.cmd1; type = zHeader & 7; addr = gfx_info.RDRAM + (zHeader&0xFFFFFFF8); switch (type) { case 1: //sh tri case 3: //sh quad { rdp.cmd1 = ((uint32_t*)addr)[1]; if (rdp.cmd1 != rdpcmds[0]) { rdpcmds[0] = rdp.cmd1; uc9_rpdcmd(w0, w1); } update(); uc9_draw_object(addr + 8, type); } break; case 0: //null case 2: //tx tri case 4: //tx quad { rdp.cmd1 = ((uint32_t*)addr)[1]; if (rdp.cmd1 != rdpcmds[0]) { rdpcmds[0] = rdp.cmd1; uc9_rpdcmd(w0, w1); } rdp.cmd1 = ((uint32_t*)addr)[2]; if (rdp.cmd1 != rdpcmds[1]) { uc9_rpdcmd(w0, w1); rdpcmds[1] = rdp.cmd1; } rdp.cmd1 = ((uint32_t*)addr)[3]; if (rdp.cmd1 != rdpcmds[2]) { uc9_rpdcmd(w0, w1); rdpcmds[2] = rdp.cmd1; } if (type) { update(); uc9_draw_object(addr + 16, type); } } break; } return RSP_SegmentToPhysical(((uint32_t*)addr)[0]); } static void uc9_object(uint32_t w0, uint32_t w1) { uint32_t cmd1, zHeader; uint32_t rdpcmds[3]; rdpcmds[0] = 0; rdpcmds[1] = 0; rdpcmds[2] = 0; cmd1 = w1; zHeader = RSP_SegmentToPhysical(w0); while (zHeader) zHeader = uc9_load_object(zHeader, rdpcmds); zHeader = RSP_SegmentToPhysical(cmd1); while (zHeader) zHeader = uc9_load_object(zHeader, rdpcmds); } static void uc9_mix(uint32_t w0, uint32_t w1) { } static void uc9_fmlight(uint32_t w0, uint32_t w1) { uint32_t i, a; int mid; M44 *m; mid = w0 & 0xFF; gSPNumLights_G64(1 + _SHIFTR(w1, 12, 8)); a = -1024 + (w1 & 0xFFF); FRDP ("uc9:fmlight matrix: %d, num: %d, dmem: %04lx\n", mid, rdp.num_lights, a); switch (mid) { case 4: m = (M44*)rdp.model; break; case 6: m = (M44*)rdp.proj; break; case 8: m = (M44*)rdp.combined; break; } rdp.light[rdp.num_lights].col[0] = (float)(((uint8_t*)gfx_info.DMEM)[(a+0)^3]) / 255.0f; rdp.light[rdp.num_lights].col[1] = (float)(((uint8_t*)gfx_info.DMEM)[(a+1)^3]) / 255.0f; rdp.light[rdp.num_lights].col[2] = (float)(((uint8_t*)gfx_info.DMEM)[(a+2)^3]) / 255.0f; rdp.light[rdp.num_lights].col[3] = 1.0f; //FRDP ("ambient light: r: %.3f, g: %.3f, b: %.3f\n", rdp.light[rdp.num_lights].r, rdp.light[rdp.num_lights].g, rdp.light[rdp.num_lights].b); a += 8; for (i = 0; i < rdp.num_lights; i++) { rdp.light[i].col[0] = (float)(((uint8_t*)gfx_info.DMEM)[(a+0)^3]) / 255.0f; rdp.light[i].col[1] = (float)(((uint8_t*)gfx_info.DMEM)[(a+1)^3]) / 255.0f; rdp.light[i].col[2] = (float)(((uint8_t*)gfx_info.DMEM)[(a+2)^3]) / 255.0f; rdp.light[i].col[3] = 1.0f; rdp.light[i].dir[0] = (float)(((int8_t*)gfx_info.DMEM)[(a+8)^3]) / 127.0f; rdp.light[i].dir[1] = (float)(((int8_t*)gfx_info.DMEM)[(a+9)^3]) / 127.0f; rdp.light[i].dir[2] = (float)(((int8_t*)gfx_info.DMEM)[(a+10)^3]) / 127.0f; //FRDP ("light: n: %d, r: %.3f, g: %.3f, b: %.3f, x: %.3f, y: %.3f, z: %.3f\n", i, rdp.light[i].r, rdp.light[i].g, rdp.light[i].b, rdp.light[i].dir_x, rdp.light[i].dir_y, rdp.light[i].dir_z); InverseTransformVector(&rdp.light[i].dir[0], rdp.light_vector[i], *m); NormalizeVector (rdp.light_vector[i]); //FRDP ("light vector: n: %d, x: %.3f, y: %.3f, z: %.3f\n", i, rdp.light_vector[i][0], rdp.light_vector[i][1], rdp.light_vector[i][2]); a += 24; } for (i = 0; i < 2; i++) { float dir_x = (float)(((int8_t*)gfx_info.DMEM)[(a+8)^3]) / 127.0f; float dir_y = (float)(((int8_t*)gfx_info.DMEM)[(a+9)^3]) / 127.0f; float dir_z = (float)(((int8_t*)gfx_info.DMEM)[(a+10)^3]) / 127.0f; if (sqrt(dir_x*dir_x + dir_y*dir_y + dir_z*dir_z) < 0.98) { rdp.use_lookat = false; return; } rdp.lookat[i][0] = dir_x; rdp.lookat[i][1] = dir_y; rdp.lookat[i][2] = dir_z; a += 24; } rdp.use_lookat = true; } static void uc9_light(uint32_t w0, uint32_t w1) { VERTEX v; uint32_t i; uint32_t csrs = -1024 + ((w0 >> 12) & 0xFFF); uint32_t nsrs = -1024 + (w0 & 0xFFF); uint32_t num = 1 + ((w1 >> 24) & 0xFF); uint32_t cdest = -1024 + ((w1 >> 12) & 0xFFF); uint32_t tdest = -1024 + (w1 & 0xFFF); int use_material = (csrs != 0x0ff0); tdest >>= 1; FRDP ("uc9:light n: %d, colsrs: %04lx, normales: %04lx, coldst: %04lx, texdst: %04lx\n", num, csrs, nsrs, cdest, tdest); for (i = 0; i < num; i++) { v.vec[0] = ((int8_t*)gfx_info.DMEM)[(nsrs++)^3]; v.vec[1] = ((int8_t*)gfx_info.DMEM)[(nsrs++)^3]; v.vec[2] = ((int8_t*)gfx_info.DMEM)[(nsrs++)^3]; calc_sphere (&v); // calc_linear (&v); NormalizeVector (v.vec); calc_light(&v); v.a = 0xFF; if (use_material) { v.r = (uint8_t)(((uint32_t)v.r * gfx_info.DMEM[(csrs++)^3]) >> 8); v.g = (uint8_t)(((uint32_t)v.g * gfx_info.DMEM[(csrs++)^3]) >> 8); v.b = (uint8_t)(((uint32_t)v.b * gfx_info.DMEM[(csrs++)^3]) >> 8); v.a = gfx_info.DMEM[(csrs++)^3]; } gfx_info.DMEM[(cdest++)^3] = v.r; gfx_info.DMEM[(cdest++)^3] = v.g; gfx_info.DMEM[(cdest++)^3] = v.b; gfx_info.DMEM[(cdest++)^3] = v.a; ((int16_t*)gfx_info.DMEM)[(tdest++)^1] = (int16_t)v.ou; ((int16_t*)gfx_info.DMEM)[(tdest++)^1] = (int16_t)v.ov; } } static void uc9_mtxtrnsp(uint32_t w0, uint32_t w1) { /* M44 *s; switch (w1 & 0xF) { case 4: s = (M44*)rdp.model; LRDP("Model\n"); break; case 6: s = (M44*)rdp.proj; LRDP("Proj\n"); break; case 8: s = (M44*)rdp.combined; LRDP("Comb\n"); break; } float m = *s[1][0]; *s[1][0] = *s[0][1]; *s[0][1] = m; m = *s[2][0]; *s[2][0] = *s[0][2]; *s[0][2] = m; m = *s[2][1]; *s[2][1] = *s[1][2]; *s[1][2] = m; */ } static void uc9_mtxcat(uint32_t w0, uint32_t w1) { M44 *s; M44 *t; DECLAREALIGN16VAR(m[4][4]); uint32_t S = w0 & 0xF; uint32_t T = (w1 >> 16) & 0xF; uint32_t D = w1 & 0xF; switch (S) { case 4: s = (M44*)rdp.model; LRDP("Model * "); break; case 6: s = (M44*)rdp.proj; LRDP("Proj * "); break; case 8: s = (M44*)rdp.combined; LRDP("Comb * "); break; } switch (T) { case 4: t = (M44*)rdp.model; LRDP("Model -> "); break; case 6: t = (M44*)rdp.proj; LRDP("Proj -> "); break; case 8: LRDP("Comb -> "); t = (M44*)rdp.combined; break; } MulMatrices(*s, *t, m); switch (D) { case 4: memcpy (rdp.model, m, 64);; LRDP("Model\n"); break; case 6: memcpy (rdp.proj, m, 64);; LRDP("Proj\n"); break; case 8: memcpy (rdp.combined, m, 64);; LRDP("Comb\n"); break; } #ifdef EXTREME_LOGGING FRDP ("\nmodel\n{%f,%f,%f,%f}\n", rdp.model[0][0], rdp.model[0][1], rdp.model[0][2], rdp.model[0][3]); FRDP ("{%f,%f,%f,%f}\n", rdp.model[1][0], rdp.model[1][1], rdp.model[1][2], rdp.model[1][3]); FRDP ("{%f,%f,%f,%f}\n", rdp.model[2][0], rdp.model[2][1], rdp.model[2][2], rdp.model[2][3]); FRDP ("{%f,%f,%f,%f}\n", rdp.model[3][0], rdp.model[3][1], rdp.model[3][2], rdp.model[3][3]); FRDP ("\nproj\n{%f,%f,%f,%f}\n", rdp.proj[0][0], rdp.proj[0][1], rdp.proj[0][2], rdp.proj[0][3]); FRDP ("{%f,%f,%f,%f}\n", rdp.proj[1][0], rdp.proj[1][1], rdp.proj[1][2], rdp.proj[1][3]); FRDP ("{%f,%f,%f,%f}\n", rdp.proj[2][0], rdp.proj[2][1], rdp.proj[2][2], rdp.proj[2][3]); FRDP ("{%f,%f,%f,%f}\n", rdp.proj[3][0], rdp.proj[3][1], rdp.proj[3][2], rdp.proj[3][3]); FRDP ("\ncombined\n{%f,%f,%f,%f}\n", rdp.combined[0][0], rdp.combined[0][1], rdp.combined[0][2], rdp.combined[0][3]); FRDP ("{%f,%f,%f,%f}\n", rdp.combined[1][0], rdp.combined[1][1], rdp.combined[1][2], rdp.combined[1][3]); FRDP ("{%f,%f,%f,%f}\n", rdp.combined[2][0], rdp.combined[2][1], rdp.combined[2][2], rdp.combined[2][3]); FRDP ("{%f,%f,%f,%f}\n", rdp.combined[3][0], rdp.combined[3][1], rdp.combined[3][2], rdp.combined[3][3]); #endif } typedef struct { int16_t sy; int16_t sx; int invw; int16_t yi; int16_t xi; int16_t wi; uint8_t fog; uint8_t cc; } zSortVDest; static void uc9_mult_mpmtx(uint32_t w0, uint32_t w1) { int i, idx, num, src, dst; int16_t *saddr; zSortVDest v, *daddr; num = 1+ ((w1 >> 24) & 0xFF); src = -1024 + ((w1 >> 12) & 0xFFF); dst = -1024 + (w1 & 0xFFF); FRDP ("uc9:mult_mpmtx from: %04lx to: %04lx n: %d\n", src, dst, num); saddr = (int16_t*)(gfx_info.DMEM+src); daddr = (zSortVDest*)(gfx_info.DMEM+dst); idx = 0; memset(&v, 0, sizeof(zSortVDest)); //float scale_x = 4.0f/rdp.scale_x; //float scale_y = 4.0f/rdp.scale_y; for (i = 0; i < num; i++) { int16_t sx = saddr[(idx++)^1]; int16_t sy = saddr[(idx++)^1]; int16_t sz = saddr[(idx++)^1]; float x = sx*rdp.combined[0][0] + sy*rdp.combined[1][0] + sz*rdp.combined[2][0] + rdp.combined[3][0]; float y = sx*rdp.combined[0][1] + sy*rdp.combined[1][1] + sz*rdp.combined[2][1] + rdp.combined[3][1]; float z = sx*rdp.combined[0][2] + sy*rdp.combined[1][2] + sz*rdp.combined[2][2] + rdp.combined[3][2]; float w = sx*rdp.combined[0][3] + sy*rdp.combined[1][3] + sz*rdp.combined[2][3] + rdp.combined[3][3]; v.sx = (int16_t)(zSortRdp.view_trans[0] + x / w * zSortRdp.view_scale[0]); v.sy = (int16_t)(zSortRdp.view_trans[1] + y / w * zSortRdp.view_scale[1]); v.xi = (int16_t)x; v.yi = (int16_t)y; v.wi = (int16_t)w; v.invw = Calc_invw((int)(w * 31.0)); if (w < 0.0f) v.fog = 0; else { int fog = (int)(z / w * rdp.fog_multiplier + rdp.fog_offset); if (fog > 255) fog = 255; v.fog = (fog >= 0) ? (uint8_t)fog : 0; } v.cc = 0; if (x < -w) v.cc |= 0x10; if (x > w) v.cc |= 0x01; if (y < -w) v.cc |= 0x20; if (y > w) v.cc |= 0x02; if (w < 0.1f) v.cc |= 0x04; daddr[i] = v; //memcpy(gfx_info.DMEM+dst+sizeof(zSortVDest)*i, &v, sizeof(zSortVDest)); // FRDP("v%d x: %d, y: %d, z: %d -> sx: %d, sy: %d, w: %d, xi: %d, yi: %d, wi: %d, fog: %d\n", i, sx, sy, sz, v.sx, v.sy, v.invw, v.xi, v.yi, v.wi, v.fog); FRDP("v%d x: %d, y: %d, z: %d -> sx: %04lx, sy: %04lx, invw: %08lx - %f, xi: %04lx, yi: %04lx, wi: %04lx, fog: %04lx\n", i, sx, sy, sz, v.sx, v.sy, v.invw, w, v.xi, v.yi, v.wi, v.fog); } } static void uc9_link_subdl(uint32_t w0, uint32_t w1) { } static void uc9_set_subdl(uint32_t w0, uint32_t w1) { } static void uc9_wait_signal(uint32_t w0, uint32_t w1) { } static void uc9_send_signal(uint32_t w0, uint32_t w1) { } static void uc9_movemem(uint32_t w0, uint32_t w1) { int idx = w0 & 0x0E; int ofs = ((w0 >> 6) & 0x1ff)<<3; int len = (1 + ((w0 >> 15) & 0x1ff))<<3; int flag = w0 & 0x01; uint32_t addr = RSP_SegmentToPhysical(w1); switch (idx) { case 0: //save/load if (flag == 0) { int dmem_addr = (idx<<3) + ofs; FRDP ("Load to DMEM. %08lx -> %08lx\n", addr, dmem_addr); memcpy(gfx_info.DMEM + dmem_addr, gfx_info.RDRAM + addr, len); } else { int dmem_addr = (idx<<3) + ofs; FRDP ("Load from DMEM. %08lx -> %08lx\n", dmem_addr, addr); memcpy(gfx_info.RDRAM + addr, gfx_info.DMEM + dmem_addr, len); } break; case 4: // model matrix case 6: // projection matrix case 8: // combined matrix { DECLAREALIGN16VAR(m[4][4]); load_matrix(m, addr); switch (idx) { case 4: // model matrix modelview_load (m); break; case 6: // projection matrix projection_load (m); break; case 8: // projection matrix LRDP("Combined load\n"); g_gdp.flags &= ~UPDATE_MULT_MAT; memcpy (rdp.combined, m, 64);; break; } #ifdef EXTREME_LOGGING FRDP ("{%f,%f,%f,%f}\n", m[0][0], m[0][1], m[0][2], m[0][3]); FRDP ("{%f,%f,%f,%f}\n", m[1][0], m[1][1], m[1][2], m[1][3]); FRDP ("{%f,%f,%f,%f}\n", m[2][0], m[2][1], m[2][2], m[2][3]); FRDP ("{%f,%f,%f,%f}\n", m[3][0], m[3][1], m[3][2], m[3][3]); FRDP ("\nmodel\n{%f,%f,%f,%f}\n", rdp.model[0][0], rdp.model[0][1], rdp.model[0][2], rdp.model[0][3]); FRDP ("{%f,%f,%f,%f}\n", rdp.model[1][0], rdp.model[1][1], rdp.model[1][2], rdp.model[1][3]); FRDP ("{%f,%f,%f,%f}\n", rdp.model[2][0], rdp.model[2][1], rdp.model[2][2], rdp.model[2][3]); FRDP ("{%f,%f,%f,%f}\n", rdp.model[3][0], rdp.model[3][1], rdp.model[3][2], rdp.model[3][3]); FRDP ("\nproj\n{%f,%f,%f,%f}\n", rdp.proj[0][0], rdp.proj[0][1], rdp.proj[0][2], rdp.proj[0][3]); FRDP ("{%f,%f,%f,%f}\n", rdp.proj[1][0], rdp.proj[1][1], rdp.proj[1][2], rdp.proj[1][3]); FRDP ("{%f,%f,%f,%f}\n", rdp.proj[2][0], rdp.proj[2][1], rdp.proj[2][2], rdp.proj[2][3]); FRDP ("{%f,%f,%f,%f}\n", rdp.proj[3][0], rdp.proj[3][1], rdp.proj[3][2], rdp.proj[3][3]); #endif } break; case 10: LRDP("Othermode - IGNORED\n"); break; case 12: // VIEWPORT { int16_t scale_x, scale_y, scale_z, trans_x, trans_y, trans_z; uint32_t a; TILE *tmp_tile; a = addr >> 1; scale_x = ((int16_t*)gfx_info.RDRAM)[(a+0)^1] >> 2; scale_y = ((int16_t*)gfx_info.RDRAM)[(a+1)^1] >> 2; scale_z = ((int16_t*)gfx_info.RDRAM)[(a+2)^1]; rdp.fog_multiplier = ((int16_t*)gfx_info.RDRAM)[(a+3)^1]; trans_x = ((int16_t*)gfx_info.RDRAM)[(a+4)^1] >> 2; trans_y = ((int16_t*)gfx_info.RDRAM)[(a+5)^1] >> 2; trans_z = ((int16_t*)gfx_info.RDRAM)[(a+6)^1]; rdp.fog_offset = ((int16_t*)gfx_info.RDRAM)[(a+7)^1]; rdp.view_scale[0] = scale_x * rdp.scale_x; rdp.view_scale[1] = scale_y * rdp.scale_y; rdp.view_scale[2] = 32.0f * scale_z; rdp.view_trans[0] = trans_x * rdp.scale_x; rdp.view_trans[1] = trans_y * rdp.scale_y; rdp.view_trans[2] = 32.0f * trans_z; zSortRdp.view_scale[0] = (float)(scale_x*4); zSortRdp.view_scale[1] = (float)(scale_y*4); zSortRdp.view_trans[0] = (float)(trans_x*4); zSortRdp.view_trans[1] = (float)(trans_y*4); zSortRdp.scale_x = rdp.scale_x / 4.0f; zSortRdp.scale_y = rdp.scale_y / 4.0f; g_gdp.flags |= UPDATE_VIEWPORT; rdp.mipmap_level = 0; rdp.cur_tile = 0; tmp_tile = (TILE*)&rdp.tiles[0]; tmp_tile->on = 1; tmp_tile->org_s_scale = 0xFFFF; tmp_tile->org_t_scale = 0xFFFF; tmp_tile->s_scale = 0.031250f; tmp_tile->t_scale = 0.031250f; rdp.geom_mode |= 0x0200; FRDP ("viewport scale(%d, %d, %d), trans(%d, %d, %d), from:%08lx\n", scale_x, scale_y, scale_z, trans_x, trans_y, trans_z, a); FRDP ("fog: multiplier: %f, offset: %f\n", rdp.fog_multiplier, rdp.fog_offset); } break; default: FRDP ("** UNKNOWN %d\n", idx); } } static void uc9_setscissor(uint32_t w0, uint32_t w1) { rdp_setscissor(w0, w1); if ((g_gdp.__clip.xl - g_gdp.__clip.xh) > (zSortRdp.view_scale[0] - zSortRdp.view_trans[0])) { TILE *tmp_tile; float w = (g_gdp.__clip.xl - g_gdp.__clip.xh) / 2.0f; float h = (g_gdp.__clip.yl - g_gdp.__clip.yh) / 2.0f; rdp.view_scale[0] = w * rdp.scale_x; rdp.view_scale[1] = h * rdp.scale_y; rdp.view_trans[0] = w * rdp.scale_x; rdp.view_trans[1] = h * rdp.scale_y; zSortRdp.view_scale[0] = w * 4.0f; zSortRdp.view_scale[1] = h * 4.0f; zSortRdp.view_trans[0] = w * 4.0f; zSortRdp.view_trans[1] = h * 4.0f; zSortRdp.scale_x = rdp.scale_x / 4.0f; zSortRdp.scale_y = rdp.scale_y / 4.0f; g_gdp.flags |= UPDATE_VIEWPORT; rdp.mipmap_level = 0; rdp.cur_tile = 0; tmp_tile = (TILE*)&rdp.tiles[0]; tmp_tile->on = 1; tmp_tile->org_s_scale = 0xFFFF; tmp_tile->org_t_scale = 0xFFFF; tmp_tile->s_scale = 0.031250f; tmp_tile->t_scale = 0.031250f; rdp.geom_mode |= 0x0200; } } mupen64plus-core/tools/regtests/000700 001750 001750 00000000000 12656647145 020036 5ustar00sergiosergio000000 000000 mupen64plus-video-gliden64/ini/GLideN64.custom.ini000664 001750 001750 00000023266 12655644434 022715 0ustar00sergiosergio000000 000000 ; Custom game settings [General] version=5 [TWINE] Good_Name=007 - The World Is Not Enough (E)(U) frameBufferEmulation\N64DepthCompare=1 [1080%20SNOWBOARDING] Good_Name=1080 Snowboarding (E)(JU) frameBufferEmulation\copyToRDRAM=2 frameBufferEmulation\copyDepthToRDRAM=1 [6D120CBF] Good_Name=64 De Hakken!! Tamagotchi - Minna De Tamagotchi World (J) [68DD0BB5] Good_Name=64 Hanafuda - Tenshi No Yakusoku (J) [1F580575] Good_Name=64 Oozumou 2 (J) [1333047D] Good_Name=AI Shougi 3 (J) [30080737] Good_Name=Air Boarder 64 (J) [44BB08DC] Good_Name=Bakushou Jinsei 64 - Mezase! Resort Ou (J) [BANJO-KAZOOIE] Good_Name=Banjo-Kazooie (E)(U) / Banjo To Kazooie No Daibouken (J) frameBufferEmulation\copyToRDRAM=2 [BANJO%20KAZOOIE%202] Good_Name=Banjo to Kazooie no Daibouken 2 (J) frameBufferEmulation\copyToRDRAM=2 [BANJO%20TOOIE] Good_Name=Banjo-Tooie (E)(U) frameBufferEmulation\copyToRDRAM=2 [BEETLE%20ADVENTURE%20RAC] Good_Name=Beetle Adventure Racing (E)(U) frameBufferEmulation\copyToRDRAM=2 frameBufferEmulation\copyDepthToRDRAM=1 [BEETLE%20ADVENTURE%20JP] Good_Name=Beetle Adventure Racing (J) frameBufferEmulation\copyToRDRAM=2 frameBufferEmulation\copyDepthToRDRAM=1 [BIOFREAKS] Good_Name=Bio F.R.E.A.K.S. (E)(U) frameBufferEmulation\copyToRDRAM=1 frameBufferEmulation\detectCFB=1 [BIOHAZARD%20II] Good_Name=Biohazard 2 (J) frameBufferEmulation\detectCFB=1 [52150A67] Good_Name=Bokujou Monogatari 2 (J) frameBufferEmulation\N64DepthCompare=1 [476C09C1] Good_Name=Bomberman Hero - Mirian Oujo Wo Sukue! (J) [13E50365] Good_Name=Choro Q 64 2 - Hacha Mecha Grand Prix Race (J) [CASTLEVANIA] Good_Name=Castlevania (E)(U) frameBufferEmulation\copyToRDRAM=2 [CASTLEVANIA2] Good_Name=Castlevania - Legacy Of Darkness (E)(U) frameBufferEmulation\copyToRDRAM=1 [3D9F08DB] Good_Name=Chou Kuukan Nighter Pro Yakyuu King 2 (J) [31DC0863] Good_Name=Chou Snobow Kids (J) [CONKER%20BFD] Good_Name=Conker's Bad Fur Day (E)(U) frameBufferEmulation\copyToRDRAM=2 frameBufferEmulation\copyDepthToRDRAM=1 [362D06B6] Good_Name=Densha de Go! 64 (J) [DONALD%20DUCK%20GOIN%27%20QU] Good_Name=Donald Duck - Goin' Quackers (U) frameBufferEmulation\copyToRDRAM=2 frameBufferEmulation\detectCFB=1 frameBufferEmulation\copyDepthToRDRAM=1 [DONALD%20DUCK%20QUACK%20AT] Good_Name=Donald Duck - Quack Attack (E) frameBufferEmulation\copyToRDRAM=2 frameBufferEmulation\detectCFB=1 frameBufferEmulation\copyDepthToRDRAM=1 [DONKEY%20KONG%2064] Good_Name=Donkey Kong 64 (E)(J)(U) frameBufferEmulation\copyToRDRAM=1 frameBufferEmulation\detectCFB=1 frameBufferEmulation\copyDepthToRDRAM=1 [D%20K%20DISPLAY] Good_Name=Donkey Kong 64 Kiosk Demo (U) frameBufferEmulation\copyToRDRAM=1 frameBufferEmulation\detectCFB=1 frameBufferEmulation\copyDepthToRDRAM=1 [72390C86] Good_Name=Doraemon - Nobita To 3tsu No Seireiseki (J) [6E3D0C76] Good_Name=Doraemon 2 - Nobita To Hikari No Shinden (J) [84CE0BDF] Good_Name=Doraemon 3 - Nobita No Machi SOS! (J) [DR.MARIO%2064] Good_Name=Dr. Mario 64 (U) frameBufferEmulation\copyFromRDRAM=1 [67000C2B] Good_Name=Eikou No Saint Andrews (J) [EXCITEBIKE64] frameBufferEmulation\copyDepthToRDRAM=1 [EXTREME_G] Good_Name=Extreme-G (E) frameBufferEmulation\N64DepthCompare=1 [EXTREME-G] Good_Name=Extreme-G (J) frameBufferEmulation\N64DepthCompare=1 [EXTREMEG] Good_Name=Extreme-G (U) frameBufferEmulation\N64DepthCompare=1 [208E05CD] Good_Name=Extreme-G XG2 (J) [F1%20POLE%20POSITION%2064] Good_Name=F-1 Pole Position 64 (E)(U) frameBufferEmulation\copyToRDRAM=1 [F-ZERO%20X] Good_Name=F-Zero X (E)(J)(U) frameBufferEmulation\copyToRDRAM=2 [18000458] Good_Name=Famista 64 (J) [2997071D] Good_Name=Fushigi No Dungeon - Fuurai No Shiren 2 - Oni Shuurai! Shiren Jou! (J) [3BE3091D] Good_Name=Ganbare Goemon - Neo Momoyama Bakufu No Odori (J) [53900B10] Good_Name=Goemon - Mononoke Sugoroku (J) [457A0908] Good_Name=Hamster Monogatari 64 (J) [HARVESTMOON64] Good_Name=Harvest Moon 64 (U) frameBufferEmulation\N64DepthCompare=1 [5CFA0A2E] Good_Name=Heiwa Pachinko World 64 (J) frameBufferEmulation\copyToRDRAM=1 [HEXEN] Good_Name=Hexen (E)(F)(G)(J)(U) frameBufferEmulation\copyToRDRAM=1 frameBufferEmulation\detectCFB=1 [30AB07E1] Good_Name=Hiryuu No Ken Twin (J) [HSV%20ADVENTURE%20RACING] Good_Name=HSV Adventure Racing (A) frameBufferEmulation\copyToRDRAM=2 frameBufferEmulation\copyDepthToRDRAM=1 [83CA0DCA] Good_Name=Ide Yousuke No Mahjong Juku (J) [I%20S%20S%2064] Good_Name=International Superstar Soccer 64 (E) (U) frameBufferEmulation\N64DepthCompare=1 [43CC08A2] Good_Name=J.League Dynamite Soccer 64 (J) [7EA50BA0] Good_Name=J.League Eleven Beat 1997 (J) [31E0076F] Good_Name=Jangou Simulation Mahjong Dou 64 (J) [JET%20FORCE%20GEMINI] Good_Name=Jet Force Gemini (E)(U) ; Show all crosshair reticules and miscellaneous graphics frameBufferEmulation\copyFromRDRAM=1 ; Required for character select monitor and possibly other effects, but disabled due to #378 frameBufferEmulation\copyToRDRAM=0 [J%20F%20G%20DISPLAY] ; See Jet Force Gemini for notes Good_Name=Jet Force Gemini Kiosk Demo (U) frameBufferEmulation\copyFromRDRAM=1 frameBufferEmulation\copyToRDRAM=0 [PERFECT%20STRIKER] Good_Name=Jikkyou J.League Perfect Striker (J) frameBufferEmulation\N64DepthCompare=1 [713F0C09] Good_Name=Kiratto Kaiketsu! 64 Tanteidan (J) [LEGORACERS] Good_Name=Lego Racers (E)(U) frameBufferEmulation\copyToRDRAM=2 frameBufferEmulation\detectCFB=1 [76910A78] Good_Name=Mahjong Hourouki Classic (J) [301E07CC] Good_Name=Mahjong Master (J) frameBufferEmulation\N64DepthCompare=1 [MARIOGOLF64] Good_Name=Mario Golf (E)(J)(U) frameBufferEmulation\copyToRDRAM=2 frameBufferEmulation\copyDepthToRDRAM=1 [MARIOKART64] Good_Name=Mario Kart 64 (E)(J)(U) frameBufferEmulation\copyToRDRAM=2 [2B6D07C8] Good_Name=Mario No Photopi (J) [MARIO%20STORY] Good_Name=Mario Story (J) frameBufferEmulation\copyToRDRAM=2 [MARIOTENNIS] Good_Name=Mario Tennis (E)(U) frameBufferEmulation\copyToRDRAM=2 [MARIOTENNIS64] Good_Name=Mario Tennis 64 (J) frameBufferEmulation\copyToRDRAM=2 [MICKEY%20USA%20PAL] Good_Name=Mickey's Speedway USA (E) frameBufferEmulation\copyDepthToRDRAM=1 frameBufferEmulation\copyToRDRAM=2 [MICKEY%20USA] Good_Name=Mickey's Speedway USA (U) / Mickey No Racing Challenge USA (J) frameBufferEmulation\copyDepthToRDRAM=1 frameBufferEmulation\copyToRDRAM=2 [293D0695] Good_Name=Morita Shougi 64 (J) [MS.%20PAC-MAN%20MM] Good_Name=Ms. Pac-Man - Maze Madness (U) frameBufferEmulation\detectCFB=1 [14B30473] Good_Name=Nushi Duri 64 (J) [5E5A0B37] Good_Name=Nushi Duri 64 - Shiokaze Ni Notte (J) [PAPER%20MARIO] Good_Name=Paper Mario (E)(U) frameBufferEmulation\copyToRDRAM=2 [PENNY%20RACERS] Good_Name=Penny Racers (E)(U) frameBufferEmulation\copyToRDRAM=0 [PERFECT%20DARK] Good_Name=Perfect Dark (E)(J)(U) frameBufferEmulation\copyToRDRAM=2 frameBufferEmulation\copyDepthToRDRAM=1 [PUZZLE%20LEAGUE%20N64] Good_Name=Pokemon Puzzle League (E)(F)(G)(U) frameBufferEmulation\detectCFB=1 [POKEMON%20SNAP] Good_Name=Pokemon Snap (U) frameBufferEmulation\copyToRDRAM=1 [POKEMON%20STADIUM%202] Good_Name=Pokemon Stadium 2 (E)(F)(G)(I)(J)(S)(U) frameBufferEmulation\copyToRDRAM=0 [POKEMON%20STADIUM%20G&S] Good_Name=Pokemon Stadium Kin Gin (J) frameBufferEmulation\copyToRDRAM=0 [QUAKE%20II] Good_Name=Quake II (U) ; set to 1 for correct HUD in pause menu frameBufferEmulation\copyToRDRAM=2 [RAYMAN%202] Good_Name=Rayman 2 - The Great Escape (E)(U) frameBufferEmulation\copyToRDRAM=2 frameBufferEmulation\detectCFB=1 [RESIDENT%20EVIL%20II] Good_Name=Resident Evil 2 (E)(U) frameBufferEmulation\detectCFB=1 [437009B9] Good_Name=Saikyou Habu Shougi (J) [RUSH%202049] Good_Name=San Francisco Rush 2049 (E)(U) frameBufferEmulation\copyToRDRAM=0 [1C500641] Good_Name=Snobow Kids (J) [SPACE%20INVADERS] Good_Name=Space Invaders (U) frameBufferEmulation\copyToRDRAM=0 [STARCRAFT%2064] Good_Name=Star Craft 64 (E)(G)(U) frameBufferEmulation\detectCFB=1 [75DA0AC4] Good_Name=Star Craft 64 (U) frameBufferEmulation\detectCFB=1 [STAR%20TWINS] ; See Jet Force Gemini for notes Good_Name=Star Twins (J) frameBufferEmulation\copyFromRDRAM=1 frameBufferEmulation\copyToRDRAM=0 [STAR%20WARS%20EP1%20RACER] Good_Name=Star Wars Episode I - Racer (E)(U)(J) frameBufferEmulation\copyDepthToRDRAM=1 [67ED0B45] Good_Name=Super Robot Taisen 64 (J) [622D0C12] Good_Name=Susume! Taisen Puzzle Dama - Toukon! Marutama Chou (J) [TWISTED%20EDGE] frameBufferEmulation\copyDepthToRDRAM=1 [ZELDA%20MAJORA%27S%20MASK] Good_Name=The Legend Of Zelda - Majora's Mask (E)(U) / Zelda No Densetsu - Mujura No Karmen (J) frameBufferEmulation\copyToRDRAM=2 frameBufferEmulation\copyDepthToRDRAM=1 [MAJORA%27S%20MASK] Good_Name=The Legend Of Zelda - Majora's Mask Demo (U) frameBufferEmulation\copyToRDRAM=2 frameBufferEmulation\copyDepthToRDRAM=1 [THE%20LEGEND%20OF%20ZELDA] Good_Name=The Legend Of Zelda - Ocarina Of Time (E)(U) / Zelda No Densetsu - Toki No Ocarina (J) frameBufferEmulation\detectCFB=0 frameBufferEmulation\copyDepthToRDRAM=1 [ZELDA%20MASTER%20QUEST] Good_Name=The Legend Of Zelda - Ocarina Of Time - Master Quest frameBufferEmulation\detectCFB=0 frameBufferEmulation\copyDepthToRDRAM=1 [TIGGER%27S%20HONEY%20HUNT] Good_Name=Tigger's Honey Hunt (E)(U) frameBufferEmulation\N64DepthCompare=1 [TONIC%20TROUBLE] Good_Name=Tonic Trouble (E)(U) frameBufferEmulation\copyToRDRAM=1 frameBufferEmulation\detectCFB=1 [48460A35] Good_Name=Ucchan Nanchan No Hono No Challenger - Denryuu Ira Ira Bou (J) [VIGILANTE%208] Good_Name=Vigilante 8 (E)(F)(G)(U) frameBufferEmulation\copyDepthToRDRAM=1 [4C2E093B] Good_Name=Virtual Pro Wrestling 2 - Oudou Keishou (J) [8B6F0CBE] Good_Name=Virtual Pro Wrestling 64 (J) [34060655] Good_Name=WWF Wrestlemania 2000 (J) [THE%20MASK%20OF%20MUJURA] Good_Name=Zelda No Densetsu - Mujura No Karmen (J) frameBufferEmulation\copyToRDRAM=2 frameBufferEmulation\copyDepthToRDRAM=1 [7BC50D43] Good_Name=Zool - Majuu Tsukai Densetsu (J) gles2rice/README000664 001750 001750 00000007056 12655644434 014466 0ustar00sergiosergio000000 000000 =============================================================================== ------------------------------------------------------------------------------- Mupen64plus-video-rice README v2.0 ------------------------------------------------------------------------------- =============================================================================== The latest version of this document can be found online at: https://code.google.com/p/mupen64plus/wiki/HighResolutionTextures ------------------------------------------------------------------------------- ABOUT ------------------------------------------------------------------------------- Mupen64Plus's Rice Video plugin supports a very nice feature which allows the user to replace all of the original textures used for 3D rendering in a game with high-resolution replacement textures drawn by graphic artists. ------------------------------------------------------------------------------- Enable Hi-Res Texture Loading in Rice Video ------------------------------------------------------------------------------- In order to begin using the hi-resolution texture feature, you must enable it by editing the Mupen64Plus config file. One option is to find the file and edit it directly with a text editor. On Linux or OSX, this is located at: "~/.config/ mupen64plus/", and on Windows it is in the "Application Data" sub-folder of your user folder. On Windows XP and prior, this is "C:\Documents and Settings\ \Application Data\Mupen64Plus\", while on Windows Vista and newer this is "C:\Users\\AppData\Mupen64Plus". You should find a section in this file labeled [Video-Rice], and within this section is a parameter called LoadHiResTextures. Set this to True to enable searching for and loading high- resolution textures. Another option to enable this feature is to use the --set option with the Mupen64Plus command-line user interface. To do this, run a game with a command similar to this: ./mupen64plus --set Video-Rice[LoadHiResTextures]=True --saveoptions m64p_test_rom.v64 ------------------------------------------------------------------------------- Installing Hi-Res Texture Files ------------------------------------------------------------------------------- To install a high-resolution texture pack for a game, all that you need to do is unzip the archive and put the extracted directory full of images into the right place. On Linux and OSX, this is usually "/home//.local/share/ mupen64plus/hires_texture". On Windows it is in the "Application Data" sub- folder of your user folder. On Windows XP and prior, this is "C:\Documents and Settings\\Application Data\Mupen64Plus\hires_texture", while on Windows Vista and newer this is "C:\Users\\AppData\Mupen64Plus\ hires_texture". If this directory doesn't exist, create it and copy the hi-res texture directory inside. The folder containing hi-res textures must be named exactly the same as the ROM's name in the header of the ROM file. Usually this name is short with all capital letters, like "MARIOKART64" or "SMASH BROTHERS". The command-line UI prints out this ROM name when running a game, right after the Goodname and before the MD5. ------------------------------------------------------------------------------- Running ------------------------------------------------------------------------------- After setup, just run the game as usual. If using the command-line UI, you should see a line printed out which says: Video: Texture loading option is enabled. Finding all hires textures mupen64plus-video-gliden64/src/mupenplus/GLideN64_mupenplus.h000664 001750 001750 00000004232 12655644434 025214 0ustar00sergiosergio000000 000000 #ifndef GLIDEN64_MUPENPLUS_H #define GLIDEN64_MUPENPLUS_H #include "m64p_config.h" #include "m64p_vidext.h" #define PLUGIN_VERSION 0x020000 #define VIDEO_PLUGIN_API_VERSION 0x020200 #define CONFIG_API_VERSION 0x020000 #define VIDEXT_API_VERSION 0x030000 /* definitions of pointers to Core config functions */ extern ptr_ConfigOpenSection ConfigOpenSection; extern ptr_ConfigDeleteSection ConfigDeleteSection; extern ptr_ConfigSaveSection ConfigSaveSection; extern ptr_ConfigSaveFile ConfigSaveFile; extern ptr_ConfigSetParameter ConfigSetParameter; extern ptr_ConfigGetParameter ConfigGetParameter; extern ptr_ConfigGetParameterHelp ConfigGetParameterHelp; extern ptr_ConfigSetDefaultInt ConfigSetDefaultInt; extern ptr_ConfigSetDefaultFloat ConfigSetDefaultFloat; extern ptr_ConfigSetDefaultBool ConfigSetDefaultBool; extern ptr_ConfigSetDefaultString ConfigSetDefaultString; extern ptr_ConfigGetParamInt ConfigGetParamInt; extern ptr_ConfigGetParamFloat ConfigGetParamFloat; extern ptr_ConfigGetParamBool ConfigGetParamBool; extern ptr_ConfigGetParamString ConfigGetParamString; extern ptr_ConfigGetSharedDataFilepath ConfigGetSharedDataFilepath; extern ptr_ConfigGetUserConfigPath ConfigGetUserConfigPath; extern ptr_ConfigGetUserDataPath ConfigGetUserDataPath; extern ptr_ConfigGetUserCachePath ConfigGetUserCachePath; extern ptr_VidExt_Init CoreVideo_Init; extern ptr_VidExt_Quit CoreVideo_Quit; extern ptr_VidExt_ListFullscreenModes CoreVideo_ListFullscreenModes; extern ptr_VidExt_SetVideoMode CoreVideo_SetVideoMode; extern ptr_VidExt_SetCaption CoreVideo_SetCaption; extern ptr_VidExt_ToggleFullScreen CoreVideo_ToggleFullScreen; extern ptr_VidExt_ResizeWindow CoreVideo_ResizeWindow; extern ptr_VidExt_GL_GetProcAddress CoreVideo_GL_GetProcAddress; extern ptr_VidExt_GL_SetAttribute CoreVideo_GL_SetAttribute; extern ptr_VidExt_GL_GetAttribute CoreVideo_GL_GetAttribute; extern ptr_VidExt_GL_SwapBuffers CoreVideo_GL_SwapBuffers; extern void(*renderCallback)(int); #endif // GLIDEN64_MUPENPLUS_H mupen64plus-rsp-hle/src/jpeg.c000664 001750 001750 00000047731 12655644434 017365 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-rsp-hle - jpeg.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2012 Bobby Smiles * * Copyright (C) 2009 Richard Goedeken * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include "arithmetics.h" #include "hle_external.h" #include "hle_internal.h" #include "memory.h" #define SUBBLOCK_SIZE 64 typedef void (*tile_line_emitter_t)(struct hle_t* hle, const int16_t *y, const int16_t *u, uint32_t address); typedef void (*subblock_transform_t)(int16_t *dst, const int16_t *src); /* standard jpeg ucode decoder */ static void jpeg_decode_std(struct hle_t* hle, const char *const version, const subblock_transform_t transform_luma, const subblock_transform_t transform_chroma, const tile_line_emitter_t emit_line); /* helper functions */ static uint8_t clamp_u8(int16_t x); static int16_t clamp_s12(int16_t x); static uint16_t clamp_RGBA_component(int16_t x); /* pixel conversion & formatting */ static uint32_t GetUYVY(int16_t y1, int16_t y2, int16_t u, int16_t v); static uint16_t GetRGBA(int16_t y, int16_t u, int16_t v); /* tile line emitters */ static void EmitYUVTileLine(struct hle_t* hle, const int16_t *y, const int16_t *u, uint32_t address); static void EmitRGBATileLine(struct hle_t* hle, const int16_t *y, const int16_t *u, uint32_t address); /* macroblocks operations */ static void decode_macroblock_ob(int16_t *macroblock, int32_t *y_dc, int32_t *u_dc, int32_t *v_dc, const int16_t *qtable); static void decode_macroblock_std(const subblock_transform_t transform_luma, const subblock_transform_t transform_chroma, int16_t *macroblock, unsigned int subblock_count, const int16_t qtables[3][SUBBLOCK_SIZE]); static void EmitTilesMode0(struct hle_t* hle, const tile_line_emitter_t emit_line, const int16_t *macroblock, uint32_t address); static void EmitTilesMode2(struct hle_t* hle, const tile_line_emitter_t emit_line, const int16_t *macroblock, uint32_t address); /* subblocks operations */ static void TransposeSubBlock(int16_t *dst, const int16_t *src); static void ZigZagSubBlock(int16_t *dst, const int16_t *src); static void ReorderSubBlock(int16_t *dst, const int16_t *src, const unsigned int *table); static void MultSubBlocks(int16_t *dst, const int16_t *src1, const int16_t *src2, unsigned int shift); static void ScaleSubBlock(int16_t *dst, const int16_t *src, int16_t scale); static void RShiftSubBlock(int16_t *dst, const int16_t *src, unsigned int shift); static void InverseDCT1D(const float *const x, float *dst, unsigned int stride); static void InverseDCTSubBlock(int16_t *dst, const int16_t *src); static void RescaleYSubBlock(int16_t *dst, const int16_t *src); static void RescaleUVSubBlock(int16_t *dst, const int16_t *src); /* transposed dequantization table */ static const int16_t DEFAULT_QTABLE[SUBBLOCK_SIZE] = { 16, 12, 14, 14, 18, 24, 49, 72, 11, 12, 13, 17, 22, 35, 64, 92, 10, 14, 16, 22, 37, 55, 78, 95, 16, 19, 24, 29, 56, 64, 87, 98, 24, 26, 40, 51, 68, 81, 103, 112, 40, 58, 57, 87, 109, 104, 121, 100, 51, 60, 69, 80, 103, 113, 120, 103, 61, 55, 56, 62, 77, 92, 101, 99 }; /* zig-zag indices */ static const unsigned int ZIGZAG_TABLE[SUBBLOCK_SIZE] = { 0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53, 10, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63 }; /* transposition indices */ static const unsigned int TRANSPOSE_TABLE[SUBBLOCK_SIZE] = { 0, 8, 16, 24, 32, 40, 48, 56, 1, 9, 17, 25, 33, 41, 49, 57, 2, 10, 18, 26, 34, 42, 50, 58, 3, 11, 19, 27, 35, 43, 51, 59, 4, 12, 20, 28, 36, 44, 52, 60, 5, 13, 21, 29, 37, 45, 53, 61, 6, 14, 22, 30, 38, 46, 54, 62, 7, 15, 23, 31, 39, 47, 55, 63 }; /* IDCT related constants * Cn = alpha * cos(n * PI / 16) (alpha is chosen such as C4 = 1) */ static const float IDCT_C3 = 1.175875602f; static const float IDCT_C6 = 0.541196100f; static const float IDCT_K[10] = { 0.765366865f, /* C2-C6 */ -1.847759065f, /* -C2-C6 */ -0.390180644f, /* C5-C3 */ -1.961570561f, /* -C5-C3 */ 1.501321110f, /* C1+C3-C5-C7 */ 2.053119869f, /* C1+C3-C5+C7 */ 3.072711027f, /* C1+C3+C5-C7 */ 0.298631336f, /* -C1+C3+C5-C7 */ -0.899976223f, /* C7-C3 */ -2.562915448f /* -C1-C3 */ }; /* global functions */ /*************************************************************************** * JPEG decoding ucode found in Japanese exclusive version of Pokemon Stadium. **************************************************************************/ void jpeg_decode_PS0(struct hle_t* hle) { jpeg_decode_std(hle, "PS0", RescaleYSubBlock, RescaleUVSubBlock, EmitYUVTileLine); } /*************************************************************************** * JPEG decoding ucode found in Ocarina of Time, Pokemon Stadium 1 and * Pokemon Stadium 2. **************************************************************************/ void jpeg_decode_PS(struct hle_t* hle) { jpeg_decode_std(hle, "PS", NULL, NULL, EmitRGBATileLine); } /*************************************************************************** * JPEG decoding ucode found in Ogre Battle and Bottom of the 9th. **************************************************************************/ void jpeg_decode_OB(struct hle_t* hle) { int16_t qtable[SUBBLOCK_SIZE]; unsigned int mb; int32_t y_dc = 0; int32_t u_dc = 0; int32_t v_dc = 0; uint32_t address = *dmem_u32(hle, TASK_DATA_PTR); const unsigned int macroblock_count = *dmem_u32(hle, TASK_DATA_SIZE); const int qscale = *dmem_u32(hle, TASK_YIELD_DATA_SIZE); HleVerboseMessage(hle->user_defined, "jpeg_decode_OB: *buffer=%x, #MB=%d, qscale=%d", address, macroblock_count, qscale); if (qscale != 0) { if (qscale > 0) ScaleSubBlock(qtable, DEFAULT_QTABLE, qscale); else RShiftSubBlock(qtable, DEFAULT_QTABLE, -qscale); } for (mb = 0; mb < macroblock_count; ++mb) { int16_t macroblock[6 * SUBBLOCK_SIZE]; dram_load_u16(hle, (uint16_t *)macroblock, address, 6 * SUBBLOCK_SIZE); decode_macroblock_ob(macroblock, &y_dc, &u_dc, &v_dc, (qscale != 0) ? qtable : NULL); EmitTilesMode2(hle, EmitYUVTileLine, macroblock, address); address += (2 * 6 * SUBBLOCK_SIZE); } } /* local functions */ static void jpeg_decode_std(struct hle_t* hle, const char *const version, const subblock_transform_t transform_luma, const subblock_transform_t transform_chroma, const tile_line_emitter_t emit_line) { int16_t qtables[3][SUBBLOCK_SIZE]; unsigned int mb; uint32_t address; uint32_t macroblock_count; uint32_t mode; uint32_t qtableY_ptr; uint32_t qtableU_ptr; uint32_t qtableV_ptr; unsigned int subblock_count; unsigned int macroblock_size; /* macroblock contains at most 6 subblocks */ int16_t macroblock[6 * SUBBLOCK_SIZE]; uint32_t data_ptr; if (*dmem_u32(hle, TASK_FLAGS) & 0x1) { HleWarnMessage(hle->user_defined, "jpeg_decode_%s: task yielding not implemented", version); return; } data_ptr = *dmem_u32(hle, TASK_DATA_PTR); address = *dram_u32(hle, data_ptr); macroblock_count = *dram_u32(hle, data_ptr + 4); mode = *dram_u32(hle, data_ptr + 8); qtableY_ptr = *dram_u32(hle, data_ptr + 12); qtableU_ptr = *dram_u32(hle, data_ptr + 16); qtableV_ptr = *dram_u32(hle, data_ptr + 20); HleVerboseMessage(hle->user_defined, "jpeg_decode_%s: *buffer=%x, #MB=%d, mode=%d, *Qy=%x, *Qu=%x, *Qv=%x", version, address, macroblock_count, mode, qtableY_ptr, qtableU_ptr, qtableV_ptr); if (mode != 0 && mode != 2) { HleWarnMessage(hle->user_defined, "jpeg_decode_%s: invalid mode %d", version, mode); return; } subblock_count = mode + 4; macroblock_size = subblock_count * SUBBLOCK_SIZE; dram_load_u16(hle, (uint16_t *)qtables[0], qtableY_ptr, SUBBLOCK_SIZE); dram_load_u16(hle, (uint16_t *)qtables[1], qtableU_ptr, SUBBLOCK_SIZE); dram_load_u16(hle, (uint16_t *)qtables[2], qtableV_ptr, SUBBLOCK_SIZE); for (mb = 0; mb < macroblock_count; ++mb) { dram_load_u16(hle, (uint16_t *)macroblock, address, macroblock_size); decode_macroblock_std(transform_luma, transform_chroma, macroblock, subblock_count, (const int16_t (*)[SUBBLOCK_SIZE])qtables); if (mode == 0) EmitTilesMode0(hle, emit_line, macroblock, address); else EmitTilesMode2(hle, emit_line, macroblock, address); address += 2 * macroblock_size; } } static uint8_t clamp_u8(int16_t x) { return (x & (0xff00)) ? ((-x) >> 15) & 0xff : x; } static int16_t clamp_s12(int16_t x) { if (x < -0x800) x = -0x800; else if (x > 0x7f0) x = 0x7f0; return x; } static uint16_t clamp_RGBA_component(int16_t x) { if (x > 0xff0) x = 0xff0; else if (x < 0) x = 0; return (x & 0xf80); } static uint32_t GetUYVY(int16_t y1, int16_t y2, int16_t u, int16_t v) { return (uint32_t)clamp_u8(u) << 24 | (uint32_t)clamp_u8(y1) << 16 | (uint32_t)clamp_u8(v) << 8 | (uint32_t)clamp_u8(y2); } static uint16_t GetRGBA(int16_t y, int16_t u, int16_t v) { const float fY = (float)y + 2048.0f; const float fU = (float)u; const float fV = (float)v; const uint16_t r = clamp_RGBA_component((int16_t)(fY + 1.4025 * fV)); const uint16_t g = clamp_RGBA_component((int16_t)(fY - 0.3443 * fU - 0.7144 * fV)); const uint16_t b = clamp_RGBA_component((int16_t)(fY + 1.7729 * fU)); return (r << 4) | (g >> 1) | (b >> 6) | 1; } static void EmitYUVTileLine(struct hle_t* hle, const int16_t *y, const int16_t *u, uint32_t address) { uint32_t uyvy[8]; const int16_t *const v = u + SUBBLOCK_SIZE; const int16_t *const y2 = y + SUBBLOCK_SIZE; uyvy[0] = GetUYVY(y[0], y[1], u[0], v[0]); uyvy[1] = GetUYVY(y[2], y[3], u[1], v[1]); uyvy[2] = GetUYVY(y[4], y[5], u[2], v[2]); uyvy[3] = GetUYVY(y[6], y[7], u[3], v[3]); uyvy[4] = GetUYVY(y2[0], y2[1], u[4], v[4]); uyvy[5] = GetUYVY(y2[2], y2[3], u[5], v[5]); uyvy[6] = GetUYVY(y2[4], y2[5], u[6], v[6]); uyvy[7] = GetUYVY(y2[6], y2[7], u[7], v[7]); dram_store_u32(hle, uyvy, address, 8); } static void EmitRGBATileLine(struct hle_t* hle, const int16_t *y, const int16_t *u, uint32_t address) { uint16_t rgba[16]; const int16_t *const v = u + SUBBLOCK_SIZE; const int16_t *const y2 = y + SUBBLOCK_SIZE; rgba[0] = GetRGBA(y[0], u[0], v[0]); rgba[1] = GetRGBA(y[1], u[0], v[0]); rgba[2] = GetRGBA(y[2], u[1], v[1]); rgba[3] = GetRGBA(y[3], u[1], v[1]); rgba[4] = GetRGBA(y[4], u[2], v[2]); rgba[5] = GetRGBA(y[5], u[2], v[2]); rgba[6] = GetRGBA(y[6], u[3], v[3]); rgba[7] = GetRGBA(y[7], u[3], v[3]); rgba[8] = GetRGBA(y2[0], u[4], v[4]); rgba[9] = GetRGBA(y2[1], u[4], v[4]); rgba[10] = GetRGBA(y2[2], u[5], v[5]); rgba[11] = GetRGBA(y2[3], u[5], v[5]); rgba[12] = GetRGBA(y2[4], u[6], v[6]); rgba[13] = GetRGBA(y2[5], u[6], v[6]); rgba[14] = GetRGBA(y2[6], u[7], v[7]); rgba[15] = GetRGBA(y2[7], u[7], v[7]); dram_store_u16(hle, rgba, address, 16); } static void EmitTilesMode0(struct hle_t* hle, const tile_line_emitter_t emit_line, const int16_t *macroblock, uint32_t address) { unsigned int i; unsigned int y_offset = 0; unsigned int u_offset = 2 * SUBBLOCK_SIZE; for (i = 0; i < 8; ++i) { emit_line(hle, ¯oblock[y_offset], ¯oblock[u_offset], address); y_offset += 8; u_offset += 8; address += 32; } } static void EmitTilesMode2(struct hle_t* hle, const tile_line_emitter_t emit_line, const int16_t *macroblock, uint32_t address) { unsigned int i; unsigned int y_offset = 0; unsigned int u_offset = 4 * SUBBLOCK_SIZE; for (i = 0; i < 8; ++i) { emit_line(hle, ¯oblock[y_offset], ¯oblock[u_offset], address); emit_line(hle, ¯oblock[y_offset + 8], ¯oblock[u_offset], address + 32); y_offset += (i == 3) ? SUBBLOCK_SIZE + 16 : 16; u_offset += 8; address += 64; } } static void decode_macroblock_ob(int16_t *macroblock, int32_t *y_dc, int32_t *u_dc, int32_t *v_dc, const int16_t *qtable) { int sb; for (sb = 0; sb < 6; ++sb) { int16_t tmp_sb[SUBBLOCK_SIZE]; /* update DC */ int32_t dc = (int32_t)macroblock[0]; switch (sb) { case 0: case 1: case 2: case 3: *y_dc += dc; macroblock[0] = *y_dc & 0xffff; break; case 4: *u_dc += dc; macroblock[0] = *u_dc & 0xffff; break; case 5: *v_dc += dc; macroblock[0] = *v_dc & 0xffff; break; } ZigZagSubBlock(tmp_sb, macroblock); if (qtable != NULL) MultSubBlocks(tmp_sb, tmp_sb, qtable, 0); TransposeSubBlock(macroblock, tmp_sb); InverseDCTSubBlock(macroblock, macroblock); macroblock += SUBBLOCK_SIZE; } } static void decode_macroblock_std(const subblock_transform_t transform_luma, const subblock_transform_t transform_chroma, int16_t *macroblock, unsigned int subblock_count, const int16_t qtables[3][SUBBLOCK_SIZE]) { unsigned int sb; unsigned int q = 0; for (sb = 0; sb < subblock_count; ++sb) { int16_t tmp_sb[SUBBLOCK_SIZE]; const int isChromaSubBlock = (subblock_count - sb <= 2); if (isChromaSubBlock) ++q; MultSubBlocks(macroblock, macroblock, qtables[q], 4); ZigZagSubBlock(tmp_sb, macroblock); InverseDCTSubBlock(macroblock, tmp_sb); if (isChromaSubBlock) { if (transform_chroma != NULL) transform_chroma(macroblock, macroblock); } else { if (transform_luma != NULL) transform_luma(macroblock, macroblock); } macroblock += SUBBLOCK_SIZE; } } static void TransposeSubBlock(int16_t *dst, const int16_t *src) { ReorderSubBlock(dst, src, TRANSPOSE_TABLE); } static void ZigZagSubBlock(int16_t *dst, const int16_t *src) { ReorderSubBlock(dst, src, ZIGZAG_TABLE); } static void ReorderSubBlock(int16_t *dst, const int16_t *src, const unsigned int *table) { unsigned int i; /* source and destination sublocks cannot overlap */ assert(abs(dst - src) > SUBBLOCK_SIZE); for (i = 0; i < SUBBLOCK_SIZE; ++i) dst[i] = src[table[i]]; } static void MultSubBlocks(int16_t *dst, const int16_t *src1, const int16_t *src2, unsigned int shift) { unsigned int i; for (i = 0; i < SUBBLOCK_SIZE; ++i) { int32_t v = src1[i] * src2[i]; dst[i] = clamp_s16(v) << shift; } } static void ScaleSubBlock(int16_t *dst, const int16_t *src, int16_t scale) { unsigned int i; for (i = 0; i < SUBBLOCK_SIZE; ++i) { int32_t v = src[i] * scale; dst[i] = clamp_s16(v); } } static void RShiftSubBlock(int16_t *dst, const int16_t *src, unsigned int shift) { unsigned int i; for (i = 0; i < SUBBLOCK_SIZE; ++i) dst[i] = src[i] >> shift; } /*************************************************************************** * Fast 2D IDCT using separable formulation and normalization * Computations use single precision floats * Implementation based on Wikipedia : * http://fr.wikipedia.org/wiki/Transform%C3%A9e_en_cosinus_discr%C3%A8te **************************************************************************/ static void InverseDCT1D(const float *const x, float *dst, unsigned int stride) { float e[4]; float f[4]; float x26, x1357, x15, x37, x17, x35; x15 = IDCT_K[2] * (x[1] + x[5]); x37 = IDCT_K[3] * (x[3] + x[7]); x17 = IDCT_K[8] * (x[1] + x[7]); x35 = IDCT_K[9] * (x[3] + x[5]); x1357 = IDCT_C3 * (x[1] + x[3] + x[5] + x[7]); x26 = IDCT_C6 * (x[2] + x[6]); f[0] = x[0] + x[4]; f[1] = x[0] - x[4]; f[2] = x26 + IDCT_K[0] * x[2]; f[3] = x26 + IDCT_K[1] * x[6]; e[0] = x1357 + x15 + IDCT_K[4] * x[1] + x17; e[1] = x1357 + x37 + IDCT_K[6] * x[3] + x35; e[2] = x1357 + x15 + IDCT_K[5] * x[5] + x35; e[3] = x1357 + x37 + IDCT_K[7] * x[7] + x17; *dst = f[0] + f[2] + e[0]; dst += stride; *dst = f[1] + f[3] + e[1]; dst += stride; *dst = f[1] - f[3] + e[2]; dst += stride; *dst = f[0] - f[2] + e[3]; dst += stride; *dst = f[0] - f[2] - e[3]; dst += stride; *dst = f[1] - f[3] - e[2]; dst += stride; *dst = f[1] + f[3] - e[1]; dst += stride; *dst = f[0] + f[2] - e[0]; } static void InverseDCTSubBlock(int16_t *dst, const int16_t *src) { float x[8]; float block[SUBBLOCK_SIZE]; unsigned int i, j; /* idct 1d on rows (+transposition) */ for (i = 0; i < 8; ++i) { for (j = 0; j < 8; ++j) x[j] = (float)src[i * 8 + j]; InverseDCT1D(x, &block[i], 8); } /* idct 1d on columns (thanks to previous transposition) */ for (i = 0; i < 8; ++i) { InverseDCT1D(&block[i * 8], x, 1); /* C4 = 1 normalization implies a division by 8 */ for (j = 0; j < 8; ++j) dst[i + j * 8] = (int16_t)x[j] >> 3; } } static void RescaleYSubBlock(int16_t *dst, const int16_t *src) { unsigned int i; for (i = 0; i < SUBBLOCK_SIZE; ++i) dst[i] = (((uint32_t)(clamp_s12(src[i]) + 0x800) * 0xdb0) >> 16) + 0x10; } static void RescaleUVSubBlock(int16_t *dst, const int16_t *src) { unsigned int i; for (i = 0; i < SUBBLOCK_SIZE; ++i) dst[i] = (((int)clamp_s12(src[i]) * 0xe00) >> 16) + 0x80; } mupen64plus-core/src/main/rom.h000664 001750 001750 00000005102 12655644434 017526 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - rom.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2008 Tillin9 * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef __ROM_H__ #define __ROM_H__ #include "api/m64p_types.h" #include "md5.h" /* ROM Loading and Saving functions */ m64p_error open_rom(const unsigned char* romimage, unsigned int size); m64p_error close_rom(void); extern unsigned char* g_rom; extern int g_rom_size; extern unsigned char isGoldeneyeRom; typedef struct _rom_params { m64p_system_type systemtype; int vilimit; int aidacrate; char headername[21]; /* ROM Name as in the header, removing trailing whitespace */ } rom_params; extern m64p_rom_header ROM_HEADER; extern rom_params ROM_PARAMS; extern m64p_rom_settings ROM_SETTINGS; /* Supported rom image types. */ enum { Z64IMAGE, V64IMAGE, N64IMAGE }; /* Supported CIC chips. */ enum { CIC_NUS_6101, CIC_NUS_6102, CIC_NUS_6103, CIC_NUS_6105, CIC_NUS_6106, CIC_NUS_5167 }; /* Supported save types. */ enum { EEPROM_4KB, EEPROM_16KB, SRAM, FLASH_RAM, CONTROLLER_PACK, NONE }; #endif /* __ROM_H__ */ mupen64plus-core/src/main/rom.c000664 001750 001750 00000024372 12655644434 017533 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - rom.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2008 Tillin9 * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #define M64P_CORE_PROTOTYPES 1 #include "api/m64p_types.h" #include "api/callbacks.h" #include "api/config.h" #include "api/m64p_config.h" #include "md5.h" #include "rom.h" #include "main.h" #include "util.h" #include "memory/memory.h" #include "osal/preproc.h" #include "../r4300/r4300.h" #define DEFAULT 16 /* Global loaded rom memory space. */ unsigned char* g_rom = NULL; /* Global loaded rom size. */ int g_rom_size = 0; uint8_t isGoldeneyeRom = 0; extern unsigned int frame_dupe; m64p_rom_header ROM_HEADER; rom_params ROM_PARAMS; m64p_rom_settings ROM_SETTINGS; static const uint8_t Z64_SIGNATURE[4] = { 0x80, 0x37, 0x12, 0x40 }; static const uint8_t V64_SIGNATURE[4] = { 0x37, 0x80, 0x40, 0x12 }; static const uint8_t N64_SIGNATURE[4] = { 0x40, 0x12, 0x37, 0x80 }; // Get the system type associated to a ROM country code. static m64p_system_type rom_country_code_to_system_type(char country_code) { switch (country_code) { // PAL codes case 0x44: case 0x46: case 0x49: case 0x50: case 0x53: case 0x55: case 0x58: case 0x59: return SYSTEM_PAL; // NTSC codes case 0x37: case 0x41: case 0x45: case 0x4a: default: // Fallback for unknown codes return SYSTEM_NTSC; } } // Get the VI (vertical interrupt) limit associated to a ROM system type. static int rom_system_type_to_vi_limit(m64p_system_type system_type) { switch (system_type) { case SYSTEM_PAL: case SYSTEM_MPAL: return 50; case SYSTEM_NTSC: default: return 60; } } static int rom_system_type_to_ai_dac_rate(m64p_system_type system_type) { switch (system_type) { case SYSTEM_PAL: return 49656530; case SYSTEM_MPAL: return 48628316; case SYSTEM_NTSC: default: return 48681812; } } /* Tests if a file is a valid N64 rom by checking the first 4 bytes. */ static int is_valid_rom(const unsigned char *buffer) { if (memcmp(buffer, Z64_SIGNATURE, sizeof(Z64_SIGNATURE)) == 0 || memcmp(buffer, V64_SIGNATURE, sizeof(V64_SIGNATURE)) == 0 || memcmp(buffer, N64_SIGNATURE, sizeof(N64_SIGNATURE)) == 0) return 1; else return 0; } /* If rom is a .v64 or .n64 image, byteswap or wordswap loadlength amount of * rom data to native .z64 before forwarding. Makes sure that data extraction * and MD5ing routines always deal with a .z64 image. */ static void swap_rom(unsigned char* localrom, unsigned char* imagetype, int loadlength) { unsigned char temp; int i; /* Btyeswap if .v64 image. */ if(localrom[0]==0x37) { *imagetype = V64IMAGE; for (i = 0; i < loadlength; i+=2) { temp=localrom[i]; localrom[i]=localrom[i+1]; localrom[i+1]=temp; } } /* Wordswap if .n64 image. */ else if(localrom[0]==0x40) { *imagetype = N64IMAGE; for (i = 0; i < loadlength; i+=4) { temp=localrom[i]; localrom[i]=localrom[i+3]; localrom[i+3]=temp; temp=localrom[i+1]; localrom[i+1]=localrom[i+2]; localrom[i+2]=temp; } } else *imagetype = Z64IMAGE; } m64p_error open_rom(const unsigned char* romimage, unsigned int size) { #include "rom_luts.c" md5_state_t state; md5_byte_t digest[16]; char buffer[256]; unsigned char imagetype; int i; uint64_t lut_id; int patch_applied = 0; /* check input requirements */ if (g_rom != NULL) { DebugMessage(M64MSG_ERROR, "open_rom(): previous ROM image was not freed"); return M64ERR_INTERNAL; } if (romimage == NULL || !is_valid_rom(romimage)) { DebugMessage(M64MSG_ERROR, "open_rom(): not a valid ROM image"); return M64ERR_INPUT_INVALID; } /* Clear Byte-swapped flag, since ROM is now deleted. */ g_MemHasBeenBSwapped = 0; /* allocate new buffer for ROM and copy into this buffer */ g_rom_size = size; g_rom = (unsigned char *) malloc(size); if (g_rom == NULL) return M64ERR_NO_MEMORY; memcpy(g_rom, romimage, size); swap_rom(g_rom, &imagetype, g_rom_size); memcpy(&ROM_HEADER, g_rom, sizeof(m64p_rom_header)); /* Calculate MD5 hash */ md5_init(&state); md5_append(&state, (const md5_byte_t*)g_rom, g_rom_size); md5_finish(&state, digest); for ( i = 0; i < 16; ++i ) sprintf(buffer+i*2, "%02X", digest[i]); buffer[32] = '\0'; strcpy(ROM_SETTINGS.MD5, buffer); /* add some useful properties to ROM_PARAMS */ ROM_PARAMS.systemtype = rom_country_code_to_system_type(ROM_HEADER.destination_code); ROM_PARAMS.vilimit = rom_system_type_to_vi_limit(ROM_PARAMS.systemtype); ROM_PARAMS.aidacrate = rom_system_type_to_ai_dac_rate(ROM_PARAMS.systemtype); memcpy(ROM_PARAMS.headername, ROM_HEADER.Name, 20); ROM_PARAMS.headername[20] = '\0'; trim(ROM_PARAMS.headername); /* Remove trailing whitespace from ROM name. */ lut_id = (((uint64_t)sl(ROM_HEADER.CRC1)) << 32) | sl(ROM_HEADER.CRC2); for (i = 0; i < sizeof(lut_ee16k)/sizeof(lut_ee16k[0]); ++i) { if (lut_ee16k[i] == lut_id) { strcpy(ROM_SETTINGS.goodname, ROM_PARAMS.headername); ROM_SETTINGS.savetype = EEPROM_16KB; DebugMessage(M64MSG_INFO, "%s INI patches applied.", ROM_PARAMS.headername); patch_applied = 1; break; } } for (i = 0; i < sizeof(lut_ee4k)/sizeof(lut_ee4k[0]); ++i) { if (lut_ee4k[i] == lut_id) { strcpy(ROM_SETTINGS.goodname, ROM_PARAMS.headername); ROM_SETTINGS.savetype = EEPROM_4KB; DebugMessage(M64MSG_INFO, "%s INI patches applied.", ROM_PARAMS.headername); patch_applied = 1; break; } } for (i = 0; i < sizeof(lut_flashram)/sizeof(lut_flashram[0]); ++i) { if (lut_flashram[i] == lut_id) { strcpy(ROM_SETTINGS.goodname, ROM_PARAMS.headername); ROM_SETTINGS.savetype = FLASH_RAM; DebugMessage(M64MSG_INFO, "%s INI patches applied.", ROM_PARAMS.headername); patch_applied = 1; break; } } if (!patch_applied) { strcpy(ROM_SETTINGS.goodname, ROM_PARAMS.headername); strcat(ROM_SETTINGS.goodname, " (unknown rom)"); ROM_SETTINGS.savetype = NONE; ROM_SETTINGS.status = 0; ROM_SETTINGS.players = 0; ROM_SETTINGS.rumble = 0; } for (i = 0; i < sizeof(lut_cpop)/sizeof(lut_cpop[0]); ++i) { if (lut_cpop[i][0] == lut_id) { count_per_op = lut_cpop[i][1]; DebugMessage(M64MSG_INFO, "CountPerOp set to %u.", count_per_op); break; } } if (frame_dupe) count_per_op = 1; g_delay_si = 1; /* default */ for (i = 0; i < sizeof(lut_delaysi)/sizeof(lut_delaysi[0]); ++i) { if (lut_delaysi[i][0] == lut_id) { g_delay_si = lut_delaysi[i][1]; DebugMessage(M64MSG_INFO, "DelaySI set to %u.", g_delay_si); break; } } /* print out a bunch of info about the ROM */ DebugMessage(M64MSG_INFO, "Goodname: %s", ROM_SETTINGS.goodname); DebugMessage(M64MSG_INFO, "Headername: %s", ROM_PARAMS.headername); DebugMessage(M64MSG_INFO, "Name: %s", ROM_HEADER.Name); imagestring(imagetype, buffer); DebugMessage(M64MSG_INFO, "MD5: %s", ROM_SETTINGS.MD5); DebugMessage(M64MSG_INFO, "CRC: %x %x", sl(ROM_HEADER.CRC1), sl(ROM_HEADER.CRC2)); DebugMessage(M64MSG_INFO, "Imagetype: %s", buffer); DebugMessage(M64MSG_INFO, "Rom size: %d bytes (or %d Mb or %d Megabits)", g_rom_size, g_rom_size/1024/1024, g_rom_size/1024/1024*8); DebugMessage(M64MSG_VERBOSE, "ClockRate = %x", sl(ROM_HEADER.ClockRate)); DebugMessage(M64MSG_INFO, "Version: %x", sl(ROM_HEADER.Release)); if(sl(ROM_HEADER.Manufacturer_ID) == 'N') DebugMessage(M64MSG_INFO, "Manufacturer: Nintendo"); else DebugMessage(M64MSG_INFO, "Manufacturer: %x", sl(ROM_HEADER.Manufacturer_ID)); DebugMessage(M64MSG_VERBOSE, "Cartridge_ID: %x", ROM_HEADER.Cartridge_ID); countrycodestring(ROM_HEADER.destination_code, buffer); DebugMessage(M64MSG_INFO, "Country: %s", buffer); DebugMessage(M64MSG_VERBOSE, "PC = %x", sl((unsigned int)ROM_HEADER.PC)); DebugMessage(M64MSG_VERBOSE, "Save type: %d", ROM_SETTINGS.savetype); //Prepare Hack for GOLDENEYE isGoldeneyeRom = 0; if(strcmp(ROM_PARAMS.headername, "GOLDENEYE") == 0) isGoldeneyeRom = 1; return M64ERR_SUCCESS; } m64p_error close_rom(void) { if (g_rom == NULL) return M64ERR_INVALID_STATE; free(g_rom); g_rom = NULL; /* Clear Byte-swapped flag, since ROM is now deleted. */ g_MemHasBeenBSwapped = 0; DebugMessage(M64MSG_STATUS, "Rom closed."); return M64ERR_SUCCESS; } mupen64plus-core/src/api/callbacks.h000664 001750 001750 00000004201 12655644434 020474 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-core - api/callbacks.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2009 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file contains the definitions for callback functions which will be * called from the other Core modules */ #if !defined(API_CALLBACKS_H) #define API_CALLBACKS_H #include "m64p_types.h" #include "m64p_frontend.h" /* Functions for use by the Core, to send information back to the front-end app */ extern m64p_error SetDebugCallback(ptr_DebugCallback pFunc, void *Context); extern m64p_error SetStateCallback(ptr_StateCallback pFunc, void *Context); extern void DebugMessage(int level, const char *message, ...); extern void StateChanged(m64p_core_param param_type, int new_value); #endif /* API_CALLBACKS_H */ gles2rice/src/RiceDebugger.cpp000664 001750 001750 00000054365 12655644434 017435 0ustar00sergiosergio000000 000000 /* Copyright (C) 2002 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define M64P_PLUGIN_PROTOTYPES 1 #include "m64p_plugin.h" #include "typedefs.h" #ifndef DEBUGGER void DebuggerAppendMsg(const char * Message, ...) {} #else void DumpMatrix2(const Matrix &mtx, const char* prompt); bool debuggerWinOpened = false; bool debuggerDrawRenderTexture = false; int debuggerDrawRenderTextureNo = 0; bool logCombiners = false; bool logWarning = true; bool logTriangles = false; bool logMatrix = false; bool logVertex = false; bool logTextures = false; bool logTextureBuffer = false; bool logToScreen = true; bool logToFile = false; bool logUcodes = false; bool logMicrocode = false; bool logFog = false; bool logDetails = false; FILE *logFp = NULL; bool debuggerEnableTexture=true; bool debuggerEnableZBuffer=true; bool debuggerEnableCullFace=true; bool debuggerEnableTestTris=true; bool debuggerEnableAlphaTest=true; bool debuggerContinueWithUnknown=false; bool debuggerPause = false; bool pauseAtNext = true; int eventToPause = NEXT_FRAME; int debuggerPauseCount = 340; int countToPause = 1; bool debuggerDropCombiners=false; bool debuggerDropGeneralCombiners=false; bool debuggerDropDecodedMux=false; bool debuggerDropCombinerInfos=false; char msgBuf[0x20000+2]; bool msgBufUpdated = false; extern FiddledVtx * g_pVtxBase; uint32 CachedTexIndex = 0; const char* otherNexts[] = { "Frame", "Flush Tri", "TextRect", "Triangle", "Set CImg", "ObjTxt Cmd", "Obj BG", "Sprite2D", "FillRect", "DList", "Ucode", "Texture Buffer", "Matrix Cmd", "Vertex Cmd", "New Texture", "Set Texture", "Mux", "Set Light", "Set Mode Cmd", "Set Prim Color", "Texture Cmd", "Unknown Ops", "Scale Image", "LoadTlut", "Ucode Switching", }; int numberOfNextOthers = sizeof(otherNexts)/sizeof(char*); const char* thingsToDump[] = { "Cur Texture RGBA", "Cur+1 Texture RGBA", "Colors", "Memory At", "Mux", "Simple Mux", "Other Modes", "Texture #", "Tile #", "VI Regs", "Cur Txt to file", "Cur+1 Txt to file", "Cur Texture RGB", "Cur Texture Alpha", "Cur+1 Texture RGB", "Cur+1 Texture Alpha", "Light Info", "Tlut", "Obj Tlut", "Vertexes", "Cached Texture", "Next Texture", "Prev Texture", "Dlist At", "Matrix At", "Combined Matrix", "World Top Matrix", "Projection Matrix", "World Matrix #", "Frame Buffer in RDRAM", "BackBuffer", "TexBuffer #", }; int numberOfThingsToDump = sizeof(thingsToDump)/sizeof(char*); enum { DUMP_CUR_TEXTURE_RGBA, DUMP_CUR_1_TEXTURE_RGBA, DUMP_COLORS, DUMP_CONTENT_AT, DUMP_CUR_MUX, DUMP_SIMPLE_MUX, DUMP_OTHER_MODE, DUMP_TEXTURE_AT, DUMP_TILE_AT, DUMP_VI_REGS, DUMP_CUR_TEXTURE_TO_FILE, DUMP_CUR_1_TEXTURE_TO_FILE, DUMP_CUR_TEXTURE_RGB, DUMP_CUR_TEXTURE_ALPHA, DUMP_CUR_1_TEXTURE_RGB, DUMP_CUR_1_TEXTURE_ALPHA, DUMP_LIGHT, DUMP_TLUT, DUMP_OBJ_TLUT, DUMP_VERTEXES, DUMP_CACHED_TEX, DUMP_NEXT_TEX, DUMP_PREV_TEX, DUMP_DLIST_AT, DUMP_MATRIX_AT, DUMP_COMBINED_MATRIX, DUMP_WORLD_TOP_MATRIX, DUMP_PROJECTION_MATRIX, DUMP_WORLD_MATRIX_AT, DUMP_FRAME_BUFFER, DUMP_BACKBUFFER, DUMP_TEXBUFFER_AT, }; //--------------------------------------------------------------------- void DumpVIRegisters(void) { DebuggerAppendMsg("----VI Registers----\nSTATUS:\t%08X\nORIGIN:\t%08X\nWIDTH:\t%08X\n\ V_SYNC:\t%08X\nH_SYNC:\t%08X\nX_SCALE:\t%08X\nY_SCALE:\t%08X\n\ H_START:\t%08X\nV_START:\t%08X\nVI Width=%f(x %f), VI Height=%f(x %f)\n\n", *gfx_info.VI_STATUS_REG, *gfx_info.VI_ORIGIN_REG, *gfx_info.VI_WIDTH_REG, *gfx_info.VI_V_SYNC_REG, *gfx_info.VI_H_SYNC_REG, *gfx_info.VI_X_SCALE_REG, *gfx_info.VI_Y_SCALE_REG, *gfx_info.VI_H_START_REG, *gfx_info.VI_V_START_REG, windowSetting.fViWidth,windowSetting.fMultX, windowSetting.fViHeight,windowSetting.fMultY); DebuggerAppendMsg("Scissor: x0=%d y0=%d x1=%d y1=%d mode=%d", gRDP.scissor.left, gRDP.scissor.top, gRDP.scissor.right, gRDP.scissor.bottom, gRDP.scissor.mode); DebuggerAppendMsg("Effective scissor: x0=%d y0=%d x1=%d y1=%d", gRSP.real_clip_scissor_left, gRSP.real_clip_scissor_top, gRSP.real_clip_scissor_right, gRSP.real_clip_scissor_bottom); DebuggerAppendMsg("Clipping: (%d) left=%f top=%f right=%f bottom=%f", gRSP.clip_ratio_posx, gRSP.real_clip_ratio_negx , gRSP.real_clip_ratio_negy, gRSP.real_clip_ratio_posx, gRSP.real_clip_ratio_posy); DebuggerAppendMsg("Viewport: left=%d top=%d right=%d bottom=%d", gRSP.nVPLeftN, gRSP.nVPTopN , gRSP.nVPRightN, gRSP.nVPBottomN); DebuggerAppendMsg("Current CImg: Address=0x%08X, Format:%s-%sb, Width=%d\n", g_CI.dwAddr, pszImgFormat[g_CI.dwFormat], pszImgSize[g_CI.dwSize], g_CI.dwWidth); DebuggerAppendMsg("Current ZImg: Address=0x%08X, Format:%s-%sb, Width=%d\n", g_ZI.dwAddr, pszImgFormat[g_ZI.dwFormat], pszImgSize[g_ZI.dwSize], g_ZI.dwWidth); } void DumpVertexArray(void) { DebuggerAppendMsg("----Vertexes----\n"); try { for( int i=0; i<32; i++ ) { FiddledVtx &v = g_pVtxBase[i]; DebuggerAppendMsg("[%d] x=%d,y=%d,z=%d -- r=%d,g=%d,b=%d,a=%d\n", i, v.x, v.y, v.z, v.rgba.r, v.rgba.g, v.rgba.b, v.rgba.a); DebuggerAppendMsg("\tx=%f,y=%f,z=%f,rhw=%f\n", g_vecProjected[i].x, g_vecProjected[i].y, g_vecProjected[i].z, g_vecProjected[i].w); } } catch(...) { DebuggerAppendMsg("Invalid memory pointer of vertex array\n"); } } void DumpHex(uint32 rdramAddr, int count); uint32 StrToHex(char *HexStr); void DumpTileInfo(uint32 dwTile) { const char *pszOnOff[2] = {"Off", "On"}; DebuggerAppendMsg("Tile: %d\nFmt: %s/%s Line:%d (Pitch %d) TMem:0x%04x Palette:%d\n", dwTile, pszImgFormat[gRDP.tiles[dwTile].dwFormat], pszImgSize[gRDP.tiles[dwTile].dwSize], gRDP.tiles[dwTile].dwLine, gRDP.tiles[dwTile].dwPitch, gRDP.tiles[dwTile].dwTMem, gRDP.tiles[dwTile].dwPalette); DebuggerAppendMsg("S: Clamp: %s Mirror:%s Mask:0x%x Shift:0x%x\n", pszOnOff[gRDP.tiles[dwTile].bClampS],pszOnOff[gRDP.tiles[dwTile].bMirrorS], gRDP.tiles[dwTile].dwMaskS, gRDP.tiles[dwTile].dwShiftS); DebuggerAppendMsg("T: Clamp: %s Mirror:%s Mask:0x%x Shift:0x%x\n", pszOnOff[gRDP.tiles[dwTile].bClampT],pszOnOff[gRDP.tiles[dwTile].bMirrorT], gRDP.tiles[dwTile].dwMaskT, gRDP.tiles[dwTile].dwShiftT); DebuggerAppendMsg("(%d,%d) -> (%d,%d), hilite [%d, %d]\n", gRDP.tiles[dwTile].sl, gRDP.tiles[dwTile].tl, gRDP.tiles[dwTile].sh, gRDP.tiles[dwTile].th, gRDP.tiles[dwTile].hilite_sl,gRDP.tiles[dwTile].hilite_tl); } void DumpTexture(int tex, TextureChannel channel) { CRender::GetRender()->DrawTexture(tex, channel); } void DumpRenderTexture(int tex) { if( CDeviceBuilder::GetBuilder()->GetGeneralDeviceType() == DIRECTX_DEVICE ) { g_pFrameBufferManager->DisplayRenderTexture(tex); } else { debuggerDrawRenderTextureNo = tex; debuggerDrawRenderTexture = true; } } void DumpTextureToFile(int tex, TextureChannel channel = TXT_RGB) { CRender::GetRender()->SaveTextureToFile(tex, channel, false); } void DumpTlut(uint16* palAddr) { for( uint32 i=0; i<0x100; i+=8 ) { DebuggerAppendMsg("0x%4X 0x%4X 0x%4X 0x%4X 0x%4X 0x%4X 0x%4X 0x%4X ", g_wRDPTlut[i], g_wRDPTlut[i+1], g_wRDPTlut[i+2], g_wRDPTlut[i+2], g_wRDPTlut[i+4], g_wRDPTlut[i+5], g_wRDPTlut[i+6], g_wRDPTlut[i+7]); } } extern char ucodeNames_GBI1[256]; extern char ucodeNames_GBI2[256]; void DumpDlistAt(uint32 dwPC) { uint32 word0, word1, opcode; char *name; uint32_t *rdram_u32 = (uint32_t*)gfx_info.RDRAM; switch( gRSP.ucode ) { case 2: case 10: //case 8: name=ucodeNames_GBI2; break; default: name=ucodeNames_GBI1; } DebuggerAppendMsg("\n\n"); for( uint32 i=0; i<20; i++) { word0 = rdram_u32[(dwPC>>2)+0]; word1 = rdram_u32[(dwPC>>2)+1]; opcode = word0>>24; DebuggerAppendMsg("%08X: %08X, %08X - %s", dwPC, word0, word1, name[opcode] ); dwPC+=8; } DebuggerAppendMsg("\n\n"); } void DumpMatrixAt(uint32 dwPC) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; Matrix mat; const float fRecip = 1.0f / 65536.0f; for (uint32 dwI = 0; dwI < 4; dwI++) { for (uint32 dwJ = 0; dwJ < 4; dwJ++) { int nDataHi = *(short *)(rdram_u8 + ((dwPC+(dwI<<3)+(dwJ<<1) )^0x2)); int nDataLo = *(uint16 *)(rdram_u8 + ((dwPC+(dwI<<3)+(dwJ<<1) + 32)^0x2)); mat.m[dwI][dwJ] = (float)((nDataHi << 16) | nDataLo) * fRecip; } } TRACE0("Dump Matrix in Memory"); DebuggerAppendMsg( " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\n" " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\n" " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\n" " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\n", mat.m[0][0], mat.m[0][1], mat.m[0][2], mat.m[0][3], mat.m[1][0], mat.m[1][1], mat.m[1][2], mat.m[1][3], mat.m[2][0], mat.m[2][1], mat.m[2][2], mat.m[2][3], mat.m[3][0], mat.m[3][1], mat.m[3][2], mat.m[3][3]); } // High static const char *alphadithertypes[4] = {"Pattern", "NotPattern", "Noise", "Disable"}; static const char *rgbdithertype[4] = {"MagicSQ", "Bayer", "Noise", "Disable"}; static const char *convtype[8] = {"Conv", "?", "?", "?", "?", "FiltConv", "Filt", "?"}; static const char *filtertype[4] = {"Point", "?", "Bilinear", "Average"}; static const char *cycletype[4] = {"1Cycle", "2Cycle", "Copy", "Fill"}; static const char *alphacomptype[4] = {"None", "Threshold", "?", "Dither"}; static const char * szCvgDstMode[4] = { "Clamp", "Wrap", "Full", "Save" }; static const char * szZMode[4] = { "Opa", "Inter", "XLU", "Decal" }; static const char * szZSrcSel[2] = { "Pixel", "Primitive" }; static const char * sc_szBlClr[4] = { "In", "Mem", "Bl", "Fog" }; static const char * sc_szBlA1[4] = { "AIn", "AFog", "AShade", "0" }; static const char * sc_szBlA2[4] = { "1-A", "AMem", "1", "0" }; void DumpOtherMode() { uint16 blender = gRDP.otherMode.blender; RDP_BlenderSetting &bl = *(RDP_BlenderSetting*)(&(blender)); DebuggerAppendMsg( "Other Modes"); DebuggerAppendMsg( "\talpha_compare:\t%s", alphacomptype[ gRDP.otherMode.alpha_compare ]); DebuggerAppendMsg( "\tdepth_source:\t%s", szZSrcSel[ gRDP.otherMode.depth_source ]); DebuggerAppendMsg( "\taa_en:\t\t%d", gRDP.otherMode.aa_en ); DebuggerAppendMsg( "\tz_cmp:\t\t%d", gRDP.otherMode.z_cmp ); DebuggerAppendMsg( "\tz_upd:\t\t%d", gRDP.otherMode.z_upd ); DebuggerAppendMsg( "\tim_rd:\t\t%d", gRDP.otherMode.im_rd ); DebuggerAppendMsg( "\tclr_on_cvg:\t%d", gRDP.otherMode.clr_on_cvg ); DebuggerAppendMsg( "\tcvg_dst:\t\t%s", szCvgDstMode[ gRDP.otherMode.cvg_dst ] ); DebuggerAppendMsg( "\tzmode:\t\t%s", szZMode[ gRDP.otherMode.zmode ] ); DebuggerAppendMsg( "\tcvg_x_alpha:\t%d", gRDP.otherMode.cvg_x_alpha ); DebuggerAppendMsg( "\talpha_cvg_sel:\t%d", gRDP.otherMode.alpha_cvg_sel ); DebuggerAppendMsg( "\tforce_bl:\t\t%d", gRDP.otherMode.force_bl ); DebuggerAppendMsg( "\ttex_edge:\t\t%d", gRDP.otherMode.tex_edge ); DebuggerAppendMsg( "\tblender:\t\t%04x - Cycle1:\t%s * %s + %s * %s\n\t\t\tCycle2:\t%s * %s + %s * %s", gRDP.otherMode.blender, sc_szBlClr[bl.c1_m1a], sc_szBlA1[bl.c1_m1b], sc_szBlClr[bl.c1_m2a], sc_szBlA2[bl.c1_m2b], sc_szBlClr[bl.c2_m1a], sc_szBlA1[bl.c2_m1b], sc_szBlClr[bl.c2_m2a], sc_szBlA2[bl.c2_m2b]); DebuggerAppendMsg( "\tblend_mask:\t%d", gRDP.otherMode.blend_mask ); DebuggerAppendMsg( "\talpha_dither:\t%s", alphadithertypes[ gRDP.otherMode.alpha_dither ] ); DebuggerAppendMsg( "\trgb_dither:\t\t%s", rgbdithertype[ gRDP.otherMode.rgb_dither ] ); DebuggerAppendMsg( "\tcomb_key:\t%s", gRDP.otherMode.key_en ? "Key" : "None" ); DebuggerAppendMsg( "\ttext_conv:\t\t%s", convtype[ gRDP.otherMode.text_conv ] ); DebuggerAppendMsg( "\ttext_filt:\t\t%s", filtertype[ gRDP.otherMode.text_filt ] ); DebuggerAppendMsg( "\ttext_tlut:\t\t%s", textluttype[ gRDP.otherMode.text_tlut ] ); DebuggerAppendMsg( "\ttext_lod:\t\t%s", gRDP.otherMode.text_lod ? "Yes": "No" ); DebuggerAppendMsg( "\ttext_detail:\t\t%s", gRDP.otherMode.text_detail ? "Yes": "No" ); DebuggerAppendMsg( "\ttext_sharpen:\t\t%s", gRDP.otherMode.text_sharpen ? "Yes": "No" ); DebuggerAppendMsg( "\ttext_persp:\t%s", gRDP.otherMode.text_persp ? "On" : "Off" ); DebuggerAppendMsg( "\tcycle_type:\t%s", cycletype[ gRDP.otherMode.cycle_type ] ); DebuggerAppendMsg( "\tpipeline:\t\t%s", gRDP.otherMode.atomic_prim ? "1Primitive" : "NPrimitive" ); DebuggerAppendMsg("\n\nSP render flags:"); DebuggerAppendMsg("\tCull mode: %s%s", gRSP.bCullFront?"Cull Front":"", gRSP.bCullBack?" Cull Back":""); DebuggerAppendMsg("\tShade mode: %d", gRSP.shadeMode); DebuggerAppendMsg("\tFog: %s", gRSP.bFogEnabled?"enabled":"disabled"); DebuggerAppendMsg("\tZbuffer in SP: %s", gRSP.bZBufferEnabled?"enabled":"disabled"); DebuggerAppendMsg("\tLighting: %s", gRSP.bLightingEnable?"enabled":"disabled"); DebuggerAppendMsg("\\Number of lights: %d", gRSPnumLights); DebuggerAppendMsg("\tTexture Gen: %s", gRSP.bTextureGen?"enabled":"disabled"); DebuggerAppendMsg("\tTexture Gen Linear: %s", (gRDP.geometryMode & G_TEXTURE_GEN_LINEAR)?"enabled":"disabled"); } void DumpCachedTexture(uint32 index) { TxtrCacheEntry *p = gTextureManager.GetCachedTexture(index); if( p != NULL ) { char filename[80]; sprintf(filename,"\\Texture%d_rgb", index); CRender::GetRender()->SaveTextureToFile(*(p->pTexture), filename, TXT_RGB, false, true, -1, -1); DebuggerAppendMsg("Display cached texture #%d of %d\n", index, gTextureManager.GetNumOfCachedTexture()); DebuggerAppendMsg("W:%d, H:%d, RealW:%d, RealH:%d, D3DW:%d, D3DH: %d", p->ti.WidthToCreate, p->ti.HeightToCreate, p->ti.WidthToLoad, p->ti.HeightToLoad, p->pTexture->m_dwCreatedTextureWidth, p->pTexture->m_dwCreatedTextureHeight); DebuggerAppendMsg("ScaledS:%s, ScaledT:%s", p->pTexture->m_bScaledS?"T":"F", p->pTexture->m_bScaledT?"T":"F"); } else { DebuggerAppendMsg("No cached texture at index = %d\n", index); } } extern uint32 gObjTlutAddr; void DumpInfo(int thingToDump) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; switch(thingToDump) { case DUMP_COLORS: DebuggerAppendMsg("----Colors----\nPrim Color:\t%08X\nEnv Color:\t%08X\n" "Fill Color:\t%08X\nFog Color:\t%08X\n" "Prim Depth:\t%f\nPrim LOD Frac:\t%08X\n", GetPrimitiveColor(), GetEnvColor(), gRDP.fillColor, CRender::GetRender()->GetFogColor(), GetPrimitiveDepth(), GetLODFrac()); break; case DUMP_CUR_MUX: CRender::GetRender()->m_pColorCombiner->DisplayMuxString(); break; case DUMP_LIGHT: DebuggerAppendMsg("----Light Colors----\nNumber of Lights: %d\n",GetNumLights()); for( uint32 i=0; im_pColorCombiner->DisplaySimpleMuxString(); break; case DUMP_OTHER_MODE: DumpOtherMode(); break; case DUMP_FRAME_BUFFER: CRender::GetRender()->DrawFrameBuffer(true, 0, 0, 0, 0); break; case DUMP_CONTENT_AT: { } break; case DUMP_DLIST_AT: { } break; case DUMP_MATRIX_AT: { } break; case DUMP_NEXT_TEX: CachedTexIndex++; if( CachedTexIndex >= gTextureManager.GetNumOfCachedTexture() ) { CachedTexIndex = 0; } DumpCachedTexture(CachedTexIndex); break; case DUMP_PREV_TEX: CachedTexIndex--; if( CachedTexIndex < 0 || CachedTexIndex >= gTextureManager.GetNumOfCachedTexture() ) CachedTexIndex = 0; DumpCachedTexture(CachedTexIndex); break; case DUMP_CACHED_TEX: DumpCachedTexture(CachedTexIndex); break; case DUMP_TEXBUFFER_AT: { } break; case DUMP_COMBINED_MATRIX: DumpMatrix2(gRSPworldProject,"Combined Matrix"); break; case DUMP_WORLD_TOP_MATRIX: DumpMatrix2(gRSP.modelviewMtxs[gRSP.modelViewMtxTop],"World Top Matrix"); break; case DUMP_WORLD_MATRIX_AT: { } break; case DUMP_PROJECTION_MATRIX: DumpMatrix2(gRSP.projectionMtxs[gRSP.projectionMtxTop],"Projection Top Matrix"); break; } } void SetLogToFile(bool log) { if( log ) { if( logFp == NULL ) { logFp = fopen("\\RiceVideo.log", "at"); } } else { if( logFp != NULL ) { fclose(logFp); logFp = NULL; } } } void DebuggerAppendMsg(const char * Message, ...) { if( !logToScreen && !logToFile ) return; char Msg[5000]; va_list ap; va_start( ap, Message ); vsprintf( Msg, Message, ap ); va_end( ap ); if( Msg[strlen(Msg)-1]!='\n' ) strcat(Msg,"\n"); if( logToScreen ) { DebugMessage(M64MSG_INFO, "Rice Debug: %s", Msg); } if( logToFile ) { fprintf(logFp, "%s\n", Msg); } } void DebuggerPause() { while( debuggerPause ) { if( debuggerDrawRenderTexture ) { g_pFrameBufferManager->DisplayRenderTexture(debuggerDrawRenderTextureNo); debuggerDrawRenderTexture = false; } usleep(100 * 1000); debuggerPause = false; } } void LOG_UCODE(const char* szFormat, ...) { if( logUcodes) { char Msg[400]; va_list va; va_start(va, szFormat); vsprintf( Msg, szFormat, va ); va_end(va); DebuggerAppendMsg("%s\n", Msg); } } void DumpHex(uint32 rdramAddr, int count) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; rdramAddr &= 0xFFFFFFF0; uint32 *ptr = (uint32 *)((rdramAddr&(g_dwRamSize-1))+ rdram_u8); for( int i=0; i<(count+3)/4; i++) { DebuggerAppendMsg("%08X: %08X, %08X, %08X, %08X\n", rdramAddr+i*16, ptr[i*4], ptr[i*4+1], ptr[i*4+2], ptr[i*4+3]); } DebuggerAppendMsg("\n"); } uint32 StrToHex(char *HexStr) { uint32 temp = 0; for(uint32 k = 0; k < strlen(HexStr); k++) { if(HexStr[k] <= '9' && HexStr[k] >= '0') { temp = temp << 4; temp += HexStr[k] - '0'; } else if(HexStr[k] <= 'F' && HexStr[k] >= 'A') { temp = temp << 4; temp += HexStr[k] - 'A' + 10; } else if(HexStr[k] <= 'f' && HexStr[k] >= 'a') { temp = temp << 4; temp += HexStr[k] - 'a' + 10; } else { return(temp); } } return(temp); } void DEBUGGER_PAUSE_COUNT_N(uint32 val) { if (eventToPause == (int)val) { if(debuggerPauseCount>0) debuggerPauseCount--; if(debuggerPauseCount==0) { CGraphicsContext::Get()->UpdateFrame(false); debuggerPause = true; } } } void DEBUGGER_PAUSE_COUNT_N_WITHOUT_UPDATE(uint32 val) { if(eventToPause == (int)val) { if(debuggerPauseCount>0) debuggerPauseCount--; if(debuggerPauseCount==0) { debuggerPauseCount = countToPause; debuggerPause = true; } } } void DumpMatrix2(const Matrix &mat, const char* prompt) { DebuggerAppendMsg(prompt); DebuggerAppendMsg( " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\n" " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\n" " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\n" " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\n", mat.m[0][0], mat.m[0][1], mat.m[0][2], mat.m[0][3], mat.m[1][0], mat.m[1][1], mat.m[1][2], mat.m[1][3], mat.m[2][0], mat.m[2][1], mat.m[2][2], mat.m[2][3], mat.m[3][0], mat.m[3][1], mat.m[3][2], mat.m[3][3]); } void DumpMatrix(const Matrix &mat, const char* prompt) { if( pauseAtNext && logMatrix ) { DumpMatrix2(mat, prompt); } } #endif mupen64plus-core/src/si/mempak.h000664 001750 001750 00000003660 12655644434 017701 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - mempak.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_SI_MEMPAK_H #define M64P_SI_MEMPAK_H #include struct mempak { /* external mpk storage */ void* user_data; void (*save)(void*); uint8_t* data; }; enum { MEMPAK_SIZE = 0x8000 }; void mempak_save(struct mempak* mpk); void format_mempak(uint8_t* mempak); void mempak_read_command(struct mempak* mpk, uint8_t* cmd); void mempak_write_command(struct mempak* mpk, uint8_t* cmd); #endif mupen64plus-core/src/memory/000700 001750 001750 00000000000 12656647145 017135 5ustar00sergiosergio000000 000000 mupen64plus-core/src/r4300/new_dynarec/000700 001750 001750 00000000000 12656647145 020673 5ustar00sergiosergio000000 000000 mupen64plus-core/src/api/callbacks.c000664 001750 001750 00000005255 12655644434 020501 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-core - api/callbacks.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2009 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file contains the Core functions for handling callbacks to the * front-end application */ #include #include #include #include "m64p_types.h" #include "callbacks.h" /* local variables */ static ptr_DebugCallback pDebugFunc = NULL; static ptr_StateCallback pStateFunc = NULL; static void * DebugContext = NULL; static void * StateContext = NULL; /* global Functions for use by the Core */ m64p_error SetDebugCallback(ptr_DebugCallback pFunc, void *Context) { pDebugFunc = pFunc; DebugContext = Context; return M64ERR_SUCCESS; } m64p_error SetStateCallback(ptr_StateCallback pFunc, void *Context) { pStateFunc = pFunc; StateContext = Context; return M64ERR_SUCCESS; } void DebugMessage(int level, const char *message, ...) { char msgbuf[256]; va_list args; if (pDebugFunc == NULL) return; va_start(args, message); vsprintf(msgbuf, message, args); (*pDebugFunc)(DebugContext, level, msgbuf); va_end(args); } void StateChanged(m64p_core_param param_type, int new_value) { if (pStateFunc == NULL) return; (*pStateFunc)(StateContext, param_type, new_value); } mupen64plus-core/src/si/mempak.c000664 001750 001750 00000006574 12655644434 017703 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - mempak.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "mempak.h" #include #include void mempak_save(struct mempak* mpk) { mpk->save(mpk->user_data); } void format_mempak(uint8_t* mpk_data) { size_t i; static const uint8_t init[] = { 0x81,0x01,0x02,0x03, 0x04,0x05,0x06,0x07, 0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f, 0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17, 0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f, 0xff,0xff,0xff,0xff, 0x05,0x1a,0x5f,0x13, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0x01,0xff, 0x66,0x25,0x99,0xcd, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0xff,0xff,0xff,0xff, 0x05,0x1a,0x5f,0x13, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0x01,0xff, 0x66,0x25,0x99,0xcd, 0xff,0xff,0xff,0xff, 0x05,0x1a,0x5f,0x13, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0x01,0xff, 0x66,0x25,0x99,0xcd, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0xff,0xff,0xff,0xff, 0x05,0x1a,0x5f,0x13, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0x01,0xff, 0x66,0x25,0x99,0xcd, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x71,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03 }; memcpy(mpk_data, init, 272); for(i = 272; i < MEMPAK_SIZE; i += 2) { mpk_data[i] = 0x00; mpk_data[i+1] = 0x03; } } void mempak_read_command(struct mempak* mpk, uint8_t* cmd) { uint16_t address = (cmd[3] << 8) | (cmd[4] & 0xe0); if (address < 0x8000) { memcpy(&cmd[5], &mpk->data[address], 0x20); } else { memset(&cmd[5], 0x00, 0x20); } } void mempak_write_command(struct mempak* mpk, uint8_t* cmd) { uint16_t address = (cmd[3] << 8) | (cmd[4] & 0xe0); if (address < 0x8000) { memcpy(&mpk->data[address], &cmd[5], 0x20); mempak_save(mpk); } else { /* do nothing */ } } gles2rice/src/FrameBuffer.h000664 001750 001750 00000014013 12655644434 016721 0ustar00sergiosergio000000 000000 /* Copyright (C) 2002 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _FRAME_BUFFER_H_ #define _FRAME_BUFFER_H_ #include "typedefs.h" #include "RenderTexture.h" #include "TextureManager.h" typedef int SURFFORMAT; extern void TexRectToN64FrameBuffer_16b(uint32_t x0, uint32_t y0, uint32_t width, uint32_t height, uint32_t dwTile); extern void TexRectToFrameBuffer_8b(uint32_t dwXL, uint32_t dwYL, uint32_t dwXH, uint32_t dwYH, float t0u0, float t0v0, float t0u1, float t0v1, uint32_t dwTile); class FrameBufferManager { friend class CGraphicsContext; friend class CDXGraphicsContext; public: FrameBufferManager(); virtual ~FrameBufferManager(); void Initialize(); void CloseUp(); void Set_CI_addr(SetImgInfo &newCI); void UpdateRecentCIAddr(SetImgInfo &ciinfo); void SetAddrBeDisplayed(uint32_t addr); bool HasAddrBeenDisplayed(uint32_t addr, uint32_t width); int FindRecentCIInfoIndex(uint32_t addr); bool IsDIaRenderTexture(); int CheckAddrInRenderTextures(uint32_t addr, bool checkcrc); uint32_t ComputeRenderTextureCRCInRDRAM(int infoIdx); void CheckRenderTextureCRCInRDRAM(void); int CheckRenderTexturesWithNewCI(SetImgInfo &CIinfo, uint32_t height, bool byNewTxtrBuf); virtual void ClearN64FrameBufferToBlack(uint32_t left, uint32_t top, uint32_t width, uint32_t height); virtual int SetBackBufferAsRenderTexture(SetImgInfo &CIinfo, int ciInfoIdx); void LoadTextureFromRenderTexture(TxtrCacheEntry* pEntry, int infoIdx); void UpdateFrameBufferBeforeUpdateFrame(); virtual void RestoreNormalBackBuffer(); // restore the normal back buffer virtual void CopyBackToFrameBufferIfReadByCPU(uint32_t addr); virtual void SetRenderTexture(void); virtual void CloseRenderTexture(bool toSave); virtual void ActiveTextureBuffer(void); int IsAddrInRecentFrameBuffers(uint32_t addr); int CheckAddrInBackBuffers(uint32_t addr, uint32_t memsize, bool copyToRDRAM); uint8_t CIFindIndex(uint16_t val); uint32_t ComputeCImgHeight(SetImgInfo &info, uint32_t &height); int FindASlot(void); bool ProcessFrameWriteRecord(); void FrameBufferWriteByCPU(uint32_t addr, uint32_t size); void FrameBufferReadByCPU( uint32_t addr ); bool FrameBufferInRDRAMCheckCRC(); void StoreRenderTextureToRDRAM(int infoIdx); virtual bool IsRenderingToTexture() {return m_isRenderingToTexture;} // Device dependent functions virtual void SaveBackBuffer(int ciInfoIdx, M64P_RECT* pRect, bool forceToSaveToRDRAM); // Copy the current back buffer to temp buffer virtual void CopyBackBufferToRenderTexture(int idx, RecentCIInfo &ciInfo, M64P_RECT* pRect) {} // Copy the current back buffer to temp buffer virtual void CopyBufferToRDRAM(uint32_t addr, uint32_t fmt, uint32_t siz, uint32_t width, uint32_t height, uint32_t bufWidth, uint32_t bufHeight, uint32_t startaddr, uint32_t memsize, uint32_t pitch, TextureFmt bufFmt, void *surf, uint32_t bufPitch); virtual void StoreBackBufferToRDRAM(uint32_t addr, uint32_t fmt, uint32_t siz, uint32_t width, uint32_t height, uint32_t bufWidth, uint32_t bufHeight, uint32_t startaddr, uint32_t memsize, uint32_t pitch, SURFFORMAT surf_fmt) {} #ifdef DEBUGGER virtual void DisplayRenderTexture(int infoIdx); #endif protected: bool m_isRenderingToTexture; int m_curRenderTextureIndex; int m_lastTextureBufferIndex; }; // // DirectX Framebuffer // class DXFrameBufferManager : public FrameBufferManager { virtual ~DXFrameBufferManager() {} public: // Device dependent functions virtual void CopyBackBufferToRenderTexture(int idx, RecentCIInfo &ciInfo, M64P_RECT* pRect); // Copy the current back buffer to temp buffer virtual void StoreBackBufferToRDRAM(uint32_t addr, uint32_t fmt, uint32_t siz, uint32_t width, uint32_t height, uint32_t bufWidth, uint32_t bufHeight, uint32_t startaddr, uint32_t memsize, uint32_t pitch, SURFFORMAT surf_fmt); }; // // OpenGL Framebuffer // class OGLFrameBufferManager : public FrameBufferManager { virtual ~OGLFrameBufferManager() {} public: // Device dependent functions virtual void CopyBackBufferToRenderTexture(int idx, RecentCIInfo &ciInfo, M64P_RECT* pRect); // Copy the current back buffer to temp buffer virtual void StoreBackBufferToRDRAM(uint32_t addr, uint32_t fmt, uint32_t siz, uint32_t width, uint32_t height, uint32_t bufWidth, uint32_t bufHeight, uint32_t startaddr, uint32_t memsize, uint32_t pitch, SURFFORMAT surf_fmt); }; extern RenderTextureInfo gRenderTextureInfos[]; extern RenderTextureInfo newRenderTextureInfo; #define NEW_TEXTURE_BUFFER extern RenderTextureInfo g_ZI_saves[2]; extern RenderTextureInfo *g_pRenderTextureInfo; extern FrameBufferManager* g_pFrameBufferManager; extern RecentCIInfo g_RecentCIInfo[]; extern RecentViOriginInfo g_RecentVIOriginInfo[]; extern RenderTextureInfo gRenderTextureInfos[]; extern int numOfTxtBufInfos; extern RecentCIInfo *g_uRecentCIInfoPtrs[5]; extern uint8_t RevTlutTable[0x10000]; extern uint32_t CalculateRDRAMCRC(void *pAddr, uint32_t left, uint32_t top, uint32_t width, uint32_t height, uint32_t size, uint32_t pitchInBytes); extern uint16_t ConvertRGBATo555(uint8_t r, uint8_t g, uint8_t b, uint8_t a); extern uint16_t ConvertRGBATo555(uint32_t color32); extern void InitTlutReverseLookup(void); #endif mupen64plus-video-gliden64/src/GLSLCombiner.h000664 001750 001750 00000007206 12655644434 022024 0ustar00sergiosergio000000 000000 #ifndef GLSL_COMBINER_H #define GLSL_COMBINER_H #include #include #include "gDP.h" #include "Combiner.h" class ShaderCombiner { public: ShaderCombiner(); ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCombine & _combine); ~ShaderCombiner(); void update(bool _bForce); void updateFogMode(bool _bForce = false); void updateDitherMode(bool _bForce = false); void updateLOD(bool _bForce = false); void updateFBInfo(bool _bForce = false); void updateDepthInfo(bool _bForce = false); void updateAlphaTestInfo(bool _bForce = false); void updateTextureInfo(bool _bForce = false); void updateRenderState(bool _bForce = false); u64 getMux() const {return m_combine.mux;} bool usesTile(u32 _t) const { if (_t == 0) return (m_nInputs & ((1<> (std::istream & _os, ShaderCombiner & _combiner); static void getShaderCombinerOptionsSet(std::vector & _vecOptions); private: friend class UniformBlock; friend class UniformSet; struct iUniform { GLint loc; int val; void set(int _val, bool _force) { if (loc >= 0 && (_force || val != _val)) { val = _val; glUniform1i(loc, _val); } } }; struct fUniform { GLint loc; float val; void set(float _val, bool _force) { if (loc >= 0 && (_force || val != _val)) { val = _val; glUniform1f(loc, _val); } } }; struct fv2Uniform { GLint loc; float val[2]; void set(float _val1, float _val2, bool _force) { if (loc >= 0 && (_force || val[0] != _val1 || val[1] != _val2)) { val[0] = _val1; val[1] = _val2; glUniform2f(loc, _val1, _val2); } } }; struct iv2Uniform { GLint loc; int val[2]; void set(int _val1, int _val2, bool _force) { if (loc >= 0 && (_force || val[0] != _val1 || val[1] != _val2)) { val[0] = _val1; val[1] = _val2; glUniform2i(loc, _val1, _val2); } } }; struct UniformLocation { iUniform uTex0, uTex1, uMSTex0, uMSTex1, uTexNoise, uTlutImage, uZlutImage, uDepthImage, uFogMode, uFogUsage, uEnableLod, uEnableAlphaTest, uEnableDepth, uEnableDepthCompare, uEnableDepthUpdate, uDepthMode, uDepthSource, uRenderState, uSpecialBlendMode, uMaxTile, uTextureDetail, uTexturePersp, uTextureFilterMode, uMSAASamples, uAlphaCompareMode, uAlphaDitherMode, uColorDitherMode; fUniform uFogAlpha, uMinLod, uDeltaZ, uAlphaTestValue, uMSAAScale; fv2Uniform uScreenScale, uDepthScale, uFogScale; iv2Uniform uMSTexEnabled, uFbMonochrome, uFbFixedAlpha; }; #ifdef OS_MAC_OS_X #define glUniform1i glUniform1iARB #define glUniform1f glUniform1fARB #define glUniform2f glUniform2fARB #define glUniform2i glUniform2iARB #define glUniform3fv glUniform3fvARB #define glUniform4fv glUniform4fvARB #endif void _locate_attributes() const; void _locateUniforms(); gDPCombine m_combine; UniformLocation m_uniforms; GLuint m_program; int m_nInputs; bool m_bNeedUpdate; }; void InitShaderCombiner(); void DestroyShaderCombiner(); #ifdef GL_IMAGE_TEXTURES_SUPPORT void SetDepthFogCombiner(); void SetMonochromeCombiner(); #endif // GL_IMAGE_TEXTURES_SUPPORT //#define USE_TOONIFY #endif //GLSL_COMBINER_H libretro/SDL_opengl.h000664 001750 001750 00000002111 12655644434 015673 0ustar00sergiosergio000000 000000 /* SDL - Simple DirectMedia Layer Copyright (C) 1997-2012 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Sam Lantinga slouken@libsdl.org */ /** @file SDL_opengl.h * This is a simple file to encapsulate the OpenGL API headers */ #ifndef _SDL_OPENGLES2_LIBRETRO_H #define _SDL_OPENGLES2_LIBRETRO_H #include "opengl_state_machine.h" #include "glsym/rglgen.h" #endif mupen64plus-core/tools/cheat_code_convert.py000755 001750 001750 00000010277 12655644434 022407 0ustar00sergiosergio000000 000000 #!/usr/bin/python '''* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - code_convert.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2010 Rhett Osborne * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Usage: python code_convert.py > ../data/mupencheat.txt < ../data/mupen64plus.cht ''' from sys import stdin class cheat: def __init__(self): self.n="" self.d="" self.c=[] self.v=0 self.hb='00' def add(self, l): if(self.n == ""): return l.append(" cn %s"%(self.n)) if(self.d != ""): l.append(" cd %s"%(self.d)) for code in self.c: l.append(" "+code) def clear(self): self.n="" self.d="" self.c=[] self.v=0 l=[] cCount=0 _cs = [] for i in range(225): _cs.append(cheat()) cs = _cs[:] def print_l(): global l, cs for cheat in cs: cheat.add(l) for line in l: print line.replace("\x00", "") l=[] cCount=0 for i in range(225): cs[i].clear() lines = stdin.read().split("\n") for line in lines: if len(line) < 2: continue elif(line[:2] == "//" and line != "//----" and line != "//---" ): l.append(line) elif len(line) < 4: continue elif(line[0] == '[' and line[-1] == ']' and len(line) > 23): print_l() l.append("\ncrc %s" % line[1:-1]) elif(line[:5] == "Name="): l.append("gn %s" % (line[5:])) elif(line[:5] == "Cheat"): t = line[5:].split('=')[0] if (len(t)>1 and t[-2] == '_'): n = int(t[:-2]) if(t[-1] == 'N'): cs[n].d = line.split("=")[1] else: for option in line.split("=")[1].split("$")[1:]: if(len(option) < 4): break; if(option[-1]==','): end =-1 else: end = None if(option[2] == " "): cs[n].c[cs[n].v] += "%s%s:\"%s\""%(cs[n].hb,option[:2],option[3:end].replace("\"", "\\\"")) else: cs[n].c[cs[n].v] += "%s:\"%s\""%(option[:4],option[5:end].replace("\"", "\\\"")) cs[n].c[cs[n].v]+=',' cs[n].c[cs[n].v] = cs[n].c[cs[n].v][:-1] else: n = int(t) cn = line.split('"') cs[n].c = cn[2][1:].split(',') cs[n].n = cn[1]; i=0 for cheat in cs[n].c: if(cheat[-1] == '?'): if(cheat[-2:] == '??' and cheat[-4:-2] != '??'): cs[n].hb = cheat[-4:-2] else: cs[n].hb = '00' cs[n].c[i] = cheat[:9] + "???? "; cs[n].v=i i+=1 if(n > cCount): cCount = n elif(line != "//----" and line != "//---" ): l.append("//%s" %line) mupen64plus-core/src/plugin/audio_libretro/drivers_resampler/sinc_neon.S000664 001750 001750 00000003135 12655644434 027770 0ustar00sergiosergio000000 000000 /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. * * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with RetroArch. * If not, see . */ #if defined(__ARM_NEON__) #ifndef __MACH__ .arm #endif .align 4 .globl process_sinc_neon_asm .globl _process_sinc_neon_asm # void process_sinc_neon(float *out, const float *left, const float *right, const float *coeff, unsigned taps) # Assumes taps is >= 8, and a multiple of 8. process_sinc_neon_asm: _process_sinc_neon_asm: push {r4, lr} vmov.f32 q0, #0.0 vmov.f32 q8, #0.0 # Taps argument (r4) goes on stack in armeabi. ldr r4, [sp, #8] 1: # Left vld1.f32 {q2-q3}, [r1]! # Right vld1.f32 {q10-q11}, [r2]! # Coeff vld1.f32 {q12-q13}, [r3, :128]! # Left / Right vmla.f32 q0, q2, q12 vmla.f32 q8, q10, q12 vmla.f32 q0, q3, q13 vmla.f32 q8, q11, q13 subs r4, r4, #8 bne 1b # Add everything together vadd.f32 d0, d0, d1 vadd.f32 d16, d16, d17 vpadd.f32 d0, d0, d16 vst1.f32 d0, [r0] pop {r4, pc} #endif tools/gas-preprocessor.pl000664 001750 001750 00000036601 12655644434 016720 0ustar00sergiosergio000000 000000 #!/usr/bin/env perl # by David Conrad # This code is licensed under GPLv2 or later; go to gnu.org to read it # (not that it much matters for an asm preprocessor) # usage: set your assembler to be something like "perl gas-preprocessor.pl gcc" use strict; # Apple's gas is ancient and doesn't support modern preprocessing features like # .rept and has ugly macro syntax, among other things. Thus, this script # implements the subset of the gas preprocessor used by x264 and ffmpeg # that isn't supported by Apple's gas. my @gcc_cmd = @ARGV; my @preprocess_c_cmd; my $fix_unreq = $^O eq "darwin"; if ($gcc_cmd[0] eq "-fix-unreq") { $fix_unreq = 1; shift @gcc_cmd; } elsif ($gcc_cmd[0] eq "-no-fix-unreq") { $fix_unreq = 0; shift @gcc_cmd; } if (grep /\.c$/, @gcc_cmd) { # C file (inline asm?) - compile @preprocess_c_cmd = (@gcc_cmd, "-S"); } elsif (grep /\.[sS]$/, @gcc_cmd) { # asm file, just do C preprocessor @preprocess_c_cmd = (@gcc_cmd, "-E"); } else { die "Unrecognized input filetype"; } # if compiling, avoid creating an output file named '-.o' if ((grep /^-c$/, @gcc_cmd) && !(grep /^-o/, @gcc_cmd)) { foreach my $i (@gcc_cmd) { if ($i =~ /\.[csS]$/) { my $outputfile = $i; $outputfile =~ s/\.[csS]$/.o/; push(@gcc_cmd, "-o"); push(@gcc_cmd, $outputfile); last; } } } @gcc_cmd = map { /\.[csS]$/ ? qw(-x assembler -) : $_ } @gcc_cmd; @preprocess_c_cmd = map { /\.o$/ ? "-" : $_ } @preprocess_c_cmd; my $comm; # detect architecture from gcc binary name if ($gcc_cmd[0] =~ /arm/) { $comm = '@'; } elsif ($gcc_cmd[0] =~ /powerpc|ppc/) { $comm = '#'; } # look for -arch flag foreach my $i (1 .. $#gcc_cmd-1) { if ($gcc_cmd[$i] eq "-arch") { if ($gcc_cmd[$i+1] =~ /arm/) { $comm = '@'; } elsif ($gcc_cmd[$i+1] =~ /powerpc|ppc/) { $comm = '#'; } } } # assume we're not cross-compiling if no -arch or the binary doesn't have the arch name if (!$comm) { my $native_arch = qx/arch/; if ($native_arch =~ /arm/) { $comm = '@'; } elsif ($native_arch =~ /powerpc|ppc/) { $comm = '#'; } } if (!$comm) { die "Unable to identify target architecture"; } my %ppc_spr = (ctr => 9, vrsave => 256); open(ASMFILE, "-|", @preprocess_c_cmd) || die "Error running preprocessor"; my $current_macro = ''; my $macro_level = 0; my %macro_lines; my %macro_args; my %macro_args_default; my $macro_count = 0; my $altmacro = 0; my @pass1_lines; my @ifstack; my %symbols; # pass 1: parse .macro # note that the handling of arguments is probably overly permissive vs. gas # but it should be the same for valid cases while () { # remove all comments (to avoid interfering with evaluating directives) s/(? 0) { $ifstack[-1] = -$ifstack[-1]; } return; } elsif (/\.else/) { $ifstack[-1] = !$ifstack[-1]; return; } elsif (handle_if($line)) { return; } # discard lines in false .if blocks foreach my $i (0 .. $#ifstack) { if ($ifstack[$i] <= 0) { return; } } } if (/\.macro/) { $macro_level++; if ($macro_level > 1 && !$current_macro) { die "nested macros but we don't have master macro"; } } elsif (/\.endm/) { $macro_level--; if ($macro_level < 0) { die "unmatched .endm"; } elsif ($macro_level == 0) { $current_macro = ''; return; } } if ($macro_level > 1) { push(@{$macro_lines{$current_macro}}, $line); } elsif ($macro_level == 0) { expand_macros($line); } else { if ($line =~ /\.macro\s+([\d\w\.]+)\s*(.*)/) { $current_macro = $1; # commas in the argument list are optional, so only use whitespace as the separator my $arglist = $2; $arglist =~ s/,/ /g; my @args = split(/\s+/, $arglist); foreach my $i (0 .. $#args) { my @argpair = split(/=/, $args[$i]); $macro_args{$current_macro}[$i] = $argpair[0]; $argpair[0] =~ s/:vararg$//; $macro_args_default{$current_macro}{$argpair[0]} = $argpair[1]; } # ensure %macro_lines has the macro name added as a key $macro_lines{$current_macro} = []; } elsif ($current_macro) { push(@{$macro_lines{$current_macro}}, $line); } else { die "macro level without a macro name"; } } } sub expand_macros { my $line = @_[0]; # handle .if directives; apple's assembler doesn't support important non-basic ones # evaluating them is also needed to handle recursive macros if (handle_if($line)) { return; } if (/\.purgem\s+([\d\w\.]+)/) { delete $macro_lines{$1}; delete $macro_args{$1}; delete $macro_args_default{$1}; return; } if ($line =~ /\.altmacro/) { $altmacro = 1; return; } if ($line =~ /\.noaltmacro/) { $altmacro = 0; return; } $line =~ s/\%([^,]*)/eval_expr($1)/eg if $altmacro; if ($line =~ /\.set\s+(.*),\s*(.*)/) { $symbols{$1} = eval_expr($2); } if ($line =~ /(\S+:|)\s*([\w\d\.]+)\s*(.*)/ && exists $macro_lines{$2}) { push(@pass1_lines, $1); my $macro = $2; # commas are optional here too, but are syntactically important because # parameters can be blank my @arglist = split(/,/, $3); my @args; my @args_seperator; my $comma_sep_required = 0; foreach (@arglist) { # allow arithmetic/shift operators in macro arguments $_ =~ s/\s*(\+|-|\*|\/|<<|>>)\s*/$1/g; my @whitespace_split = split(/\s+/, $_); if (!@whitespace_split) { push(@args, ''); push(@args_seperator, ''); } else { foreach (@whitespace_split) { #print ("arglist = \"$_\"\n"); if (length($_)) { push(@args, $_); my $sep = $comma_sep_required ? "," : " "; push(@args_seperator, $sep); #print ("sep = \"$sep\", arg = \"$_\"\n"); $comma_sep_required = 0; } } } $comma_sep_required = 1; } my %replacements; if ($macro_args_default{$macro}){ %replacements = %{$macro_args_default{$macro}}; } # construct hashtable of text to replace foreach my $i (0 .. $#args) { my $argname = $macro_args{$macro}[$i]; my @macro_args = @{ $macro_args{$macro} }; if ($args[$i] =~ m/=/) { # arg=val references the argument name # XXX: I'm not sure what the expected behaviour if a lot of # these are mixed with unnamed args my @named_arg = split(/=/, $args[$i]); $replacements{$named_arg[0]} = $named_arg[1]; } elsif ($i > $#{$macro_args{$macro}}) { # more args given than the macro has named args # XXX: is vararg allowed on arguments before the last? $argname = $macro_args{$macro}[-1]; if ($argname =~ s/:vararg$//) { #print "macro = $macro, args[$i] = $args[$i], args_seperator=@args_seperator, argname = $argname, arglist[$i] = $arglist[$i], arglist = @arglist, args=@args, macro_args=@macro_args\n"; #$replacements{$argname} .= ", $args[$i]"; $replacements{$argname} .= "$args_seperator[$i] $args[$i]"; } else { die "Too many arguments to macro $macro"; } } else { $argname =~ s/:vararg$//; $replacements{$argname} = $args[$i]; } } my $count = $macro_count++; # apply replacements as regex foreach (@{$macro_lines{$macro}}) { my $macro_line = $_; # do replacements by longest first, this avoids wrong replacement # when argument names are subsets of each other foreach (reverse sort {length $a <=> length $b} keys %replacements) { $macro_line =~ s/\\$_/$replacements{$_}/g; } $macro_line =~ s/\\\@/$count/g; $macro_line =~ s/\\\(\)//g; # remove \() parse_line($macro_line); } } else { push(@pass1_lines, $line); } } close(ASMFILE) or exit 1; open(ASMFILE, "|-", @gcc_cmd) or die "Error running assembler"; #open(ASMFILE, ">/tmp/a.S") or die "Error running assembler"; my @sections; my $num_repts; my $rept_lines; my %literal_labels; # for ldr , = my $literal_num = 0; my $thumb = 0; my %thumb_labels; my %call_targets; my $in_irp = 0; my @irp_args; my $irp_param; # pass 2: parse .rept and .if variants # NOTE: since we don't implement a proper parser, using .rept with a # variable assigned from .set is not supported foreach my $line (@pass1_lines) { # handle .previous (only with regard to .section not .subsection) if ($line =~ /\.(section|text|const_data)/) { push(@sections, $line); } elsif ($line =~ /\.previous/) { if (!$sections[-2]) { die ".previous without a previous section"; } $line = $sections[-2]; push(@sections, $line); } $thumb = 1 if $line =~ /\.code\s+16|\.thumb/; $thumb = 0 if $line =~ /\.code\s+32|\.arm/; # handle ldr , = if ($line =~ /(.*)\s*ldr([\w\s\d]+)\s*,\s*=(.*)/) { my $label = $literal_labels{$3}; if (!$label) { $label = "Literal_$literal_num"; $literal_num++; $literal_labels{$3} = $label; } $line = "$1 ldr$2, $label\n"; } elsif ($line =~ /\.ltorg/) { $line .= ".align 2\n"; foreach my $literal (keys %literal_labels) { $line .= "$literal_labels{$literal}:\n .word $literal\n"; } %literal_labels = (); } # thumb add with large immediate needs explicit add.w if ($thumb and $line =~ /add\s+.*#([^@]+)/) { $line =~ s/add/add.w/ if eval_expr($1) > 255; } # mach-o local symbol names start with L (no dot) $line =~ s/(? lo16() @ha -> ha16() $line =~ s/,\s+([^,]+)\@l\b/, lo16($1)/g; $line =~ s/,\s+([^,]+)\@ha\b/, ha16($1)/g; # move to/from SPR if ($line =~ /(\s+)(m[ft])([a-z]+)\s+(\w+)/ and exists $ppc_spr{$3}) { if ($2 eq 'mt') { $line = "$1${2}spr $ppc_spr{$3}, $4\n"; } else { $line = "$1${2}spr $4, $ppc_spr{$3}\n"; } } # old gas versions store upper and lower case names on .req, # but they remove only one on .unreq if ($fix_unreq) { if ($line =~ /\.unreq\s+(.*)/) { $line = ".unreq " . lc($1) . "\n"; print ASMFILE ".unreq " . uc($1) . "\n"; } } if ($line =~ /\.rept\s+(.*)/) { $num_repts = $1; $rept_lines = "\n"; # handle the possibility of repeating another directive on the same line # .endr on the same line is not valid, I don't know if a non-directive is if ($num_repts =~ s/(\.\w+.*)//) { $rept_lines .= "$1\n"; } $num_repts = eval($num_repts); } elsif ($line =~ /\.irp\s+([\d\w\.]+)\s*(.*)/) { $in_irp = 1; $num_repts = 1; $rept_lines = "\n"; $irp_param = $1; # only use whitespace as the separator my $irp_arglist = $2; $irp_arglist =~ s/,/ /g; $irp_arglist =~ s/^\s+//; @irp_args = split(/\s+/, $irp_arglist); } elsif ($line =~ /\.irpc\s+([\d\w\.]+)\s*(.*)/) { $in_irp = 1; $num_repts = 1; $rept_lines = "\n"; $irp_param = $1; my $irp_arglist = $2; $irp_arglist =~ s/,/ /g; $irp_arglist =~ s/^\s+//; @irp_args = split(//, $irp_arglist); } elsif ($line =~ /\.endr/) { if ($in_irp != 0) { foreach my $i (@irp_args) { my $line = $rept_lines; $line =~ s/\\$irp_param/$i/g; $line =~ s/\\\(\)//g; # remove \() print ASMFILE $line; } } else { for (1 .. $num_repts) { print ASMFILE $rept_lines; } } $rept_lines = ''; $in_irp = 0; @irp_args = ''; } elsif ($rept_lines) { $rept_lines .= $line; } else { print ASMFILE $line; } } print ASMFILE ".text\n"; print ASMFILE ".align 2\n"; foreach my $literal (keys %literal_labels) { print ASMFILE "$literal_labels{$literal}:\n .word $literal\n"; } map print(ASMFILE ".thumb_func $_\n"), grep exists $thumb_labels{$_}, keys %call_targets; close(ASMFILE) or exit 1; #exit 1 glide2gl/src/Glitch64/000700 001750 001750 00000000000 12656647145 015552 5ustar00sergiosergio000000 000000 mupen64plus-video-gliden64/src/GLideNHQ/CMakeLists.txt000664 001750 001750 00000010155 12655644434 023523 0ustar00sergiosergio000000 000000 cmake_minimum_required(VERSION 2.6) project( GLideNHQ ) set(GLideNHQ_SOURCES TextureFilters.cpp TextureFilters_2xsai.cpp TextureFilters_hq2x.cpp TextureFilters_hq4x.cpp TextureFilters_xbrz.cpp TxCache.cpp TxDbg.cpp TxFilter.cpp TxFilterExport.cpp TxHiResCache.cpp TxImage.cpp TxQuantize.cpp TxReSample.cpp TxTexCache.cpp TxUtil.cpp ) if(PANDORA OR BCMHOST) include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../osal ) else(PANDORA OR BCMHOST) include_directories( inc ${CMAKE_CURRENT_SOURCE_DIR}/../osal ) endif(PANDORA OR BCMHOST) LINK_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/lib ) if(UNIX) add_definitions( -DNDEBUG -DOS_LINUX ) endif(UNIX) if(WIN32) LINK_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/lib ) add_definitions( -DWIN32 -DOS_WINDOWS -D_CRT_SECURE_NO_WARNINGS ) endif(WIN32) # Build type if( NOT CMAKE_BUILD_TYPE) set( CMAKE_BUILD_TYPE Release) endif( NOT CMAKE_BUILD_TYPE) if( CMAKE_BUILD_TYPE STREQUAL "Debug") set( CMAKE_BUILD_TYPE Debug) set( DEBUG_BUILD TRUE) add_definitions( -DDEBUG ) endif( CMAKE_BUILD_TYPE STREQUAL "Debug") if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") add_definitions( -D__MSC__) endif() if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") SET(GCC_CPP11_COMPILE_FLAGS "-std=c++0x") if( NOT GHQCHK ) SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_CPP11_COMPILE_FLAGS} -static -fPIC " ) SET( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static -fPIC " ) else( NOT GHQCHK ) SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_CPP11_COMPILE_FLAGS}" ) endif( NOT GHQCHK ) #SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_CPP11_COMPILE_FLAGS} " ) endif() if( NOT GHQCHK ) add_definitions( -DTXFILTER_LIB) if( CMAKE_BUILD_TYPE STREQUAL "Debug") add_library( GLideNHQd STATIC ${GLideNHQ_SOURCES}) set_target_properties(GLideNHQd PROPERTIES LINK_SEARCH_START_STATIC 1) set_target_properties(GLideNHQd PROPERTIES LINK_SEARCH_END_STATIC 1) if(BCMHOST) FIND_PACKAGE( ZLIB REQUIRED ) FIND_PACKAGE( PNG REQUIRED ) target_link_libraries(GLideNHQd ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} osald ) else(BCMHOST) target_link_libraries(GLideNHQd PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/lib/libpng.a ${CMAKE_CURRENT_SOURCE_DIR}/lib/libz.a dl osald ) endif(BCMHOST) endif( CMAKE_BUILD_TYPE STREQUAL "Debug") if( CMAKE_BUILD_TYPE STREQUAL "Release") add_library( GLideNHQ STATIC ${GLideNHQ_SOURCES}) # set_target_properties(GLideNHQ PROPERTIES LINK_SEARCH_START_STATIC 1) # set_target_properties(GLideNHQ PROPERTIES LINK_SEARCH_END_STATIC 1) # set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") # find_library(PNGLIB libpng.a) if(PANDORA) target_link_libraries(GLideNHQ PRIVATE /mnt/utmp/codeblocks/usr/lib/libpng.a /mnt/utmp/codeblocks/usr/lib/libz.a osal ) elseif(BCMHOST) FIND_PACKAGE( ZLIB REQUIRED ) FIND_PACKAGE( PNG REQUIRED ) target_link_libraries(GLideNHQ ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} osal ) else(PANDORA) target_link_libraries(GLideNHQ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/lib/libpng.a ${CMAKE_CURRENT_SOURCE_DIR}/lib/libz.a dl osal ) endif(PANDORA) endif( CMAKE_BUILD_TYPE STREQUAL "Release") else( NOT GHQCHK ) add_definitions(-DGHQCHK) add_library( ghqchk SHARED ${GLideNHQ_SOURCES}) SET_TARGET_PROPERTIES( ghqchk PROPERTIES LINKER_LANGUAGE CXX # Or else we get an error message, because cmake can't figure out from the ".o"-suffix that it is a C-linker we need. PREFIX "" LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/plugin ) if( CMAKE_BUILD_TYPE STREQUAL "Debug") target_link_libraries(ghqchk ${OPENGL_LIBRARIES} png z ) endif( CMAKE_BUILD_TYPE STREQUAL "Debug") if( CMAKE_BUILD_TYPE STREQUAL "Release") target_link_libraries(ghqchk ${OPENGL_LIBRARIES} png z ) endif( CMAKE_BUILD_TYPE STREQUAL "Release") endif( NOT GHQCHK ) mupen64plus-core/tools/savestate_convert.c000664 001750 001750 00000025705 12655644434 022123 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - savestate_convert.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2008 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include /* savestate file header: magic number and version number */ const char *savestate_magic = "M64+SAVE"; const int savestate_newest_version = 0x00010000; // 1.0 /* Data field lengths */ #define SIZE_REG_RDRAM 40 #define SIZE_REG_MIPS 36 #define SIZE_REG_PI 52 #define SIZE_REG_SP 52 #define SIZE_REG_RSP 8 #define SIZE_REG_SI 16 #define SIZE_REG_VI 60 #define SIZE_REG_RI 32 #define SIZE_REG_AI 40 #define SIZE_REG_DPC 48 #define SIZE_REG_DPS 16 #define SIZE_FLASHRAM_INFO 24 #define SIZE_TLB_ENTRY 52 #define SIZE_MAX_EVENTQUEUE 1024 /* Arrays and pointers for savestate data */ char rom_md5[32]; char rdram_register[SIZE_REG_RDRAM]; char mips_register[SIZE_REG_MIPS]; char pi_register[SIZE_REG_PI]; char sp_register[SIZE_REG_SP]; char rsp_register[SIZE_REG_RSP]; char si_register[SIZE_REG_SI]; char vi_register[SIZE_REG_VI]; char ri_register[SIZE_REG_RI]; char ai_register[SIZE_REG_AI]; char dpc_register[SIZE_REG_DPC]; char dps_register[SIZE_REG_DPS]; char *rdram; /* 0x800000 bytes */ char SP_DMEM[0x1000]; char SP_IMEM[0x1000]; char PIF_RAM[0x40]; char flashram[SIZE_FLASHRAM_INFO]; char *tlb_LUT_r; /* 0x400000 bytes */ char *tlb_LUT_w; /* 0x400000 bytes */ char llbit[4]; char reg[32][8]; char g_cp0_regs[32][4]; char lo[8]; char hi[8]; char reg_cop1_fgr_64[32][8]; char FCR0[4]; char FCR31[4]; char tlb_e[32][SIZE_TLB_ENTRY]; char PCaddr[4]; char next_interupt[4]; char next_vi[4]; char vi_field[4]; char eventqueue[SIZE_MAX_EVENTQUEUE]; /* savestate data parameters calculated from file contents */ int queuelength = 0; /* Forward declarations for functions */ void printhelp(const char *progname); int allocate_memory(void); void free_memory(void); int load_original_mupen64(const char *filename); int save_newest(const char *filename); /* Main Function - parse arguments, check version, load state file, overwrite state file with new one */ int main(int argc, char *argv[]) { FILE *pfTest; gzFile f; char *filename; char magictag[8]; unsigned char inbuf[4]; int (*load_function)(const char *) = NULL; int iVersion; /* start by parsing the command-line arguments */ if (argc != 2 || strncmp(argv[1], "-h", 2) == 0 || strncmp(argv[1], "--help", 6) == 0) { printhelp(argv[0]); return 1; } filename = argv[1]; pfTest = fopen(filename, "rb"); if (pfTest == NULL) { printf("Error: cannot open savestate file '%s' for reading.\n", filename); return 2; } fclose(pfTest); /* try to determine the version of this savestate file */ f = gzopen(filename, "rb"); if (f == NULL) { printf("Error: state file '%s' is corrupt\n", filename); return 3; } if (gzread(f, magictag, 8) != 8 || gzread(f, inbuf, 4) != 4) { printf("Error: state file '%s' is corrupt: end of savestate file while reading header.\n", filename); gzclose(f); return 4; } gzclose(f); iVersion = inbuf[0]; iVersion = (iVersion << 8) | inbuf[1]; iVersion = (iVersion << 8) | inbuf[2]; iVersion = (iVersion << 8) | inbuf[3]; /* determine which type of savestate file to load, based on savestate version */ if (strncmp(magictag, savestate_magic, 8) != 0) { printf("Warning: old savestate file format. This is presumed to be from the original Mupen64 or Mupen64Plus version 1.4 or earlier.\n"); load_function = load_original_mupen64; } else if (iVersion == savestate_newest_version) { printf("This savestate file is already up to date (version %08x)\n", savestate_newest_version); return 0; } else { printf("This savestate file uses an unknown version (%08x)\n", iVersion); return 5; } /* allocate memory for savestate data */ if (allocate_memory() != 0) { printf("Error: couldn't allocate memory for savestate data storage.\n"); return 6; } /* load the savestate file */ if (load_function(filename) != 0) { free_memory(); return 7; } /* write new updated savestate file */ if (save_newest(filename) != 0) { free_memory(); return 8; } /* free the memory and return */ printf("Savestate file '%s' successfully converted to latest version (%08x).\n", filename, savestate_newest_version); free_memory(); return 0; } void printhelp(const char *progname) { printf("%s - convert older Mupen64Plus savestate files to most recent version.\n\n", progname); printf("Usage: %s [-h] [--help] \n\n", progname); printf(" -h, --help: display this message\n"); printf(" : full path to savestate file which will be overwritten with latest version.\n"); } int allocate_memory(void) { rdram = malloc(0x800000); if (rdram == NULL) return 1; tlb_LUT_r = malloc(0x400000); if (tlb_LUT_r == NULL) { free_memory(); return 2; } tlb_LUT_w = malloc(0x400000); if (tlb_LUT_w == NULL) { free_memory(); return 3; } return 0; } void free_memory(void) { if (rdram != NULL) { free(rdram); rdram = NULL; } if (tlb_LUT_r != NULL) { free(tlb_LUT_r); tlb_LUT_r = NULL; } if (tlb_LUT_w != NULL) { free(tlb_LUT_w); tlb_LUT_w = NULL; } } /* State Loading Functions */ int load_original_mupen64(const char *filename) { char buffer[4]; int i; gzFile f; f = gzopen(filename, "rb"); if (f == NULL) { printf("Error: savestate file '%s' is corrupt.\n", filename); return 1; } gzread(f, rom_md5, 32); gzread(f, rdram_register, SIZE_REG_RDRAM); gzread(f, mips_register, SIZE_REG_MIPS); gzread(f, pi_register, SIZE_REG_PI); gzread(f, sp_register, SIZE_REG_SP); gzread(f, rsp_register, SIZE_REG_RSP); gzread(f, si_register, SIZE_REG_SI); gzread(f, vi_register, SIZE_REG_VI); gzread(f, ri_register, SIZE_REG_RI); gzread(f, ai_register, SIZE_REG_AI); gzread(f, dpc_register, SIZE_REG_DPC); gzread(f, dps_register, SIZE_REG_DPS); gzread(f, rdram, 0x800000); gzread(f, SP_DMEM, 0x1000); gzread(f, SP_IMEM, 0x1000); gzread(f, PIF_RAM, 0x40); gzread(f, flashram, SIZE_FLASHRAM_INFO); memset(tlb_LUT_r, 0, 0x400000); memset(tlb_LUT_w, 0, 0x400000); gzread(f, tlb_LUT_r, 0x100000); gzread(f, tlb_LUT_w, 0x100000); gzread(f, llbit, 4); gzread(f, reg, 32*8); for (i = 0; i < 32; i++) { gzread(f, g_cp0_regs[i], 4); gzread(f, buffer, 4); /* for compatibility with older versions. */ } gzread(f, lo, 8); gzread(f, hi, 8); gzread(f, reg_cop1_fgr_64[0], 32 * 8); gzread(f, FCR0, 4); gzread(f, FCR31, 4); gzread(f, tlb_e[0], 32 * SIZE_TLB_ENTRY); gzread(f, PCaddr, 4); gzread(f, next_interupt, 4); gzread(f, next_vi, 4); gzread(f, vi_field, 4); queuelength = 0; while(queuelength < SIZE_MAX_EVENTQUEUE) { if (gzread(f, eventqueue + queuelength, 4) != 4) { printf("Error: savestate file '%s' is corrupt.\n", filename); return 2; } if (*((unsigned int*) &eventqueue[queuelength]) == 0xFFFFFFFF) { queuelength += 4; break; } gzread(f, eventqueue + queuelength + 4, 4); queuelength += 8; } if (queuelength >= SIZE_MAX_EVENTQUEUE) { printf("Error: savestate file '%s' has event queue larger than %i bytes.\n", filename, SIZE_MAX_EVENTQUEUE); return 3; } gzclose(f); return 0; } /* State Saving Functions */ int save_newest(const char *filename) { unsigned char outbuf[4]; gzFile f; f = gzopen(filename, "wb"); /* write magic number */ gzwrite(f, savestate_magic, 8); /* write savestate file version in big-endian */ outbuf[0] = (savestate_newest_version >> 24) & 0xff; outbuf[1] = (savestate_newest_version >> 16) & 0xff; outbuf[2] = (savestate_newest_version >> 8) & 0xff; outbuf[3] = (savestate_newest_version >> 0) & 0xff; gzwrite(f, outbuf, 4); gzwrite(f, rom_md5, 32); gzwrite(f, rdram_register, SIZE_REG_RDRAM); gzwrite(f, mips_register, SIZE_REG_MIPS); gzwrite(f, pi_register, SIZE_REG_PI); gzwrite(f, sp_register, SIZE_REG_SP); gzwrite(f, rsp_register, SIZE_REG_RSP); gzwrite(f, si_register, SIZE_REG_SI); gzwrite(f, vi_register, SIZE_REG_VI); gzwrite(f, ri_register, SIZE_REG_RI); gzwrite(f, ai_register, SIZE_REG_AI); gzwrite(f, dpc_register, SIZE_REG_DPC); gzwrite(f, dps_register, SIZE_REG_DPS); gzwrite(f, rdram, 0x800000); gzwrite(f, SP_DMEM, 0x1000); gzwrite(f, SP_IMEM, 0x1000); gzwrite(f, PIF_RAM, 0x40); gzwrite(f, flashram, SIZE_FLASHRAM_INFO); gzwrite(f, tlb_LUT_r, 0x400000); gzwrite(f, tlb_LUT_w, 0x400000); gzwrite(f, llbit, 4); gzwrite(f, reg[0], 32*8); gzwrite(f, g_cp0_regs[0], 32*4); gzwrite(f, lo, 8); gzwrite(f, hi, 8); gzwrite(f, reg_cop1_fgr_64[0], 32*8); gzwrite(f, FCR0, 4); gzwrite(f, FCR31, 4); gzwrite(f, tlb_e[0], 32 * SIZE_TLB_ENTRY); gzwrite(f, PCaddr, 4); gzwrite(f, next_interupt, 4); gzwrite(f, next_vi, 4); gzwrite(f, vi_field, 4); gzwrite(f, eventqueue, queuelength); gzclose(f); return 0; } libretro-common/libco/amd64.c000664 001750 001750 00000017545 12655644434 017212 0ustar00sergiosergio000000 000000 /* libco.amd64 (2009-10-12) author: byuu license: public domain */ #define LIBCO_C #include "libco.h" #include #include #if defined(__GNUC__) && !defined(_WIN32) && !defined(__cplusplus) #define CO_USE_INLINE_ASM #endif #ifdef __cplusplus extern "C" { #endif static thread_local long long co_active_buffer[64]; static thread_local cothread_t co_active_handle = 0; #ifndef CO_USE_INLINE_ASM static void (*co_swap)(cothread_t, cothread_t) = 0; #else void co_swap(cothread_t, cothread_t); #endif #ifdef _WIN32 //ABI: Win64 static unsigned char co_swap_function[] = { 0x48, 0x89, 0x22, /* mov [rdx],rsp */ 0x48, 0x8b, 0x21, /* mov rsp,[rcx] */ 0x58, /* pop rax */ 0x48, 0x89, 0x6a, 0x08, /* mov [rdx+0x8],rbp */ 0x48, 0x89, 0x72, 0x10, /* mov [rdx+0x10],rsi */ 0x48, 0x89, 0x7a, 0x18, /* mov [rdx+0x18],rdi */ 0x48, 0x89, 0x5a, 0x20, /* mov [rdx+0x20],rbx */ 0x4c, 0x89, 0x62, 0x28, /* mov [rdx+0x28],r12 */ 0x4c, 0x89, 0x6a, 0x30, /* mov [rdx+0x30],r13 */ 0x4c, 0x89, 0x72, 0x38, /* mov [rdx+0x38],r14 */ 0x4c, 0x89, 0x7a, 0x40, /* mov [rdx+0x40],r15 */ 0x48, 0x81, 0xc2, 0x80, 0x00, 0x00, 0x00, /* add rdx,0x80 */ 0x48, 0x83, 0xe2, 0xf0, /* and rdx,-0x10 */ 0x0f, 0x29, 0x32, /* movaps [rdx],xmm6 */ 0x0f, 0x29, 0x7a, 0x10, /* movaps [rdx+0x10],xmm7 */ 0x44, 0x0f, 0x29, 0x42, 0x20, /* movaps [rdx+0x20],xmm8 */ 0x44, 0x0f, 0x29, 0x4a, 0x30, /* movaps [rdx+0x30],xmm9 */ 0x44, 0x0f, 0x29, 0x52, 0x40, /* movaps [rdx+0x40],xmm10 */ 0x44, 0x0f, 0x29, 0x5a, 0x50, /* movaps [rdx+0x50],xmm11 */ 0x44, 0x0f, 0x29, 0x62, 0x60, /* movaps [rdx+0x60],xmm12 */ 0x44, 0x0f, 0x29, 0x6a, 0x70, /* movaps [rdx+0x70],xmm13 */ 0x44, 0x0f, 0x29, 0xb2, 0x80, 0x00, 0x00, 0x00, /* movaps [rdx+0x80],xmm14 */ 0x44, 0x0f, 0x29, 0xba, 0x90, 0x00, 0x00, 0x00, /* movaps [rdx+0x90],xmm15 */ 0x48, 0x8b, 0x69, 0x08, /* mov rbp,[rcx+0x8] */ 0x48, 0x8b, 0x71, 0x10, /* mov rsi,[rcx+0x10] */ 0x48, 0x8b, 0x79, 0x18, /* mov rdi,[rcx+0x18] */ 0x48, 0x8b, 0x59, 0x20, /* mov rbx,[rcx+0x20] */ 0x4c, 0x8b, 0x61, 0x28, /* mov r12,[rcx+0x28] */ 0x4c, 0x8b, 0x69, 0x30, /* mov r13,[rcx+0x30] */ 0x4c, 0x8b, 0x71, 0x38, /* mov r14,[rcx+0x38] */ 0x4c, 0x8b, 0x79, 0x40, /* mov r15,[rcx+0x40] */ 0x48, 0x81, 0xc1, 0x80, 0x00, 0x00, 0x00, /* add rcx,0x80 */ 0x48, 0x83, 0xe1, 0xf0, /* and rcx,-0x10 */ 0x0f, 0x29, 0x31, /* movaps [rcx],xmm6 */ 0x0f, 0x29, 0x79, 0x10, /* movaps [rcx+0x10],xmm7 */ 0x44, 0x0f, 0x29, 0x41, 0x20, /* movaps [rcx+0x20],xmm8 */ 0x44, 0x0f, 0x29, 0x49, 0x30, /* movaps [rcx+0x30],xmm9 */ 0x44, 0x0f, 0x29, 0x51, 0x40, /* movaps [rcx+0x40],xmm10 */ 0x44, 0x0f, 0x29, 0x59, 0x50, /* movaps [rcx+0x50],xmm11 */ 0x44, 0x0f, 0x29, 0x61, 0x60, /* movaps [rcx+0x60],xmm12 */ 0x44, 0x0f, 0x29, 0x69, 0x70, /* movaps [rcx+0x70],xmm13 */ 0x44, 0x0f, 0x29, 0xb1, 0x80, 0x00, 0x00, 0x00, /* movaps [rcx+0x80],xmm14 */ 0x44, 0x0f, 0x29, 0xb9, 0x90, 0x00, 0x00, 0x00, /* movaps [rcx+0x90],xmm15 */ 0xff, 0xe0, /* jmp rax */ }; #include void co_init(void) { DWORD old_privileges; VirtualProtect(co_swap_function, sizeof(co_swap_function), PAGE_EXECUTE_READWRITE, &old_privileges); } #else //ABI: SystemV #ifndef CO_USE_INLINE_ASM static unsigned char co_swap_function[] = { 0x48, 0x89, 0x26, /* mov [rsi],rsp */ 0x48, 0x8b, 0x27, /* mov rsp,[rdi] */ 0x58, /* pop rax */ 0x48, 0x89, 0x6e, 0x08, /* mov [rsi+0x08],rbp */ 0x48, 0x89, 0x5e, 0x10, /* mov [rsi+0x10],rbx */ 0x4c, 0x89, 0x66, 0x18, /* mov [rsi+0x18],r12 */ 0x4c, 0x89, 0x6e, 0x20, /* mov [rsi+0x20],r13 */ 0x4c, 0x89, 0x76, 0x28, /* mov [rsi+0x28],r14 */ 0x4c, 0x89, 0x7e, 0x30, /* mov [rsi+0x30],r15 */ 0x48, 0x8b, 0x6f, 0x08, /* mov rbp,[rdi+0x08] */ 0x48, 0x8b, 0x5f, 0x10, /* mov rbx,[rdi+0x10] */ 0x4c, 0x8b, 0x67, 0x18, /* mov r12,[rdi+0x18] */ 0x4c, 0x8b, 0x6f, 0x20, /* mov r13,[rdi+0x20] */ 0x4c, 0x8b, 0x77, 0x28, /* mov r14,[rdi+0x28] */ 0x4c, 0x8b, 0x7f, 0x30, /* mov r15,[rdi+0x30] */ 0xff, 0xe0, /* jmp rax */ }; #include #include void co_init(void) { unsigned long long addr = (unsigned long long)co_swap_function; unsigned long long base = addr - (addr % sysconf(_SC_PAGESIZE)); unsigned long long size = (addr - base) + sizeof(co_swap_function); mprotect((void*)base, size, PROT_READ | PROT_WRITE | PROT_EXEC); } #else __asm__( ".intel_syntax noprefix\n" ".globl co_swap \n" "co_swap: \n" ".globl _co_swap \n" /* OSX ABI is different from Linux. */ "_co_swap: \n" "mov [rsi],rsp \n" "mov [rsi+0x08],rbp \n" "mov [rsi+0x10],rbx \n" "mov [rsi+0x18],r12 \n" "mov [rsi+0x20],r13 \n" "mov [rsi+0x28],r14 \n" "mov [rsi+0x30],r15 \n" "mov rsp,[rdi] \n" "mov rbp,[rdi+0x08] \n" "mov rbx,[rdi+0x10] \n" "mov r12,[rdi+0x18] \n" "mov r13,[rdi+0x20] \n" "mov r14,[rdi+0x28] \n" "mov r15,[rdi+0x30] \n" "ret \n" ".att_syntax \n" ); #endif #endif static void crash(void) { assert(0); /* called only if cothread_t entrypoint returns */ } cothread_t co_active(void) { if (!co_active_handle) co_active_handle = &co_active_buffer; return co_active_handle; } cothread_t co_create(unsigned int size, void (*entrypoint)(void)) { cothread_t handle; #ifndef CO_USE_INLINE_ASM if(!co_swap) { co_init(); co_swap = (void (*)(cothread_t, cothread_t))co_swap_function; } #endif if (!co_active_handle) co_active_handle = &co_active_buffer; size += 512; /* allocate additional space for storage */ size &= ~15; /* align stack to 16-byte boundary */ if((handle = (cothread_t)malloc(size))) { long long *p = (long long*)((char*)handle + size); /* seek to top of stack */ *--p = (long long)crash; /* crash if entrypoint returns */ *--p = (long long)entrypoint; /* start of function */ *(long long*)handle = (long long)p; /* stack pointer */ } return handle; } void co_delete(cothread_t handle) { free(handle); } void co_switch(cothread_t handle) { register cothread_t co_previous_handle = co_active_handle; co_swap(co_active_handle = handle, co_previous_handle); } #ifdef __cplusplus } #endif mupen64plus-core/src/r4300/hacktarux_dynarec/gcop1_l.c000664 001750 001750 00000005473 12655644434 023606 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - gcop1_l.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "assemble.h" #include "interpret.h" #include "r4300/recomph.h" #include "r4300/r4300.h" #include "r4300/ops.h" #include "r4300/cp1_private.h" void gencvt_s_l(void) { #ifdef INTERPRET_CVT_S_L gencallinterp((native_type)cached_interpreter_table.CVT_S_L, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fild_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fd])); fstp_preg64_dword(RAX); #else mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fild_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_simple[dst->f.cf.fd])); fstp_preg32_dword(EAX); #endif #endif } void gencvt_d_l(void) { #ifdef INTERPRET_CVT_D_L gencallinterp((native_type)cached_interpreter_table.CVT_D_L, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fild_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fd])); fstp_preg64_qword(RAX); #else mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fild_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fd])); fstp_preg32_qword(EAX); #endif #endif } mupen64plus-core/src/r4300/hacktarux_dynarec/regcache.h000664 001750 001750 00000005710 12655644434 024022 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - regcache.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2007 Richard Goedeken (Richard42) * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef __REGCACHE_H__ #define __REGCACHE_H__ #include "r4300/recomp.h" void free_register(int reg); void init_cache(precomp_instr* start); #if defined(__x86_64__) void free_registers_move_start(void); int allocate_register_32(uint32_t *addr); int allocate_register_64(uint64_t *addr); int allocate_register_32_w(uint32_t *addr); int allocate_register_64_w(uint64_t *addr); void allocate_register_32_manually(int reg, uint32_t *addr); void allocate_register_32_manually_w(int reg, uint32_t *addr); #else int lru_register_exc1(int exc1); int allocate_register(uint32_t *addr); int allocate_64_register1(uint32_t *addr); int allocate_64_register2(uint32_t *addr); int allocate_register_w(uint32_t *addr); int allocate_64_register1_w(uint32_t *addr); int allocate_64_register2_w(uint32_t *addr); void allocate_register_manually(int reg, uint32_t *addr); void allocate_register_manually_w(int reg, uint32_t *addr, int load); void set_64_register_state(int reg1, int reg2, uint32_t *addr, int dirty); void force_32(int reg); #endif void simplify_access(void); void free_all_registers(void); int is64(uint32_t *addr); int lru_register(void); int lru_base_register(void); void set_register_state(int reg, uint32_t *addr, int dirty, int is64bits); int lock_register(int reg); void unlock_register(int reg); void build_wrappers(precomp_instr*, int, int, precomp_block*); #endif /* __REGCACHE_H__ */ mupen64plus-core/src/plugin/emulate_game_controller_via_libretro.c000664 001750 001750 00000145470 12655644434 026744 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - emulate_game_controller_via_input_plugin.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "emulate_game_controller_via_input_plugin.h" #include "plugin.h" #include "api/m64p_plugin.h" #include "api/libretro.h" #include "si/game_controller.h" #include #include #include #include #define ROUND(x) floor((x) + 0.5) /* snprintf not available in MSVC 2010 and earlier */ #include "api/msvc_compat.h" extern retro_environment_t environ_cb; extern retro_input_state_t input_cb; extern struct retro_rumble_interface rumble; extern int pad_pak_types[4]; extern int pad_present[4]; extern int astick_deadzone; extern m64p_rom_header ROM_HEADER; // Some stuff from n-rage plugin #define RD_GETSTATUS 0x00 // get status #define RD_READKEYS 0x01 // read button values #define RD_READPAK 0x02 // read from controllerpack #define RD_WRITEPAK 0x03 // write to controllerpack #define RD_RESETCONTROLLER 0xff // reset controller #define RD_READEEPROM 0x04 // read eeprom #define RD_WRITEEPROM 0x05 // write eeprom #define PAK_IO_RUMBLE 0xC000 // the address where rumble-commands are sent to #define FRAME_DURATION 24 /* global data definitions */ struct { CONTROL *control; // pointer to CONTROL struct in Core library BUTTONS buttons; } controller[4]; static void inputGetKeys_default( int Control, BUTTONS *Keys ); typedef void (*get_keys_t)(int, BUTTONS*); static get_keys_t getKeys = inputGetKeys_default; static void inputGetKeys_default_descriptor(void) { static struct retro_input_descriptor desc[] = { { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "A Button (C-Right)" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B Button (C-Down)" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "Z-Trigger" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "START Button" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "Up (digital)" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "Down (digital)" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "Left (digital)" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "Right (digital)" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Change Controls" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "C Buttons Mode" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L-Trigger" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R-Trigger" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "(C-Up)" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "(C-Left)" }, { 0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT , RETRO_DEVICE_ID_ANALOG_X, "Control Stick X" }, { 0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT , RETRO_DEVICE_ID_ANALOG_Y, "Control Stick Y" }, { 0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X, "C Buttons X" }, { 0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y, "C Buttons Y" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "A Button (C-Right)" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B Button (C-Down)" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "Z-Trigger" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "START Button" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "Up (digital)" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "Down (digital)" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "Left (digital)" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "Right (digital)" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Change Controls" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "C Buttons Mode" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L-Trigger" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R-Trigger" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "(C-Up)" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "(C-Left)" }, { 1, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT , RETRO_DEVICE_ID_ANALOG_X, "Control Stick X" }, { 1, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT , RETRO_DEVICE_ID_ANALOG_Y, "Control Stick Y" }, { 1, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X, "C Buttons X" }, { 1, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y, "C Buttons Y" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "A Button (C-Right)" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B Button (C-Down)" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "Z-Trigger" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "START Button" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "Up (digital)" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "Down (digital)" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "Left (digital)" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "Right (digital)" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Change Controls" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "C Buttons Mode" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L-Trigger" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R-Trigger" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "(C-Up)" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "(C-Left)" }, { 2, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT , RETRO_DEVICE_ID_ANALOG_X, "Control Stick X" }, { 2, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT , RETRO_DEVICE_ID_ANALOG_Y, "Control Stick Y" }, { 2, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X, "C Buttons X" }, { 2, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y, "C Buttons Y" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "A Button (C-Right)" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B Button (C-Down)" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "Z-Trigger" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "START Button" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "Up (digital)" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "Down (digital)" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "Left (digital)" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "Right (digital)" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Change Controls" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "C Buttons Mode" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L-Trigger" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R-Trigger" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "(C-Up)" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "(C-Left)" }, { 3, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT , RETRO_DEVICE_ID_ANALOG_X, "Control Stick X" }, { 3, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT , RETRO_DEVICE_ID_ANALOG_Y, "Control Stick Y" }, { 3, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X, "C Buttons X" }, { 3, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y, "C Buttons Y" }, { 0 }, }; environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, desc); } /* Mupen64Plus plugin functions */ EXPORT m64p_error CALL inputPluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context, void (*DebugCallback)(void *, int, const char *)) { getKeys = inputGetKeys_default; inputGetKeys_default_descriptor(); return M64ERR_SUCCESS; } EXPORT m64p_error CALL inputPluginShutdown(void) { abort(); return 0; } EXPORT m64p_error CALL inputPluginGetVersion(m64p_plugin_type *PluginType, int *PluginVersion, int *APIVersion, const char **PluginNamePtr, int *Capabilities) { // This function should never be called in libretro version return M64ERR_SUCCESS; } static unsigned char DataCRC( unsigned char *Data, int iLenght ) { unsigned char Remainder = Data[0]; int iByte = 1; unsigned char bBit = 0; while( iByte <= iLenght ) { int HighBit = ((Remainder & 0x80) != 0); Remainder = Remainder << 1; Remainder += ( iByte < iLenght && Data[iByte] & (0x80 >> bBit )) ? 1 : 0; Remainder ^= (HighBit) ? 0x85 : 0; bBit++; iByte += bBit/8; bBit %= 8; } return Remainder; } /****************************************************************** Function: ControllerCommand Purpose: To process the raw data that has just been sent to a specific controller. input: - Controller Number (0 to 3) and -1 signalling end of processing the pif ram. - Pointer of data to be processed. output: none note: This function is only needed if the DLL is allowing raw data, or the plugin is set to raw the data that is being processed looks like this: initilize controller: 01 03 00 FF FF FF read controller: 01 04 01 FF FF FF FF *******************************************************************/ EXPORT void CALL inputControllerCommand(int Control, unsigned char *Command) { unsigned char *Data = &Command[5]; if (Control == -1) return; switch (Command[2]) { case RD_GETSTATUS: break; case RD_READKEYS: break; case RD_READPAK: if (controller[Control].control->Plugin == PLUGIN_RAW) { unsigned int dwAddress = (Command[3] << 8) + (Command[4] & 0xE0); if(( dwAddress >= 0x8000 ) && ( dwAddress < 0x9000 ) ) memset( Data, 0x80, 32 ); else memset( Data, 0x00, 32 ); Data[32] = DataCRC( Data, 32 ); } break; case RD_WRITEPAK: if (controller[Control].control->Plugin == PLUGIN_RAW) { unsigned int dwAddress = (Command[3] << 8) + (Command[4] & 0xE0); Data[32] = DataCRC( Data, 32 ); if ((dwAddress == PAK_IO_RUMBLE) && (rumble.set_rumble_state)) { if (*Data) { rumble.set_rumble_state(Control, RETRO_RUMBLE_WEAK, 0xFFFF); rumble.set_rumble_state(Control, RETRO_RUMBLE_STRONG, 0xFFFF); } else { rumble.set_rumble_state(Control, RETRO_RUMBLE_WEAK, 0); rumble.set_rumble_state(Control, RETRO_RUMBLE_STRONG, 0); } } } break; case RD_RESETCONTROLLER: break; case RD_READEEPROM: break; case RD_WRITEEPROM: break; } } /****************************************************************** Function: GetKeys Purpose: To get the current state of the controllers buttons. input: - Controller Number (0 to 3) - A pointer to a BUTTONS structure to be filled with the controller state. output: none *******************************************************************/ // System analog stick range is -0x8000 to 0x8000 #define ASTICK_MAX 0x8000 #define CSTICK_DEADZONE 0x4000 #define CSTICK_RIGHT 0x200 #define CSTICK_LEFT 0x100 #define CSTICK_UP 0x800 #define CSTICK_DOWN 0x400 int timeout = 0; extern void inputInitiateCallback(const char *headername); static void inputGetKeys_reuse(int16_t analogX, int16_t analogY, int Control, BUTTONS* Keys) { double radius, angle; // Keys->Value |= input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_XX) ? 0x4000 : 0; // Mempak switch // Keys->Value |= input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_XX) ? 0x8000 : 0; // Rumblepak switch analogX = input_cb(Control, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X); analogY = input_cb(Control, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y); // Convert cartesian coordinate analog stick to polar coordinates radius = sqrt(analogX * analogX + analogY * analogY); angle = atan2(analogY, analogX); if (radius > astick_deadzone) { // Re-scale analog stick range to negate deadzone (makes slow movements possible) radius = (radius - astick_deadzone)*((float)ASTICK_MAX/(ASTICK_MAX - astick_deadzone)); // N64 Analog stick range is from -80 to 80 radius *= 80.0 / ASTICK_MAX; // Convert back to cartesian coordinates Keys->X_AXIS = +(int32_t)ROUND(radius * cos(angle)); Keys->Y_AXIS = -(int32_t)ROUND(radius * sin(angle)); } else { Keys->X_AXIS = 0; Keys->Y_AXIS = 0; } if (input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT) && --timeout <= 0) inputInitiateCallback((const char*)ROM_HEADER.Name); } static void inputGetKeys_6ButtonFighters(int Control, BUTTONS *Keys) { int16_t analogX = 0; int16_t analogY = 0; Keys->Value = 0; Keys->R_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT); Keys->L_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT); Keys->D_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN); Keys->U_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP); Keys->START_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START); Keys->A_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B); Keys->B_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y); Keys->D_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A); Keys->L_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X); Keys->R_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R); Keys->U_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L); Keys->R_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2); Keys->Z_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2); inputGetKeys_reuse(analogX, analogY, Control, Keys); } static void inputGetKeys_XENA(int Control, BUTTONS *Keys) { int16_t analogX = 0; int16_t analogY = 0; Keys->Value = 0; Keys->R_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT); Keys->L_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT); Keys->D_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN); Keys->U_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP); Keys->START_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START); Keys->A_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2); Keys->B_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2); Keys->D_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A); Keys->L_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B); Keys->R_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X); Keys->U_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y); Keys->R_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R); Keys->Z_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L); inputGetKeys_reuse(analogX, analogY, Control, Keys); } static void inputGetKeys_Biofreaks(int Control, BUTTONS *Keys) { int16_t analogX = 0; int16_t analogY = 0; Keys->Value = 0; Keys->R_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT); Keys->L_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT); Keys->D_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN); Keys->U_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP); Keys->START_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START); Keys->A_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R); Keys->B_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L); Keys->D_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B); Keys->L_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y); Keys->R_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A); Keys->U_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X); Keys->L_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2); Keys->R_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2); inputGetKeys_reuse(analogX, analogY, Control, Keys); } static void inputGetKeys_DarkRift(int Control, BUTTONS *Keys) { int16_t analogX = 0; int16_t analogY = 0; Keys->Value = 0; Keys->R_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT); Keys->L_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT); Keys->D_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN); Keys->U_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP); Keys->START_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START); Keys->A_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R); Keys->B_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L); Keys->D_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A); Keys->L_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X); Keys->R_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B); Keys->U_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y); Keys->L_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2); Keys->R_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2); inputGetKeys_reuse(analogX, analogY, Control, Keys); } static void inputGetKeys_ISS(int Control, BUTTONS *Keys) { int16_t analogX = 0; int16_t analogY = 0; Keys->Value = 0; Keys->R_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT); Keys->L_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT); Keys->D_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN); Keys->U_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP); Keys->START_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START); Keys->A_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B); Keys->B_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X); Keys->D_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y); Keys->L_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A); Keys->R_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R); Keys->U_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L); Keys->Z_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2); Keys->R_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2); inputGetKeys_reuse(analogX, analogY, Control, Keys); } static void inputGetKeys_Mace(int Control, BUTTONS *Keys) { int16_t analogX = 0; int16_t analogY = 0; Keys->Value = 0; Keys->R_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT); Keys->L_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT); Keys->D_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN); Keys->U_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP); Keys->START_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START); Keys->A_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A); Keys->B_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B); Keys->D_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X); Keys->R_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y); Keys->L_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L); Keys->R_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R); inputGetKeys_reuse(analogX, analogY, Control, Keys); } static void inputGetKeys_MischiefMakers(int Control, BUTTONS *Keys) { int16_t analogX = 0; int16_t analogY = 0; Keys->Value = 0; Keys->R_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT); Keys->L_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT); Keys->D_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN); Keys->U_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP); Keys->START_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START); Keys->A_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A); Keys->B_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B); Keys->D_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L); Keys->L_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y); Keys->R_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X); Keys->U_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R); Keys->Z_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2); Keys->R_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2); inputGetKeys_reuse(analogX, analogY, Control, Keys); } static void inputGetKeys_MKTrilogy(int Control, BUTTONS *Keys) { int16_t analogX = 0; int16_t analogY = 0; Keys->Value = 0; Keys->R_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT); Keys->L_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT); Keys->D_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN); Keys->U_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP); Keys->START_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START); Keys->A_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B); Keys->B_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y); Keys->R_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A); Keys->U_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X); Keys->L_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R); Keys->R_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L); inputGetKeys_reuse(analogX, analogY, Control, Keys); } static void inputGetKeys_MK4(int Control, BUTTONS *Keys) { int16_t analogX = 0; int16_t analogY = 0; Keys->Value = 0; Keys->R_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT); Keys->L_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT); Keys->D_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN); Keys->U_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP); Keys->START_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START); Keys->A_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B); Keys->B_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y); Keys->D_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R); Keys->R_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A); Keys->U_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X); Keys->L_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2); Keys->R_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2); Keys->Z_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L); inputGetKeys_reuse(analogX, analogY, Control, Keys); } static void inputGetKeys_MKMythologies(int Control, BUTTONS *Keys) { int16_t analogX = 0; int16_t analogY = 0; Keys->Value = 0; Keys->R_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT); Keys->L_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT); Keys->D_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN); Keys->U_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP); Keys->START_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START); Keys->A_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2); Keys->B_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2); Keys->D_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B); Keys->L_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y); Keys->R_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A); Keys->U_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X); Keys->L_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L); Keys->R_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R); inputGetKeys_reuse(analogX, analogY, Control, Keys); } static void inputGetKeys_Rampage(int Control, BUTTONS *Keys) { int16_t analogX = 0; int16_t analogY = 0; Keys->Value = 0; Keys->R_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT); Keys->L_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT); Keys->D_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN); Keys->U_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP); Keys->START_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START); Keys->A_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A); Keys->B_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B); Keys->D_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y); Keys->R_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R); inputGetKeys_reuse(analogX, analogY, Control, Keys); } static void inputGetKeys_Ready2Rumble(int Control, BUTTONS *Keys) { int16_t analogX = 0; int16_t analogY = 0; Keys->Value = 0; Keys->R_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT); Keys->L_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT); Keys->D_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN); Keys->U_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP); Keys->START_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START); Keys->A_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L); Keys->B_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R); Keys->D_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B); Keys->L_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y); Keys->R_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A); Keys->U_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X); inputGetKeys_reuse(analogX, analogY, Control, Keys); } static void inputGetKeys_Wipeout64(int Control, BUTTONS *Keys) { int16_t analogX = 0; int16_t analogY = 0; Keys->Value = 0; Keys->R_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT); Keys->L_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT); Keys->D_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN); Keys->U_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP); Keys->START_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START); Keys->A_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B); Keys->B_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A); Keys->D_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y); Keys->U_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X); Keys->R_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R); Keys->Z_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L); inputGetKeys_reuse(analogX, analogY, Control, Keys); } static void inputGetKeys_WWF(int Control, BUTTONS *Keys) { int16_t analogX = 0; int16_t analogY = 0; Keys->Value = 0; Keys->R_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT); Keys->L_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT); Keys->D_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN); Keys->U_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP); Keys->START_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START); Keys->A_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A); Keys->B_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B); Keys->D_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y); Keys->L_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X); Keys->R_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2); Keys->U_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2); Keys->L_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L); Keys->R_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R); inputGetKeys_reuse(analogX, analogY, Control, Keys); } static void inputGetKeys_RR64( int Control, BUTTONS *Keys ) { int16_t analogX = 0; int16_t analogY = 0; Keys->Value = 0; Keys->R_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT); Keys->L_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT); Keys->D_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN); Keys->U_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP); Keys->START_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START); Keys->L_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L); Keys->R_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R); Keys->B_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y); Keys->A_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B); //Keys->D_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A); //Keys->L_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X); //Keys->R_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R); Keys->U_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X); inputGetKeys_reuse(analogX, analogY, Control, Keys); } static void inputGetKeys_default( int Control, BUTTONS *Keys ) { bool hold_cstick = false; int16_t analogX = 0; int16_t analogY = 0; Keys->Value = 0; Keys->R_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT); Keys->L_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT); Keys->D_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN); Keys->U_DPAD = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP); Keys->START_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START); Keys->R_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R); hold_cstick = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2); if (hold_cstick) { Keys->R_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A); Keys->L_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y); Keys->D_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B); Keys->U_CBUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X); Keys->L_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L); Keys->Z_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2); } else { Keys->B_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B); Keys->A_BUTTON = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A); Keys->L_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L); Keys->Z_TRIG = input_cb(Control, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2); } // C buttons analogX = input_cb(Control, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X); analogY = input_cb(Control, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y); if (abs(analogX) > CSTICK_DEADZONE) Keys->Value |= (analogX < 0) ? CSTICK_RIGHT : CSTICK_LEFT; if (abs(analogY) > CSTICK_DEADZONE) Keys->Value |= (analogY < 0) ? CSTICK_UP : CSTICK_DOWN; inputGetKeys_reuse(analogX, analogY, Control, Keys); } void inputInitiateCallback(const char *headername) { struct retro_message msg; char msg_local[256]; if (getKeys != &inputGetKeys_default) { getKeys = inputGetKeys_default; inputGetKeys_default_descriptor(); snprintf(msg_local, sizeof(msg_local), "Controls: Default"); msg.msg = msg_local; msg.frames = FRAME_DURATION; timeout = FRAME_DURATION / 2; if (environ_cb) environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, (void*)&msg); return; } if ( (!strcmp(headername, "KILLER INSTINCT GOLD")) || (!strcmp(headername, "Killer Instinct Gold")) || (!strcmp(headername, "CLAYFIGHTER 63")) || (!strcmp(headername, "Clayfighter SC")) || (!strcmp(headername, "RAKUGAKIDS"))) { static struct retro_input_descriptor desc[] = { { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "A [Low Kick]" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "C-Down [Medium Kick]" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "C-Left [Medium Punch]" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "B [Low Punch]" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "C-Up [Fierce Punch]" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "C-Right [Fierce Kick]" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "Z-Trigger" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Change Controls" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "A [Low Kick]" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "C-Down [Medium Kick]" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "C-Left [Medium Punch]" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "B [Low Punch]" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "C-Up [Fierce Punch]" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "C-Right [Fierce Kick]" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "Z-Trigger" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Change Controls" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "A [Low Kick]" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "C-Down [Medium Kick]" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "C-Left [Medium Punch]" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "B [Low Punch]" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "C-Up [Fierce Punch]" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "C-Right [Fierce Kick]" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "Z-Trigger" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Change Controls" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "A [Low Kick]" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "C-Down [Medium Kick]" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "C-Left [Medium Punch]" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "B [Low Punch]" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "C-Up [Fierce Punch]" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "C-Right [Fierce Kick]" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "Z-Trigger" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Change Controls" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, { 0 }, }; environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, desc); getKeys = inputGetKeys_6ButtonFighters; } else if (!strcmp(headername, "BIOFREAKS")) getKeys = inputGetKeys_Biofreaks; else if (!strcmp(headername, "DARK RIFT")) getKeys = inputGetKeys_DarkRift; else if (!strcmp(headername, "XENAWARRIORPRINCESS")) getKeys = inputGetKeys_XENA; else if (!strcmp(headername, "RIDGE RACER 64")) { static struct retro_input_descriptor desc[] = { { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "A" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "C-Up" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "B" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Change Controls" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "A" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "C-Up" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "B" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Change Controls" }, { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "A" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "C-Up" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "B" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Change Controls" }, { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "A" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "C-Up" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "B" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Change Controls" }, { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, { 0 }, }; environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, desc); getKeys = inputGetKeys_RR64; } else if ((!strcmp(headername, "I S S 64")) || (!strcmp(headername, "J WORLD SOCCER3")) || (!strcmp(headername, "J.WORLD CUP 98")) || (!strcmp(headername, "I.S.S.98")) || (!strcmp(headername, "PERFECT STRIKER2")) || (!strcmp(headername, "I.S.S.2000"))) getKeys = inputGetKeys_ISS; else if (!strcmp(headername, "MACE")) getKeys = inputGetKeys_Mace; else if ((!strcmp(headername, "MISCHIEF MAKERS")) || (!strcmp(headername, "TROUBLE MAKERS"))) getKeys = inputGetKeys_MischiefMakers; else if ((!strcmp(headername, "MortalKombatTrilogy")) || (!strcmp(headername, "WAR GODS"))) getKeys = inputGetKeys_MKTrilogy; else if (!strcmp(headername, "MORTAL KOMBAT 4")) getKeys = inputGetKeys_MK4; else if (!strcmp(headername, "MK_MYTHOLOGIES")) getKeys = inputGetKeys_MKMythologies; else if ((!strcmp(headername, "RAMPAGE")) || (!strcmp(headername, "RAMPAGE2"))) getKeys = inputGetKeys_Rampage; else if ((!strcmp(headername, "READY 2 RUMBLE")) || (!strcmp(headername, "Ready to Rumble"))) getKeys = inputGetKeys_Ready2Rumble; else if (!strcmp(headername, "Wipeout 64")) getKeys = inputGetKeys_Wipeout64; else if ((!strcmp(headername, "WRESTLEMANIA 2000")) || (!strcmp(headername, "WWF No Mercy"))) getKeys = inputGetKeys_WWF; if (getKeys == &inputGetKeys_default) return; snprintf(msg_local, sizeof(msg_local), "Controls: Alternate"); msg.msg = msg_local; msg.frames = FRAME_DURATION; timeout = FRAME_DURATION / 2; if (environ_cb) environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, (void*)&msg); } /****************************************************************** Function: InitiateControllers Purpose: This function initialises how each of the controllers should be handled. input: - The handle to the main window. - A controller structure that needs to be filled for the emulator to know how to handle each controller. output: none *******************************************************************/ EXPORT void CALL inputInitiateControllers(CONTROL_INFO ControlInfo) { int i; for( i = 0; i < 4; i++ ) { controller[i].control = ControlInfo.Controls + i; controller[i].control->Present = pad_present[i]; controller[i].control->RawData = 0; if (pad_pak_types[i] == PLUGIN_MEMPAK) controller[i].control->Plugin = PLUGIN_MEMPAK; else if (pad_pak_types[i] == PLUGIN_RAW) controller[i].control->Plugin = PLUGIN_RAW; else controller[i].control->Plugin = PLUGIN_NONE; } getKeys = inputGetKeys_default; inputGetKeys_default_descriptor(); } /****************************************************************** Function: ReadController Purpose: To process the raw data in the pif ram that is about to be read. input: - Controller Number (0 to 3) and -1 signalling end of processing the pif ram. - Pointer of data to be processed. output: none note: This function is only needed if the DLL is allowing raw data. *******************************************************************/ EXPORT void CALL inputReadController(int Control, unsigned char *Command) { inputControllerCommand(Control, Command); } /****************************************************************** Function: RomClosed Purpose: This function is called when a rom is closed. input: none output: none *******************************************************************/ EXPORT void CALL inputRomClosed(void) { } /****************************************************************** Function: RomOpen Purpose: This function is called when a rom is open. (from the emulation thread) input: none output: none *******************************************************************/ EXPORT int CALL inputRomOpen(void) { return 1; } int egcvip_is_connected(void* opaque, enum pak_type* pak) { int channel = *(int*)opaque; CONTROL* c = &Controls[channel]; switch(c->Plugin) { case PLUGIN_NONE: *pak = PAK_NONE; break; case PLUGIN_MEMPAK: *pak = PAK_MEM; break; case PLUGIN_RUMBLE_PAK: *pak = PAK_RUMBLE; break; case PLUGIN_TRANSFER_PAK: *pak = PAK_TRANSFER; break; case PLUGIN_RAW: /* historically PLUGIN_RAW has been mostly (exclusively ?) used for rumble, * so we just reproduce that behavior */ *pak = PAK_RUMBLE; break; } return c->Present; } uint32_t egcvip_get_input(void* opaque) { BUTTONS keys = { 0 }; int channel = *(int*)opaque; if (getKeys) getKeys(channel, &keys); return keys.Value; } mupen64plus-video-gliden64/src/GLideNHQ/TxDbg.h000664 001750 001750 00000003002 12655644434 022135 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __TXDBG_H__ #define __TXDBG_H__ #include #include "TxInternal.h" class TxDbg { private: FILE* _dbgfile; int _level; TxDbg(); public: static TxDbg* getInstance() { static TxDbg txDbg; return &txDbg; } ~TxDbg(); void output(const int level, const wchar_t *format, ...); }; #ifdef DEBUG #define DBG_INFO TxDbg::getInstance()->output #define INFO DBG_INFO #else #define DBG_INFO(A, ...) #ifdef GHQCHK #define INFO TxDbg::getInstance()->output #else #if 0 /* XXX enable this to log basic hires texture checks */ #define INFO TxDbg::getInstance()->output #else #define INFO DBG_INFO #endif #endif #endif #endif /* __TXDBG_H__ */ mupen64plus-video-gliden64/src/GLideNHQ/TextureFilters_lq2x.h000664 001750 001750 00000041764 12655644434 025105 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Copyright (C) 2007 Hiroshi Morii * Modified for the Texture Filtering library */ case 0 : case 2 : case 4 : case 6 : case 8 : case 12 : case 16 : case 20 : case 24 : case 28 : case 32 : case 34 : case 36 : case 38 : case 40 : case 44 : case 48 : case 52 : case 56 : case 60 : case 64 : case 66 : case 68 : case 70 : case 96 : case 98 : case 100 : case 102 : case 128 : case 130 : case 132 : case 134 : case 136 : case 140 : case 144 : case 148 : case 152 : case 156 : case 160 : case 162 : case 164 : case 166 : case 168 : case 172 : case 176 : case 180 : case 184 : case 188 : case 192 : case 194 : case 196 : case 198 : case 224 : case 226 : case 228 : case 230 : { P0 = IC(0); P1 = IC(0); P2 = IC(0); P3 = IC(0); } break; case 1 : case 5 : case 9 : case 13 : case 17 : case 21 : case 25 : case 29 : case 33 : case 37 : case 41 : case 45 : case 49 : case 53 : case 57 : case 61 : case 65 : case 69 : case 97 : case 101 : case 129 : case 133 : case 137 : case 141 : case 145 : case 149 : case 153 : case 157 : case 161 : case 165 : case 169 : case 173 : case 177 : case 181 : case 185 : case 189 : case 193 : case 197 : case 225 : case 229 : { P0 = IC(1); P1 = IC(1); P2 = IC(1); P3 = IC(1); } break; case 3 : case 35 : case 67 : case 99 : case 131 : case 163 : case 195 : case 227 : { P0 = IC(2); P1 = IC(2); P2 = IC(2); P3 = IC(2); } break; case 7 : case 39 : case 71 : case 103 : case 135 : case 167 : case 199 : case 231 : { P0 = IC(3); P1 = IC(3); P2 = IC(3); P3 = IC(3); } break; case 10 : case 138 : { P1 = IC(0); P2 = IC(0); P3 = IC(0); if (HQ2X_MUL) { P0 = IC(0); } else { P0 = I211(0, 1, 3); } } break; case 11 : case 27 : case 75 : case 139 : case 155 : case 203 : { P1 = IC(2); P2 = IC(2); P3 = IC(2); if (HQ2X_MUL) { P0 = IC(2); } else { P0 = I211(2, 1, 3); } } break; case 14 : case 142 : { P2 = IC(0); P3 = IC(0); if (HQ2X_MUL) { P0 = IC(0); P1 = IC(0); } else { P0 = I332(1, 3, 0); P1 = I31(0, 1); } } break; case 15 : case 143 : case 207 : { P2 = IC(4); P3 = IC(4); if (HQ2X_MUL) { P0 = IC(4); P1 = IC(4); } else { P0 = I332(1, 3, 4); P1 = I31(4, 1); } } break; case 18 : case 22 : case 30 : case 50 : case 54 : case 62 : case 86 : case 118 : { P0 = IC(0); P2 = IC(0); P3 = IC(0); if (HQ2X_MUR) { P1 = IC(0); } else { P1 = I211(0, 1, 5); } } break; case 19 : case 51 : { P2 = IC(2); P3 = IC(2); if (HQ2X_MUR) { P0 = IC(2); P1 = IC(2); } else { P0 = I31(2, 1); P1 = I332(1, 5, 2); } } break; case 23 : case 55 : case 119 : { P2 = IC(3); P3 = IC(3); if (HQ2X_MUR) { P0 = IC(3); P1 = IC(3); } else { P0 = I31(3, 1); P1 = I332(1, 5, 3); } } break; case 26 : { P2 = IC(0); P3 = IC(0); if (HQ2X_MUL) { P0 = IC(0); } else { P0 = I211(0, 1, 3); } if (HQ2X_MUR) { P1 = IC(0); } else { P1 = I211(0, 1, 5); } } break; case 31 : case 95 : { P2 = IC(4); P3 = IC(4); if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I211(4, 1, 3); } if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I211(4, 1, 5); } } break; case 42 : case 170 : { P1 = IC(0); P3 = IC(0); if (HQ2X_MUL) { P0 = IC(0); P2 = IC(0); } else { P0 = I332(1, 3, 0); P2 = I31(0, 3); } } break; case 43 : case 171 : case 187 : { P1 = IC(2); P3 = IC(2); if (HQ2X_MUL) { P0 = IC(2); P2 = IC(2); } else { P0 = I332(1, 3, 2); P2 = I31(2, 3); } } break; case 46 : case 174 : { P1 = IC(0); P2 = IC(0); P3 = IC(0); if (HQ2X_MUL) { P0 = IC(0); } else { P0 = I611(0, 1, 3); } } break; case 47 : case 175 : { P1 = IC(4); P2 = IC(4); P3 = IC(4); if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I1411(4, 1, 3); } } break; case 58 : case 154 : case 186 : { P2 = IC(0); P3 = IC(0); if (HQ2X_MUL) { P0 = IC(0); } else { P0 = I611(0, 1, 3); } if (HQ2X_MUR) { P1 = IC(0); } else { P1 = I611(0, 1, 5); } } break; case 59 : { P2 = IC(2); P3 = IC(2); if (HQ2X_MUL) { P0 = IC(2); } else { P0 = I211(2, 1, 3); } if (HQ2X_MUR) { P1 = IC(2); } else { P1 = I611(2, 1, 5); } } break; case 63 : { P2 = IC(4); P3 = IC(4); if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I1411(4, 1, 3); } if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I211(4, 1, 5); } } break; case 72 : case 76 : case 104 : case 106 : case 108 : case 110 : case 120 : case 124 : { P0 = IC(0); P1 = IC(0); P3 = IC(0); if (HQ2X_MDL) { P2 = IC(0); } else { P2 = I211(0, 3, 7); } } break; case 73 : case 77 : case 105 : case 109 : case 125 : { P1 = IC(1); P3 = IC(1); if (HQ2X_MDL) { P0 = IC(1); P2 = IC(1); } else { P0 = I31(1, 3); P2 = I332(3, 7, 1); } } break; case 74 : { P1 = IC(0); P3 = IC(0); if (HQ2X_MDL) { P2 = IC(0); } else { P2 = I211(0, 3, 7); } if (HQ2X_MUL) { P0 = IC(0); } else { P0 = I211(0, 1, 3); } } break; case 78 : case 202 : case 206 : { P1 = IC(0); P3 = IC(0); if (HQ2X_MDL) { P2 = IC(0); } else { P2 = I611(0, 3, 7); } if (HQ2X_MUL) { P0 = IC(0); } else { P0 = I611(0, 1, 3); } } break; case 79 : { P1 = IC(4); P3 = IC(4); if (HQ2X_MDL) { P2 = IC(4); } else { P2 = I611(4, 3, 7); } if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I211(4, 1, 3); } } break; case 80 : case 208 : case 210 : case 216 : { P0 = IC(0); P1 = IC(0); P2 = IC(0); if (HQ2X_MDR) { P3 = IC(0); } else { P3 = I211(0, 5, 7); } } break; case 81 : case 209 : case 217 : { P0 = IC(1); P1 = IC(1); P2 = IC(1); if (HQ2X_MDR) { P3 = IC(1); } else { P3 = I211(1, 5, 7); } } break; case 82 : case 214 : case 222 : { P0 = IC(0); P2 = IC(0); if (HQ2X_MDR) { P3 = IC(0); } else { P3 = I211(0, 5, 7); } if (HQ2X_MUR) { P1 = IC(0); } else { P1 = I211(0, 1, 5); } } break; case 83 : case 115 : { P0 = IC(2); P2 = IC(2); if (HQ2X_MDR) { P3 = IC(2); } else { P3 = I611(2, 5, 7); } if (HQ2X_MUR) { P1 = IC(2); } else { P1 = I611(2, 1, 5); } } break; case 84 : case 212 : { P0 = IC(0); P2 = IC(0); if (HQ2X_MDR) { P1 = IC(0); P3 = IC(0); } else { P1 = I31(0, 5); P3 = I332(5, 7, 0); } } break; case 85 : case 213 : case 221 : { P0 = IC(1); P2 = IC(1); if (HQ2X_MDR) { P1 = IC(1); P3 = IC(1); } else { P1 = I31(1, 5); P3 = I332(5, 7, 1); } } break; case 87 : { P0 = IC(3); P2 = IC(3); if (HQ2X_MDR) { P3 = IC(3); } else { P3 = I611(3, 5, 7); } if (HQ2X_MUR) { P1 = IC(3); } else { P1 = I211(3, 1, 5); } } break; case 88 : case 248 : case 250 : { P0 = IC(0); P1 = IC(0); if (HQ2X_MDL) { P2 = IC(0); } else { P2 = I211(0, 3, 7); } if (HQ2X_MDR) { P3 = IC(0); } else { P3 = I211(0, 5, 7); } } break; case 89 : case 93 : { P0 = IC(1); P1 = IC(1); if (HQ2X_MDL) { P2 = IC(1); } else { P2 = I611(1, 3, 7); } if (HQ2X_MDR) { P3 = IC(1); } else { P3 = I611(1, 5, 7); } } break; case 90 : { if (HQ2X_MDL) { P2 = IC(0); } else { P2 = I611(0, 3, 7); } if (HQ2X_MDR) { P3 = IC(0); } else { P3 = I611(0, 5, 7); } if (HQ2X_MUL) { P0 = IC(0); } else { P0 = I611(0, 1, 3); } if (HQ2X_MUR) { P1 = IC(0); } else { P1 = I611(0, 1, 5); } } break; case 91 : { if (HQ2X_MDL) { P2 = IC(2); } else { P2 = I611(2, 3, 7); } if (HQ2X_MDR) { P3 = IC(2); } else { P3 = I611(2, 5, 7); } if (HQ2X_MUL) { P0 = IC(2); } else { P0 = I211(2, 1, 3); } if (HQ2X_MUR) { P1 = IC(2); } else { P1 = I611(2, 1, 5); } } break; case 92 : { P0 = IC(0); P1 = IC(0); if (HQ2X_MDL) { P2 = IC(0); } else { P2 = I611(0, 3, 7); } if (HQ2X_MDR) { P3 = IC(0); } else { P3 = I611(0, 5, 7); } } break; case 94 : { if (HQ2X_MDL) { P2 = IC(0); } else { P2 = I611(0, 3, 7); } if (HQ2X_MDR) { P3 = IC(0); } else { P3 = I611(0, 5, 7); } if (HQ2X_MUL) { P0 = IC(0); } else { P0 = I611(0, 1, 3); } if (HQ2X_MUR) { P1 = IC(0); } else { P1 = I211(0, 1, 5); } } break; case 107 : case 123 : { P1 = IC(2); P3 = IC(2); if (HQ2X_MDL) { P2 = IC(2); } else { P2 = I211(2, 3, 7); } if (HQ2X_MUL) { P0 = IC(2); } else { P0 = I211(2, 1, 3); } } break; case 111 : { P1 = IC(4); P3 = IC(4); if (HQ2X_MDL) { P2 = IC(4); } else { P2 = I211(4, 3, 7); } if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I1411(4, 1, 3); } } break; case 112 : case 240 : { P0 = IC(0); P1 = IC(0); if (HQ2X_MDR) { P2 = IC(0); P3 = IC(0); } else { P2 = I31(0, 7); P3 = I332(5, 7, 0); } } break; case 113 : case 241 : { P0 = IC(1); P1 = IC(1); if (HQ2X_MDR) { P2 = IC(1); P3 = IC(1); } else { P2 = I31(1, 7); P3 = I332(5, 7, 1); } } break; case 114 : { P0 = IC(0); P2 = IC(0); if (HQ2X_MDR) { P3 = IC(0); } else { P3 = I611(0, 5, 7); } if (HQ2X_MUR) { P1 = IC(0); } else { P1 = I611(0, 1, 5); } } break; case 116 : { P0 = IC(0); P1 = IC(0); P2 = IC(0); if (HQ2X_MDR) { P3 = IC(0); } else { P3 = I611(0, 5, 7); } } break; case 117 : { P0 = IC(1); P1 = IC(1); P2 = IC(1); if (HQ2X_MDR) { P3 = IC(1); } else { P3 = I611(1, 5, 7); } } break; case 121 : { P0 = IC(1); P1 = IC(1); if (HQ2X_MDL) { P2 = IC(1); } else { P2 = I211(1, 3, 7); } if (HQ2X_MDR) { P3 = IC(1); } else { P3 = I611(1, 5, 7); } } break; case 122 : { if (HQ2X_MDL) { P2 = IC(0); } else { P2 = I211(0, 3, 7); } if (HQ2X_MDR) { P3 = IC(0); } else { P3 = I611(0, 5, 7); } if (HQ2X_MUL) { P0 = IC(0); } else { P0 = I611(0, 1, 3); } if (HQ2X_MUR) { P1 = IC(0); } else { P1 = I611(0, 1, 5); } } break; case 126 : { P0 = IC(0); P3 = IC(0); if (HQ2X_MDL) { P2 = IC(0); } else { P2 = I211(0, 3, 7); } if (HQ2X_MUR) { P1 = IC(0); } else { P1 = I211(0, 1, 5); } } break; case 127 : { P3 = IC(4); if (HQ2X_MDL) { P2 = IC(4); } else { P2 = I211(4, 3, 7); } if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I1411(4, 1, 3); } if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I211(4, 1, 5); } } break; case 146 : case 150 : case 178 : case 182 : case 190 : { P0 = IC(0); P2 = IC(0); if (HQ2X_MUR) { P1 = IC(0); P3 = IC(0); } else { P1 = I332(1, 5, 0); P3 = I31(0, 5); } } break; case 147 : case 179 : { P0 = IC(2); P2 = IC(2); P3 = IC(2); if (HQ2X_MUR) { P1 = IC(2); } else { P1 = I611(2, 1, 5); } } break; case 151 : case 183 : { P0 = IC(3); P2 = IC(3); P3 = IC(3); if (HQ2X_MUR) { P1 = IC(3); } else { P1 = I1411(3, 1, 5); } } break; case 158 : { P2 = IC(0); P3 = IC(0); if (HQ2X_MUL) { P0 = IC(0); } else { P0 = I611(0, 1, 3); } if (HQ2X_MUR) { P1 = IC(0); } else { P1 = I211(0, 1, 5); } } break; case 159 : { P2 = IC(4); P3 = IC(4); if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I211(4, 1, 3); } if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I1411(4, 1, 5); } } break; case 191 : { P2 = IC(4); P3 = IC(4); if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I1411(4, 1, 3); } if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I1411(4, 1, 5); } } break; case 200 : case 204 : case 232 : case 236 : case 238 : { P0 = IC(0); P1 = IC(0); if (HQ2X_MDL) { P2 = IC(0); P3 = IC(0); } else { P2 = I332(3, 7, 0); P3 = I31(0, 7); } } break; case 201 : case 205 : { P0 = IC(1); P1 = IC(1); P3 = IC(1); if (HQ2X_MDL) { P2 = IC(1); } else { P2 = I611(1, 3, 7); } } break; case 211 : { P0 = IC(2); P1 = IC(2); P2 = IC(2); if (HQ2X_MDR) { P3 = IC(2); } else { P3 = I211(2, 5, 7); } } break; case 215 : { P0 = IC(3); P2 = IC(3); if (HQ2X_MDR) { P3 = IC(3); } else { P3 = I211(3, 5, 7); } if (HQ2X_MUR) { P1 = IC(3); } else { P1 = I1411(3, 1, 5); } } break; case 218 : { if (HQ2X_MDL) { P2 = IC(0); } else { P2 = I611(0, 3, 7); } if (HQ2X_MDR) { P3 = IC(0); } else { P3 = I211(0, 5, 7); } if (HQ2X_MUL) { P0 = IC(0); } else { P0 = I611(0, 1, 3); } if (HQ2X_MUR) { P1 = IC(0); } else { P1 = I611(0, 1, 5); } } break; case 219 : { P1 = IC(2); P2 = IC(2); if (HQ2X_MDR) { P3 = IC(2); } else { P3 = I211(2, 5, 7); } if (HQ2X_MUL) { P0 = IC(2); } else { P0 = I211(2, 1, 3); } } break; case 220 : { P0 = IC(0); P1 = IC(0); if (HQ2X_MDL) { P2 = IC(0); } else { P2 = I611(0, 3, 7); } if (HQ2X_MDR) { P3 = IC(0); } else { P3 = I211(0, 5, 7); } } break; case 223 : { P2 = IC(4); if (HQ2X_MDR) { P3 = IC(4); } else { P3 = I211(4, 5, 7); } if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I211(4, 1, 3); } if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I1411(4, 1, 5); } } break; case 233 : case 237 : { P0 = IC(1); P1 = IC(1); P3 = IC(1); if (HQ2X_MDL) { P2 = IC(1); } else { P2 = I1411(1, 3, 7); } } break; case 234 : { P1 = IC(0); P3 = IC(0); if (HQ2X_MDL) { P2 = IC(0); } else { P2 = I211(0, 3, 7); } if (HQ2X_MUL) { P0 = IC(0); } else { P0 = I611(0, 1, 3); } } break; case 235 : { P1 = IC(2); P3 = IC(2); if (HQ2X_MDL) { P2 = IC(2); } else { P2 = I1411(2, 3, 7); } if (HQ2X_MUL) { P0 = IC(2); } else { P0 = I211(2, 1, 3); } } break; case 239 : { P1 = IC(4); P3 = IC(4); if (HQ2X_MDL) { P2 = IC(4); } else { P2 = I1411(4, 3, 7); } if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I1411(4, 1, 3); } } break; case 242 : { P0 = IC(0); P2 = IC(0); if (HQ2X_MDR) { P3 = IC(0); } else { P3 = I211(0, 5, 7); } if (HQ2X_MUR) { P1 = IC(0); } else { P1 = I611(0, 1, 5); } } break; case 243 : { P0 = IC(2); P1 = IC(2); if (HQ2X_MDR) { P2 = IC(2); P3 = IC(2); } else { P2 = I31(2, 7); P3 = I332(5, 7, 2); } } break; case 244 : { P0 = IC(0); P1 = IC(0); P2 = IC(0); if (HQ2X_MDR) { P3 = IC(0); } else { P3 = I1411(0, 5, 7); } } break; case 245 : { P0 = IC(1); P1 = IC(1); P2 = IC(1); if (HQ2X_MDR) { P3 = IC(1); } else { P3 = I1411(1, 5, 7); } } break; case 246 : { P0 = IC(0); P2 = IC(0); if (HQ2X_MDR) { P3 = IC(0); } else { P3 = I1411(0, 5, 7); } if (HQ2X_MUR) { P1 = IC(0); } else { P1 = I211(0, 1, 5); } } break; case 247 : { P0 = IC(3); P2 = IC(3); if (HQ2X_MDR) { P3 = IC(3); } else { P3 = I1411(3, 5, 7); } if (HQ2X_MUR) { P1 = IC(3); } else { P1 = I1411(3, 1, 5); } } break; case 249 : { P0 = IC(1); P1 = IC(1); if (HQ2X_MDL) { P2 = IC(1); } else { P2 = I1411(1, 3, 7); } if (HQ2X_MDR) { P3 = IC(1); } else { P3 = I211(1, 5, 7); } } break; case 251 : { P1 = IC(2); if (HQ2X_MDL) { P2 = IC(2); } else { P2 = I1411(2, 3, 7); } if (HQ2X_MDR) { P3 = IC(2); } else { P3 = I211(2, 5, 7); } if (HQ2X_MUL) { P0 = IC(2); } else { P0 = I211(2, 1, 3); } } break; case 252 : { P0 = IC(0); P1 = IC(0); if (HQ2X_MDL) { P2 = IC(0); } else { P2 = I211(0, 3, 7); } if (HQ2X_MDR) { P3 = IC(0); } else { P3 = I1411(0, 5, 7); } } break; case 253 : { P0 = IC(1); P1 = IC(1); if (HQ2X_MDL) { P2 = IC(1); } else { P2 = I1411(1, 3, 7); } if (HQ2X_MDR) { P3 = IC(1); } else { P3 = I1411(1, 5, 7); } } break; case 254 : { P0 = IC(0); if (HQ2X_MDL) { P2 = IC(0); } else { P2 = I211(0, 3, 7); } if (HQ2X_MDR) { P3 = IC(0); } else { P3 = I1411(0, 5, 7); } if (HQ2X_MUR) { P1 = IC(0); } else { P1 = I211(0, 1, 5); } } break; case 255 : { if (HQ2X_MDL) { P2 = IC(4); } else { P2 = I1411(4, 3, 7); } if (HQ2X_MDR) { P3 = IC(4); } else { P3 = I1411(4, 5, 7); } if (HQ2X_MUL) { P0 = IC(4); } else { P0 = I1411(4, 1, 3); } if (HQ2X_MUR) { P1 = IC(4); } else { P1 = I1411(4, 1, 5); } } break; mupen64plus-core/src/r4300/hacktarux_dynarec/regcache.c000664 001750 001750 00000077275 12655644434 024034 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - regcache.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2007 Richard Goedeken (Richard42) * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include "regcache.h" #include "api/m64p_types.h" #include "api/callbacks.h" #include "r4300/recomp.h" #include "r4300/r4300.h" #include "r4300/recomph.h" static precomp_instr *last_access[8]; static precomp_instr *free_since[8]; static int dirty[8]; static int r64[8]; static native_type *reg_content[8]; static native_type *r0; void init_cache(precomp_instr* start) { int i; for (i=0; i<8; i++) { last_access[i] = NULL; free_since[i] = start; reg_content[i] = NULL; #if defined(__x86_64__) dirty[i] = 0; r64[i] = 0; #endif } r0 = (native_type*)reg; } void free_all_registers(void) { int i; for (i = 0; i < 8; i++) { if (last_access[i]) free_register(i); else { while (free_since[i] <= dst) { free_since[i]->reg_cache_infos.needed_registers[i] = NULL; free_since[i]++; } } } } void simplify_access(void) { int i; dst->local_addr = code_length; for(i=0; i<8; i++) dst->reg_cache_infos.needed_registers[i] = NULL; } #if defined(__x86_64__) void free_registers_move_start(void) { /* flush all dirty registers and clear needed_registers table */ free_all_registers(); /* now move the start of the new instruction down past the flushing instructions */ simplify_access(); } #endif // this function frees a specific X86 GPR void free_register(int reg) { precomp_instr *last; #if !defined(__x86_64__) if (last_access[reg] && r64[reg] != -1 && (int)reg_content[reg] != (int)reg_content[r64[reg]]-4) { free_register(r64[reg]); return; } #endif if (last_access[reg]) last = last_access[reg]+1; else last = free_since[reg]; while (last <= dst) { if (last_access[reg] && dirty[reg]) last->reg_cache_infos.needed_registers[reg] = reg_content[reg]; else last->reg_cache_infos.needed_registers[reg] = NULL; #if !defined(__x86_64__) if (last_access[reg] && r64[reg] != -1) { if (dirty[r64[reg]]) last->reg_cache_infos.needed_registers[r64[reg]] = reg_content[r64[reg]]; else last->reg_cache_infos.needed_registers[r64[reg]] = NULL; } #endif last++; } if (!last_access[reg]) { free_since[reg] = dst+1; return; } if (dirty[reg]) { #if defined(__x86_64__) if (r64[reg]) mov_m64rel_xreg64((uint64_t*)reg_content[reg], reg); else { movsxd_reg64_reg32(reg, reg); mov_m64rel_xreg64((uint64_t*)reg_content[reg], reg); } #else mov_m32_reg32(reg_content[reg], reg); if (r64[reg] == -1) { sar_reg32_imm8(reg, 31); mov_m32_reg32((uint32_t*)reg_content[reg]+1, reg); } else mov_m32_reg32(reg_content[r64[reg]], r64[reg]); #endif } last_access[reg] = NULL; free_since[reg] = dst+1; #if !defined(__x86_64__) if (r64[reg] != -1) { last_access[r64[reg]] = NULL; free_since[r64[reg]] = dst+1; } #endif } int lru_register(void) { #if defined(__x86_64__) uint64_t oldest_access = 0xFFFFFFFFFFFFFFFFULL; #else uint32_t oldest_access = 0xFFFFFFFF; #endif int i, reg = 0; for (i=0; i<8; i++) { bool ret = i != ESP; bool ret2 = (native_type)last_access[i] < oldest_access; bool ret_fin = ret && ret2; if (ret_fin) { oldest_access = (native_type)last_access[i]; reg = i; } } return reg; } void set_register_state(int reg, uint32_t *addr, int _dirty, int _is64bits) { last_access[reg] = NULL; if (addr) last_access[reg] = dst; reg_content[reg] = (native_type*) addr; r64[reg] = -1; #ifdef __x86_64__ r64[reg] = _is64bits; #endif dirty[reg] = _dirty; } #if defined(__x86_64__) int lru_base_register(void) /* EBP cannot be used as a base register for SIB addressing byte */ { uint64_t oldest_access = 0xFFFFFFFFFFFFFFFFULL; int i, reg = 0; for (i=0; i<8; i++) { if (i != ESP && i != EBP && (uint64_t) last_access[i] < oldest_access) { oldest_access = (uint64_t)last_access[i]; reg = i; } } return reg; } int lock_register(int reg) { free_register(reg); last_access[reg] = (precomp_instr *) 0xFFFFFFFFFFFFFFFFULL; reg_content[reg] = NULL; return reg; } void unlock_register(int reg) { last_access[reg] = NULL; } #else int lru_register_exc1(int exc1) { uint32_t oldest_access = 0xFFFFFFFF; int i, reg = 0; for (i=0; i<8; i++) { if (i != ESP && i != exc1 && (uint32_t)last_access[i] < oldest_access) { oldest_access = (int)last_access[i]; reg = i; } } return reg; } #endif // this function finds a register to put the data contained in addr, // if there was another value before it's cleanly removed of the // register cache. After that, the register number is returned. // If data are already cached, the function only returns the register number #if defined(__x86_64__) // this function is similar to allocate_register except it loads // a 64 bits value, and return the register number of the LSB part int allocate_register_64(uint64_t *addr) { int reg; /* is it already cached? */ if (addr) { unsigned i; for (i = 0; i < 8; i++) { if (last_access[i] && reg_content[i] == addr) { precomp_instr *last = last_access[i]+1; while (last <= dst) { last->reg_cache_infos.needed_registers[i] = reg_content[i]; last++; } last_access[i] = dst; if (r64[i] == 0) { movsxd_reg64_reg32(i, i); r64[i] = 1; } return i; } } } /* it's not cached, so take the least recently used register */ reg = lru_register(); if (last_access[reg]) free_register(reg); else { while (free_since[reg] <= dst) { free_since[reg]->reg_cache_infos.needed_registers[reg] = NULL; free_since[reg]++; } } last_access[reg] = dst; reg_content[reg] = addr; dirty[reg] = 0; r64[reg] = 1; if (addr) { if (addr == r0) xor_reg64_reg64(reg, reg); else mov_xreg64_m64rel(reg, addr); } return reg; } int allocate_register_32(uint32_t *addr) { int reg = 0; /* is it already cached ? */ if (addr) { int i; for (i = 0; i < 8; i++) { if (last_access[i] && (uint32_t*) reg_content[i] == addr) { precomp_instr *last = (precomp_instr*)(last_access[i] + 1); while (last <= dst) { last->reg_cache_infos.needed_registers[i] = reg_content[i]; last++; } last_access[i] = dst; r64[i] = 0; return i; } } } /* it's not cached, so take the least recently used register */ reg = lru_register(); if (last_access[reg]) free_register(reg); else { while (free_since[reg] <= dst) { free_since[reg]->reg_cache_infos.needed_registers[reg] = NULL; free_since[reg]++; } } last_access[reg] = dst; reg_content[reg] = (uint64_t*) addr; dirty[reg] = 0; r64[reg] = 0; if (addr) { if (addr == (uint32_t*) r0) xor_reg32_reg32(reg, reg); else mov_xreg32_m32rel(reg, addr); } return reg; } #else int allocate_register(uint32_t *addr) { uint32_t oldest_access = 0xFFFFFFFF; int reg = 0, i; /* is it already cached ? */ if (addr) { for (i=0; i<8; i++) { if (last_access[i] && reg_content[i] == addr) { precomp_instr *last = last_access[i]+1; while (last <= dst) { last->reg_cache_infos.needed_registers[i] = reg_content[i]; last++; } last_access[i] = dst; if (r64[i] != -1) { last = last_access[r64[i]]+1; while (last <= dst) { last->reg_cache_infos.needed_registers[r64[i]] = reg_content[r64[i]]; last++; } last_access[r64[i]] = dst; } return i; } } } /* if it's not cached, we take the least recently used register */ for (i=0; i<8; i++) { if (i != ESP && (uint32_t)last_access[i] < oldest_access) { oldest_access = (int)last_access[i]; reg = i; } } if (last_access[reg]) free_register(reg); else { while (free_since[reg] <= dst) { free_since[reg]->reg_cache_infos.needed_registers[reg] = NULL; free_since[reg]++; } } last_access[reg] = dst; reg_content[reg] = addr; dirty[reg] = 0; r64[reg] = -1; if (addr) { if (addr == r0 || addr == r0+1) xor_reg32_reg32(reg, reg); else mov_reg32_m32(reg, addr); } return reg; } // this function is similar to allocate_register except it loads // a 64 bits value, and return the register number of the LSB part int allocate_64_register1(uint32_t *addr) { int reg1, reg2, i; // is it already cached as a 32 bits value ? for (i=0; i<8; i++) { if (last_access[i] && reg_content[i] == addr) { if (r64[i] == -1) { allocate_register(addr); reg2 = allocate_register(dirty[i] ? NULL : addr+1); r64[i] = reg2; r64[reg2] = i; if (dirty[i]) { reg_content[reg2] = addr+1; dirty[reg2] = 1; mov_reg32_reg32(reg2, i); sar_reg32_imm8(reg2, 31); } return i; } } } reg1 = allocate_register(addr); reg2 = allocate_register(addr+1); r64[reg1] = reg2; r64[reg2] = reg1; return reg1; } // this function is similar to allocate_register except it loads // a 64 bits value, and return the register number of the MSB part int allocate_64_register2(uint32_t *addr) { int reg1, reg2, i; // is it already cached as a 32 bits value ? for (i=0; i<8; i++) { if (last_access[i] && reg_content[i] == addr) { if (r64[i] == -1) { allocate_register(addr); reg2 = allocate_register(dirty[i] ? NULL : addr+1); r64[i] = reg2; r64[reg2] = i; if (dirty[i]) { reg_content[reg2] = addr+1; dirty[reg2] = 1; mov_reg32_reg32(reg2, i); sar_reg32_imm8(reg2, 31); } return reg2; } } } reg1 = allocate_register(addr); reg2 = allocate_register(addr+1); r64[reg1] = reg2; r64[reg2] = reg1; return reg2; } #endif // this function checks if the data located at addr are cached in a register // and then, it returns 1 if it's a 64 bit value // 0 if it's a 32 bit value // -1 if it's not cached int is64(uint32_t *addr) { int i; for (i = 0; i < 8; i++) { if (last_access[i] && reg_content[i] == (native_type*)addr) { #if defined(__x86_64__) return r64[i]; #else if (r64[i] == -1) return 0; return 1; #endif } } return -1; } #if defined(__x86_64__) int allocate_register_32_w(uint32_t *addr) { int reg = 0, i; /* is it already cached ? */ for (i = 0; i < 8; i++) { if (last_access[i] && reg_content[i] == (uint64_t*) addr) { precomp_instr *last = last_access[i] + 1; while (last <= dst) { last->reg_cache_infos.needed_registers[i] = NULL; last++; } last_access[i] = dst; dirty[i] = 1; r64 [i] = 0; return i; } } // it's not cached, so take the least recently used register reg = lru_register(); if (last_access[reg]) free_register(reg); else { while (free_since[reg] <= dst) { free_since[reg]->reg_cache_infos.needed_registers[reg] = NULL; free_since[reg]++; } } last_access[reg] = dst; reg_content[reg] = (uint64_t*) addr; dirty[reg] = 1; r64[reg] = 0; return reg; } int allocate_register_64_w(uint64_t *addr) { int reg, i; // is it already cached? for (i = 0; i < 8; i++) { if (last_access[i] && reg_content[i] == addr) { precomp_instr *last = last_access[i] + 1; while (last <= dst) { last->reg_cache_infos.needed_registers[i] = NULL; last++; } last_access[i] = dst; r64[i] = 1; dirty[i] = 1; return i; } } // it's not cached, so take the least recently used register reg = lru_register(); if (last_access[reg]) free_register(reg); else { while (free_since[reg] <= dst) { free_since[reg]->reg_cache_infos.needed_registers[reg] = NULL; free_since[reg]++; } } last_access[reg] = dst; reg_content[reg] = addr; dirty[reg] = 1; r64[reg] = 1; return reg; } void allocate_register_32_manually(int reg, uint32_t *addr) { int i; /* check if we just happen to already have this r4300 reg cached in the requested x86 reg */ if (last_access[reg] && reg_content[reg] == (uint64_t*) addr) { precomp_instr *last = last_access[reg] + 1; while (last <= dst) { last->reg_cache_infos.needed_registers[reg] = reg_content[reg]; last++; } last_access[reg] = dst; /* we won't touch r64 or dirty; the register returned is "read-only" */ return; } /* otherwise free up the requested x86 register */ if (last_access[reg]) free_register(reg); else { while (free_since[reg] <= dst) { free_since[reg]->reg_cache_infos.needed_registers[reg] = NULL; free_since[reg]++; } } /* if the r4300 register is already cached in a different x86 register, then copy it to the requested x86 register */ for (i=0; i<8; i++) { if (last_access[i] && reg_content[i] == (uint64_t*) addr) { precomp_instr *last = last_access[i]+1; while (last <= dst) { last->reg_cache_infos.needed_registers[i] = reg_content[i]; last++; } last_access[i] = dst; if (r64[i]) mov_reg64_reg64(reg, i); else mov_reg32_reg32(reg, i); last_access[reg] = dst; r64[reg] = r64[i]; dirty[reg] = dirty[i]; reg_content[reg] = reg_content[i]; /* free the previous x86 register used to cache this r4300 register */ free_since[i] = dst + 1; last_access[i] = NULL; return; } } /* otherwise just load the 32-bit value into the requested register */ last_access[reg] = dst; reg_content[reg] = (uint64_t*) addr; dirty[reg] = 0; r64[reg] = 0; if ((uint64_t*) addr == r0) xor_reg32_reg32(reg, reg); else mov_xreg32_m32rel(reg, addr); } void allocate_register_32_manually_w(int reg, uint32_t *addr) { int i; /* check if we just happen to already have this r4300 reg cached in the requested x86 reg */ if (last_access[reg] && reg_content[reg] == (uint64_t*) addr) { precomp_instr *last = last_access[reg]+1; while (last <= dst) { last->reg_cache_infos.needed_registers[reg] = NULL; last++; } last_access[reg] = dst; r64[reg] = 0; dirty[reg] = 1; return; } /* otherwise free up the requested x86 register */ if (last_access[reg]) free_register(reg); else { while (free_since[reg] <= dst) { free_since[reg]->reg_cache_infos.needed_registers[reg] = NULL; free_since[reg]++; } } /* if the r4300 register is already cached in a different x86 register, then free it and bind to the requested x86 register */ for (i = 0; i < 8; i++) { if (last_access[i] && reg_content[i] == (uint64_t*) addr) { precomp_instr *last = last_access[i] + 1; while (last <= dst) { last->reg_cache_infos.needed_registers[i] = NULL; last++; } last_access[reg] = dst; reg_content[reg] = reg_content[i]; dirty[reg] = 1; r64[reg] = 0; /* free the previous x86 register used to cache this r4300 register */ free_since[i] = dst+1; last_access[i] = NULL; return; } } /* otherwise just set up the requested register as 32-bit */ last_access[reg] = dst; reg_content[reg] = (uint64_t*) addr; dirty[reg] = 1; r64[reg] = 0; } // 0x48 0x83 0xEC 0x8 sub rsp, byte 8 // 0x48 0xA1 0xXXXXXXXXXXXXXXXX mov rax, qword (&code start) // 0x48 0x05 0xXXXXXXXX add rax, dword (local_addr) // 0x48 0x89 0x04 0x24 mov [rsp], rax // 0x48 0xB8 0xXXXXXXXXXXXXXXXX mov rax, ®[0] // 0x48 0x8B (reg<<3)|0x80 0xXXXXXXXX mov rdi, [rax + XXXXXXXX] // 0x48 0x8B (reg<<3)|0x80 0xXXXXXXXX mov rsi, [rax + XXXXXXXX] // 0x48 0x8B (reg<<3)|0x80 0xXXXXXXXX mov rbp, [rax + XXXXXXXX] // 0x48 0x8B (reg<<3)|0x80 0xXXXXXXXX mov rdx, [rax + XXXXXXXX] // 0x48 0x8B (reg<<3)|0x80 0xXXXXXXXX mov rcx, [rax + XXXXXXXX] // 0x48 0x8B (reg<<3)|0x80 0xXXXXXXXX mov rbx, [rax + XXXXXXXX] // 0x48 0x8B (reg<<3)|0x80 0xXXXXXXXX mov rax, [rax + XXXXXXXX] // 0xC3 ret // total : 84 bytes static void build_wrapper(precomp_instr *instr, unsigned char* pCode, precomp_block* block) { int i; *pCode++ = 0x48; *pCode++ = 0x83; *pCode++ = 0xEC; *pCode++ = 0x08; *pCode++ = 0x48; *pCode++ = 0xA1; *((uint64_t*) pCode) = (uint64_t)(&block->code); pCode += 8; *pCode++ = 0x48; *pCode++ = 0x05; *((uint32_t*) pCode) = (uint32_t)instr->local_addr; pCode += 4; *pCode++ = 0x48; *pCode++ = 0x89; *pCode++ = 0x04; *pCode++ = 0x24; *pCode++ = 0x48; *pCode++ = 0xB8; *((uint64_t*) pCode) = (uint64_t)®[0]; pCode += 8; for (i=7; i>=0; i--) { if (instr->reg_cache_infos.needed_registers[i]) { int64_t riprel; *pCode++ = 0x48; *pCode++ = 0x8B; *pCode++ = 0x80 | (i << 3); riprel = (int64_t) ((unsigned char *) instr->reg_cache_infos.needed_registers[i] - (unsigned char *) ®[0]); *((int *) pCode) = (int) riprel; pCode += 4; if (riprel >= 0x7fffffffLL || riprel < -0x80000000LL) { DebugMessage(M64MSG_ERROR, "build_wrapper error: reg[%i] offset too big for relative address from %p to %p", i, (®[0]), instr->reg_cache_infos.needed_registers[i]); #if !defined(_MSC_VER) asm(" int $3; "); #endif } } } *pCode++ = 0xC3; } #else int allocate_register_w(uint32_t *addr) { uint32_t oldest_access = 0xFFFFFFFF; int reg = 0, i; // is it already cached ? for (i=0; i<8; i++) { if (last_access[i] && reg_content[i] == addr) { precomp_instr *last = last_access[i]+1; while (last <= dst) { last->reg_cache_infos.needed_registers[i] = NULL; last++; } last_access[i] = dst; dirty[i] = 1; if (r64[i] != -1) { last = last_access[r64[i]]+1; while (last <= dst) { last->reg_cache_infos.needed_registers[r64[i]] = NULL; last++; } free_since[r64[i]] = dst+1; last_access[r64[i]] = NULL; r64[i] = -1; } return i; } } // if it's not cached, we take the least recently used register for (i=0; i<8; i++) { if (i != ESP && (uint32_t)last_access[i] < oldest_access) { oldest_access = (int)last_access[i]; reg = i; } } if (last_access[reg]) free_register(reg); else { while (free_since[reg] <= dst) { free_since[reg]->reg_cache_infos.needed_registers[reg] = NULL; free_since[reg]++; } } last_access[reg] = dst; reg_content[reg] = addr; dirty[reg] = 1; r64[reg] = -1; return reg; } int allocate_64_register1_w(uint32_t *addr) { int reg1, reg2, i; // is it already cached as a 32 bits value ? for (i=0; i<8; i++) { if (last_access[i] && reg_content[i] == addr) { if (r64[i] == -1) { allocate_register_w(addr); reg2 = lru_register(); if (last_access[reg2]) free_register(reg2); else { while (free_since[reg2] <= dst) { free_since[reg2]->reg_cache_infos.needed_registers[reg2] = NULL; free_since[reg2]++; } } r64[i] = reg2; r64[reg2] = i; last_access[reg2] = dst; reg_content[reg2] = addr+1; dirty[reg2] = 1; mov_reg32_reg32(reg2, i); sar_reg32_imm8(reg2, 31); return i; } else { last_access[i] = dst; last_access[r64[i]] = dst; dirty[i] = dirty[r64[i]] = 1; return i; } } } reg1 = allocate_register_w(addr); reg2 = lru_register(); if (last_access[reg2]) free_register(reg2); else { while (free_since[reg2] <= dst) { free_since[reg2]->reg_cache_infos.needed_registers[reg2] = NULL; free_since[reg2]++; } } r64[reg1] = reg2; r64[reg2] = reg1; last_access[reg2] = dst; reg_content[reg2] = addr+1; dirty[reg2] = 1; return reg1; } int allocate_64_register2_w(uint32_t *addr) { int reg1, reg2, i; // is it already cached as a 32 bits value ? for (i=0; i<8; i++) { if (last_access[i] && reg_content[i] == addr) { if (r64[i] == -1) { allocate_register_w(addr); reg2 = lru_register(); if (last_access[reg2]) free_register(reg2); else { while (free_since[reg2] <= dst) { free_since[reg2]->reg_cache_infos.needed_registers[reg2] = NULL; free_since[reg2]++; } } r64[i] = reg2; r64[reg2] = i; last_access[reg2] = dst; reg_content[reg2] = addr+1; dirty[reg2] = 1; mov_reg32_reg32(reg2, i); sar_reg32_imm8(reg2, 31); return reg2; } else { last_access[i] = dst; last_access[r64[i]] = dst; dirty[i] = dirty[r64[i]] = 1; return r64[i]; } } } reg1 = allocate_register_w(addr); reg2 = lru_register(); if (last_access[reg2]) free_register(reg2); else { while (free_since[reg2] <= dst) { free_since[reg2]->reg_cache_infos.needed_registers[reg2] = NULL; free_since[reg2]++; } } r64[reg1] = reg2; r64[reg2] = reg1; last_access[reg2] = dst; reg_content[reg2] = addr+1; dirty[reg2] = 1; return reg2; } void set_64_register_state(int reg1, int reg2, uint32_t *addr, int d) { last_access[reg1] = dst; last_access[reg2] = dst; reg_content[reg1] = addr; reg_content[reg2] = addr+1; r64[reg1] = reg2; r64[reg2] = reg1; dirty[reg1] = d; dirty[reg2] = d; } void force_32(int reg) { if (r64[reg] != -1) { precomp_instr *last = last_access[reg]+1; while (last <= dst) { if (dirty[reg]) last->reg_cache_infos.needed_registers[reg] = reg_content[reg]; else last->reg_cache_infos.needed_registers[reg] = NULL; if (dirty[r64[reg]]) last->reg_cache_infos.needed_registers[r64[reg]] = reg_content[r64[reg]]; else last->reg_cache_infos.needed_registers[r64[reg]] = NULL; last++; } if (dirty[reg]) { mov_m32_reg32(reg_content[reg], reg); mov_m32_reg32(reg_content[r64[reg]], r64[reg]); dirty[reg] = 0; } last_access[r64[reg]] = NULL; free_since[r64[reg]] = dst+1; r64[reg] = -1; } } void allocate_register_manually(int reg, uint32_t *addr) { int i; if (last_access[reg] && reg_content[reg] == addr) { precomp_instr *last = last_access[reg]+1; while (last <= dst) { last->reg_cache_infos.needed_registers[reg] = reg_content[reg]; last++; } last_access[reg] = dst; if (r64[reg] != -1) { last = last_access[r64[reg]]+1; while (last <= dst) { last->reg_cache_infos.needed_registers[r64[reg]] = reg_content[r64[reg]]; last++; } last_access[r64[reg]] = dst; } return; } if (last_access[reg]) free_register(reg); else { while (free_since[reg] <= dst) { free_since[reg]->reg_cache_infos.needed_registers[reg] = NULL; free_since[reg]++; } } // is it already cached ? for (i=0; i<8; i++) { if (last_access[i] && reg_content[i] == addr) { precomp_instr *last = last_access[i]+1; while (last <= dst) { last->reg_cache_infos.needed_registers[i] = reg_content[i]; last++; } last_access[i] = dst; if (r64[i] != -1) { last = last_access[r64[i]]+1; while (last <= dst) { last->reg_cache_infos.needed_registers[r64[i]] = reg_content[r64[i]]; last++; } last_access[r64[i]] = dst; } mov_reg32_reg32(reg, i); last_access[reg] = dst; r64[reg] = r64[i]; if (r64[reg] != -1) r64[r64[reg]] = reg; dirty[reg] = dirty[i]; reg_content[reg] = reg_content[i]; free_since[i] = dst+1; last_access[i] = NULL; return; } } last_access[reg] = dst; reg_content[reg] = addr; dirty[reg] = 0; r64[reg] = -1; if (addr) { if (addr == r0 || addr == r0+1) xor_reg32_reg32(reg, reg); else mov_reg32_m32(reg, addr); } } void allocate_register_manually_w(int reg, uint32_t *addr, int load) { int i; if (last_access[reg] && reg_content[reg] == addr) { precomp_instr *last = last_access[reg]+1; while (last <= dst) { last->reg_cache_infos.needed_registers[reg] = reg_content[reg]; last++; } last_access[reg] = dst; if (r64[reg] != -1) { last = last_access[r64[reg]]+1; while (last <= dst) { last->reg_cache_infos.needed_registers[r64[reg]] = reg_content[r64[reg]]; last++; } last_access[r64[reg]] = NULL; free_since[r64[reg]] = dst+1; r64[reg] = -1; } dirty[reg] = 1; return; } if (last_access[reg]) free_register(reg); else { while (free_since[reg] <= dst) { free_since[reg]->reg_cache_infos.needed_registers[reg] = NULL; free_since[reg]++; } } // is it already cached ? for (i=0; i<8; i++) { if (last_access[i] && reg_content[i] == addr) { precomp_instr *last = last_access[i]+1; while (last <= dst) { last->reg_cache_infos.needed_registers[i] = reg_content[i]; last++; } last_access[i] = dst; if (r64[i] != -1) { last = last_access[r64[i]]+1; while (last <= dst) { last->reg_cache_infos.needed_registers[r64[i]] = NULL; last++; } free_since[r64[i]] = dst+1; last_access[r64[i]] = NULL; r64[i] = -1; } if (load) mov_reg32_reg32(reg, i); last_access[reg] = dst; dirty[reg] = 1; r64[reg] = -1; reg_content[reg] = reg_content[i]; free_since[i] = dst+1; last_access[i] = NULL; return; } } last_access[reg] = dst; reg_content[reg] = addr; dirty[reg] = 1; r64[reg] = -1; if (addr && load) { if (addr == r0 || addr == r0+1) xor_reg32_reg32(reg, reg); else mov_reg32_m32(reg, addr); } } // 0x81 0xEC 0x4 0x0 0x0 0x0 sub esp, 4 // 0xA1 0xXXXXXXXX mov eax, XXXXXXXX (&code start) // 0x05 0xXXXXXXXX add eax, XXXXXXXX (local_addr) // 0x89 0x04 0x24 mov [esp], eax // 0x8B (reg<<3)|5 0xXXXXXXXX mov eax, [XXXXXXXX] // 0x8B (reg<<3)|5 0xXXXXXXXX mov ebx, [XXXXXXXX] // 0x8B (reg<<3)|5 0xXXXXXXXX mov ecx, [XXXXXXXX] // 0x8B (reg<<3)|5 0xXXXXXXXX mov edx, [XXXXXXXX] // 0x8B (reg<<3)|5 0xXXXXXXXX mov ebp, [XXXXXXXX] // 0x8B (reg<<3)|5 0xXXXXXXXX mov esi, [XXXXXXXX] // 0x8B (reg<<3)|5 0xXXXXXXXX mov edi, [XXXXXXXX] // 0xC3 ret // total : 62 bytes static void build_wrapper(precomp_instr *instr, unsigned char* pCode, precomp_block* block) { int i; int j=0; pCode[j++] = 0x81; pCode[j++] = 0xEC; pCode[j++] = 0x04; pCode[j++] = 0x00; pCode[j++] = 0x00; pCode[j++] = 0x00; pCode[j++] = 0xA1; *((uint32_t*)&pCode[j]) = (uint32_t)(&block->code); j+=4; pCode[j++] = 0x05; *((uint32_t*)&pCode[j]) = (uint32_t)instr->local_addr; j+=4; pCode[j++] = 0x89; pCode[j++] = 0x04; pCode[j++] = 0x24; for (i=0; i<8; i++) { if (instr->reg_cache_infos.needed_registers[i]) { pCode[j++] = 0x8B; pCode[j++] = (i << 3) | 5; *((uint32_t*)&pCode[j]) = (uint32_t)instr->reg_cache_infos.needed_registers[i]; j+=4; } } pCode[j++] = 0xC3; } #endif void build_wrappers(precomp_instr *instr, int start, int end, precomp_block* block) { int i, reg; for (i=start; i> 10) & 0x0F] = w1; } static void fb_uc2_moveword(uint32_t w0, uint32_t w1) { if (((w0 >> 16) & 0xFF) == 0x06) // segment rdp.segment[((w0 & 0xFFFF) >> 2)&0xF] = w1; } static void fb_bg_copy(uint32_t w0, uint32_t w1) { CI_STATUS status; uint32_t addr, imagePtr; if (rdp.main_ci == 0) return; status = rdp.frame_buffers[rdp.ci_count-1].status; if (status == CI_COPY) return; addr = RSP_SegmentToPhysical(w1) >> 1; imagePtr = RSP_SegmentToPhysical(((uint32_t*)gfx_info.RDRAM)[(addr+8)>>1]); if (status == CI_MAIN) { uint16_t frameW = ((uint16_t *)gfx_info.RDRAM)[(addr+3)^1] >> 2; uint16_t frameH = ((uint16_t *)gfx_info.RDRAM)[(addr+7)^1] >> 2; if ( (frameW == rdp.frame_buffers[rdp.ci_count-1].width) && (frameH == rdp.frame_buffers[rdp.ci_count-1].height) ) rdp.main_ci_bg = imagePtr; } else if (imagePtr >= rdp.main_ci && imagePtr < rdp.main_ci_end) //addr within main frame buffer { rdp.copy_ci_index = rdp.ci_count-1; rdp.frame_buffers[rdp.copy_ci_index].status = CI_COPY; FRDP("rdp.frame_buffers[%d].status = CI_COPY\n", rdp.copy_ci_index); if (rdp.frame_buffers[rdp.copy_ci_index].addr != rdp.main_ci_bg) { rdp.scale_x = 1.0f; rdp.scale_y = 1.0f; } else { rdp.motionblur = true; } FRDP ("Detect FB usage. texture addr is inside framebuffer: %08lx - %08lx \n", imagePtr, rdp.main_ci); } else if (imagePtr == g_gdp.zb_address) { if (status == CI_UNKNOWN) { rdp.frame_buffers[rdp.ci_count-1].status = CI_ZCOPY; rdp.tmpzimg = rdp.frame_buffers[rdp.ci_count-1].addr; if (!rdp.copy_zi_index) rdp.copy_zi_index = rdp.ci_count-1; FRDP("rdp.frame_buffers[%d].status = CI_ZCOPY\n", rdp.copy_ci_index); } } } static void fb_setscissor(uint32_t w0, uint32_t w1) { gDPSetScissor_G64( _SHIFTR( w1, 24, 2 ), // mode _FIXED2FLOAT( _SHIFTR( w0, 12, 12 ), 2 ), // ulx _FIXED2FLOAT( _SHIFTR( w0, 0, 12 ), 2 ), // uly _FIXED2FLOAT( _SHIFTR( w1, 12, 12 ), 2 ), // lrx _FIXED2FLOAT( _SHIFTR( w1, 0, 12 ), 2 ) ); // lry } static void fb_uc2_movemem(uint32_t w0, uint32_t w1) { if ((w0 & 0xFF) == 8) { uint32_t a = RSP_SegmentToPhysical(w1) >> 1; int16_t scale_x = ((int16_t*)gfx_info.RDRAM)[(a+0)^1] >> 2; int16_t trans_x = ((int16_t*)gfx_info.RDRAM)[(a+4)^1] >> 2; COLOR_IMAGE *cur_fb = (COLOR_IMAGE*)&rdp.frame_buffers[rdp.ci_count-1]; if ( abs((int)(scale_x + trans_x - cur_fb->width)) < 3) { int16_t scale_y = ((int16_t*)gfx_info.RDRAM)[(a+1)^1] >> 2; int16_t trans_y = ((int16_t*)gfx_info.RDRAM)[(a+5)^1] >> 2; uint32_t height = scale_y + trans_y; if (height < g_gdp.__clip.yl) cur_fb->height = height; } } } static void fb_rect(uint32_t w0, uint32_t w1) { int ul_x, lr_x, width, diff; if (rdp.frame_buffers[rdp.ci_count-1].width == 32) return; ul_x = ((w1 & 0x00FFF000) >> 14); lr_x = ((w0 & 0x00FFF000) >> 14); width = lr_x-ul_x; diff = abs((int)rdp.frame_buffers[rdp.ci_count-1].width - width); if (diff < 4) { uint32_t lr_y = min(g_gdp.__clip.yl, (w0 & 0xFFF) >> 2); if (rdp.frame_buffers[rdp.ci_count-1].height < lr_y) { FRDP("fb_rect. ul_x: %d, lr_x: %d, fb_height: %d -> %d\n", ul_x, lr_x, rdp.frame_buffers[rdp.ci_count-1].height, lr_y); rdp.frame_buffers[rdp.ci_count-1].height = lr_y; } } } static void fb_rdphalf_1(uint32_t w0, uint32_t w1) { branch_dl = w1; } static void fb_settextureimage(uint32_t w0, uint32_t w1) { COLOR_IMAGE *cur_fb; if (rdp.main_ci == 0) return; cur_fb = (COLOR_IMAGE*)&rdp.frame_buffers[rdp.ci_count-1]; if ( cur_fb->status >= CI_COPY) return; if (((w0 >> 19) & 0x03) >= 2) //check that texture is 16/32bit { int tex_format = ((w0 >> 21) & 0x07); uint32_t addr = RSP_SegmentToPhysical(w1); if ( tex_format == 0 ) { FRDP ("fb_settextureimage. fmt: %d, size: %d, imagePtr %08lx, main_ci: %08lx, cur_ci: %08lx \n", ((w0 >> 21) & 0x07), ((w0 >> 19) & 0x03), addr, rdp.main_ci, rdp.frame_buffers[rdp.ci_count-1].addr); if (cur_fb->status == CI_MAIN) { rdp.main_ci_last_tex_addr = addr; if (cur_fb->height == 0) { cur_fb->height = g_gdp.__clip.yl; rdp.main_ci_end = cur_fb->addr + ((cur_fb->width * cur_fb->height) << cur_fb->size >> 1); } } if ((addr >= rdp.main_ci) && (addr < rdp.main_ci_end)) //addr within main frame buffer { if (cur_fb->status == CI_MAIN) { rdp.copy_ci_index = rdp.ci_count-1; cur_fb->status = CI_COPY_SELF; rdp.scale_x = rdp.scale_x_bak; rdp.scale_y = rdp.scale_y_bak; FRDP("rdp.frame_buffers[%d].status = CI_COPY_SELF\n", rdp.ci_count-1); } else { if (cur_fb->width == rdp.frame_buffers[rdp.main_ci_index].width) { rdp.copy_ci_index = rdp.ci_count-1; cur_fb->status = CI_COPY; FRDP("rdp.frame_buffers[%d].status = CI_COPY\n", rdp.copy_ci_index); if ((rdp.main_ci_last_tex_addr >= cur_fb->addr) && (rdp.main_ci_last_tex_addr < (cur_fb->addr + cur_fb->width*cur_fb->height*cur_fb->size))) { rdp.motionblur = true; } else { rdp.scale_x = 1.0f; rdp.scale_y = 1.0f; } } else if (!(settings.frame_buffer & fb_ignore_aux_copy) && cur_fb->width < rdp.frame_buffers[rdp.main_ci_index].width) { rdp.copy_ci_index = rdp.ci_count-1; cur_fb->status = CI_AUX_COPY; FRDP("rdp.frame_buffers[%d].status = ci_aux_copy\n", rdp.copy_ci_index); rdp.scale_x = 1.0f; rdp.scale_y = 1.0f; } else { cur_fb->status = CI_AUX; FRDP("rdp.frame_buffers[%d].status = ci_aux\n", rdp.copy_ci_index); } } FRDP ("Detect FB usage. texture addr is inside framebuffer: %08lx - %08lx \n", addr, rdp.main_ci); } ///* else if ((cur_fb->status != CI_MAIN) && (addr >= g_gdp.zb_address && addr < rdp.zimg_end)) { cur_fb->status = CI_ZCOPY; if (!rdp.copy_zi_index) rdp.copy_zi_index = rdp.ci_count-1; FRDP("fb_settextureimage. rdp.frame_buffers[%d].status = CI_ZCOPY\n", rdp.ci_count-1); } //*/ else if ((rdp.maincimg[0].width > 64) && (addr >= rdp.maincimg[0].addr) && (addr < (rdp.maincimg[0].addr + rdp.maincimg[0].width*rdp.maincimg[0].height*2))) { if (cur_fb->status != CI_MAIN) { cur_fb->status = CI_OLD_COPY; FRDP("rdp.frame_buffers[%d].status = CI_OLD_COPY 1, addr:%08lx\n", rdp.ci_count-1, rdp.last_drawn_ci_addr); } rdp.read_previous_ci = true; } else if ((addr >= rdp.last_drawn_ci_addr) && (addr < (rdp.last_drawn_ci_addr + rdp.maincimg[0].width*rdp.maincimg[0].height*2))) { if (cur_fb->status != CI_MAIN) { cur_fb->status = CI_OLD_COPY; FRDP("rdp.frame_buffers[%d].status = CI_OLD_COPY 2, addr:%08lx\n", rdp.ci_count-1, rdp.last_drawn_ci_addr); } rdp.read_previous_ci = true; } } else if (fb_hwfbe_enabled && (cur_fb->status == CI_MAIN)) { if ((addr >= rdp.main_ci) && (addr < rdp.main_ci_end)) //addr within main frame buffer { rdp.copy_ci_index = rdp.ci_count-1; rdp.black_ci_index = rdp.ci_count-1; cur_fb->status = CI_COPY_SELF; FRDP("rdp.frame_buffers[%d].status = CI_COPY_SELF\n", rdp.ci_count-1); } } } if (cur_fb->status == CI_UNKNOWN) { cur_fb->status = CI_AUX; FRDP("fb_settextureimage. rdp.frame_buffers[%d].status = ci_aux\n", rdp.ci_count-1); } } static void fb_loadtxtr(uint32_t w0, uint32_t w1) { if (rdp.frame_buffers[rdp.ci_count-1].status == CI_UNKNOWN) { rdp.frame_buffers[rdp.ci_count-1].status = CI_AUX; FRDP("rdp.frame_buffers[%d].status = ci_aux\n", rdp.ci_count-1); } } static void fb_setdepthimage(uint32_t w0, uint32_t w1) { int i; g_gdp.zb_address = RSP_SegmentToPhysical(w1); rdp.zimg_end = g_gdp.zb_address + rdp.ci_width*rdp.ci_height*2; if (g_gdp.zb_address == rdp.main_ci) //strange, but can happen { rdp.frame_buffers[rdp.main_ci_index].status = CI_UNKNOWN; if (rdp.main_ci_index < rdp.ci_count) { rdp.frame_buffers[rdp.main_ci_index].status = CI_ZIMG; FRDP("rdp.frame_buffers[%d].status = CI_ZIMG\n", rdp.main_ci_index); rdp.main_ci_index++; rdp.frame_buffers[rdp.main_ci_index].status = CI_MAIN; FRDP("rdp.frame_buffers[%d].status = CI_MAIN\n", rdp.main_ci_index); rdp.main_ci = rdp.frame_buffers[rdp.main_ci_index].addr; rdp.main_ci_end = rdp.main_ci + (rdp.frame_buffers[rdp.main_ci_index].width * rdp.frame_buffers[rdp.main_ci_index].height * rdp.frame_buffers[rdp.main_ci_index].size); for (i = rdp.main_ci_index+1; i < rdp.ci_count; i++) { COLOR_IMAGE *fb = (COLOR_IMAGE*)&rdp.frame_buffers[i]; if (fb->addr == rdp.main_ci) { fb->status = CI_MAIN; FRDP("rdp.frame_buffers[%d].status = CI_MAIN\n", i); } } } else rdp.main_ci = 0; } for (i = 0; i < rdp.ci_count; i++) { COLOR_IMAGE *fb = (COLOR_IMAGE*)&rdp.frame_buffers[i]; if ((fb->addr == g_gdp.zb_address) && (fb->status == CI_AUX || fb->status == CI_USELESS)) { fb->status = CI_ZIMG; FRDP("rdp.frame_buffers[%d].status = CI_ZIMG\n", i); } } } static void fb_setcolorimage(uint32_t w0, uint32_t w1) { COLOR_IMAGE *cur_fb; rdp.ocimg = rdp.cimg; rdp.cimg = RSP_SegmentToPhysical(w1); cur_fb = (COLOR_IMAGE*)&rdp.frame_buffers[rdp.ci_count]; cur_fb->width = (w0 & 0xFFF) + 1; if (cur_fb->width == 32 ) cur_fb->height = 32; else if (cur_fb->width == 16 ) cur_fb->height = 16; else if (rdp.ci_count > 0) cur_fb->height = g_gdp.__clip.yl; else cur_fb->height = 0; cur_fb->format = (w0 >> 21) & 0x7; cur_fb->size = (w0 >> 19) & 0x3; cur_fb->addr = rdp.cimg; cur_fb->changed = 1; /* if (rdp.ci_count > 0) if (rdp.frame_buffers[0].addr == rdp.cimg) rdp.frame_buffers[0].height = g_gdp.__clip.yl; */ //FRDP ("fb_setcolorimage. width: %d, height: %d, fmt: %d, size: %d, addr %08lx\n", cur_fb->width, cur_fb->height, cur_fb->format, cur_fb->size, cur_fb->addr); if (rdp.cimg == g_gdp.zb_address) { cur_fb->status = CI_ZIMG; rdp.zimg_end = g_gdp.zb_address + cur_fb->width * g_gdp.__clip.yl * 2; //FRDP("rdp.frame_buffers[%d].status = CI_ZIMG\n", rdp.ci_count); } else if (rdp.cimg == rdp.tmpzimg) { cur_fb->status = CI_ZCOPY; if (!rdp.copy_zi_index) rdp.copy_zi_index = rdp.ci_count-1; //FRDP("rdp.frame_buffers[%d].status = CI_ZCOPY\n", rdp.ci_count); } else if (rdp.main_ci != 0) { if (rdp.cimg == rdp.main_ci) //switched to main fb again { cur_fb->height = max(cur_fb->height, rdp.frame_buffers[rdp.main_ci_index].height); rdp.main_ci_index = rdp.ci_count; rdp.main_ci_end = rdp.cimg + ((cur_fb->width * cur_fb->height) << cur_fb->size >> 1); cur_fb->status = CI_MAIN; //FRDP("rdp.frame_buffers[%d].status = CI_MAIN\n", rdp.ci_count); } else // status is not known yet cur_fb->status = CI_UNKNOWN; } else { if ((g_gdp.zb_address != rdp.cimg))//&& (rdp.ocimg != rdp.cimg)) { rdp.main_ci = rdp.cimg; rdp.main_ci_end = rdp.cimg + ((cur_fb->width * cur_fb->height) << cur_fb->size >> 1); rdp.main_ci_index = rdp.ci_count; cur_fb->status = CI_MAIN; //FRDP("rdp.frame_buffers[%d].status = CI_MAIN\n", rdp.ci_count); } else cur_fb->status = CI_UNKNOWN; } if (rdp.ci_count > 0 && rdp.frame_buffers[rdp.ci_count-1].status == CI_UNKNOWN) //status of previous fb was not changed - it is useless { if (fb_hwfbe_enabled && !(settings.frame_buffer & fb_useless_is_useless)) { rdp.frame_buffers[rdp.ci_count-1].status = CI_AUX; rdp.frame_buffers[rdp.ci_count-1].changed = 0; FRDP("rdp.frame_buffers[%d].status = ci_aux\n", rdp.ci_count-1); } else { rdp.frame_buffers[rdp.ci_count-1].status = CI_USELESS; /* uint32_t addr = rdp.frame_buffers[rdp.ci_count-1].addr; for (i = 0; i < rdp.ci_count - 1; i++) { if (rdp.frame_buffers[i].addr == addr) { rdp.frame_buffers[rdp.ci_count-1].status = rdp.frame_buffers[i].status; break; } } //*/ //FRDP("rdp.frame_buffers[%d].status = %s\n", rdp.ci_count-1, CIStatus[rdp.frame_buffers[rdp.ci_count-1].status]); } } if (cur_fb->status == CI_MAIN) { int viSwapOK = ((settings.swapmode == 2) && (rdp.vi_org_reg == *gfx_info.VI_ORIGIN_REG)) ? false : true; if ((rdp.maincimg[0].addr != cur_fb->addr) && SwapOK && viSwapOK) { SwapOK = false; rdp.swap_ci_index = rdp.ci_count; } } rdp.ci_count++; if (rdp.ci_count > NUMTEXBUF) //overflow rdp.halt = 1; } // RDP graphic instructions pointer table used in DetectFrameBufferUsage static rdp_instr gfx_instruction_lite[9][256] = { { // uCode 0 - RSP SW 2.0X // 00-3f // games: Super Mario 64, Tetrisphere, Demos 0, 0, 0, 0, 0, 0, uc0_displaylist, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40-7f: Unused 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80-bf: Immediate commands 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, uc0_enddl, 0, 0, 0, fb_uc0_moveword, 0, uc0_culldl, 0, // c0-ff: RDP commands 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, fb_rect, fb_rect, 0, 0, 0, 0, 0, 0, 0, fb_setscissor, 0, 0, 0, 0, 0, 0, 0, 0, fb_rect, 0, 0, 0, 0, 0, 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage }, // uCode 1 - F3DEX 1.XX // 00-3f // games: Mario Kart, Star Fox { 0, 0, 0, 0, 0, 0, uc0_displaylist, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40-7f: unused 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80-bf: Immediate commands 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, uc6_loaducode, uc1_branch_z, 0, 0, 0, fb_rdphalf_1, 0, 0, 0, uc0_enddl, 0, 0, 0, fb_uc0_moveword, 0, uc2_culldl, 0, // c0-ff: RDP commands 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, fb_rect, fb_rect, 0, 0, 0, 0, 0, 0, 0, fb_setscissor, 0, 0, 0, 0, 0, 0, 0, 0, fb_rect, 0, 0, 0, 0, 0, 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage }, // uCode 2 - F3DEX 2.XX // games: Zelda 64 { // 00-3f 0, 0, 0, uc2_culldl, uc1_branch_z, 0, 0, 0, 0, fb_bg_copy, fb_bg_copy, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40-7f: unused 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80-bf: unused 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // c0-ff: RDP commands mixed with uc2 commands 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, uc2_dlist_cnt, 0, 0, 0, 0, 0, fb_uc2_moveword, fb_uc2_movemem, uc2_load_ucode, uc0_displaylist, uc0_enddl, 0, fb_rdphalf_1, 0, 0, fb_rect, fb_rect, 0, 0, 0, 0, 0, 0, 0, fb_setscissor, 0, 0, 0, 0, 0, 0, 0, 0, fb_rect, 0, 0, 0, 0, 0, 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage }, // uCode 3 - "RSP SW 2.0D", but not really // 00-3f // games: Wave Race // ** Added by Gonetz ** { 0, 0, 0, 0, 0, 0, uc0_displaylist, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40-7f: unused 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80-bf: Immediate commands 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, uc0_enddl, 0, 0, 0, fb_uc0_moveword, 0, uc0_culldl, 0, // c0-ff: RDP commands 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, fb_rect, fb_rect, 0, 0, 0, 0, 0, 0, 0, fb_setscissor, 0, 0, 0, 0, 0, 0, 0, 0, fb_rect, 0, 0, 0, 0, 0, 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage }, { // uCode 4 - RSP SW 2.0D EXT // 00-3f // games: Star Wars: Shadows of the Empire 0, 0, 0, 0, 0, 0, uc0_displaylist, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40-7f: Unused 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80-bf: Immediate commands 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, uc0_enddl, 0, 0, 0, fb_uc0_moveword, 0, uc0_culldl, 0, // c0-ff: RDP commands gdp_no_op, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, fb_rect, fb_rect, 0, 0, 0, 0, 0, 0, 0, fb_setscissor, 0, 0, 0, 0, 0, 0, 0, 0, fb_rect, 0, 0, 0, 0, 0, 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage }, { // uCode 5 - RSP SW 2.0 Diddy // 00-3f // games: Diddy Kong Racing 0, 0, 0, 0, 0, 0, uc0_displaylist, uc5_dl_in_mem, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40-7f: Unused 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80-bf: Immediate commands 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, uc0_enddl, 0, 0, 0, fb_uc0_moveword, 0, uc0_culldl, 0, // c0-ff: RDP commands 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, fb_rect, fb_rect, 0, 0, 0, 0, 0, 0, 0, fb_setscissor, 0, 0, 0, 0, 0, 0, 0, 0, fb_rect, 0, 0, 0, 0, 0, 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage }, // uCode 6 - S2DEX 1.XX // games: Yoshi's Story { 0, 0, 0, 0, 0, 0, uc0_displaylist, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40-7f: unused 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80-bf: Immediate commands 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, uc6_loaducode, uc6_select_dl, 0, 0, 0, 0, 0, 0, 0, uc0_enddl, 0, 0, 0, fb_uc0_moveword, 0, uc2_culldl, 0, // c0-ff: RDP commands 0, fb_loadtxtr, fb_loadtxtr, fb_loadtxtr, fb_loadtxtr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, fb_rect, fb_rect, 0, 0, 0, 0, 0, 0, 0, fb_setscissor, 0, 0, 0, 0, 0, 0, 0, 0, fb_rect, 0, 0, 0, 0, 0, 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage }, { 0, 0, 0, 0, 0, 0, uc0_displaylist, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40-7f: unused 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80-bf: Immediate commands 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, uc0_enddl, 0, 0, 0, fb_uc0_moveword, 0, uc0_culldl, 0, // c0-ff: RDP commands 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, fb_rect, fb_rect, 0, 0, 0, 0, 0, 0, 0, fb_setscissor, 0, 0, 0, 0, 0, 0, 0, 0, fb_rect, 0, 0, 0, 0, 0, 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage }, { // 00-3f 0, 0, 0, uc2_culldl, uc1_branch_z, 0, 0, 0, 0, fb_bg_copy, fb_bg_copy, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40-7f: unused 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80-bf: unused 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // c0-ff: RDP commands mixed with uc2 commands 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, uc2_dlist_cnt, 0, 0, 0, 0, 0, fb_uc2_moveword, 0, uc2_load_ucode, uc0_displaylist, uc0_enddl, 0, 0, 0, 0, fb_rect, fb_rect, 0, 0, 0, 0, 0, 0, 0, fb_setscissor, 0, 0, 0, 0, 0, 0, 0, 0, fb_rect, 0, 0, 0, 0, 0, 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage } }; mupen64plus-video-gliden64/src/OGL3X/UniformBlock.h000664 001750 001750 00000004373 12655644434 023034 0ustar00sergiosergio000000 000000 #ifndef UNIFORM_BLOCK_H #define UNIFORM_BLOCK_H #include "../UniformCollection.h" class UniformBlock : public UniformCollection { public: UniformBlock(); ~UniformBlock(); virtual void bindWithShaderCombiner(ShaderCombiner * _pCombiner); virtual void setColorData(ColorUniforms _index, u32 _dataSize, const void * _data); virtual void updateTextureParameters(); virtual void updateLightParameters(); virtual void updateUniforms(ShaderCombiner * /*_pCombiner*/, OGLRender::RENDER_STATE /*_renderState*/) {} private: void _initTextureBuffer(GLuint _program); void _initColorsBuffer(GLuint _program); void _initLightBuffer(GLuint _program); bool _isDataChanged(void * _pBuffer, const void * _pData, u32 _dataSize); template struct UniformBlockData { UniformBlockData() : m_buffer(0), m_blockBindingPoint(_bindingPoint) { memset(m_indices, 0, sizeof(m_indices)); memset(m_offsets, 0, sizeof(m_offsets)); } ~UniformBlockData() { if (m_buffer != 0) { glDeleteBuffers(1, &m_buffer); m_buffer = 0; } } GLint initBuffer(GLuint _program, const char * _strBlockName, const char ** _strUniformNames) { GLuint blockIndex = glGetUniformBlockIndex(_program, _strBlockName); if (blockIndex == GL_INVALID_INDEX) return 0; GLint blockSize, numUniforms; glGetActiveUniformBlockiv(_program, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize); glGetActiveUniformBlockiv(_program, blockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &numUniforms); glGetUniformIndices(_program, numUniforms, _strUniformNames, m_indices); glGetActiveUniformsiv(_program, numUniforms, m_indices, GL_UNIFORM_OFFSET, m_offsets); glUniformBlockBinding(_program, blockIndex, m_blockBindingPoint); glGenBuffers(1, &m_buffer); return blockSize; } GLuint m_buffer; GLuint m_blockBindingPoint; GLuint m_indices[_numUniforms]; GLint m_offsets[_numUniforms]; }; GLuint m_currentBuffer; OGLRender::OGL_RENDERER m_renderer; UniformBlockData m_textureBlock; UniformBlockData m_colorsBlock; UniformBlockData m_lightBlock; std::vector m_textureBlockData; std::vector m_colorsBlockData; std::vector m_lightBlockData; }; #endif // UNIFORM_BLOCK_H mupen64plus-core/src/pi/pi_controller.h000664 001750 001750 00000005542 12655644434 021300 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - pi_controller.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_PI_PI_CONTROLLER_H #define M64P_PI_PI_CONTROLLER_H #include #include #include "cart_rom.h" #include "flashram.h" #include "sram.h" #include "../dd/dd_rom.h" #ifndef PI_REG #define PI_REG(a) ((a & 0xffff) >> 2) #endif struct r4300_core; struct ri_controller; enum pi_registers { PI_DRAM_ADDR_REG, PI_CART_ADDR_REG, PI_RD_LEN_REG, PI_WR_LEN_REG, PI_STATUS_REG, PI_BSD_DOM1_LAT_REG, PI_BSD_DOM1_PWD_REG, PI_BSD_DOM1_PGS_REG, PI_BSD_DOM1_RLS_REG, PI_BSD_DOM2_LAT_REG, PI_BSD_DOM2_PWD_REG, PI_BSD_DOM2_PGS_REG, PI_BSD_DOM2_RLS_REG, PI_REGS_COUNT }; struct pi_controller { uint32_t regs[PI_REGS_COUNT]; struct cart_rom cart_rom; struct flashram flashram; struct sram sram; struct dd_rom dd_rom; int use_flashram; struct r4300_core* r4300; struct ri_controller *ri; }; void connect_pi(struct pi_controller* pi, struct r4300_core* r4300, struct ri_controller *ri, uint8_t* rom, size_t rom_size, uint8_t* ddrom, size_t ddrom_size); void init_pi(struct pi_controller* pi); int read_pi_regs(void* opaque, uint32_t address, uint32_t* value); int write_pi_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask); void pi_end_of_dma_event(struct pi_controller* pi); #endif libretro-common/libco/armeabi.c000664 001750 001750 00000003756 12655644434 017676 0ustar00sergiosergio000000 000000 /* libco.armeabi (2013-04-05) author: Themaister license: public domain */ #define LIBCO_C #include #include #include #include #include #ifndef __APPLE__ #include #endif #ifdef __cplusplus extern "C" { #endif static thread_local uint32_t co_active_buffer[64]; static thread_local cothread_t co_active_handle; asm ( ".arm\n" ".align 4\n" ".globl co_switch_arm\n" ".globl _co_switch_arm\n" "co_switch_arm:\n" "_co_switch_arm:\n" " stmia r1!, {r4, r5, r6, r7, r8, r9, r10, r11, sp, lr}\n" " ldmia r0!, {r4, r5, r6, r7, r8, r9, r10, r11, sp, pc}\n" ); /* ASM */ void co_switch_arm(cothread_t handle, cothread_t current); static void crash(void) { /* Called only if cothread_t entrypoint returns. */ assert(0); } cothread_t co_create(unsigned int size, void (*entrypoint)(void)) { size = (size + 1023) & ~1023; cothread_t handle = 0; #if defined(__APPLE__) || HAVE_POSIX_MEMALIGN >= 1 if (posix_memalign(&handle, 1024, size + 256) < 0) return 0; #else handle = memalign(1024, size + 256); #endif if (!handle) return handle; uint32_t *ptr = (uint32_t*)handle; /* Non-volatiles. */ ptr[0] = 0; /* r4 */ ptr[1] = 0; /* r5 */ ptr[2] = 0; /* r6 */ ptr[3] = 0; /* r7 */ ptr[4] = 0; /* r8 */ ptr[5] = 0; /* r9 */ ptr[6] = 0; /* r10 */ ptr[7] = 0; /* r11 */ /* Align stack to 64-bit */ ptr[8] = (uintptr_t)ptr + size + 256 - 8; /* r13, stack pointer */ ptr[9] = (uintptr_t)entrypoint; /* r15, PC (link register r14 gets saved here). */ return handle; } cothread_t co_active(void) { if (!co_active_handle) co_active_handle = co_active_buffer; return co_active_handle; } void co_delete(cothread_t handle) { free(handle); } void co_switch(cothread_t handle) { cothread_t co_previous_handle = co_active(); co_switch_arm(co_active_handle = handle, co_previous_handle); } #ifdef __cplusplus } #endif mupen64plus-video-gliden64/src/PluginAPI.h000664 001750 001750 00000004455 12655644434 021377 0ustar00sergiosergio000000 000000 #ifndef COMMONPLUGINAPI_H #define COMMONPLUGINAPI_H #include #include #ifdef MUPENPLUSAPI #include "m64p_plugin.h" #else #include "ZilmarGFX_1_3.h" #define RSPTHREAD #endif enum API_COMMAND { acNone = 0, acProcessDList, acProcessRDPList, acUpdateScreen, acRomClosed }; class PluginAPI { public: #ifdef RSPTHREAD ~PluginAPI() { delete m_pRspThread; m_pRspThread = NULL; } #endif // Common void MoveScreen(int /*_xpos*/, int /*_ypos*/) {} void ViStatusChanged() {} void ViWidthChanged() {} void ProcessDList(); void ProcessRDPList(); void RomClosed(); void RomOpen(); void ShowCFB(); void UpdateScreen(); int InitiateGFX(const GFX_INFO & _gfxInfo); void ChangeWindow(); void FindPluginPath(wchar_t * _strPath); void GetUserDataPath(wchar_t * _strPath); void GetUserCachePath(wchar_t * _strPath); #ifndef MUPENPLUSAPI // Zilmar void DllTest(HWND /*_hParent*/) {} void DrawScreen() {} void CloseDLL(void) {} void CaptureScreen(char * _Directory); void DllConfig(HWND _hParent); void GetDllInfo (PLUGIN_INFO * PluginInfo); void ReadScreen(void **_dest, long *_width, long *_height); void DllAbout(/*HWND _hParent*/); #else // MupenPlus void FBRead(unsigned int _addr) {} void FBWrite(unsigned int addr, unsigned int size) {} void FBGetFrameBufferInfo(void * _p) {} void ResizeVideoOutput(int _Width, int _Height); void ReadScreen2(void * _dest, int * _width, int * _height, int _front); m64p_error PluginStartup(m64p_dynlib_handle _CoreLibHandle); m64p_error PluginShutdown(); m64p_error PluginGetVersion( m64p_plugin_type * _PluginType, int * _PluginVersion, int * _APIVersion, const char ** _PluginNamePtr, int * _Capabilities ); void SetRenderingCallback(void (*callback)(int)); #endif static PluginAPI & get(); private: PluginAPI() #ifdef RSPTHREAD : m_pRspThread(NULL), m_command(acNone) #endif {} PluginAPI(const PluginAPI &); void _initiateGFX(const GFX_INFO & _gfxInfo) const; #ifdef RSPTHREAD void _callAPICommand(API_COMMAND _command); std::mutex m_rspThreadMtx; std::mutex m_pluginThreadMtx; std::condition_variable_any m_rspThreadCv; std::condition_variable_any m_pluginThreadCv; std::thread * m_pRspThread; API_COMMAND m_command; #endif }; inline PluginAPI & api() { return PluginAPI::get(); } #endif // COMMONPLUGINAPI_H libretro/msvc/msvc-2010/libretro.def000664 001750 001750 00000001010 12655644434 020333 0ustar00sergiosergio000000 000000 LIBRARY "libretro" EXPORTS retro_set_environment retro_set_video_refresh retro_set_audio_sample retro_set_audio_sample_batch retro_set_input_poll retro_set_input_state retro_init retro_deinit retro_api_version retro_get_system_info retro_get_system_av_info retro_set_controller_port_device retro_reset retro_run retro_serialize_size retro_serialize retro_unserialize retro_cheat_reset retro_cheat_set retro_load_game retro_load_game_special retro_unload_game retro_get_region retro_get_memory_data retro_get_memory_size mupen64plus-core/src/pi/pi_controller.c000664 001750 001750 00000023550 12655644434 021272 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - pi_controller.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "pi_controller.h" #define M64P_CORE_PROTOTYPES 1 #include "../api/callbacks.h" #include "../api/m64p_types.h" #include "../main/main.h" #include "../memory/memory.h" #include "../r4300/r4300_core.h" #include "../ri/rdram_detection_hack.h" #include "../ri/ri_controller.h" #include "../dd/dd_controller.h" #include /* Copies data from the PI into RDRAM */ static void dma_pi_read(struct pi_controller *pi) { if (pi->regs[PI_CART_ADDR_REG] >= 0x08000000 && pi->regs[PI_CART_ADDR_REG] < 0x08010000) { if (pi->use_flashram != 1) { dma_write_sram(pi); pi->use_flashram = -1; } else { dma_write_flashram(pi); } } else { DebugMessage(M64MSG_WARNING, "Unknown dma read at 0x%08X in dma_pi_read()", pi->regs[PI_CART_ADDR_REG]); } pi->regs[PI_STATUS_REG] |= 1; cp0_update_count(); add_interupt_event(PI_INT, 0x1000/* pi->regs[PI_RD_LEN_REG] */); } /* Copies data from the PI into RDRAM. */ static void dma_pi_write(struct pi_controller *pi) { uint32_t length, i; uint32_t dram_address; uint32_t rom_address; uint8_t* dram; const uint8_t* rom; if (pi->regs[PI_CART_ADDR_REG] < 0x10000000 && !(pi->regs[PI_CART_ADDR_REG] >= 0x06000000 && pi->regs[PI_CART_ADDR_REG] < 0x08000000)) { if (pi->regs[PI_CART_ADDR_REG] >= 0x08000000 && pi->regs[PI_CART_ADDR_REG] < 0x08010000) { if (pi->use_flashram != 1) { dma_read_sram(pi); pi->use_flashram = -1; } else { dma_read_flashram(pi); } } else if (pi->regs[PI_CART_ADDR_REG] >= 0x05000000 && pi->regs[PI_CART_ADDR_REG] < 0x06000000) { //64DD REG/BUFFER length = (pi->regs[PI_WR_LEN_REG] & 0xFFFFFF) + 1; i = (pi->regs[PI_CART_ADDR_REG] - 0x05000000) & 0x1FFFFFF; if (pi->regs[PI_CART_ADDR_REG] == 0x05000400) { //SECTOR BUFFER i -= 0x400; length = (i + length) > 0x100 ? (0x100 - i) : length; rom_address = (pi->regs[PI_CART_ADDR_REG] - 0x05000400) & 0x3fffff; rom = (uint8_t*)g_dd.sec_buf; //g_dd.regs[ASIC_CMD_STATUS] &= ~0x14000000; g_dd.regs[ASIC_CMD_STATUS] &= ~0x10000000; } else if (pi->regs[PI_CART_ADDR_REG] == 0x05000000) { //C2 BUFFER rom_address = (pi->regs[PI_CART_ADDR_REG] - 0x05000000) & 0x3fffff; length = (i + length) > 0x400 ? (0x400 - i) : length; rom = (uint8_t*)g_dd.c2_buf; //g_dd.regs[ASIC_CMD_STATUS] &= ~0x44000000; g_dd.regs[ASIC_CMD_STATUS] &= ~0x40000000; } else { pi->regs[PI_STATUS_REG] |= 3; cp0_update_count(); add_interupt_event(PI_INT, length / 8); return; } length = (pi->regs[PI_DRAM_ADDR_REG] + length) > 0x7FFFFF ? (0x7FFFFF - pi->regs[PI_DRAM_ADDR_REG]) : length; dram_address = pi->regs[PI_DRAM_ADDR_REG]; dram = (uint8_t*)pi->ri->rdram.dram; for (i = 0; i < length; ++i) dram[(dram_address + i) ^ S8] = rom[(rom_address + i) ^ S8]; invalidate_r4300_cached_code(0x80000000 + dram_address, length); invalidate_r4300_cached_code(0xa0000000 + dram_address, length); pi->regs[PI_STATUS_REG] |= 3; cp0_update_count(); add_interupt_event(PI_INT, length / 8); #if 0 dd_update_bm(&g_dd); #endif } else { #if 0 DebugMessage(M64MSG_WARNING, "Unknown dma write 0x%" PRIX32 " in dma_pi_write()", pi->regs[PI_CART_ADDR_REG]); #endif } pi->regs[PI_STATUS_REG] |= 1; cp0_update_count(); add_interupt_event(PI_INT, /*pi->regs[PI_WR_LEN_REG]*/0x1000); return; } if (pi->regs[PI_CART_ADDR_REG] >= 0x1fc00000) // for paper mario { pi->regs[PI_STATUS_REG] |= 1; cp0_update_count(); add_interupt_event(PI_INT, 0x1000); return; } if (pi->regs[PI_CART_ADDR_REG] >= 0x06000000 && pi->regs[PI_CART_ADDR_REG] < 0x08000000) { /* 64DD IPL */ length = (pi->regs[PI_WR_LEN_REG] & 0xFFFFFF) + 1; i = (pi->regs[PI_CART_ADDR_REG] - 0x06000000) & 0x1FFFFFF; length = (i + length) > pi->dd_rom.rom_size ? (pi->dd_rom.rom_size - i) : length; length = (pi->regs[PI_DRAM_ADDR_REG] + length) > 0x7FFFFF ? (0x7FFFFF - pi->regs[PI_DRAM_ADDR_REG]) : length; if (i > pi->dd_rom.rom_size || pi->regs[PI_DRAM_ADDR_REG] > 0x7FFFFF) { pi->regs[PI_STATUS_REG] |= 3; cp0_update_count(); add_interupt_event(PI_INT, length / 8); return; } dram_address = pi->regs[PI_DRAM_ADDR_REG]; rom_address = (pi->regs[PI_CART_ADDR_REG] - 0x06000000) & 0x3fffff; dram = (uint8_t*)pi->ri->rdram.dram; rom = pi->dd_rom.rom; } else { /* CART ROM */ length = (pi->regs[PI_WR_LEN_REG] & 0xFFFFFF) + 1; i = (pi->regs[PI_CART_ADDR_REG] - 0x10000000) & 0x3FFFFFF; length = (i + length) > pi->cart_rom.rom_size ? (pi->cart_rom.rom_size - i) : length; length = (pi->regs[PI_DRAM_ADDR_REG] + length) > 0x7FFFFF ? (0x7FFFFF - pi->regs[PI_DRAM_ADDR_REG]) : length; if (i > pi->cart_rom.rom_size || pi->regs[PI_DRAM_ADDR_REG] > 0x7FFFFF) { pi->regs[PI_STATUS_REG] |= 3; cp0_update_count(); add_interupt_event(PI_INT, length / 8); return; } dram_address = pi->regs[PI_DRAM_ADDR_REG]; rom_address = (pi->regs[PI_CART_ADDR_REG] - 0x10000000) & 0x3ffffff; dram = (uint8_t*)pi->ri->rdram.dram; rom = pi->cart_rom.rom; } for (i = 0; i < length; ++i) dram[(dram_address + i) ^ S8] = rom[(rom_address + i) ^ S8]; invalidate_r4300_cached_code(0x80000000 + dram_address, length); invalidate_r4300_cached_code(0xa0000000 + dram_address, length); /* HACK: monitor PI DMA to trigger RDRAM size detection * hack just before initial cart ROM loading. */ if (pi->regs[PI_CART_ADDR_REG] == 0x10001000 || pi->regs[PI_CART_ADDR_REG] == 0x06001000) { force_detected_rdram_size_hack(); } pi->regs[PI_STATUS_REG] |= 3; cp0_update_count(); add_interupt_event(PI_INT, length / 8); } void connect_pi(struct pi_controller* pi, struct r4300_core* r4300, struct ri_controller *ri, uint8_t *rom, size_t rom_size, uint8_t *ddrom, size_t ddrom_size) { connect_cart_rom(&pi->cart_rom, rom, rom_size); connect_dd_rom(&pi->dd_rom, ddrom, ddrom_size); pi->r4300 = r4300; pi->ri = ri; } /* Initializes the PI. */ void init_pi(struct pi_controller* pi) { memset(pi->regs, 0, PI_REGS_COUNT*sizeof(uint32_t)); init_flashram(&pi->flashram); pi->use_flashram = 0; } /* Reads a word from the PI MMIO register space. */ int read_pi_regs(void* opaque, uint32_t address, uint32_t* value) { struct pi_controller* pi = (struct pi_controller*)opaque; uint32_t reg = PI_REG(address); *value = pi->regs[reg]; return 0; } /* writes a word to the PI MMIO register space. */ int write_pi_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask) { struct pi_controller* pi = (struct pi_controller*)opaque; uint32_t reg = PI_REG(address); switch (reg) { case PI_RD_LEN_REG: pi->regs[PI_RD_LEN_REG] = MASKED_WRITE(&pi->regs[PI_RD_LEN_REG], value, mask); dma_pi_read(pi); return 0; case PI_WR_LEN_REG: pi->regs[PI_WR_LEN_REG] = MASKED_WRITE(&pi->regs[PI_WR_LEN_REG], value, mask); dma_pi_write(pi); return 0; case PI_STATUS_REG: if (value & mask & 2) clear_rcp_interrupt(pi->r4300, MI_INTR_PI); return 0; case PI_BSD_DOM1_LAT_REG: case PI_BSD_DOM1_PWD_REG: case PI_BSD_DOM1_PGS_REG: case PI_BSD_DOM1_RLS_REG: case PI_BSD_DOM2_LAT_REG: case PI_BSD_DOM2_PWD_REG: case PI_BSD_DOM2_PGS_REG: case PI_BSD_DOM2_RLS_REG: pi->regs[reg] = MASKED_WRITE(&pi->regs[reg], value & 0xff, mask); return 0; } pi->regs[reg] = MASKED_WRITE(&pi->regs[reg], value, mask); return 0; } void pi_end_of_dma_event(struct pi_controller* pi) { pi->regs[PI_STATUS_REG] &= ~3; raise_rcp_interrupt(pi->r4300, MI_INTR_PI); } libretro/link.T000664 001750 001750 00000000047 12655644434 014624 0ustar00sergiosergio000000 000000 { global: retro_*; local: *; }; gles2rice/src/Combiner.h000664 001750 001750 00000005317 12655644434 016302 0ustar00sergiosergio000000 000000 /* Copyright (C) 2002 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _COMBINER_H_ #define _COMBINER_H_ #include "typedefs.h" #include "CombinerDefs.h" #include "CSortedList.h" #include "DecodedMux.h" class CRender; extern const char* cycleTypeStrs[]; class CColorCombiner { friend class CRender; public: virtual ~CColorCombiner() {}; COLOR GetConstFactor(uint32_t colorFlag, uint32_t alphaFlag, uint32_t defaultColor); virtual void InitCombinerMode(void); virtual bool Initialize(void)=0; virtual void CleanUp(void) {}; virtual void UpdateCombiner(uint32_t dwMux0, uint32_t dwMux1); virtual void InitCombinerBlenderForSimpleTextureDraw(uint32_t tile)=0; virtual void DisableCombiner(void)=0; #ifdef DEBUGGER virtual void DisplaySimpleMuxString(void); virtual void DisplayMuxString(void); #endif DecodedMux *m_pDecodedMux; protected: CColorCombiner(CRender *pRender) : m_pDecodedMux(NULL), m_bTex0Enabled(false),m_bTex1Enabled(false),m_bTexelsEnable(false), m_bCycleChanged(false), m_supportedStages(1),m_pRender(pRender) { } virtual void InitCombinerCycleCopy(void)=0; virtual void InitCombinerCycleFill(void)=0; virtual void InitCombinerCycle12(void)=0; bool m_bTex0Enabled; bool m_bTex1Enabled; bool m_bTexelsEnable; bool m_bCycleChanged; // A flag will be set if cycle is changed to FILL or COPY int m_supportedStages; CRender *m_pRender; CSortedList m_DecodedMuxList; }; uint32_t GetTexelNumber(N64CombinerType &m); int CountTexel1Cycle(N64CombinerType &m); bool IsTextureUsed(N64CombinerType &m); void swap(uint8_t &a, uint8_t &b); inline bool isEqual(uint8_t val1, uint8_t val2) { if( (val1&MUX_MASK) == (val2&MUX_MASK) ) return true; else return false; } inline bool isTexel(uint8_t val) { if( (val&MUX_MASK) == MUX_TEXEL0 || (val&MUX_MASK) == MUX_TEXEL1 ) return true; else return false; } COLOR CalculateConstFactor(uint32_t colorOp, uint32_t alphaOp, uint32_t curCol); #endif gles2n64/src/L3DEX.h000664 001750 001750 00000000277 12655644434 015050 0ustar00sergiosergio000000 000000 #ifndef L3DEX_H #define L3DEX_H #ifdef __cplusplus extern "C" { #endif #include "Types.h" void L3DEX_Line3D( u32 w0, u32 w1 ); void L3DEX_Init(void); #ifdef __cplusplus } #endif #endif gles2n64/src/ZSort.h000664 001750 001750 00000000122 12655644434 015277 0ustar00sergiosergio000000 000000 #ifndef GLN64_ZSORT_H #define GLN64_ZSORT_H void ZSort_Init(void); #endif mupen64plus-video-gliden64/src/GLideNHQ/TxFilter.h000664 001750 001750 00000004407 12655644434 022700 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __TXFILTER_H__ #define __TXFILTER_H__ #include "TxInternal.h" #include "TxQuantize.h" #include "TxHiResCache.h" #include "TxTexCache.h" #include "TxUtil.h" #include "TxImage.h" class TxFilter { private: int _numcore; uint8 *_tex1; uint8 *_tex2; int _maxwidth; int _maxheight; int _maxbpp; int _options; int _cacheSize; tx_wstring _ident; tx_wstring _path; TxQuantize *_txQuantize; TxTexCache *_txTexCache; TxHiResCache *_txHiResCache; TxUtil *_txUtil; TxImage *_txImage; boolean _initialized; void clear(); public: ~TxFilter(); TxFilter(int maxwidth, int maxheight, int maxbpp, int options, int cachesize, const wchar_t *path, const wchar_t * texPackPath, const wchar_t *ident, dispInfoFuncExt callback); boolean filter(uint8 *src, int srcwidth, int srcheight, uint16 srcformat, uint64 g64crc, /* glide64 crc, 64bit for future use */ GHQTexInfo *info); boolean hirestex(uint64 g64crc, /* glide64 crc, 64bit for future use */ uint64 r_crc64, /* checksum hi:palette low:texture */ uint16 *palette, GHQTexInfo *info); uint64 checksum64(uint8 *src, int width, int height, int size, int rowStride, uint8 *palette); boolean dmptx(uint8 *src, int width, int height, int rowStridePixel, uint16 gfmt, uint16 n64fmt, uint64 r_crc64); boolean reloadhirestex(); }; #endif /* __TXFILTER_H__ */ mupen64plus-rsp-cxd4/000700 001750 001750 00000000000 12656647145 015552 5ustar00sergiosergio000000 000000 mupen64plus-video-gliden64/src/Combiner.h000664 001750 001750 00000007733 12655644434 021347 0ustar00sergiosergio000000 000000 #ifndef COMBINER_H #define COMBINER_H #include #include "GLideN64.h" #include "OpenGL.h" #include "gDP.h" #include "Types.h" /* * G_SETCOMBINE: color combine modes */ /* Color combiner constants: */ #define G_CCMUX_COMBINED 0 #define G_CCMUX_TEXEL0 1 #define G_CCMUX_TEXEL1 2 #define G_CCMUX_PRIMITIVE 3 #define G_CCMUX_SHADE 4 #define G_CCMUX_ENVIRONMENT 5 #define G_CCMUX_CENTER 6 #define G_CCMUX_SCALE 6 #define G_CCMUX_COMBINED_ALPHA 7 #define G_CCMUX_TEXEL0_ALPHA 8 #define G_CCMUX_TEXEL1_ALPHA 9 #define G_CCMUX_PRIMITIVE_ALPHA 10 #define G_CCMUX_SHADE_ALPHA 11 #define G_CCMUX_ENV_ALPHA 12 #define G_CCMUX_LOD_FRACTION 13 #define G_CCMUX_PRIM_LOD_FRAC 14 #define G_CCMUX_NOISE 7 #define G_CCMUX_K4 7 #define G_CCMUX_K5 15 #define G_CCMUX_1 6 #define G_CCMUX_0 31 /* Alpha combiner constants: */ #define G_ACMUX_COMBINED 0 #define G_ACMUX_TEXEL0 1 #define G_ACMUX_TEXEL1 2 #define G_ACMUX_PRIMITIVE 3 #define G_ACMUX_SHADE 4 #define G_ACMUX_ENVIRONMENT 5 #define G_ACMUX_LOD_FRACTION 0 #define G_ACMUX_PRIM_LOD_FRAC 6 #define G_ACMUX_1 6 #define G_ACMUX_0 7 #define EncodeCombineMode( a0, b0, c0, d0, Aa0, Ab0, Ac0, Ad0, \ a1, b1, c1, d1, Aa1, Ab1, Ac1, Ad1 ) \ (u64)(((u64)(_SHIFTL( G_CCMUX_##a0, 20, 4 ) | _SHIFTL( G_CCMUX_##c0, 15, 5 ) | \ _SHIFTL( G_ACMUX_##Aa0, 12, 3 ) | _SHIFTL( G_ACMUX_##Ac0, 9, 3 ) | \ _SHIFTL( G_CCMUX_##a1, 5, 4 ) | _SHIFTL( G_CCMUX_##c1, 0, 5 )) << 32) | \ (u64)(_SHIFTL( G_CCMUX_##b0, 28, 4 ) | _SHIFTL( G_CCMUX_##d0, 15, 3 ) | \ _SHIFTL( G_ACMUX_##Ab0, 12, 3 ) | _SHIFTL( G_ACMUX_##Ad0, 9, 3 ) | \ _SHIFTL( G_CCMUX_##b1, 24, 4 ) | _SHIFTL( G_ACMUX_##Aa1, 21, 3 ) | \ _SHIFTL( G_ACMUX_##Ac1, 18, 3 ) | _SHIFTL( G_CCMUX_##d1, 6, 3 ) | \ _SHIFTL( G_ACMUX_##Ab1, 3, 3 ) | _SHIFTL( G_ACMUX_##Ad1, 0, 3 ))) // Internal combiner commands #define LOAD 0 #define SUB 1 #define MUL 2 #define ADD 3 #define INTER 4 // Internal generalized combiner inputs #define COMBINED 0 #define TEXEL0 1 #define TEXEL1 2 #define PRIMITIVE 3 #define SHADE 4 #define ENVIRONMENT 5 #define CENTER 6 #define SCALE 7 #define COMBINED_ALPHA 8 #define TEXEL0_ALPHA 9 #define TEXEL1_ALPHA 10 #define PRIMITIVE_ALPHA 11 #define SHADE_ALPHA 12 #define ENV_ALPHA 13 #define LOD_FRACTION 14 #define PRIM_LOD_FRAC 15 #define NOISE 16 #define K4 17 #define K5 18 #define ONE 19 #define ZERO 20 #define LIGHT 21 struct CombinerOp { int op; int param1; int param2; int param3; }; struct CombinerStage { int numOps; CombinerOp op[6]; }; struct Combiner { int numStages; CombinerStage stage[2]; }; struct CombineCycle { int sa, sb, m, a; }; class ShaderCombiner; class UniformCollection; class CombinerInfo { public: void init(); void destroy(); void update(); void setCombine(u64 _mux); ShaderCombiner * getCurrent() const {return m_pCurrent;} bool isChanged() const {return m_bChanged;} bool isShaderCacheSupported() const { return m_bShaderCacheSupported; } size_t getCombinersNumber() const { return m_combiners.size(); } static CombinerInfo & get(); void updatePrimColor(); void updateEnvColor(); void updateFogColor(); void updateBlendColor(); void updateKeyColor(); void updateConvertColor(); void updateTextureParameters(); void updateLightParameters(); // Update uniforms for GL without UniformBlock support void updateParameters(OGLRender::RENDER_STATE _renderState); private: CombinerInfo() : m_bChanged(false), m_bShaderCacheSupported(false), m_shadersLoaded(0), m_pCurrent(NULL) {} CombinerInfo(const CombinerInfo &); void _saveShadersStorage() const; bool _loadShadersStorage(); u32 _getConfigOptionsBitSet() const; ShaderCombiner * _compile(u64 mux) const; bool m_bChanged; bool m_bShaderCacheSupported; u32 m_shadersLoaded; ShaderCombiner * m_pCurrent; typedef std::map Combiners; Combiners m_combiners; UniformCollection * m_pUniformCollection; }; inline ShaderCombiner * currentCombiner() { return CombinerInfo::get().getCurrent(); } void Combiner_Init(); void Combiner_Destroy(); #endif gles2n64/src/L3DEX.c000664 001750 001750 00000005425 12655644434 015043 0ustar00sergiosergio000000 000000 #include "gles2N64.h" #include "Debug.h" #include "F3D.h" #include "F3DEX.h" #include "L3D.h" #include "L3DEX.h" #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gSP.h" #include "gDP.h" #include "GBI.h" void L3DEX_Line3D( u32 w0, u32 w1 ) { u32 wd = _SHIFTR( w1, 0, 8 ); if (wd == 0) gSPLine3D( _SHIFTR( w1, 17, 7 ), _SHIFTR( w1, 9, 7 ), 0 ); else gSPLineW3D( _SHIFTR( w1, 17, 7 ), _SHIFTR( w1, 9, 7 ), wd, 0 ); } void L3DEX_Init(void) { gSPSetupFunctions(); // Set GeometryMode flags GBI_InitFlags( F3DEX ); GBI.PCStackSize = 18; // GBI Command Command Value Command Function GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_MTX, F3D_MTX, F3D_Mtx ); GBI_SetGBI( G_RESERVED0, F3D_RESERVED0, F3D_Reserved0 ); GBI_SetGBI( G_MOVEMEM, F3D_MOVEMEM, F3D_MoveMem ); GBI_SetGBI( G_VTX, F3D_VTX, F3DEX_Vtx ); GBI_SetGBI( G_RESERVED1, F3D_RESERVED1, F3D_Reserved1 ); GBI_SetGBI( G_DL, F3D_DL, F3D_DList ); GBI_SetGBI( G_RESERVED2, F3D_RESERVED2, F3D_Reserved2 ); GBI_SetGBI( G_RESERVED3, F3D_RESERVED3, F3D_Reserved3 ); GBI_SetGBI( G_SPRITE2D_BASE, F3D_SPRITE2D_BASE, F3D_Sprite2D_Base ); // GBI_SetGBI( G_TRI1, F3D_TRI1, F3DEX_Tri1 ); GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3DEX_CullDL ); GBI_SetGBI( G_POPMTX, F3D_POPMTX, F3D_PopMtx ); GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3D_MoveWord ); GBI_SetGBI( G_TEXTURE, F3D_TEXTURE, F3D_Texture ); GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L ); GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL ); GBI_SetGBI( G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, F3D_SetGeometryMode ); GBI_SetGBI( G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE, F3D_ClearGeometryMode ); GBI_SetGBI( G_LINE3D, L3D_LINE3D, L3DEX_Line3D ); GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_MODIFYVTX, F3DEX_MODIFYVTX, F3DEX_ModifyVtx ); // GBI_SetGBI( G_TRI2, F3DEX_TRI2, F3DEX_Tri2 ); GBI_SetGBI( G_BRANCH_Z, F3DEX_BRANCH_Z, F3DEX_Branch_Z ); GBI_SetGBI( G_LOAD_UCODE, F3DEX_LOAD_UCODE, F3DEX_Load_uCode ); } gles2n64/src/ZSort.c000664 001750 001750 00000046530 12655644434 015307 0ustar00sergiosergio000000 000000 #include #include #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gSP.h" #include "gDP.h" #include "F3D.h" #include "OpenGL.h" #include "3DMath.h" #define GZM_USER0 0 #define GZM_USER1 2 #define GZM_MMTX 4 #define GZM_PMTX 6 #define GZM_MPMTX 8 #define GZM_OTHERMODE 10 #define GZM_VIEWPORT 12 #define GZF_LOAD 0 #define GZF_SAVE 1 #define ZH_NULL 0 #define ZH_SHTRI 1 #define ZH_TXTRI 2 #define ZH_SHQUAD 3 #define ZH_TXQUAD 4 typedef f32 M44[4][4]; struct ZSORTRDP { f32 view_scale[2]; f32 view_trans[2]; } GLN64zSortRdp = {{0, 0}, {0, 0}}; void ZSort_RDPCMD( u32 a, u32 _w1) { u32 addr = RSP_SegmentToPhysical(_w1) >> 2; if (addr) { __RSP.bLLE = true; while(true) { u32 w0 = ((u32*)gfx_info.RDRAM)[addr++]; __RSP.cmd = _SHIFTR( w0, 24, 8 ); if (__RSP.cmd == 0xDF) break; u32 w1 = ((u32*)gfx_info.RDRAM)[addr++]; if (__RSP.cmd == 0xE4 || __RSP.cmd == 0xE5) { addr++; __RDP.w2 = ((u32*)gfx_info.RDRAM)[addr++]; addr++; __RDP.w3 = ((u32*)gfx_info.RDRAM)[addr++]; } GBI.cmd[__RSP.cmd]( w0, w1 ); }; __RSP.bLLE = false; } } //RSP command VRCPL static int Calc_invw (int _w) { int count, neg; union { s32 W; u32 UW; s16 HW[2]; u16 UHW[2]; } Result; Result.W = _w; if (Result.UW == 0) Result.UW = 0x7FFFFFFF; else { if (Result.W < 0) { neg = TRUE; if (Result.UHW[1] == 0xFFFF && Result.HW[0] < 0) Result.W = ~Result.W + 1; else Result.W = ~Result.W; } else neg = FALSE; for (count = 31; count > 0; --count) { if ((Result.W & (1 << count))) { Result.W &= (0xFFC00000 >> (31 - count) ); count = 0; } } Result.W = 0x7FFFFFFF / Result.W; for (count = 31; count > 0; --count) { if ((Result.W & (1 << count))) { Result.W &= (0xFFFF8000 >> (31 - count) ); count = 0; } } if (neg == TRUE) Result.W = ~Result.W; } return Result.W; } static void ZSort_DrawObject (u8 * _addr, u32 _type) { u32 i; u32 textured = 0, vnum = 0, vsize = 0; switch (_type) { case ZH_NULL: textured = vnum = vsize = 0; break; case ZH_SHTRI: textured = 0; vnum = 3; vsize = 8; break; case ZH_TXTRI: textured = 1; vnum = 3; vsize = 16; break; case ZH_SHQUAD: textured = 0; vnum = 4; vsize = 8; break; case ZH_TXQUAD: textured = 1; vnum = 4; vsize = 16; break; } for (i = 0; i < vnum; ++i) { SPVertex *vtx = (SPVertex*)&OGL.triangles.vertices[i]; vtx->x = _FIXED2FLOAT(((s16*)_addr)[0 ^ 1], 2); vtx->y = _FIXED2FLOAT(((s16*)_addr)[1 ^ 1], 2); vtx->z = 0.0f; vtx->r = _addr[4^3] * 0.0039215689f; vtx->g = _addr[5^3] * 0.0039215689f; vtx->b = _addr[6^3] * 0.0039215689f; vtx->a = _addr[7^3] * 0.0039215689f; vtx->flag = 0; vtx->HWLight = 0; vtx->clip = 0; if (textured != 0) { vtx->s = _FIXED2FLOAT(((s16*)_addr)[4^1], 5 ); vtx->t = _FIXED2FLOAT(((s16*)_addr)[5^1], 5 ); vtx->w = Calc_invw(((int*)_addr)[3]) / 31.0f; } else vtx->w = 1.0f; _addr += vsize; } //render.drawLLETriangle(vnum); } static u32 ZSort_LoadObject (u32 _zHeader, u32 * _pRdpCmds) { u32 w1; const u32 type = _zHeader & 7; u8 * addr = gfx_info.RDRAM + (_zHeader&0xFFFFFFF8); switch (type) { case ZH_SHTRI: case ZH_SHQUAD: { w1 = ((u32*)addr)[1]; if (w1 != _pRdpCmds[0]) { _pRdpCmds[0] = w1; ZSort_RDPCMD (0, w1); } ZSort_DrawObject(addr + 8, type); } break; case ZH_NULL: case ZH_TXTRI: case ZH_TXQUAD: { w1 = ((u32*)addr)[1]; if (w1 != _pRdpCmds[0]) { _pRdpCmds[0] = w1; ZSort_RDPCMD (0, w1); } w1 = ((u32*)addr)[2]; if (w1 != _pRdpCmds[1]) { ZSort_RDPCMD (0, w1); _pRdpCmds[1] = w1; } w1 = ((u32*)addr)[3]; if (w1 != _pRdpCmds[2]) { ZSort_RDPCMD (0, w1); _pRdpCmds[2] = w1; } if (type != 0) { ZSort_DrawObject(addr + 16, type); } } break; } return RSP_SegmentToPhysical(((u32*)addr)[0]); } void ZSort_Obj( u32 _w0, u32 _w1 ) { u32 rdpcmds[3] = {0, 0, 0}; u32 cmd1 = _w1; u32 zHeader = RSP_SegmentToPhysical(_w0); while (zHeader) zHeader = ZSort_LoadObject(zHeader, rdpcmds); zHeader = RSP_SegmentToPhysical(cmd1); while (zHeader) zHeader = ZSort_LoadObject(zHeader, rdpcmds); } void ZSort_Interpolate( u32 a , u32 b) { #ifdef DEBUG LOG(LOG_VERBOSE, "ZSort_Interpolate Ignored\n"); #endif } void ZSort_XFMLight( u32 _w0, u32 _w1 ) { u32 i; int mid = _SHIFTR(_w0, 0, 8); gSPNumLights(1 + _SHIFTR(_w1, 12, 8)); u32 addr = -1024 + _SHIFTR(_w1, 0, 12); assert(mid == GZM_MMTX); gSP.lights[gSP.numLights].r = (f32)(((u8*)gfx_info.DMEM)[(addr+0)^3]) * 0.0039215689f; gSP.lights[gSP.numLights].g = (f32)(((u8*)gfx_info.DMEM)[(addr+1)^3]) * 0.0039215689f; gSP.lights[gSP.numLights].b = (f32)(((u8*)gfx_info.DMEM)[(addr+2)^3]) * 0.0039215689f; addr += 8; for (i = 0; i < gSP.numLights; ++i) { gSP.lights[i].r = (f32)(((u8*)gfx_info.DMEM)[(addr+0)^3]) * 0.0039215689f; gSP.lights[i].g = (f32)(((u8*)gfx_info.DMEM)[(addr+1)^3]) * 0.0039215689f; gSP.lights[i].b = (f32)(((u8*)gfx_info.DMEM)[(addr+2)^3]) * 0.0039215689f; gSP.lights[i].x = (f32)(((s8*)gfx_info.DMEM)[(addr+8)^3]); gSP.lights[i].y = (f32)(((s8*)gfx_info.DMEM)[(addr+9)^3]); gSP.lights[i].z = (f32)(((s8*)gfx_info.DMEM)[(addr+10)^3]); addr += 24; } for (i = 0; i < 2; i++) { gSP.lookat[i].x = (f32)(((s8*)gfx_info.DMEM)[(addr+8)^3]); gSP.lookat[i].y = (f32)(((s8*)gfx_info.DMEM)[(addr+9)^3]); gSP.lookat[i].z = (f32)(((s8*)gfx_info.DMEM)[(addr+10)^3]); gSP.lookatEnable = (i == 0) || (i == 1 && gSP.lookat[i].x != 0 && gSP.lookat[i].y != 0); addr += 24; } } void ZSort_LightingL( u32 a, u32 b ) { #ifdef DEBUG LOG(LOG_VERBOSE, "ZSort_LightingL Ignored\n"); #endif } void ZSort_Lighting( u32 _w0, u32 _w1 ) { u32 i; u32 csrs = -1024 + _SHIFTR(_w0, 12, 12); u32 nsrs = -1024 + _SHIFTR(_w0, 0, 12); u32 num = 1 + _SHIFTR(_w1, 24, 8); u32 cdest = -1024 + _SHIFTR(_w1, 12, 12); u32 tdest = -1024 + _SHIFTR(_w1, 0, 12); int use_material = (csrs != 0x0ff0); tdest >>= 1; for (i = 0; i < num; i++) { SPVertex *vtx = (SPVertex*)&OGL.triangles.vertices[i]; vtx->nx = ((s8*)gfx_info.DMEM)[(nsrs++)^3]; vtx->ny = ((s8*)gfx_info.DMEM)[(nsrs++)^3]; vtx->nz = ((s8*)gfx_info.DMEM)[(nsrs++)^3]; TransformVectorNormalize( &vtx->nx, gSP.matrix.modelView[gSP.matrix.modelViewi] ); gSPLightVertex(vtx); f32 fLightDir[3] = {vtx->nx, vtx->ny, vtx->nz}; TransformVectorNormalize(fLightDir, gSP.matrix.projection); f32 x, y; if (gSP.lookatEnable) { x = DotProduct(&gSP.lookat[0].x, fLightDir); y = DotProduct(&gSP.lookat[1].x, fLightDir); } else { x = fLightDir[0]; y = fLightDir[1]; } vtx->s = (x + 1.0f) * 512.0f; vtx->t = (y + 1.0f) * 512.0f; vtx->a = 1.0f; if (use_material) { vtx->r *= gfx_info.DMEM[(csrs++)^3] * 0.0039215689f; vtx->g *= gfx_info.DMEM[(csrs++)^3] * 0.0039215689f; vtx->b *= gfx_info.DMEM[(csrs++)^3] * 0.0039215689f; vtx->a = gfx_info.DMEM[(csrs++)^3] * 0.0039215689f; } gfx_info.DMEM[(cdest++)^3] = (u8)(vtx->r * 255.0f); gfx_info.DMEM[(cdest++)^3] = (u8)(vtx->g * 255.0f); gfx_info.DMEM[(cdest++)^3] = (u8)(vtx->b * 255.0f); gfx_info.DMEM[(cdest++)^3] = (u8)(vtx->a * 255.0f); ((s16*)gfx_info.DMEM)[(tdest++)^1] = (s16)(vtx->s * 32.0f); ((s16*)gfx_info.DMEM)[(tdest++)^1] = (s16)(vtx->t * 32.0f); } } void ZSort_MTXRNSP(u32 a, u32 b) { #ifdef DEBUG LOG(LOG_VERBOSE, "ZSort_MTXRNSP Ignored\n"); #endif } void ZSort_MTXCAT(u32 _w0, u32 _w1) { M44 *s = NULL; M44 *t = NULL; u32 S = _SHIFTR(_w0, 0, 4); u32 T = _SHIFTR(_w1, 16, 4); u32 D = _SHIFTR(_w1, 0, 4); switch (S) { case GZM_MMTX: s = (M44*)gSP.matrix.modelView[gSP.matrix.modelViewi]; break; case GZM_PMTX: s = (M44*)gSP.matrix.projection; break; case GZM_MPMTX: s = (M44*)gSP.matrix.combined; break; } switch (T) { case GZM_MMTX: t = (M44*)gSP.matrix.modelView[gSP.matrix.modelViewi]; break; case GZM_PMTX: t = (M44*)gSP.matrix.projection; break; case GZM_MPMTX: t = (M44*)gSP.matrix.combined; break; } assert(s != NULL && t != NULL); f32 m[4][4]; MultMatrix(*s, *t, m); switch (D) { case GZM_MMTX: memcpy (gSP.matrix.modelView[gSP.matrix.modelViewi], m, 64);; break; case GZM_PMTX: memcpy (gSP.matrix.projection, m, 64);; break; case GZM_MPMTX: memcpy (gSP.matrix.combined, m, 64);; break; } } struct zSortVDest{ s16 sy; s16 sx; s32 invw; s16 yi; s16 xi; s16 wi; u8 fog; u8 cc; }; void ZSort_MultMPMTX( u32 _w0, u32 _w1 ) { unsigned i; struct zSortVDest v; int num = 1 + _SHIFTR(_w1, 24, 8); int src = -1024 + _SHIFTR(_w1, 12, 12); int dst = -1024 + _SHIFTR(_w1, 0, 12); s16 * saddr = (s16*)(gfx_info.DMEM+src); struct zSortVDest * daddr = (struct zSortVDest*)(gfx_info.DMEM+dst); int idx = 0; memset(&v, 0, sizeof(struct zSortVDest)); for (i = 0; i < num; ++i) { s16 sx = saddr[(idx++)^1]; s16 sy = saddr[(idx++)^1]; s16 sz = saddr[(idx++)^1]; f32 x = sx*gSP.matrix.combined[0][0] + sy*gSP.matrix.combined[1][0] + sz*gSP.matrix.combined[2][0] + gSP.matrix.combined[3][0]; f32 y = sx*gSP.matrix.combined[0][1] + sy*gSP.matrix.combined[1][1] + sz*gSP.matrix.combined[2][1] + gSP.matrix.combined[3][1]; f32 z = sx*gSP.matrix.combined[0][2] + sy*gSP.matrix.combined[1][2] + sz*gSP.matrix.combined[2][2] + gSP.matrix.combined[3][2]; f32 w = sx*gSP.matrix.combined[0][3] + sy*gSP.matrix.combined[1][3] + sz*gSP.matrix.combined[2][3] + gSP.matrix.combined[3][3]; v.sx = (s16)(GLN64zSortRdp.view_trans[0] + x / w * GLN64zSortRdp.view_scale[0]); v.sy = (s16)(GLN64zSortRdp.view_trans[1] + y / w * GLN64zSortRdp.view_scale[1]); v.xi = (s16)x; v.yi = (s16)y; v.wi = (s16)w; v.invw = Calc_invw((int)(w * 31.0)); if (w < 0.0f) v.fog = 0; else { int fog = (int)(z / w * gSP.fog.multiplier + gSP.fog.offset); if (fog > 255) fog = 255; v.fog = (fog >= 0) ? (u8)fog : 0; } v.cc = 0; if (x < -w) v.cc |= 0x10; if (x > w) v.cc |= 0x01; if (y < -w) v.cc |= 0x20; if (y > w) v.cc |= 0x02; if (w < 0.1f) v.cc |= 0x04; daddr[i] = v; } } void ZSort_LinkSubDL( u32 a , u32 b) { #ifdef DEBUG LOG(LOG_VERBOSE, "ZSort_LinkSubDL Ignored\n"); #endif } void ZSort_SetSubDL( u32 a, u32 b) { #ifdef DEBUG LOG(LOG_VERBOSE, "ZSort_SetSubDL Ignored\n"); #endif } void ZSort_WaitSignal( u32 a, u32 b) { #ifdef DEBUG LOG(LOG_VERBOSE, "ZSort_WaitSignal Ignored\n"); #endif } void ZSort_SendSignal( u32 a, u32 b) { #ifdef DEBUG LOG(LOG_VERBOSE, "ZSort_SendSignal Ignored\n"); #endif } static void ZSort_SetTexture(void) { gSP.texture.scales = 1.0f; gSP.texture.scalet = 1.0f; gSP.texture.level = 0; gSP.texture.on = 1; gSP.texture.tile = 0; gSPSetGeometryMode(0x0200); } void ZSort_MoveMem( u32 _w0, u32 _w1 ) { int idx = _w0 & 0x0E; int ofs = _SHIFTR(_w0, 6, 9)<<3; int len = 1 + (_SHIFTR(_w0, 15, 9)<<3); int flag = _w0 & 0x01; u32 addr = RSP_SegmentToPhysical(_w1); switch (idx) { case GZF_LOAD: //save/load if (flag == 0) { int dmem_addr = (idx<<3) + ofs; memcpy(gfx_info.DMEM + dmem_addr, gfx_info.RDRAM + addr, len); } else { int dmem_addr = (idx<<3) + ofs; memcpy(gfx_info.RDRAM + addr, gfx_info.DMEM + dmem_addr, len); } break; case GZM_MMTX: // model matrix RSP_LoadMatrix(gSP.matrix.modelView[gSP.matrix.modelViewi], addr); gSP.changed |= CHANGED_MATRIX; break; case GZM_PMTX: // projection matrix RSP_LoadMatrix(gSP.matrix.projection, addr); gSP.changed |= CHANGED_MATRIX; break; case GZM_MPMTX: // combined matrix RSP_LoadMatrix(gSP.matrix.combined, addr); gSP.changed &= ~CHANGED_MATRIX; break; case GZM_OTHERMODE: #ifdef DEBUG LOG(LOG_VERBOSE, "MoveMem Othermode Ignored\n"); #endif break; case GZM_VIEWPORT: // VIEWPORT { u32 a = addr >> 1; const f32 scale_x = _FIXED2FLOAT( *(s16*)&gfx_info.RDRAM[(a+0)^1], 2 ); const f32 scale_y = _FIXED2FLOAT( *(s16*)&gfx_info.RDRAM[(a+1)^1], 2 ); const f32 scale_z = _FIXED2FLOAT( *(s16*)&gfx_info.RDRAM[(a+2)^1], 10 ); gSP.fog.multiplier = ((s16*)gfx_info.RDRAM)[(a+3)^1]; const f32 trans_x = _FIXED2FLOAT( *(s16*)&gfx_info.RDRAM[(a+4)^1], 2 ); const f32 trans_y = _FIXED2FLOAT( *(s16*)&gfx_info.RDRAM[(a+5)^1], 2 ); const f32 trans_z = _FIXED2FLOAT( *(s16*)&gfx_info.RDRAM[(a+6)^1], 10 ); gSP.fog.offset = ((s16*)gfx_info.RDRAM)[(a+7)^1]; gSP.viewport.vscale[0] = scale_x; gSP.viewport.vscale[1] = scale_y; gSP.viewport.vscale[2] = scale_z; gSP.viewport.vtrans[0] = trans_x; gSP.viewport.vtrans[1] = trans_y; gSP.viewport.vtrans[2] = trans_z; gSP.viewport.x = gSP.viewport.vtrans[0] - gSP.viewport.vscale[0]; gSP.viewport.y = gSP.viewport.vtrans[1] - gSP.viewport.vscale[1]; gSP.viewport.width = gSP.viewport.vscale[0] * 2; gSP.viewport.height = gSP.viewport.vscale[1] * 2; gSP.viewport.nearz = gSP.viewport.vtrans[2] - gSP.viewport.vscale[2]; gSP.viewport.farz = (gSP.viewport.vtrans[2] + gSP.viewport.vscale[2]) ; GLN64zSortRdp.view_scale[0] = scale_x*4.0f; GLN64zSortRdp.view_scale[1] = scale_y*4.0f; GLN64zSortRdp.view_trans[0] = trans_x*4.0f; GLN64zSortRdp.view_trans[1] = trans_y*4.0f; gSP.changed |= CHANGED_VIEWPORT; ZSort_SetTexture(); } break; default: //LOG(LOG_ERROR, "ZSort_MoveMem UNKNOWN %d\n", idx); break; } } void SZort_SetScissor(u32 _w0, u32 _w1) { RDP_SetScissor(_w0, _w1); if ((gDP.scissor.lrx - gDP.scissor.ulx) > (GLN64zSortRdp.view_scale[0] - GLN64zSortRdp.view_trans[0])) { f32 w = (gDP.scissor.lrx - gDP.scissor.ulx) / 2.0f; f32 h = (gDP.scissor.lry - gDP.scissor.uly) / 2.0f; gSP.viewport.vscale[0] = w; gSP.viewport.vscale[1] = h; gSP.viewport.vtrans[0] = w; gSP.viewport.vtrans[1] = h; gSP.viewport.x = gSP.viewport.vtrans[0] - gSP.viewport.vscale[0]; gSP.viewport.y = gSP.viewport.vtrans[1] - gSP.viewport.vscale[1]; gSP.viewport.width = gSP.viewport.vscale[0] * 2; gSP.viewport.height = gSP.viewport.vscale[1] * 2; GLN64zSortRdp.view_scale[0] = w * 4.0f; GLN64zSortRdp.view_scale[1] = h * 4.0f; GLN64zSortRdp.view_trans[0] = w * 4.0f; GLN64zSortRdp.view_trans[1] = h * 4.0f; gSP.changed |= CHANGED_VIEWPORT; ZSort_SetTexture(); } } #define G_ZS_ZOBJ 0x80 #define G_ZS_RDPCMD 0x81 #define G_ZS_SETOTHERMODE_H 0xE3 #define G_ZS_SETOTHERMODE_L 0xE2 #define G_ZS_ENDDL 0xDF #define G_ZS_DL 0xDE #define G_ZS_MOVEMEM 0xDC #define G_ZS_MOVEWORD 0xDB #define G_ZS_SENDSIGNAL 0xDA #define G_ZS_WAITSIGNAL 0xD9 #define G_ZS_SETSUBDL 0xD8 #define G_ZS_LINKSUBDL 0xD7 #define G_ZS_MULT_MPMTX 0xD6 #define G_ZS_MTXCAT 0xD5 #define G_ZS_MTXTRNSP 0xD4 #define G_ZS_LIGHTING_L 0xD3 #define G_ZS_LIGHTING 0xD2 #define G_ZS_XFMLIGHT 0xD1 #define G_ZS_INTERPOLATE 0xD0 u32 G_ZOBJ, G_ZRDPCMD, G_ZSENDSIGNAL, G_ZWAITSIGNAL, G_ZSETSUBDL, G_ZLINKSUBDL, G_ZMULT_MPMTX, G_ZMTXCAT, G_ZMTXTRNSP; u32 G_ZLIGHTING_L, G_ZLIGHTING, G_ZXFMLIGHT, G_ZINTERPOLATE, G_ZSETSCISSOR; void ZSort_Init(void) { gSPSetupFunctions(); // Set GeometryMode flags GBI_InitFlags( F3D ); GBI.PCStackSize = 10; // GBI Command Command Value Command Function GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_RESERVED0, F3D_RESERVED0, F3D_Reserved0 ); GBI_SetGBI( G_RESERVED1, F3D_RESERVED1, F3D_Reserved1 ); GBI_SetGBI( G_DL, G_ZS_DL, F3D_DList ); GBI_SetGBI( G_RESERVED2, F3D_RESERVED2, F3D_Reserved2 ); GBI_SetGBI( G_RESERVED3, F3D_RESERVED3, F3D_Reserved3 ); GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3D_CullDL ); GBI_SetGBI( G_MOVEWORD, G_ZS_MOVEWORD, F3D_MoveWord ); GBI_SetGBI( G_TEXTURE, F3D_TEXTURE, F3D_Texture ); GBI_SetGBI( G_ZSETSCISSOR, G_SETSCISSOR, SZort_SetScissor ); GBI_SetGBI( G_SETOTHERMODE_H, G_ZS_SETOTHERMODE_H, F3D_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, G_ZS_SETOTHERMODE_L, F3D_SetOtherMode_L ); GBI_SetGBI( G_ENDDL, G_ZS_ENDDL, F3D_EndDL ); GBI_SetGBI( G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, F3D_SetGeometryMode ); GBI_SetGBI( G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE, F3D_ClearGeometryMode ); GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_RDPHALF_CONT, F3D_RDPHALF_CONT, F3D_RDPHalf_Cont ); GBI_SetGBI( G_ZOBJ, G_ZS_ZOBJ, ZSort_Obj ); GBI_SetGBI( G_ZRDPCMD, G_ZS_RDPCMD, ZSort_RDPCMD ); GBI_SetGBI( G_MOVEMEM, G_ZS_MOVEMEM, ZSort_MoveMem ); GBI_SetGBI( G_ZSENDSIGNAL, G_ZS_SENDSIGNAL, ZSort_SendSignal ); GBI_SetGBI( G_ZWAITSIGNAL, G_ZS_WAITSIGNAL, ZSort_WaitSignal ); GBI_SetGBI( G_ZSETSUBDL, G_ZS_SETSUBDL, ZSort_SetSubDL ); GBI_SetGBI( G_ZLINKSUBDL, G_ZS_LINKSUBDL, ZSort_LinkSubDL ); GBI_SetGBI( G_ZMULT_MPMTX, G_ZS_MULT_MPMTX, ZSort_MultMPMTX ); GBI_SetGBI( G_ZMTXCAT, G_ZS_MTXCAT, ZSort_MTXCAT ); GBI_SetGBI( G_ZMTXTRNSP, G_ZS_MTXTRNSP, ZSort_MTXRNSP ); GBI_SetGBI( G_ZLIGHTING_L, G_ZS_LIGHTING_L, ZSort_LightingL ); GBI_SetGBI( G_ZLIGHTING, G_ZS_LIGHTING, ZSort_Lighting ); GBI_SetGBI( G_ZXFMLIGHT, G_ZS_XFMLIGHT, ZSort_XFMLight ); GBI_SetGBI( G_ZINTERPOLATE, G_ZS_INTERPOLATE, ZSort_Interpolate ); } mupen64plus-video-gliden64/src/gDP.cpp000664 001750 001750 00000112675 12655644434 020620 0ustar00sergiosergio000000 000000 #include #include #include "GLideN64.h" #include "N64.h" #include "GBI.h" #include "RSP.h" #include "RDP.h" #include "gDP.h" #include "gSP.h" #include "Types.h" #include "Debug.h" #include "convert.h" #include "OpenGL.h" #include "CRC.h" #include "FrameBuffer.h" #include "DepthBuffer.h" #include "VI.h" #include "Config.h" #include "Combiner.h" using namespace std; gDPInfo gDP; void gDPSetOtherMode( u32 mode0, u32 mode1 ) { gDP.otherMode.h = mode0; gDP.otherMode.l = mode1; gDP.changed |= CHANGED_RENDERMODE | CHANGED_CYCLETYPE | CHANGED_ALPHACOMPARE; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetOtherMode( %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s, %s | %s | %s%s%s%s%s | %s | %s%s%s );\n", AlphaDitherText[gDP.otherMode.alphaDither], ColorDitherText[gDP.otherMode.colorDither], CombineKeyText[gDP.otherMode.combineKey], TextureConvertText[gDP.otherMode.textureConvert], TextureFilterText[gDP.otherMode.textureFilter], TextureLUTText[gDP.otherMode.textureLUT], TextureLODText[gDP.otherMode.textureLOD], TextureDetailText[gDP.otherMode.textureDetail], TexturePerspText[gDP.otherMode.texturePersp], CycleTypeText[gDP.otherMode.cycleType], PipelineModeText[gDP.otherMode.pipelineMode], AlphaCompareText[gDP.otherMode.alphaCompare], DepthSourceText[gDP.otherMode.depthSource], gDP.otherMode.AAEnable ? "AA_EN | " : "", gDP.otherMode.depthCompare ? "Z_CMP | " : "", gDP.otherMode.depthUpdate ? "Z_UPD | " : "", gDP.otherMode.imageRead ? "IM_RD | " : "", CvgDestText[gDP.otherMode.cvgDest], DepthModeText[gDP.otherMode.depthMode], gDP.otherMode.cvgXAlpha ? "CVG_X_ALPHA | " : "", gDP.otherMode.alphaCvgSel ? "ALPHA_CVG_SEL | " : "", gDP.otherMode.forceBlender ? "FORCE_BL" : "" ); #endif } void gDPSetPrimDepth( u16 z, u16 dz ) { if (gSP.viewport.vscale[2] == 0) gDP.primDepth.z = _FIXED2FLOAT(_SHIFTR(z, 0, 15), 15); else gDP.primDepth.z = min(1.0f, max(-1.0f, (_FIXED2FLOAT(_SHIFTR(z, 0, 15), 15) - gSP.viewport.vtrans[2]) / gSP.viewport.vscale[2])); gDP.primDepth.deltaZ = _FIXED2FLOAT(_SHIFTR(dz, 0, 15), 15); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetPrimDepth( %f, %f );\n", gDP.primDepth.z, gDP.primDepth.deltaZ); #endif } void gDPSetTexturePersp( u32 enable ) { gDP.otherMode.texturePersp = enable & 1; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPSetTexturePersp( %s );\n", TexturePerspText[gDP.otherMode.texturePersp] ); #endif } void gDPSetTextureLUT( u32 mode ) { gDP.otherMode.textureLUT = mode & 3; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPSetTextureLUT( %s );\n", TextureLUTText[gDP.otherMode.textureLUT] ); #endif } void gDPSetCombine( s32 muxs0, s32 muxs1 ) { gDP.combine.muxs0 = muxs0; gDP.combine.muxs1 = muxs1; gDP.changed |= CHANGED_COMBINE; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_COMBINE, "gDPSetCombine( %s, %s, %s, %s, %s, %s, %s, %s,\n", saRGBText[gDP.combine.saRGB0], sbRGBText[gDP.combine.sbRGB0], mRGBText[gDP.combine.mRGB0], aRGBText[gDP.combine.aRGB0], saAText[gDP.combine.saA0], sbAText[gDP.combine.sbA0], mAText[gDP.combine.mA0], aAText[gDP.combine.aA0] ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_COMBINE, " %s, %s, %s, %s, %s, %s, %s, %s );\n", saRGBText[gDP.combine.saRGB1], sbRGBText[gDP.combine.sbRGB1], mRGBText[gDP.combine.mRGB1], aRGBText[gDP.combine.aRGB1], saAText[gDP.combine.saA1], sbAText[gDP.combine.sbA1], mAText[gDP.combine.mA1], aAText[gDP.combine.aA1] ); #endif } void gDPSetColorImage( u32 format, u32 size, u32 width, u32 address ) { address = RSP_SegmentToPhysical( address ); if (gDP.colorImage.address != address || gDP.colorImage.width != width || gDP.colorImage.size != size) { u32 height = 1; if (width == VI.width) height = VI.height > 0 ? VI.height : gDP.scissor.lry; else if (!__RSP.bLLE && width == gDP.scissor.lrx && width == gSP.viewport.width) { height = max(gDP.scissor.lry, gSP.viewport.height); if (VI.height > 0) height = min(height, VI.height); } else if (width == gDP.scissor.lrx) height = gDP.scissor.lry; else if (width <= 64) height = width; else if (!__RSP.bLLE && gSP.viewport.height > 0) height = gSP.viewport.height; else height = gDP.scissor.lry; if (config.frameBufferEmulation.enable) // && address != gDP.depthImageAddress) { frameBufferList().saveBuffer(address, (u16)format, (u16)size, (u16)width, height, false); gDP.colorImage.height = 0; } else gDP.colorImage.height = height; } gDP.colorImage.format = format; gDP.colorImage.size = size; gDP.colorImage.width = width; gDP.colorImage.address = address; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetColorImage( %s, %s, %i, 0x%08X );\n", ImageFormatText[gDP.colorImage.format], ImageSizeText[gDP.colorImage.size], gDP.colorImage.width, gDP.colorImage.address ); #endif } void gDPSetTextureImage(u32 format, u32 size, u32 width, u32 address) { gDP.textureImage.format = format; gDP.textureImage.size = size; gDP.textureImage.width = width; gDP.textureImage.address = RSP_SegmentToPhysical(address); gDP.textureImage.bpl = gDP.textureImage.width << gDP.textureImage.size >> 1; if (gSP.DMAOffsets.tex_offset != 0) { if (format == G_IM_FMT_RGBA) { u16 * t = (u16*)(gfx_info.RDRAM + gSP.DMAOffsets.tex_offset); gSP.DMAOffsets.tex_shift = t[gSP.DMAOffsets.tex_count ^ 1]; gDP.textureImage.address += gSP.DMAOffsets.tex_shift; } else { gSP.DMAOffsets.tex_offset = 0; gSP.DMAOffsets.tex_shift = 0; gSP.DMAOffsets.tex_count = 0; } } #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPSetTextureImage( %s, %s, %i, 0x%08X );\n", ImageFormatText[gDP.textureImage.format], ImageSizeText[gDP.textureImage.size], gDP.textureImage.width, gDP.textureImage.address ); #endif } void gDPSetDepthImage( u32 address ) { address = RSP_SegmentToPhysical( address ); gDP.depthImageAddress = address; depthBufferList().saveBuffer(address); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetDepthImage( 0x%08X );\n", gDP.depthImageAddress ); #endif } void gDPSetEnvColor( u32 r, u32 g, u32 b, u32 a ) { gDP.envColor.r = r * 0.0039215689f; gDP.envColor.g = g * 0.0039215689f; gDP.envColor.b = b * 0.0039215689f; gDP.envColor.a = a * 0.0039215689f; CombinerInfo::get().updateEnvColor(); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_COMBINE, "gDPSetEnvColor( %i, %i, %i, %i );\n", r, g, b, a ); #endif } void gDPSetBlendColor( u32 r, u32 g, u32 b, u32 a ) { gDP.blendColor.r = r * 0.0039215689f; gDP.blendColor.g = g * 0.0039215689f; gDP.blendColor.b = b * 0.0039215689f; gDP.blendColor.a = a * 0.0039215689f; CombinerInfo::get().updateBlendColor(); gDP.changed |= CHANGED_BLENDCOLOR; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetBlendColor( %i, %i, %i, %i );\n", r, g, b, a ); #endif } void gDPSetFogColor( u32 r, u32 g, u32 b, u32 a ) { gDP.fogColor.r = r * 0.0039215689f; gDP.fogColor.g = g * 0.0039215689f; gDP.fogColor.b = b * 0.0039215689f; gDP.fogColor.a = a * 0.0039215689f; CombinerInfo::get().updateFogColor(); gDP.changed |= CHANGED_FOGCOLOR; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetFogColor( %i, %i, %i, %i );\n", r, g, b, a ); #endif } void gDPSetFillColor( u32 c ) { gDP.fillColor.color = c; gDP.fillColor.z = (f32)_SHIFTR( c, 2, 14 ); gDP.fillColor.dz = (f32)_SHIFTR( c, 0, 2 ); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetFillColor( 0x%08X );\n", c ); #endif } void gDPGetFillColor(f32 _fillColor[4]) { const u32 c = gDP.fillColor.color; if (gDP.colorImage.size < 3) { _fillColor[0] = _SHIFTR( c, 11, 5 ) * 0.032258064f; _fillColor[1] = _SHIFTR( c, 6, 5 ) * 0.032258064f; _fillColor[2] = _SHIFTR( c, 1, 5 ) * 0.032258064f; _fillColor[3] = (f32)_SHIFTR( c, 0, 1 ); } else { _fillColor[0] = _SHIFTR( c, 24, 8 ) * 0.0039215686f; _fillColor[1] = _SHIFTR( c, 16, 8 ) * 0.0039215686f; _fillColor[2] = _SHIFTR( c, 8, 8 ) * 0.0039215686f; _fillColor[3] = _SHIFTR( c, 0, 8 ) * 0.0039215686f; } } void gDPSetPrimColor( u32 m, u32 l, u32 r, u32 g, u32 b, u32 a ) { gDP.primColor.m = m * 0.0312500000; gDP.primColor.l = l * 0.0039215689f; gDP.primColor.r = r * 0.0039215689f; gDP.primColor.g = g * 0.0039215689f; gDP.primColor.b = b * 0.0039215689f; gDP.primColor.a = a * 0.0039215689f; CombinerInfo::get().updatePrimColor(); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_COMBINE, "gDPSetPrimColor( %i, %i, %i, %i, %i, %i );\n", m, l, r, g, b, a ); #endif } void gDPSetTile( u32 format, u32 size, u32 line, u32 tmem, u32 tile, u32 palette, u32 cmt, u32 cms, u32 maskt, u32 masks, u32 shiftt, u32 shifts ) { gDP.tiles[tile].format = format; gDP.tiles[tile].size = size; gDP.tiles[tile].line = line; gDP.tiles[tile].tmem = tmem; gDP.tiles[tile].palette = palette; gDP.tiles[tile].cmt = cmt; gDP.tiles[tile].cms = cms; gDP.tiles[tile].maskt = maskt; gDP.tiles[tile].masks = masks; gDP.tiles[tile].shiftt = shiftt; gDP.tiles[tile].shifts = shifts; if (!gDP.tiles[tile].masks) gDP.tiles[tile].clamps = 1; if (!gDP.tiles[tile].maskt) gDP.tiles[tile].clampt = 1; if (tile == gSP.texture.tile || tile == gSP.texture.tile + 1) { u32 nTile = 7; while(gDP.tiles[nTile].tmem != tmem && nTile > gSP.texture.tile + 1) --nTile; if (nTile > gSP.texture.tile + 1) { gDP.tiles[tile].textureMode = gDP.tiles[nTile].textureMode; gDP.tiles[tile].loadType = gDP.tiles[nTile].loadType; gDP.tiles[tile].frameBuffer = gDP.tiles[nTile].frameBuffer; gDP.tiles[tile].imageAddress = gDP.tiles[nTile].imageAddress; } } gDP.changed |= CHANGED_TILE; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPSetTile( %s, %s, %i, %i, %i, %i, %s%s, %s%s, %i, %i, %i, %i );\n", ImageFormatText[format], ImageSizeText[size], line, tmem, tile, palette, cmt & G_TX_MIRROR ? "G_TX_MIRROR" : "G_TX_NOMIRROR", cmt & G_TX_CLAMP ? " | G_TX_CLAMP" : "", cms & G_TX_MIRROR ? "G_TX_MIRROR" : "G_TX_NOMIRROR", cms & G_TX_CLAMP ? " | G_TX_CLAMP" : "", maskt, masks, shiftt, shifts ); #endif } void gDPSetTileSize( u32 tile, u32 uls, u32 ult, u32 lrs, u32 lrt ) { gDP.tiles[tile].uls = _SHIFTR( uls, 2, 10 ); gDP.tiles[tile].ult = _SHIFTR( ult, 2, 10 ); gDP.tiles[tile].lrs = _SHIFTR( lrs, 2, 10 ); gDP.tiles[tile].lrt = _SHIFTR( lrt, 2, 10 ); gDP.tiles[tile].fuls = _FIXED2FLOAT( uls, 2 ); gDP.tiles[tile].fult = _FIXED2FLOAT( ult, 2 ); gDP.tiles[tile].flrs = _FIXED2FLOAT( lrs, 2 ); gDP.tiles[tile].flrt = _FIXED2FLOAT( lrt, 2 ); gDP.changed |= CHANGED_TILE; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPSetTileSize( %i, %.2f, %.2f, %.2f, %.2f );\n", tile, gDP.tiles[tile].fuls, gDP.tiles[tile].fult, gDP.tiles[tile].flrs, gDP.tiles[tile].flrt ); #endif } static bool CheckForFrameBufferTexture(u32 _address, u32 _bytes) { gDP.loadTile->textureMode = TEXTUREMODE_NORMAL; gDP.loadTile->frameBuffer = NULL; gDP.changed |= CHANGED_TMEM; if (!config.frameBufferEmulation.enable) return false; FrameBufferList & fbList = frameBufferList(); FrameBuffer *pBuffer = fbList.findBuffer(_address); bool bRes = pBuffer != NULL; if (bRes) { if ((config.generalEmulation.hacks & hack_blurPauseScreen) != 0) { if (gDP.colorImage.address == gDP.depthImageAddress && pBuffer->m_copiedToRdram) { memcpy(gfx_info.RDRAM + gDP.depthImageAddress, gfx_info.RDRAM + pBuffer->m_startAddress, (pBuffer->m_width*pBuffer->m_height) << pBuffer->m_size >> 1); pBuffer->m_copiedToRdram = false; fbList.getCurrent()->m_isPauseScreen = true; } if (pBuffer->m_isPauseScreen) bRes = false; } if (pBuffer->m_cfb) { fbList.removeBuffer(pBuffer->m_startAddress); bRes = false; } if ((config.generalEmulation.hacks & hack_noDepthFrameBuffers) != 0 && pBuffer->m_isDepthBuffer) { fbList.removeBuffer(pBuffer->m_startAddress); bRes = false; } const u32 texEndAddress = _address + _bytes - 1; if (_address > pBuffer->m_startAddress && texEndAddress > (pBuffer->m_endAddress + (pBuffer->m_width << pBuffer->m_size >> 1))) { bRes = false; } if (bRes && gDP.loadTile->loadType == LOADTYPE_TILE && gDP.textureImage.width != pBuffer->m_width && gDP.textureImage.size != pBuffer->m_size) { bRes = false; } if (bRes) { bRes = pBuffer->isValid(); if (bRes) pBuffer->m_validityChecked = video().getBuffersSwapCount(); else fbList.removeBuffer(pBuffer->m_startAddress); } if (bRes) { pBuffer->m_pLoadTile = gDP.loadTile; gDP.loadTile->frameBuffer = pBuffer; gDP.loadTile->textureMode = TEXTUREMODE_FRAMEBUFFER; } } for (int nTile = gSP.texture.tile; nTile < 6; ++nTile) { if (gDP.tiles[nTile].tmem == gDP.loadTile->tmem) { gDPTile & curTile = gDP.tiles[nTile]; curTile.textureMode = gDP.loadTile->textureMode; curTile.loadType = gDP.loadTile->loadType; curTile.frameBuffer = gDP.loadTile->frameBuffer; curTile.imageAddress = gDP.loadTile->imageAddress; } } return bRes; } //**************************************************************** // LoadTile for 32bit RGBA texture // Based on sources of angrylion's software plugin. // void gDPLoadTile32b(u32 uls, u32 ult, u32 lrs, u32 lrt) { const u32 width = lrs - uls + 1; const u32 height = lrt - ult + 1; const u32 line = gDP.loadTile->line << 2; const u32 tbase = gDP.loadTile->tmem << 2; const u32 addr = gDP.textureImage.address >> 2; const u32 * src = (const u32*)gfx_info.RDRAM; u16 * tmem16 = (u16*)TMEM; u32 c, ptr, tline, s, xorval; for (u32 j = 0; j < height; ++j) { tline = tbase + line * j; s = ((j + ult) * gDP.textureImage.width) + uls; xorval = (j & 1) ? 3 : 1; for (u32 i = 0; i < width; ++i) { c = src[addr + s + i]; ptr = ((tline + i) ^ xorval) & 0x3ff; tmem16[ptr] = c >> 16; tmem16[ptr | 0x400] = c & 0xffff; } } } void gDPLoadTile(u32 tile, u32 uls, u32 ult, u32 lrs, u32 lrt) { gDPSetTileSize( tile, uls, ult, lrs, lrt ); gDP.loadTile = &gDP.tiles[tile]; gDP.loadTile->loadType = LOADTYPE_TILE; gDP.loadTile->imageAddress = gDP.textureImage.address; const u32 width = (gDP.loadTile->lrs - gDP.loadTile->uls + 1) & 0x03FF; u32 height = (gDP.loadTile->lrt - gDP.loadTile->ult + 1) & 0x03FF; gDPLoadTileInfo &info = gDP.loadInfo[gDP.loadTile->tmem]; info.texAddress = gDP.loadTile->imageAddress; info.uls = gDP.loadTile->uls; info.ult = gDP.loadTile->ult; info.width = gDP.loadTile->masks != 0 ? (u16)min(width, 1U<masks) : (u16)width; info.height = gDP.loadTile->maskt != 0 ? (u16)min(height, 1U<maskt) : (u16)height; info.texWidth = gDP.textureImage.width; info.size = gDP.textureImage.size; info.loadType = LOADTYPE_TILE; if (gDP.loadTile->line == 0) return; u32 address = gDP.textureImage.address + gDP.loadTile->ult * gDP.textureImage.bpl + (gDP.loadTile->uls << gDP.textureImage.size >> 1); if ((address + height * gDP.textureImage.bpl) > RDRAMSize) return; const u32 bpl = gDP.loadTile->line << 3; u32 bpl2 = bpl; if (gDP.loadTile->lrs > gDP.textureImage.width) bpl2 = (gDP.textureImage.width - gDP.loadTile->uls); u32 height2 = height; if (gDP.loadTile->lrt > gDP.scissor.lry) height2 = gDP.scissor.lry - gDP.loadTile->ult; if (CheckForFrameBufferTexture(address, bpl2*height2)) return; if (gDP.loadTile->size == G_IM_SIZ_32b) gDPLoadTile32b(gDP.loadTile->uls, gDP.loadTile->ult, gDP.loadTile->lrs, gDP.loadTile->lrt); else { u32 tmemAddr = gDP.loadTile->tmem; const u32 line = gDP.loadTile->line; for (u32 y = 0; y < height; ++y) { UnswapCopyWrap(gfx_info.RDRAM, address, (u8*)TMEM, tmemAddr << 3, 0xFFF, bpl); if (y & 1) DWordInterleaveWrap((u32*)TMEM, tmemAddr << 1, 0x3FF, line); address += gDP.textureImage.bpl; tmemAddr += line; } } #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPLoadTile( %i, %i, %i, %i, %i );\n", tile, gDP.loadTile->uls, gDP.loadTile->ult, gDP.loadTile->lrs, gDP.loadTile->lrt ); #endif } //**************************************************************** // LoadBlock for 32bit RGBA texture // Based on sources of angrylion's software plugin. // void gDPLoadBlock32(u32 uls,u32 lrs, u32 dxt) { const u32 * src = (const u32*)gfx_info.RDRAM; const u32 tb = gDP.loadTile->tmem << 2; const u32 line = gDP.loadTile->line << 2; u16 *tmem16 = (u16*)TMEM; u32 addr = gDP.loadTile->imageAddress >> 2; u32 width = (lrs - uls + 1) << 2; if (width == 4) // lr_s == 0, 1x1 texture width = 1; else if (width & 7) width = (width & (~7)) + 8; if (dxt != 0) { u32 j = 0; u32 t = 0; u32 oldt = 0; u32 ptr; u32 c = 0; for (u32 i = 0; i < width; i += 2) { oldt = t; t = ((j >> 11) & 1) ? 3 : 1; if (t != oldt) i += line; ptr = ((tb + i) ^ t) & 0x3ff; c = src[addr + i]; tmem16[ptr] = c >> 16; tmem16[ptr | 0x400] = c & 0xffff; ptr = ((tb + i + 1) ^ t) & 0x3ff; c = src[addr + i + 1]; tmem16[ptr] = c >> 16; tmem16[ptr | 0x400] = c & 0xffff; j += dxt; } } else { u32 c, ptr; for (u32 i = 0; i < width; i++) { ptr = ((tb + i) ^ 1) & 0x3ff; c = src[addr + i]; tmem16[ptr] = c >> 16; tmem16[ptr | 0x400] = c & 0xffff; } } } void gDPLoadBlock(u32 tile, u32 uls, u32 ult, u32 lrs, u32 dxt) { gDPSetTileSize( tile, uls, ult, lrs, dxt ); gDP.loadTile = &gDP.tiles[tile]; gDP.loadTile->loadType = LOADTYPE_BLOCK; if (gSP.DMAOffsets.tex_offset != 0) { if (gSP.DMAOffsets.tex_shift % (((lrs>>2) + 1) << 3)) { gDP.textureImage.address -= gSP.DMAOffsets.tex_shift; gSP.DMAOffsets.tex_offset = 0; gSP.DMAOffsets.tex_shift = 0; gSP.DMAOffsets.tex_count = 0; } else ++gSP.DMAOffsets.tex_count; } gDP.loadTile->imageAddress = gDP.textureImage.address; gDPLoadTileInfo &info = gDP.loadInfo[gDP.loadTile->tmem]; info.texAddress = gDP.loadTile->imageAddress; info.width = gDP.loadTile->lrs; info.dxt = dxt; info.size = gDP.textureImage.size; info.loadType = LOADTYPE_BLOCK; u32 bytes = (lrs - uls + 1) << gDP.loadTile->size >> 1; if ((bytes & 7) != 0) bytes = (bytes & (~7)) + 8; u32 address = gDP.textureImage.address + ult * gDP.textureImage.bpl + (uls << gDP.textureImage.size >> 1); if (bytes == 0 || (address + bytes) > RDRAMSize) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR | DEBUG_TEXTURE, "// Attempting to load texture block out of range\n" ); DebugMsg(DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPLoadBlock( %i, %i, %i, %i, %i );\n", tile, uls, ult, lrs, dxt ); #endif return; } gDP.loadTile->frameBuffer = NULL; CheckForFrameBufferTexture(address, bytes); // Load data to TMEM even if FB texture is found. See comment to texturedRectDepthBufferCopy if (gDP.loadTile->size == G_IM_SIZ_32b) gDPLoadBlock32(gDP.loadTile->uls, gDP.loadTile->lrs, dxt); else if (gDP.loadTile->format == G_IM_FMT_YUV) memcpy(TMEM, &gfx_info.RDRAM[address], bytes); // HACK! else { u32 tmemAddr = gDP.loadTile->tmem; if (dxt > 0) { u32 line = (2047 + dxt) / dxt; u32 bpl = line << 3; u32 height = bytes / bpl; for (u32 y = 0; y < height; ++y) { UnswapCopyWrap(gfx_info.RDRAM, address, (u8*)TMEM, tmemAddr << 3, 0xFFF, bpl); if (y & 1) DWordInterleaveWrap((u32*)TMEM, tmemAddr << 1, 0x3FF, line); address += bpl; tmemAddr += line; } } else UnswapCopyWrap(gfx_info.RDRAM, address, (u8*)TMEM, tmemAddr << 3, 0xFFF, bytes); } #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPLoadBlock( %i, %i, %i, %i, %i );\n", tile, uls, ult, lrs, dxt ); #endif } void gDPLoadTLUT( u32 tile, u32 uls, u32 ult, u32 lrs, u32 lrt ) { gDPSetTileSize( tile, uls, ult, lrs, lrt ); if (gDP.tiles[tile].tmem < 256) return; const u16 count = (u16)((gDP.tiles[tile].lrs - gDP.tiles[tile].uls + 1) * (gDP.tiles[tile].lrt - gDP.tiles[tile].ult + 1)); u32 address = gDP.textureImage.address + gDP.tiles[tile].ult * gDP.textureImage.bpl + (gDP.tiles[tile].uls << gDP.textureImage.size >> 1); u16 pal = (u16)((gDP.tiles[tile].tmem - 256) >> 4); u16 *dest = (u16*)&TMEM[gDP.tiles[tile].tmem]; int i = 0; while (i < count) { for (u16 j = 0; (j < 16) && (i < count); ++j, ++i) { *dest = swapword(*(u16*)(gfx_info.RDRAM + (address ^ 2))); address += 2; dest += 4; } gDP.paletteCRC16[pal] = CRC_CalculatePalette(0xFFFFFFFF, &TMEM[256 + (pal << 4)], 16); ++pal; } gDP.paletteCRC256 = CRC_Calculate(0xFFFFFFFF, gDP.paletteCRC16, 64); if (TFH.isInited()) { const u16 start = gDP.tiles[tile].tmem - 256; // starting location in the palettes u16 *spal = (u16*)(gfx_info.RDRAM + gDP.textureImage.address); memcpy((u8*)(gDP.TexFilterPalette + start), spal, count<<1); } gDP.changed |= CHANGED_TMEM; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPLoadTLUT( %i, %i, %i, %i, %i );\n", tile, gDP.tiles[tile].uls, gDP.tiles[tile].ult, gDP.tiles[tile].lrs, gDP.tiles[tile].lrt ); #endif } void gDPSetScissor( u32 mode, f32 ulx, f32 uly, f32 lrx, f32 lry ) { gDP.scissor.mode = mode; gDP.scissor.ulx = ulx; gDP.scissor.uly = uly; gDP.scissor.lrx = lrx; gDP.scissor.lry = lry; gDP.changed |= CHANGED_SCISSOR; frameBufferList().correctHeight(); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_IGNORED, "gDPSetScissor( %s, %.2f, %.2f, %.2f, %.2f );\n", ScissorModeText[gDP.scissor.mode], gDP.scissor.ulx, gDP.scissor.uly, gDP.scissor.lrx, gDP.scissor.lry ); #endif } const bool g_bDepthClearOnly = false; void gDPFillRDRAM(u32 address, s32 ulx, s32 uly, s32 lrx, s32 lry, u32 width, u32 size, u32 color, bool scissor) { if (g_bDepthClearOnly && color != DepthClearColor) return; FrameBuffer * pCurrentBuffer = frameBufferList().getCurrent(); if (pCurrentBuffer != NULL) { pCurrentBuffer->m_cleared = true; pCurrentBuffer->m_fillcolor = color; } if (scissor) { ulx = min(max((float)ulx, gDP.scissor.ulx), gDP.scissor.lrx); lrx = min(max((float)lrx, gDP.scissor.ulx), gDP.scissor.lrx); uly = min(max((float)uly, gDP.scissor.uly), gDP.scissor.lry); lry = min(max((float)lry, gDP.scissor.uly), gDP.scissor.lry); } const u32 stride = width << size >> 1; const u32 lowerBound = address + lry*stride; if (lowerBound > RDRAMSize) lry -= (lowerBound - RDRAMSize) / stride; u32 ci_width_in_dwords = width >> (3 - size); ulx >>= (3 - size); lrx >>= (3 - size); u32 * dst = (u32*)(gfx_info.RDRAM + address); dst += uly * ci_width_in_dwords; for (u32 y = uly; y < lry; ++y) { for (u32 x = ulx; x < lrx; ++x) dst[x] = color; dst += ci_width_in_dwords; } } void gDPFillRectangle( s32 ulx, s32 uly, s32 lrx, s32 lry ) { OGLRender & render = video().getRender(); if (gDP.otherMode.cycleType == G_CYC_FILL) { ++lrx; ++lry; } else if (lry == uly) ++lry; if (gDP.depthImageAddress == gDP.colorImage.address) { // Game may use depth texture as auxilary color texture. Example: Mario Tennis // If color is not depth clear color, that is most likely the case if (gDP.fillColor.color == DepthClearColor) { gDPFillRDRAM(gDP.colorImage.address, ulx, uly, lrx, lry, gDP.colorImage.width, gDP.colorImage.size, gDP.fillColor.color); render.clearDepthBuffer(uly, lry); return; } } else if (gDP.fillColor.color == DepthClearColor && gDP.otherMode.cycleType == G_CYC_FILL) { depthBufferList().saveBuffer(gDP.colorImage.address); gDPFillRDRAM(gDP.colorImage.address, ulx, uly, lrx, lry, gDP.colorImage.width, gDP.colorImage.size, gDP.fillColor.color); render.clearDepthBuffer(uly, lry); return; } frameBufferList().setBufferChanged(); f32 fillColor[4]; gDPGetFillColor(fillColor); if (gDP.otherMode.cycleType == G_CYC_FILL) { if ((ulx == 0) && (uly == 0) && (lrx == gDP.scissor.lrx) && (lry == gDP.scissor.lry)) { gDPFillRDRAM(gDP.colorImage.address, ulx, uly, lrx, lry, gDP.colorImage.width, gDP.colorImage.size, gDP.fillColor.color); if ((*gfx_info.VI_STATUS & 8) != 0) { fillColor[0] = sqrtf(fillColor[0]); fillColor[1] = sqrtf(fillColor[1]); fillColor[2] = sqrtf(fillColor[2]); } render.clearColorBuffer(fillColor); return; } } render.drawRect(ulx, uly, lrx, lry, fillColor); if (gDP.otherMode.cycleType == G_CYC_FILL) { if (lry > (u32)gDP.scissor.lry) gDP.colorImage.height = (u32)max(gDP.colorImage.height, (u32)gDP.scissor.lry); else gDP.colorImage.height = (u32)max((s32)gDP.colorImage.height, lry); } else gDP.colorImage.height = max( gDP.colorImage.height, (u32)gDP.scissor.lry ); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPFillRectangle( %i, %i, %i, %i );\n", ulx, uly, lrx, lry ); #endif } void gDPSetConvert( s32 k0, s32 k1, s32 k2, s32 k3, s32 k4, s32 k5 ) { // angrylion's macro #define SRA(exp, sa) ((signed)(exp) >> (sa)) #define SIGN(i, b) SRA((i) << (32 - (b)), (32 - (b))) gDP.convert.k0 = SIGN(k0, 9); gDP.convert.k1 = SIGN(k1, 9); gDP.convert.k2 = SIGN(k2, 9); gDP.convert.k3 = SIGN(k3, 9); gDP.convert.k4 = SIGN(k4, 9); gDP.convert.k5 = SIGN(k5, 9); CombinerInfo::get().updateConvertColor(); } void gDPSetKeyR( u32 cR, u32 sR, u32 wR ) { gDP.key.center.r = cR * 0.0039215689f; gDP.key.scale.r = sR * 0.0039215689f; gDP.key.width.r = wR * 0.0039215689f; } void gDPSetKeyGB(u32 cG, u32 sG, u32 wG, u32 cB, u32 sB, u32 wB ) { gDP.key.center.g = cG * 0.0039215689f; gDP.key.scale.g = sG * 0.0039215689f; gDP.key.width.g = wG * 0.0039215689f; gDP.key.center.b = cB * 0.0039215689f; gDP.key.scale.b = sB * 0.0039215689f; gDP.key.width.b = wB * 0.0039215689f; CombinerInfo::get().updateKeyColor(); } void gDPTextureRectangle( f32 ulx, f32 uly, f32 lrx, f32 lry, s32 tile, f32 s, f32 t, f32 dsdx, f32 dtdy ) { if (gDP.otherMode.cycleType == G_CYC_COPY) { dsdx = 1.0f; lrx += 1.0f; lry += 1.0f; } lry = max(lry, uly + 1.0f); gDPTile *textureTileOrg[2]; textureTileOrg[0] = gSP.textureTile[0]; textureTileOrg[1] = gSP.textureTile[1]; gSP.textureTile[0] = &gDP.tiles[tile]; gSP.textureTile[1] = &gDP.tiles[(tile + 1) & 7]; // HACK ALERT! if ((int(s) == 512) && (gDP.colorImage.width < 512)) s = 0.0f; f32 lrs, lrt; if (__RSP.cmd == G_TEXRECTFLIP) { lrs = s + (lry - uly - 1) * dsdx; lrt = t + (lrx - ulx - 1) * dtdy; } else { lrs = s + (lrx - ulx - 1) * dsdx; lrt = t + (lry - uly - 1) * dtdy; } OGLRender::TexturedRectParams params(ulx, uly, lrx, lry, s, t, lrs, lrt, (__RSP.cmd == G_TEXRECTFLIP)); video().getRender().drawTexturedRect(params); gSP.textureTile[0] = textureTileOrg[0]; gSP.textureTile[1] = textureTileOrg[1]; frameBufferList().setBufferChanged(); if (gDP.colorImage.width < 64) gDP.colorImage.height = (u32)max( (f32)gDP.colorImage.height, lry ); else gDP.colorImage.height = max( gDP.colorImage.height, (u32)gDP.scissor.lry ); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPTextureRectangle( %f, %f, %f, %f, %i, %i, %f, %f, %f, %f );\n", ulx, uly, lrx, lry, tile, s, t, dsdx, dtdy ); #endif } void gDPTextureRectangleFlip( f32 ulx, f32 uly, f32 lrx, f32 lry, s32 tile, f32 s, f32 t, f32 dsdx, f32 dtdy ) { gDPTextureRectangle( ulx, uly, lrx, lry, tile, s, t, dsdx, dtdy ); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPTextureRectangleFlip( %f, %f, %f, %f, %i, %f, %f, %f, %f);\n", ulx, uly, lrx, lry, tile, s, t, dsdx, dtdy ); #endif } void gDPFullSync() { if (config.frameBufferEmulation.copyAuxToRDRAM != 0) { frameBufferList().copyAux(); frameBufferList().removeAux(); } const bool sync = config.frameBufferEmulation.copyToRDRAM == Config::ctSync; if (config.frameBufferEmulation.copyToRDRAM != Config::ctDisable) FrameBuffer_CopyToRDRAM(gDP.colorImage.address, sync); if (__RSP.bLLE) { if (config.frameBufferEmulation.copyDepthToRDRAM != Config::ctDisable) FrameBuffer_CopyDepthBuffer(gDP.colorImage.address); } *gfx_info.MI_INTR_REG |= MI_INTR_DP; if (gfx_info.CheckInterrupts) gfx_info.CheckInterrupts(); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPFullSync();\n" ); #endif } void gDPTileSync() { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_IGNORED | DEBUG_TEXTURE, "gDPTileSync();\n" ); #endif } void gDPPipeSync() { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_IGNORED, "gDPPipeSync();\n" ); #endif } void gDPLoadSync() { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_IGNORED, "gDPLoadSync();\n" ); #endif } void gDPNoOp() { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_IGNORED, "gDPNoOp();\n" ); #endif } /******************************************* * Low level triangle * ******************************************* * based on sources of ziggy's z64 * *******************************************/ void gDPLLETriangle(u32 _w1, u32 _w2, int _shade, int _texture, int _zbuffer, u32 * _pRdpCmd) { const u32 tile = _SHIFTR(_w1, 16, 3); gDPTile *textureTileOrg[2]; textureTileOrg[0] = gSP.textureTile[0]; textureTileOrg[1] = gSP.textureTile[1]; gSP.textureTile[0] = &gDP.tiles[tile]; gSP.textureTile[1] = &gDP.tiles[(tile + 1) & 7]; int j; int xleft, xright, xleft_inc, xright_inc; int r, g, b, a, z, s, t, w; int drdx = 0, dgdx = 0, dbdx = 0, dadx = 0, dzdx = 0, dsdx = 0, dtdx = 0, dwdx = 0; int drde = 0, dgde = 0, dbde = 0, dade = 0, dzde = 0, dsde = 0, dtde = 0, dwde = 0; int flip = (_w1 & 0x800000) ? 1 : 0; s32 yl, ym, yh; s32 xl, xm, xh; s32 dxldy, dxhdy, dxmdy; u32 w3, w4, w5, w6, w7, w8; u32 * shade_base = _pRdpCmd + 8; u32 * texture_base = _pRdpCmd + 8; u32 * zbuffer_base = _pRdpCmd + 8; if (_shade != 0) { texture_base += 16; zbuffer_base += 16; } if (_texture != 0) { zbuffer_base += 16; } w3 = _pRdpCmd[2]; w4 = _pRdpCmd[3]; w5 = _pRdpCmd[4]; w6 = _pRdpCmd[5]; w7 = _pRdpCmd[6]; w8 = _pRdpCmd[7]; yl = (_w1 & 0x3fff); ym = ((_w2 >> 16) & 0x3fff); yh = ((_w2 >> 0) & 0x3fff); xl = (s32)(w3); xh = (s32)(w5); xm = (s32)(w7); dxldy = (s32)(w4); dxhdy = (s32)(w6); dxmdy = (s32)(w8); if (yl & (0x800<<2)) yl |= 0xfffff000<<2; if (ym & (0x800<<2)) ym |= 0xfffff000<<2; if (yh & (0x800<<2)) yh |= 0xfffff000<<2; yh &= ~3; r = 0xff; g = 0xff; b = 0xff; a = 0xff; z = 0xffff0000; s = 0; t = 0; w = 0x30000; if (_shade != 0) { r = (shade_base[0] & 0xffff0000) | ((shade_base[+4 ] >> 16) & 0x0000ffff); g = ((shade_base[0 ] << 16) & 0xffff0000) | (shade_base[4 ] & 0x0000ffff); b = (shade_base[1 ] & 0xffff0000) | ((shade_base[5 ] >> 16) & 0x0000ffff); a = ((shade_base[1 ] << 16) & 0xffff0000) | (shade_base[5 ] & 0x0000ffff); drdx = (shade_base[2 ] & 0xffff0000) | ((shade_base[6 ] >> 16) & 0x0000ffff); dgdx = ((shade_base[2 ] << 16) & 0xffff0000) | (shade_base[6 ] & 0x0000ffff); dbdx = (shade_base[3 ] & 0xffff0000) | ((shade_base[7 ] >> 16) & 0x0000ffff); dadx = ((shade_base[3 ] << 16) & 0xffff0000) | (shade_base[7 ] & 0x0000ffff); drde = (shade_base[8 ] & 0xffff0000) | ((shade_base[12] >> 16) & 0x0000ffff); dgde = ((shade_base[8 ] << 16) & 0xffff0000) | (shade_base[12] & 0x0000ffff); dbde = (shade_base[9 ] & 0xffff0000) | ((shade_base[13] >> 16) & 0x0000ffff); dade = ((shade_base[9 ] << 16) & 0xffff0000) | (shade_base[13] & 0x0000ffff); } if (_texture != 0) { s = (texture_base[0 ] & 0xffff0000) | ((texture_base[4 ] >> 16) & 0x0000ffff); t = ((texture_base[0 ] << 16) & 0xffff0000) | (texture_base[4 ] & 0x0000ffff); w = (texture_base[1 ] & 0xffff0000) | ((texture_base[5 ] >> 16) & 0x0000ffff); // w = abs(w); dsdx = (texture_base[2 ] & 0xffff0000) | ((texture_base[6 ] >> 16) & 0x0000ffff); dtdx = ((texture_base[2 ] << 16) & 0xffff0000) | (texture_base[6 ] & 0x0000ffff); dwdx = (texture_base[3 ] & 0xffff0000) | ((texture_base[7 ] >> 16) & 0x0000ffff); dsde = (texture_base[8 ] & 0xffff0000) | ((texture_base[12] >> 16) & 0x0000ffff); dtde = ((texture_base[8 ] << 16) & 0xffff0000) | (texture_base[12] & 0x0000ffff); dwde = (texture_base[9 ] & 0xffff0000) | ((texture_base[13] >> 16) & 0x0000ffff); } if (_zbuffer != 0) { z = zbuffer_base[0]; dzdx = zbuffer_base[1]; dzde = zbuffer_base[2]; } xh <<= 2; xm <<= 2; xl <<= 2; r <<= 2; g <<= 2; b <<= 2; a <<= 2; dsde >>= 2; dtde >>= 2; dsdx >>= 2; dtdx >>= 2; dzdx >>= 2; dzde >>= 2; dwdx >>= 2; dwde >>= 2; #define XSCALE(x) (float(x)/(1<<18)) #define YSCALE(y) (float(y)/(1<<2)) #define ZSCALE(z) ((gDP.otherMode.depthSource == G_ZS_PRIM)? gDP.primDepth.z : float(u32(z))/0xffff0000) #define PERSP_EN (gDP.otherMode.texturePersp != 0) #define WSCALE(z) 1.0f/(PERSP_EN? (float(u32(z) + 0x10000)/0xffff0000) : 1.0f) #define CSCALE(c) ((((c)>0x3ff0000? 0x3ff0000:((c)<0? 0 : (c)))>>18)*0.0039215689f) #define _PERSP(w) ( w ) #define PERSP(s, w) ( ((s64)(s) << 20) / (_PERSP(w)? _PERSP(w):1) ) #define SSCALE(s, _w) (PERSP_EN? float(PERSP(s, _w))/(1 << 10) : float(s)/(1<<21)) #define TSCALE(s, w) (PERSP_EN? float(PERSP(s, w))/(1 << 10) : float(s)/(1<<21)) OGLRender & render = video().getRender(); SPVertex * vtx0 = &render.getVertex(0); SPVertex * vtx = vtx0; xleft = xm; xright = xh; xleft_inc = dxmdy; xright_inc = dxhdy; while (yh xright-0x10000))) { xleft += xleft_inc; xright += xright_inc; s += dsde; t += dtde; w += dwde; r += drde; g += dgde; b += dbde; a += dade; z += dzde; yh++; } j = ym-yh; if (j > 0) { int dx = (xleft-xright)>>16; if ((!flip && xleft < xright) || (flip/* && xleft > xright*/)) { if (_shade != 0) { vtx->r = CSCALE(r+drdx*dx); vtx->g = CSCALE(g+dgdx*dx); vtx->b = CSCALE(b+dbdx*dx); vtx->a = CSCALE(a+dadx*dx); } if (_texture != 0) { vtx->s = SSCALE(s+dsdx*dx, w+dwdx*dx); vtx->t = TSCALE(t+dtdx*dx, w+dwdx*dx); } vtx->x = XSCALE(xleft); vtx->y = YSCALE(yh); vtx->z = ZSCALE(z+dzdx*dx); vtx->w = WSCALE(w+dwdx*dx); ++vtx; } if ((!flip/* && xleft < xright*/) || (flip && xleft > xright)) { if (_shade != 0) { vtx->r = CSCALE(r); vtx->g = CSCALE(g); vtx->b = CSCALE(b); vtx->a = CSCALE(a); } if (_texture != 0) { vtx->s = SSCALE(s, w); vtx->t = TSCALE(t, w); } vtx->x = XSCALE(xright); vtx->y = YSCALE(yh); vtx->z = ZSCALE(z); vtx->w = WSCALE(w); ++vtx; } xleft += xleft_inc*j; xright += xright_inc*j; s += dsde*j; t += dtde*j; if (w + dwde*j) w += dwde*j; else w += dwde*(j-1); r += drde*j; g += dgde*j; b += dbde*j; a += dade*j; z += dzde*j; // render ... } if (xl != xh) xleft = xl; //if (yl-ym > 0) { int dx = (xleft-xright)>>16; if ((!flip && xleft <= xright) || (flip/* && xleft >= xright*/)) { if (_shade != 0) { vtx->r = CSCALE(r+drdx*dx); vtx->g = CSCALE(g+dgdx*dx); vtx->b = CSCALE(b+dbdx*dx); vtx->a = CSCALE(a+dadx*dx); } if (_texture != 0) { vtx->s = SSCALE(s+dsdx*dx, w+dwdx*dx); vtx->t = TSCALE(t+dtdx*dx, w+dwdx*dx); } vtx->x = XSCALE(xleft); vtx->y = YSCALE(ym); vtx->z = ZSCALE(z+dzdx*dx); vtx->w = WSCALE(w+dwdx*dx); ++vtx; } if ((!flip/* && xleft <= xright*/) || (flip && xleft >= xright)) { if (_shade != 0) { vtx->r = CSCALE(r); vtx->g = CSCALE(g); vtx->b = CSCALE(b); vtx->a = CSCALE(a); } if (_texture != 0) { vtx->s = SSCALE(s, w); vtx->t = TSCALE(t, w); } vtx->x = XSCALE(xright); vtx->y = YSCALE(ym); vtx->z = ZSCALE(z); vtx->w = WSCALE(w); ++vtx; } } xleft_inc = dxldy; xright_inc = dxhdy; j = yl-ym; //j--; // ? xleft += xleft_inc*j; xright += xright_inc*j; s += dsde*j; t += dtde*j; w += dwde*j; r += drde*j; g += dgde*j; b += dbde*j; a += dade*j; z += dzde*j; while (yl>ym && !((!flip && xleft < xright+0x10000) || (flip && xleft > xright-0x10000))) { xleft -= xleft_inc; xright -= xright_inc; s -= dsde; t -= dtde; w -= dwde; r -= drde; g -= dgde; b -= dbde; a -= dade; z -= dzde; --j; --yl; } // render ... if (j >= 0) { int dx = (xleft-xright)>>16; if ((!flip && xleft <= xright) || (flip/* && xleft >= xright*/)) { if (_shade != 0) { vtx->r = CSCALE(r+drdx*dx); vtx->g = CSCALE(g+dgdx*dx); vtx->b = CSCALE(b+dbdx*dx); vtx->a = CSCALE(a+dadx*dx); } if (_texture != 0) { vtx->s = SSCALE(s+dsdx*dx, w+dwdx*dx); vtx->t = TSCALE(t+dtdx*dx, w+dwdx*dx); } vtx->x = XSCALE(xleft); vtx->y = YSCALE(yl); vtx->z = ZSCALE(z+dzdx*dx); vtx->w = WSCALE(w+dwdx*dx); ++vtx; } if ((!flip/* && xleft <= xright*/) || (flip && xleft >= xright)) { if (_shade != 0) { vtx->r = CSCALE(r); vtx->g = CSCALE(g); vtx->b = CSCALE(b); vtx->a = CSCALE(a); } if (_texture != 0) { vtx->s = SSCALE(s, w); vtx->t = TSCALE(t, w); } vtx->x = XSCALE(xright); vtx->y = YSCALE(yl); vtx->z = ZSCALE(z); vtx->w = WSCALE(w); ++vtx; } } if (_texture != 0) gDP.changed |= CHANGED_TILE; if (_zbuffer != 0) gSP.geometryMode |= G_ZBUFFER; render.drawLLETriangle(vtx - vtx0); gSP.textureTile[0] = textureTileOrg[0]; gSP.textureTile[1] = textureTileOrg[1]; } static void gDPTriangle(u32 _w1, u32 _w2, int shade, int texture, int zbuffer) { gDPLLETriangle(_w1, _w2, shade, texture, zbuffer, __RDP.cmd_data + __RDP.cmd_cur); } void gDPTriFill(u32 w0, u32 w1) { gDPTriangle(w0, w1, 0, 0, 0); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "trifill\n"); } void gDPTriShade(u32 w0, u32 w1) { gDPTriangle(w0, w1, 1, 0, 0); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "trishade\n"); } void gDPTriTxtr(u32 w0, u32 w1) { gDPTriangle(w0, w1, 0, 1, 0); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "tritxtr\n"); } void gDPTriShadeTxtr(u32 w0, u32 w1) { gDPTriangle(w0, w1, 1, 1, 0); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "trishadetxtr\n"); } void gDPTriFillZ(u32 w0, u32 w1) { gDPTriangle(w0, w1, 0, 0, 1); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "trifillz\n"); } void gDPTriShadeZ(u32 w0, u32 w1) { gDPTriangle(w0, w1, 1, 0, 1); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "trishadez\n"); } void gDPTriTxtrZ(u32 w0, u32 w1) { gDPTriangle(w0, w1, 0, 1, 1); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "tritxtrz\n"); } void gDPTriShadeTxtrZ(u32 w0, u32 w1) { gDPTriangle(w0, w1, 1, 1, 1); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "trishadetxtrz\n"); } glide2gl/src/Glide64/ucode08.h000664 001750 001750 00000030772 12655644434 017026 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** // // January 2004 Created by Gonetz (Gonetz@ngs.ru) // //**************************************************************** uint32_t uc8_normale_addr = 0; float uc8_coord_mod[16]; static void uc8_vertex(uint32_t w0, uint32_t w1) { uint32_t i; uint32_t addr = RSP_SegmentToPhysical(w1); int32_t n = (w0 >> 12) & 0xFF; int32_t v0 = ((w0 >> 1) & 0x7F) - n; void *membase_ptr = (void*)(gfx_info.RDRAM + addr); uint32_t iter = 16; if (v0 < 0) return; pre_update(); for (i=0; i < (n * iter); i+= iter) { VERTEX *vert = (VERTEX*)&rdp.vtx[v0 + (i / iter)]; int16_t *rdram = (int16_t*)membase_ptr; uint8_t *rdram_u8 = (uint8_t*)membase_ptr; uint8_t *color = (uint8_t*)(rdram_u8 + 12); float x = (float)rdram[1]; float y = (float)rdram[0]; float z = (float)rdram[3]; vert->flags = (uint16_t)rdram[2]; vert->ov = (float)rdram[4]; vert->ou = (float)rdram[5]; vert->uv_scaled = 0; vert->a = color[0]; vert->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0]; vert->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1]; vert->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2]; vert->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3]; vert->uv_calculated = 0xFFFFFFFF; vert->screen_translated = 0; vert->shade_mod = 0; if (fabs(vert->w) < 0.001) vert->w = 0.001f; vert->oow = 1.0f / vert->w; vert->x_w = vert->x * vert->oow; vert->y_w = vert->y * vert->oow; vert->z_w = vert->z * vert->oow; vert->scr_off = 0; if (vert->x < -vert->w) vert->scr_off |= 1; if (vert->x > vert->w) vert->scr_off |= 2; if (vert->y < -vert->w) vert->scr_off |= 4; if (vert->y > vert->w) vert->scr_off |= 8; if (vert->w < 0.1f) vert->scr_off |= 16; vert->r = color[3]; vert->g = color[2]; vert->b = color[1]; if ((rdp.geom_mode & G_LIGHTING)) { uint32_t shift, l; float light_intensity, color[3]; shift = v0 << 1; vert->vec[0] = ((int8_t*)gfx_info.RDRAM)[(uc8_normale_addr + (i>>3) + shift + 0)^3]; vert->vec[1] = ((int8_t*)gfx_info.RDRAM)[(uc8_normale_addr + (i>>3) + shift + 1)^3]; vert->vec[2] = (int8_t)(vert->flags & 0xff); if (rdp.geom_mode & G_TEXTURE_GEN_LINEAR) calc_linear (vert); else if (rdp.geom_mode & G_TEXTURE_GEN) calc_sphere (vert); color[0] = rdp.light[rdp.num_lights].col[0]; color[1] = rdp.light[rdp.num_lights].col[1]; color[2] = rdp.light[rdp.num_lights].col[2]; light_intensity = 0.0f; if (rdp.geom_mode & 0x00400000) { NormalizeVector (vert->vec); for (l = 0; l < rdp.num_lights-1; l++) { if (!rdp.light[l].nonblack) continue; light_intensity = DotProduct (rdp.light_vector[l], vert->vec); FRDP("light %d, intensity : %f\n", l, light_intensity); if (light_intensity < 0.0f) continue; //* if (rdp.light[l].ca > 0.0f) { float vx = (vert->x + uc8_coord_mod[8])*uc8_coord_mod[12] - rdp.light[l].x; float vy = (vert->y + uc8_coord_mod[9])*uc8_coord_mod[13] - rdp.light[l].y; float vz = (vert->z + uc8_coord_mod[10])*uc8_coord_mod[14] - rdp.light[l].z; float vw = (vert->w + uc8_coord_mod[11])*uc8_coord_mod[15] - rdp.light[l].w; float len = (vx*vx+vy*vy+vz*vz+vw*vw)/65536.0f; float p_i = rdp.light[l].ca / len; if (p_i > 1.0f) p_i = 1.0f; light_intensity *= p_i; } //*/ color[0] += rdp.light[l].col[0] * light_intensity; color[1] += rdp.light[l].col[1] * light_intensity; color[2] += rdp.light[l].col[2] * light_intensity; } light_intensity = DotProduct (rdp.light_vector[l], vert->vec); if (light_intensity > 0.0f) { color[0] += rdp.light[l].col[0] * light_intensity; color[1] += rdp.light[l].col[1] * light_intensity; color[2] += rdp.light[l].col[2] * light_intensity; } } else { for (l = 0; l < rdp.num_lights; l++) { if (rdp.light[l].nonblack && rdp.light[l].nonzero) { float vx = (vert->x + uc8_coord_mod[8])*uc8_coord_mod[12] - rdp.light[l].x; float vy = (vert->y + uc8_coord_mod[9])*uc8_coord_mod[13] - rdp.light[l].y; float vz = (vert->z + uc8_coord_mod[10])*uc8_coord_mod[14] - rdp.light[l].z; float vw = (vert->w + uc8_coord_mod[11])*uc8_coord_mod[15] - rdp.light[l].w; float len = (vx*vx+vy*vy+vz*vz+vw*vw)/65536.0f; light_intensity = rdp.light[l].ca / len; if (light_intensity > 1.0f) light_intensity = 1.0f; color[0] += rdp.light[l].col[0] * light_intensity; color[1] += rdp.light[l].col[1] * light_intensity; color[2] += rdp.light[l].col[2] * light_intensity; } } } if (color[0] > 1.0f) color[0] = 1.0f; if (color[1] > 1.0f) color[1] = 1.0f; if (color[2] > 1.0f) color[2] = 1.0f; vert->r = (uint8_t)(((float)vert->r)*color[0]); vert->g = (uint8_t)(((float)vert->g)*color[1]); vert->b = (uint8_t)(((float)vert->b)*color[2]); } membase_ptr = (char*)membase_ptr + iter; } } static void uc8_moveword(uint32_t w0, uint32_t w1) { int k; uint8_t index = (uint8_t)((w0 >> 16) & 0xFF); uint16_t offset = (uint16_t)(w0 & 0xFFFF); switch (index) { // NOTE: right now it's assuming that it sets the integer part first. This could // be easily fixed, but only if i had something to test with. case G_MW_NUMLIGHT: gSPNumLights_G64(w1 / 48); break; case G_MW_CLIP: if (offset == 0x04) { rdp.clip_ratio = (float)vi_integer_sqrt(w1); g_gdp.flags |= UPDATE_VIEWPORT; } break; case G_MW_SEGMENT: rdp.segment[(offset >> 2) & 0xF] = w1; break; case G_MW_FOG: gSPFogFactor_G64((int16_t)_SHIFTR(w1, 16, 16), (int16_t)_SHIFTR(w1, 0, 16)); break; case G_MW_PERSPNORM: break; case G_MV_COORDMOD: // moveword coord mod { uint32_t idx, pos; uint8_t n; n = offset >> 2; FRDP ("coord mod:%d, %08lx\n", n, w1); if (w0 & 8) return; idx = (w0 >> 1)&3; pos = w0 & 0x30; if (pos == 0) { uc8_coord_mod[0+idx] = (int16_t)(w1 >> 16); uc8_coord_mod[1+idx] = (int16_t)(w1 & 0xffff); } else if (pos == 0x10) { uc8_coord_mod[4+idx] = (w1 >> 16) / 65536.0f; uc8_coord_mod[5+idx] = (w1 & 0xffff) / 65536.0f; uc8_coord_mod[12+idx] = uc8_coord_mod[0+idx] + uc8_coord_mod[4+idx]; uc8_coord_mod[13+idx] = uc8_coord_mod[1+idx] + uc8_coord_mod[5+idx]; } else if (pos == 0x20) { uc8_coord_mod[8+idx] = (int16_t)(w1 >> 16); uc8_coord_mod[9+idx] = (int16_t)(w1 & 0xffff); } } break; } } static void uc8_movemem(uint32_t w0, uint32_t w1) { int i, t; uint32_t addr = RSP_SegmentToPhysical(w1); int ofs = _SHIFTR(w0, 5, 14); switch (_SHIFTR(w0, 0, 8)) { case F3DCBFD_MV_VIEWPORT: gSPViewport_G64(w1); break; case F3DCBFD_MV_LIGHT: // LIGHT { uint32_t a; int n = (ofs / 48); if (n < 2) gSPLookAt_G64(w1, n); else { n -= 2; rdp.light[n].nonblack = gfx_info.RDRAM[(addr+0)^3]; rdp.light[n].nonblack += gfx_info.RDRAM[(addr+1)^3]; rdp.light[n].nonblack += gfx_info.RDRAM[(addr+2)^3]; rdp.light[n].col[0] = (((uint8_t*)gfx_info.RDRAM)[(addr+0)^3]) / 255.0f; rdp.light[n].col[1] = (((uint8_t*)gfx_info.RDRAM)[(addr+1)^3]) / 255.0f; rdp.light[n].col[2] = (((uint8_t*)gfx_info.RDRAM)[(addr+2)^3]) / 255.0f; rdp.light[n].col[3] = 1.0f; // ** Thanks to Icepir8 for pointing this out ** // Lighting must be signed byte instead of byte rdp.light[n].dir[0] = (float)(((int8_t*)gfx_info.RDRAM)[(addr+8)^3]) / 127.0f; rdp.light[n].dir[1] = (float)(((int8_t*)gfx_info.RDRAM)[(addr+9)^3]) / 127.0f; rdp.light[n].dir[2] = (float)(((int8_t*)gfx_info.RDRAM)[(addr+10)^3]) / 127.0f; // ** a = addr >> 1; rdp.light[n].x = (float)(((int16_t*)gfx_info.RDRAM)[(a+16)^1]); rdp.light[n].y = (float)(((int16_t*)gfx_info.RDRAM)[(a+17)^1]); rdp.light[n].z = (float)(((int16_t*)gfx_info.RDRAM)[(a+18)^1]); rdp.light[n].w = (float)(((int16_t*)gfx_info.RDRAM)[(a+19)^1]); rdp.light[n].nonzero = gfx_info.RDRAM[(addr+12)^3]; rdp.light[n].ca = (float)rdp.light[n].nonzero / 16.0f; //rdp.light[n].la = rdp.light[n].ca * 1.0f; } } break; case F3DCBFD_MV_NORMAL: //Normals uc8_normale_addr = RSP_SegmentToPhysical(w1); break; } } static void uc8_tri4(uint32_t w0, uint32_t w1) //by Gugaman Apr 19 2002 { VERTEX *v[12]; if (rdp.skip_drawing) return; v[0] = &rdp.vtx[_SHIFTR( w0, 23, 5)]; /* v00 */ v[1] = &rdp.vtx[_SHIFTR( w0, 18, 5)]; /* v01 */ v[2] = &rdp.vtx[(_SHIFTR(w0, 15, 3) << 2) | _SHIFTR(w1, 30, 2)]; /* v02 */ v[3] = &rdp.vtx[_SHIFTR( w0, 10, 5)]; /* v10 */ v[4] = &rdp.vtx[_SHIFTR( w0, 5, 5)]; /* v11 */ v[5] = &rdp.vtx[_SHIFTR( w0, 0, 5)]; /* v12 */ v[6] = &rdp.vtx[_SHIFTR( w1, 25, 5)]; /* v20 */ v[7] = &rdp.vtx[_SHIFTR( w1, 20, 5)]; /* v21 */ v[8] = &rdp.vtx[_SHIFTR( w1, 15, 5)]; /* v22 */ v[9] = &rdp.vtx[_SHIFTR( w1, 10, 5)]; /* v30 */ v[10] = &rdp.vtx[_SHIFTR( w1, 5, 5)]; /* v31 */ v[11] = &rdp.vtx[_SHIFTR( w1, 0, 5)]; /* v32 */ cull_trianglefaces(v, 4, true, true, 0); } mupen64plus-core/src/vi/000700 001750 001750 00000000000 12656647145 016243 5ustar00sergiosergio000000 000000 mupen64plus-video-gliden64/src/GLideNHQ/test/test.cpp000664 001750 001750 00000006465 12655644434 023436 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "../Ext_TxFilter.h" #include #include #include void DisplayLoadProgress(const wchar_t *format, ...) { #if 0 va_list args; wchar_t wbuf[INFO_BUF]; char buf[INFO_BUF]; /* process input */ va_start(args, format); vswprintf(wbuf, format, args); va_end(args); /* XXX: convert to multibyte */ wcstombs(buf, wbuf, INFO_BUF); printf(buf); #else static unsigned int i = 0; i++; if (i == 1) printf("\b-"); else if (i == 2) printf("\b\\"); else if (i == 3) printf("\b|"); else { printf("\b/"); i = 0; } #endif } int main(int argc, char* argv[]) { float dummy = 1.1; /* force the compiler to load floating point support */ boolean bret = 0; int options = 0; /* Plugin path */ wchar_t path[MAX_PATH]; #ifdef WIN32 GETCWD(MAX_PATH, path); #else char cbuf[MAX_PATH]; GETCWD(MAX_PATH, cbuf); mbstowcs(path, cbuf, MAX_PATH); #endif /* ROM name */ wchar_t name[21] = L"DEFAULT"; printf("------------------------------------------------------------------\n"); printf(" GlideHQ Hires Texture Checker version 1.2\n"); printf(" Copyright (C) 2010 Hiroshi Morii All Rights Reserved\n"); printf(" email : koolsmoky(at)users.sourceforge.net\n"); printf(" website : http://www.3dfxzone.it/koolsmoky\n"); printf("\n"); printf(" Glide64 official website : http://glide64.emuxhaven.net\n"); printf("\n"); printf(" Usage: ghqchk.exe \"INTERNAL ROM NAME\"\n"); printf("------------------------------------------------------------------\n"); if (argc != 2) return 0; printf("Checking \"%s\"... ", argv[1]); mbstowcs(name, argv[1], 21); //options |= COMPRESS_TEX; //options |= COMPRESS_HIRESTEX; //options |= S3TC_COMPRESSION; //options |= TILE_HIRESTEX; //options |= FORCE16BPP_TEX; //options |= FORCE16BPP_HIRESTEX; //options |= GZ_TEXCACHE; options |= GZ_HIRESTEXCACHE; //options |= (DUMP_TEXCACHE|DUMP_HIRESTEXCACHE); options |= LET_TEXARTISTS_FLY; //options |= DUMP_TEX; options |= RICE_HIRESTEXTURES; bret = ext_ghq_init(1024, // max texture width supported by hardware 1024, // max texture height supported by hardware 32, // max texture bpp supported by hardware options, 0, // cache texture to system memory path, // plugin path name, // name of ROM. must be no longer than 256 characters DisplayLoadProgress); ext_ghq_shutdown(); printf("\bDone!\nLogged to ghqchk.txt\n"); return bret; } mupen64plus-core/src/main/eventloop.h000664 001750 001750 00000003241 12655644434 020746 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - eventloop.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2009 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef EVENTLOOP_H #define EVENTLOOP_H extern int event_gameshark_active(void); extern void event_set_gameshark(int active); #endif /* EVENTLOOP_H */ mupen64plus-video-gliden64/src/VI.cpp000664 001750 001750 00000012342 12655644434 020452 0ustar00sergiosergio000000 000000 #include "GLideN64.h" #include #include "Types.h" #include "VI.h" #include "OpenGL.h" #include "N64.h" #include "gSP.h" #include "gDP.h" #include "RSP.h" #include "FrameBuffer.h" #include "DepthBuffer.h" #include "Config.h" #include "Debug.h" using namespace std; VIInfo VI; void VI_UpdateSize() { const f32 xScale = _FIXED2FLOAT( _SHIFTR( *gfx_info.VI_X_SCALE, 0, 12 ), 10 ); // f32 xOffset = _FIXED2FLOAT( _SHIFTR( *gfx_info.VI_X_SCALE, 16, 12 ), 10 ); const u32 vScale = _SHIFTR(*gfx_info.VI_Y_SCALE, 0, 12); // f32 yOffset = _FIXED2FLOAT( _SHIFTR( *gfx_info.VI_Y_SCALE, 16, 12 ), 10 ); const u32 hEnd = _SHIFTR( *gfx_info.VI_H_START, 0, 10 ); const u32 hStart = _SHIFTR( *gfx_info.VI_H_START, 16, 10 ); // These are in half-lines, so shift an extra bit const u32 vEnd = _SHIFTR( *gfx_info.VI_V_START, 0, 10 ); const u32 vStart = _SHIFTR( *gfx_info.VI_V_START, 16, 10 ); const bool interlacedPrev = VI.interlaced; if (VI.width > 0) VI.widthPrev = VI.width; VI.real_height = vEnd > vStart ? (((vEnd - vStart) >> 1) * vScale) >> 10 : 0; VI.width = *gfx_info.VI_WIDTH; VI.interlaced = (*gfx_info.VI_STATUS & 0x40) != 0; if (VI.interlaced) { f32 fullWidth = 640.0f*xScale; if (*gfx_info.VI_WIDTH > fullWidth) { const u32 scale = (u32)floorf(*gfx_info.VI_WIDTH / fullWidth + 0.5f); VI.width /= scale; VI.real_height *= scale; } if (VI.real_height % 2 == 1) --VI.real_height; } VI.PAL = (*gfx_info.VI_V_SYNC & 0x3ff) > 550; if (VI.PAL && (vEnd - vStart) > 478) { VI.height = (u32)(VI.real_height*1.0041841f); if (VI.height > 576) VI.height = VI.real_height = 576; } else { VI.height = (u32)(VI.real_height*1.0126582f); if (VI.height > 480) VI.height = VI.real_height = 480; } if (VI.height % 2 == 1) --VI.height; // const int fsaa = ((*gfx_info.VI_STATUS) >> 8) & 3; // const int divot = ((*gfx_info.VI_STATUS) >> 4) & 1; FrameBufferList & fbList = frameBufferList(); FrameBuffer * pBuffer = fbList.findBuffer(VI.lastOrigin); DepthBuffer * pDepthBuffer = pBuffer != NULL ? pBuffer->m_pDepthBuffer : NULL; if (config.frameBufferEmulation.enable && ((config.generalEmulation.hacks & hack_skipVIChangeCheck) == 0) && ((interlacedPrev != VI.interlaced) || (VI.width > 0 && VI.width != VI.widthPrev) || (!VI.interlaced && pDepthBuffer != NULL && pDepthBuffer->m_width != VI.width) || ((config.generalEmulation.hacks & hack_ignoreVIHeightChange) == 0 && pBuffer != NULL && pBuffer->m_height != VI.height)) ) { fbList.removeBuffers(VI.widthPrev); fbList.removeBuffers(VI.width); depthBufferList().destroy(); depthBufferList().init(); } VI.rwidth = VI.width != 0 ? 1.0f / VI.width : 0.0f; VI.rheight = VI.height != 0 ? 1.0f / VI.height : 0.0f; } void VI_UpdateScreen() { if (VI.lastOrigin == -1) // Workaround for Mupen64Plus issue with initialization isGLError(); if (ConfigOpen) return; OGLVideo & ogl = video(); if (ogl.changeWindow()) return; if (ogl.resizeWindow()) return; ogl.saveScreenshot(); bool bVIUpdated = false; if (*gfx_info.VI_ORIGIN_REG != VI.lastOrigin) { VI_UpdateSize(); bVIUpdated = true; ogl.updateScale(); } if (config.frameBufferEmulation.enable) { FrameBuffer * pBuffer = frameBufferList().findBuffer(*gfx_info.VI_ORIGIN_REG); if (pBuffer == NULL) gDP.changed |= CHANGED_CPU_FB_WRITE; else if (!pBuffer->isValid()) { gDP.changed |= CHANGED_CPU_FB_WRITE; if (config.frameBufferEmulation.copyToRDRAM == 0) pBuffer->copyRdram(); } const bool bCFB = (gDP.changed&CHANGED_CPU_FB_WRITE) == CHANGED_CPU_FB_WRITE; bool bNeedSwap = false; switch (config.frameBufferEmulation.bufferSwapMode) { case Config::bsOnVerticalInterrupt: bNeedSwap = true; break; case Config::bsOnVIOriginChange: bNeedSwap = bCFB ? true : (*gfx_info.VI_ORIGIN_REG != VI.lastOrigin); break; case Config::bsOnColorImageChange: bNeedSwap = bCFB ? true : (gDP.colorImage.changed != 0); break; } if (bNeedSwap) { if (bCFB) { if (pBuffer == NULL || pBuffer->m_width != VI.width) { if (!bVIUpdated) { VI_UpdateSize(); ogl.updateScale(); bVIUpdated = true; } const u32 size = *gfx_info.VI_STATUS & 3; if (VI.height > 0 && size > G_IM_SIZ_8b && VI.width > 0) frameBufferList().saveBuffer(*gfx_info.VI_ORIGIN_REG, G_IM_FMT_RGBA, size, VI.width, VI.height, true); } } if ((((*gfx_info.VI_STATUS) & 3) > 0) && ((config.frameBufferEmulation.copyFromRDRAM && gDP.colorImage.changed) || bCFB)) { if (!bVIUpdated) { VI_UpdateSize(); bVIUpdated = true; } FrameBuffer_CopyFromRDRAM(*gfx_info.VI_ORIGIN_REG, config.frameBufferEmulation.copyFromRDRAM && !bCFB); } frameBufferList().renderBuffer(*gfx_info.VI_ORIGIN_REG); frameBufferList().clearBuffersChanged(); VI.lastOrigin = *gfx_info.VI_ORIGIN_REG; #ifdef DEBUG while (Debug.paused && !Debug.step); Debug.step = FALSE; #endif } } else { if (gDP.changed & CHANGED_COLORBUFFER) { ogl.swapBuffers(); gDP.changed &= ~CHANGED_COLORBUFFER; #ifdef DEBUG while (Debug.paused && !Debug.step); Debug.step = FALSE; #endif VI.lastOrigin = *gfx_info.VI_ORIGIN_REG; } } if (VI.lastOrigin == -1) { // Workaround for Mupen64Plus issue with initialization glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); } } mupen64plus-video-gliden64/src/OGL3X/000700 001750 001750 00000000000 12656647145 020251 5ustar00sergiosergio000000 000000 gles2n64/src/S2DEX.h000664 001750 001750 00000022062 12655644434 015052 0ustar00sergiosergio000000 000000 #ifndef S2DEX_H #define S2DEX_H #ifdef __cplusplus extern "C" { #endif #define G_BGLT_LOADBLOCK 0x0033 #define G_BGLT_LOADTILE 0xfff4 #define G_BG_FLAG_FLIPS 0x01 #define G_BG_FLAG_FLIPT 0x10 #define G_OBJRM_NOTXCLAMP 0x01 #define G_OBJRM_XLU 0x02 #define G_OBJRM_ANTIALIAS 0x04 #define G_OBJRM_BILERP 0x08 #define G_OBJRM_SHRINKSIZE_1 0x10 #define G_OBJRM_SHRINKSIZE_2 0x20 #define G_OBJRM_WIDEN 0x40 struct uObjScaleBg { u16 imageW; /* Texture width (8-byte alignment, u10.2) */ u16 imageX; /* x-coordinate of upper-left position of texture (u10.5) */ u16 frameW; /* Transfer destination frame width (u10.2) */ s16 frameX; /* x-coordinate of upper-left position of transfer destination frame (s10.2) */ u16 imageH; /* Texture height (u10.2) */ u16 imageY; /* y-coordinate of upper-left position of texture (u10.5) */ u16 frameH; /* Transfer destination frame height (u10.2) */ s16 frameY; /* y-coordinate of upper-left position of transfer destination frame (s10.2) */ u32 imagePtr; /* Address of texture source in DRAM*/ u8 imageSiz; /* Texel size G_IM_SIZ_4b (4 bits/texel) G_IM_SIZ_8b (8 bits/texel) G_IM_SIZ_16b (16 bits/texel) G_IM_SIZ_32b (32 bits/texel) */ u8 imageFmt; /*Texel format G_IM_FMT_RGBA (RGBA format) G_IM_FMT_YUV (YUV format) G_IM_FMT_CI (CI format) G_IM_FMT_IA (IA format) G_IM_FMT_I (I format) */ u16 imageLoad; /* Method for loading the BG image texture G_BGLT_LOADBLOCK (use LoadBlock) G_BGLT_LOADTILE (use LoadTile) */ u16 imageFlip; /* Image inversion on/off (horizontal direction only) 0 (normal display (no inversion)) G_BG_FLAG_FLIPS (horizontal inversion of texture image) */ u16 imagePal; /* Position of palette for 4-bit color index texture (4-bit precision, 0~15) */ u16 scaleH; /* y-direction scale value (u5.10) */ u16 scaleW; /* x-direction scale value (u5.10) */ s32 imageYorig; /* image drawing origin (s20.5)*/ u8 padding[4]; /* Padding */ }; /* 40 bytes */ typedef struct { u16 imageW; /* Texture width (8-byte alignment, u10.2) */ u16 imageX; /* x-coordinate of upper-left position of texture (u10.5) */ u16 frameW; /* Transfer destination frame width (u10.2) */ s16 frameX; /* x-coordinate of upper-left position of transfer destination frame (s10.2) */ u16 imageH; /* Texture height (u10.2) */ u16 imageY; /* y-coordinate of upper-left position of texture (u10.5) */ u16 frameH; /* Transfer destination frame height (u10.2) */ s16 frameY; /* y-coordinate of upper-left position of transfer destination frame (s10.2) */ u32 imagePtr; /* Address of texture source in DRAM*/ u8 imageSiz; /* Texel size G_IM_SIZ_4b (4 bits/texel) G_IM_SIZ_8b (8 bits/texel) G_IM_SIZ_16b (16 bits/texel) G_IM_SIZ_32b (32 bits/texel) */ u8 imageFmt; /*Texel format G_IM_FMT_RGBA (RGBA format) G_IM_FMT_YUV (YUV format) G_IM_FMT_CI (CI format) G_IM_FMT_IA (IA format) G_IM_FMT_I (I format) */ u16 imageLoad; /* Method for loading the BG image texture G_BGLT_LOADBLOCK (use LoadBlock) G_BGLT_LOADTILE (use LoadTile) */ u16 imageFlip; /* Image inversion on/off (horizontal direction only) 0 (normal display (no inversion)) G_BG_FLAG_FLIPS (horizontal inversion of texture image) */ u16 imagePal; /* Position of palette for 4-bit color index texture (4-bit precision, 0~15) */ /* The following is set in the initialization routine guS2DInitBg */ u16 tmemH; /* TMEM height for a single load (quadruple value, s13.2) */ u16 tmemW; /* TMEM width for one frame line (word size) */ u16 tmemLoadTH; /* TH value or Stride value */ u16 tmemLoadSH; /* SH value */ u16 tmemSize; /* imagePtr skip value for a single load */ u16 tmemSizeW; /* imagePtr skip value for one image line */ } uObjBg; /* 40 bytes */ struct uSprite { u32 imagePtr; u32 tlutPtr; s16 imageW; s16 stride; s8 imageSiz; s8 imageFmt; s16 imageH; s16 imageY; s16 imageX; s8 dummy[4]; }; /* 24 bytes */ struct uObjSprite { u16 scaleW; /* Width-direction scaling (u5.10) */ s16 objX; /* x-coordinate of upper-left corner of OBJ (s10.2) */ u16 paddingX; /* Unused (always 0) */ u16 imageW; /* Texture width (length in s direction, u10.5) */ u16 scaleH; /* Height-direction scaling (u5.10) */ s16 objY; /* y-coordinate of upper-left corner of OBJ (s10.2) */ u16 paddingY; /* Unused (always 0) */ u16 imageH; /* Texture height (length in t direction, u10.5) */ u16 imageAdrs; /* Texture starting position in TMEM (In units of 64-bit words) */ u16 imageStride; /* Texel wrapping width (In units of 64-bit words) */ u8 imageFlags; /* Display flag (*) More than one of the following flags can be specified as the bit sum of the flags: 0 (Normal display (no inversion)) G_OBJ_FLAG_FLIPS (s-direction (x) inversion) G_OBJ_FLAG_FLIPT (t-direction (y) inversion) */ u8 imagePal; /* Position of palette for 4-bit color index texture (4-bit precision, 0~7) */ u8 imageSiz; /* Texel size G_IM_SIZ_4b (4 bits/texel) G_IM_SIZ_8b (8 bits/texel) G_IM_SIZ_16b (16 bits/texel) G_IM_SIZ_32b (32 bits/texel) */ u8 imageFmt; /* Texel format G_IM_FMT_RGBA (RGBA format) G_IM_FMT_YUV (YUV format) G_IM_FMT_CI (CI format) G_IM_FMT_IA (IA format) G_IM_FMT_I (I format) */ }; /* 24 bytes */ typedef struct { u32 type; /* Structure identifier (G_OBJLT_TXTRBLOCK) */ u32 image; /* Texture source address in DRAM (8-byte alignment) */ u16 tsize; /* Texture size (specified by GS_TB_TSIZE) */ u16 tmem; /* TMEM word address where texture will be loaded (8-byte word) */ u16 sid; /* Status ID (multiple of 4: either 0, 4, 8, or 12) */ u16 tline; /* Texture line width (specified by GS_TB_TLINE) */ u32 flag; /* Status flag */ u32 mask; /* Status mask */ } uObjTxtrBlock; /* 24 bytes */ typedef struct { u32 type; /* Structure identifier (G_OBJLT_TXTRTILE) */ u32 image; /* Texture source address in DRAM (8-byte alignment) */ u16 twidth; /* Texture width (specified by GS_TT_TWIDTH) */ u16 tmem; /* TMEM word address where texture will be loaded (8-byte word) */ u16 sid; /* Status ID (multiple of 4: either 0, 4, 8, or 12) */ u16 theight;/* Texture height (specified by GS_TT_THEIGHT) */ u32 flag; /* Status flag */ u32 mask; /* Status mask */ } uObjTxtrTile; /* 24 bytes */ typedef struct { u32 type; /* Structure identifier (G_OBJLT_TLUT) */ u32 image; /* Texture source address in DRAM */ u16 pnum; /* Number of palettes to load - 1 */ u16 phead; /* Palette position at start of load (256~511) */ u16 sid; /* Status ID (multiple of 4: either 0, 4, 8, or 12) */ u16 zero; /* Always assign 0 */ u32 flag; /* Status flag */ u32 mask; /* Status mask */ } uObjTxtrTLUT; /* 24 bytes */ typedef union { uObjTxtrBlock block; uObjTxtrTile tile; uObjTxtrTLUT tlut; } uObjTxtr; struct uObjTxSprite { uObjTxtr txtr; struct uObjSprite sprite; }; typedef struct { s32 A, B, C, D; /* s15.16 */ s16 Y, X; /* s10.2 */ u16 BaseScaleY; /* u5.10 */ u16 BaseScaleX; /* u5.10 */ } uObjMtx; typedef struct { s16 Y, X; /* s10.2 */ u16 BaseScaleY; /* u5.10 */ u16 BaseScaleX; /* u5.10 */ } uObjSubMtx; void S2DEX_BG_1Cyc( u32 w0, u32 w1 ); void S2DEX_BG_Copy( u32 w0, u32 w1 ); void S2DEX_Obj_Rectangle( u32 w0, u32 w1 ); void S2DEX_Obj_Sprite( u32 w0, u32 w1 ); void S2DEX_Obj_MoveMem( u32 w0, u32 w1 ); void S2DEX_Select_DL( u32 w0, u32 w1 ); void S2DEX_Obj_RenderMode( u32 w0, u32 w1 ); void S2DEX_Obj_Rectangle_R( u32 w0, u32 w1 ); void S2DEX_Obj_LoadTxtr( u32 w0, u32 w1 ); void S2DEX_Obj_LdTx_Sprite( u32 w0, u32 w1 ); void S2DEX_Obj_LdTx_Rect( u32 w0, u32 w1 ); void S2DEX_Obj_LdTx_Rect_R( u32 w0, u32 w1 ); void S2DEX_Init(); #define S2DEX_MV_MATRIX 0 #define S2DEX_MV_SUBMUTRIX 2 #define S2DEX_MV_VIEWPORT 8 #define S2DEX_BG_1CYC 0x01 #define S2DEX_BG_COPY 0x02 #define S2DEX_OBJ_RECTANGLE 0x03 #define S2DEX_OBJ_SPRITE 0x04 #define S2DEX_OBJ_MOVEMEM 0x05 #define S2DEX_LOAD_UCODE 0xAF #define S2DEX_SELECT_DL 0xB0 #define S2DEX_OBJ_RENDERMODE 0xB1 #define S2DEX_OBJ_RECTANGLE_R 0xB2 #define S2DEX_OBJ_LOADTXTR 0xC1 #define S2DEX_OBJ_LDTX_SPRITE 0xC2 #define S2DEX_OBJ_LDTX_RECT 0xC3 #define S2DEX_OBJ_LDTX_RECT_R 0xC4 #define S2DEX_RDPHALF_0 0xE4 #ifdef __cplusplus } #endif #endif libretro/msvc/000700 001750 001750 00000000000 12656647145 014500 5ustar00sergiosergio000000 000000 mupen64plus-core/src/main/eventloop.c000664 001750 001750 00000004611 12655644434 020743 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - eventloop.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2008-2009 Richard Goedeken * * Copyright (C) 2008 Ebenblues Nmn Okaygo Tillin9 * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #define M64P_CORE_PROTOTYPES 1 #include "main.h" #include "eventloop.h" #include "util.h" #include "api/callbacks.h" #include "api/config.h" #include "api/m64p_config.h" #include "plugin/plugin.h" #include "r4300/reset.h" /* version number for CoreEvents config section */ #define CONFIG_PARAM_VERSION 1.00 static int GamesharkActive = 0; int event_gameshark_active(void) { return GamesharkActive; } void event_set_gameshark(int active) { /* if boolean value doesn't change then just return */ if (!active == !GamesharkActive) return; /* set the button state */ GamesharkActive = 0; if (active) GamesharkActive = 1; /* notify front-end application that * gameshark button state has changed */ StateChanged(M64CORE_INPUT_GAMESHARK, GamesharkActive); } mupen64plus-video-gliden64/src/OGL3X/GLSLCombiner_ogl3x.cpp000664 001750 001750 00000067717 12655644434 024344 0ustar00sergiosergio000000 000000 #include #include #include #include #include "../N64.h" #include "../OpenGL.h" #include "../Config.h" #include "../GLSLCombiner.h" #include "../ShaderUtils.h" #include "../FrameBuffer.h" #include "../DepthBuffer.h" #include "../RSP.h" #include "../VI.h" #include "../Log.h" #include "Shaders_ogl3x.h" using namespace std; static GLuint g_vertex_shader_object; static GLuint g_vertex_shader_object_notex; static GLuint g_calc_light_shader_object; static GLuint g_calc_mipmap_shader_object; static GLuint g_calc_noise_shader_object; static GLuint g_calc_depth_shader_object; static GLuint g_readtex_shader_object; static GLuint g_readtex_ms_shader_object; static GLuint g_dither_shader_object; static GLuint g_monochrome_image_program = 0; #ifdef GL_IMAGE_TEXTURES_SUPPORT GLuint g_draw_shadow_map_program = 0; static GLuint g_zlut_tex = 0; GLuint g_tlut_tex = 0; static u32 g_paletteCRC256 = 0; #endif // GL_IMAGE_TEXTURES_SUPPORT static std::string strFragmentShader; class NoiseTexture { public: NoiseTexture() : m_pTexture(NULL), m_PBO(0), m_DList(0) {} void init(); void destroy(); void update(); private: CachedTexture * m_pTexture; GLuint m_PBO; u32 m_DList; } noiseTex; void NoiseTexture::init() { if (config.generalEmulation.enableNoise == 0) return; m_pTexture = textureCache().addFrameBufferTexture(); m_pTexture->format = G_IM_FMT_RGBA; m_pTexture->clampS = 1; m_pTexture->clampT = 1; m_pTexture->frameBufferTexture = CachedTexture::fbOneSample; m_pTexture->maskS = 0; m_pTexture->maskT = 0; m_pTexture->mirrorS = 0; m_pTexture->mirrorT = 0; m_pTexture->realWidth = 640; m_pTexture->realHeight = 580; m_pTexture->textureBytes = m_pTexture->realWidth * m_pTexture->realHeight; textureCache().addFrameBufferTextureSize(m_pTexture->textureBytes); glBindTexture(GL_TEXTURE_2D, m_pTexture->glName); glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, m_pTexture->realWidth, m_pTexture->realHeight, 0, GL_RED, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glBindTexture(GL_TEXTURE_2D, 0); // Generate Pixel Buffer Object. Initialize it with max buffer size. glGenBuffers(1, &m_PBO); PBOBinder binder(GL_PIXEL_UNPACK_BUFFER, m_PBO); glBufferData(GL_PIXEL_UNPACK_BUFFER, 640*580, NULL, GL_DYNAMIC_DRAW); } void NoiseTexture::destroy() { if (m_pTexture != NULL) { textureCache().removeFrameBufferTexture(m_pTexture); m_pTexture = NULL; } glDeleteBuffers(1, &m_PBO); m_PBO = 0; } void NoiseTexture::update() { if (m_DList == video().getBuffersSwapCount() || config.generalEmulation.enableNoise == 0) return; const u32 dataSize = VI.width*VI.height; if (dataSize == 0) return; PBOBinder binder(GL_PIXEL_UNPACK_BUFFER, m_PBO); GLubyte* ptr = (GLubyte*)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, dataSize, GL_MAP_WRITE_BIT); if (ptr == NULL) return; for (u32 y = 0; y < VI.height; ++y) { for (u32 x = 0; x < VI.width; ++x) ptr[x + y*VI.width] = rand()&0xFF; } glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); // release the mapped buffer glActiveTexture(GL_TEXTURE0 + g_noiseTexIndex); glBindTexture(GL_TEXTURE_2D, m_pTexture->glName); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VI.width, VI.height, GL_RED, GL_UNSIGNED_BYTE, 0); m_DList = video().getBuffersSwapCount(); } #ifdef GL_IMAGE_TEXTURES_SUPPORT static void InitZlutTexture() { if (!video().getRender().isImageTexturesSupported()) return; #ifdef GLESX std::vector vecZLUT(0x40000); const u16 * const zLUT16 = depthBufferList().getZLUT(); for (u32 i = 0; i < 0x40000; ++i) vecZLUT[i] = zLUT16[i]; const u32 * zLUT = vecZLUT.data(); #else const u16 * const zLUT = depthBufferList().getZLUT(); #endif glGenTextures(1, &g_zlut_tex); glBindTexture(GL_TEXTURE_2D, g_zlut_tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, fboFormats.lutInternalFormat, 512, 512, 0, fboFormats.lutFormat, fboFormats.lutType, zLUT); glBindImageTexture(ZlutImageUnit, g_zlut_tex, 0, GL_FALSE, 0, GL_READ_ONLY, fboFormats.lutInternalFormat); } static void DestroyZlutTexture() { if (!video().getRender().isImageTexturesSupported()) return; glBindImageTexture(ZlutImageUnit, 0, 0, GL_FALSE, 0, GL_READ_ONLY, fboFormats.lutInternalFormat); if (g_zlut_tex > 0) { glBindTexture(GL_TEXTURE_2D, 0); glDeleteTextures(1, &g_zlut_tex); g_zlut_tex = 0; } } static void InitShadowMapShader() { if (!video().getRender().isImageTexturesSupported()) return; g_paletteCRC256 = 0; glGenTextures(1, &g_tlut_tex); glBindTexture(GL_TEXTURE_2D, g_tlut_tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, fboFormats.lutInternalFormat, 256, 1, 0, fboFormats.lutFormat, fboFormats.lutType, NULL); g_draw_shadow_map_program = createShaderProgram(default_vertex_shader, shadow_map_fragment_shader_float); } static void DestroyShadowMapShader() { if (!video().getRender().isImageTexturesSupported()) return; glBindImageTexture(TlutImageUnit, 0, 0, GL_FALSE, 0, GL_READ_ONLY, fboFormats.lutInternalFormat); if (g_tlut_tex > 0) { glBindTexture(GL_TEXTURE_2D, 0); glDeleteTextures(1, &g_tlut_tex); g_tlut_tex = 0; } glDeleteProgram(g_draw_shadow_map_program); g_draw_shadow_map_program = 0; } #endif // GL_IMAGE_TEXTURES_SUPPORT static GLuint _createShader(GLenum _type, const char * _strShader) { GLuint shader_object = glCreateShader(_type); glShaderSource(shader_object, 1, &_strShader, NULL); glCompileShader(shader_object); assert(checkShaderCompileStatus(shader_object)); return shader_object; } void InitShaderCombiner() { glActiveTexture(GL_TEXTURE0); glEnable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE1); glEnable(GL_TEXTURE_2D); g_vertex_shader_object = _createShader(GL_VERTEX_SHADER, vertex_shader); g_vertex_shader_object_notex = _createShader(GL_VERTEX_SHADER, vertex_shader_notex); strFragmentShader.reserve(1024*5); #ifndef GLESX g_calc_light_shader_object = _createShader(GL_FRAGMENT_SHADER, fragment_shader_calc_light); g_calc_mipmap_shader_object = _createShader(GL_FRAGMENT_SHADER, fragment_shader_mipmap); g_calc_noise_shader_object = _createShader(GL_FRAGMENT_SHADER, fragment_shader_noise); g_readtex_shader_object = _createShader(GL_FRAGMENT_SHADER, config.texture.bilinearMode == BILINEAR_3POINT ? fragment_shader_readtex_3point : fragment_shader_readtex); g_readtex_ms_shader_object = _createShader(GL_FRAGMENT_SHADER, fragment_shader_readtex_ms); g_dither_shader_object = _createShader(GL_FRAGMENT_SHADER, fragment_shader_dither); #endif // GLESX noiseTex.init(); g_monochrome_image_program = createShaderProgram(default_vertex_shader, zelda_monochrome_fragment_shader); glUseProgram(g_monochrome_image_program); const int texLoc = glGetUniformLocation(g_monochrome_image_program, "uColorImage"); glUniform1i(texLoc, 0); glUseProgram(0); #ifdef GL_IMAGE_TEXTURES_SUPPORT if (video().getRender().isImageTexturesSupported() && config.frameBufferEmulation.N64DepthCompare != 0) g_calc_depth_shader_object = _createShader(GL_FRAGMENT_SHADER, depth_compare_shader_float); InitZlutTexture(); InitShadowMapShader(); #endif // GL_IMAGE_TEXTURES_SUPPORT } void DestroyShaderCombiner() { strFragmentShader.clear(); glBindFramebuffer(GL_FRAMEBUFFER, 0); glDeleteShader(g_vertex_shader_object); g_vertex_shader_object = 0; glDeleteShader(g_vertex_shader_object_notex); g_vertex_shader_object_notex = 0; #ifndef GLESX glDeleteShader(g_calc_light_shader_object); g_calc_light_shader_object = 0; glDeleteShader(g_calc_mipmap_shader_object); g_calc_mipmap_shader_object = 0; glDeleteShader(g_readtex_shader_object); g_readtex_shader_object = 0; glDeleteShader(g_readtex_ms_shader_object); g_readtex_ms_shader_object = 0; glDeleteShader(g_calc_noise_shader_object); g_calc_noise_shader_object = 0; glDeleteShader(g_dither_shader_object); g_dither_shader_object = 0; glDeleteShader(g_calc_depth_shader_object); g_calc_depth_shader_object = 0; #endif // GLESX glDeleteProgram(g_monochrome_image_program); g_monochrome_image_program = 0; noiseTex.destroy(); #ifdef GL_IMAGE_TEXTURES_SUPPORT DestroyZlutTexture(); DestroyShadowMapShader(); #endif // GL_IMAGE_TEXTURES_SUPPORT } ShaderCombiner::ShaderCombiner() : m_bNeedUpdate(true) { m_program = glCreateProgram(); _locate_attributes(); } ShaderCombiner::ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCombine & _combine) : m_combine(_combine), m_bNeedUpdate(true) { char strCombiner[1024]; m_nInputs = compileCombiner(_color, _alpha, strCombiner); if (usesTexture()) { strFragmentShader.assign(fragment_shader_header_common_variables); strFragmentShader.append(fragment_shader_header_common_functions); } else { strFragmentShader.assign(fragment_shader_header_common_variables_notex); strFragmentShader.append(fragment_shader_header_common_functions_notex); } strFragmentShader.append(fragment_shader_header_main); const bool bUseLod = usesLOD(); if (bUseLod) { strFragmentShader.append(" lowp vec4 readtex0, readtex1; \n"); strFragmentShader.append(" lowp float lod_frac = mipmap(readtex0, readtex1); \n"); } else { #ifdef GL_MULTISAMPLING_SUPPORT if (usesTile(0)) { if (config.video.multisampling > 0) { strFragmentShader.append(" lowp vec4 readtex0; \n"); strFragmentShader.append(" if (uMSTexEnabled[0] == 0) readtex0 = readTex(uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0] != 0); \n"); strFragmentShader.append(" else readtex0 = readTexMS(uMSTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0] != 0); \n"); } else strFragmentShader.append(" lowp vec4 readtex0 = readTex(uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0] != 0); \n"); } if (usesTile(1)) { if (config.video.multisampling > 0) { strFragmentShader.append(" lowp vec4 readtex1; \n"); strFragmentShader.append(" if (uMSTexEnabled[1] == 0) readtex1 = readTex(uTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1] != 0); \n"); strFragmentShader.append(" else readtex1 = readTexMS(uMSTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1] != 0); \n"); } else strFragmentShader.append(" lowp vec4 readtex1 = readTex(uTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1] != 0); \n"); } #else if (usesTile(0)) strFragmentShader.append(" lowp vec4 readtex0 = readTex(uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0] != 0); \n"); if (usesTile(1)) strFragmentShader.append(" lowp vec4 readtex1 = readTex(uTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1] != 0); \n"); #endif // GL_MULTISAMPLING_SUPPORT } const bool bUseHWLight = config.generalEmulation.enableHWLighting != 0 && GBI.isHWLSupported() && usesShadeColor(); if (bUseHWLight) strFragmentShader.append(" calc_light(vNumLights, vShadeColor.rgb, input_color); \n"); else strFragmentShader.append(" input_color = vShadeColor.rgb;\n"); strFragmentShader.append(" vec_color = vec4(input_color, vShadeColor.a); \n"); strFragmentShader.append(strCombiner); strFragmentShader.append( " if (uEnableAlphaTest != 0) { \n" " lowp float alphaTestValue = (uAlphaCompareMode == 3 && alpha2 > 0.0) ? snoise() : uAlphaTestValue; \n" " if (alpha2 < alphaTestValue) discard; \n" " } \n" ); if (config.generalEmulation.enableNoise != 0) { strFragmentShader.append( " if (uColorDitherMode == 2) colorNoiseDither(snoise(), color2); \n" " if (uAlphaDitherMode == 2) alphaNoiseDither(snoise(), alpha2); \n" ); } strFragmentShader.append( " lowp int fogUsage = uFogUsage; \n" " if (fogUsage >= 256) fogUsage -= 256; \n" " if (fogUsage == 2) fragColor = vec4(color2, uFogColor.a); \n" " else if (fogUsage == 3) fragColor = uFogColor; \n" " else if (fogUsage == 4) fragColor = vec4(color2, uFogColor.a*alpha2); \n" " else fragColor = vec4(color2, alpha2); \n" ); if (video().getRender().isImageTexturesSupported() && config.frameBufferEmulation.N64DepthCompare != 0) strFragmentShader.append(" if (!depth_compare()) discard; \n"); strFragmentShader.append( " if (uFogUsage == 257) \n" " fragColor.rgb = mix(fragColor.rgb, uFogColor.rgb, vFogFragCoord); \n" ); strFragmentShader.append(fragment_shader_end); if (config.generalEmulation.enableNoise == 0) strFragmentShader.append(fragment_shader_dummy_noise); if (bUseLod && config.generalEmulation.enableLOD == 0) strFragmentShader.append(fragment_shader_fake_mipmap); #ifdef GLESX if (bUseHWLight) strFragmentShader.append(fragment_shader_calc_light); if (bUseLod) { if (config.generalEmulation.enableLOD != 0) strFragmentShader.append(fragment_shader_mipmap); } else if (usesTexture()) { strFragmentShader.append(config.texture.bilinearMode == BILINEAR_3POINT ? fragment_shader_readtex_3point : fragment_shader_readtex); #ifdef GL_MULTISAMPLING_SUPPORT if (config.video.multisampling > 0) strFragmentShader.append(fragment_shader_readtex_ms); #endif } #ifdef GL_IMAGE_TEXTURES_SUPPORT if (video().getRender().isImageTexturesSupported() && config.frameBufferEmulation.N64DepthCompare != 0) strFragmentShader.append(depth_compare_shader_float); #endif if (config.generalEmulation.enableNoise != 0) { strFragmentShader.append(fragment_shader_noise); strFragmentShader.append(fragment_shader_dither); } #endif GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); const GLchar * strShaderData = strFragmentShader.data(); glShaderSource(fragmentShader, 1, &strShaderData, NULL); glCompileShader(fragmentShader); if (!checkShaderCompileStatus(fragmentShader)) LOG(LOG_ERROR, "Error in fragment shader:\n%s\n", strFragmentShader.data()); m_program = glCreateProgram(); _locate_attributes(); if (usesTexture()) glAttachShader(m_program, g_vertex_shader_object); else glAttachShader(m_program, g_vertex_shader_object_notex); glAttachShader(m_program, fragmentShader); #ifndef GLESX if (bUseHWLight) glAttachShader(m_program, g_calc_light_shader_object); if (bUseLod) { if (config.generalEmulation.enableLOD != 0) glAttachShader(m_program, g_calc_mipmap_shader_object); } else if (usesTexture()) { glAttachShader(m_program, g_readtex_shader_object); if (config.video.multisampling > 0) glAttachShader(m_program, g_readtex_ms_shader_object); } if (video().getRender().isImageTexturesSupported() && config.frameBufferEmulation.N64DepthCompare != 0) glAttachShader(m_program, g_calc_depth_shader_object); if (config.generalEmulation.enableNoise != 0) { glAttachShader(m_program, g_calc_noise_shader_object); glAttachShader(m_program, g_dither_shader_object); } #endif if (CombinerInfo::get().isShaderCacheSupported()) glProgramParameteri(m_program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE); glLinkProgram(m_program); assert(checkProgramLinkStatus(m_program)); glDeleteShader(fragmentShader); _locateUniforms(); } ShaderCombiner::~ShaderCombiner() { glDeleteProgram(m_program); m_program = 0; } #define LocateUniform(A) \ m_uniforms.A.loc = glGetUniformLocation(m_program, #A); void ShaderCombiner::_locateUniforms() { LocateUniform(uTex0); LocateUniform(uTex1); LocateUniform(uTexNoise); LocateUniform(uTlutImage); LocateUniform(uZlutImage); LocateUniform(uDepthImage); LocateUniform(uFogMode); LocateUniform(uFogUsage); LocateUniform(uAlphaCompareMode); LocateUniform(uAlphaDitherMode); LocateUniform(uColorDitherMode); LocateUniform(uEnableLod); LocateUniform(uEnableAlphaTest); LocateUniform(uEnableDepth); LocateUniform(uEnableDepthCompare) LocateUniform(uEnableDepthUpdate); LocateUniform(uDepthMode); LocateUniform(uDepthSource); LocateUniform(uFbMonochrome); LocateUniform(uFbFixedAlpha); LocateUniform(uMaxTile) LocateUniform(uTextureDetail); LocateUniform(uTexturePersp); LocateUniform(uTextureFilterMode); LocateUniform(uSpecialBlendMode); LocateUniform(uFogAlpha); LocateUniform(uMinLod); LocateUniform(uDeltaZ); LocateUniform(uAlphaTestValue); LocateUniform(uRenderState); LocateUniform(uScreenScale); LocateUniform(uDepthScale); LocateUniform(uFogScale); #ifdef GL_MULTISAMPLING_SUPPORT LocateUniform(uMSTex0); LocateUniform(uMSTex1); LocateUniform(uMSTexEnabled); LocateUniform(uMSAASamples); LocateUniform(uMSAAScale); #endif } void ShaderCombiner::_locate_attributes() const { glBindAttribLocation(m_program, SC_POSITION, "aPosition"); glBindAttribLocation(m_program, SC_COLOR, "aColor"); glBindAttribLocation(m_program, SC_TEXCOORD0, "aTexCoord0"); glBindAttribLocation(m_program, SC_TEXCOORD1, "aTexCoord1"); glBindAttribLocation(m_program, SC_NUMLIGHTS, "aNumLights"); } void ShaderCombiner::update(bool _bForce) { _bForce |= m_bNeedUpdate; m_bNeedUpdate = false; glUseProgram(m_program); if (_bForce) { m_uniforms.uTexNoise.set(g_noiseTexIndex, true); if (usesTexture()) { m_uniforms.uTex0.set(0, true); m_uniforms.uTex1.set(1, true); #ifdef GL_MULTISAMPLING_SUPPORT m_uniforms.uMSTex0.set(g_MSTex0Index + 0, true); m_uniforms.uMSTex1.set(g_MSTex0Index + 1, true); m_uniforms.uMSAASamples.set(config.video.multisampling, true); m_uniforms.uMSAAScale.set(1.0f / (float)config.video.multisampling, true); m_uniforms.uMSTexEnabled.set(0, 0, true); #endif } updateFBInfo(true); updateRenderState(true); } updateFogMode(_bForce); updateDitherMode(_bForce); updateLOD(_bForce); updateTextureInfo(_bForce); updateAlphaTestInfo(_bForce); updateDepthInfo(_bForce); } void ShaderCombiner::updateRenderState(bool _bForce) { m_uniforms.uRenderState.set(video().getRender().getRenderState(), _bForce); } void ShaderCombiner::updateFogMode(bool _bForce) { const u32 blender = (gDP.otherMode.l >> 16); const int nFogBlendEnabled = config.generalEmulation.enableFog != 0 && gSP.fog.multiplier >= 0 && (gDP.otherMode.c1_m1a == 3 || gDP.otherMode.c1_m2a == 3 || gDP.otherMode.c2_m1a == 3 || gDP.otherMode.c2_m2a == 3) ? 256 : 0; int nFogUsage = ((gSP.geometryMode & G_FOG) != 0) ? 1 : 0; int nSpecialBlendMode = 0; switch (blender) { case 0x0150: case 0x0D18: nFogUsage = gDP.otherMode.cycleType == G_CYC_2CYCLE ? 2 : 0; break; case 0x0440: nFogUsage = gDP.otherMode.cycleType == G_CYC_1CYCLE ? 2 : 0; break; case 0xC912: nFogUsage = 2; break; case 0xF550: nFogUsage = 3; break; case 0x0550: nFogUsage = 4; break; case 0x0382: case 0x0091: // Mace // CLR_IN * A_IN + CLR_BL * 1MA if (gDP.otherMode.cycleType == G_CYC_2CYCLE) nSpecialBlendMode = 1; break; case 0xA500: // Bomberman 2 // CLR_BL * A_FOG + CLR_IN * 1MA if (gDP.otherMode.cycleType == G_CYC_1CYCLE) { nSpecialBlendMode = 2; nFogUsage = 5; } break; case 0x07C2: // Conker BFD shadow // CLR_IN * A_FOG + CLR_FOG * 1MA if (gDP.otherMode.cycleType == G_CYC_2CYCLE) { nSpecialBlendMode = 3; nFogUsage = 5; } break; /* Brings troubles with Roadsters sky case 0xc702: // Donald Duck // clr_fog*a_fog + clr_in*1ma nFogUsage = 5; nSpecialBlendMode = 2; break; */ } int nFogMode = 0; // Normal if (nFogUsage == 0) { switch (blender) { case 0xC410: case 0xC411: case 0xF500: nFogMode = 1; // fog blend nFogUsage = 1; break; case 0x04D1: nFogMode = 2; // inverse fog blend nFogUsage = 1; break; } } m_uniforms.uSpecialBlendMode.set(nSpecialBlendMode, _bForce); m_uniforms.uFogUsage.set(nFogUsage | nFogBlendEnabled, _bForce); m_uniforms.uFogMode.set(nFogMode, _bForce); if (nFogUsage + nFogMode != 0) { m_uniforms.uFogScale.set((float)gSP.fog.multiplier / 256.0f, (float)gSP.fog.offset / 256.0f, _bForce); m_uniforms.uFogAlpha.set(gDP.fogColor.a, _bForce); } } void ShaderCombiner::updateDitherMode(bool _bForce) { if (gDP.otherMode.cycleType < G_CYC_COPY) { m_uniforms.uAlphaCompareMode.set(gDP.otherMode.alphaCompare, _bForce); m_uniforms.uAlphaDitherMode.set(gDP.otherMode.alphaDither, _bForce); m_uniforms.uColorDitherMode.set(gDP.otherMode.colorDither, _bForce); } else { m_uniforms.uAlphaCompareMode.set(0, _bForce); m_uniforms.uAlphaDitherMode.set(0, _bForce); m_uniforms.uColorDitherMode.set(0, _bForce); } const int nDither = (gDP.otherMode.cycleType < G_CYC_COPY) && (gDP.otherMode.colorDither == G_CD_NOISE || gDP.otherMode.alphaDither == G_AD_NOISE || gDP.otherMode.alphaCompare == G_AC_DITHER) ? 1 : 0; if ((m_nInputs & (1 << NOISE)) + nDither != 0) { m_uniforms.uScreenScale.set(video().getScaleX(), video().getScaleY(), _bForce); noiseTex.update(); } } void ShaderCombiner::updateLOD(bool _bForce) { if (!usesLOD()) return; m_uniforms.uMinLod.set(gDP.primColor.m, _bForce); m_uniforms.uMaxTile.set(gSP.texture.level, _bForce); if (config.generalEmulation.enableLOD != 0) { const int uCalcLOD = (gDP.otherMode.textureLOD == G_TL_LOD) ? 1 : 0; m_uniforms.uEnableLod.set(uCalcLOD, _bForce); m_uniforms.uScreenScale.set(video().getScaleX(), video().getScaleY(), _bForce); m_uniforms.uTextureDetail.set(gDP.otherMode.textureDetail, _bForce); } } void ShaderCombiner::updateTextureInfo(bool _bForce) { m_uniforms.uTexturePersp.set(gDP.otherMode.texturePersp, _bForce); if (config.texture.bilinearMode == BILINEAR_3POINT) m_uniforms.uTextureFilterMode.set(gDP.otherMode.textureFilter | (gSP.objRendermode&G_OBJRM_BILERP), _bForce); } void ShaderCombiner::updateFBInfo(bool _bForce) { if (!usesTexture()) return; int nFbMonochromeMode0 = 0, nFbMonochromeMode1 = 0; int nFbFixedAlpha0 = 0, nFbFixedAlpha1 = 0; int nMSTex0Enabled = 0, nMSTex1Enabled = 0; TextureCache & cache = textureCache(); if (cache.current[0] != NULL && cache.current[0]->frameBufferTexture != CachedTexture::fbNone) { if (cache.current[0]->size == G_IM_SIZ_8b) { nFbMonochromeMode0 = 1; if (gDP.otherMode.imageRead == 0) nFbFixedAlpha0 = 1; } else if (gSP.textureTile[0]->size == G_IM_SIZ_16b && gSP.textureTile[0]->format == G_IM_FMT_IA) nFbMonochromeMode0 = 2; nMSTex0Enabled = cache.current[0]->frameBufferTexture == CachedTexture::fbMultiSample ? 1 : 0; } if (cache.current[1] != NULL && cache.current[1]->frameBufferTexture != CachedTexture::fbNone) { if (cache.current[1]->size == G_IM_SIZ_8b) { nFbMonochromeMode1 = 1; if (gDP.otherMode.imageRead == 0) nFbFixedAlpha1 = 1; } else if (gSP.textureTile[1]->size == G_IM_SIZ_16b && gSP.textureTile[1]->format == G_IM_FMT_IA) nFbMonochromeMode1 = 2; nMSTex1Enabled = cache.current[1]->frameBufferTexture == CachedTexture::fbMultiSample ? 1 : 0; } m_uniforms.uFbMonochrome.set(nFbMonochromeMode0, nFbMonochromeMode1, _bForce); m_uniforms.uFbFixedAlpha.set(nFbFixedAlpha0, nFbFixedAlpha1, _bForce); m_uniforms.uMSTexEnabled.set(nMSTex0Enabled, nMSTex1Enabled, _bForce); gDP.changed &= ~CHANGED_FB_TEXTURE; } void ShaderCombiner::updateDepthInfo(bool _bForce) { if (RSP.bLLE) m_uniforms.uDepthScale.set(0.5f, 0.5f, _bForce); else m_uniforms.uDepthScale.set(gSP.viewport.vscale[2], gSP.viewport.vtrans[2], _bForce); if (config.frameBufferEmulation.N64DepthCompare == 0 || !video().getRender().isImageTexturesSupported()) return; FrameBuffer * pBuffer = frameBufferList().getCurrent(); if (pBuffer == NULL || pBuffer->m_pDepthBuffer == NULL) return; const int nDepthEnabled = (gSP.geometryMode & G_ZBUFFER) > 0 ? 1 : 0; m_uniforms.uEnableDepth.set(nDepthEnabled, _bForce); if (nDepthEnabled == 0) { m_uniforms.uEnableDepthCompare.set(0, _bForce); m_uniforms.uEnableDepthUpdate.set(0, _bForce); } else { m_uniforms.uEnableDepthCompare.set(gDP.otherMode.depthCompare, _bForce); m_uniforms.uEnableDepthUpdate.set(gDP.otherMode.depthUpdate, _bForce); } m_uniforms.uDepthMode.set(gDP.otherMode.depthMode, _bForce); m_uniforms.uDepthSource.set(gDP.otherMode.depthSource, _bForce); if (gDP.otherMode.depthSource == G_ZS_PRIM) m_uniforms.uDeltaZ.set(gDP.primDepth.deltaZ, _bForce); } void ShaderCombiner::updateAlphaTestInfo(bool _bForce) { if (gDP.otherMode.cycleType == G_CYC_FILL) { m_uniforms.uEnableAlphaTest.set(0, _bForce); m_uniforms.uAlphaTestValue.set(0.0f, _bForce); } else if (gDP.otherMode.cycleType == G_CYC_COPY) { if (gDP.otherMode.alphaCompare & G_AC_THRESHOLD) { m_uniforms.uEnableAlphaTest.set(1, _bForce); m_uniforms.uAlphaTestValue.set(0.5f, _bForce); } else { m_uniforms.uEnableAlphaTest.set(0, _bForce); m_uniforms.uAlphaTestValue.set(0.0f, _bForce); } } else if (((gDP.otherMode.alphaCompare & G_AC_THRESHOLD) != 0) && (gDP.otherMode.alphaCvgSel == 0) && (gDP.otherMode.forceBlender == 0 || gDP.blendColor.a > 0)) { m_uniforms.uEnableAlphaTest.set(1, _bForce); m_uniforms.uAlphaTestValue.set(max(gDP.blendColor.a, 1.0f / 256.0f), _bForce); } else if ((gDP.otherMode.alphaCompare == G_AC_DITHER) && (gDP.otherMode.alphaCvgSel == 0)) { m_uniforms.uEnableAlphaTest.set(1, _bForce); m_uniforms.uAlphaTestValue.set(0.0f, _bForce); } else if (gDP.otherMode.cvgXAlpha != 0) { m_uniforms.uEnableAlphaTest.set(1, _bForce); m_uniforms.uAlphaTestValue.set(0.125f, _bForce); } else { m_uniforms.uEnableAlphaTest.set(0, _bForce); m_uniforms.uAlphaTestValue.set(0.0f, _bForce); } } std::ostream & operator<< (std::ostream & _os, const ShaderCombiner & _combiner) { GLint binaryLength; glGetProgramiv(_combiner.m_program, GL_PROGRAM_BINARY_LENGTH, &binaryLength); if (binaryLength < 1) return _os; std::vector binary(binaryLength); if (binary.size() == 0) return _os; GLenum binaryFormat; glGetProgramBinary(_combiner.m_program, binaryLength, &binaryLength, &binaryFormat, binary.data()); if (isGLError()) return _os; _os.write((char*)&_combiner.m_combine.mux, sizeof(_combiner.m_combine.mux)); _os.write((char*)&_combiner.m_nInputs, sizeof(_combiner.m_nInputs)); _os.write((char*)&binaryFormat, sizeof(binaryFormat)); _os.write((char*)&binaryLength, sizeof(binaryLength)); _os.write(binary.data(), binaryLength); return _os; } std::istream & operator>> (std::istream & _is, ShaderCombiner & _combiner) { _is.read((char*)&_combiner.m_combine.mux, sizeof(_combiner.m_combine.mux)); _is.read((char*)&_combiner.m_nInputs, sizeof(_combiner.m_nInputs)); GLenum binaryFormat; GLint binaryLength; _is.read((char*)&binaryFormat, sizeof(binaryFormat)); _is.read((char*)&binaryLength, sizeof(binaryLength)); std::vector binary(binaryLength); _is.read(binary.data(), binaryLength); glProgramBinary(_combiner.m_program, binaryFormat, binary.data(), binaryLength); assert(checkProgramLinkStatus(_combiner.m_program)); _combiner._locateUniforms(); return _is; } void ShaderCombiner::getShaderCombinerOptionsSet(std::vector & _vecOptions) { // WARNING: Shader Storage format version must be increased after any change in this function. _vecOptions.push_back(config.video.multisampling > 0 ? 1 : 0); _vecOptions.push_back(config.texture.bilinearMode); _vecOptions.push_back(config.generalEmulation.enableHWLighting); _vecOptions.push_back(config.generalEmulation.enableNoise); _vecOptions.push_back(config.generalEmulation.enableLOD); _vecOptions.push_back(config.frameBufferEmulation.N64DepthCompare); } #ifdef GL_IMAGE_TEXTURES_SUPPORT void SetDepthFogCombiner() { if (!video().getRender().isImageTexturesSupported()) return; if (g_paletteCRC256 != gDP.paletteCRC256) { g_paletteCRC256 = gDP.paletteCRC256; #ifdef GLESX u32 palette[256]; #else u16 palette[256]; #endif u16 *src = (u16*)&TMEM[256]; for (int i = 0; i < 256; ++i) palette[i] = swapword(src[i*4]); glBindImageTexture(TlutImageUnit, 0, 0, GL_FALSE, 0, GL_READ_ONLY, fboFormats.lutInternalFormat); glBindTexture(GL_TEXTURE_2D, g_tlut_tex); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 1, fboFormats.lutFormat, fboFormats.lutType, palette); glBindTexture(GL_TEXTURE_2D, 0); glBindImageTexture(TlutImageUnit, g_tlut_tex, 0, GL_FALSE, 0, GL_READ_ONLY, fboFormats.lutInternalFormat); } glUseProgram(g_draw_shadow_map_program); int loc = glGetUniformLocation(g_draw_shadow_map_program, "uFogColor"); if (loc >= 0) glUniform4fv(loc, 1, &gDP.fogColor.r); gDP.changed |= CHANGED_COMBINE; } #endif // GL_IMAGE_TEXTURES_SUPPORT void SetMonochromeCombiner() { glUseProgram(g_monochrome_image_program); gDP.changed |= CHANGED_COMBINE; } gles2n64/src/S2DEX.c000664 001750 001750 00000006167 12655644434 015055 0ustar00sergiosergio000000 000000 #include "OpenGL.h" #include "S2DEX.h" #include "F3D.h" #include "F3DEX.h" #include "GBI.h" #include "gSP.h" #include "gDP.h" #include "RSP.h" #include "Types.h" void S2DEX_BG_1Cyc( u32 w0, u32 w1 ) { gSPBgRect1Cyc( w1 ); } void S2DEX_BG_Copy( u32 w0, u32 w1 ) { gSPBgRectCopy( w1 ); } void S2DEX_Obj_Rectangle( u32 w0, u32 w1 ) { gSPObjRectangle( w1 ); } void S2DEX_Obj_Sprite( u32 w0, u32 w1 ) { gSPObjSprite( w1 ); } void S2DEX_Obj_MoveMem( u32 w0, u32 w1 ) { switch (_SHIFTR( w0, 0, 16 )) { case S2DEX_MV_MATRIX: gSPObjMatrix( w1 ); break; case S2DEX_MV_SUBMUTRIX: gSPObjSubMatrix( w1 ); break; case S2DEX_MV_VIEWPORT: gSPViewport( w1 ); break; } } void S2DEX_Select_DL( u32 w0, u32 w1 ) { #ifdef DEBUG LOG(LOG_WARNING, "S2DEX_Select_DL unimplemented\n"); #endif } void S2DEX_Obj_RenderMode( u32 w0, u32 w1 ) { gSPObjRendermode(w1); } void S2DEX_Obj_Rectangle_R( u32 w0, u32 w1 ) { gSPObjRectangleR(w1); } void S2DEX_Obj_LoadTxtr( u32 w0, u32 w1 ) { gSPObjLoadTxtr( w1 ); } void S2DEX_Obj_LdTx_Sprite( u32 w0, u32 w1 ) { gSPObjLoadTxSprite( w1 ); } void S2DEX_Obj_LdTx_Rect( u32 w0, u32 w1 ) { gSPObjLoadTxSprite( w1 ); } void S2DEX_Obj_LdTx_Rect_R( u32 w0, u32 w1 ) { gSPObjLoadTxRectR( w1 ); } void S2DEX_Init(void) { // Set GeometryMode flags GBI_InitFlags( F3DEX ); GBI.PCStackSize = 18; // GBI Command Command Value Command Function GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_BG_1CYC, S2DEX_BG_1CYC, S2DEX_BG_1Cyc ); GBI_SetGBI( G_BG_COPY, S2DEX_BG_COPY, S2DEX_BG_Copy ); GBI_SetGBI( G_OBJ_RECTANGLE, S2DEX_OBJ_RECTANGLE, S2DEX_Obj_Rectangle ); GBI_SetGBI( G_OBJ_SPRITE, S2DEX_OBJ_SPRITE, S2DEX_Obj_Sprite ); GBI_SetGBI( G_OBJ_MOVEMEM, S2DEX_OBJ_MOVEMEM, S2DEX_Obj_MoveMem ); GBI_SetGBI( G_DL, F3D_DL, F3D_DList ); GBI_SetGBI( G_SELECT_DL, S2DEX_SELECT_DL, S2DEX_Select_DL ); GBI_SetGBI( G_OBJ_RENDERMODE, S2DEX_OBJ_RENDERMODE, S2DEX_Obj_RenderMode ); GBI_SetGBI( G_OBJ_RECTANGLE_R, S2DEX_OBJ_RECTANGLE_R, S2DEX_Obj_Rectangle_R ); GBI_SetGBI( G_OBJ_LOADTXTR, S2DEX_OBJ_LOADTXTR, S2DEX_Obj_LoadTxtr ); GBI_SetGBI( G_OBJ_LDTX_SPRITE, S2DEX_OBJ_LDTX_SPRITE, S2DEX_Obj_LdTx_Sprite ); GBI_SetGBI( G_OBJ_LDTX_RECT, S2DEX_OBJ_LDTX_RECT, S2DEX_Obj_LdTx_Rect ); GBI_SetGBI( G_OBJ_LDTX_RECT_R, S2DEX_OBJ_LDTX_RECT_R, S2DEX_Obj_LdTx_Rect_R ); GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3D_MoveWord ); GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L ); GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL ); GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_LOAD_UCODE, S2DEX_LOAD_UCODE, F3DEX_Load_uCode ); } mupen64plus-core/src/api/m64p_common.h000664 001750 001750 00000005550 12655644434 020723 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-core - m64p_common.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2009 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This header file defines typedefs for function pointers to common Core * and plugin functions, for use by the front-end and plugin modules to attach * to the dynamic libraries. */ #ifndef M64P_COMMON_H #define M64P_COMMON_H #include "m64p_types.h" #ifdef __cplusplus extern "C" { #endif /* PluginGetVersion() * * This function retrieves version information from a library. This * function is the same for the core library and the plugins. */ typedef m64p_error (*ptr_PluginGetVersion)(m64p_plugin_type *, int *, int *, const char **, int *); #if defined(M64P_PLUGIN_PROTOTYPES) || defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL PluginGetVersion(m64p_plugin_type *, int *, int *, const char **, int *); #endif /* CoreGetAPIVersions() * * This function retrieves API version information from the core. */ typedef m64p_error (*ptr_CoreGetAPIVersions)(int *, int *, int *, int *); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL CoreGetAPIVersions(int *, int *, int *, int *); #endif /* CoreErrorMessage() * * This function returns a pointer to a NULL-terminated string giving a * human-readable description of the error. */ typedef const char * (*ptr_CoreErrorMessage)(m64p_error); #if defined(M64P_CORE_PROTOTYPES) EXPORT const char * CALL CoreErrorMessage(m64p_error); #endif #ifdef __cplusplus } #endif #endif /* #define M64P_COMMON_H */ mupen64plus-core/src/main/main.h000664 001750 001750 00000006123 12655644434 017661 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - main.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2012 CasualJames * * Copyright (C) 2002 Blight * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef __MAIN_H__ #define __MAIN_H__ #include "api/m64p_types.h" #include "osal/preproc.h" #include struct r4300_core; struct rsp_core; struct ai_controller; struct pi_controller; struct ri_controller; struct si_controller; struct vi_controller; struct dd_controller; enum { RDRAM_MAX_SIZE = 0x800000 }; /* globals */ extern m64p_handle g_CoreConfig; extern int g_MemHasBeenBSwapped; extern int g_DDMemHasBeenBSwapped; extern int g_EmulatorRunning; extern ALIGN(16, uint32_t g_rdram[RDRAM_MAX_SIZE/4]); extern struct ai_controller g_ai; extern struct pi_controller g_pi; extern struct ri_controller g_ri; extern struct si_controller g_si; extern struct vi_controller g_vi; extern struct dd_controller g_dd; extern struct r4300_core g_r4300; extern struct rdp_core g_dp; extern struct rsp_core g_sp; extern m64p_frame_callback g_FrameCallback; extern int g_delay_si; extern int g_gs_vi_counter; void new_frame(void); int main_set_core_defaults(void); void main_message(m64p_msg_level level, unsigned int osd_corner, const char *format, ...); m64p_error main_init(void); m64p_error main_run(void); void main_exit(void); void main_stop(void); void main_toggle_pause(void); void main_advance_one(void); void main_check_inputs(void); void new_vi(void); m64p_error main_core_state_query(m64p_core_param param, int *rval); m64p_error main_core_state_set(m64p_core_param param, int val); m64p_error main_read_screen(void *pixels, int bFront); m64p_error main_reset(int do_hard_reset); #endif /* __MAIN_H__ */ gles2rice/src/RSP_Parser.h000664 001750 001750 00000046337 12655644434 016533 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __RICE_RDP_GFX_H__ #define __RICE_RDP_GFX_H__ #define RSP_SPNOOP 0 // handle 0 gracefully #define RSP_MTX 1 #define RSP_RESERVED0 2 // unknown #define RSP_MOVEMEM 3 // move a block of memory (up to 4 words) to dmem #define RSP_VTX 4 #define RSP_RESERVED1 5 // unknown #define RSP_DL 6 #define RSP_RESERVED2 7 // unknown #define RSP_RESERVED3 8 // unknown #define RSP_SPRITE2D 9 // sprite command #define RSP_SPRITE2D_BASE 9 // sprite command #define RSP_1ST 0xBF #define RSP_TRI1 (RSP_1ST-0) #define RSP_CULLDL (RSP_1ST-1) #define RSP_POPMTX (RSP_1ST-2) #define RSP_MOVEWORD (RSP_1ST-3) #define RSP_TEXTURE (RSP_1ST-4) #define RSP_SETOTHERMODE_H (RSP_1ST-5) #define RSP_SETOTHERMODE_L (RSP_1ST-6) #define RSP_ENDDL (RSP_1ST-7) #define RSP_SETGEOMETRYMODE (RSP_1ST-8) #define RSP_CLEARGEOMETRYMODE (RSP_1ST-9) #define RSP_LINE3D (RSP_1ST-10) #define RSP_RDPHALF_1 (RSP_1ST-11) #define RSP_RDPHALF_2 (RSP_1ST-12) #define RSP_RDPHALF_CONT (RSP_1ST-13) #define RSP_MODIFYVTX (RSP_1ST-13) #define RSP_TRI2 (RSP_1ST-14) #define RSP_BRANCH_Z (RSP_1ST-15) #define RSP_LOAD_UCODE (RSP_1ST-16) #define RSP_SPRITE2D_SCALEFLIP (RSP_1ST-1) #define RSP_SPRITE2D_DRAW (RSP_1ST-2) #define RSP_ZELDAVTX 1 #define RSP_ZELDAMODIFYVTX 2 #define RSP_ZELDACULLDL 3 #define RSP_ZELDABRANCHZ 4 #define RSP_ZELDATRI1 5 #define RSP_ZELDATRI2 6 #define RSP_ZELDALINE3D 7 #define RSP_ZELDARDPHALF_2 0xf1 #define RSP_ZELDASETOTHERMODE_H 0xe3 #define RSP_ZELDASETOTHERMODE_L 0xe2 #define RSP_ZELDARDPHALF_1 0xe1 #define RSP_ZELDASPNOOP 0xe0 #define RSP_ZELDAENDDL 0xdf #define RSP_ZELDADL 0xde #define RSP_ZELDALOAD_UCODE 0xdd #define RSP_ZELDAMOVEMEM 0xdc #define RSP_ZELDAMOVEWORD 0xdb #define RSP_ZELDAMTX 0xda #define RSP_ZELDAGEOMETRYMODE 0xd9 #define RSP_ZELDAPOPMTX 0xd8 #define RSP_ZELDATEXTURE 0xd7 #define RSP_ZELDASUBMODULE 0xd6 // 4 is something like a conditional DL #define RSP_DMATRI 0x05 #define G_DLINMEM 0x07 // RDP commands: #define RDP_NOOP 0xc0 #define RDP_SETCIMG 0xff #define RDP_SETZIMG 0xfe #define RDP_SETTIMG 0xfd #define RDP_SETCOMBINE 0xfc #define RDP_SETENVCOLOR 0xfb #define RDP_SETPRIMCOLOR 0xfa #define RDP_SETBLENDCOLOR 0xf9 #define RDP_SETFOGCOLOR 0xf8 #define RDP_SETFILLCOLOR 0xf7 #define RDP_FILLRECT 0xf6 #define RDP_SETTILE 0xf5 #define RDP_LOADTILE 0xf4 #define RDP_LOADBLOCK 0xf3 #define RDP_SETTILESIZE 0xf2 #define RDP_LOADTLUT 0xf0 #define RDP_RDPSETOTHERMODE 0xef #define RDP_SETPRIMDEPTH 0xee #define RDP_SETSCISSOR 0xed #define RDP_SETCONVERT 0xec #define RDP_SETKEYR 0xeb #define RDP_SETKEYGB 0xea #define RDP_FULLSYNC 0xe9 #define RDP_TILESYNC 0xe8 #define RDP_PIPESYNC 0xe7 #define RDP_LOADSYNC 0xe6 #define RDP_TEXRECT_FLIP 0xe5 #define RDP_TEXRECT 0xe4 #define RSP_ZELDA_MTX_MODELVIEW 0x00 #define RSP_ZELDA_MTX_PROJECTION 0x04 #define RSP_ZELDA_MTX_MUL 0x00 #define RSP_ZELDA_MTX_LOAD 0x02 #define RSP_ZELDA_MTX_PUSH 0x00 #define RSP_ZELDA_MTX_NOPUSH 0x01 // // RSP_SETOTHERMODE_L sft: shift count #define RSP_SETOTHERMODE_SHIFT_ALPHACOMPARE 0 #define RSP_SETOTHERMODE_SHIFT_ZSRCSEL 2 #define RSP_SETOTHERMODE_SHIFT_RENDERMODE 3 #define RSP_SETOTHERMODE_SHIFT_BLENDER 16 // // RSP_SETOTHERMODE_H sft: shift count #define RSP_SETOTHERMODE_SHIFT_BLENDMASK 0 // unsupported #define RSP_SETOTHERMODE_SHIFT_ALPHADITHER 4 #define RSP_SETOTHERMODE_SHIFT_RGBDITHER 6 #define RSP_SETOTHERMODE_SHIFT_COMBKEY 8 #define RSP_SETOTHERMODE_SHIFT_TEXTCONV 9 #define RSP_SETOTHERMODE_SHIFT_TEXTFILT 12 #define RSP_SETOTHERMODE_SHIFT_TEXTLUT 14 #define RSP_SETOTHERMODE_SHIFT_TEXTLOD 16 #define RSP_SETOTHERMODE_SHIFT_TEXTDETAIL 17 #define RSP_SETOTHERMODE_SHIFT_TEXTPERSP 19 #define RSP_SETOTHERMODE_SHIFT_CYCLETYPE 20 #define RSP_SETOTHERMODE_SHIFT_COLORDITHER 22 // unsupported in HW 2.0 #define RSP_SETOTHERMODE_SHIFT_PIPELINE 23 // RSP_SETOTHERMODE_H gPipelineMode #define RSP_PIPELINE_MODE_1PRIMITIVE (1 << RSP_SETOTHERMODE_SHIFT_PIPELINE) #define RSP_PIPELINE_MODE_NPRIMITIVE (0 << RSP_SETOTHERMODE_SHIFT_PIPELINE) // RSP_SETOTHERMODE_H gSetCycleType #define CYCLE_TYPE_1 0 #define CYCLE_TYPE_2 1 #define CYCLE_TYPE_COPY 2 #define CYCLE_TYPE_FILL 3 // RSP_SETOTHERMODE_H gSetTextureLUT #define TLUT_FMT_NONE (0 << RSP_SETOTHERMODE_SHIFT_TEXTLUT) #define TLUT_FMT_UNKNOWN (1 << RSP_SETOTHERMODE_SHIFT_TEXTLUT) #define TLUT_FMT_RGBA16 (2 << RSP_SETOTHERMODE_SHIFT_TEXTLUT) #define TLUT_FMT_IA16 (3 << RSP_SETOTHERMODE_SHIFT_TEXTLUT) // RSP_SETOTHERMODE_H gSetTextureFilter #define RDP_TFILTER_POINT (0 << RSP_SETOTHERMODE_SHIFT_TEXTFILT) #define RDP_TFILTER_AVERAGE (3 << RSP_SETOTHERMODE_SHIFT_TEXTFILT) #define RDP_TFILTER_BILERP (2 << RSP_SETOTHERMODE_SHIFT_TEXTFILT) // RSP_SETOTHERMODE_L gSetAlphaCompare #define RDP_ALPHA_COMPARE_NONE (0 << RSP_SETOTHERMODE_SHIFT_ALPHACOMPARE) #define RDP_ALPHA_COMPARE_THRESHOLD (1 << RSP_SETOTHERMODE_SHIFT_ALPHACOMPARE) #define RDP_ALPHA_COMPARE_DITHER (3 << RSP_SETOTHERMODE_SHIFT_ALPHACOMPARE) // RSP_SETOTHERMODE_L gSetRenderMode #define Z_COMPARE 0x0010 #define Z_UPDATE 0x0020 #define ZMODE_DEC 0x0c00 // // flags for RSP_SETGEOMETRYMODE // #define G_ZBUFFER 0x00000001 #define G_TEXTURE_ENABLE 0x00000002 // Microcode use only #define G_SHADE 0x00000004 // Enable Gouraud interp // #define G_SHADING_SMOOTH 0x00000200 // Flat or smooth shaded #define G_CULL_FRONT 0x00001000 #define G_CULL_BACK 0x00002000 #define G_CULL_BOTH 0x00003000 // To make code cleaner #define G_FOG 0x00010000 #define G_LIGHTING 0x00020000 #define G_TEXTURE_GEN 0x00040000 #define G_TEXTURE_GEN_LINEAR 0x00080000 #define G_LOD 0x00100000 // NOT IMPLEMENTED // // G_SETIMG fmt: set image formats // #define TXT_FMT_RGBA 0 #define TXT_FMT_YUV 1 #define TXT_FMT_CI 2 #define TXT_FMT_IA 3 #define TXT_FMT_I 4 // // G_SETIMG siz: set image pixel size // #define TXT_SIZE_4b 0 #define TXT_SIZE_8b 1 #define TXT_SIZE_16b 2 #define TXT_SIZE_32b 3 // // Texturing macros // #define RDP_TXT_LOADTILE 7 #define RDP_TXT_RENDERTILE 0 #define RDP_TXT_NOMIRROR 0 #define RDP_TXT_WRAP 0 #define RDP_TXT_MIRROR 0x1 #define RDP_TXT_CLAMP 0x2 #define RDP_TXT_NOMASK 0 #define RDP_TXT_NOLOD 0 // // MOVEMEM indices // // Each of these indexes an entry in a dmem table // which points to a 1-4 word block of dmem in // which to store a 1-4 word DMA. // // #define RSP_GBI1_MV_MEM_VIEWPORT 0x80 #define RSP_GBI1_MV_MEM_LOOKATY 0x82 #define RSP_GBI1_MV_MEM_LOOKATX 0x84 #define RSP_GBI1_MV_MEM_L0 0x86 #define RSP_GBI1_MV_MEM_L1 0x88 #define RSP_GBI1_MV_MEM_L2 0x8a #define RSP_GBI1_MV_MEM_L3 0x8c #define RSP_GBI1_MV_MEM_L4 0x8e #define RSP_GBI1_MV_MEM_L5 0x90 #define RSP_GBI1_MV_MEM_L6 0x92 #define RSP_GBI1_MV_MEM_L7 0x94 #define RSP_GBI1_MV_MEM_TXTATT 0x96 #define RSP_GBI1_MV_MEM_MATRIX_1 0x9e // NOTE: this is in moveword table #define RSP_GBI1_MV_MEM_MATRIX_2 0x98 #define RSP_GBI1_MV_MEM_MATRIX_3 0x9a #define RSP_GBI1_MV_MEM_MATRIX_4 0x9c # define RSP_GBI2_MV_MEM__VIEWPORT 8 # define RSP_GBI2_MV_MEM__LIGHT 10 # define RSP_GBI2_MV_MEM__POINT 12 # define RSP_GBI2_MV_MEM__MATRIX 14 // NOTE: this is in moveword table # define RSP_GBI2_MV_MEM_O_LOOKATX (0*24) # define RSP_GBI2_MV_MEM_O_LOOKATY (1*24) # define RSP_GBI2_MV_MEM_O_L0 (2*24) # define RSP_GBI2_MV_MEM_O_L1 (3*24) # define RSP_GBI2_MV_MEM_O_L2 (4*24) # define RSP_GBI2_MV_MEM_O_L3 (5*24) # define RSP_GBI2_MV_MEM_O_L4 (6*24) # define RSP_GBI2_MV_MEM_O_L5 (7*24) # define RSP_GBI2_MV_MEM_O_L6 (8*24) # define RSP_GBI2_MV_MEM_O_L7 (9*24) // // MOVEWORD indices // // Each of these indexes an entry in a dmem table // which points to a word in dmem in dmem where // an immediate word will be stored. // // #define RSP_MOVE_WORD_MATRIX 0x00 // NOTE: also used by movemem #define RSP_MOVE_WORD_NUMLIGHT 0x02 #define RSP_MOVE_WORD_CLIP 0x04 #define RSP_MOVE_WORD_SEGMENT 0x06 #define RSP_MOVE_WORD_FOG 0x08 #define RSP_MOVE_WORD_LIGHTCOL 0x0a #define RSP_MOVE_WORD_POINTS 0x0c #define RSP_MOVE_WORD_PERSPNORM 0x0e // // These are offsets from the address in the dmem table // #define RSP_MV_WORD_OFFSET_NUMLIGHT 0x00 #define RSP_MV_WORD_OFFSET_CLIP_RNX 0x04 #define RSP_MV_WORD_OFFSET_CLIP_RNY 0x0c #define RSP_MV_WORD_OFFSET_CLIP_RPX 0x14 #define RSP_MV_WORD_OFFSET_CLIP_RPY 0x1c #define RSP_MV_WORD_OFFSET_FOG 0x00 #define RSP_MV_WORD_OFFSET_POINT_RGBA 0x10 #define RSP_MV_WORD_OFFSET_POINT_ST 0x14 #define RSP_MV_WORD_OFFSET_POINT_XYSCREEN 0x18 #define RSP_MV_WORD_OFFSET_POINT_ZSCREEN 0x1c // Flags to inhibit pushing of the display list (on branch) #define RSP_DLIST_PUSH 0x00 #define RSP_DLIST_NOPUSH 0x01 // // RSP_MTX: parameter flags // #define RSP_MATRIX_MODELVIEW 0x00 #define RSP_MATRIX_PROJECTION 0x01 #define RSP_MATRIX_MUL 0x00 #define RSP_MATRIX_LOAD 0x02 #define RSP_MATRIX_NOPUSH 0x00 #define RSP_MATRIX_PUSH 0x04 typedef struct { uint32_t type; uint32_t flags; uint32_t ucode_boot; uint32_t ucode_boot_size; uint32_t ucode; uint32_t ucode_size; uint32_t ucode_data; uint32_t ucode_data_size; uint32_t dram_stack; uint32_t dram_stack_size; uint32_t output_buff; uint32_t output_buff_size; uint32_t data_ptr; uint32_t data_size; uint32_t yield_data_ptr; uint32_t yield_data_size; } OSTask_t; typedef union { OSTask_t t; uint64_t force_structure_alignment; } OSTask; #define MAX_DL_STACK_SIZE 32 #define MAX_DL_COUNT 1000000 typedef struct { bool used; uint32_t crc_size; uint32_t crc_800; uint32_t ucode; uint32_t minor_ver; uint32_t variant; char rspstr[200]; uint32_t ucStart; uint32_t ucSize; uint32_t ucDStart; uint32_t ucDSize; uint32_t ucCRC; uint32_t ucDWORD1; uint32_t ucDWORD2; uint32_t ucDWORD3; uint32_t ucDWORD4; } UcodeInfo; typedef struct { uint32_t ucode; uint32_t crc_size; uint32_t crc_800; const unsigned char * ucode_name; bool non_nearclip; bool reject; } UcodeData; struct TileDescriptor { // Set by SetTile unsigned int dwFormat :3; // e.g. RGBA, YUV etc unsigned int dwSize :2; // e.g 4/8/16/32bpp unsigned int dwLine :9; // Ummm... unsigned int dwPalette :4; // 0..15 - a palette index? uint32_t dwTMem; // Texture memory location unsigned int bClampS :1; unsigned int bClampT :1; unsigned int bMirrorS :1; unsigned int bMirrorT :1; unsigned int dwMaskS :4; unsigned int dwMaskT :4; unsigned int dwShiftS :4; unsigned int dwShiftT :4; // Set by SetTileSize unsigned int sl :10; // Upper left S - 8:3 unsigned int tl :10; // Upper Left T - 8:3 unsigned int sh :10; // Lower Right S unsigned int th :10; // Lower Right T }; enum LoadType { BY_NEVER_SET, BY_LOAD_BLOCK, BY_LOAD_TILE, BY_LOAD_TLUT, }; struct LoadCmdInfo { LoadType loadtype; unsigned int sl :10; // Upper left S - 8:3 unsigned int tl :10; // Upper Left T - 8:3 unsigned int sh :10; // Lower Right S unsigned int th :10; // Lower Right T unsigned int dxt :12; }; typedef struct { // This is in Intel format uint32_t SourceImagePointer; uint32_t TlutPointer; short SubImageWidth; short Stride; char SourceImageBitSize; char SourceImageType; short SubImageHeight; short SourceImageOffsetT; short SourceImageOffsetS; char dummy[4]; } SpriteStruct; //Converted Sprint struct in Intel format typedef struct{ short px; short py; float scaleX; float scaleY; uint8_t flipX; uint8_t flipY; SpriteStruct *spritePtr; } Sprite2DInfo; typedef struct { unsigned int c2_m2b:2; unsigned int c1_m2b:2; unsigned int c2_m2a:2; unsigned int c1_m2a:2; unsigned int c2_m1b:2; unsigned int c1_m1b:2; unsigned int c2_m1a:2; unsigned int c1_m1a:2; } RDP_BlenderSetting; typedef struct { union { struct { // Low bits unsigned int alpha_compare : 2; // 0..1 unsigned int depth_source : 1; // 2..2 // unsigned int render_mode : 13; // 3..15 unsigned int aa_en : 1; // 3 unsigned int z_cmp : 1; // 4 unsigned int z_upd : 1; // 5 unsigned int im_rd : 1; // 6 unsigned int clr_on_cvg : 1; // 7 unsigned int cvg_dst : 2; // 8..9 unsigned int zmode : 2; // 10..11 unsigned int cvg_x_alpha : 1; // 12 unsigned int alpha_cvg_sel : 1; // 13 unsigned int force_bl : 1; // 14 unsigned int tex_edge : 1; // 15 - Not used unsigned int blender : 16; // 16..31 // High bits unsigned int blend_mask : 4; // 0..3 - not supported unsigned int alpha_dither : 2; // 4..5 unsigned int rgb_dither : 2; // 6..7 unsigned int key_en : 1; // 8..8 unsigned int text_conv : 3; // 9..11 unsigned int text_filt : 2; // 12..13 unsigned int text_tlut : 2; // 14..15 unsigned int text_lod : 1; // 16..16 unsigned int text_sharpen : 1; // 17..18 unsigned int text_detail : 1; // 17..18 unsigned int text_persp : 1; // 19..19 unsigned int cycle_type : 2; // 20..21 unsigned int reserved : 1; // 22..22 - not supported unsigned int atomic_prim : 1; // 23..23 unsigned int pad : 8; // 24..31 - padding }; uint64_t _u64; uint32_t _u32[2]; }; } RDP_OtherMode; typedef enum { CMD_SETTILE, CMD_SETTILE_SIZE, CMD_LOADBLOCK, CMD_LOADTILE, CMD_LOADTLUT, CMD_SET_TEXTURE, CMD_LOAD_OBJ_TXTR, } SetTileCmdType; // The display list PC stack. Before this was an array of 10 // items, but this way we can nest as deeply as necessary. typedef struct { uint32_t pc; int countdown; } DListStack; typedef struct { int x0, y0, x1, y1, mode; int left, top, right, bottom; } ScissorType; // Mask down to 0x003FFFFF? #define RSPSegmentAddr(seg) ( gRSP.segments[((seg)>>24)&0x0F] + ((seg)&0x00FFFFFF) ) #define RDRAM_UWORD(addr) (*(uint32_t_t *)((addr)+ (uint8_t*)gfx_info.RDRAM)) #define RDRAM_SWORD(addr) (*(int32_t *)((addr)+ (uint8_t*)gfx_info.RDRAM)) #define RDRAM_UHALF(addr) (*(uint16_t *)(((addr)^2) + (uint8_t*)gfx_info.RDRAM)) #define RDRAM_SHALF(addr) (*(int16_t *)(((addr)^2)+ (uint8_t*)gfx_info.RDRAM)) #define RDRAM_UBYTE(addr) (*(uint8_t *)(((addr)^3)+ (uint8_t*)gfx_info.RDRAM)) #define RDRAM_SBYTE(addr) (*(int8_t *)(((addr)^3) + (uint8_t*)gfx_info.RDRAM)) #define pRDRAM_UWORD(addr) ((uint32_t_t *)((addr) + (uint8_t*)gfx_info.RDRAM)) #define pRDRAM_SWORD(addr) ((int32_t *)((addr)+ (uint8_t*)gfx_info.RDRAM)) #define pRDRAM_UHALF(addr) ((uint16_t *)(((addr)^2) + (uint8_t*)gfx_info.RDRAM)) #define pRDRAM_SHALF(addr) ((int16_t*)(((addr)^2) + (uint8_t*)gfx_info.RDRAM)) #define pRDRAM_UBYTE(addr) ((uint8_t *)(((addr)^3) + (uint8_t*)gfx_info.RDRAM)) #define pRDRAM_SBYTE(addr) ((int8_t *)(((addr)^3)) + (uint8_t*)gfx_info.RDRAM) extern uint16_t g_wRDPTlut[]; extern const char *textluttype[4]; extern const char *pszImgFormat[8]; extern const char *pszImgSize[4]; extern uint8_t pnImgSize[4]; extern const char *textlutname[4]; extern SetImgInfo g_CI; extern SetImgInfo g_ZI; extern SetImgInfo g_TI; extern TmemType g_Tmem; extern DListStack gDlistStack[MAX_DL_STACK_SIZE]; extern int gDlistStackPointer; void DLParser_Init(); void RDP_GFX_Reset(); void RDP_Cleanup(); void DLParser_Process(OSTask * pTask); void RDP_DLParser_Process(void); void PrepareTextures(); void RDP_InitRenderState(); void DisplayVertexInfo(uint32_t dwAddr, uint32_t dwV0, uint32_t dwN); void RSP_MoveMemLight(uint32_t dwLight, uint32_t dwAddr); void RSP_MoveMemViewport(uint32_t dwAddr); void RDP_NOIMPL_WARN(const char* op); void RSP_GFX_Force_Matrix(uint32_t dwAddr); void RSP_GFX_InitGeometryMode(); void RSP_SetUcode(int ucode, uint32_t ucStart, uint32_t ucDStart, uint32_t cdSize); uint32_t CalcalateCRC(uint32_t* srcPtr, uint32_t srcSize); void RDP_GFX_PopDL(); extern Matrix matToLoad; void LoadMatrix(uint32_t addr); unsigned int ComputeCRC32(unsigned int crc, const uint8_t *buf, unsigned int len); void TriggerDPInterrupt(); void TriggerSPInterrupt(); uint32_t DLParser_CheckUcode(uint32_t ucStart, uint32_t ucDStart, uint32_t ucSize, uint32_t ucDSize); bool IsUsedAsDI(uint32_t addr); #if defined(DEBUGGER) void __cdecl LOG_UCODE(const char* szFormat, ...); #else inline void LOG_UCODE(...) {} #endif #endif // __RICE_RDP_GFX_H__ gles2rice/src/DecodedMux.h000664 001750 001750 00000016273 12655644434 016570 0ustar00sergiosergio000000 000000 /* Copyright (C) 2002 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _DECODEDMUX_H_ #define _DECODEDMUX_H_ #include #include #include "typedefs.h" #include "CombinerDefs.h" #define CM_IGNORE 0 #define CM_IGNORE_BYTE 0xFF typedef enum { N64Cycle0RGB = 0, N64Cycle0Alpha = 1, N64Cycle1RGB = 2, N64Cycle1Alpha = 3, } N64StageNumberType; typedef union { struct { uint32_t dwMux0; uint32_t dwMux1; }; uint64_t Mux64; } MuxType; typedef struct { MuxType ori_mux; MuxType simple_mux; } SimpleMuxMapType; class DecodedMux { public: union { struct { uint8_t aRGB0; uint8_t bRGB0; uint8_t cRGB0; uint8_t dRGB0; uint8_t aA0; uint8_t bA0; uint8_t cA0; uint8_t dA0; uint8_t aRGB1; uint8_t bRGB1; uint8_t cRGB1; uint8_t dRGB1; uint8_t aA1; uint8_t bA1; uint8_t cA1; uint8_t dA1; }; uint8_t m_bytes[16]; uint32_t m_dWords[4]; N64CombinerType m_n64Combiners[4]; }; union { struct { uint32_t m_dwMux0; uint32_t m_dwMux1; }; uint64_t m_u64Mux; }; CombinerFormatType splitType[4]; CombinerFormatType mType; uint32_t m_dwShadeColorChannelFlag; uint32_t m_dwShadeAlphaChannelFlag; uint32_t m_ColorTextureFlag[2]; // I may use a texture to represent a constant color // when there are more constant colors are used than // the system can support bool m_bShadeIsUsed[2]; // 0 for color channel, 1 for alpha channel bool m_bTexel0IsUsed; bool m_bTexel1IsUsed; int m_maxConstants; // OpenGL 1.1 does not really support a constant color in combiner // must use shade for constants; int m_maxTextures; // 1 or 2 void Decode(uint32_t dwMux0, uint32_t dwMux1); virtual void Hack(void); bool IsUsed(uint8_t fac, uint8_t mask); bool IsUsedInAlphaChannel(uint8_t fac, uint8_t mask); bool IsUsedInColorChannel(uint8_t fac, uint8_t mask); bool IsUsedInCycle(uint8_t fac, int cycle, CombineChannel channel, uint8_t mask); bool IsUsedInCycle(uint8_t fac, int cycle, uint8_t mask); uint32_t GetCycle(int cycle, CombineChannel channel); uint32_t GetCycle(int cycle); CombinerFormatType GetCombinerFormatType(uint32_t cycle); void Display(bool simplified, FILE *fp); static char* FormatStr(uint8_t val, char *buf); void CheckCombineInCycle1(void); virtual void Simplify(void); virtual void Reformat(bool do_complement); virtual void To_AB_Add_CD_Format(void); // Use by TNT,Geforce virtual void To_AB_Add_C_Format(void); // Use by ATI Radeon virtual void MergeShadeWithConstants(void); virtual void MergeShadeWithConstantsInChannel(CombineChannel channel); virtual void MergeConstants(void); virtual void UseShadeForConstant(void); virtual void UseTextureForConstant(void); void ConvertComplements(); int HowManyConstFactors(); int HowManyTextures(); void MergeConstFactors(); virtual void SplitComplexStages(); // Only used if the combiner supports more than 1 stages void ConvertLODFracTo0(); void ReplaceVal(uint8_t val1, uint8_t val2, int cycle, uint8_t mask); void Replace1Val(uint8_t &val1, const uint8_t val2, uint8_t mask) { val1 &= (~mask); val1 |= val2; } int CountTexels(void); int Count(uint8_t val, int cycle, uint8_t mask); #ifdef DEBUGGER void DisplayMuxString(const char *prompt); void DisplaySimpliedMuxString(const char *prompt); void DisplayConstantsWithShade(uint32_t flag,CombineChannel channel); #else void DisplayMuxString(const char *prompt) {} void DisplaySimpliedMuxString(const char *prompt){} void DisplayConstantsWithShade(uint32_t flag,CombineChannel channel){} void LogMuxString(const char *prompt, FILE *fp); void LogSimpliedMuxString(const char *prompt, FILE *fp); void LogConstantsWithShade(uint32_t flag,CombineChannel channel, FILE *fp); #endif virtual DecodedMux& operator=(const DecodedMux& mux) { m_dWords[0] = mux.m_dWords[0]; m_dWords[1] = mux.m_dWords[1]; m_dWords[2] = mux.m_dWords[2]; m_dWords[3] = mux.m_dWords[3]; m_u64Mux = mux.m_u64Mux; splitType[0] = mux.splitType[0]; splitType[1] = mux.splitType[1]; splitType[2] = mux.splitType[2]; splitType[3] = mux.splitType[3]; mType = mux.mType; m_dwShadeColorChannelFlag = mux.m_dwShadeColorChannelFlag; m_dwShadeAlphaChannelFlag = mux.m_dwShadeAlphaChannelFlag; m_bShadeIsUsed[0] = mux.m_bShadeIsUsed[0]; m_bShadeIsUsed[1] = mux.m_bShadeIsUsed[1]; m_bTexel0IsUsed = mux.m_bTexel0IsUsed; m_bTexel1IsUsed = mux.m_bTexel1IsUsed; m_maxConstants = mux.m_maxConstants; m_maxTextures = mux.m_maxTextures; m_ColorTextureFlag[0] = mux.m_ColorTextureFlag[0]; m_ColorTextureFlag[1] = mux.m_ColorTextureFlag[1]; return *this; } static inline bool IsConstFactor(uint8_t val) { uint8_t v = val&MUX_MASK; return( v == MUX_0 || v == MUX_1 || v == MUX_PRIM || v == MUX_ENV || v == MUX_LODFRAC || v == MUX_PRIMLODFRAC ); } DecodedMux() { memset(m_bytes, 0, sizeof(m_bytes)); mType=CM_FMT_TYPE_NOT_CHECKED; for( int i=0; i<4; i++ ) { splitType[i] = CM_FMT_TYPE_NOT_CHECKED; } m_maxConstants = 1; m_maxTextures = 2; } virtual ~DecodedMux() {} }; class DecodedMuxForPixelShader : public DecodedMux { public: virtual void Simplify(void); void SplitComplexStages() {}; }; class DecodedMuxForSemiPixelShader : public DecodedMux { public: void Reset(void); }; class DecodedMuxForOGL14V2 : public DecodedMuxForPixelShader { public: virtual void Simplify(void); void UseTextureForConstant(void); }; typedef struct { bool bFurtherFormatForOGL2; bool bUseShadeForConstants; bool bUseTextureForConstants; bool bUseMoreThan2TextureForConstants; bool bReformatToAB_CD; bool bAllowHack; bool bAllowComplimentary; bool bCheckCombineInCycle1; bool bSetLODFracTo0; bool bMergeShadeWithConstants; bool bSplitComplexStage; bool bReformatAgainWithTwoTexels; } MuxConverterOptions; #endif mupen64plus-video-gliden64/src/UniformCollection.h000664 001750 001750 00000001700 12655644434 023230 0ustar00sergiosergio000000 000000 #ifndef UNIFORM_COLLECTION_H #define UNIFORM_COLLECTION_H #include "GLSLCombiner.h" class UniformCollection { public: enum TextureUniforms { tuTexScale, tuTexOffset, tuCacheScale, tuCacheOffset, tuCacheShiftScale, tuCacheFrameBuffer, tuTotal }; enum ColorUniforms { cuFogColor, cuCenterColor, cuScaleColor, cuBlendColor, cuEnvColor, cuPrimColor, cuPrimLod, cuK4, cuK5, cuTotal }; enum LightUniforms { luLightDirection, luLightColor, luTotal }; virtual ~UniformCollection() {} virtual void bindWithShaderCombiner(ShaderCombiner * _pCombiner) = 0; virtual void setColorData(ColorUniforms _index, u32 _dataSize, const void * _data) = 0; virtual void updateTextureParameters() = 0; virtual void updateLightParameters() = 0; virtual void updateUniforms(ShaderCombiner * _pCombiner, OGLRender::RENDER_STATE _renderState) = 0; }; UniformCollection * createUniformCollection(); #endif // UNIFORM_COLLECTION_Hmupen64plus-video-gliden64/src/Turbo3D.h000664 001750 001750 00000000115 12655644434 021056 0ustar00sergiosergio000000 000000 #ifndef TURBO3D_H #define TURBO3D_H void RunTurbo3D(); #endif // TURBO3D_H mupen64plus-core/src/main/main.c000664 001750 001750 00000035412 12655644434 017657 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - main.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2012 CasualJames * * Copyright (C) 2008-2009 Richard Goedeken * * Copyright (C) 2008 Ebenblues Nmn Okaygo Tillin9 * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This is MUPEN64's main entry point. It contains code that is common * to both the gui and non-gui versions of mupen64. See * gui subdirectories for the gui-specific code. * if you want to implement an interface, you should look here */ #include #include #include #include #define M64P_CORE_PROTOTYPES 1 #include "../api/m64p_types.h" #include "../api/callbacks.h" #include "../api/config.h" #include "../api/m64p_config.h" #include "../api/debugger.h" #include "../api/m64p_vidext.h" #include "../api/vidext.h" #include "main.h" #include "cheat.h" #include "eventloop.h" #include "rom.h" #include "savestates.h" #include "util.h" #include "../ai/ai_controller.h" #include "../memory/memory.h" #include "../osal/preproc.h" #include "../pi/pi_controller.h" #include "../plugin/plugin.h" #include "../plugin/emulate_game_controller_via_input_plugin.h" #include "../plugin/get_time_using_C_localtime.h" #include "../plugin/rumble_via_input_plugin.h" #include "../r4300/r4300.h" #include "../r4300/r4300_core.h" #include "../r4300/reset.h" #include "../rdp/rdp_core.h" #include "../rsp/rsp_core.h" #include "../ri/ri_controller.h" #include "../si/si_controller.h" #include "../vi/vi_controller.h" #include "../dd/dd_controller.h" #include "../dd/dd_rom.h" #include "../dd/dd_disk.h" #ifdef DBG #include "../debugger/dbg_types.h" #include "../debugger/debugger.h" #endif #include "api/libretro.h" extern retro_input_poll_t poll_cb; /* version number for Core config section */ #define CONFIG_PARAM_VERSION 1.01 /** globals **/ m64p_handle g_CoreConfig = NULL; m64p_frame_callback g_FrameCallback = NULL; int g_MemHasBeenBSwapped = 0; /* store byte-swapped flag so we don't swap twice when re-playing game */ int g_DDMemHasBeenBSwapped = 0; /* store byte-swapped flag so we don't swap twice when re-playing game */ int g_EmulatorRunning = 0; /* need separate boolean to tell if emulator is running, since --nogui doesn't use a thread */ ALIGN(16, uint32_t g_rdram[RDRAM_MAX_SIZE/4]); struct ai_controller g_ai; struct pi_controller g_pi; struct ri_controller g_ri; struct si_controller g_si; struct vi_controller g_vi; struct dd_controller g_dd; struct r4300_core g_r4300; struct rdp_core g_dp; struct rsp_core g_sp; int g_delay_si = 0; int g_gs_vi_counter = 0; /** static (local) variables **/ static int l_CurrentFrame = 0; // frame counter /********************************************************************************************************* * helper functions */ void main_message(m64p_msg_level level, unsigned int corner, const char *format, ...) { va_list ap; char buffer[2049]; va_start(ap, format); vsnprintf(buffer, 2047, format, ap); buffer[2048]='\0'; va_end(ap); /* send message to front-end */ DebugMessage(level, "%s", buffer); } /********************************************************************************************************* * global functions, for adjusting the core emulator behavior */ int main_set_core_defaults(void) { float fConfigParamsVersion; int bSaveConfig = 0, bUpgrade = 0; if (ConfigGetParameter(g_CoreConfig, "Version", M64TYPE_FLOAT, &fConfigParamsVersion, sizeof(float)) != M64ERR_SUCCESS) { DebugMessage(M64MSG_WARNING, "No version number in 'Core' config section. Setting defaults."); ConfigDeleteSection("Core"); ConfigOpenSection("Core", &g_CoreConfig); bSaveConfig = 1; } else if (((int) fConfigParamsVersion) != ((int) CONFIG_PARAM_VERSION)) { DebugMessage(M64MSG_WARNING, "Incompatible version %.2f in 'Core' config section: current is %.2f. Setting defaults.", fConfigParamsVersion, (float) CONFIG_PARAM_VERSION); ConfigDeleteSection("Core"); ConfigOpenSection("Core", &g_CoreConfig); bSaveConfig = 1; } else if ((CONFIG_PARAM_VERSION - fConfigParamsVersion) >= 0.0001f) { float fVersion = (float) CONFIG_PARAM_VERSION; ConfigSetParameter(g_CoreConfig, "Version", M64TYPE_FLOAT, &fVersion); DebugMessage(M64MSG_INFO, "Updating parameter set version in 'Core' config section to %.2f", fVersion); bUpgrade = 1; bSaveConfig = 1; } /* parameters controlling the operation of the core */ ConfigSetDefaultFloat(g_CoreConfig, "Version", (float) CONFIG_PARAM_VERSION, "Mupen64Plus Core config parameter set version number. Please don't change this version number."); ConfigSetDefaultBool(g_CoreConfig, "OnScreenDisplay", 1, "Draw on-screen display if True, otherwise don't draw OSD"); #if defined(DYNAREC) ConfigSetDefaultInt(g_CoreConfig, "R4300Emulator", 2, "Use Pure Interpreter if 0, Cached Interpreter if 1, or Dynamic Recompiler if 2 or more"); #else ConfigSetDefaultInt(g_CoreConfig, "R4300Emulator", 1, "Use Pure Interpreter if 0, Cached Interpreter if 1, or Dynamic Recompiler if 2 or more"); #endif ConfigSetDefaultBool(g_CoreConfig, "NoCompiledJump", 0, "Disable compiled jump commands in dynamic recompiler (should be set to False) "); ConfigSetDefaultBool(g_CoreConfig, "DisableExtraMem", 0, "Disable 4MB expansion RAM pack. May be necessary for some games"); ConfigSetDefaultBool(g_CoreConfig, "EnableDebugger", 0, "Activate the R4300 debugger when ROM execution begins, if core was built with Debugger support"); ConfigSetDefaultInt(g_CoreConfig, "CountPerOp", 0, "Force number of cycles per emulated instruction."); ConfigSetDefaultBool(g_CoreConfig, "DelaySI", 1, "Delay interrupt after DMA SI read/write"); if (bSaveConfig) ConfigSaveSection("Core"); return 1; } m64p_error main_core_state_query(m64p_core_param param, int *rval) { switch (param) { case M64CORE_EMU_STATE: if (!g_EmulatorRunning) *rval = M64EMU_STOPPED; else *rval = M64EMU_RUNNING; break; case M64CORE_INPUT_GAMESHARK: *rval = event_gameshark_active(); break; default: return M64ERR_INPUT_INVALID; } return M64ERR_SUCCESS; } m64p_error main_core_state_set(m64p_core_param param, int val) { switch (param) { case M64CORE_EMU_STATE: if (!g_EmulatorRunning) return M64ERR_INVALID_STATE; if (val == M64EMU_STOPPED) { /* this stop function is asynchronous. The emulator may not terminate until later */ main_stop(); return M64ERR_SUCCESS; } else if (val == M64EMU_RUNNING) return M64ERR_SUCCESS; return M64ERR_INPUT_INVALID; case M64CORE_INPUT_GAMESHARK: if (!g_EmulatorRunning) return M64ERR_INVALID_STATE; event_set_gameshark(val); return M64ERR_SUCCESS; default: break; } return M64ERR_INPUT_INVALID; } m64p_error main_read_screen(void *pixels, int bFront) { int width_trash, height_trash; gfx.readScreen(pixels, &width_trash, &height_trash, bFront); return M64ERR_SUCCESS; } m64p_error main_reset(int do_hard_reset) { if (do_hard_reset) reset_hard_job |= 1; else reset_soft(); return M64ERR_SUCCESS; } /********************************************************************************************************* * global functions, callbacks from the r4300 core or from other plugins */ void new_frame(void) { if (g_FrameCallback) (*g_FrameCallback)(l_CurrentFrame++); } void main_exit(void) { /* now begin to shut down */ #ifdef DBG if (g_DebuggerActive) destroy_debugger(); #endif rsp.romClosed(); input.romClosed(); gfx.romClosed(); // clean up g_EmulatorRunning = 0; StateChanged(M64CORE_EMU_STATE, M64EMU_STOPPED); } /* TODO: make a GameShark module and move that there */ static void gs_apply_cheats(void) { if(g_gs_vi_counter < 60) { if (g_gs_vi_counter == 0) cheat_apply_cheats(ENTRY_BOOT); g_gs_vi_counter++; } else { cheat_apply_cheats(ENTRY_VI); } } /* called on vertical interrupt. * Allow the core to perform various things */ void new_vi(void) { gs_apply_cheats(); main_check_inputs(); #if 0 timed_sections_refresh(); pause_loop(); apply_speed_limiter(); #endif } static void connect_all( struct r4300_core *r4300, struct rdp_core* dp, struct rsp_core* sp, struct ai_controller* ai, struct pi_controller* pi, struct ri_controller* ri, struct si_controller* si, struct vi_controller* vi, struct dd_controller* dd, uint32_t* dram, size_t dram_size, uint8_t *rom, size_t rom_size, uint8_t *ddrom, size_t ddrom_size, uint8_t *dd_disk, size_t dd_disk_size ) { connect_rdp(dp, r4300, sp, ri); connect_rsp(sp, r4300, dp, ri); connect_ai(ai, r4300, ri, vi); connect_pi(pi, r4300, ri, rom, rom_size, ddrom, ddrom_size); connect_ri(ri, dram, dram_size); connect_si(si, r4300, ri); connect_vi(vi, r4300); connect_dd(dd, r4300, dd_disk, dd_disk_size); } static void dummy_save(void *user_data) { } /********************************************************************************************************* * emulation thread - runs the core */ m64p_error main_init(void) { size_t i; unsigned int disable_extra_mem; static int channels[] = { 0, 1, 2, 3 }; /* take the r4300 emulator mode from the config file at this point and cache it in a global variable */ r4300emu = ConfigGetParamInt(g_CoreConfig, "R4300Emulator"); /* set some other core parameters based on the config file values */ no_compiled_jump = ConfigGetParamBool(g_CoreConfig, "NoCompiledJump"); disable_extra_mem = ConfigGetParamInt(g_CoreConfig, "DisableExtraMem"); #if 0 count_per_op = ConfigGetParamInt(g_CoreConfig, "CountPerOp"); #endif if (count_per_op <= 0) count_per_op = 2; /* do byte-swapping if it's not been done yet */ if (g_MemHasBeenBSwapped == 0) { swap_buffer(g_rom, 4, g_rom_size / 4); g_MemHasBeenBSwapped = 1; } if (g_DDMemHasBeenBSwapped == 0) { swap_buffer(g_ddrom, 4, g_ddrom_size / 4); g_DDMemHasBeenBSwapped = 1; } connect_all(&g_r4300, &g_dp, &g_sp, &g_ai, &g_pi, &g_ri, &g_si, &g_vi, &g_dd, g_rdram, (disable_extra_mem == 0) ? 0x800000 : 0x400000, g_rom, g_rom_size, g_ddrom, g_ddrom_size, g_dd_disk, g_dd_disk_size); init_memory(); // Attach rom to plugins printf("Gfx RomOpen.\n"); if (!gfx.romOpen()) { printf("Gfx RomOpen failed.\n"); return M64ERR_PLUGIN_FAIL; } printf("Input RomOpen.\n"); if (!input.romOpen()) { printf("Input RomOpen failed.\n"); gfx.romClosed(); return M64ERR_PLUGIN_FAIL; } /* connect external time source to AF_RTC component */ g_si.pif.af_rtc.user_data = NULL; g_si.pif.af_rtc.get_time = get_time_using_C_localtime; /* connect external game controllers */ for(i = 0; i < GAME_CONTROLLERS_COUNT; ++i) { g_si.pif.controllers[i].user_data = &channels[i]; g_si.pif.controllers[i].is_connected = egcvip_is_connected; g_si.pif.controllers[i].get_input = egcvip_get_input; } /* connect external rumblepaks */ for(i = 0; i < GAME_CONTROLLERS_COUNT; ++i) { g_si.pif.controllers[i].rumblepak.user_data = &channels[i]; g_si.pif.controllers[i].rumblepak.rumble = rvip_rumble; } /* connect saved_memory.mempacks to mempaks */ for(i = 0; i < GAME_CONTROLLERS_COUNT; ++i) { g_si.pif.controllers[i].mempak.user_data = NULL; g_si.pif.controllers[i].mempak.save = dummy_save; g_si.pif.controllers[i].mempak.data = &saved_memory.mempack[i][0]; } /* connect saved_memory.eeprom to eeprom */ g_si.pif.eeprom.user_data = NULL; g_si.pif.eeprom.save = dummy_save; g_si.pif.eeprom.data = saved_memory.eeprom; if (ROM_SETTINGS.savetype != EEPROM_16KB) { /* 4kbits EEPROM */ g_si.pif.eeprom.size = 0x200; g_si.pif.eeprom.id = 0x8000; } else { /* 16kbits EEPROM */ g_si.pif.eeprom.size = 0x800; g_si.pif.eeprom.id = 0xc000; } /* connect saved_memory.flashram to flashram */ g_pi.flashram.user_data = NULL; g_pi.flashram.save = dummy_save; g_pi.flashram.data = saved_memory.flashram; /* connect saved_memory.sram to SRAM */ g_pi.sram.user_data = NULL; g_pi.sram.save = dummy_save; g_pi.sram.data = saved_memory.sram; #ifdef DBG if (ConfigGetParamBool(g_CoreConfig, "EnableDebugger")) init_debugger(); #endif g_EmulatorRunning = 1; StateChanged(M64CORE_EMU_STATE, M64EMU_RUNNING); /* call r4300 CPU core and run the game */ r4300_reset_hard(); r4300_reset_soft(); r4300_init(); return M64ERR_SUCCESS; } m64p_error main_run(void) { r4300_execute(); return M64ERR_SUCCESS; } void main_stop(void) { /* note: this operation is asynchronous. It may be called from a thread other than the main emulator thread, and may return before the emulator is completely stopped */ if (!g_EmulatorRunning) return; DebugMessage(M64MSG_STATUS, "Stopping emulation."); stop = 1; #ifdef DBG if(g_DebuggerActive) debugger_step(); #endif r4300_deinit(); } void main_check_inputs(void) { poll_cb(); } mupen64plus-core/src/r4300/new_dynarec/linkage_x86.S000664 001750 001750 00000046404 12655644434 023157 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - linkage_x86.s * * Copyright (C) 2009-2011 Ari64 * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ .file "linkage_x86.s" .bss .align 4 .section .rodata .text .globl dyna_linker .hidden dyna_linker .type dyna_linker, @function dyna_linker: /* eax = virtual target address */ /* ebx = instruction to patch */ mov %eax, %edi mov %eax, %ecx shr $12, %edi cmp $0xC0000000, %eax cmovge tlb_LUT_r(,%edi,4), %ecx test %ecx, %ecx cmovz %eax, %ecx xor $0x80000000, %ecx mov $2047, %edx shr $12, %ecx and %ecx, %edx or $2048, %edx cmp %edx, %ecx cmova %edx, %ecx /* jump_in lookup */ mov jump_in(,%ecx,4), %edx .A1: test %edx, %edx je .A3 mov (%edx), %edi xor %eax, %edi or 4(%edx), %edi je .A2 movl 12(%edx), %edx jmp .A1 .A2: mov (%ebx), %edi mov %esi, %ebp lea 4(%ebx,%edi,1), %esi mov %eax, %edi pusha call add_link popa mov 8(%edx), %edi mov %ebp, %esi lea -4(%edi), %edx subl %ebx, %edx movl %edx, (%ebx) jmp *%edi .A3: /* hash_table lookup */ mov %eax, %edi mov %eax, %edx shr $16, %edi shr $12, %edx xor %eax, %edi and $2047, %edx movzwl %di, %edi shl $4, %edi cmp $2048, %ecx cmovc %edx, %ecx cmp hash_table(%edi), %eax jne .A5 .A4: mov hash_table+4(%edi), %edx jmp *%edx .A5: cmp hash_table+8(%edi), %eax lea 8(%edi), %edi je .A4 /* jump_dirty lookup */ mov jump_dirty(,%ecx,4), %edx .A6: testl %edx, %edx je .A8 mov (%edx), %ecx xor %eax, %ecx or 4(%edx), %ecx je .A7 movl 12(%edx), %edx jmp .A6 .A7: mov 8(%edx), %edx /* hash_table insert */ mov hash_table-8(%edi), %ebx mov hash_table-4(%edi), %ecx mov %eax, hash_table-8(%edi) mov %edx, hash_table-4(%edi) mov %ebx, hash_table(%edi) mov %ecx, hash_table+4(%edi) jmp *%edx .A8: mov %eax, %edi pusha call new_recompile_block test %eax, %eax popa je dyna_linker /* pagefault */ mov %eax, %ebx mov $0x08, %ecx .size dyna_linker, .-dyna_linker .type exec_pagefault, @function exec_pagefault: /* eax = instruction pointer */ /* ebx = fault address */ /* ecx = cause */ mov g_cp0_regs+48, %edx add $-12, %esp mov g_cp0_regs+16, %edi or $2, %edx mov %ebx, g_cp0_regs+32 /* BadVAddr */ and $0xFF80000F, %edi mov %edx, g_cp0_regs+48 /* Status */ mov %ecx, g_cp0_regs+52 /* Cause */ mov %eax, g_cp0_regs+56 /* EPC */ mov %ebx, %ecx shr $9, %ebx and $0xFFFFE000, %ecx and $0x007FFFF0, %ebx mov %ecx, g_cp0_regs+40 /* EntryHI */ or %ebx, %edi mov %edi, g_cp0_regs+16 /* Context */ push $0x80000000 call get_addr_ht add $16, %esp jmp *%eax .size exec_pagefault, .-exec_pagefault /* Special dynamic linker for the case where a page fault may occur in a branch delay slot */ .globl dyna_linker_ds .hidden dyna_linker_ds .type dyna_linker_ds, @function dyna_linker_ds: mov %eax, %edi mov %eax, %ecx shr $12, %edi cmp $0xC0000000, %eax cmovge tlb_LUT_r(,%edi,4), %ecx test %ecx, %ecx cmovz %eax, %ecx xor $0x80000000, %ecx mov $2047, %edx shr $12, %ecx and %ecx, %edx or $2048, %edx cmp %edx, %ecx cmova %edx, %ecx /* jump_in lookup */ mov jump_in(,%ecx,4), %edx .B1: test %edx, %edx je .B3 mov (%edx), %edi xor %eax, %edi or 4(%edx), %edi je .B2 movl 12(%edx), %edx jmp .B1 .B2: mov (%ebx), %edi mov %esi, %ecx lea 4(%ebx,%edi,1), %esi mov %eax, %edi pusha call add_link popa mov 8(%edx), %edi mov %ecx, %esi lea -4(%edi), %edx subl %ebx, %edx movl %edx, (%ebx) jmp *%edi .B3: /* hash_table lookup */ mov %eax, %edi mov %eax, %edx shr $16, %edi shr $12, %edx xor %eax, %edi and $2047, %edx movzwl %di, %edi shl $4, %edi cmp $2048, %ecx cmovc %edx, %ecx cmp hash_table(%edi), %eax jne .B5 .B4: mov hash_table+4(%edi), %edx jmp *%edx .B5: cmp hash_table+8(%edi), %eax lea 8(%edi), %edi je .B4 /* jump_dirty lookup */ mov jump_dirty(,%ecx,4), %edx .B6: testl %edx, %edx je .B8 mov (%edx), %ecx xor %eax, %ecx or 4(%edx), %ecx je .B7 movl 12(%edx), %edx jmp .B6 .B7: mov 8(%edx), %edx /* hash_table insert */ mov hash_table-8(%edi), %ebx mov hash_table-4(%edi), %ecx mov %eax, hash_table-8(%edi) mov %edx, hash_table-4(%edi) mov %ebx, hash_table(%edi) mov %ecx, hash_table+4(%edi) jmp *%edx .B8: mov %eax, %edi and $0xFFFFFFF8, %edi inc %edi pusha call new_recompile_block test %eax, %eax popa je dyna_linker_ds /* pagefault */ and $0xFFFFFFF8, %eax mov $0x80000008, %ecx /* High bit set indicates pagefault in delay slot */ mov %eax, %ebx sub $4, %eax jmp exec_pagefault .size dyna_linker_ds, .-dyna_linker_ds .globl jump_vaddr_eax .hidden jump_vaddr_eax .type jump_vaddr_eax, @function jump_vaddr_eax: mov %eax, %edi jmp jump_vaddr_edi .size jump_vaddr_eax, .-jump_vaddr_eax .globl jump_vaddr_ecx .hidden jump_vaddr_ecx .type jump_vaddr_ecx, @function jump_vaddr_ecx: mov %ecx, %edi jmp jump_vaddr_edi .size jump_vaddr_ecx, .-jump_vaddr_ecx .globl jump_vaddr_edx .hidden jump_vaddr_edx .type jump_vaddr_edx, @function jump_vaddr_edx: mov %edx, %edi jmp jump_vaddr_edi .size jump_vaddr_edx, .-jump_vaddr_edx .globl jump_vaddr_ebx .hidden jump_vaddr_ebx .type jump_vaddr_ebx, @function jump_vaddr_ebx: mov %ebx, %edi jmp jump_vaddr_edi .size jump_vaddr_ebx, .-jump_vaddr_ebx .globl jump_vaddr_ebp .hidden jump_vaddr_ebp .type jump_vaddr_ebp, @function jump_vaddr_ebp: mov %ebp, %edi .size jump_vaddr_ebp, .-jump_vaddr_ebp .globl jump_vaddr_edi .hidden jump_vaddr_edi .type jump_vaddr_edi, @function jump_vaddr_edi: mov %edi, %eax .size jump_vaddr_edi, .-jump_vaddr_edi .type jump_vaddr, @function jump_vaddr: /* Check hash table */ shr $16, %eax xor %edi, %eax movzwl %ax, %eax shl $4, %eax cmp hash_table(%eax), %edi jne .C2 .C1: mov hash_table+4(%eax), %edi jmp *%edi .C2: cmp hash_table+8(%eax), %edi lea 8(%eax), %eax je .C1 /* No hit on hash table, call compiler */ add $-12, %esp push %edi mov %esi, cycle_count /* CCREG */ call get_addr mov cycle_count, %esi add $16, %esp jmp *%eax .size jump_vaddr, .-jump_vaddr .globl verify_code_ds .hidden verify_code_ds .type verify_code_ds, @function verify_code_ds: mov %ebp, branch_target .size verify_code_ds, .-verify_code_ds .globl verify_code_vm .hidden verify_code_vm .type verify_code_vm, @function verify_code_vm: /* eax = source (virtual address) */ /* ebx = target */ /* ecx = length */ cmp $0xC0000000, %eax jl verify_code mov %eax, %edx lea -1(%eax,%ecx,1), %ebp shr $12, %edx shr $12, %ebp mov memory_map(,%edx,4), %edi test %edi, %edi js .D5 lea (%eax,%edi,4), %eax .D1: xor memory_map(,%edx,4), %edi shl $2, %edi jne .D5 mov memory_map(,%edx,4), %edi inc %edx cmp %ebp, %edx jbe .D1 .size verify_code_vm, .-verify_code_vm .globl verify_code .hidden verify_code .type verify_code, @function verify_code: /* eax = source */ /* ebx = target */ /* ecx = length */ mov -4(%eax,%ecx,1), %edi xor -4(%ebx,%ecx,1), %edi jne .D5 mov %ecx, %edx add $-4, %ecx je .D3 test $4, %edx cmove %edx, %ecx mov %esi, cycle_count .D2: mov -4(%eax,%ecx,1), %edx mov -4(%ebx,%ecx,1), %ebp mov -8(%eax,%ecx,1), %esi xor %edx, %ebp mov -8(%ebx,%ecx,1), %edi jne .D4 xor %esi, %edi jne .D4 add $-8, %ecx jne .D2 mov cycle_count, %esi mov branch_target, %ebp .D3: ret .D4: mov cycle_count, %esi .D5: mov branch_target, %ebp push %esi /* for stack alignment, unused */ push 8(%esp) call get_addr add $16, %esp /* pop stack */ jmp *%eax .size verify_code, .-verify_code .globl cc_interrupt .hidden cc_interrupt .type cc_interrupt, @function cc_interrupt: add last_count, %esi add $-28, %esp /* Align stack */ mov %esi, g_cp0_regs+36 /* Count */ shr $19, %esi movl $0, pending_exception and $0x7f, %esi cmpl $0, restore_candidate(,%esi,4) jne .E4 .E1: call gen_interupt mov g_cp0_regs+36, %esi mov next_interupt, %eax mov pending_exception, %ebx mov stop, %ecx add $28, %esp mov %eax, last_count sub %eax, %esi test %ecx, %ecx jne .E3 test %ebx, %ebx jne .E2 ret .E2: add $-8, %esp mov pcaddr, %edi mov %esi, cycle_count /* CCREG */ push %edi call get_addr_ht mov cycle_count, %esi add $16, %esp jmp *%eax .E3: add $16, %esp /* pop stack */ pop %edi /* restore edi */ pop %esi /* restore esi */ pop %ebx /* restore ebx */ pop %ebp /* restore ebp */ ret /* exit dynarec */ .E4: /* Move 'dirty' blocks to the 'clean' list */ mov restore_candidate(,%esi,4), %ebx mov %esi, %ebp movl $0, restore_candidate(,%esi,4) shl $5, %ebp .E5: shr $1, %ebx jnc .E6 mov %ebp, (%esp) call clean_blocks .E6: inc %ebp test $31, %ebp jne .E5 jmp .E1 .size cc_interrupt, .-cc_interrupt .globl do_interrupt .hidden do_interrupt .type do_interrupt, @function do_interrupt: mov pcaddr, %edi add $-12, %esp push %edi call get_addr_ht add $16, %esp mov g_cp0_regs+36, %esi mov next_interupt, %ebx mov %ebx, last_count sub %ebx, %esi add $2, %esi jmp *%eax .size do_interrupt, .-do_interrupt .globl fp_exception .hidden fp_exception .type fp_exception, @function fp_exception: mov $0x1000002c, %edx .E7: mov g_cp0_regs+48, %ebx add $-12, %esp or $2, %ebx mov %ebx, g_cp0_regs+48 /* Status */ mov %edx, g_cp0_regs+52 /* Cause */ mov %eax, g_cp0_regs+56 /* EPC */ push $0x80000180 call get_addr_ht add $16, %esp jmp *%eax .size fp_exception, .-fp_exception .globl fp_exception_ds .hidden fp_exception_ds .type fp_exception_ds, @function fp_exception_ds: mov $0x9000002c, %edx /* Set high bit if delay slot */ jmp .E7 .size fp_exception_ds, .-fp_exception_ds .globl jump_syscall .hidden jump_syscall .type jump_syscall, @function jump_syscall: mov $0x20, %edx mov g_cp0_regs+48, %ebx add $-12, %esp or $2, %ebx mov %ebx, g_cp0_regs+48 /* Status */ mov %edx, g_cp0_regs+52 /* Cause */ mov %eax, g_cp0_regs+56 /* EPC */ push $0x80000180 call get_addr_ht add $16, %esp jmp *%eax .size jump_syscall, .-jump_syscall .globl jump_eret .hidden jump_eret .type jump_eret, @function jump_eret: mov g_cp0_regs+48, %ebx /* Status */ add last_count, %esi and $0xFFFFFFFD, %ebx mov %esi, g_cp0_regs+36 /* Count */ mov %ebx, g_cp0_regs+48 /* Status */ call check_interupt mov next_interupt, %eax mov g_cp0_regs+36, %esi mov %eax, last_count sub %eax, %esi mov g_cp0_regs+56, %eax /* EPC */ jns .E11 .E8: mov $248, %ebx xor %edi, %edi .E9: mov reg(%ebx), %ecx mov reg+4(%ebx), %edx sar $31, %ecx xor %ecx, %edx neg %edx adc %edi, %edi sub $8, %ebx jne .E9 mov hi, %ecx mov hi+4, %edx sar $31, %ecx xor %ecx, %edx jne .E10 mov lo, %ecx mov lo+4, %edx sar $31, %ecx xor %ecx, %edx .E10: neg %edx adc %edi, %edi add $-8, %esp push %edi push %eax mov %esi, cycle_count call get_addr_32 mov cycle_count, %esi add $16, %esp jmp *%eax .E11: mov %eax, pcaddr call cc_interrupt mov pcaddr, %eax jmp .E8 .size jump_eret, .-jump_eret .globl new_dyna_start .hidden new_dyna_start .type new_dyna_start, @function new_dyna_start: push %ebp push %ebx push %esi push %edi add $-8, %esp /* align stack */ push $0xa4000040 call new_recompile_block movl next_interupt, %edi movl g_cp0_regs+36, %esi movl %edi, last_count subl %edi, %esi jmp *base_addr .size new_dyna_start, .-new_dyna_start /* Note: Assumes %ebx, %ebp, %esi, %edi are callee-saved */ .globl invalidate_block_eax .hidden invalidate_block_eax .type invalidate_block_eax, @function invalidate_block_eax: push %eax push %ecx push %edx push %eax jmp invalidate_block_call .size invalidate_block_eax, .-invalidate_block_eax .globl invalidate_block_ecx .hidden invalidate_block_ecx .type invalidate_block_ecx, @function invalidate_block_ecx: push %eax push %ecx push %edx push %ecx jmp invalidate_block_call .size invalidate_block_ecx, .-invalidate_block_ecx .globl invalidate_block_edx .hidden invalidate_block_edx .type invalidate_block_edx, @function invalidate_block_edx: push %eax push %ecx push %edx push %edx jmp invalidate_block_call .size invalidate_block_edx, .-invalidate_block_edx .globl invalidate_block_ebx .hidden invalidate_block_ebx .type invalidate_block_ebx, @function invalidate_block_ebx: push %eax push %ecx push %edx push %ebx jmp invalidate_block_call .size invalidate_block_ebx, .-invalidate_block_ebx .globl invalidate_block_ebp .hidden invalidate_block_ebp .type invalidate_block_ebp, @function invalidate_block_ebp: push %eax push %ecx push %edx push %ebp jmp invalidate_block_call .size invalidate_block_ebp, .-invalidate_block_ebp .globl invalidate_block_esi .hidden invalidate_block_esi .type invalidate_block_esi, @function invalidate_block_esi: push %eax push %ecx push %edx push %esi jmp invalidate_block_call .size invalidate_block_esi, .-invalidate_block_esi .globl invalidate_block_edi .hidden invalidate_block_edi .type invalidate_block_edi, @function invalidate_block_edi: push %eax push %ecx push %edx push %edi .size invalidate_block_edi, .-invalidate_block_edi .type invalidate_block_call, @function invalidate_block_call: call invalidate_block pop %eax /* Throw away */ pop %edx pop %ecx pop %eax ret .size invalidate_block_call, .-invalidate_block_call .globl write_rdram_new .hidden write_rdram_new .type write_rdram_new, @function write_rdram_new: mov address, %edi mov word, %ecx mov %ecx, g_rdram-0x80000000(%edi) jmp .E12 .size write_rdram_new, .-write_rdram_new .globl write_rdramb_new .hidden write_rdramb_new .type write_rdramb_new, @function write_rdramb_new: mov address, %edi xor $3, %edi movb cpu_byte, %cl movb %cl, g_rdram-0x80000000(%edi) jmp .E12 .size write_rdramb_new, .-write_rdramb_new .globl write_rdramh_new .hidden write_rdramh_new .type write_rdramh_new, @function write_rdramh_new: mov address, %edi xor $2, %edi movw hword, %cx movw %cx, g_rdram-0x80000000(%edi) jmp .E12 .size write_rdramh_new, .-write_rdramh_new .globl write_rdramd_new .hidden write_rdramd_new .type write_rdramd_new, @function write_rdramd_new: mov address, %edi mov dword+4, %ecx mov dword, %edx mov %ecx, g_rdram-0x80000000(%edi) mov %edx, g_rdram-0x80000000+4(%edi) jmp .E12 .size write_rdramd_new, .-write_rdramd_new .type do_invalidate, @function do_invalidate: mov address, %edi mov %edi, %ebx /* Return ebx to caller */ .E12: shr $12, %edi cmpb $1, invalid_code(%edi) je .E13 push %edi call invalidate_block pop %edi .E13: ret .size do_invalidate, .-do_invalidate .globl read_nomem_new .hidden read_nomem_new .type read_nomem_new, @function read_nomem_new: mov address, %edi mov %edi, %ebx shr $12, %edi mov memory_map(,%edi,4),%edi mov $0x8, %eax test %edi, %edi js tlb_exception mov (%ebx,%edi,4), %ecx mov %ecx, readmem_dword ret .size read_nomem_new, .-read_nomem_new .globl read_nomemb_new .hidden read_nomemb_new .type read_nomemb_new, @function read_nomemb_new: mov address, %edi mov %edi, %ebx shr $12, %edi mov memory_map(,%edi,4),%edi mov $0x8, %eax test %edi, %edi js tlb_exception xor $3, %ebx movzbl (%ebx,%edi,4), %ecx mov %ecx, readmem_dword ret .size read_nomemb_new, .-read_nomemb_new .globl read_nomemh_new .hidden read_nomemh_new .type read_nomemh_new, @function read_nomemh_new: mov address, %edi mov %edi, %ebx shr $12, %edi mov memory_map(,%edi,4),%edi mov $0x8, %eax test %edi, %edi js tlb_exception xor $2, %ebx movzwl (%ebx,%edi,4), %ecx mov %ecx, readmem_dword ret .size read_nomemh_new, .-read_nomemh_new .globl read_nomemd_new .hidden read_nomemd_new .type read_nomemd_new, @function read_nomemd_new: mov address, %edi mov %edi, %ebx shr $12, %edi mov memory_map(,%edi,4),%edi mov $0x8, %eax test %edi, %edi js tlb_exception mov 4(%ebx,%edi,4), %ecx mov (%ebx,%edi,4), %edx mov %ecx, readmem_dword mov %edx, readmem_dword+4 ret .size read_nomemd_new, .-read_nomemd_new .globl write_nomem_new .hidden write_nomem_new .type write_nomem_new, @function write_nomem_new: call do_invalidate mov memory_map(,%edi,4),%edi mov word, %ecx mov $0xc, %eax shl $2, %edi jc tlb_exception mov %ecx, (%ebx,%edi) ret .size write_nomem_new, .-write_nomem_new .globl write_nomemb_new .hidden write_nomemb_new .type write_nomemb_new, @function write_nomemb_new: call do_invalidate mov memory_map(,%edi,4),%edi movb cpu_byte, %cl mov $0xc, %eax shl $2, %edi jc tlb_exception xor $3, %ebx movb %cl, (%ebx,%edi) ret .size write_nomemb_new, .-write_nomemb_new .globl write_nomemh_new .hidden write_nomemh_new .type write_nomemh_new, @function write_nomemh_new: call do_invalidate mov memory_map(,%edi,4),%edi movw hword, %cx mov $0xc, %eax shl $2, %edi jc tlb_exception xor $2, %ebx movw %cx, (%ebx,%edi) ret .size write_nomemh_new, .-write_nomemh_new .globl write_nomemd_new .hidden write_nomemd_new .type write_nomemd_new, @function write_nomemd_new: call do_invalidate mov memory_map(,%edi,4),%edi mov dword+4, %edx mov dword, %ecx mov $0xc, %eax shl $2, %edi jc tlb_exception mov %edx, (%ebx,%edi) mov %ecx, 4(%ebx,%edi) ret .size write_nomemd_new, .-write_nomemd_new .type tlb_exception, @function tlb_exception: /* eax = cause */ /* ebx = address */ /* ebp = instr addr + flags */ mov 0x24(%esp), %ebp /* Debug: push %ebp push %ebx push %eax call tlb_debug pop %eax pop %ebx pop %ebp /* end debug */ mov g_cp0_regs+48, %esi mov %ebp, %ecx mov %ebp, %edx mov %ebp, %edi shl $31, %ebp shr $12, %ecx or %ebp, %eax sar $29, %ebp and $0xFFFFFFFC, %edx mov memory_map(,%ecx,4), %ecx or $2, %esi mov (%edx, %ecx, 4), %ecx add %ebp, %edx mov %esi, g_cp0_regs+48 /* Status */ mov %eax, g_cp0_regs+52 /* Cause */ mov %edx, g_cp0_regs+56 /* EPC */ add $0x24, %esp mov $0x6000022, %edx mov %ecx, %ebp movswl %cx, %eax shr $26, %ecx shr $21, %ebp sub %eax, %ebx and $0x1f, %ebp ror %cl, %edx mov g_cp0_regs+16, %esi cmovc reg(,%ebp,8), %ebx and $0xFF80000F, %esi mov %ebx, reg(,%ebp,8) add %ebx, %eax sar $31, %ebx mov %eax, g_cp0_regs+32 /* BadVAddr */ shr $9, %eax test $2, %edi cmove reg+4(,%ebp,8), %ebx add $-12, %esp and $0x007FFFF0, %eax mov %ebx, reg+4(,%ebp,8) push $0x80000180 or %eax, %esi mov %esi, g_cp0_regs+16 /* Context */ call get_addr_ht add $16, %esp movl next_interupt, %edi movl g_cp0_regs+36, %esi /* Count */ movl %edi, last_count subl %edi, %esi jmp *%eax .size tlb_exception, .-tlb_exception .globl breakpoint .hidden breakpoint .type breakpoint, @function breakpoint: .size breakpoint, .-breakpoint mupen64plus-rsp-hle/INSTALL000664 001750 001750 00000001457 12655644434 016531 0ustar00sergiosergio000000 000000 Mupen64Plus-RSP-HLE INSTALL --------------------------- This text file was written to explain the installation process of the Mupen64Plus-RSP-HLE plugin. If this module is part of a Mupen64Plus source code bundle, the user should run the "m64p_install.sh" script in the root of the unzipped bundle to install all of the included modules in the bundle. If this module is a standalone source code release, you should build the library from source code and install it via the makefile, like this: $ cd projects/unix $ make all $ sudo make install If you want to build the Mupen64Plus-RSP-HLE module for installation in a home folder for a single user, you may build it like this (replacing with your desired local installation path): $ cd projects/unix $ make all $ make install LIBDIR= libretro/libretro_crc.c000664 001750 001750 00000002232 12655644434 016355 0ustar00sergiosergio000000 000000 #include #include #define CRC32_POLYNOMIAL 0x04C11DB7 unsigned int CRCTable[ 256 ]; static uint32_t Reflect(uint32_t ref, char ch ) { char i; uint32_t value = 0; /* Swap bit 0 for bit 7. * bit 1 for bit 6, etc. */ for (i = 1; i < (ch + 1); i++) { if(ref & 1) value |= 1 << (ch - i); ref >>= 1; } return value; } void CRC_BuildTable(void) { int i, j; uint32_t crc; for (i = 0; i < 256; i++) { crc = Reflect( i, 8 ) << 24; for (j = 0; j < 8; j++) crc = (crc << 1) ^ (crc & (1 << 31) ? CRC32_POLYNOMIAL : 0); CRCTable[i] = Reflect( crc, 32 ); } } unsigned int CRC32( unsigned int crc, void *buffer, unsigned int count ) { uint8_t *p = (uint8_t*) buffer; while (count--) crc = (crc >> 8) ^ CRCTable[(crc & 0xFF) ^ *p++]; return ~crc; } uint32_t CRC_Calculate(void *buffer, uint32_t count) { uint32_t crc = 0xffffffff; uint8_t *p = (uint8_t*) buffer; while (count--) crc = (crc >> 8) ^ CRCTable[(crc & 0xFF) ^ *p++]; return ~crc; } uint32_t adler32(uint32_t adler, void *buf, int len) { return CRC32(adler, buf, len); } mupen64plus-video-gliden64/src/000700 001750 001750 00000000000 12656647145 017415 5ustar00sergiosergio000000 000000 mupen64plus-video-gliden64/src/Log.h000664 001750 001750 00000001037 12655644434 020321 0ustar00sergiosergio000000 000000 #ifndef __LOG_H__ #define __LOG_H__ #define LOG_NONE 0 #define LOG_ERROR 1 #define LOG_MINIMAL 2 #define LOG_WARNING 3 #define LOG_VERBOSE 4 #define LOG_APIFUNC 5 #define LOG_LEVEL LOG_ERROR #if LOG_LEVEL>0 #include #include inline void LOG( u16 type, const char * format, ... ) { if (type > LOG_LEVEL) return; FILE *dumpFile = fopen( "gliden64.log", "a+" ); va_list va; va_start( va, format ); vfprintf( dumpFile, format, va ); fclose( dumpFile ); va_end( va ); } #else #define LOG(A, ...) #endif #endif mupen64plus-core/src/si/n64_cic_nus_6105.h000664 001750 001750 00000012456 12655644434 021217 0ustar00sergiosergio000000 000000 /* * Copyright 2011 X-Scale. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. 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. * * THIS SOFTWARE IS PROVIDED BY X-Scale ``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 X-Scale 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. * * The views and conclusions contained in the software and documentation are * those of the authors and should not be interpreted as representing official * policies, either expressed or implied, of X-Scale. * * This software provides an algorithm that emulates the protection scheme of * N64 PIF/CIC-NUS-6105, by determining the proper response to each challenge. * It was synthesized after a careful, exhaustive and detailed analysis of the * challenge/response pairs stored in the 'pif2.dat' file from Project 64. * These challenge/response pairs were the only resource used during this * project. There was no kind of physical access to N64 hardware. * * This project would have never been possible without the contribuitions of * the following individuals and organizations: * * - Oman: For being at the right place at the right time and being brave * enough to pay a personal price so we could understand in a much deeper * way how this magical console really works. We owe you so much. * * - Jovis: For all the positive energy and impressive hacking spirit that you * shared with the N64 community. You were absolutely instrumental in * several key events that shaped the N64 community in the last 14 years. * Even if you're not physically with us anymore, your heritage, your * knowledge and your attitude will never be forgotten. * * 'The candle that burns twice as bright burns half as long.' * * - LaC: For the endless contributions that you've given to the N64 community * since the early days, when N64 was the next big thing. I've always * admired the deep knowledge that you've gathered about the most little * hardware details. Recently, you challanged us to find a small and * concise algorithm that would emulate the behaviour of CIC-NUS-6105 * challenge/response protection scheme and here is the final result. * LaC, Oman and Jovis were definitly the dream team of N64 reversing in * the late 90's. Without your contributions, we would be much poorer. * * - marshall: For keeping the N64 scene alive during the last decade, when * most people lost interest and moved along to different projects. You * are the force that has been keeping us all together in the later * years. When almost nobody cared about N64 anymore, you were always * there, spreading the word, developing in the console, and lately, * making impressive advances on the hardware side. I wish the best * success to your new 64drive project. * * - hcs: For your contributions to the better understanding of the inner * workings of the Reality Co-Processor (RCP). Your skills have impressed * me for a long time now. And without your precious help by sharing your * kownledge, I would have never understood the immense importance of * Oman, Jovis and LaC achievements. Thank you ! * * - Azimer & Tooie: For sharing with the N64 community your findings about the * challenge/response pair used in 'Jet Force Gemini' and the 267 * challenge/response pairs used in 'Banjo Tooie', all stored in the * 'pif2.dat' file of Project 64. They were instrumental to the final * success of this endeavour. * * - Silicon Graphics, Inc. (SGI): For creating MIPS R4000, MIPS R4300 and * Reality Co-Processor (RCP). You were the ultimate dream creator during * the late 80's and early 90's. A very special word of gratitude goes to * the two teams that during those years created RCP and MIPS R4300. They * were technological breakthroughs back then. * * On a personal note, I would like to show my deepest gratitude to _Bijou_, * for being always a source of endless hope and inspiration. * * -= X-Scale =- (#n64dev@EFnet) */ #ifndef N64_CIC_NUS_6105_H #define N64_CIC_NUS_6105_H #include #define CHL_LEN 0x20 void n64_cic_nus_6105(int8_t chl[], int8_t rsp[], int len); #endif /* N64_CIC_NUS_6105_H */ mupen64plus-video-gliden64/src/S2DEX2.cpp000664 001750 001750 00000003506 12655644434 021045 0ustar00sergiosergio000000 000000 #include "OpenGL.h" #include "S2DEX.h" #include "S2DEX2.h" #include "F3D.h" #include "F3DEX.h" #include "F3DEX2.h" #include "GBI.h" #include "gSP.h" #include "gDP.h" #include "RSP.h" #include "Types.h" void S2DEX2_Init() { gSPSetupFunctions(); // Set GeometryMode flags GBI_InitFlags( F3DEX2 ); GBI.PCStackSize = 18; // GBI Command Command Value Command Function GBI_SetGBI( G_SPNOOP, F3DEX2_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_BG_1CYC, S2DEX2_BG_1CYC, S2DEX_BG_1Cyc ); GBI_SetGBI( G_BG_COPY, S2DEX2_BG_COPY, S2DEX_BG_Copy ); GBI_SetGBI( G_OBJ_RECTANGLE, S2DEX2_OBJ_RECTANGLE, S2DEX_Obj_Rectangle ); GBI_SetGBI( G_OBJ_SPRITE, S2DEX2_OBJ_SPRITE, S2DEX_Obj_Sprite ); GBI_SetGBI( G_OBJ_MOVEMEM, S2DEX2_OBJ_MOVEMEM, S2DEX_Obj_MoveMem ); GBI_SetGBI( G_DL, F3DEX2_DL, F3D_DList ); GBI_SetGBI( G_SELECT_DL, S2DEX2_SELECT_DL, S2DEX_Select_DL ); GBI_SetGBI( G_OBJ_RENDERMODE, S2DEX2_OBJ_RENDERMODE, S2DEX_Obj_RenderMode ); GBI_SetGBI( G_OBJ_RECTANGLE_R, S2DEX2_OBJ_RECTANGLE_R, S2DEX_Obj_Rectangle_R ); GBI_SetGBI( G_OBJ_LOADTXTR, S2DEX2_OBJ_LOADTXTR, S2DEX_Obj_LoadTxtr ); GBI_SetGBI( G_OBJ_LDTX_SPRITE, S2DEX2_OBJ_LDTX_SPRITE, S2DEX_Obj_LdTx_Sprite ); GBI_SetGBI( G_OBJ_LDTX_RECT, S2DEX2_OBJ_LDTX_RECT, S2DEX_Obj_LdTx_Rect ); GBI_SetGBI( G_OBJ_LDTX_RECT_R, S2DEX2_OBJ_LDTX_RECT_R, S2DEX_Obj_LdTx_Rect_R ); GBI_SetGBI( G_MOVEWORD, F3DEX2_MOVEWORD, F3DEX2_MoveWord ); GBI_SetGBI( G_SETOTHERMODE_H, F3DEX2_SETOTHERMODE_H, F3DEX2_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3DEX2_SETOTHERMODE_L, F3DEX2_SetOtherMode_L ); GBI_SetGBI( G_ENDDL, F3DEX2_ENDDL, F3D_EndDL ); GBI_SetGBI( G_RDPHALF_1, F3DEX2_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_RDPHALF_2, F3DEX2_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_LOAD_UCODE, F3DEX2_LOAD_UCODE, F3DEX_Load_uCode ); } glide2gl/src/Glide64/000700 001750 001750 00000000000 12656647145 015364 5ustar00sergiosergio000000 000000 mupen64plus-core/src/si/n64_cic_nus_6105.c000664 001750 001750 00000013734 12655644434 021212 0ustar00sergiosergio000000 000000 /* * Copyright 2011 X-Scale. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. 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. * * THIS SOFTWARE IS PROVIDED BY X-Scale ``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 X-Scale 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. * * The views and conclusions contained in the software and documentation are * those of the authors and should not be interpreted as representing official * policies, either expressed or implied, of X-Scale. * * This software provides an algorithm that emulates the protection scheme of * N64 PIF/CIC-NUS-6105, by determining the proper response to each challenge. * It was synthesized after a careful, exhaustive and detailed analysis of the * challenge/response pairs stored in the 'pif2.dat' file from Project 64. * These challenge/response pairs were the only resource used during this * project. There was no kind of physical access to N64 hardware. * * This project would have never been possible without the contribuitions of * the following individuals and organizations: * * - Oman: For being at the right place at the right time and being brave * enough to pay a personal price so we could understand in a much deeper * way how this magical console really works. We owe you so much. * * - Jovis: For all the positive energy and impressive hacking spirit that you * shared with the N64 community. You were absolutely instrumental in * several key events that shaped the N64 community in the last 14 years. * Even if you're not physically with us anymore, your heritage, your * knowledge and your attitude will never be forgotten. * * 'The candle that burns twice as bright burns half as long.' * * - LaC: For the endless contributions that you've given to the N64 community * since the early days, when N64 was the next big thing. I've always * admired the deep knowledge that you've gathered about the most little * hardware details. Recently, you challanged us to find a small and * concise algorithm that would emulate the behaviour of CIC-NUS-6105 * challenge/response protection scheme and here is the final result. * LaC, Oman and Jovis were definitly the dream team of N64 reversing in * the late 90's. Without your contributions, we would be much poorer. * * - marshall: For keeping the N64 scene alive during the last decade, when * most people lost interest and moved along to different projects. You * are the force that has been keeping us all together in the later * years. When almost nobody cared about N64 anymore, you were always * there, spreading the word, developing in the console, and lately, * making impressive advances on the hardware side. I wish the best * success to your new 64drive project. * * - hcs: For your contributions to the better understanding of the inner * workings of the Reality Co-Processor (RCP). Your skills have impressed * me for a long time now. And without your precious help by sharing your * kownledge, I would have never understood the immense importance of * Oman, Jovis and LaC achievements. Thank you ! * * - Azimer & Tooie: For sharing with the N64 community your findings about the * challenge/response pair used in 'Jet Force Gemini' and the 267 * challenge/response pairs used in 'Banjo Tooie', all stored in the * 'pif2.dat' file of Project 64. They were instrumental to the final * success of this endeavour. * * - Silicon Graphics, Inc. (SGI): For creating MIPS R4000, MIPS R4300 and * Reality Co-Processor (RCP). You were the ultimate dream creator during * the late 80's and early 90's. A very special word of gratitude goes to * the two teams that during those years created RCP and MIPS R4300. They * were technological breakthroughs back then. * * On a personal note, I would like to show my deepest gratitude to _Bijou_, * for being always a source of endless hope and inspiration. * * -= X-Scale =- (#n64dev@EFnet) */ #include "n64_cic_nus_6105.h" void n64_cic_nus_6105(int8_t chl[], int8_t rsp[], int len) { char key, *lut; int i; static char lut0[0x10] = { 0x4, 0x7, 0xA, 0x7, 0xE, 0x5, 0xE, 0x1, 0xC, 0xF, 0x8, 0xF, 0x6, 0x3, 0x6, 0x9 }; static char lut1[0x10] = { 0x4, 0x1, 0xA, 0x7, 0xE, 0x5, 0xE, 0x1, 0xC, 0x9, 0x8, 0x5, 0x6, 0x3, 0xC, 0x9 }; for (key = 0xB, lut = lut0, i = 0; i < len; i++) { int mag, mod, sgn; rsp[i] = (key + 5 * chl[i]) & 0xF; key = lut[(int) rsp[i]]; sgn = (rsp[i] >> 3) & 0x1; mag = ((sgn == 1) ? ~rsp[i] : rsp[i]) & 0x7; mod = (mag % 3 == 1) ? sgn : 1 - sgn; if (lut == lut1 && (rsp[i] == 0x1 || rsp[i] == 0x9)) mod = 1; if (lut == lut1 && (rsp[i] == 0xB || rsp[i] == 0xE)) mod = 0; lut = (mod == 1) ? lut1 : lut0; } } mupen64plus-video-gliden64/src/Types.h000664 001750 001750 00000002232 12655644434 020702 0ustar00sergiosergio000000 000000 #ifndef TYPES_H #define TYPES_H typedef unsigned char u8; /* unsigned 8-bit */ typedef unsigned short u16; /* unsigned 16-bit */ typedef unsigned int u32; /* unsigned 32-bit */ typedef unsigned long long u64; /* unsigned 64-bit */ typedef signed char s8; /* signed 8-bit */ typedef short s16; /* signed 16-bit */ typedef int s32; /* signed 32-bit */ typedef long long s64; /* signed 64-bit */ typedef volatile unsigned char vu8; /* unsigned 8-bit */ typedef volatile unsigned short vu16; /* unsigned 16-bit */ typedef volatile unsigned int vu32; /* unsigned 32-bit */ typedef volatile unsigned long long vu64; /* unsigned 64-bit */ typedef volatile signed char vs8; /* signed 8-bit */ typedef volatile short vs16; /* signed 16-bit */ typedef volatile int vs32; /* signed 32-bit */ typedef volatile long long vs64; /* signed 64-bit */ typedef float f32; /* single prec floating point */ typedef double f64; /* double prec floating point */ #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #ifndef NULL #define NULL 0 #endif #ifndef PLUGIN_PATH_SIZE #define PLUGIN_PATH_SIZE 260 #endif #endif // TYPES_H mupen64plus-video-gliden64/ini/GLideN64.ini000664 001750 001750 00000001502 12655644434 021371 0ustar00sergiosergio000000 000000 [General] version=5 [video] fullscreenWidth=640 fullscreenHeight=480 windowedWidth=640 windowedHeight=480 fullscreenRefresh=60 multisampling=0 [texture] maxAnisotropy=0 bilinearMode=1 maxBytes=524288000 screenShotFormat=0 [generalEmulation] enableFog=1 enableNoise=1 enableLOD=1 enableHWLighting=0 enableCustomSettings=1 [frameBufferEmulation] enable=1 copyToRDRAM=2 copyDepthToRDRAM=0 copyFromRDRAM=0 detectCFB=0 N64DepthCompare=0 aspect=1 [textureFilter] txFilterMode=0 txEnhancementMode=0 txFilterIgnoreBG=0 txCacheSize=104857600 txHiresEnable=0 txHiresFullAlphaChannel=0 txHresAltCRC=0 txDump=0 txForce16bpp=0 txCacheCompression=1 txSaveCache=1 [font] name=arial.ttf size=18 color=@Variant(\0\0\0\x43\x1\xff\xff\xb5\xb5\xe6\xe6\x1d\x1d\0\0) [bloomFilter] enable=0 thresholdLevel=4 blendMode=0 blurAmount=10 blurStrength=20 mupen64plus-video-gliden64/licenses/GlideHQ/000700 001750 001750 00000000000 12656647145 021710 5ustar00sergiosergio000000 000000 mupen64plus-video-gliden64/src/FrameBuffer.h000664 001750 001750 00000005741 12655644434 021772 0ustar00sergiosergio000000 000000 #ifndef FRAMEBUFFER_H #define FRAMEBUFFER_H #include #include #include "Types.h" #include "Textures.h" struct gDPTile; struct DepthBuffer; const int fingerprint[4] = { 2, 6, 4, 3 }; struct FrameBuffer { FrameBuffer(); FrameBuffer(FrameBuffer && _other); ~FrameBuffer(); void init(u32 _address, u32 _endAddress, u16 _format, u16 _size, u16 _width, u16 _height, bool _cfb); void reinit(u16 _height); void resolveMultisampledTexture(); CachedTexture * getTexture(); void copyRdram(); bool isValid() const; bool _isMarioTennisScoreboard() const; u32 m_startAddress, m_endAddress; u32 m_size, m_width, m_height, m_fillcolor, m_validityChecked; float m_scaleX, m_scaleY; bool m_copiedToRdram; bool m_fingerprint; bool m_cleared; bool m_changed; bool m_cfb; bool m_isDepthBuffer; bool m_isPauseScreen; bool m_isOBScreen; bool m_needHeightCorrection; u32 m_postProcessed; GLuint m_FBO; gDPTile *m_pLoadTile; CachedTexture *m_pTexture; DepthBuffer *m_pDepthBuffer; // multisampling CachedTexture *m_pResolveTexture; GLuint m_resolveFBO; bool m_resolved; std::vector m_RdramCopy; private: void _initTexture(u16 _format, u16 _size, CachedTexture *_pTexture); void _setAndAttachTexture(u16 _size, CachedTexture *_pTexture); }; class FrameBufferList { public: void init(); void destroy(); void saveBuffer(u32 _address, u16 _format, u16 _size, u16 _width, u16 _height, bool _cfb); void removeAux(); void copyAux(); void removeBuffer(u32 _address); void removeBuffers(u32 _width); void attachDepthBuffer(); FrameBuffer * findBuffer(u32 _startAddress); FrameBuffer * findTmpBuffer(u32 _address); FrameBuffer * getCurrent() const {return m_pCurrent;} void renderBuffer(u32 _address); void setBufferChanged(); void correctHeight(); void clearBuffersChanged(); FrameBuffer * getCopyBuffer() const { return m_pCopy; } void setCopyBuffer(FrameBuffer * _pBuffer) { m_pCopy = _pBuffer; } static FrameBufferList & get(); private: FrameBufferList() : m_pCurrent(NULL), m_pCopy(NULL) {} FrameBufferList(const FrameBufferList &); FrameBuffer * _findBuffer(u32 _startAddress, u32 _endAddress, u32 _width); typedef std::list FrameBuffers; FrameBuffers m_list; FrameBuffer * m_pCurrent; FrameBuffer * m_pCopy; }; struct PBOBinder { #ifndef GLES2 PBOBinder(GLenum _target, GLuint _PBO) : m_target(_target) { glBindBuffer(m_target, _PBO); } ~PBOBinder() { glBindBuffer(m_target, 0); } GLenum m_target; #else PBOBinder(GLubyte* _ptr) : ptr(_ptr) {} ~PBOBinder() { free(ptr); } GLubyte* ptr; #endif }; inline FrameBufferList & frameBufferList() { return FrameBufferList::get(); } void FrameBuffer_Init(); void FrameBuffer_Destroy(); void FrameBuffer_CopyToRDRAM( u32 _address , bool _sync ); void FrameBuffer_CopyFromRDRAM( u32 address, bool bUseAlpha ); bool FrameBuffer_CopyDepthBuffer( u32 address ); void FrameBuffer_ActivateBufferTexture(s16 t, FrameBuffer *pBuffer); void FrameBuffer_ActivateBufferTextureBG(s16 t, FrameBuffer *pBuffer); #endif mupen64plus-video-gliden64/src/GLideNHQ/TextureFilters_2xsai.cpp000664 001750 001750 00000012674 12655644434 025576 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Based on Derek Liauw Kie Fa and Rice1964 Super2xSaI code */ #include "TextureFilters.h" #define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D)) void Super2xSaI_8888(uint32 *srcPtr, uint32 *destPtr, uint32 width, uint32 height, uint32 pitch) { #define SAI_INTERPOLATE_8888(A, B) ((A & 0xFEFEFEFE) >> 1) + ((B & 0xFEFEFEFE) >> 1) + (A & B & 0x01010101) #define SAI_Q_INTERPOLATE_8888(A, B, C, D) ((A & 0xFCFCFCFC) >> 2) + ((B & 0xFCFCFCFC) >> 2) + ((C & 0xFCFCFCFC) >> 2) + ((D & 0xFCFCFCFC) >> 2) \ + ((((A & 0x03030303) + (B & 0x03030303) + (C & 0x03030303) + (D & 0x03030303)) >> 2) & 0x03030303) #define SAI_INTERPOLATE SAI_INTERPOLATE_8888 #define SAI_Q_INTERPOLATE SAI_Q_INTERPOLATE_8888 uint32 destWidth = width << 1; uint32 destHeight = height << 1; uint32 color4, color5, color6; uint32 color1, color2, color3; uint32 colorA0, colorA1, colorA2, colorA3; uint32 colorB0, colorB1, colorB2, colorB3; uint32 colorS1, colorS2; uint32 product1a, product1b, product2a, product2b; #include "TextureFilters_2xsai.h" #undef SAI_INTERPOLATE #undef SAI_Q_INTERPOLATE } #if !_16BPP_HACK void Super2xSaI_4444(uint16 *srcPtr, uint16 *destPtr, uint32 width, uint32 height, uint32 pitch) { #define SAI_INTERPOLATE_4444(A, B) ((A & 0xEEEE) >> 1) + ((B & 0xEEEE) >> 1) + (A & B & 0x1111) #define SAI_Q_INTERPOLATE_4444(A, B, C, D) ((A & 0xCCCC) >> 2) + ((B & 0xCCCC) >> 2) + ((C & 0xCCCC) >> 2) + ((D & 0xCCCC) >> 2) \ + ((((A & 0x3333) + (B & 0x3333) + (C & 0x3333) + (D & 0x3333)) >> 2) & 0x3333) #define SAI_INTERPOLATE SAI_INTERPOLATE_4444 #define SAI_Q_INTERPOLATE SAI_Q_INTERPOLATE_4444 uint32 destWidth = width << 1; uint32 destHeight = height << 1; uint16 color4, color5, color6; uint16 color1, color2, color3; uint16 colorA0, colorA1, colorA2, colorA3; uint16 colorB0, colorB1, colorB2, colorB3; uint16 colorS1, colorS2; uint16 product1a, product1b, product2a, product2b; #include "TextureFilters_2xsai.h" #undef SAI_INTERPOLATE #undef SAI_Q_INTERPOLATE } void Super2xSaI_1555(uint16 *srcPtr, uint16 *destPtr, uint32 width, uint32 height, uint32 pitch) { #define SAI_INTERPOLATE_1555(A, B) ((A & 0x7BDE) >> 1) + ((B & 0x7BDE) >> 1) + (A & B & 0x8421) #define SAI_Q_INTERPOLATE_1555(A, B, C, D) ((A & 0x739C) >> 2) + ((B & 0x739C) >> 2) + ((C & 0x739C) >> 2) + ((D & 0x739C) >> 2) \ + ((((A & 0x8C63) + (B & 0x8C63) + (C & 0x8C63) + (D & 0x8C63)) >> 2) & 0x8C63) #define SAI_INTERPOLATE SAI_INTERPOLATE_1555 #define SAI_Q_INTERPOLATE SAI_Q_INTERPOLATE_1555 uint32 destWidth = width << 1; uint32 destHeight = height << 1; uint16 color4, color5, color6; uint16 color1, color2, color3; uint16 colorA0, colorA1, colorA2, colorA3; uint16 colorB0, colorB1, colorB2, colorB3; uint16 colorS1, colorS2; uint16 product1a, product1b, product2a, product2b; #include "TextureFilters_2xsai.h" #undef SAI_INTERPOLATE #undef SAI_Q_INTERPOLATE } void Super2xSaI_565(uint16 *srcPtr, uint16 *destPtr, uint32 width, uint32 height, uint32 pitch) { #define SAI_INTERPOLATE_565(A, B) ((A & 0xF7DE) >> 1) + ((B & 0xF7DE) >> 1) + (A & B & 0x0821) #define SAI_Q_INTERPOLATE_565(A, B, C, D) ((A & 0xE79C) >> 2) + ((B & 0xE79C) >> 2) + ((C & 0xE79C) >> 2) + ((D & 0xE79C) >> 2) \ + ((((A & 0x1863) + (B & 0x1863) + (C & 0x1863) + (D & 0x1863)) >> 2) & 0x1863) #define SAI_INTERPOLATE SAI_INTERPOLATE_565 #define SAI_Q_INTERPOLATE SAI_Q_INTERPOLATE_565 uint32 destWidth = width << 1; uint32 destHeight = height << 1; uint16 color4, color5, color6; uint16 color1, color2, color3; uint16 colorA0, colorA1, colorA2, colorA3; uint16 colorB0, colorB1, colorB2, colorB3; uint16 colorS1, colorS2; uint16 product1a, product1b, product2a, product2b; #include "TextureFilters_2xsai.h" #undef SAI_INTERPOLATE #undef SAI_Q_INTERPOLATE } void Super2xSaI_8(uint8 *srcPtr, uint8 *destPtr, uint32 width, uint32 height, uint32 pitch) { #define SAI_INTERPOLATE_8(A, B) ((A & 0xFE) >> 1) + ((B & 0xFE) >> 1) + (A & B & 0x01) #define SAI_Q_INTERPOLATE_8(A, B, C, D) ((A & 0xFC) >> 2) + ((B & 0xFC) >> 2) + ((C & 0xFC) >> 2) + ((D & 0xFC) >> 2) \ + ((((A & 0x03) + (B & 0x03) + (C & 0x03) + (D & 0x03)) >> 2) & 0x03) #define SAI_INTERPOLATE SAI_INTERPOLATE_8 #define SAI_Q_INTERPOLATE SAI_Q_INTERPOLATE_8 uint32 destWidth = width << 1; uint32 destHeight = height << 1; uint8 color4, color5, color6; uint8 color1, color2, color3; uint8 colorA0, colorA1, colorA2, colorA3; uint8 colorB0, colorB1, colorB2, colorB3; uint8 colorS1, colorS2; uint8 product1a, product1b, product2a, product2b; #include "TextureFilters_2xsai.h" #undef SAI_INTERPOLATE #undef SAI_Q_INTERPOLATE } #endif /* !_16BPP_HACK */ mupen64plus-core/src/si/si_controller.h000664 001750 001750 00000004672 12655644434 021311 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - si_controller.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef SI_SI_CONTROLLER_H #define SI_SI_CONTROLLER_H #include #include "pif.h" #ifndef SI_REG #define SI_REG(a) ((a & 0xffff) >> 2) #endif struct r4300_core; struct ri_controller; enum si_registers { SI_DRAM_ADDR_REG, SI_PIF_ADDR_RD64B_REG, SI_R2_REG, /* reserved */ SI_R3_REG, /* reserved */ SI_PIF_ADDR_WR64B_REG, SI_R5_REG, /* reserved */ SI_STATUS_REG, SI_REGS_COUNT }; struct si_controller { uint32_t regs[SI_REGS_COUNT]; struct pif pif; struct r4300_core* r4300; struct ri_controller *ri; }; void connect_si(struct si_controller* si, struct r4300_core* r4300, struct ri_controller *ri); void init_si(struct si_controller* si); int read_si_regs(void* opaque, uint32_t address, uint32_t* value); int write_si_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask); void si_end_of_dma_event(struct si_controller* si); #endif mupen64plus-core/src/r4300/new_dynarec/linkage_arm.S000664 001750 001750 00000061020 12655644434 023300 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - linkage_arm.s * * Copyright (C) 2009-2011 Ari64 * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* .cpu arm9tdmi .fpu softvfp .eabi_attribute 20, 1 .eabi_attribute 21, 1 .eabi_attribute 23, 3 .eabi_attribute 24, 1 .eabi_attribute 25, 1 .eabi_attribute 26, 2 #if (defined(__VFP_FP__) && !defined(__SOFTFP__) && defined(__ARM_PCS_VFP)) .eabi_attribute 28, 1 #endif .eabi_attribute 30, 6 .eabi_attribute 18, 4 .file "linkage_arm.S"*/ /* global function/external symbol */ #ifndef __MACH__ #define ESYM(name) name #define FUNCTION(name) \ .align 2; \ .globl name; \ .type name, %function; \ name #else #define ESYM(name) _##name #define FUNCTION(name) \ .align 2; \ .globl ESYM(name); \ name: \ ESYM(name) #endif #include "linkage_offsets.h" #ifdef __MACH__ #define extra_memory ESYM(extra_memory) #define add_link ESYM(add_link) #define check_interupt ESYM(check_interupt) #define clean_blocks ESYM(clean_blocks) #define dynarec_local ESYM(dynarec_local) #define gen_interupt ESYM(gen_interupt) #define get_addr ESYM(get_addr) #define get_addr_32 ESYM(get_addr_32) #define get_addr_ht ESYM(get_addr_ht) #define invalidate_block ESYM(invalidate_block) #define new_recompile_block ESYM(new_recompile_block) #endif .bss .align 12 .global extra_memory .type extra_memory, %object .size extra_memory, 33554432 extra_memory: .space 33554432 .global dynarec_local .type dynarec_local, %object .size dynarec_local, 64+16+16+8+8+8+8+256+8+8+128+128+128+16+8+132+4+256+512+4194304 dynarec_local: .space 64+16+16+8+8+8+8+256+8+8+128+128+128+16+8+132+4+256+512+4194304 #define DRC_VAR_(name, vname, size_) \ vname = dynarec_local + LO_##name; \ .global vname; \ .type vname, %object; \ .size vname, size_ #define DRC_VAR(name, size_) \ DRC_VAR_(name, ESYM(name), size_) DRC_VAR(next_interupt, 4) DRC_VAR(cycle_count, 4) DRC_VAR(last_count, 4) DRC_VAR(pending_exception, 4) DRC_VAR(pcaddr, 4) DRC_VAR(stop, 4) DRC_VAR(invc_ptr, 4) DRC_VAR(address, 4) DRC_VAR(readmem_dword, 8) DRC_VAR(dword, 8) DRC_VAR(word, 4) DRC_VAR(hword, 2) DRC_VAR(cpu_byte, 1) /* 1 byte free */ DRC_VAR(cpu_byte_two, 1) /* padding */ DRC_VAR(FCR0, 4) DRC_VAR(FCR31, 4) DRC_VAR(reg, 256) DRC_VAR(hi, 8) DRC_VAR(lo, 8) DRC_VAR(g_cp0_regs, 128) DRC_VAR(reg_cop1_simple, 128) DRC_VAR(reg_cop1_double, 128) DRC_VAR(rounding_modes, 16) DRC_VAR(branch_target, 4) DRC_VAR(PC, 4) DRC_VAR(fake_pc, 132) DRC_VAR(ram_offset, 4) DRC_VAR(mini_ht, 256) DRC_VAR(restore_candidate, 512) DRC_VAR(memory_map, 4194304) #ifdef __MACH__ .data .align 2 ptr_jump_in: .word ESYM(jump_in) ptr_jump_dirty: .word ESYM(jump_dirty) ptr_tlb_LUT_r: .word ESYM(tlb_LUT_r) ptr_hash_table: .word ESYM(hash_table) ptr_out: .word ESYM(out) #endif .syntax unified .text .macro load_varadr reg var #if defined(__ARM_ARCH_7A__) && !defined(__PIC__) movw \reg, #:lower16:\var movt \reg, #:upper16:\var #elif defined(__ARM_ARCH_7A__) && defined(__MACH__) movw \reg, #:lower16:(\var-(1678f+8)) movt \reg, #:upper16:(\var-(1678f+8)) 1678: add \reg, pc #else ldr \reg, =\var #endif .endm .macro load_varadr_ext reg var #if defined(__ARM_ARCH_7A__) && defined(__MACH__) && defined(__PIC__) movw \reg, #:lower16:(ptr_\var-(1678f+8)) movt \reg, #:upper16:(ptr_\var-(1678f+8)) 1678: ldr \reg, [pc, \reg] #else load_varadr \reg \var #endif .endm FUNCTION(dyna_linker): /* r0 = virtual target address */ /* r1 = instruction to patch */ load_varadr_ext r4, tlb_LUT_r lsr r5, r0, #12 mov r12, r0 cmp r0, #0xC0000000 mov r6, #4096 ldrge r12, [r4, r5, lsl #2] mov r2, #0x80000 load_varadr_ext r3, jump_in tst r12, r12 sub r6, r6, #1 moveq r12, r0 ldr r7, [r1] eor r2, r2, r12, lsr #12 and r6, r6, r12, lsr #12 cmp r2, #2048 add r12, r7, #2 orrcs r2, r6, #2048 ldr r5, [r3, r2, lsl #2] lsl r12, r12, #8 /* jump_in lookup */ .A1: movs r4, r5 beq .A3 ldr r3, [r5] ldr r5, [r4, #12] teq r3, r0 bne .A1 ldr r3, [r4, #4] ldr r4, [r4, #8] tst r3, r3 bne .A1 .A2: mov r5, r1 add r1, r1, r12, asr #6 teq r1, r4 moveq pc, r4 /* Stale i-cache */ bl add_link sub r2, r4, r5 and r1, r7, #0xff000000 lsl r2, r2, #6 sub r1, r1, #2 add r1, r1, r2, lsr #8 str r1, [r5] mov pc, r4 .A3: /* hash_table lookup */ cmp r2, #2048 load_varadr_ext r3, jump_dirty eor r4, r0, r0, lsl #16 lslcc r2, r0, #9 load_varadr_ext r6, hash_table lsr r4, r4, #12 lsrcc r2, r2, #21 bic r4, r4, #15 ldr r5, [r3, r2, lsl #2] ldr r7, [r6, r4]! teq r7, r0 ldreq pc, [r6, #4] ldr r7, [r6, #8] teq r7, r0 ldreq pc, [r6, #12] /* jump_dirty lookup */ .A6: movs r4, r5 beq .A8 ldr r3, [r5] ldr r5, [r4, #12] teq r3, r0 bne .A6 .A7: ldr r1, [r4, #8] /* hash_table insert */ ldr r2, [r6] ldr r3, [r6, #4] str r0, [r6] str r1, [r6, #4] str r2, [r6, #8] str r3, [r6, #12] mov pc, r1 .A8: mov r4, r0 mov r5, r1 bl new_recompile_block tst r0, r0 mov r0, r4 mov r1, r5 beq dyna_linker /* pagefault */ mov r1, r0 mov r2, #8 .size dyna_linker, .-dyna_linker FUNCTION(exec_pagefault): /* r0 = instruction pointer */ /* r1 = fault address */ /* r2 = cause */ ldr r3, [fp, #LO_g_cp0_regs+48-LO_dynarec_local] /* Status */ mvn r6, #0xF000000F ldr r4, [fp, #LO_g_cp0_regs+16-LO_dynarec_local] /* Context */ bic r6, r6, #0x0F800000 str r0, [fp, #LO_g_cp0_regs+56-LO_dynarec_local] /* EPC */ orr r3, r3, #2 str r1, [fp, #LO_g_cp0_regs+32-LO_dynarec_local] /* BadVAddr */ bic r4, r4, r6 str r3, [fp, #LO_g_cp0_regs+48-LO_dynarec_local] /* Status */ and r5, r6, r1, lsr #9 str r2, [fp, #LO_g_cp0_regs+52-LO_dynarec_local] /* Cause */ and r1, r1, r6, lsl #9 str r1, [fp, #LO_g_cp0_regs+40-LO_dynarec_local] /* EntryHi */ orr r4, r4, r5 str r4, [fp, #LO_g_cp0_regs+16-LO_dynarec_local] /* Context */ mov r0, #0x80000000 bl get_addr_ht mov pc, r0 .size exec_pagefault, .-exec_pagefault /* Special dynamic linker for the case where a page fault may occur in a branch delay slot */ FUNCTION(dyna_linker_ds): /* r0 = virtual target address */ /* r1 = instruction to patch */ load_varadr_ext r4, tlb_LUT_r lsr r5, r0, #12 mov r12, r0 cmp r0, #0xC0000000 mov r6, #4096 ldrge r12, [r4, r5, lsl #2] mov r2, #0x80000 load_varadr_ext r3, jump_in tst r12, r12 sub r6, r6, #1 moveq r12, r0 ldr r7, [r1] eor r2, r2, r12, lsr #12 and r6, r6, r12, lsr #12 cmp r2, #2048 add r12, r7, #2 orrcs r2, r6, #2048 ldr r5, [r3, r2, lsl #2] lsl r12, r12, #8 /* jump_in lookup */ .B1: movs r4, r5 beq .B3 ldr r3, [r5] ldr r5, [r4, #12] teq r3, r0 bne .B1 ldr r3, [r4, #4] ldr r4, [r4, #8] tst r3, r3 bne .B1 .B2: mov r5, r1 add r1, r1, r12, asr #6 teq r1, r4 moveq pc, r4 /* Stale i-cache */ bl add_link sub r2, r4, r5 and r1, r7, #0xff000000 lsl r2, r2, #6 sub r1, r1, #2 add r1, r1, r2, lsr #8 str r1, [r5] mov pc, r4 .B3: /* hash_table lookup */ cmp r2, #2048 load_varadr_ext r3, jump_dirty eor r4, r0, r0, lsl #16 lslcc r2, r0, #9 load_varadr_ext r6, hash_table lsr r4, r4, #12 lsrcc r2, r2, #21 bic r4, r4, #15 ldr r5, [r3, r2, lsl #2] ldr r7, [r6, r4]! teq r7, r0 ldreq pc, [r6, #4] ldr r7, [r6, #8] teq r7, r0 ldreq pc, [r6, #12] /* jump_dirty lookup */ .B6: movs r4, r5 beq .B8 ldr r3, [r5] ldr r5, [r4, #12] teq r3, r0 bne .B6 .B7: ldr r1, [r4, #8] /* hash_table insert */ ldr r2, [r6] ldr r3, [r6, #4] str r0, [r6] str r1, [r6, #4] str r2, [r6, #8] str r3, [r6, #12] mov pc, r1 .B8: mov r4, r0 bic r0, r0, #7 mov r5, r1 orr r0, r0, #1 bl new_recompile_block tst r0, r0 mov r0, r4 mov r1, r5 beq dyna_linker_ds /* pagefault */ bic r1, r0, #7 mov r2, #0x80000008 /* High bit set indicates pagefault in delay slot */ sub r0, r1, #4 b exec_pagefault .size dyna_linker_ds, .-dyna_linker_ds FUNCTION(jump_vaddr_r0): eor r2, r0, r0, lsl #16 b jump_vaddr .size jump_vaddr_r0, .-jump_vaddr_r0 FUNCTION(jump_vaddr_r1): eor r2, r1, r1, lsl #16 mov r0, r1 b jump_vaddr .size jump_vaddr_r1, .-jump_vaddr_r1 FUNCTION(jump_vaddr_r2): mov r0, r2 eor r2, r2, r2, lsl #16 b jump_vaddr .size jump_vaddr_r2, .-jump_vaddr_r2 FUNCTION(jump_vaddr_r3): eor r2, r3, r3, lsl #16 mov r0, r3 b jump_vaddr .size jump_vaddr_r3, .-jump_vaddr_r3 FUNCTION(jump_vaddr_r4): eor r2, r4, r4, lsl #16 mov r0, r4 b jump_vaddr .size jump_vaddr_r4, .-jump_vaddr_r4 FUNCTION(jump_vaddr_r5): eor r2, r5, r5, lsl #16 mov r0, r5 b jump_vaddr .size jump_vaddr_r5, .-jump_vaddr_r5 FUNCTION(jump_vaddr_r6): eor r2, r6, r6, lsl #16 mov r0, r6 b jump_vaddr .size jump_vaddr_r6, .-jump_vaddr_r6 FUNCTION(jump_vaddr_r8): eor r2, r8, r8, lsl #16 mov r0, r8 b jump_vaddr .size jump_vaddr_r8, .-jump_vaddr_r8 FUNCTION(jump_vaddr_r9): eor r2, r9, r9, lsl #16 mov r0, r9 b jump_vaddr .size jump_vaddr_r9, .-jump_vaddr_r9 FUNCTION(jump_vaddr_r10): eor r2, r10, r10, lsl #16 mov r0, r10 b jump_vaddr .size jump_vaddr_r10, .-jump_vaddr_r10 FUNCTION(jump_vaddr_r12): eor r2, r12, r12, lsl #16 mov r0, r12 b jump_vaddr .size jump_vaddr_r12, .-jump_vaddr_r12 FUNCTION(jump_vaddr_r7): eor r2, r7, r7, lsl #16 add r0, r7, #0 .size jump_vaddr_r7, .-jump_vaddr_r7 FUNCTION(jump_vaddr): load_varadr_ext r1, hash_table mvn r3, #15 and r2, r3, r2, lsr #12 ldr r2, [r1, r2]! teq r2, r0 ldreq pc, [r1, #4] ldr r2, [r1, #8] teq r2, r0 ldreq pc, [r1, #12] str r10, [fp, #LO_cycle_count-LO_dynarec_local] bl get_addr ldr r10, [fp, #LO_cycle_count-LO_dynarec_local] mov pc, r0 .size jump_vaddr, .-jump_vaddr FUNCTION(verify_code_ds): // Unused? str r8, [fp, #LO_branch_target-LO_dynarec_local] .size verify_code_ds, .-verify_code_ds FUNCTION(verify_code_vm): /* r0 = instruction pointer (virtual address) */ /* r1 = source (virtual address) */ /* r2 = target */ /* r3 = length */ cmp r1, #0xC0000000 blt verify_code add r12, fp, #LO_memory_map-LO_dynarec_local lsr r4, r1, #12 add r5, r1, r3 sub r5, #1 ldr r6, [r12, r4, lsl #2] lsr r5, r5, #12 movs r7, r6 bmi .D5 add r1, r1, r6, lsl #2 lsl r6, r6, #2 .D1: add r4, r4, #1 teq r6, r7, lsl #2 bne .D5 ldr r7, [r12, r4, lsl #2] cmp r4, r5 bls .D1 .size verify_code_vm, .-verify_code_vm FUNCTION(verify_code): /* r1 = source */ /* r2 = target */ /* r3 = length */ tst r3, #4 mov r4, #0 add r3, r1, r3 mov r5, #0 ldrne r4, [r1], #4 mov r12, #0 ldrne r5, [r2], #4 teq r1, r3 beq .D3 .D2: ldr r7, [r1], #4 eor r9, r4, r5 ldr r8, [r2], #4 orrs r9, r9, r12 bne .D4 ldr r4, [r1], #4 eor r12, r7, r8 ldr r5, [r2], #4 cmp r1, r3 bcc .D2 teq r7, r8 .D3: teqeq r4, r5 .D4: ldr r8, [fp, #LO_branch_target-LO_dynarec_local] moveq pc, lr .D5: bl get_addr mov pc, r0 .size verify_code, .-verify_code FUNCTION(cc_interrupt): ldr r0, [fp, #LO_last_count-LO_dynarec_local] mov r1, #0 mov r2, #0x1fc add r10, r0, r10 str r1, [fp, #LO_pending_exception-LO_dynarec_local] and r2, r2, r10, lsr #17 add r3, fp, #LO_restore_candidate-LO_dynarec_local str r10, [fp, #LO_g_cp0_regs+36-LO_dynarec_local] /* Count */ ldr r4, [r2, r3] mov r10, lr tst r4, r4 bne .E4 .E1: bl gen_interupt mov lr, r10 ldr r10, [fp, #LO_g_cp0_regs+36-LO_dynarec_local] /* Count */ ldr r0, [fp, #LO_next_interupt-LO_dynarec_local] ldr r1, [fp, #LO_pending_exception-LO_dynarec_local] ldr r2, [fp, #LO_stop-LO_dynarec_local] str r0, [fp, #LO_last_count-LO_dynarec_local] sub r10, r10, r0 tst r2, r2 bne .E3 tst r1, r1 moveq pc, lr .E2: ldr r0, [fp, #LO_pcaddr-LO_dynarec_local] bl get_addr_ht mov pc, r0 .E3: ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, pc} .E4: /* Move 'dirty' blocks to the 'clean' list */ lsl r5, r2, #3 str r1, [r2, r3] .E5: lsrs r4, r4, #1 mov r0, r5 add r5, r5, #1 blcs clean_blocks tst r5, #31 bne .E5 b .E1 .size cc_interrupt, .-cc_interrupt FUNCTION(do_interrupt): ldr r0, [fp, #LO_pcaddr-LO_dynarec_local] bl get_addr_ht ldr r1, [fp, #LO_next_interupt-LO_dynarec_local] ldr r10, [fp, #LO_g_cp0_regs+36-LO_dynarec_local] /* Count */ str r1, [fp, #LO_last_count-LO_dynarec_local] sub r10, r10, r1 add r10, r10, #2 mov pc, r0 .size do_interrupt, .-do_interrupt FUNCTION(fp_exception): mov r2, #0x10000000 .E7: ldr r1, [fp, #LO_g_cp0_regs+48-LO_dynarec_local] /* Status */ mov r3, #0x80000000 str r0, [fp, #LO_g_cp0_regs+56-LO_dynarec_local] /* EPC */ orr r1, #2 add r2, r2, #0x2c str r1, [fp, #LO_g_cp0_regs+48-LO_dynarec_local] /* Status */ str r2, [fp, #LO_g_cp0_regs+52-LO_dynarec_local] /* Cause */ add r0, r3, #0x180 bl get_addr_ht mov pc, r0 .size fp_exception, .-fp_exception FUNCTION(fp_exception_ds): mov r2, #0x90000000 /* Set high bit if delay slot */ b .E7 .size fp_exception_ds, .-fp_exception_ds FUNCTION(jump_syscall): ldr r1, [fp, #LO_g_cp0_regs+48-LO_dynarec_local] /* Status */ mov r3, #0x80000000 str r0, [fp, #LO_g_cp0_regs+56-LO_dynarec_local] /* EPC */ orr r1, #2 mov r2, #0x20 str r1, [fp, #LO_g_cp0_regs+48-LO_dynarec_local] /* Status */ str r2, [fp, #LO_g_cp0_regs+52-LO_dynarec_local] /* Cause */ add r0, r3, #0x180 bl get_addr_ht mov pc, r0 .size jump_syscall, .-jump_syscall FUNCTION(indirect_jump_indexed): ldr r0, [r0, r1, lsl #2] .size indirect_jump_indexed, .-indirect_jump_indexed FUNCTION(indirect_jump): ldr r12, [fp, #LO_last_count-LO_dynarec_local] add r2, r2, r12 str r2, [fp, #LO_g_cp0_regs+36-LO_dynarec_local] /* Count */ mov pc, r0 .size indirect_jump, .-indirect_jump FUNCTION(jump_eret): ldr r1, [fp, #LO_g_cp0_regs+48-LO_dynarec_local] /* Status */ ldr r0, [fp, #LO_last_count-LO_dynarec_local] bic r1, r1, #2 add r10, r0, r10 str r1, [fp, #LO_g_cp0_regs+48-LO_dynarec_local] /* Status */ str r10, [fp, #LO_g_cp0_regs+36-LO_dynarec_local] /* Count */ bl check_interupt ldr r1, [fp, #LO_next_interupt-LO_dynarec_local] ldr r0, [fp, #LO_g_cp0_regs+56-LO_dynarec_local] /* EPC */ str r1, [fp, #LO_last_count-LO_dynarec_local] subs r10, r10, r1 bpl .E11 .E8: add r6, fp, #LO_reg+256-LO_dynarec_local mov r5, #248 mov r1, #0 .E9: ldr r2, [r6, #-8]! ldr r3, [r6, #4] eor r3, r3, r2, asr #31 subs r3, r3, #1 adc r1, r1, r1 subs r5, r5, #8 bne .E9 ldr r2, [fp, #LO_hi-LO_dynarec_local] ldr r3, [fp, #LO_hi+4-LO_dynarec_local] eors r3, r3, r2, asr #31 ldr r2, [fp, #LO_lo-LO_dynarec_local] ldreq r3, [fp, #LO_lo+4-LO_dynarec_local] eoreq r3, r3, r2, asr #31 subs r3, r3, #1 adc r1, r1, r1 bl get_addr_32 mov pc, r0 .E11: str r0, [fp, #LO_pcaddr-LO_dynarec_local] bl cc_interrupt ldr r0, [fp, #LO_pcaddr-LO_dynarec_local] b .E8 .size jump_eret, .-jump_eret FUNCTION(new_dyna_start): stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr} load_varadr fp, dynarec_local load_varadr_ext r1, out mov r0, #0xa4000000 ldr r4, [r1] add r0, r0, #0x40 bl new_recompile_block ldr r0, [fp, #LO_next_interupt-LO_dynarec_local] ldr r10, [fp, #LO_g_cp0_regs+36-LO_dynarec_local] /* Count */ str r0, [fp, #LO_last_count-LO_dynarec_local] sub r10, r10, r0 mov pc, r4 .size new_dyna_start, .-new_dyna_start FUNCTION(invalidate_addr_r0): stmia fp, {r0, r1, r2, r3, r9, r12, lr} lsr r0, r0, #12 b invalidate_addr_call .size invalidate_addr_r0, .-invalidate_addr_r0 FUNCTION(invalidate_addr_r1): stmia fp, {r0, r1, r2, r3, r9, r12, lr} lsr r0, r1, #12 b invalidate_addr_call .size invalidate_addr_r1, .-invalidate_addr_r1 FUNCTION(invalidate_addr_r2): stmia fp, {r0, r1, r2, r3, r9, r12, lr} lsr r0, r2, #12 b invalidate_addr_call .size invalidate_addr_r2, .-invalidate_addr_r2 FUNCTION(invalidate_addr_r3): stmia fp, {r0, r1, r2, r3, r9, r12, lr} lsr r0, r3, #12 b invalidate_addr_call .size invalidate_addr_r3, .-invalidate_addr_r3 FUNCTION(invalidate_addr_r4): stmia fp, {r0, r1, r2, r3, r9, r12, lr} lsr r0, r4, #12 b invalidate_addr_call .size invalidate_addr_r4, .-invalidate_addr_r4 FUNCTION(invalidate_addr_r5): stmia fp, {r0, r1, r2, r3, r9, r12, lr} lsr r0, r5, #12 b invalidate_addr_call .size invalidate_addr_r5, .-invalidate_addr_r5 FUNCTION(invalidate_addr_r6): stmia fp, {r0, r1, r2, r3, r9, r12, lr} lsr r0, r6, #12 b invalidate_addr_call .size invalidate_addr_r6, .-invalidate_addr_r6 FUNCTION(invalidate_addr_r7): stmia fp, {r0, r1, r2, r3, r9, r12, lr} lsr r0, r7, #12 b invalidate_addr_call .size invalidate_addr_r7, .-invalidate_addr_r7 FUNCTION(invalidate_addr_r8): stmia fp, {r0, r1, r2, r3, r9, r12, lr} lsr r0, r8, #12 b invalidate_addr_call .size invalidate_addr_r8, .-invalidate_addr_r8 FUNCTION(invalidate_addr_r9): stmia fp, {r0, r1, r2, r3, r9, r12, lr} lsr r0, r9, #12 b invalidate_addr_call .size invalidate_addr_r9, .-invalidate_addr_r9 FUNCTION(invalidate_addr_r10): stmia fp, {r0, r1, r2, r3, r9, r12, lr} lsr r0, r10, #12 b invalidate_addr_call .size invalidate_addr_r10, .-invalidate_addr_r10 FUNCTION(invalidate_addr_r12): stmia fp, {r0, r1, r2, r3, r9, r12, lr} lsr r0, r12, #12 .size invalidate_addr_r12, .-invalidate_addr_r12 FUNCTION(invalidate_addr_call): // Not global? bl invalidate_block ldmia fp, {r0, r1, r2, r3, r9, r12, pc} .size invalidate_addr_call, .-invalidate_addr_call FUNCTION(write_rdram_new): ldr r3, [fp, #LO_ram_offset-LO_dynarec_local] ldr r2, [fp, #LO_address-LO_dynarec_local] ldr r0, [fp, #LO_word-LO_dynarec_local] str r0, [r2, r3, lsl #2] b .E12 .size write_rdram_new, .-write_rdram_new FUNCTION(write_rdramb_new): ldr r3, [fp, #LO_ram_offset-LO_dynarec_local] ldr r2, [fp, #LO_address-LO_dynarec_local] ldrb r0, [fp, #LO_cpu_byte-LO_dynarec_local] eor r2, r2, #3 strb r0, [r2, r3, lsl #2] b .E12 .size write_rdramb_new, .-write_rdramb_new FUNCTION(write_rdramh_new): ldr r3, [fp, #LO_ram_offset-LO_dynarec_local] ldr r2, [fp, #LO_address-LO_dynarec_local] ldrh r0, [fp, #LO_hword-LO_dynarec_local] eor r2, r2, #2 lsl r3, r3, #2 strh r0, [r2, r3] b .E12 .size write_rdramh_new, .-write_rdramh_new FUNCTION(write_rdramd_new): ldr r3, [fp, #LO_ram_offset-LO_dynarec_local] ldr r2, [fp, #LO_address-LO_dynarec_local] /* ldrd r0, [fp, #LO_dword-LO_dynarec_local]*/ ldr r0, [fp, #LO_dword-LO_dynarec_local] ldr r1, [fp, #LO_dword+4-LO_dynarec_local] add r3, r2, r3, lsl #2 str r0, [r3, #4] str r1, [r3] b .E12 .size write_rdramd_new, .-write_rdramd_new FUNCTION(do_invalidate): // Not Global? ldr r2, [fp, #LO_address-LO_dynarec_local] .E12: ldr r1, [fp, #LO_invc_ptr-LO_dynarec_local] lsr r0, r2, #12 ldrb r2, [r1, r0] tst r2, r2 beq invalidate_block mov pc, lr .size do_invalidate, .-do_invalidate FUNCTION(read_nomem_new): ldr r2, [fp, #LO_address-LO_dynarec_local] add r12, fp, #LO_memory_map-LO_dynarec_local lsr r0, r2, #12 ldr r12, [r12, r0, lsl #2] mov r1, #8 tst r12, r12 bmi tlb_exception ldr r0, [r2, r12, lsl #2] str r0, [fp, #LO_readmem_dword-LO_dynarec_local] mov pc, lr .size read_nomem_new, .-read_nomem_new FUNCTION(read_nomemb_new): ldr r2, [fp, #LO_address-LO_dynarec_local] add r12, fp, #LO_memory_map-LO_dynarec_local lsr r0, r2, #12 ldr r12, [r12, r0, lsl #2] mov r1, #8 tst r12, r12 bmi tlb_exception eor r2, r2, #3 ldrb r0, [r2, r12, lsl #2] str r0, [fp, #LO_readmem_dword-LO_dynarec_local] mov pc, lr .size read_nomemb_new, .-read_nomemb_new FUNCTION(read_nomemh_new): ldr r2, [fp, #LO_address-LO_dynarec_local] add r12, fp, #LO_memory_map-LO_dynarec_local lsr r0, r2, #12 ldr r12, [r12, r0, lsl #2] mov r1, #8 tst r12, r12 bmi tlb_exception lsl r12, r12, #2 eor r2, r2, #2 ldrh r0, [r2, r12] str r0, [fp, #LO_readmem_dword-LO_dynarec_local] mov pc, lr .size read_nomemh_new, .-read_nomemh_new FUNCTION(read_nomemd_new): ldr r2, [fp, #LO_address-LO_dynarec_local] add r12, fp, #LO_memory_map-LO_dynarec_local lsr r0, r2, #12 ldr r12, [r12, r0, lsl #2] mov r1, #8 tst r12, r12 bmi tlb_exception lsl r12, r12, #2 /* ldrd r0, [r2, r12]*/ add r3, r2, #4 ldr r0, [r2, r12] ldr r1, [r3, r12] str r0, [fp, #LO_readmem_dword+4-LO_dynarec_local] str r1, [fp, #LO_readmem_dword-LO_dynarec_local] mov pc, lr .size read_nomemd_new, .-read_nomemd_new FUNCTION(write_nomem_new): str r3, [fp, #28] str lr, [fp, #32] bl do_invalidate ldr r2, [fp, #LO_address-LO_dynarec_local] add r12, fp, #LO_memory_map-LO_dynarec_local ldr lr, [fp, #32] lsr r0, r2, #12 ldr r3, [fp, #28] ldr r12, [r12, r0, lsl #2] mov r1, #0xc tst r12, #0x40000000 bne tlb_exception ldr r0, [fp, #LO_word-LO_dynarec_local] str r0, [r2, r12, lsl #2] mov pc, lr .size write_nomem_new, .-write_nomem_new FUNCTION(write_nomemb_new): str r3, [fp, #28] str lr, [fp, #32] bl do_invalidate ldr r2, [fp, #LO_address-LO_dynarec_local] add r12, fp, #LO_memory_map-LO_dynarec_local ldr lr, [fp, #32] lsr r0, r2, #12 ldr r3, [fp, #28] ldr r12, [r12, r0, lsl #2] mov r1, #0xc tst r12, #0x40000000 bne tlb_exception eor r2, r2, #3 ldrb r0, [fp, #LO_cpu_byte-LO_dynarec_local] strb r0, [r2, r12, lsl #2] mov pc, lr .size write_nomemb_new, .-write_nomemb_new FUNCTION(write_nomemh_new): str r3, [fp, #28] str lr, [fp, #32] bl do_invalidate ldr r2, [fp, #LO_address-LO_dynarec_local] add r12, fp, #LO_memory_map-LO_dynarec_local ldr lr, [fp, #32] lsr r0, r2, #12 ldr r3, [fp, #28] ldr r12, [r12, r0, lsl #2] mov r1, #0xc lsls r12, #2 bcs tlb_exception eor r2, r2, #2 ldrh r0, [fp, #LO_hword-LO_dynarec_local] strh r0, [r2, r12] mov pc, lr .size write_nomemh_new, .-write_nomemh_new FUNCTION(write_nomemd_new): str r3, [fp, #28] str lr, [fp, #32] bl do_invalidate ldr r2, [fp, #LO_address-LO_dynarec_local] add r12, fp, #LO_memory_map-LO_dynarec_local ldr lr, [fp, #32] lsr r0, r2, #12 ldr r3, [fp, #28] ldr r12, [r12, r0, lsl #2] mov r1, #0xc lsls r12, #2 bcs tlb_exception add r3, r2, #4 ldr r0, [fp, #LO_dword+4-LO_dynarec_local] ldr r1, [fp, #LO_dword-LO_dynarec_local] /* strd r0, [r2, r12]*/ str r0, [r2, r12] str r1, [r3, r12] mov pc, lr .size write_nomemd_new, .-write_nomemd_new FUNCTION(tlb_exception): // Not global? /* r1 = cause */ /* r2 = address */ /* r3 = instr addr/flags */ ldr r4, [fp, #LO_g_cp0_regs+48-LO_dynarec_local] /* Status */ add r5, fp, #LO_memory_map-LO_dynarec_local lsr r6, r3, #12 orr r1, r1, r3, lsl #31 orr r4, r4, #2 ldr r7, [r5, r6, lsl #2] bic r8, r3, #3 str r4, [fp, #LO_g_cp0_regs+48-LO_dynarec_local] /* Status */ mov r6, #0x6000000 str r1, [fp, #LO_g_cp0_regs+52-LO_dynarec_local] /* Cause */ orr r6, r6, #0x22 ldr r0, [r8, r7, lsl #2] add r4, r8, r1, asr #29 add r5, fp, #LO_reg-LO_dynarec_local str r4, [fp, #LO_g_cp0_regs+56-LO_dynarec_local] /* EPC */ mov r7, #0xf8 ldr r8, [fp, #LO_g_cp0_regs+16-LO_dynarec_local] /* Context */ lsl r1, r0, #16 lsr r4, r0, #26 and r7, r7, r0, lsr #18 mvn r9, #0xF000000F sub r2, r2, r1, asr #16 bic r9, r9, #0x0F800000 rors r6, r6, r4 mov r0, #0x80000000 ldrcs r2, [r5, r7] bic r8, r8, r9 tst r3, #2 str r2, [r5, r7] add r4, r2, r1, asr #16 add r6, fp, #LO_reg+4-LO_dynarec_local asr r3, r2, #31 str r4, [fp, #LO_g_cp0_regs+32-LO_dynarec_local] /* BadVAddr */ add r0, r0, #0x180 and r4, r9, r4, lsr #9 strne r3, [r6, r7] orr r8, r8, r4 str r8, [fp, #LO_g_cp0_regs+16-LO_dynarec_local] /* Context */ bl get_addr_ht ldr r1, [fp, #LO_next_interupt-LO_dynarec_local] ldr r10, [fp, #LO_g_cp0_regs+36-LO_dynarec_local] /* Count */ str r1, [fp, #LO_last_count-LO_dynarec_local] sub r10, r10, r1 mov pc, r0 .size tlb_exception, .-tlb_exception FUNCTION(breakpoint): /* Set breakpoint here for debugging */ mov pc, lr .size breakpoint, .-breakpoint /* The following bug-fix implements __clear_cache (missing in Android) */ FUNCTION(__clear_cache_bugfix): push {r7, lr} mov r2, #0 mov r7, #0x2 add r7, r7, #0xf0000 svc 0x00000000 pop {r7, pc} .size __clear_cache_bugfix, .-__clear_cache_bugfix /* End of bug-fix */ #ifndef __MACH__ .section .note.GNU-stack,"",%progbits #endif mupen64plus-core/src/si/si_controller.c000664 001750 001750 00000011023 12655644434 021270 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - si_controller.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "si_controller.h" #include "../api/m64p_types.h" #include "../api/callbacks.h" #include "../main/main.h" #include "../memory/memory.h" #include "../r4300/r4300_core.h" #include "../ri/ri_controller.h" #include static void dma_si_write(struct si_controller* si) { int i; if (si->regs[SI_PIF_ADDR_WR64B_REG] != 0x1FC007C0) { DebugMessage(M64MSG_ERROR, "dma_si_write(): unknown SI use"); return; } for (i = 0; i < PIF_RAM_SIZE; i += 4) *((uint32_t*)(&si->pif.ram[i])) = sl(si->ri->rdram.dram[(si->regs[SI_DRAM_ADDR_REG]+i)/4]); update_pif_write(si); cp0_update_count(); if (g_delay_si) add_interupt_event(SI_INT, /*0x100*/0x900); else { si->regs[SI_STATUS_REG] |= 0x1000; // INTERRUPT signal_rcp_interrupt(si->r4300, MI_INTR_SI); } } static void dma_si_read(struct si_controller* si) { int i; if (si->regs[SI_PIF_ADDR_RD64B_REG] != 0x1FC007C0) { DebugMessage(M64MSG_ERROR, "dma_si_read(): unknown SI use"); return; } update_pif_read(si); for (i = 0; i < PIF_RAM_SIZE; i += 4) si->ri->rdram.dram[(si->regs[SI_DRAM_ADDR_REG]+i)/4] = sl(*(uint32_t*)(&si->pif.ram[i])); cp0_update_count(); if (g_delay_si) add_interupt_event(SI_INT, /*0x100*/0x900); else { si->regs[SI_STATUS_REG] |= 0x1000; // INTERRUPT signal_rcp_interrupt(si->r4300, MI_INTR_SI); } } void connect_si(struct si_controller* si, struct r4300_core* r4300, struct ri_controller *ri) { si->r4300 = r4300; si->ri = ri; } void init_si(struct si_controller* si) { memset(si->regs, 0, SI_REGS_COUNT*sizeof(uint32_t)); init_pif(&si->pif); } int read_si_regs(void* opaque, uint32_t address, uint32_t* value) { struct si_controller* si = (struct si_controller*)opaque; uint32_t reg = SI_REG(address); *value = si->regs[reg]; return 0; } int write_si_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask) { struct si_controller* si = (struct si_controller*)opaque; uint32_t reg = SI_REG(address); switch (reg) { case SI_DRAM_ADDR_REG: si->regs[SI_DRAM_ADDR_REG] = MASKED_WRITE(&si->regs[SI_DRAM_ADDR_REG], value, mask); break; case SI_PIF_ADDR_RD64B_REG: si->regs[SI_PIF_ADDR_RD64B_REG] = MASKED_WRITE(&si->regs[SI_PIF_ADDR_RD64B_REG], value, mask); dma_si_read(si); break; case SI_PIF_ADDR_WR64B_REG: si->regs[SI_PIF_ADDR_WR64B_REG] = MASKED_WRITE(&si->regs[SI_PIF_ADDR_WR64B_REG], value, mask); dma_si_write(si); break; case SI_STATUS_REG: si->regs[SI_STATUS_REG] &= ~0x1000; clear_rcp_interrupt(si->r4300, MI_INTR_SI); break; } return 0; } void si_end_of_dma_event(struct si_controller* si) { main_check_inputs(); si->pif.ram[0x3f] = 0x0; /* trigger SI interrupt */ si->regs[SI_STATUS_REG] |= 0x1000; raise_rcp_interrupt(si->r4300, MI_INTR_SI); } mupen64plus-video-gliden64/src/GLideNHQ/TxUtil.h000664 001750 001750 00000004346 12655644434 022372 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __TXUTIL_H__ #define __TXUTIL_H__ /* maximum number of CPU cores allowed */ #define MAX_NUMCORE 8 #include "TxInternal.h" /* extension for cache files */ #define TEXCACHE_EXT wst("htc") class TxUtil { private: uint32 RiceCRC32(const uint8* src, int width, int height, int size, int rowStride); boolean RiceCRC32_CI4(const uint8* src, int width, int height, int rowStride, uint32* crc32, uint32* cimax); boolean RiceCRC32_CI8(const uint8* src, int width, int height, int rowStride, uint32* crc32, uint32* cimax); public: TxUtil() { } ~TxUtil() { } int sizeofTx(int width, int height, uint16 format); uint32 checksumTx(uint8 *data, int width, int height, uint16 format); #if 0 /* unused */ uint32 chkAlpha(uint32* src, int width, int height); #endif uint32 checksum(uint8 *src, int width, int height, int size, int rowStride); uint64 checksum64(uint8 *src, int width, int height, int size, int rowStride, uint8 *palette); int getNumberofProcessors(); }; class TxMemBuf { private: uint8 *_tex[2]; uint32 _size[2]; TxMemBuf(); public: static TxMemBuf* getInstance() { static TxMemBuf txMemBuf; return &txMemBuf; } ~TxMemBuf(); boolean init(int maxwidth, int maxheight); void shutdown(void); uint8 *get(unsigned int num); uint32 size_of(unsigned int num); }; void setTextureFormat(uint16 internalFormat, GHQTexInfo * info); #endif /* __TXUTIL_H__ */ mupen64plus-video-gliden64/src/Debug.h000664 001750 001750 00000000176 12655644434 020631 0ustar00sergiosergio000000 000000 #ifndef DEBUG_H #define DEBUG_H // TODO Debug log. #define DebugMsg(A, ...) #define DebugRSPState(A, ...) #endif // DEBUG_H libretro-common/glsym/glgen.py000755 001750 001750 00000012000 12655644434 017622 0ustar00sergiosergio000000 000000 #!/usr/bin/env python3 """ License statement applies to this file (glgen.py) only. """ """ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ import sys import os import re banned_ext = [ 'AMD', 'APPLE', 'EXT', 'NV', 'NVX', 'ATI', '3DLABS', 'SUN', 'SGI', 'SGIX', 'SGIS', 'INTEL', '3DFX', 'IBM', 'MESA', 'GREMEDY', 'OML', 'PGI', 'I3D', 'INGL', 'MTX', 'QCOM', 'IMG', 'ANGLE', 'SUNX', 'INGR' ] def noext(sym): for ext in banned_ext: if sym.endswith(ext): return False return True def find_gl_symbols(lines): typedefs = [] syms = [] for line in lines: m = re.search(r'^typedef.+PFN(\S+)PROC.+$', line) g = re.search(r'^.+(gl\S+)\W*\(.+\).*$', line) if m and noext(m.group(1)): typedefs.append(m.group(0).replace('PFN', 'RGLSYM').replace('GLDEBUGPROC', 'RGLGENGLDEBUGPROC')) if g and noext(g.group(1)): syms.append(g.group(1)) return (typedefs, syms) def generate_defines(gl_syms): res = [] for line in gl_syms: res.append('#define {} __rglgen_{}'.format(line, line)) return res def generate_declarations(gl_syms): return ['RGLSYM' + x.upper() + 'PROC ' + '__rglgen_' + x + ';' for x in gl_syms] def generate_macros(gl_syms): return [' SYM(' + x.replace('gl', '') + '),' for x in gl_syms] def dump(f, lines): f.write('\n'.join(lines)) f.write('\n\n') if __name__ == '__main__': if len(sys.argv) > 4: for banned in sys.argv[4:]: banned_ext.append(banned) with open(sys.argv[1], 'r') as f: lines = f.readlines() typedefs, syms = find_gl_symbols(lines) overrides = generate_defines(syms) declarations = generate_declarations(syms) externs = ['extern ' + x for x in declarations] macros = generate_macros(syms) with open(sys.argv[2], 'w') as f: f.write('#ifndef RGLGEN_DECL_H__\n') f.write('#define RGLGEN_DECL_H__\n') f.write('#ifdef __cplusplus\n') f.write('extern "C" {\n') f.write('#endif\n') f.write('#ifdef GL_APIENTRY\n') f.write('typedef void (GL_APIENTRY *RGLGENGLDEBUGPROC)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*);\n') f.write('typedef void (GL_APIENTRY *RGLGENGLDEBUGPROCKHR)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*);\n') f.write('#else\n') f.write('#ifndef APIENTRY\n') f.write('#define APIENTRY\n') f.write('#endif\n') f.write('#ifndef APIENTRYP\n') f.write('#define APIENTRYP APIENTRY *\n') f.write('#endif\n') f.write('typedef void (APIENTRY *RGLGENGLDEBUGPROCARB)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*);\n') f.write('typedef void (APIENTRY *RGLGENGLDEBUGPROC)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*);\n') f.write('#endif\n') f.write('#ifndef GL_OES_EGL_image\n') f.write('typedef void *GLeglImageOES;\n') f.write('#endif\n') f.write('#if !defined(GL_OES_fixed_point) && !defined(HAVE_OPENGLES2)\n') f.write('typedef GLint GLfixed;\n') f.write('#endif\n') f.write('#if defined(OSX) && !defined(MAC_OS_X_VERSION_10_7)\n') f.write('typedef long long int GLint64;\n') f.write('typedef unsigned long long int GLuint64;\n') f.write('typedef unsigned long long int GLuint64EXT;\n') f.write('typedef struct __GLsync *GLsync;\n') f.write('#endif\n') dump(f, typedefs) dump(f, overrides) dump(f, externs) f.write('struct rglgen_sym_map { const char *sym; void *ptr; };\n') f.write('extern const struct rglgen_sym_map rglgen_symbol_map[];\n') f.write('#ifdef __cplusplus\n') f.write('}\n') f.write('#endif\n') f.write('#endif\n') with open(sys.argv[3], 'w') as f: f.write('#include "glsym.h"\n') f.write('#include \n') f.write('#define SYM(x) { "gl" #x, &(gl##x) }\n') f.write('const struct rglgen_sym_map rglgen_symbol_map[] = {\n') dump(f, macros) f.write(' { NULL, NULL },\n') f.write('};\n') dump(f, declarations) gles2rice/src/ConvertImage.h000664 001750 001750 00000022375 12655644434 017132 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CONVERTIMAGE_H__ #define __CONVERTIMAGE_H__ #include "typedefs.h" #include "Texture.h" #include "TextureManager.h" static const uint8_t OneToEight[2] = { 0x00, // 0 -> 00 00 00 00 0xff // 1 -> 11 11 11 11 }; static const uint8_t OneToFour[2] = { 0x00, // 0 -> 00 00 0x0f // 1 -> 11 11 }; static const uint8_t TwoToEight[4] = { 0x00, // 00 -> 00 00 00 00 0x55, // 01 -> 01 01 01 01 0xaa, // 10 -> 10 10 10 10 0xff // 11 -> 11 11 11 11 }; static const uint8_t TwoToFour[4] = { 0x0, // 00 -> 00 00 0x5, // 01 -> 01 01 0xa, // 10 -> 10 10 0xf // 11 -> 11 11 }; static const uint8_t ThreeToEight[8] = { 0x00, // 000 -> 00 00 00 00 0x24, // 001 -> 00 10 01 00 0x49, // 010 -> 01 00 10 01 0x6d, // 011 -> 01 10 11 01 0x92, // 100 -> 10 01 00 10 0xb6, // 101 -> 10 11 01 10 0xdb, // 110 -> 11 01 10 11 0xff // 111 -> 11 11 11 11 }; static const uint8_t ThreeToFour[8] = { 0x0, // 000 -> 00 00 00 00 0x2, // 001 -> 00 10 01 00 0x4, // 010 -> 01 00 10 01 0x6, // 011 -> 01 10 11 01 0x9, // 100 -> 10 01 00 10 0xb, // 101 -> 10 11 01 10 0xd, // 110 -> 11 01 10 11 0xf // 111 -> 11 11 11 11 }; static const uint8_t FourToEight[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; static const uint16_t FourToSixteen[16] = { 0x0000, 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888, 0x9999, 0xaaaa, 0xbbbb, 0xcccc, 0xdddd, 0xeeee, 0xffff }; static const uint8_t FiveToEight[32] = { 0x00, // 00000 -> 00000000 0x08, // 00001 -> 00001000 0x10, // 00010 -> 00010000 0x18, // 00011 -> 00011000 0x21, // 00100 -> 00100001 0x29, // 00101 -> 00101001 0x31, // 00110 -> 00110001 0x39, // 00111 -> 00111001 0x42, // 01000 -> 01000010 0x4a, // 01001 -> 01001010 0x52, // 01010 -> 01010010 0x5a, // 01011 -> 01011010 0x63, // 01100 -> 01100011 0x6b, // 01101 -> 01101011 0x73, // 01110 -> 01110011 0x7b, // 01111 -> 01111011 0x84, // 10000 -> 10000100 0x8c, // 10001 -> 10001100 0x94, // 10010 -> 10010100 0x9c, // 10011 -> 10011100 0xa5, // 10100 -> 10100101 0xad, // 10101 -> 10101101 0xb5, // 10110 -> 10110101 0xbd, // 10111 -> 10111101 0xc6, // 11000 -> 11000110 0xce, // 11001 -> 11001110 0xd6, // 11010 -> 11010110 0xde, // 11011 -> 11011110 0xe7, // 11100 -> 11100111 0xef, // 11101 -> 11101111 0xf7, // 11110 -> 11110111 0xff // 11111 -> 11111111 }; #define RGBA5551_RedMask (0xF800) #define RGBA5551_GreenMask (0x07C0) #define RGBA5551_BlueMask (0x003E) #define RGBA5551_AlphaMask (0x0001) #define RGBA5551_RedShift 11 #define RGBA5551_GreenShift 6 #define RGBA5551_BlueShift 1 #define RGBA5551_AlphaShift 0 #define RGBA565_RedMask (0xF800) #define RGBA565_GreenMask (0x07E0) #define RGBA565_BlueMask (0x001F) #define RGBA565_RedShift 11 #define RGBA565_GreenShift 5 #define RGBA565_BlueShift 0 inline uint16_t ConvertRGBTo555(uint8_t red, uint8_t grn, uint8_t blu) { return (uint16_t)(((uint16_t)(red >> 3) << RGBA5551_RedShift) | ((uint16_t)(grn >> 3) << RGBA5551_GreenShift) | ((uint16_t)(blu >> 3) << RGBA5551_BlueShift) | ((uint16_t)(1) << RGBA5551_AlphaShift)); } inline uint16_t ConvertRGBTo565(uint8_t red, uint8_t grn, uint8_t blu) { return (uint16_t)(((uint16_t)(red >> 3) << RGBA565_RedShift) | ((uint16_t)(grn >> 2) << RGBA565_GreenShift) | ((uint16_t)(blu >> 3) << RGBA565_BlueShift)); } inline uint16_t Convert555To565(uint16_t w555) { // Probably a faster method by fudging the low bits.. uint8_t red = FiveToEight[(w555&RGBA5551_RedMask) >> RGBA5551_RedShift]; uint8_t grn = FiveToEight[(w555&RGBA5551_GreenMask)>> RGBA5551_GreenShift]; uint8_t blu = FiveToEight[(w555&RGBA5551_BlueMask) >> RGBA5551_BlueShift]; return ConvertRGBTo565(red, grn, blu); } #define R4G4B4A4_MAKE(r,g,b,a) ((uint16_t)(((a) << 12) | ((r)<< 8) | ((g)<<4) | (b))) inline uint32_t Convert555ToRGBA(uint16_t w555) { uint32_t dwRed = FiveToEight[(w555&RGBA5551_RedMask) >> RGBA5551_RedShift]; uint32_t dwGreen = FiveToEight[(w555&RGBA5551_GreenMask)>> RGBA5551_GreenShift]; uint32_t dwBlue = FiveToEight[(w555&RGBA5551_BlueMask) >> RGBA5551_BlueShift]; uint32_t dwAlpha = (w555&RGBA5551_AlphaMask) ? 0xFF : 0x00; return COLOR_RGBA(dwRed, dwGreen, dwBlue, dwAlpha); } inline uint16_t Convert555ToR4G4B4A4(uint16_t w555) { uint8_t dwRed = ((w555&RGBA5551_RedMask) >> RGBA5551_RedShift)>>1; uint8_t dwGreen = ((w555&RGBA5551_GreenMask)>> RGBA5551_GreenShift)>>1; uint8_t dwBlue = ((w555&RGBA5551_BlueMask) >> RGBA5551_BlueShift)>>1; uint8_t dwAlpha = (w555&RGBA5551_AlphaMask) ? 0xF : 0x0; return R4G4B4A4_MAKE(dwRed, dwGreen, dwBlue, dwAlpha); } inline uint32_t ConvertIA4ToRGBA(uint8_t IA4) { uint32_t I = ThreeToEight[(IA4 & 0x0F) >> 1]; uint32_t A = OneToEight[(IA4 & 0x01)]; return COLOR_RGBA(I, I, I, A); } inline uint16_t ConvertIA4ToR4G4B4A4(uint8_t IA4) { uint32_t I = ThreeToFour[(IA4 & 0x0F) >> 1]; uint32_t A = OneToFour[(IA4 & 0x01)]; return R4G4B4A4_MAKE(I, I, I, A); } inline uint32_t ConvertI4ToRGBA(uint8_t I4) { uint32_t I = FourToEight[I4 & 0x0F]; return COLOR_RGBA(I, I, I, I); } inline uint16_t ConvertI4ToR4G4B4A4(uint8_t I4) { return FourToSixteen[I4 & 0x0F]; } inline uint32_t ConvertIA16ToRGBA(uint16_t wIA) { uint32_t dwIntensity = (wIA >> 8) & 0xFF; uint32_t dwAlpha = (wIA ) & 0xFF; return COLOR_RGBA(dwIntensity, dwIntensity, dwIntensity, dwAlpha); } inline uint16_t ConvertIA16ToR4G4B4A4(uint16_t wIA) { uint16_t dwIntensity = (wIA >> 12) & 0x0F; uint16_t dwAlpha = (wIA >> 4) & 0x0F; return R4G4B4A4_MAKE(dwIntensity, dwIntensity, dwIntensity, dwAlpha); } extern int g_convk0,g_convk1,g_convk2,g_convk3,g_convk4,g_convk5; extern float g_convc0,g_convc1,g_convc2,g_convc3,g_convc4,g_convc5; uint32_t ConvertYUV16ToR8G8B8(int Y, int U, int V); uint16_t ConvertYUV16ToR4G4B4(int Y, int U, int V); typedef void ( * ConvertFunction )( CTexture * p_texture, const TxtrInfo & ti ); void ConvertRGBA16(CTexture *pTexture, const TxtrInfo &tinfo); void ConvertRGBA32(CTexture *pTexture, const TxtrInfo &tinfo); void ConvertIA4(CTexture *pTexture, const TxtrInfo &tinfo); void ConvertIA8(CTexture *pTexture, const TxtrInfo &tinfo); void ConvertIA16(CTexture *pTexture, const TxtrInfo &tinfo); void ConvertI4(CTexture *pTexture, const TxtrInfo &tinfo); void ConvertI8(CTexture *pTexture, const TxtrInfo &tinfo); void ConvertCI4( CTexture *pTexture, const TxtrInfo & ti ); void ConvertCI8( CTexture *pTexture, const TxtrInfo & ti ); void ConvertCI4_RGBA16(CTexture *pTexture, const TxtrInfo &tinfo); void ConvertCI4_IA16(CTexture *pTexture, const TxtrInfo &tinfo); void ConvertCI8_RGBA16(CTexture *pTexture, const TxtrInfo &tinfo); void ConvertCI8_IA16(CTexture *pTexture, const TxtrInfo &tinfo); void ConvertYUV(CTexture *pTexture, const TxtrInfo &tinfo); // 16 a4r4g4b4 void ConvertRGBA16_16(CTexture *pTexture, const TxtrInfo &tinfo); void ConvertRGBA32_16(CTexture *pTexture, const TxtrInfo &tinfo); void ConvertIA4_16(CTexture *pTexture, const TxtrInfo &tinfo); void ConvertIA8_16(CTexture *pTexture, const TxtrInfo &tinfo); void ConvertIA16_16(CTexture *pTexture, const TxtrInfo &tinfo); void ConvertI4_16(CTexture *pTexture, const TxtrInfo &tinfo); void ConvertI8_16(CTexture *pTexture, const TxtrInfo &tinfo); void ConvertCI4_16( CTexture *pTexture, const TxtrInfo & ti ); void ConvertCI8_16( CTexture *pTexture, const TxtrInfo & ti ); void ConvertCI4_RGBA16_16(CTexture *pTexture, const TxtrInfo &tinfo); void ConvertCI4_IA16_16(CTexture *pTexture, const TxtrInfo &tinfo); void ConvertCI8_RGBA16_16(CTexture *pTexture, const TxtrInfo &tinfo); void ConvertCI8_IA16_16(CTexture *pTexture, const TxtrInfo &tinfo); void ConvertYUV_16(CTexture *pTexture, const TxtrInfo &tinfo); void Convert4b(CTexture *pTexture, const TxtrInfo &tinfo); void Convert8b(CTexture *pTexture, const TxtrInfo &tinfo); void Convert16b(CTexture *pTexture, const TxtrInfo &tinfo); void Convert4b_16(CTexture *pTexture, const TxtrInfo &tinfo); void Convert8b_16(CTexture *pTexture, const TxtrInfo &tinfo); void Convert16b_16(CTexture *pTexture, const TxtrInfo &tinfo); #endif mupen64plus-rsp-hle/src/common.h000664 001750 001750 00000003341 12655644434 017722 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-rsp-hle - common.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef COMMON_H #define COMMON_H /* macro for unused variable warning suppression */ #ifdef __GNUC__ # define UNUSED(x) UNUSED_ ## x __attribute__((__unused__)) #else # define UNUSED(x) UNUSED_ ## x #endif #endif libretro-common/libco/x86.c000664 001750 001750 00000005547 12655644434 016723 0ustar00sergiosergio000000 000000 /* libco.x86 (2009-10-12) author: byuu license: public domain */ #define LIBCO_C #include #include #include #ifdef __cplusplus extern "C" { #endif #if defined(_MSC_VER) #define fastcall __fastcall #elif defined(__GNUC__) #define fastcall __attribute__((fastcall)) #else #error "libco: please define fastcall macro" #endif static thread_local long co_active_buffer[64]; static thread_local cothread_t co_active_handle = 0; static void (fastcall *co_swap)(cothread_t, cothread_t) = 0; //ABI: fastcall static unsigned char co_swap_function[] = { 0x89, 0x22, /* mov [edx],esp */ 0x8b, 0x21, /* mov esp,[ecx] */ 0x58, /* pop eax */ 0x89, 0x6a, 0x04, /* mov [edx+0x04],ebp */ 0x89, 0x72, 0x08, /* mov [edx+0x08],esi */ 0x89, 0x7a, 0x0c, /* mov [edx+0x0c],edi */ 0x89, 0x5a, 0x10, /* mov [edx+0x10],ebx */ 0x8b, 0x69, 0x04, /* mov ebp,[ecx+0x04] */ 0x8b, 0x71, 0x08, /* mov esi,[ecx+0x08] */ 0x8b, 0x79, 0x0c, /* mov edi,[ecx+0x0c] */ 0x8b, 0x59, 0x10, /* mov ebx,[ecx+0x10] */ 0xff, 0xe0, /* jmp eax */ }; #ifdef _WIN32 #include void co_init(void) { DWORD old_privileges; VirtualProtect(co_swap_function, sizeof co_swap_function, PAGE_EXECUTE_READWRITE, &old_privileges); } #else #include #include void co_init(void) { unsigned long addr = (unsigned long)co_swap_function; unsigned long base = addr - (addr % sysconf(_SC_PAGESIZE)); unsigned long size = (addr - base) + sizeof co_swap_function; mprotect((void*)base, size, PROT_READ | PROT_WRITE | PROT_EXEC); } #endif static void crash(void) { assert(0); /* called only if cothread_t entrypoint returns */ } cothread_t co_active(void) { if(!co_active_handle) co_active_handle = &co_active_buffer; return co_active_handle; } cothread_t co_create(unsigned int size, void (*entrypoint)(void)) { cothread_t handle; if(!co_swap) { co_init(); co_swap = (void (fastcall*)(cothread_t, cothread_t))co_swap_function; } if(!co_active_handle) co_active_handle = &co_active_buffer; size += 256; /* allocate additional space for storage */ size &= ~15; /* align stack to 16-byte boundary */ if((handle = (cothread_t)malloc(size))) { long *p = (long*)((char*)handle + size); /* seek to top of stack */ *--p = (long)crash; /* crash if entrypoint returns */ *--p = (long)entrypoint; /* start of function */ *(long*)handle = (long)p; /* stack pointer */ } return handle; } void co_delete(cothread_t handle) { free(handle); } void co_switch(cothread_t handle) { register cothread_t co_previous_handle = co_active_handle; co_swap(co_active_handle = handle, co_previous_handle); } #ifdef __cplusplus } #endif glide2gl/src/Glide64/Gfx_1.3.h000664 001750 001750 00000012633 12655644434 016660 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** /********************************************************************************** Common gfx plugin spec, version #1.3 maintained by zilmar (zilmar@emulation64.com) All questions or suggestions should go through the mailing list. http://www.egroups.com/group/Plugin64-Dev *********************************************************************************** Notes: ------ Setting the approprate bits in the MI_INTR_REG and calling CheckInterrupts which are both passed to the DLL in InitiateGFX will generate an Interrupt from with in the plugin. The Setting of the RSP flags and generating an SP interrupt should not be done in the plugin **********************************************************************************/ #ifndef _GFX_H_INCLUDED__ #define _GFX_H_INCLUDED__ #include #include #include "m64p.h" #ifndef max #define max(a, b) ((a) > (b) ? (a) : (b)) #endif #ifndef min #define min(a, b) ((a) < (b) ? (a) : (b)) #endif #ifdef MSB_FIRST #define BYTE_ADDR_XOR 0 #define WORD_ADDR_XOR 0 #define BYTE4_XOR_BE(a) (a) #else #define BYTE_ADDR_XOR 3 #define WORD_ADDR_XOR 1 #define BYTE4_XOR_BE(a) ((a) ^ 3) #endif #include #include #include #include #include #include "../Glitch64/glide.h" #include "GlideExtensions.h" #include "rdp.h" #define _ENDUSER_RELEASE_ #ifndef _ENDUSER_RELEASE_ #define BRIGHT_RED // Keep enabled, option in dialog #endif #define COLORED_DEBUGGER // ;) pretty colors // rdram mask at 0x400000 bytes (bah, not right for majora's mask) //#define BMASK 0x7FFFFF extern uint32_t BMASK; extern uint32_t update_screen_count; extern uint32_t resolutions[0x18][2]; #ifdef LOGGING #define LOG(...) WriteLog(M64MSG_INFO, __VA_ARGS__) #define VLOG(...) WriteLog(M64MSG_VERBOSE, __VA_ARGS__) #define WARNLOG(...) WriteLog(M64MSG_WARNING, __VA_ARGS__) #define ERRLOG(...) WriteLog(M64MSG_ERROR, __VA_ARGS__) #else #define LOG(...) #define VLOG(...) #define WARNLOG(...) #define ERRLOG(...) #endif #define OPEN_RDP_LOG() #define CLOSE_RDP_LOG() #define LRDP(x) #define LRDP(x) #define FRDP(x, ...) #ifdef RDP_ERROR_LOG /* FIXME */ #define RDP_E(x) #else #define OPEN_RDP_E_LOG() #define CLOSE_RDP_E_LOG() #define RDP_E(x) #define FRDP_E(x, ...) #endif extern int romopen; extern int debugging; extern int exception; extern GFX_INFO gfx_info; int glide64InitGfx(void); void ReleaseGfx(void); // The highest 8 bits are the segment # (1-16), and the lower 24 bits are the offset to // add to it. #define RSP_SegmentToPhysical(so) (((rdp.segment[((so) >> 24) & 0x0f] + ((so) & BMASK)) & BMASK) & 0x00ffffff) /* Plugin types */ #define PLUGIN_TYPE_GFX 2 /***** Structures *****/ typedef struct { uint16_t Version; /* Set to 0x0103 */ uint16_t Type; /* Set to PLUGIN_TYPE_GFX */ char Name[100]; /* Name of the DLL */ /* If DLL supports memory these memory options then set them to TRUE or FALSE if it does not support it */ int NormalMemory; /* a normal uint8_t array */ int MemoryBswaped; /* a normal uint8_t array where the memory has been pre bswap on a dword (32 bits) boundry */ } PLUGIN_INFO; extern bool no_dlist; #ifndef GR_STIPPLE_DISABLE #define GR_STIPPLE_DISABLE 0x0 #define GR_STIPPLE_PATTERN 0x1 #define GR_STIPPLE_ROTATE 0x2 #endif int GetTexAddrUMA(int tmu, int texsize); extern void ReadSettings(void); extern void ReadSpecialSettings(const char * name); extern void (*_gSPVertex)(uint32_t addr, uint32_t n, uint32_t v0); #endif //_GFX_H_INCLUDED__ gles2n64/src/F3DWRUS.h000664 001750 001750 00000000255 12655644434 015322 0ustar00sergiosergio000000 000000 #ifndef F3DWRUS_H #define F3DWRUS_H #ifdef __cplusplus extern "C" { #endif #define F3DWRUS_TRI2 0xB1 void F3DWRUS_Init(void); #ifdef __cplusplus } #endif #endif mupen64plus-core/doc/module-api-versions.txt000664 001750 001750 00000025153 12655644434 022265 0ustar00sergiosergio000000 000000 Mupen64Plus API versions --------------------------------------------------------------------------------------------------- Goal: The Mupen64Plus API versioning scheme was invented to give a more friendly and less confusing experience for users as the various components evolve over time. There are 6 basic components to the Mupen64Plus system, which may be independently built and installed: 1. The Front-end UI application 2. The Core emulator library 3. The Video plugin 4. The Audio plugin 5. The Input plugin 6. The RSP plugin These components interact with each other in several different ways. The design goal of the versioning scheme is to gracefully handle all situations in which two components support different versions of their common API (due to one component being newer than the other). In particular, each pair of components sharing a common API must discover whether or not they are compatible with each other. They must make this determination early enough in the startup process to inform the user of an incompatibility and gracefully exit the software if necessary without crashing. There are 2 different decisions that pertain to the compatibility determination: 1. Major API version. The various API version numbers are 32-bit. The major version number is stored in the upper 16 bits, and the minor version number is in the lower 16 bits. If two components have different major API version numbers, then they are definitely incompatible. 2. Minor API version. If two components with a common API have different minor version numbers, then the newer component may decide whether or not it can interact with the older component based upon the older component's version number. The newer component may optionally disable new features and still retain backwards compatibility, or it may refuse to operate with the older component. This decision is left to the component author when new features are added. --------------------------------------------------------------------------------------------------- Basic Design: In mupen64plus-core/src/plugin/plugin.h, the following macros are defined: #define RSP_API_MAJOR_VERSION 0x20000 #define GFX_API_MAJOR_VERSION 0x20000 #define AUDIO_API_MAJOR_VERSION 0x20000 #define INPUT_API_MAJOR_VERSION 0x20000 In mupen64plus-core/src/main/version.h, the following macros are defined: #define FRONTEND_API_VERSION 0x020000 #define CONFIG_API_VERSION 0x020000 #define DEBUG_API_VERSION 0x020000 #define VIDEXT_API_VERSION 0x020000 1. When the front-end application calls the CoreStartup(), it passes it's Core<-->Front-end API version to the core. If the API major version numbers for the core and front-end don't match, the core return from this function with a failure code of M64ERR_INCOMPATIBLE. 2. The Console-UI front-end also checks for API compatibility, during the AttachCoreLib() function call. It is not strictly necessary for a front-end application to verify the API compatibility with the core, since the core will also check during CoreStartup(). However, by doing so, an updated front-end may detect a core library using a newer (but backwards-compatible) API, and enable some extra features as a result of the expanded API. 3. At the time each plugin is attached to the core (during CoreAttachPlugin function call), the core checks the version number of the plugin API by calling the PluginGetVersion function. If the major version number of the plugin's reported API (APIVersion & 0xffff0000) does not match the corresponding version number for that plugin type in the core (defined in plugin.h), then the plugin is incompatible and cannot be attached to the core. Currently the plugins have no way to request the major version number required for a particular plugin type in the core library. 4. The emulator core exports several different API groups which may be used by the front-end and plugin modules. Currently, these groups are: Front-end, Config, Debug, and Video Extension. A front-end application or any plugin may call the CoreGetAPIVersions() function to retrieve the API version numbers for these groups. Any plugin or front-end which can use any updated (not present in the original "2.0" API) functions in one of these groups should call the core's CoreGetAPIVersions() function (during PluginStartup for a plugin or at core attach time for a front-end) to check the version # of the API supported by the core, and react accordingly. 5. All front-ends and plugins should verify API version compatibility for the Config API. --------------------------------------------------------------------------------------------------- Handling Future Changes: 1. New feature added to a plugin library If the feature is backwards-compatible with older cores, then plugin API minor version will be bumped. Otherwise, major version number will be bumped. If change is backwards-compatible, then newest core can test the plugin's API version and only enable the feature if present. 2. New feature added to Core<-->Front-end API Typically this will happen when a new function or a new feature of an existing function is added to the core. If the older front-ends will still be compatible with newer cores, then the minor version number of the front-end API will be bumped. Otherwise the major version number will be bumped. A newer front-end can check the version of the API supported by the core and choose whether to retain backwards-compatibility with older cores or refuse to interoperate. 3. New feature added to Core Config API If older plugins can still use the Core Config API with the new feature, then Config API minor version will be bumped. Otherwise, major version number will be bumped. Newer plugins should check the Core's Config API version and maintain backwards compatibility with older cores if possible. 4. New feature added to Core Debug API If older front-ends can still use the Core Debug API with the new feature, then Debug API minor version number will be bumped. Otherwise, major version number will be bumped. Newer front-end applications should check the Core's Debug API version and maintain backwards compatibility with older cores if possible. 5. New feature added to Video Extension API This is the most complicated interface, because it involves 3 components: the video plugin, the core, and the front-end application. If older video plugins can still use the newer Video Extension API with the core, *and* newer front-end applications can work with older cores, then the Video Extension API minor version number will be bumped. Otherwise, the major version number will be bumped. Newer video plugins can check the Core's Video Extension API version and maintain backwards compatibility with older cores if possible, otherwise they can refuse and give a compatibility error. Front-end applications (such as the default console-ui) which do not hook into the Video Extension do not need to check the Core's Video Extension API version. However, front-end applications which do hook into the Video Extension must check the API version. If the Core and Front-end have different API major version numbers, then they are incompatible. Also if the Core has a *newer* minor version than the front-end, then they are incompatible. This is a unique restriction, and it must be checked and verified by the front-end; the Core has no way to check this. --------------------------------------------------------------------------------------------------- Changelog: - Version 2.0.0 is the base for all APIs - FRONTEND_API_VERSION version 2.0.1: - added "m64p_command" type "M64CMD_CORE_STATE_SET", handled by CoreDoCommand() - added "m64p_core_param" type "M64CORE_SPEED_LIMITER", handled by "M64CMD_CORE_STATE_QUERY" and "M64CMD_CORE_STATE_SET" commands - FRONTEND_API_VERSION version 2.0.2: - added "m64p_command" types: - M64CMD_GET_SCREEN_WIDTH - M64CMD_GET_SCREEN_HEIGHT - M64CMD_READ_SCREEN - M64CMD_VOLUME_UP - M64CMD_VOLUME_DOWN - M64CMD_VOLUME_GET_LEVEL - M64CMD_VOLUME_SET_LEVEL - M64CMD_VOLUME_MUTE - M64CMD_RESET - M64CMD_ADVANCE_FRAME - extend command M64CMD_STATE_SAVE to support saving uncompressed PJ64 savestate files as well as zip compressed - FRONTEND_API_VERSION version 2.1.0: - removed "m64p_command" types: - M64CMD_GET_SCREEN_WIDTH - M64CMD_GET_SCREEN_HEIGHT - M64CMD_VOLUME_UP - M64CMD_VOLUME_DOWN - M64CMD_VOLUME_GET_LEVEL - M64CMD_VOLUME_SET_LEVEL - M64CMD_VOLUME_MUTE - added new "m64p_core_param" types: - M64CORE_VIDEO_SIZE - M64CORE_AUDIO_VOLUME - M64CORE_AUDIO_MUTE - M64CORE_INPUT_GAMESHARK - M64CORE_STATE_LOADCOMPLETE - M64CORE_STATE_SAVECOMPLETE - FRONTEND_API_VERSION version 2.1.1: - Core command M64CMD_CORE_STATE_SET will now accept M64CORE_VIDEO_SIZE parameter - will call the video plugin function ResizeVideoOutput() - CONFIG_API_VERSION version 2.1.0: - add new function "ConfigSaveSection()" to save only a single config section to disk - CONFIG_API_VERSION version 2.2.0: - add new function "ConfigHasUnsavedChanges()" to determine if a given Section (or all sections) of the Mupen64Plus Core configuration file has been modified since it was last saved or loaded. - add new function "ConfigRevertChanges()" to revert changes previously made to one section of the configuration file, so that it will match with the configuration at the last time that it was loaded from or saved to disk. - VIDEO_API_VERSION version 2.1.0: - video render callback function now takes a boolean (int) parameter, which specifies whether the video frame has been re-drawn since the last time the render callback was called. This allows us to take screenshots without the On-Screen-Display text - VIDEO_API_VERSION version 2.2.0: - add (optional) ResizeVideoOutput function in video plugin. If this function is not present in video plugin, then resizing the output video window will not work. - VIDEXT_API_VERSION version 3.0.0: - add VidExt_ResizeWindow() function in video extension. This function is called by the video plugin to notify the window manager (SDL if no video extension is registered by the front-end) that the OpenGL render window size should change. - add m64p_video_flags parameter to the VidExt_SetVideoMode() function. Currently the flags are only used to notify the window manager that resizing is supported by the video plugin, and it should create a resizable window if possible. This may be extended in the future to support other features. mupen64plus-core/src/ri/ri_controller.h000664 001750 001750 00000004352 12655644434 021302 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - ri_controller.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_RI_RI_CONTROLLER_H #define M64P_RI_RI_CONTROLLER_H #include #include "rdram.h" #ifndef RI_REG #define RI_REG(a) ((a & 0xffff) >> 2) #endif enum ri_registers { RI_MODE_REG, RI_CONFIG_REG, RI_CURRENT_LOAD_REG, RI_SELECT_REG, RI_REFRESH_REG, RI_LATENCY_REG, RI_ERROR_REG, RI_WERROR_REG, RI_REGS_COUNT }; struct ri_controller { uint32_t regs[RI_REGS_COUNT]; struct rdram rdram; }; void connect_ri(struct ri_controller* ri, uint32_t* dram, size_t dram_size); void init_ri(struct ri_controller* ri); int read_ri_regs(void* opaque, uint32_t address, uint32_t* value); int write_ri_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask); #endif mupen64plus-core/doc/emuwiki-api-doc/Mupen64Plus_v2.0_Core_Front-End.txt000664 001750 001750 00000044444 12655644434 027046 0ustar00sergiosergio000000 000000 [[Mupen64Plus v2.0 Core API v1.0|Mupen64Plus v2.0 API]] = Mupen64Plus v2.0 Core<-->Front-End API = Most libmupen64plus functions return an m64p_error return code, which is an enumerated type defined in [[Mupen64Plus v2.0 headers#m64p_types.h|m64p_types.h]]. Front-end code should check the return value of each call to a libmupen64plus function. == Startup/Shutdown Functions == {| border="1" |Prototype |'''m64p_error CoreStartup(int APIVersion, const char *ConfigPath, const char *DataPath, void *Context, void (*DebugCallback)(void *Context, int level, const char *message), void *Context2, void (*StateCallback)(void *Context2, m64p_core_param ParamChanged, int NewValue))''' |- |Input Parameters |'''APIVersion''' Integer containing the version number of the Core API used by the front-end.
'''ConfigPath''' File path to folder containing Mupen64Plus.cfg. Can be NULL.
'''DataPath''' Folder to search first when looking for shared data files. Can be NULL.
'''Context''' Pointer which will be passed back to the '''DebugCallback''' function. Can be NULL.
'''DebugCallback''' Pointer to function in front-end for receiving debug information and warnings from the core. This function must be thread-safe. Can be NULL. The value of level is 1 for an error, 2 for a warning, 3 for info, and 4 for verbose info.
'''Context2''' Pointer which will be passed back to the '''StateCallback''' function. Can be NULL.
'''StateCallback''' Pointer to function in front-end for receiving core state change notifications. This function must be thread-safe. Can be NULL. |- |Requirements |This function must be called before any other libmupen64plus functions. |- |Usage |This function initializes libmupen64plus for use by allocating memory, creating data structures, and loading the configuration file. If '''ConfigPath''' is NULL, libmupen64plus will search for the configuration file in its usual place (On Linux, in ~/.config/mupen64plus/). This function may return M64ERR_INCOMPATIBLE if older front-end is used with newer core. |}
{| border="1" |Prototype |'''m64p_error CoreShutdown(void)''' |- |Input Parameters |N/A |- |Usage |This function saves the configuration file, then destroys data structures and releases memory allocated by the core library. |}
{| border="1" |Prototype |'''m64p_error CoreAttachPlugin(m64p_plugin_type PluginType, m64p_dynlib_handle PluginLibHandle)''' |- |Input Parameters |'''PluginType''' Enumerated type specifying the plugin type to attach to the core. If this type of plugin is currently attached to the core, an error will be returned.
'''PluginLibHandle''' Dynamic library handle (defined in [[Mupen64Plus v2.0 headers#m64p_types.h|m64p_types.h]]) corresponding with the plugin object to attach. |- |Requirements |Both the core library and the plugin library must already be initialized with the CoreStartup()/PluginStartup() functions, and a ROM must be open. This function cannot be called while the emulator is running. The plugins must be attached in the following order: Video, Audio, Input, RSP. |- |Usage |This function attaches the given plugin to the emulator core. There can only be one plugin of each type attached to the core at any given time. |}
{| border="1" |Prototype |'''m64p_error CoreDetachPlugin(m64p_plugin_type PluginType)''' |- |Input Parameters |'''PluginType''' Enumerated type specifying the plugin type to detach from the core. If no plugin of this type is currently attached to the core, this function will exit with a return value of M64ERR_SUCCESS. |- |Requirements |Both the core library and the plugin library must already be initialized with the CoreStartup()/PluginStartup() functions. This function cannot be called while the emulator is running. |- |Usage |This function detaches the given plugin from the emulator core, and re-attaches the 'dummy' plugin functions. |} == Command Functions == {| border="1" |Prototype |'''m64p_error CoreDoCommand(m64p_command Command, int ParamInt, void *ParamPtr)''' |- |Input Parameters |'''Command''' Enumerated type specifying which command should be executed.
'''ParamInt''' An integer value which may be used as an input to the command.
'''ParamPtr''' A pointer which may be used as an input to the command.
|- |Requirements |The core library must already be initialized with the CoreStartup() function. Each command may have its own requirements as well. |- |Usage |This function sends a command to the emulator core. A table of all commands is given below. |}
{| border="1" !Command!!Function!!Input Parameters!!Requirements |- |M64CMD_ROM_OPEN |This will cause the core to read in a binary ROM image provided by the front-end. |'''ParamPtr''' Pointer to the uncompressed ROM image in memory.
'''ParamInt''' The size in bytes of the ROM image. |The emulator cannot be currently running. A ROM image must not be currently opened. |- |M64CMD_ROM_CLOSE |This will close any currently open ROM. The current cheat code list will also be deleted. |N/A |The emulator cannot be currently running. A ROM image must have been previously opened. There should be no plugins currently attached. |- |M64CMD_ROM_GET_HEADER |This will retrieve the header data of the currently open ROM. |'''ParamPtr''' Pointer to a rom_header struct to receive the data.
'''ParamInt''' The size in bytes of the rom_header struct. |A ROM image must be open. |- |M64CMD_ROM_GET_SETTINGS |This will retrieve the settings data of the currently open ROM. |'''ParamPtr''' Pointer to a rom_settings struct to receive the data.
'''ParamInt''' The size in bytes of the rom_settings struct. |A ROM image must be open. |- |M64CMD_EXECUTE |This command will start the emulator and begin executing the ROM image. This function call will not return until the game has been stopped. |N/A |The emulator cannot be currently running. A ROM image must have been previously opened. |- |M64CMD_STOP |This will stop the emulator, if it is currently running. |N/A |This command will execute asynchronously. |- |M64CMD_PAUSE |This command will pause the emulator if it is running. |N/A |This function will return a non-successful error code if the emulator is in the stopped state. This command may execute asynchronously. |- |M64CMD_RESUME |This command will resume execution of the emulator if it is paused. |N/A |This function will return a non-successful error code if the emulator is in the stopped state. This command may execute asynchronously. |- |M64CMD_CORE_STATE_QUERY |This command will query the emulator core for the value of a state parameter |'''ParamInt''' An m64p_core_param enumerated type specifying the desired state variable'''
ParamPtr''' Pointer to an integer to receive the value of the requested state variable. |None |- |M64CMD_CORE_STATE_SET |This command will set the value of a state parameter in the emulator core |'''ParamInt''' An m64p_core_param enumerated type specifying the desired state variable'''
ParamPtr''' Pointer to an integer to containing the value of the requested state variable. |The initial requirements vary depending upon the variable being set. Setting some variables requires the emulator to be running. |- |M64CMD_STATE_LOAD |This command will attempt to load a saved state file. If '''ParamPtr''' is not NULL, this function will load a state file from a full pathname specified by this pointer. Otherwise ('''ParamPtr''' is NULL), it will load from the current slot. |'''ParamInt''' Ignored'''
ParamPtr''' Pointer to string containing state file path and name, or NULL |The emulator must be currently running or paused. This command will execute asynchronously. |- |M64CMD_STATE_SAVE |This command will save a state file. If '''ParamPtr''' is not NULL, this function will save a state file to a full pathname specified by this pointer. Otherwise ('''ParamPtr''' is NULL), it will save to the current slot. |'''ParamInt''' This parameter will only be used if '''ParamPtr''' is not NULL. If 1, a Mupen64Plus state file will be saved. If 2, a Project64 compressed state file will be saved. If 3, a Project64 uncompressed state file will be saved. '''
ParamPtr''' Pointer to string containing state file path and name, or NULL
|The emulator must be currently running or paused. This command will execute asynchronously. |- |M64CMD_STATE_SET_SLOT |This command will set the currently selected save slot index |'''ParamInt''' Value to set for the current slot index. Must be between 0 and 9'''
ParamPtr''' Ignored
|None |- |M64CMD_SEND_SDL_KEYDOWN |This command will inject an SDL_KEYDOWN event into the emulator's core event loop. Keys not handled by the core will be passed to the input plugin. |'''ParamInt''' Key value of the keypress event to inject, with SDLMod in the upper 16 bits and SDLKey in the lower 16 bits. |The emulator must be currently running or paused. |- |M64CMD_SEND_SDL_KEYUP |This command will inject an SDL_KEYUP event into the emulator's core event loop. |'''ParamInt''' Key value of the keypress event to inject, with SDLMod in the upper 16 bits and SDLKey in the lower 16 bits. |The emulator must be currently running or paused. |- |M64CMD_SET_FRAME_CALLBACK |This command either registers or removes (if '''ParamPtr''' is NULL) a frame callback function. This function will be called after each video frame is rendered. The front-end callback function may call the video plugin's ReadScreen2() function to retrieve the frame if desired. |'''ParamPtr''' Can be either NULL or a m64p_frame_callback object. |None |- |M64CMD_TAKE_NEXT_SCREENSHOT |This will cause the core to save a screenshot at the next possible opportunity. |N/A |The emulator must be currently running or paused. This command will execute asynchronously. |- |M64CMD_READ_SCREEN |This command will copy the current contents of the video display to the buffer pointer by '''ParamPtr'''. |'''ParamInt''' 1 to copy the buffer that is currently displayed (front buffer), 0 to copy the buffer that is being drawn (back buffer).'''
ParamPtr'''A pointer to a buffer of at least width*height*3 bytes. The buffer will be filled with the current display. The format is RGB888 with the origin in the lower left corner. |The emulator must be currently running or paused. |- |M64CMD_RESET |Reset the emulated machine. |'''ParamInt''' 0 to do a soft reset, 1 to do a hard reset.'''
ParamPtr''' Ignored |The emulator must be currently running or paused. |- |M64CMD_ADVANCE_FRAME |Advance one frame (the emulator will run until the next frame, then pause). |'''ParamInt''' Ignored'''
ParamPtr''' Ignored |The emulator must be currently running or paused. |}
== Core State Parameters == These core parameters may be read and/or written using the M64CMD_CORE_STATE_QUERY and M64CMD_CORE_STATE_SET commands. The front-end application will receive a callback (via the StateCallback function pointer given to the '''CoreStartup''' function) when these parameters change value. This callback will be sent even if the function which caused the state change was called by the front-end application itself. Not all of these parameters are readable or writable. Each parameter's value is held in a single 32-bit integer. The meaning of this integer is given in the Parameter Encoding column. See the table below for details on these core parameters.
{| border="1" !Name!!Readable!!Writable!!int Parameter Encoding!!Notes |- |M64CORE_EMU_STATE |Yes |Yes |enum m64p_emu_state |1=Stopped, 2=Running, 3=Paused |- |M64CORE_VIDEO_MODE |Yes |Yes |enum m64p_video_mode |1=None (video not running), 2=Windowed, 3=Fullscreen |- |M64CORE_SAVESTATE_SLOT |Yes |Yes | |Valid values are 0 through 9. |- |M64CORE_SPEED_FACTOR |Yes |Yes |Emulator playback speed in percent |Valid values are 1 to 1000. |- |M64CORE_SPEED_LIMITER |Yes |Yes |1 to enable speed limiter, or 0 to disable speed limiter. |When speed limiter is disabled, emulator will run as fast as possible (useful for benchmarking). |- |M64CORE_VIDEO_SIZE |Yes |Yes |(ScreenWidth << 16) + ScreenHeight |This parameter can only be read or written when the emulator is running or paused. This parameter may be written by the front-end application in response to a window resizing event. Upon receiving this command, the core will pass the new width and height to the ResizeVideoOutput function in the video plugin (video API v2.2.0). If the video plugin supports resizing, it will update its viewport and then call the video extension function VidExt_ResizeWindow to update the window manager. |- |M64CORE_AUDIO_VOLUME |Yes |Yes |Volume level in percent, 0 - 100 | |- |M64CORE_AUDIO_MUTE |Yes |Yes |1 if muted, otherwise 0 | |- |M64CORE_INPUT_GAMESHARK |Yes |Yes |1 when Gameshark button pressed, 0 when button released. |Callback function will be invoked on both button press and release. |- |M64CORE_STATE_LOADCOMPLETE |No |No |1 if state loading was successful, 0 if state loading failed. |This parameter cannot be read or written. It is only used for callbacks, because the state load/save operations are asynchronous. |- |M64CORE_STATE_SAVECOMPLETE |No |No |1 if state saving was successful, 0 if state saving failed. |This parameter cannot be read or written. It is only used for callbacks, because the state load/save operations are asynchronous. |}
== ROM Handling Functions == {| border="1" |Prototype |'''m64p_error CoreGetRomSettings(m64p_rom_settings *RomSettings, int RomSettingsLength, int Crc1, int Crc2)''' |- |Input Parameters |'''RomSettings''' Pointer to m64p_rom_settings object to be filled in with data.
'''RomSettingsLength''' Size of the object pointed to by '''RomSettings''' in bytes.
'''Crc1''' A 32-bit integer value containing the first CRC (taken from the ROM header) to identify the ROM.
'''Crc2''' A 32-bit integer value containing the second CRC (taken from the ROM header) to identify the ROM. |- |Requirements |The core library must already be initialized with the CoreStartup() function. The '''RomSettings''' pointer must not be NULL. The '''RomSettingsLength''' value must be greater than or equal to the size of the m64p_rom_settings structure. This function does not require any ROM image to be currently open. |- |Usage |This function searches through the data in the Mupen64Plus.ini file to find an entry which matches the given '''Crc1''' and '''Crc2''' hashes, and if found, fills in the '''RomSettings''' structure with the data from the Mupen64Plus.ini file. |}
== Video Extension Functions == {| border="1" |Prototype |'''m64p_error CoreOverrideVidExt(m64p_video_extension_functions *VideoFunctionStruct);''' |- |Input Parameters |'''VideoFunctionStruct''' Pointer to a structure (defined in [[Mupen64Plus v2.0 headers#m64p_types.h|m64p_types.h]]) containing pointers to the Front-end's custom Video Extension functions to override the default SDL functions |- |Requirements |The Mupen64Plus library must already be initialized before calling this function. This function cannot be called while the emulator is running. |- |Usage |This function overrides the core's internal SDL-based OpenGL functions which are called from the video plugin to perform various basic tasks like opening the video window, toggling between windowed and fullscreen modes, and swapping frame buffers after a frame has been rendered. This override functionality allows a front-end to define its own video extension functions to be used instead of the SDL functions, such as for the purpose of embedding the emulator display window inside of a Qt GUI window. If any of the function pointers in the structure are NULL, the override function will be disabled and the core's internal SDL functions will be used. The core library with a Video Extension API v3.0 expects the Functions struct member to be equal to 11 or more. |}
== Cheat Functions == {| border="1" |Prototype |'''m64p_error CoreAddCheat(const char *CheatName, m64p_cheat_code *CodeList, int NumCodes)''' |- |Input Parameters |'''CheatName''' Pointer to NULL-terminated string containing a unique name for this Cheat Function.
'''CodeList''' Pointer to an array of m64p_cheat_code objects.
'''NumCodes''' Number of m64p_cheat_code elements in the cheat code array. |- |Requirements |The Mupen64Plus library must already be initialized before calling this function. A ROM image must be currently opened. |- |Usage |This function will add a Cheat Function to a list of currently active cheats which are applied to the open ROM, and set its state to Enabled. This function may be called before a ROM begins execution or while a ROM is currently running. Some cheat codes must be applied before the ROM begins executing, and may not work correctly if added after the ROM begins execution. A Cheat Function consists of a list of one or more m64p_cheat_code elements. If a Cheat Function with the given '''CheatName''' already exists, it will be removed and the new Cheat Function will be added in its place. |}
{| border="1" |Prototype |'''m64p_error CoreCheatEnabled(const char *CheatName, int Enabled)''' |- |Input Parameters |'''CheatName''' Pointer to NULL-terminated string containing the name of an existing Cheat Function.
'''Enabled''' Boolean value to which to set the enabled state of the specified Cheat Function. |- |Requirements |The Mupen64Plus library must already be initialized before calling this function. A ROM image must be currently opened. |- |Usage |This function enables or disables a specified Cheat Function. |} gles2n64/src/F3DWRUS.c000664 001750 001750 00000005767 12655644434 015332 0ustar00sergiosergio000000 000000 #include "gles2N64.h" #include "Debug.h" #include "F3D.h" #include "F3DEX.h" #include "F3DWRUS.h" #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gSP.h" #include "gDP.h" #include "GBI.h" void F3DWRUS_Vtx( u32 w0, u32 w1 ) { gSPVertex( w1, _SHIFTR( w0, 9, 7 ), _SHIFTR( w0, 16, 8 ) / 5 ); } void F3DWRUS_Tri1( u32 w0, u32 w1 ) { gSP1Triangle( _SHIFTR( w1, 16, 8 ) / 5, _SHIFTR( w1, 8, 8 ) / 5, _SHIFTR( w1, 0, 8 ) / 5); } void F3DWRUS_Tri2( u32 w0, u32 w1 ) { gSP2Triangles( _SHIFTR( w0, 16, 8 ) / 5, _SHIFTR( w0, 8, 8 ) / 5, _SHIFTR( w0, 0, 8 ) / 5, 0, _SHIFTR( w1, 16, 8 ) / 5, _SHIFTR( w1, 8, 8 ) / 5, _SHIFTR( w1, 0, 8 ) / 5, 0); } void F3DWRUS_Quad( u32 w0, u32 w1 ) { gSP1Quadrangle( _SHIFTR( w1, 24, 8 ) / 5, _SHIFTR( w1, 16, 8 ) / 5, _SHIFTR( w1, 8, 8 ) / 5, _SHIFTR( w1, 0, 8 ) / 5 ); } void F3DWRUS_Init(void) { gSPSetupFunctions(); // Set GeometryMode flags GBI_InitFlags( F3D ); GBI.PCStackSize = 10; // GBI Command Command Value Command Function GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_MTX, F3D_MTX, F3D_Mtx ); GBI_SetGBI( G_RESERVED0, F3D_RESERVED0, F3D_Reserved0 ); GBI_SetGBI( G_MOVEMEM, F3D_MOVEMEM, F3D_MoveMem ); GBI_SetGBI( G_VTX, F3D_VTX, F3DWRUS_Vtx ); GBI_SetGBI( G_RESERVED1, F3D_RESERVED1, F3D_Reserved1 ); GBI_SetGBI( G_DL, F3D_DL, F3D_DList ); GBI_SetGBI( G_RESERVED2, F3D_RESERVED2, F3D_Reserved2 ); GBI_SetGBI( G_RESERVED3, F3D_RESERVED3, F3D_Reserved3 ); GBI_SetGBI( G_SPRITE2D_BASE, F3D_SPRITE2D_BASE, F3D_Sprite2D_Base ); GBI_SetGBI( G_TRI1, F3D_TRI1, F3DWRUS_Tri1 ); GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3D_CullDL ); GBI_SetGBI( G_POPMTX, F3D_POPMTX, F3D_PopMtx ); GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3D_MoveWord ); GBI_SetGBI( G_TEXTURE, F3D_TEXTURE, F3D_Texture ); GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L ); GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL ); GBI_SetGBI( G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, F3D_SetGeometryMode ); GBI_SetGBI( G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE, F3D_ClearGeometryMode ); GBI_SetGBI( G_QUAD, F3D_QUAD, F3DWRUS_Quad ); GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_RDPHALF_CONT, F3D_RDPHALF_CONT, F3D_RDPHalf_Cont ); GBI_SetGBI( G_TRI2, F3DWRUS_TRI2, F3DWRUS_Tri2 ); } mupen64plus-core/tools/build_bundle_src.sh000755 001750 001750 00000005635 12655644434 022054 0ustar00sergiosergio000000 000000 #!/bin/sh #/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # * Mupen64plus - build_bundle_src.sh * # * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * # * Copyright (C) 2009-2013 Richard Goedeken * # * * # * This program is free software; you can redistribute it and/or modify * # * it under the terms of the GNU General Public License as published by * # * the Free Software Foundation; either version 2 of the License, or * # * (at your option) any later version. * # * * # * This program is distributed in the hope that it will be useful, * # * but WITHOUT ANY WARRANTY; without even the implied warranty of * # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * # * GNU General Public License for more details. * # * * # * You should have received a copy of the GNU General Public License * # * along with this program; if not, write to the * # * Free Software Foundation, Inc., * # * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ # terminate the script if any commands return a non-zero error code set -e if [ $# -lt 2 ]; then echo "Usage: build_bundle_src.sh " exit 1 fi OUTPUTDIR="mupen64plus-bundle-$2" echo "************************************ Creating directory: " ${OUTPUTDIR} rm -rf ${OUTPUTDIR} mkdir -p ${OUTPUTDIR}/source cd ${OUTPUTDIR}/source echo "************************************ Downloading Mupen64Plus module source code" hg clone -r $1 http://bitbucket.org/richard42/mupen64plus-core hg clone -r $1 http://bitbucket.org/richard42/mupen64plus-rom hg clone -r $1 http://bitbucket.org/richard42/mupen64plus-ui-console hg clone -r $1 http://bitbucket.org/richard42/mupen64plus-audio-sdl hg clone -r $1 http://bitbucket.org/richard42/mupen64plus-input-sdl hg clone -r $1 http://bitbucket.org/richard42/mupen64plus-rsp-hle hg clone -r $1 http://bitbucket.org/richard42/mupen64plus-video-rice hg clone -r $1 http://bitbucket.org/richard42/mupen64plus-video-glide64mk2 for dirname in ./mupen64plus-*; do rm -rf ${dirname}/.hg*; done # unzip the helper scripts and remove the Mercurial scripts cd .. tar xzvf source/mupen64plus-core/tools/m64p_helper_scripts.tar.gz rm -f m64p_get.sh m64p_update.sh echo "************************************ Creating archive" cd .. tar c "${OUTPUTDIR}" --owner 0 --group 0 --numeric-owner | gzip -n > "${OUTPUTDIR}.tar.gz" rm -rf "${OUTPUTDIR}" mupen64plus-video-gliden64/src/GLideNHQ/test/000700 001750 001750 00000000000 12656647145 021727 5ustar00sergiosergio000000 000000 mupen64plus-core/src/ri/ri_controller.c000664 001750 001750 00000005276 12655644434 021303 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - ri_controller.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "ri_controller.h" #include "memory/memory.h" #include void connect_ri(struct ri_controller* ri, uint32_t* dram, size_t dram_size) { connect_rdram(&ri->rdram, dram, dram_size); } /* Initializes the RI. */ void init_ri(struct ri_controller* ri) { memset(ri->regs, 0, RI_REGS_COUNT*sizeof(uint32_t)); init_rdram(&ri->rdram); /* MESS uses these, so we will too? (backported from CEN64) */ ri->regs[RI_MODE_REG] = 0xE; ri->regs[RI_CONFIG_REG] = 0x40; ri->regs[RI_SELECT_REG] = 0x14; ri->regs[RI_REFRESH_REG] = 0x63634; } /* Reads a word from the RI MMIO rgister space. */ int read_ri_regs(void* opaque, uint32_t address, uint32_t *word) { struct ri_controller* ri = (struct ri_controller*)opaque; uint32_t reg = RI_REG(address); *word = ri->regs[reg]; return 0; } /* Writes a word from the RI MMIO register space. */ int write_ri_regs(void* opaque, uint32_t address, uint32_t word, uint32_t mask) { struct ri_controller* ri = (struct ri_controller*)opaque; uint32_t reg = RI_REG(address); ri->regs[reg] = MASKED_WRITE(&ri->regs[reg], word, mask); return 0; } glide2gl/src/Glitch64/glitch64_combiner.c000664 001750 001750 00000263051 12655644434 021240 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #ifdef _WIN32 #include #else // _WIN32 #include #include #endif // _WIN32 #include #include "glide.h" #include "glitchmain.h" #include "../../libretro/SDL.h" float glide64_pow(float a, float b); typedef struct _shader_program_key { int index; int color_combiner; int alpha_combiner; int texture0_combiner; int texture1_combiner; int texture0_combinera; int texture1_combinera; int fog_enabled; int chroma_enabled; int dither_enabled; int three_point_filter0; int three_point_filter1; GLuint program_object; int texture0_location; int texture1_location; int vertexOffset_location; int textureSizes_location; int exactSizes_location; int fogModeEndScale_location; int fogColor_location; int alphaRef_location; int chroma_color_location; int lambda_location; int constant_color_location; int ccolor0_location; int ccolor1_location; } shader_program_key; static int fct[4], source0[4], operand0[4], source1[4], operand1[4], source2[4], operand2[4]; static int fcta[4],sourcea0[4],operanda0[4],sourcea1[4],operanda1[4],sourcea2[4],operanda2[4]; static int alpha_ref, alpha_func; bool alpha_test = 0; static shader_program_key *shader_programs = NULL; static shader_program_key *current_shader = NULL; static int number_of_programs = 0; static int color_combiner_key; static int alpha_combiner_key; static int texture0_combiner_key; static int texture1_combiner_key; static int texture0_combinera_key; static int texture1_combinera_key; float texture_env_color[4]; float ccolor[2][4]; static float chroma_color[4]; int fog_enabled; static int chroma_enabled; static int chroma_other_color; static int chroma_other_alpha; static int dither_enabled; float fogStart,fogEnd; int need_lambda[2]; float lambda_color[2][4]; // shaders variables int need_to_compile; static char *fragment_shader; static GLuint vertex_shader_object; GLuint program_object_default; static int first_color = 1; static int first_alpha = 1; static int first_texture0 = 1; static int first_texture1 = 1; static int tex0_combiner_ext = 0; static int tex1_combiner_ext = 0; static int c_combiner_ext = 0; static int a_combiner_ext = 0; #if !defined(__LIBRETRO__) || defined(HAVE_OPENGLES2) // Desktop GL fix #define GLSL_VERSION "100" #else #define GLSL_VERSION "120" #endif #define SHADER_HEADER \ "#version " GLSL_VERSION "\n" \ "#define gl_Color vFrontColor \n" \ "#define gl_FrontColor vFrontColor \n" \ "#define gl_TexCoord vTexCoord \n" \ #define SHADER_VARYING \ "varying highp vec4 gl_FrontColor; \n" \ "varying highp vec4 gl_TexCoord[4]; \n" static const char* fragment_shader_header = SHADER_HEADER #if !defined(__LIBRETRO__) || defined(HAVE_OPENGLES2) // Desktop GL fix "precision lowp float; \n" #else "#define highp \n" #endif #ifdef EMSCRIPTEN "#extension GL_EXT_frag_depth : enable\n" #endif "uniform sampler2D texture0; \n" "uniform sampler2D texture1; \n" "uniform vec4 exactSizes; \n" //textureSizes doesn't contain the correct sizes, use this one instead for offset calculations "uniform vec4 constant_color; \n" "uniform vec4 ccolor0; \n" "uniform vec4 ccolor1; \n" "uniform vec4 chroma_color; \n" "uniform float lambda; \n" "uniform vec3 fogColor; \n" "uniform float alphaRef; \n" "#define TEX0 texture2D(texture0, gl_TexCoord[0].xy) \n" \ "#define TEX0_OFFSET(off) texture2D(texture0, gl_TexCoord[0].xy - off/exactSizes.xy) \n" \ "#define TEX1 texture2D(texture1, gl_TexCoord[1].xy) \n" \ "#define TEX1_OFFSET(off) texture2D(texture1, gl_TexCoord[1].xy - off/exactSizes.zw) \n" \ SHADER_VARYING "\n" "void test_chroma(vec4 ctexture1); \n" "\n" "\n" "void main()\n" "{\n" " vec2 offset; \n" " vec4 c0,c1,c2; \n" ; // using gl_FragCoord is terribly slow on ATI and varying variables don't work for some unknown // reason, so we use the unused components of the texture2 coordinates static const char* fragment_shader_dither = " highp float temp=abs(sin((gl_TexCoord[2].a)+sin((gl_TexCoord[2].a)+(gl_TexCoord[2].b))))*170.0; \n" " if ((fract(temp)+fract(temp/2.0)+fract(temp/4.0))>1.5) discard; \n" ; static const char* fragment_shader_default = " gl_FragColor = TEX0; \n" ; static const char* fragment_shader_readtex0color = " vec4 readtex0 = TEX0; \n" ; static const char* fragment_shader_readtex0color_3point = " offset=fract(gl_TexCoord[0].xy*exactSizes.xy-vec2(0.5,0.5)); \n" " offset-=step(1.0,offset.x+offset.y); \n" " c0=TEX0_OFFSET(offset); \n" " c1=TEX0_OFFSET(vec2(offset.x-sign(offset.x),offset.y)); \n" " c2=TEX0_OFFSET(vec2(offset.x,offset.y-sign(offset.y))); \n" " vec4 readtex0 =c0+abs(offset.x)*(c1-c0)+abs(offset.y)*(c2-c0); \n" ; static const char* fragment_shader_readtex1color = " vec4 readtex1 = TEX1; \n" ; static const char* fragment_shader_readtex1color_3point = " offset=fract(gl_TexCoord[1].xy*exactSizes.zw-vec2(0.5,0.5)); \n" " offset-=step(1.0,offset.x+offset.y); \n" " c0=TEX1_OFFSET(offset); \n" " c1=TEX1_OFFSET(vec2(offset.x-sign(offset.x),offset.y)); \n" " c2=TEX1_OFFSET(vec2(offset.x,offset.y-sign(offset.y))); \n" " vec4 readtex1 =c0+abs(offset.x)*(c1-c0)+abs(offset.y)*(c2-c0); \n"; static const char* fragment_shader_fog = " float fog; \n" " fog = gl_TexCoord[0].b; \n" " gl_FragColor.rgb = mix(fogColor, gl_FragColor.rgb, fog); \n" ; static const char* fragment_shader_end = "if(gl_FragColor.a <= alphaRef) {discard;} \n" "}\n" ; static const char* vertex_shader = SHADER_HEADER #if defined(__LIBRETRO__) && !defined(HAVE_OPENGLES2) // Desktop GL fix "#define highp \n" #endif "#define Z_MAX 65536.0 \n" "attribute highp vec4 aPosition; \n" "attribute highp vec4 aColor; \n" "attribute highp vec4 aMultiTexCoord0; \n" "attribute highp vec4 aMultiTexCoord1; \n" "attribute float aFog; \n" "uniform vec3 vertexOffset; \n" //Moved some calculations from grDrawXXX to shader "uniform vec4 textureSizes; \n" "uniform vec3 fogModeEndScale; \n" //0 = Mode, 1 = gl_Fog.end, 2 = gl_Fog.scale SHADER_VARYING "\n" "void main()\n" "{\n" " highp float q = aPosition.w; \n" " highp float invertY = vertexOffset.z; \n" //Usually 1.0 but -1.0 when rendering to a texture (see inverted_culling grRenderBuffer) " gl_Position.x = (aPosition.x - vertexOffset.x) / vertexOffset.x; \n" " gl_Position.y = invertY *-(aPosition.y - vertexOffset.y) / vertexOffset.y; \n" " gl_Position.z = aPosition.z / Z_MAX; \n" " gl_Position.w = 1.0; \n" " gl_Position /= q; \n" " gl_FrontColor = aColor.bgra; \n" "\n" " gl_TexCoord[0] = vec4(aMultiTexCoord0.xy / q / textureSizes.xy,0,1); \n" " gl_TexCoord[1] = vec4(aMultiTexCoord1.xy / q / textureSizes.zw,0,1); \n" "\n" " float fogV = (1.0 / mix(q,aFog,fogModeEndScale[0])) / 255.0; \n" //" //if(fogMode == 2) { \n" //" // fogV = 1.0 / aFog / 255 \n" //" //} \n" "\n" " float f = (fogModeEndScale[1] - fogV) * fogModeEndScale[2]; \n" " f = clamp(f, 0.0, 1.0); \n" " gl_TexCoord[0].b = f; \n" " gl_TexCoord[2].b = aPosition.x; \n" " gl_TexCoord[2].a = aPosition.y; \n" "} \n" ; static char fragment_shader_color_combiner[1024*2]; static char fragment_shader_alpha_combiner[1024*2]; static char fragment_shader_texture1[1024*2]; static char fragment_shader_texture0[1024*2]; static char fragment_shader_chroma[1024*2]; static char shader_log[2048]; void check_compile(GLuint shader) { GLint success; glGetShaderiv(shader,GL_COMPILE_STATUS,&success); if (!success) { char log[1024]; glGetShaderInfoLog(shader,1024,NULL,log); if (log_cb) log_cb(RETRO_LOG_ERROR, log); } } void check_link(GLuint program) { GLint success; glGetProgramiv(program,GL_LINK_STATUS,&success); if (!success) { char log[1024]; glGetProgramInfoLog(program,1024,NULL,log); if (log_cb) log_cb(RETRO_LOG_ERROR, log); } } static void append_shader_program(shader_program_key *shader) { int curr_index; int index = number_of_programs; if (current_shader) curr_index = current_shader->index; shader->index = index; if (!shader_programs) shader_programs = (shader_program_key*)malloc(sizeof(shader_program_key)); else { shader_program_key *new_ptr = (shader_program_key*) realloc(shader_programs, (index + 1) * sizeof(shader_program_key)); if (!new_ptr) return; shader_programs = new_ptr; } if (current_shader) current_shader = &shader_programs[curr_index]; shader_programs[index] = *shader; ++number_of_programs; } static void shader_bind_attributes(shader_program_key *shader) { GLuint prog = shader->program_object; glBindAttribLocation(prog, POSITION_ATTR, "aPosition"); glBindAttribLocation(prog, COLOUR_ATTR, "aColor"); glBindAttribLocation(prog, TEXCOORD_0_ATTR, "aMultiTexCoord0"); glBindAttribLocation(prog, TEXCOORD_1_ATTR, "aMultiTexCoord1"); glBindAttribLocation(prog, FOG_ATTR, "aFog"); } static void use_shader_program(shader_program_key *shader) { current_shader = &shader_programs[shader->index]; glUseProgram(shader->program_object); } static void shader_find_uniforms(shader_program_key *shader) { GLuint prog = shader->program_object; /* vertex shader uniforms */ shader->vertexOffset_location = glGetUniformLocation(prog, "vertexOffset"); shader->textureSizes_location = glGetUniformLocation(prog, "textureSizes"); shader->fogModeEndScale_location = glGetUniformLocation(prog, "fogModeEndScale"); /* fragment shader uniforms */ shader->texture0_location = glGetUniformLocation(prog, "texture0"); shader->texture1_location = glGetUniformLocation(prog, "texture1"); shader->exactSizes_location = glGetUniformLocation(prog, "exactSizes"); shader->constant_color_location = glGetUniformLocation(prog, "constant_color"); shader->ccolor0_location = glGetUniformLocation(prog, "ccolor0"); shader->ccolor1_location = glGetUniformLocation(prog, "ccolor1"); shader->chroma_color_location = glGetUniformLocation(prog, "chroma_color"); shader->lambda_location = glGetUniformLocation(prog, "lambda"); shader->fogColor_location = glGetUniformLocation(prog, "fogColor"); shader->alphaRef_location = glGetUniformLocation(prog, "alphaRef"); } static void finish_shader_program_setup(shader_program_key *shader) { GLuint fragshader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragshader, 1, (const GLchar**)&fragment_shader, NULL); glCompileShader(fragshader); check_compile(fragshader); shader->program_object = glCreateProgram(); glAttachShader(shader->program_object, vertex_shader_object); glAttachShader(shader->program_object, fragshader); shader_bind_attributes(shader); glLinkProgram(shader->program_object); check_link(shader->program_object); glUseProgram(shader->program_object); shader_find_uniforms(shader); append_shader_program(shader); } void init_combiner(void) { shader_program_key shader; if (shader_programs) free(shader_programs); number_of_programs = 0; shader_programs = NULL; current_shader = NULL; fragment_shader = (char*)malloc(4096*2); need_to_compile = true; /* default shader */ memset(&shader, 0, sizeof(shader)); strcpy(fragment_shader, fragment_shader_header); strcat(fragment_shader, fragment_shader_default); strcat(fragment_shader, fragment_shader_end); vertex_shader_object = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex_shader_object, 1, (const GLchar**)&vertex_shader, NULL); glCompileShader(vertex_shader_object); check_compile(vertex_shader_object); finish_shader_program_setup(&shader); program_object_default = shader.program_object; use_shader_program(&shader); glUniform1i(shader.texture0_location, 0); glUniform1i(shader.texture1_location, 1); strcpy(fragment_shader_color_combiner, ""); strcpy(fragment_shader_alpha_combiner, ""); strcpy(fragment_shader_texture1, "vec4 ctexture1 = texture2D(texture0, vec2(gl_TexCoord[0])); \n"); strcpy(fragment_shader_texture0, ""); first_color = 1; first_alpha = 1; first_texture0 = 1; first_texture1 = 1; need_to_compile = 0; fog_enabled = 0; chroma_enabled = 0; dither_enabled = 0; } static void compile_chroma_shader(void) { strcpy(fragment_shader_chroma, "\nvoid test_chroma(vec4 ctexture1)\n{\n"); switch(chroma_other_alpha) { case GR_COMBINE_OTHER_ITERATED: strcat(fragment_shader_chroma, "float alpha = gl_Color.a; \n"); break; case GR_COMBINE_OTHER_TEXTURE: strcat(fragment_shader_chroma, "float alpha = ctexture1.a; \n"); break; case GR_COMBINE_OTHER_CONSTANT: strcat(fragment_shader_chroma, "float alpha = constant_color.a; \n"); break; } switch(chroma_other_color) { case GR_COMBINE_OTHER_ITERATED: strcat(fragment_shader_chroma, "vec4 color = vec4(vec3(gl_Color),alpha); \n"); break; case GR_COMBINE_OTHER_TEXTURE: strcat(fragment_shader_chroma, "vec4 color = vec4(vec3(ctexture1),alpha); \n"); break; case GR_COMBINE_OTHER_CONSTANT: strcat(fragment_shader_chroma, "vec4 color = vec4(vec3(constant_color),alpha); \n"); break; } strcat(fragment_shader_chroma, "if (color.rgb == chroma_color.rgb) discard; \n"); strcat(fragment_shader_chroma, "}"); } static void update_uniforms(const shader_program_key *prog) { GLfloat v0, v2; glUniform1i(prog->texture0_location, 0); glUniform1i(prog->texture1_location, 1); v2 = 1.0f; glUniform3f( prog->vertexOffset_location, (GLfloat)width / 2.f, (GLfloat)height / 2.f, v2 ); glUniform4f( prog->textureSizes_location, (float)tex_width[0], (float)tex_height[0], (float)tex_width[1], (float)tex_height[1] ); glUniform4f( prog->exactSizes_location, (float)tex_exactWidth[0], (float)tex_exactHeight[0], (float)tex_exactWidth[1], (float)tex_exactHeight[1] ); v0 = fog_enabled != 2 ? 0.0f : 1.0f; v2 /= (fogEnd - fogStart); glUniform3f(prog->fogModeEndScale_location, v0, fogEnd, v2); if(prog->fogColor_location != -1) glUniform3f(prog->fogColor_location, g_gdp.fog_color.r / 255.0f, g_gdp.fog_color.g / 255.0f, g_gdp.fog_color.b / 255.0f); glUniform1f(prog->alphaRef_location,alpha_test ? alpha_ref/255.0f : -1.0f); glUniform4f(prog->constant_color_location, texture_env_color[0], texture_env_color[1], texture_env_color[2], texture_env_color[3]); glUniform4f(prog->ccolor0_location, ccolor[0][0], ccolor[0][1], ccolor[0][2], ccolor[0][3]); glUniform4f(prog->ccolor1_location, ccolor[1][0], ccolor[1][1], ccolor[1][2], ccolor[1][3]); glUniform4f(prog->chroma_color_location, chroma_color[0], chroma_color[1], chroma_color[2], chroma_color[3]); set_lambda(); } void compile_shader(void) { shader_program_key shader; int i; need_to_compile = 0; for( i = 0; i < number_of_programs; i++) { shader_program_key *program = &shader_programs[i]; if(program->color_combiner == color_combiner_key && program->alpha_combiner == alpha_combiner_key && program->texture0_combiner == texture0_combiner_key && program->texture1_combiner == texture1_combiner_key && program->texture0_combinera == texture0_combinera_key && program->texture1_combinera == texture1_combinera_key && program->fog_enabled == fog_enabled && program->chroma_enabled == chroma_enabled && program->dither_enabled == dither_enabled && program->three_point_filter0 == three_point_filter[0] && program->three_point_filter1 == three_point_filter[1]) { use_shader_program(program); update_uniforms(program); return; } } memset(&shader, 0, sizeof(shader)); shader.color_combiner = color_combiner_key; shader.alpha_combiner = alpha_combiner_key; shader.texture0_combiner = texture0_combiner_key; shader.texture1_combiner = texture1_combiner_key; shader.texture0_combinera = texture0_combinera_key; shader.texture1_combinera = texture1_combinera_key; shader.fog_enabled = fog_enabled; shader.chroma_enabled = chroma_enabled; shader.dither_enabled = dither_enabled; shader.three_point_filter0 = three_point_filter[0]; shader.three_point_filter1 = three_point_filter[1]; strcpy(fragment_shader, fragment_shader_header); if (dither_enabled) strcat(fragment_shader, fragment_shader_dither); strcat(fragment_shader, three_point_filter[0] ? fragment_shader_readtex0color_3point : fragment_shader_readtex0color); strcat(fragment_shader, three_point_filter[1] ? fragment_shader_readtex1color_3point : fragment_shader_readtex1color); strcat(fragment_shader, fragment_shader_texture0); strcat(fragment_shader, fragment_shader_texture1); strcat(fragment_shader, fragment_shader_color_combiner); strcat(fragment_shader, fragment_shader_alpha_combiner); if (fog_enabled) strcat(fragment_shader, fragment_shader_fog); if (chroma_enabled) { strcat(fragment_shader, fragment_shader_chroma); strcat(fragment_shader_texture1, "test_chroma(ctexture1); \n"); compile_chroma_shader(); } strcat(fragment_shader, fragment_shader_end); finish_shader_program_setup(&shader); update_uniforms(&shader); } void free_combiners(void) { if (shader_programs) { shader_program_key *s = shader_programs; while (number_of_programs--) glDeleteProgram(s->program_object); free(shader_programs); } if (fragment_shader) free(fragment_shader); shader_programs = NULL; current_shader = NULL; fragment_shader = NULL; number_of_programs = 0; } void set_copy_shader(void) { int texture0_location; int alphaRef_location; glUseProgram(program_object_default); texture0_location = glGetUniformLocation(program_object_default, "texture0"); glUniform1i(texture0_location, 0); alphaRef_location = glGetUniformLocation(program_object_default, "alphaRef"); if(alphaRef_location != -1) glUniform1f(alphaRef_location,alpha_test ? alpha_ref/255.0f : -1.0f); } void set_depth_shader(void) { } void set_lambda(void) { glUniform1f(current_shader->lambda_location, lambda); } void grConstantColorValue( uint32_t value ) { texture_env_color[0] = ((value >> 24) & 0xFF) / 255.0f; texture_env_color[1] = ((value >> 16) & 0xFF) / 255.0f; texture_env_color[2] = ((value >> 8) & 0xFF) / 255.0f; texture_env_color[3] = (value & 0xFF) / 255.0f; glUniform4f(current_shader->constant_color_location, texture_env_color[0], texture_env_color[1], texture_env_color[2], texture_env_color[3]); } static void writeGLSLColorOther(int other) { switch(other) { case GR_COMBINE_OTHER_ITERATED: strcat(fragment_shader_color_combiner, "vec4 color_other = gl_Color; \n"); break; case GR_COMBINE_OTHER_TEXTURE: strcat(fragment_shader_color_combiner, "vec4 color_other = ctexture1; \n"); break; case GR_COMBINE_OTHER_CONSTANT: strcat(fragment_shader_color_combiner, "vec4 color_other = constant_color; \n"); break; } } static void writeGLSLColorLocal(int local) { switch(local) { case GR_COMBINE_LOCAL_ITERATED: strcat(fragment_shader_color_combiner, "vec4 color_local = gl_Color; \n"); break; case GR_COMBINE_LOCAL_CONSTANT: strcat(fragment_shader_color_combiner, "vec4 color_local = constant_color; \n"); break; } } static void writeGLSLColorFactor(int factor, int local, int need_local, int other, int need_other) { switch(factor) { case GR_COMBINE_FACTOR_ZERO: strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(0.0); \n"); break; case GR_COMBINE_FACTOR_LOCAL: if(need_local) writeGLSLColorLocal(local); strcat(fragment_shader_color_combiner, "vec4 color_factor = color_local; \n"); break; case GR_COMBINE_FACTOR_OTHER_ALPHA: if(need_other) writeGLSLColorOther(other); strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(color_other.a); \n"); break; case GR_COMBINE_FACTOR_LOCAL_ALPHA: if(need_local) writeGLSLColorLocal(local); strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(color_local.a); \n"); break; case GR_COMBINE_FACTOR_TEXTURE_ALPHA: strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(ctexture1.a); \n"); break; case GR_COMBINE_FACTOR_TEXTURE_RGB: strcat(fragment_shader_color_combiner, "vec4 color_factor = ctexture1; \n"); break; case GR_COMBINE_FACTOR_ONE: strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(1.0); \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL: if(need_local) writeGLSLColorLocal(local); strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(1.0) - color_local; \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA: if(need_other) writeGLSLColorOther(other); strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(1.0) - vec4(color_other.a); \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA: if(need_local) writeGLSLColorLocal(local); strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(1.0) - vec4(color_local.a); \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA: strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(1.0) - vec4(ctexture1.a); \n"); break; } } void grColorCombine( int32_t function, int32_t factor, int32_t local, int32_t other, int32_t invert ) { static int last_function = 0; static int last_factor = 0; static int last_local = 0; static int last_other = 0; if(last_function == function && last_factor == factor && last_local == local && last_other == other && first_color == 0 && !c_combiner_ext) return; first_color = 0; c_combiner_ext = 0; last_function = function; last_factor = factor; last_local = local; last_other = other; color_combiner_key = function | (factor << 4) | (local << 8) | (other << 10); chroma_other_color = other; strcpy(fragment_shader_color_combiner, ""); switch(function) { case GR_COMBINE_FUNCTION_ZERO: strcat(fragment_shader_color_combiner, "gl_FragColor = vec4(0.0); \n"); break; case GR_COMBINE_FUNCTION_LOCAL: writeGLSLColorLocal(local); strcat(fragment_shader_color_combiner, "gl_FragColor = color_local; \n"); break; case GR_COMBINE_FUNCTION_LOCAL_ALPHA: writeGLSLColorLocal(local); strcat(fragment_shader_color_combiner, "gl_FragColor = vec4(color_local.a); \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER: writeGLSLColorOther(other); writeGLSLColorFactor(factor,local,1,other,0); strcat(fragment_shader_color_combiner, "gl_FragColor = color_factor * color_other; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL: writeGLSLColorLocal(local); writeGLSLColorOther(other); writeGLSLColorFactor(factor,local,0,other,0); strcat(fragment_shader_color_combiner, "gl_FragColor = color_factor * color_other + color_local; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA: writeGLSLColorLocal(local); writeGLSLColorOther(other); writeGLSLColorFactor(factor,local,0,other,0); strcat(fragment_shader_color_combiner, "gl_FragColor = color_factor * color_other + vec4(color_local.a); \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL: writeGLSLColorLocal(local); writeGLSLColorOther(other); writeGLSLColorFactor(factor,local,0,other,0); strcat(fragment_shader_color_combiner, "gl_FragColor = color_factor * (color_other - color_local); \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL: writeGLSLColorLocal(local); writeGLSLColorOther(other); writeGLSLColorFactor(factor,local,0,other,0); strcat(fragment_shader_color_combiner, "gl_FragColor = color_factor * (color_other - color_local) + color_local; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA: writeGLSLColorLocal(local); writeGLSLColorOther(other); writeGLSLColorFactor(factor,local,0,other,0); strcat(fragment_shader_color_combiner, "gl_FragColor = color_factor * (color_other - color_local) + vec4(color_local.a); \n"); break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL: writeGLSLColorLocal(local); writeGLSLColorFactor(factor,local,0,other,1); strcat(fragment_shader_color_combiner, "gl_FragColor = color_factor * (-color_local) + color_local; \n"); break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA: writeGLSLColorLocal(local); writeGLSLColorFactor(factor,local,0,other,1); strcat(fragment_shader_color_combiner, "gl_FragColor = color_factor * (-color_local) + vec4(color_local.a); \n"); break; default: strcpy(fragment_shader_color_combiner, fragment_shader_default); } need_to_compile = 1; } static void writeGLSLAlphaOther(int other) { switch(other) { case GR_COMBINE_OTHER_ITERATED: strcat(fragment_shader_alpha_combiner, "float alpha_other = gl_Color.a; \n"); break; case GR_COMBINE_OTHER_TEXTURE: strcat(fragment_shader_alpha_combiner, "float alpha_other = ctexture1.a; \n"); break; case GR_COMBINE_OTHER_CONSTANT: strcat(fragment_shader_alpha_combiner, "float alpha_other = constant_color.a; \n"); break; } } static void writeGLSLAlphaLocal(int local) { switch(local) { case GR_COMBINE_LOCAL_ITERATED: strcat(fragment_shader_alpha_combiner, "float alpha_local = gl_Color.a; \n"); break; case GR_COMBINE_LOCAL_CONSTANT: strcat(fragment_shader_alpha_combiner, "float alpha_local = constant_color.a; \n"); break; } } static void writeGLSLAlphaFactor(int factor, int local, int need_local, int other, int need_other) { switch(factor) { case GR_COMBINE_FACTOR_ZERO: strcat(fragment_shader_alpha_combiner, "float alpha_factor = 0.0; \n"); break; case GR_COMBINE_FACTOR_LOCAL: if(need_local) writeGLSLAlphaLocal(local); strcat(fragment_shader_alpha_combiner, "float alpha_factor = alpha_local; \n"); break; case GR_COMBINE_FACTOR_OTHER_ALPHA: if(need_other) writeGLSLAlphaOther(other); strcat(fragment_shader_alpha_combiner, "float alpha_factor = alpha_other; \n"); break; case GR_COMBINE_FACTOR_LOCAL_ALPHA: if(need_local) writeGLSLAlphaLocal(local); strcat(fragment_shader_alpha_combiner, "float alpha_factor = alpha_local; \n"); break; case GR_COMBINE_FACTOR_TEXTURE_ALPHA: strcat(fragment_shader_alpha_combiner, "float alpha_factor = ctexture1.a; \n"); break; case GR_COMBINE_FACTOR_ONE: strcat(fragment_shader_alpha_combiner, "float alpha_factor = 1.0; \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL: if(need_local) writeGLSLAlphaLocal(local); strcat(fragment_shader_alpha_combiner, "float alpha_factor = 1.0 - alpha_local; \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA: if(need_other) writeGLSLAlphaOther(other); strcat(fragment_shader_alpha_combiner, "float alpha_factor = 1.0 - alpha_other; \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA: if(need_local) writeGLSLAlphaLocal(local); strcat(fragment_shader_alpha_combiner, "float alpha_factor = 1.0 - alpha_local; \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA: strcat(fragment_shader_alpha_combiner, "float alpha_factor = 1.0 - ctexture1.a; \n"); break; } } void grAlphaCombine( int32_t function, int32_t factor, int32_t local, int32_t other, int32_t invert ) { static int last_function = 0; static int last_factor = 0; static int last_local = 0; static int last_other = 0; if(last_function == function && last_factor == factor && last_local == local && last_other == other && first_alpha == 0 && !a_combiner_ext) return; first_alpha = 0; a_combiner_ext = 0; last_function = function; last_factor = factor; last_local = local; last_other = other; alpha_combiner_key = function | (factor << 4) | (local << 8) | (other << 10); chroma_other_alpha = other; strcpy(fragment_shader_alpha_combiner, ""); switch(function) { case GR_COMBINE_FUNCTION_ZERO: strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = 0.0; \n"); break; case GR_COMBINE_FUNCTION_LOCAL: writeGLSLAlphaLocal(local); strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_local; \n"); break; case GR_COMBINE_FUNCTION_LOCAL_ALPHA: writeGLSLAlphaLocal(local); strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_local; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER: writeGLSLAlphaOther(other); writeGLSLAlphaFactor(factor,local,1,other,0); strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_factor * alpha_other; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL: writeGLSLAlphaLocal(local); writeGLSLAlphaOther(other); writeGLSLAlphaFactor(factor,local,0,other,0); strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_factor * alpha_other + alpha_local; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA: writeGLSLAlphaLocal(local); writeGLSLAlphaOther(other); writeGLSLAlphaFactor(factor,local,0,other,0); strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_factor * alpha_other + alpha_local; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL: writeGLSLAlphaLocal(local); writeGLSLAlphaOther(other); writeGLSLAlphaFactor(factor,local,0,other,0); strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_factor * (alpha_other - alpha_local); \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL: writeGLSLAlphaLocal(local); writeGLSLAlphaOther(other); writeGLSLAlphaFactor(factor,local,0,other,0); strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_factor * (alpha_other - alpha_local) + alpha_local; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA: writeGLSLAlphaLocal(local); writeGLSLAlphaOther(other); writeGLSLAlphaFactor(factor,local,0,other,0); strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_factor * (alpha_other - alpha_local) + alpha_local; \n"); break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL: writeGLSLAlphaLocal(local); writeGLSLAlphaFactor(factor,local,0,other,1); strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_factor * (-alpha_local) + alpha_local; \n"); break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA: writeGLSLAlphaLocal(local); writeGLSLAlphaFactor(factor,local,0,other,1); strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_factor * (-alpha_local) + alpha_local; \n"); break; } need_to_compile = 1; } static void writeGLSLTextureColorFactorTMU0(int num_tex, int factor) { switch(factor) { case GR_COMBINE_FACTOR_ZERO: strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(0.0); \n"); break; case GR_COMBINE_FACTOR_LOCAL: strcat(fragment_shader_texture0, "vec4 texture0_color_factor = readtex0; \n"); break; case GR_COMBINE_FACTOR_OTHER_ALPHA: strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(0.0); \n"); break; case GR_COMBINE_FACTOR_LOCAL_ALPHA: strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(readtex0.a); \n"); break; case GR_COMBINE_FACTOR_DETAIL_FACTOR: strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(lambda); \n"); break; case GR_COMBINE_FACTOR_ONE: strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(1.0); \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL: strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(1.0) - readtex0; \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA: strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(1.0) - vec4(0.0); \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA: strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(1.0) - vec4(readtex0.a); \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_DETAIL_FACTOR: strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(1.0) - vec4(lambda); \n"); break; } } static void writeGLSLTextureColorFactorTMU1(int num_tex, int factor) { switch(factor) { case GR_COMBINE_FACTOR_ZERO: strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(0.0); \n"); break; case GR_COMBINE_FACTOR_LOCAL: strcat(fragment_shader_texture1, "vec4 texture1_color_factor = readtex1; \n"); break; case GR_COMBINE_FACTOR_OTHER_ALPHA: strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(ctexture0.a); \n"); break; case GR_COMBINE_FACTOR_LOCAL_ALPHA: strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(readtex1.a); \n"); break; case GR_COMBINE_FACTOR_DETAIL_FACTOR: strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(lambda); \n"); break; case GR_COMBINE_FACTOR_ONE: strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(1.0); \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL: strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(1.0) - readtex1; \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA: strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(1.0) - vec4(ctexture0.a); \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA: strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(1.0) - vec4(readtex1.a); \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_DETAIL_FACTOR: strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(1.0) - vec4(lambda); \n"); break; } } static void writeGLSLTextureAlphaFactorTMU0(int num_tex, int factor) { switch(factor) { case GR_COMBINE_FACTOR_ZERO: strcat(fragment_shader_texture0, "float texture0_alpha_factor = 0.0; \n"); break; case GR_COMBINE_FACTOR_LOCAL: strcat(fragment_shader_texture0, "float texture0_alpha_factor = readtex0.a; \n"); break; case GR_COMBINE_FACTOR_OTHER_ALPHA: strcat(fragment_shader_texture0, "float texture0_alpha_factor = 0.0; \n"); break; case GR_COMBINE_FACTOR_LOCAL_ALPHA: strcat(fragment_shader_texture0, "float texture0_alpha_factor = readtex0.a; \n"); break; case GR_COMBINE_FACTOR_DETAIL_FACTOR: strcat(fragment_shader_texture0, "float texture0_alpha_factor = lambda; \n"); break; case GR_COMBINE_FACTOR_ONE: strcat(fragment_shader_texture0, "float texture0_alpha_factor = 1.0; \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL: strcat(fragment_shader_texture0, "float texture0_alpha_factor = 1.0 - readtex0.a; \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA: strcat(fragment_shader_texture0, "float texture0_alpha_factor = 1.0 - 0.0; \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA: strcat(fragment_shader_texture0, "float texture0_alpha_factor = 1.0 - readtex0.a; \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_DETAIL_FACTOR: strcat(fragment_shader_texture0, "float texture0_alpha_factor = 1.0 - lambda; \n"); break; } } static void writeGLSLTextureAlphaFactorTMU1(int num_tex, int factor) { switch(factor) { case GR_COMBINE_FACTOR_ZERO: strcat(fragment_shader_texture1, "float texture1_alpha_factor = 0.0; \n"); break; case GR_COMBINE_FACTOR_LOCAL: strcat(fragment_shader_texture1, "float texture1_alpha_factor = readtex1.a; \n"); break; case GR_COMBINE_FACTOR_OTHER_ALPHA: strcat(fragment_shader_texture1, "float texture1_alpha_factor = ctexture0.a; \n"); break; case GR_COMBINE_FACTOR_LOCAL_ALPHA: strcat(fragment_shader_texture1, "float texture1_alpha_factor = readtex1.a; \n"); break; case GR_COMBINE_FACTOR_DETAIL_FACTOR: strcat(fragment_shader_texture1, "float texture1_alpha_factor = lambda; \n"); break; case GR_COMBINE_FACTOR_ONE: strcat(fragment_shader_texture1, "float texture1_alpha_factor = 1.0; \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL: strcat(fragment_shader_texture1, "float texture1_alpha_factor = 1.0 - readtex1.a; \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA: strcat(fragment_shader_texture1, "float texture1_alpha_factor = 1.0 - ctexture0.a; \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA: strcat(fragment_shader_texture1, "float texture1_alpha_factor = 1.0 - readtex1.a; \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_DETAIL_FACTOR: strcat(fragment_shader_texture1, "float texture1_alpha_factor = 1.0 - lambda; \n"); break; } } void grTexCombine( int32_t tmu, int32_t rgb_function, int32_t rgb_factor, int32_t alpha_function, int32_t alpha_factor, int32_t rgb_invert, int32_t alpha_invert ) { int num_tex = 0; if (tmu == GR_TMU0) num_tex = 1; ccolor[tmu][0] = ccolor[tmu][1] = ccolor[tmu][2] = ccolor[tmu][3] = 0; if(num_tex == 0) { static int last_function = 0; static int last_factor = 0; static int last_afunction = 0; static int last_afactor = 0; static int last_rgb_invert = 0; if(last_function == rgb_function && last_factor == rgb_factor && last_afunction == alpha_function && last_afactor == alpha_factor && last_rgb_invert == rgb_invert && first_texture0 == 0 && !tex0_combiner_ext) return; first_texture0 = 0; tex0_combiner_ext = 0; last_function = rgb_function; last_factor = rgb_factor; last_afunction = alpha_function; last_afactor = alpha_factor; last_rgb_invert= rgb_invert; texture0_combiner_key = rgb_function | (rgb_factor << 4) | (alpha_function << 8) | (alpha_factor << 12) | (rgb_invert << 16); texture0_combinera_key = 0; strcpy(fragment_shader_texture0, ""); switch(rgb_function) { case GR_COMBINE_FUNCTION_ZERO: strcat(fragment_shader_texture0, "vec4 ctexture0 = vec4(0.0); \n"); break; case GR_COMBINE_FUNCTION_LOCAL: strcat(fragment_shader_texture0, "vec4 ctexture0 = readtex0; \n"); break; case GR_COMBINE_FUNCTION_LOCAL_ALPHA: strcat(fragment_shader_texture0, "vec4 ctexture0 = vec4(readtex0.a); \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER: writeGLSLTextureColorFactorTMU0(num_tex, rgb_factor); strcat(fragment_shader_texture0, "vec4 ctexture0 = texture0_color_factor * vec4(0.0); \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL: writeGLSLTextureColorFactorTMU0(num_tex, rgb_factor); strcat(fragment_shader_texture0, "vec4 ctexture0 = texture0_color_factor * vec4(0.0) + readtex0; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA: writeGLSLTextureColorFactorTMU0(num_tex, rgb_factor); strcat(fragment_shader_texture0, "vec4 ctexture0 = texture0_color_factor * vec4(0.0) + vec4(readtex0.a); \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL: writeGLSLTextureColorFactorTMU0(num_tex, rgb_factor); strcat(fragment_shader_texture0, "vec4 ctexture0 = texture0_color_factor * (vec4(0.0) - readtex0); \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL: writeGLSLTextureColorFactorTMU0(num_tex, rgb_factor); strcat(fragment_shader_texture0, "vec4 ctexture0 = texture0_color_factor * (vec4(0.0) - readtex0) + readtex0; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA: writeGLSLTextureColorFactorTMU0(num_tex, rgb_factor); strcat(fragment_shader_texture0, "vec4 ctexture0 = texture0_color_factor * (vec4(0.0) - readtex0) + vec4(readtex0.a); \n"); break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL: writeGLSLTextureColorFactorTMU0(num_tex, rgb_factor); strcat(fragment_shader_texture0, "vec4 ctexture0 = texture0_color_factor * (-readtex0) + readtex0; \n"); break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA: writeGLSLTextureColorFactorTMU0(num_tex, rgb_factor); strcat(fragment_shader_texture0, "vec4 ctexture0 = texture0_color_factor * (-readtex0) + vec4(readtex0.a); \n"); break; default: strcat(fragment_shader_texture0, "vec4 ctexture0 = readtex0; \n"); } if (rgb_invert) strcat(fragment_shader_texture0, "ctexture0 = vec4(1.0) - ctexture0; \n"); switch(alpha_function) { case GR_COMBINE_FACTOR_ZERO: strcat(fragment_shader_texture0, "ctexture0.a = 0.0; \n"); break; case GR_COMBINE_FUNCTION_LOCAL: strcat(fragment_shader_texture0, "ctexture0.a = readtex0.a; \n"); break; case GR_COMBINE_FUNCTION_LOCAL_ALPHA: strcat(fragment_shader_texture0, "ctexture0.a = readtex0.a; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER: writeGLSLTextureAlphaFactorTMU0(num_tex, alpha_factor); strcat(fragment_shader_texture0, "ctexture0.a = texture0_alpha_factor * 0.0; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL: writeGLSLTextureAlphaFactorTMU0(num_tex, alpha_factor); strcat(fragment_shader_texture0, "ctexture0.a = texture0_alpha_factor * 0.0 + readtex0.a; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA: writeGLSLTextureAlphaFactorTMU0(num_tex, alpha_factor); strcat(fragment_shader_texture0, "ctexture0.a = texture0_alpha_factor * 0.0 + readtex0.a; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL: writeGLSLTextureAlphaFactorTMU0(num_tex, alpha_factor); strcat(fragment_shader_texture0, "ctexture0.a = texture0_alpha_factor * (0.0 - readtex0.a); \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL: writeGLSLTextureAlphaFactorTMU0(num_tex, alpha_factor); strcat(fragment_shader_texture0, "ctexture0.a = texture0_alpha_factor * (0.0 - readtex0.a) + readtex0.a; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA: writeGLSLTextureAlphaFactorTMU0(num_tex, alpha_factor); strcat(fragment_shader_texture0, "ctexture0.a = texture0_alpha_factor * (0.0 - readtex0.a) + readtex0.a; \n"); break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL: writeGLSLTextureAlphaFactorTMU0(num_tex, alpha_factor); strcat(fragment_shader_texture0, "ctexture0.a = texture0_alpha_factor * (-readtex0.a) + readtex0.a; \n"); break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA: writeGLSLTextureAlphaFactorTMU0(num_tex, alpha_factor); strcat(fragment_shader_texture0, "ctexture0.a = texture0_alpha_factor * (-readtex0.a) + readtex0.a; \n"); break; default: strcat(fragment_shader_texture0, "ctexture0.a = readtex0.a; \n"); } if (alpha_invert) strcat(fragment_shader_texture0, "ctexture0.a = 1.0 - ctexture0.a; \n"); glUniform4f(current_shader->ccolor0_location, 0, 0, 0, 0); } else { static int last_function = 0; static int last_factor = 0; static int last_afunction = 0; static int last_afactor = 0; static int last_rgb_invert = 0; if(last_function == rgb_function && last_factor == rgb_factor && last_afunction == alpha_function && last_afactor == alpha_factor && last_rgb_invert == rgb_invert && first_texture1 == 0 && !tex1_combiner_ext) return; first_texture1 = 0; tex1_combiner_ext = 0; last_function = rgb_function; last_factor = rgb_factor; last_afunction = alpha_function; last_afactor = alpha_factor; last_rgb_invert = rgb_invert; texture1_combiner_key = rgb_function | (rgb_factor << 4) | (alpha_function << 8) | (alpha_factor << 12) | (rgb_invert << 16); texture1_combinera_key = 0; strcpy(fragment_shader_texture1, ""); switch(rgb_function) { case GR_COMBINE_FUNCTION_ZERO: strcat(fragment_shader_texture1, "vec4 ctexture1 = vec4(0.0); \n"); break; case GR_COMBINE_FUNCTION_LOCAL: strcat(fragment_shader_texture1, "vec4 ctexture1 = readtex1; \n"); break; case GR_COMBINE_FUNCTION_LOCAL_ALPHA: strcat(fragment_shader_texture1, "vec4 ctexture1 = vec4(readtex1.a); \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER: writeGLSLTextureColorFactorTMU1(num_tex, rgb_factor); strcat(fragment_shader_texture1, "vec4 ctexture1 = texture1_color_factor * ctexture0; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL: writeGLSLTextureColorFactorTMU1(num_tex, rgb_factor); strcat(fragment_shader_texture1, "vec4 ctexture1 = texture1_color_factor * ctexture0 + readtex1; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA: writeGLSLTextureColorFactorTMU1(num_tex, rgb_factor); strcat(fragment_shader_texture1, "vec4 ctexture1 = texture1_color_factor * ctexture0 + vec4(readtex1.a); \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL: writeGLSLTextureColorFactorTMU1(num_tex, rgb_factor); strcat(fragment_shader_texture1, "vec4 ctexture1 = texture1_color_factor * (ctexture0 - readtex1); \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL: writeGLSLTextureColorFactorTMU1(num_tex, rgb_factor); strcat(fragment_shader_texture1, "vec4 ctexture1 = texture1_color_factor * (ctexture0 - readtex1) + readtex1; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA: writeGLSLTextureColorFactorTMU1(num_tex, rgb_factor); strcat(fragment_shader_texture1, "vec4 ctexture1 = texture1_color_factor * (ctexture0 - readtex1) + vec4(readtex1.a); \n"); break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL: writeGLSLTextureColorFactorTMU1(num_tex, rgb_factor); strcat(fragment_shader_texture1, "vec4 ctexture1 = texture1_color_factor * (-readtex1) + readtex1; \n"); break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA: writeGLSLTextureColorFactorTMU1(num_tex, rgb_factor); strcat(fragment_shader_texture1, "vec4 ctexture1 = texture1_color_factor * (-readtex1) + vec4(readtex1.a); \n"); break; default: strcat(fragment_shader_texture1, "vec4 ctexture1 = readtex1; \n"); } if (rgb_invert) strcat(fragment_shader_texture1, "ctexture1 = vec4(1.0) - ctexture1; \n"); switch(alpha_function) { case GR_COMBINE_FACTOR_ZERO: strcat(fragment_shader_texture1, "ctexture1.a = 0.0; \n"); break; case GR_COMBINE_FUNCTION_LOCAL: strcat(fragment_shader_texture1, "ctexture1.a = readtex1.a; \n"); break; case GR_COMBINE_FUNCTION_LOCAL_ALPHA: strcat(fragment_shader_texture1, "ctexture1.a = readtex1.a; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER: writeGLSLTextureAlphaFactorTMU1(num_tex, alpha_factor); strcat(fragment_shader_texture1, "ctexture1.a = texture1_alpha_factor * ctexture0.a; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL: writeGLSLTextureAlphaFactorTMU1(num_tex, alpha_factor); strcat(fragment_shader_texture1, "ctexture1.a = texture1_alpha_factor * ctexture0.a + readtex1.a; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA: writeGLSLTextureAlphaFactorTMU1(num_tex, alpha_factor); strcat(fragment_shader_texture1, "ctexture1.a = texture1_alpha_factor * ctexture0.a + readtex1.a; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL: writeGLSLTextureAlphaFactorTMU1(num_tex, alpha_factor); strcat(fragment_shader_texture1, "ctexture1.a = texture1_alpha_factor * (ctexture0.a - readtex1.a); \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL: writeGLSLTextureAlphaFactorTMU1(num_tex, alpha_factor); strcat(fragment_shader_texture1, "ctexture1.a = texture1_alpha_factor * (ctexture0.a - readtex1.a) + readtex1.a; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA: writeGLSLTextureAlphaFactorTMU1(num_tex, alpha_factor); strcat(fragment_shader_texture1, "ctexture1.a = texture1_alpha_factor * (ctexture0.a - readtex1.a) + readtex1.a; \n"); break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL: writeGLSLTextureAlphaFactorTMU1(num_tex, alpha_factor); strcat(fragment_shader_texture1, "ctexture1.a = texture1_alpha_factor * (-readtex1.a) + readtex1.a; \n"); break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA: writeGLSLTextureAlphaFactorTMU1(num_tex, alpha_factor); strcat(fragment_shader_texture1, "ctexture1.a = texture1_alpha_factor * (-readtex1.a) + readtex1.a; \n"); break; default: strcat(fragment_shader_texture1, "ctexture1.a = ctexture0.a; \n"); } if (alpha_invert) strcat(fragment_shader_texture1, "ctexture1.a = 1.0 - ctexture1.a; \n"); glUniform4f(current_shader->ccolor1_location, 0, 0, 0, 0); } need_to_compile = 1; } void grAlphaTestReferenceValue(uint8_t value) { alpha_ref = value; } void grAlphaTestFunction( int32_t function, uint8_t value, int set_alpha_ref) { alpha_func = function; alpha_test = (function == GR_CMP_ALWAYS) ? false : true; alpha_ref = (set_alpha_ref) ? value : alpha_ref; } void grFogMode( int32_t mode, uint32_t fogcolor) { fog_enabled = mode; need_to_compile = 1; } // chroma void grChromakeyMode( int32_t mode ) { switch(mode) { case GR_CHROMAKEY_DISABLE: chroma_enabled = 0; break; case GR_CHROMAKEY_ENABLE: chroma_enabled = 1; break; } need_to_compile = 1; } void grChromakeyValue( uint32_t value ) { chroma_color[0] = ((value >> 24) & 0xFF) / 255.0f; chroma_color[1] = ((value >> 16) & 0xFF) / 255.0f; chroma_color[2] = ((value >> 8) & 0xFF) / 255.0f; chroma_color[3] = 1.0;//(value & 0xFF) / 255.0f; glUniform4f(current_shader->chroma_color_location, chroma_color[0], chroma_color[1], chroma_color[2], chroma_color[3]); } void grStipplePattern(uint32_t stipple) { } void grStippleMode( int32_t mode ) { switch(mode) { case GR_STIPPLE_DISABLE: dither_enabled = 0; break; case GR_STIPPLE_PATTERN: case GR_STIPPLE_ROTATE: dither_enabled = 1; break; } need_to_compile = 1; } void grColorCombineExt(uint32_t a, uint32_t a_mode, uint32_t b, uint32_t b_mode, uint32_t c, int32_t c_invert, uint32_t d, int32_t d_invert, uint32_t shift, int32_t invert) { color_combiner_key = 0x80000000 | (a & 0x1F) | ((a_mode & 3) << 5) | ((b & 0x1F) << 7) | ((b_mode & 3) << 12) | ((c & 0x1F) << 14) | ((c_invert & 1) << 19) | ((d & 0x1F) << 20) | ((d_invert & 1) << 25); c_combiner_ext = 1; strcpy(fragment_shader_color_combiner, ""); switch(a) { case GR_CMBX_ZERO: strcat(fragment_shader_color_combiner, "vec4 cs_a = vec4(0.0); \n"); break; case GR_CMBX_TEXTURE_ALPHA: strcat(fragment_shader_color_combiner, "vec4 cs_a = vec4(ctexture1.a); \n"); break; case GR_CMBX_CONSTANT_ALPHA: strcat(fragment_shader_color_combiner, "vec4 cs_a = vec4(constant_color.a); \n"); break; case GR_CMBX_CONSTANT_COLOR: strcat(fragment_shader_color_combiner, "vec4 cs_a = constant_color; \n"); break; case GR_CMBX_ITALPHA: strcat(fragment_shader_color_combiner, "vec4 cs_a = vec4(gl_Color.a); \n"); break; case GR_CMBX_ITRGB: strcat(fragment_shader_color_combiner, "vec4 cs_a = gl_Color; \n"); break; case GR_CMBX_TEXTURE_RGB: strcat(fragment_shader_color_combiner, "vec4 cs_a = ctexture1; \n"); break; default: strcat(fragment_shader_color_combiner, "vec4 cs_a = vec4(0.0); \n"); } switch(a_mode) { case GR_FUNC_MODE_ZERO: strcat(fragment_shader_color_combiner, "vec4 c_a = vec4(0.0); \n"); break; case GR_FUNC_MODE_X: strcat(fragment_shader_color_combiner, "vec4 c_a = cs_a; \n"); break; case GR_FUNC_MODE_ONE_MINUS_X: strcat(fragment_shader_color_combiner, "vec4 c_a = vec4(1.0) - cs_a; \n"); break; case GR_FUNC_MODE_NEGATIVE_X: strcat(fragment_shader_color_combiner, "vec4 c_a = -cs_a; \n"); break; default: strcat(fragment_shader_color_combiner, "vec4 c_a = vec4(0.0); \n"); } switch(b) { case GR_CMBX_ZERO: strcat(fragment_shader_color_combiner, "vec4 cs_b = vec4(0.0); \n"); break; case GR_CMBX_TEXTURE_ALPHA: strcat(fragment_shader_color_combiner, "vec4 cs_b = vec4(ctexture1.a); \n"); break; case GR_CMBX_CONSTANT_ALPHA: strcat(fragment_shader_color_combiner, "vec4 cs_b = vec4(constant_color.a); \n"); break; case GR_CMBX_CONSTANT_COLOR: strcat(fragment_shader_color_combiner, "vec4 cs_b = constant_color; \n"); break; case GR_CMBX_ITALPHA: strcat(fragment_shader_color_combiner, "vec4 cs_b = vec4(gl_Color.a); \n"); break; case GR_CMBX_ITRGB: strcat(fragment_shader_color_combiner, "vec4 cs_b = gl_Color; \n"); break; case GR_CMBX_TEXTURE_RGB: strcat(fragment_shader_color_combiner, "vec4 cs_b = ctexture1; \n"); break; default: strcat(fragment_shader_color_combiner, "vec4 cs_b = vec4(0.0); \n"); } switch(b_mode) { case GR_FUNC_MODE_ZERO: strcat(fragment_shader_color_combiner, "vec4 c_b = vec4(0.0); \n"); break; case GR_FUNC_MODE_X: strcat(fragment_shader_color_combiner, "vec4 c_b = cs_b; \n"); break; case GR_FUNC_MODE_ONE_MINUS_X: strcat(fragment_shader_color_combiner, "vec4 c_b = vec4(1.0) - cs_b; \n"); break; case GR_FUNC_MODE_NEGATIVE_X: strcat(fragment_shader_color_combiner, "vec4 c_b = -cs_b; \n"); break; default: strcat(fragment_shader_color_combiner, "vec4 c_b = vec4(0.0); \n"); } switch(c) { case GR_CMBX_ZERO: strcat(fragment_shader_color_combiner, "vec4 c_c = vec4(0.0); \n"); break; case GR_CMBX_TEXTURE_ALPHA: strcat(fragment_shader_color_combiner, "vec4 c_c = vec4(ctexture1.a); \n"); break; case GR_CMBX_ALOCAL: strcat(fragment_shader_color_combiner, "vec4 c_c = vec4(c_b.a); \n"); break; case GR_CMBX_AOTHER: strcat(fragment_shader_color_combiner, "vec4 c_c = vec4(c_a.a); \n"); break; case GR_CMBX_B: strcat(fragment_shader_color_combiner, "vec4 c_c = cs_b; \n"); break; case GR_CMBX_CONSTANT_ALPHA: strcat(fragment_shader_color_combiner, "vec4 c_c = vec4(constant_color.a); \n"); break; case GR_CMBX_CONSTANT_COLOR: strcat(fragment_shader_color_combiner, "vec4 c_c = constant_color; \n"); break; case GR_CMBX_ITALPHA: strcat(fragment_shader_color_combiner, "vec4 c_c = vec4(gl_Color.a); \n"); break; case GR_CMBX_ITRGB: strcat(fragment_shader_color_combiner, "vec4 c_c = gl_Color; \n"); break; case GR_CMBX_TEXTURE_RGB: strcat(fragment_shader_color_combiner, "vec4 c_c = ctexture1; \n"); break; default: strcat(fragment_shader_color_combiner, "vec4 c_c = vec4(0.0); \n"); } if(c_invert) strcat(fragment_shader_color_combiner, "c_c = vec4(1.0) - c_c; \n"); switch(d) { case GR_CMBX_ZERO: strcat(fragment_shader_color_combiner, "vec4 c_d = vec4(0.0); \n"); break; case GR_CMBX_ALOCAL: strcat(fragment_shader_color_combiner, "vec4 c_d = vec4(c_b.a); \n"); break; case GR_CMBX_B: strcat(fragment_shader_color_combiner, "vec4 c_d = cs_b; \n"); break; case GR_CMBX_TEXTURE_RGB: strcat(fragment_shader_color_combiner, "vec4 c_d = ctexture1; \n"); break; case GR_CMBX_ITRGB: strcat(fragment_shader_color_combiner, "vec4 c_d = gl_Color; \n"); break; default: strcat(fragment_shader_color_combiner, "vec4 c_d = vec4(0.0); \n"); } if(d_invert) strcat(fragment_shader_color_combiner, "c_d = vec4(1.0) - c_d; \n"); strcat(fragment_shader_color_combiner, "gl_FragColor = (c_a + c_b) * c_c + c_d; \n"); need_to_compile = 1; } void grAlphaCombineExt(uint32_t a, uint32_t a_mode, uint32_t b, uint32_t b_mode, uint32_t c, int32_t c_invert, uint32_t d, int32_t d_invert, uint32_t shift, int32_t invert) { alpha_combiner_key = 0x80000000 | (a & 0x1F) | ((a_mode & 3) << 5) | ((b & 0x1F) << 7) | ((b_mode & 3) << 12) | ((c & 0x1F) << 14) | ((c_invert & 1) << 19) | ((d & 0x1F) << 20) | ((d_invert & 1) << 25); a_combiner_ext = 1; strcpy(fragment_shader_alpha_combiner, ""); switch(a) { case GR_CMBX_ZERO: strcat(fragment_shader_alpha_combiner, "float as_a = 0.0; \n"); break; case GR_CMBX_TEXTURE_ALPHA: strcat(fragment_shader_alpha_combiner, "float as_a = ctexture1.a; \n"); break; case GR_CMBX_CONSTANT_ALPHA: strcat(fragment_shader_alpha_combiner, "float as_a = constant_color.a; \n"); break; case GR_CMBX_ITALPHA: strcat(fragment_shader_alpha_combiner, "float as_a = gl_Color.a; \n"); break; default: strcat(fragment_shader_alpha_combiner, "float as_a = 0.0; \n"); } switch(a_mode) { case GR_FUNC_MODE_ZERO: strcat(fragment_shader_alpha_combiner, "float a_a = 0.0; \n"); break; case GR_FUNC_MODE_X: strcat(fragment_shader_alpha_combiner, "float a_a = as_a; \n"); break; case GR_FUNC_MODE_ONE_MINUS_X: strcat(fragment_shader_alpha_combiner, "float a_a = 1.0 - as_a; \n"); break; case GR_FUNC_MODE_NEGATIVE_X: strcat(fragment_shader_alpha_combiner, "float a_a = -as_a; \n"); break; default: strcat(fragment_shader_alpha_combiner, "float a_a = 0.0; \n"); } switch(b) { case GR_CMBX_ZERO: strcat(fragment_shader_alpha_combiner, "float as_b = 0.0; \n"); break; case GR_CMBX_TEXTURE_ALPHA: strcat(fragment_shader_alpha_combiner, "float as_b = ctexture1.a; \n"); break; case GR_CMBX_CONSTANT_ALPHA: strcat(fragment_shader_alpha_combiner, "float as_b = constant_color.a; \n"); break; case GR_CMBX_ITALPHA: strcat(fragment_shader_alpha_combiner, "float as_b = gl_Color.a; \n"); break; default: strcat(fragment_shader_alpha_combiner, "float as_b = 0.0; \n"); } switch(b_mode) { case GR_FUNC_MODE_ZERO: strcat(fragment_shader_alpha_combiner, "float a_b = 0.0; \n"); break; case GR_FUNC_MODE_X: strcat(fragment_shader_alpha_combiner, "float a_b = as_b; \n"); break; case GR_FUNC_MODE_ONE_MINUS_X: strcat(fragment_shader_alpha_combiner, "float a_b = 1.0 - as_b; \n"); break; case GR_FUNC_MODE_NEGATIVE_X: strcat(fragment_shader_alpha_combiner, "float a_b = -as_b; \n"); break; default: strcat(fragment_shader_alpha_combiner, "float a_b = 0.0; \n"); } switch(c) { case GR_CMBX_ZERO: strcat(fragment_shader_alpha_combiner, "float a_c = 0.0; \n"); break; case GR_CMBX_TEXTURE_ALPHA: strcat(fragment_shader_alpha_combiner, "float a_c = ctexture1.a; \n"); break; case GR_CMBX_ALOCAL: strcat(fragment_shader_alpha_combiner, "float a_c = as_b; \n"); break; case GR_CMBX_AOTHER: strcat(fragment_shader_alpha_combiner, "float a_c = as_a; \n"); break; case GR_CMBX_B: strcat(fragment_shader_alpha_combiner, "float a_c = as_b; \n"); break; case GR_CMBX_CONSTANT_ALPHA: strcat(fragment_shader_alpha_combiner, "float a_c = constant_color.a; \n"); break; case GR_CMBX_ITALPHA: strcat(fragment_shader_alpha_combiner, "float a_c = gl_Color.a; \n"); break; default: strcat(fragment_shader_alpha_combiner, "float a_c = 0.0; \n"); } if(c_invert) strcat(fragment_shader_alpha_combiner, "a_c = 1.0 - a_c; \n"); switch(d) { case GR_CMBX_ZERO: strcat(fragment_shader_alpha_combiner, "float a_d = 0.0; \n"); break; case GR_CMBX_TEXTURE_ALPHA: strcat(fragment_shader_alpha_combiner, "float a_d = ctexture1.a; \n"); break; case GR_CMBX_ALOCAL: strcat(fragment_shader_alpha_combiner, "float a_d = as_b; \n"); break; case GR_CMBX_B: strcat(fragment_shader_alpha_combiner, "float a_d = as_b; \n"); break; default: strcat(fragment_shader_alpha_combiner, "float a_d = 0.0; \n"); } if(d_invert) strcat(fragment_shader_alpha_combiner, "a_d = 1.0 - a_d; \n"); strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = (a_a + a_b) * a_c + a_d; \n"); need_to_compile = 1; } void grTexColorCombineExt(int32_t tmu, uint32_t a, uint32_t a_mode, uint32_t b, uint32_t b_mode, uint32_t c, int32_t c_invert, uint32_t d, int32_t d_invert, uint32_t shift, int32_t invert) { int num_tex = 0; if (tmu == GR_TMU0) num_tex = 1; if(num_tex == 0) { texture0_combiner_key = 0x80000000 | (a & 0x1F) | ((a_mode & 3) << 5) | ((b & 0x1F) << 7) | ((b_mode & 3) << 12) | ((c & 0x1F) << 14) | ((c_invert & 1) << 19) | ((d & 0x1F) << 20) | ((d_invert & 1) << 25); tex0_combiner_ext = 1; strcpy(fragment_shader_texture0, ""); switch(a) { case GR_CMBX_ZERO: strcat(fragment_shader_texture0, "vec4 ctex0s_a = vec4(0.0); \n"); break; case GR_CMBX_ITALPHA: strcat(fragment_shader_texture0, "vec4 ctex0s_a = vec4(gl_Color.a); \n"); break; case GR_CMBX_ITRGB: strcat(fragment_shader_texture0, "vec4 ctex0s_a = gl_Color; \n"); break; case GR_CMBX_LOCAL_TEXTURE_ALPHA: strcat(fragment_shader_texture0, "vec4 ctex0s_a = vec4(readtex0.a); \n"); break; case GR_CMBX_LOCAL_TEXTURE_RGB: strcat(fragment_shader_texture0, "vec4 ctex0s_a = readtex0; \n"); break; case GR_CMBX_OTHER_TEXTURE_ALPHA: strcat(fragment_shader_texture0, "vec4 ctex0s_a = vec4(0.0); \n"); break; case GR_CMBX_OTHER_TEXTURE_RGB: strcat(fragment_shader_texture0, "vec4 ctex0s_a = vec4(0.0); \n"); break; case GR_CMBX_TMU_CCOLOR: strcat(fragment_shader_texture0, "vec4 ctex0s_a = ccolor0; \n"); break; case GR_CMBX_TMU_CALPHA: strcat(fragment_shader_texture0, "vec4 ctex0s_a = vec4(ccolor0.a); \n"); break; default: strcat(fragment_shader_texture0, "vec4 ctex0s_a = vec4(0.0); \n"); } switch(a_mode) { case GR_FUNC_MODE_ZERO: strcat(fragment_shader_texture0, "vec4 ctex0_a = vec4(0.0); \n"); break; case GR_FUNC_MODE_X: strcat(fragment_shader_texture0, "vec4 ctex0_a = ctex0s_a; \n"); break; case GR_FUNC_MODE_ONE_MINUS_X: strcat(fragment_shader_texture0, "vec4 ctex0_a = vec4(1.0) - ctex0s_a; \n"); break; case GR_FUNC_MODE_NEGATIVE_X: strcat(fragment_shader_texture0, "vec4 ctex0_a = -ctex0s_a; \n"); break; default: strcat(fragment_shader_texture0, "vec4 ctex0_a = vec4(0.0); \n"); } switch(b) { case GR_CMBX_ZERO: strcat(fragment_shader_texture0, "vec4 ctex0s_b = vec4(0.0); \n"); break; case GR_CMBX_ITALPHA: strcat(fragment_shader_texture0, "vec4 ctex0s_b = vec4(gl_Color.a); \n"); break; case GR_CMBX_ITRGB: strcat(fragment_shader_texture0, "vec4 ctex0s_b = gl_Color; \n"); break; case GR_CMBX_LOCAL_TEXTURE_ALPHA: strcat(fragment_shader_texture0, "vec4 ctex0s_b = vec4(readtex0.a); \n"); break; case GR_CMBX_LOCAL_TEXTURE_RGB: strcat(fragment_shader_texture0, "vec4 ctex0s_b = readtex0; \n"); break; case GR_CMBX_OTHER_TEXTURE_ALPHA: strcat(fragment_shader_texture0, "vec4 ctex0s_b = vec4(0.0); \n"); break; case GR_CMBX_OTHER_TEXTURE_RGB: strcat(fragment_shader_texture0, "vec4 ctex0s_b = vec4(0.0); \n"); break; case GR_CMBX_TMU_CALPHA: strcat(fragment_shader_texture0, "vec4 ctex0s_b = vec4(ccolor0.a); \n"); break; case GR_CMBX_TMU_CCOLOR: strcat(fragment_shader_texture0, "vec4 ctex0s_b = ccolor0; \n"); break; default: strcat(fragment_shader_texture0, "vec4 ctex0s_b = vec4(0.0); \n"); } switch(b_mode) { case GR_FUNC_MODE_ZERO: strcat(fragment_shader_texture0, "vec4 ctex0_b = vec4(0.0); \n"); break; case GR_FUNC_MODE_X: strcat(fragment_shader_texture0, "vec4 ctex0_b = ctex0s_b; \n"); break; case GR_FUNC_MODE_ONE_MINUS_X: strcat(fragment_shader_texture0, "vec4 ctex0_b = vec4(1.0) - ctex0s_b; \n"); break; case GR_FUNC_MODE_NEGATIVE_X: strcat(fragment_shader_texture0, "vec4 ctex0_b = -ctex0s_b; \n"); break; default: strcat(fragment_shader_texture0, "vec4 ctex0_b = vec4(0.0); \n"); } switch(c) { case GR_CMBX_ZERO: strcat(fragment_shader_texture0, "vec4 ctex0_c = vec4(0.0); \n"); break; case GR_CMBX_B: strcat(fragment_shader_texture0, "vec4 ctex0_c = ctex0s_b; \n"); break; case GR_CMBX_DETAIL_FACTOR: strcat(fragment_shader_texture0, "vec4 ctex0_c = vec4(lambda); \n"); break; case GR_CMBX_ITRGB: strcat(fragment_shader_texture0, "vec4 ctex0_c = gl_Color; \n"); break; case GR_CMBX_ITALPHA: strcat(fragment_shader_texture0, "vec4 ctex0_c = vec4(gl_Color.a); \n"); break; case GR_CMBX_LOCAL_TEXTURE_ALPHA: strcat(fragment_shader_texture0, "vec4 ctex0_c = vec4(readtex0.a); \n"); break; case GR_CMBX_LOCAL_TEXTURE_RGB: strcat(fragment_shader_texture0, "vec4 ctex0_c = readtex0; \n"); break; case GR_CMBX_OTHER_TEXTURE_ALPHA: strcat(fragment_shader_texture0, "vec4 ctex0_c = vec4(0.0); \n"); break; case GR_CMBX_OTHER_TEXTURE_RGB: strcat(fragment_shader_texture0, "vec4 ctex0_c = vec4(0.0); \n"); break; case GR_CMBX_TMU_CALPHA: strcat(fragment_shader_texture0, "vec4 ctex0_c = vec4(ccolor0.a); \n"); break; case GR_CMBX_TMU_CCOLOR: strcat(fragment_shader_texture0, "vec4 ctex0_c = ccolor0; \n"); break; default: strcat(fragment_shader_texture0, "vec4 ctex0_c = vec4(0.0); \n"); } if(c_invert) strcat(fragment_shader_texture0, "ctex0_c = vec4(1.0) - ctex0_c; \n"); switch(d) { case GR_CMBX_ZERO: strcat(fragment_shader_texture0, "vec4 ctex0_d = vec4(0.0); \n"); break; case GR_CMBX_B: strcat(fragment_shader_texture0, "vec4 ctex0_d = ctex0s_b; \n"); break; case GR_CMBX_ITRGB: strcat(fragment_shader_texture0, "vec4 ctex0_d = gl_Color; \n"); break; case GR_CMBX_LOCAL_TEXTURE_ALPHA: strcat(fragment_shader_texture0, "vec4 ctex0_d = vec4(readtex0.a); \n"); break; default: strcat(fragment_shader_texture0, "vec4 ctex0_d = vec4(0.0); \n"); } if(d_invert) strcat(fragment_shader_texture0, "ctex0_d = vec4(1.0) - ctex0_d; \n"); strcat(fragment_shader_texture0, "vec4 ctexture0 = (ctex0_a + ctex0_b) * ctex0_c + ctex0_d; \n"); } else { texture1_combiner_key = 0x80000000 | (a & 0x1F) | ((a_mode & 3) << 5) | ((b & 0x1F) << 7) | ((b_mode & 3) << 12) | ((c & 0x1F) << 14) | ((c_invert & 1) << 19) | ((d & 0x1F) << 20) | ((d_invert & 1) << 25); tex1_combiner_ext = 1; strcpy(fragment_shader_texture1, ""); switch(a) { case GR_CMBX_ZERO: strcat(fragment_shader_texture1, "vec4 ctex1s_a = vec4(0.0); \n"); break; case GR_CMBX_ITALPHA: strcat(fragment_shader_texture1, "vec4 ctex1s_a = vec4(gl_Color.a); \n"); break; case GR_CMBX_ITRGB: strcat(fragment_shader_texture1, "vec4 ctex1s_a = gl_Color; \n"); break; case GR_CMBX_LOCAL_TEXTURE_ALPHA: strcat(fragment_shader_texture1, "vec4 ctex1s_a = vec4(readtex1.a); \n"); break; case GR_CMBX_LOCAL_TEXTURE_RGB: strcat(fragment_shader_texture1, "vec4 ctex1s_a = readtex1; \n"); break; case GR_CMBX_OTHER_TEXTURE_ALPHA: strcat(fragment_shader_texture1, "vec4 ctex1s_a = vec4(ctexture0.a); \n"); break; case GR_CMBX_OTHER_TEXTURE_RGB: strcat(fragment_shader_texture1, "vec4 ctex1s_a = ctexture0; \n"); break; case GR_CMBX_TMU_CCOLOR: strcat(fragment_shader_texture1, "vec4 ctex1s_a = ccolor1; \n"); break; case GR_CMBX_TMU_CALPHA: strcat(fragment_shader_texture1, "vec4 ctex1s_a = vec4(ccolor1.a); \n"); break; default: strcat(fragment_shader_texture1, "vec4 ctex1s_a = vec4(0.0); \n"); } switch(a_mode) { case GR_FUNC_MODE_ZERO: strcat(fragment_shader_texture1, "vec4 ctex1_a = vec4(0.0); \n"); break; case GR_FUNC_MODE_X: strcat(fragment_shader_texture1, "vec4 ctex1_a = ctex1s_a; \n"); break; case GR_FUNC_MODE_ONE_MINUS_X: strcat(fragment_shader_texture1, "vec4 ctex1_a = vec4(1.0) - ctex1s_a; \n"); break; case GR_FUNC_MODE_NEGATIVE_X: strcat(fragment_shader_texture1, "vec4 ctex1_a = -ctex1s_a; \n"); break; default: strcat(fragment_shader_texture1, "vec4 ctex1_a = vec4(0.0); \n"); } switch(b) { case GR_CMBX_ZERO: strcat(fragment_shader_texture1, "vec4 ctex1s_b = vec4(0.0); \n"); break; case GR_CMBX_ITALPHA: strcat(fragment_shader_texture1, "vec4 ctex1s_b = vec4(gl_Color.a); \n"); break; case GR_CMBX_ITRGB: strcat(fragment_shader_texture1, "vec4 ctex1s_b = gl_Color; \n"); break; case GR_CMBX_LOCAL_TEXTURE_ALPHA: strcat(fragment_shader_texture1, "vec4 ctex1s_b = vec4(readtex1.a); \n"); break; case GR_CMBX_LOCAL_TEXTURE_RGB: strcat(fragment_shader_texture1, "vec4 ctex1s_b = readtex1; \n"); break; case GR_CMBX_OTHER_TEXTURE_ALPHA: strcat(fragment_shader_texture1, "vec4 ctex1s_b = vec4(ctexture0.a); \n"); break; case GR_CMBX_OTHER_TEXTURE_RGB: strcat(fragment_shader_texture1, "vec4 ctex1s_b = ctexture0; \n"); break; case GR_CMBX_TMU_CALPHA: strcat(fragment_shader_texture1, "vec4 ctex1s_b = vec4(ccolor1.a); \n"); break; case GR_CMBX_TMU_CCOLOR: strcat(fragment_shader_texture1, "vec4 ctex1s_b = ccolor1; \n"); break; default: strcat(fragment_shader_texture1, "vec4 ctex1s_b = vec4(0.0); \n"); } switch(b_mode) { case GR_FUNC_MODE_ZERO: strcat(fragment_shader_texture1, "vec4 ctex1_b = vec4(0.0); \n"); break; case GR_FUNC_MODE_X: strcat(fragment_shader_texture1, "vec4 ctex1_b = ctex1s_b; \n"); break; case GR_FUNC_MODE_ONE_MINUS_X: strcat(fragment_shader_texture1, "vec4 ctex1_b = vec4(1.0) - ctex1s_b; \n"); break; case GR_FUNC_MODE_NEGATIVE_X: strcat(fragment_shader_texture1, "vec4 ctex1_b = -ctex1s_b; \n"); break; default: strcat(fragment_shader_texture1, "vec4 ctex1_b = vec4(0.0); \n"); } switch(c) { case GR_CMBX_ZERO: strcat(fragment_shader_texture1, "vec4 ctex1_c = vec4(0.0); \n"); break; case GR_CMBX_B: strcat(fragment_shader_texture1, "vec4 ctex1_c = ctex1s_b; \n"); break; case GR_CMBX_DETAIL_FACTOR: strcat(fragment_shader_texture1, "vec4 ctex1_c = vec4(lambda); \n"); break; case GR_CMBX_ITRGB: strcat(fragment_shader_texture1, "vec4 ctex1_c = gl_Color; \n"); break; case GR_CMBX_ITALPHA: strcat(fragment_shader_texture1, "vec4 ctex1_c = vec4(gl_Color.a); \n"); break; case GR_CMBX_LOCAL_TEXTURE_ALPHA: strcat(fragment_shader_texture1, "vec4 ctex1_c = vec4(readtex1.a); \n"); break; case GR_CMBX_LOCAL_TEXTURE_RGB: strcat(fragment_shader_texture1, "vec4 ctex1_c = readtex1; \n"); break; case GR_CMBX_OTHER_TEXTURE_ALPHA: strcat(fragment_shader_texture1, "vec4 ctex1_c = vec4(ctexture0.a); \n"); break; case GR_CMBX_OTHER_TEXTURE_RGB: strcat(fragment_shader_texture1, "vec4 ctex1_c = ctexture0; \n"); break; case GR_CMBX_TMU_CALPHA: strcat(fragment_shader_texture1, "vec4 ctex1_c = vec4(ccolor1.a); \n"); break; case GR_CMBX_TMU_CCOLOR: strcat(fragment_shader_texture1, "vec4 ctex1_c = ccolor1; \n"); break; default: strcat(fragment_shader_texture1, "vec4 ctex1_c = vec4(0.0); \n"); } if(c_invert) strcat(fragment_shader_texture1, "ctex1_c = vec4(1.0) - ctex1_c; \n"); switch(d) { case GR_CMBX_ZERO: strcat(fragment_shader_texture1, "vec4 ctex1_d = vec4(0.0); \n"); break; case GR_CMBX_B: strcat(fragment_shader_texture1, "vec4 ctex1_d = ctex1s_b; \n"); break; case GR_CMBX_ITRGB: strcat(fragment_shader_texture1, "vec4 ctex1_d = gl_Color; \n"); break; case GR_CMBX_LOCAL_TEXTURE_ALPHA: strcat(fragment_shader_texture1, "vec4 ctex1_d = vec4(readtex1.a); \n"); break; default: strcat(fragment_shader_texture1, "vec4 ctex1_d = vec4(0.0); \n"); } if(d_invert) strcat(fragment_shader_texture1, "ctex1_d = vec4(1.0) - ctex1_d; \n"); strcat(fragment_shader_texture1, "vec4 ctexture1 = (ctex1_a + ctex1_b) * ctex1_c + ctex1_d; \n"); } need_to_compile = 1; } void grTexAlphaCombineExt(int32_t tmu, uint32_t a, uint32_t a_mode, uint32_t b, uint32_t b_mode, uint32_t c, int32_t c_invert, uint32_t d, int32_t d_invert, uint32_t shift, int32_t invert, uint32_t ccolor_value) { int num_tex = 0; if (tmu == GR_TMU0) num_tex = 1; ccolor[num_tex][0] = ((ccolor_value >> 24) & 0xFF) / 255.0f; ccolor[num_tex][1] = ((ccolor_value >> 16) & 0xFF) / 255.0f; ccolor[num_tex][2] = ((ccolor_value >> 8) & 0xFF) / 255.0f; ccolor[num_tex][3] = (ccolor_value & 0xFF) / 255.0f; if(num_tex == 0) { texture0_combinera_key = 0x80000000 | (a & 0x1F) | ((a_mode & 3) << 5) | ((b & 0x1F) << 7) | ((b_mode & 3) << 12) | ((c & 0x1F) << 14) | ((c_invert & 1) << 19) | ((d & 0x1F) << 20) | ((d_invert & 1) << 25); switch(a) { case GR_CMBX_ITALPHA: strcat(fragment_shader_texture0, "ctex0s_a.a = gl_Color.a; \n"); break; case GR_CMBX_LOCAL_TEXTURE_ALPHA: strcat(fragment_shader_texture0, "ctex0s_a.a = readtex0.a; \n"); break; case GR_CMBX_OTHER_TEXTURE_ALPHA: strcat(fragment_shader_texture0, "ctex0s_a.a = 0.0; \n"); break; case GR_CMBX_TMU_CALPHA: strcat(fragment_shader_texture0, "ctex0s_a.a = ccolor0.a; \n"); break; default: strcat(fragment_shader_texture0, "ctex0s_a.a = 0.0; \n"); } switch(a_mode) { case GR_FUNC_MODE_ZERO: strcat(fragment_shader_texture0, "ctex0_a.a = 0.0; \n"); break; case GR_FUNC_MODE_X: strcat(fragment_shader_texture0, "ctex0_a.a = ctex0s_a.a; \n"); break; case GR_FUNC_MODE_ONE_MINUS_X: strcat(fragment_shader_texture0, "ctex0_a.a = 1.0 - ctex0s_a.a; \n"); break; case GR_FUNC_MODE_NEGATIVE_X: strcat(fragment_shader_texture0, "ctex0_a.a = -ctex0s_a.a; \n"); break; default: strcat(fragment_shader_texture0, "ctex0_a.a = 0.0; \n"); } switch(b) { case GR_CMBX_ITALPHA: strcat(fragment_shader_texture0, "ctex0s_b.a = gl_Color.a; \n"); break; case GR_CMBX_LOCAL_TEXTURE_ALPHA: strcat(fragment_shader_texture0, "ctex0s_b.a = readtex0.a; \n"); break; case GR_CMBX_OTHER_TEXTURE_ALPHA: strcat(fragment_shader_texture0, "ctex0s_b.a = 0.0; \n"); break; case GR_CMBX_TMU_CALPHA: strcat(fragment_shader_texture0, "ctex0s_b.a = ccolor0.a; \n"); break; default: strcat(fragment_shader_texture0, "ctex0s_b.a = 0.0; \n"); } switch(b_mode) { case GR_FUNC_MODE_ZERO: strcat(fragment_shader_texture0, "ctex0_b.a = 0.0; \n"); break; case GR_FUNC_MODE_X: strcat(fragment_shader_texture0, "ctex0_b.a = ctex0s_b.a; \n"); break; case GR_FUNC_MODE_ONE_MINUS_X: strcat(fragment_shader_texture0, "ctex0_b.a = 1.0 - ctex0s_b.a; \n"); break; case GR_FUNC_MODE_NEGATIVE_X: strcat(fragment_shader_texture0, "ctex0_b.a = -ctex0s_b.a; \n"); break; default: strcat(fragment_shader_texture0, "ctex0_b.a = 0.0; \n"); } switch(c) { case GR_CMBX_ZERO: strcat(fragment_shader_texture0, "ctex0_c.a = 0.0; \n"); break; case GR_CMBX_B: strcat(fragment_shader_texture0, "ctex0_c.a = ctex0s_b.a; \n"); break; case GR_CMBX_DETAIL_FACTOR: strcat(fragment_shader_texture0, "ctex0_c.a = lambda; \n"); break; case GR_CMBX_ITALPHA: strcat(fragment_shader_texture0, "ctex0_c.a = gl_Color.a; \n"); break; case GR_CMBX_LOCAL_TEXTURE_ALPHA: strcat(fragment_shader_texture0, "ctex0_c.a = readtex0.a; \n"); break; case GR_CMBX_OTHER_TEXTURE_ALPHA: strcat(fragment_shader_texture0, "ctex0_c.a = 0.0; \n"); break; case GR_CMBX_TMU_CALPHA: strcat(fragment_shader_texture0, "ctex0_c.a = ccolor0.a; \n"); break; default: strcat(fragment_shader_texture0, "ctex0_c.a = 0.0; \n"); } switch(d) { case GR_CMBX_ZERO: strcat(fragment_shader_texture0, "ctex0_d.a = 0.0; \n"); break; case GR_CMBX_B: strcat(fragment_shader_texture0, "ctex0_d.a = ctex0s_b.a; \n"); break; case GR_CMBX_ITALPHA: strcat(fragment_shader_texture0, "ctex0_d.a = gl_Color.a; \n"); break; case GR_CMBX_ITRGB: strcat(fragment_shader_texture0, "ctex0_d.a = gl_Color.a; \n"); break; case GR_CMBX_LOCAL_TEXTURE_ALPHA: strcat(fragment_shader_texture0, "ctex0_d.a = readtex0.a; \n"); break; default: strcat(fragment_shader_texture0, "ctex0_d.a = 0.0; \n"); } if(c_invert) strcat(fragment_shader_texture0, "ctex0_c.a = 1.0 - ctex0_c.a; \n"); if(d_invert) strcat(fragment_shader_texture0, "ctex0_d.a = 1.0 - ctex0_d.a; \n"); strcat(fragment_shader_texture0, "ctexture0.a = (ctex0_a.a + ctex0_b.a) * ctex0_c.a + ctex0_d.a; \n"); glUniform4f(current_shader->ccolor0_location, ccolor[0][0], ccolor[0][1], ccolor[0][2], ccolor[0][3]); } else { texture1_combinera_key = 0x80000000 | (a & 0x1F) | ((a_mode & 3) << 5) | ((b & 0x1F) << 7) | ((b_mode & 3) << 12) | ((c & 0x1F) << 14) | ((c_invert & 1) << 19) | ((d & 0x1F) << 20) | ((d_invert & 1) << 25); switch(a) { case GR_CMBX_ITALPHA: strcat(fragment_shader_texture1, "ctex1s_a.a = gl_Color.a; \n"); break; case GR_CMBX_LOCAL_TEXTURE_ALPHA: strcat(fragment_shader_texture1, "ctex1s_a.a = readtex1.a; \n"); break; case GR_CMBX_OTHER_TEXTURE_ALPHA: strcat(fragment_shader_texture1, "ctex1s_a.a = ctexture0.a; \n"); break; case GR_CMBX_TMU_CALPHA: strcat(fragment_shader_texture1, "ctex1s_a.a = ccolor1.a; \n"); break; default: strcat(fragment_shader_texture1, "ctex1s_a.a = 0.0; \n"); } switch(a_mode) { case GR_FUNC_MODE_ZERO: strcat(fragment_shader_texture1, "ctex1_a.a = 0.0; \n"); break; case GR_FUNC_MODE_X: strcat(fragment_shader_texture1, "ctex1_a.a = ctex1s_a.a; \n"); break; case GR_FUNC_MODE_ONE_MINUS_X: strcat(fragment_shader_texture1, "ctex1_a.a = 1.0 - ctex1s_a.a; \n"); break; case GR_FUNC_MODE_NEGATIVE_X: strcat(fragment_shader_texture1, "ctex1_a.a = -ctex1s_a.a; \n"); break; default: strcat(fragment_shader_texture1, "ctex1_a.a = 0.0; \n"); } switch(b) { case GR_CMBX_ITALPHA: strcat(fragment_shader_texture1, "ctex1s_b.a = gl_Color.a; \n"); break; case GR_CMBX_LOCAL_TEXTURE_ALPHA: strcat(fragment_shader_texture1, "ctex1s_b.a = readtex1.a; \n"); break; case GR_CMBX_OTHER_TEXTURE_ALPHA: strcat(fragment_shader_texture1, "ctex1s_b.a = ctexture0.a; \n"); break; case GR_CMBX_TMU_CALPHA: strcat(fragment_shader_texture1, "ctex1s_b.a = ccolor1.a; \n"); break; default: strcat(fragment_shader_texture1, "ctex1s_b.a = 0.0; \n"); } switch(b_mode) { case GR_FUNC_MODE_ZERO: strcat(fragment_shader_texture1, "ctex1_b.a = 0.0; \n"); break; case GR_FUNC_MODE_X: strcat(fragment_shader_texture1, "ctex1_b.a = ctex1s_b.a; \n"); break; case GR_FUNC_MODE_ONE_MINUS_X: strcat(fragment_shader_texture1, "ctex1_b.a = 1.0 - ctex1s_b.a; \n"); break; case GR_FUNC_MODE_NEGATIVE_X: strcat(fragment_shader_texture1, "ctex1_b.a = -ctex1s_b.a; \n"); break; default: strcat(fragment_shader_texture1, "ctex1_b.a = 0.0; \n"); } switch(c) { case GR_CMBX_ZERO: strcat(fragment_shader_texture1, "ctex1_c.a = 0.0; \n"); break; case GR_CMBX_B: strcat(fragment_shader_texture1, "ctex1_c.a = ctex1s_b.a; \n"); break; case GR_CMBX_DETAIL_FACTOR: strcat(fragment_shader_texture1, "ctex1_c.a = lambda; \n"); break; case GR_CMBX_ITALPHA: strcat(fragment_shader_texture1, "ctex1_c.a = gl_Color.a; \n"); break; case GR_CMBX_LOCAL_TEXTURE_ALPHA: strcat(fragment_shader_texture1, "ctex1_c.a = readtex1.a; \n"); break; case GR_CMBX_OTHER_TEXTURE_ALPHA: strcat(fragment_shader_texture1, "ctex1_c.a = ctexture0.a; \n"); break; case GR_CMBX_TMU_CALPHA: strcat(fragment_shader_texture1, "ctex1_c.a = ccolor1.a; \n"); break; default: strcat(fragment_shader_texture1, "ctex1_c.a = 0.0; \n"); } switch(d) { case GR_CMBX_ZERO: strcat(fragment_shader_texture1, "ctex1_d.a = 0.0; \n"); break; case GR_CMBX_B: strcat(fragment_shader_texture1, "ctex1_d.a = ctex1s_b.a; \n"); break; case GR_CMBX_ITALPHA: strcat(fragment_shader_texture1, "ctex1_d.a = gl_Color.a; \n"); break; case GR_CMBX_ITRGB: strcat(fragment_shader_texture1, "ctex1_d.a = gl_Color.a; \n"); break; case GR_CMBX_LOCAL_TEXTURE_ALPHA: strcat(fragment_shader_texture1, "ctex1_d.a = readtex1.a; \n"); break; default: strcat(fragment_shader_texture1, "ctex1_d.a = 0.0; \n"); } if(c_invert) strcat(fragment_shader_texture1, "ctex1_c.a = 1.0 - ctex1_c.a; \n"); if(d_invert) strcat(fragment_shader_texture1, "ctex1_d.a = 1.0 - ctex1_d.a; \n"); strcat(fragment_shader_texture1, "ctexture1.a = (ctex1_a.a + ctex1_b.a) * ctex1_c.a + ctex1_d.a; \n"); glUniform4f(current_shader->ccolor1_location, ccolor[1][0], ccolor[1][1], ccolor[1][2], ccolor[1][3]); } need_to_compile = 1; } void grAlphaBlendFunction(GLenum rgb_sf, GLenum rgb_df, GLenum alpha_sf, GLenum alpha_df) { glEnable(GL_BLEND); glBlendFuncSeparate(rgb_sf, rgb_df, alpha_sf, alpha_df); } mupen64plus-video-gliden64/src/F3DPD.cpp000664 001750 001750 00000004066 12655644434 020740 0ustar00sergiosergio000000 000000 #include "GLideN64.h" #include "Debug.h" #include "F3D.h" #include "F3DPD.h" #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gSP.h" #include "gDP.h" #include "GBI.h" void F3DPD_Vtx( u32 w0, u32 w1 ) { gSPCIVertex( w1, _SHIFTR( w0, 20, 4 ) + 1, _SHIFTR( w0, 16, 4 ) ); } void F3DPD_VtxColorBase( u32 w0, u32 w1 ) { gSPSetVertexColorBase( w1 ); } void F3DPD_Init() { gSPSetupFunctions(); // Set GeometryMode flags GBI_InitFlags( F3D ); GBI.PCStackSize = 10; // GBI Command Command Value Command Function GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_MTX, F3D_MTX, F3D_Mtx ); GBI_SetGBI( G_RESERVED0, F3D_RESERVED0, F3D_Reserved0 ); GBI_SetGBI( G_MOVEMEM, F3D_MOVEMEM, F3D_MoveMem ); GBI_SetGBI( G_VTX, F3D_VTX, F3DPD_Vtx ); GBI_SetGBI( G_RESERVED1, F3D_RESERVED1, F3D_Reserved1 ); GBI_SetGBI( G_DL, F3D_DL, F3D_DList ); GBI_SetGBI( G_VTXCOLORBASE, F3DPD_VTXCOLORBASE, F3DPD_VtxColorBase ); GBI_SetGBI( G_RESERVED3, F3D_RESERVED3, F3D_Reserved3 ); GBI_SetGBI( G_SPRITE2D_BASE, F3D_SPRITE2D_BASE, F3D_Sprite2D_Base ); GBI_SetGBI( G_TRI1, F3D_TRI1, F3D_Tri1 ); GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3D_CullDL ); GBI_SetGBI( G_POPMTX, F3D_POPMTX, F3D_PopMtx ); GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3D_MoveWord ); GBI_SetGBI( G_TEXTURE, F3D_TEXTURE, F3D_Texture ); GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L ); GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL ); GBI_SetGBI( G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, F3D_SetGeometryMode ); GBI_SetGBI( G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE, F3D_ClearGeometryMode ); GBI_SetGBI( G_QUAD, F3D_QUAD, F3D_Quad ); GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_RDPHALF_CONT, F3D_RDPHALF_CONT, F3D_RDPHalf_Cont ); GBI_SetGBI( G_TRI4, F3D_TRI4, F3D_Tri4 ); gSPSetDMAOffsets( 0, 0 ); } glide2gl/src/Glide64/ucode07.h000664 001750 001750 00000011411 12655644434 017012 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** // // Oct 2002 Created by Gonetz (Gonetz@ngs.ru) // Info about this ucode is taken from TR64 OGL plugin. Thanks, Icepir8! // Oct 2003 Modified by Gonetz (Gonetz@ngs.ru) // Bugs fixed with help from glN64 sources. Thanks, Orkin! //**************************************************************** uint32_t pd_col_addr = 0; static void uc7_colorbase(uint32_t w0, uint32_t w1) { pd_col_addr = RSP_SegmentToPhysical(w1); } typedef struct { int16_t y; int16_t x; uint16_t idx; int16_t z; int16_t t; int16_t s; } vtx_uc7; static void uc7_vertex(uint32_t w0, uint32_t w1) { unsigned int i; uint32_t v0 = (w0 & 0x0F0000) >> 16; uint32_t n = ((w0 & 0xF00000) >> 20) + 1; uint32_t addr = RSP_SegmentToPhysical(w1); vtx_uc7 *vertex = (vtx_uc7*)&gfx_info.RDRAM[addr]; uint32_t iter = 1; pre_update(); for (i = 0; i < (n * iter); i += iter) { VERTEX *vert = (VERTEX*)&rdp.vtx[v0 + (i / iter)]; uint8_t *color = (uint8_t*)&gfx_info.RDRAM[pd_col_addr + (vertex->idx & 0xff)]; float x = (float)vertex->x; float y = (float)vertex->y; float z = (float)vertex->z; vert->flags = 0; vert->ou = (float)vertex->s; vert->ov = (float)vertex->t; vert->uv_scaled = 0; vert->a = color[0]; vert->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0]; vert->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1]; vert->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2]; vert->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3]; vert->uv_calculated = 0xFFFFFFFF; vert->screen_translated = 0; if (fabs(vert->w) < 0.001) vert->w = 0.001f; vert->oow = 1.0f / vert->w; vert->x_w = vert->x * vert->oow; vert->y_w = vert->y * vert->oow; vert->z_w = vert->z * vert->oow; CalculateFog (vert); vert->scr_off = 0; if (vert->x < -vert->w) vert->scr_off |= 1; if (vert->x > vert->w) vert->scr_off |= 2; if (vert->y < -vert->w) vert->scr_off |= 4; if (vert->y > vert->w) vert->scr_off |= 8; if (vert->w < 0.1f) vert->scr_off |= 16; #if 0 if (vert->z_w > 1.0f) vert->scr_off |= 32; #endif if (rdp.geom_mode & G_LIGHTING) { vert->vec[0] = (int8_t)color[3]; vert->vec[1] = (int8_t)color[2]; vert->vec[2] = (int8_t)color[1]; if (rdp.geom_mode & G_TEXTURE_GEN_LINEAR) calc_linear(vert); else if (rdp.geom_mode & G_TEXTURE_GEN) calc_sphere(vert); NormalizeVector (vert->vec); calc_light (vert); } else { vert->r = color[3]; vert->g = color[2]; vert->b = color[1]; } vertex++; } } gles2rice/src/RenderBase.h000664 001750 001750 00000024576 12655644434 016566 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _RICE_RENDER_BASE_H #define _RICE_RENDER_BASE_H #include "osal_preproc.h" #include "Debugger.h" #include "RSP_Parser.h" #include "Video.h" /* * Global variables defined in this file were moved out of Render class * to make them be accessed faster */ #define RICE_MATRIX_STACK 60 #define MAX_TEXTURES 8 enum FillMode { RICE_FILLMODE_WINFRAME, RICE_FILLMODE_SOLID, }; enum { MAX_VERTS = 80 }; // F3DLP.Rej supports up to 80 verts! void myVec3Transform(float *vecout, float *vecin, float* m); // All these arrays are moved out of the class CRender // to be accessed in faster speed extern ALIGN(16, XVECTOR4 g_vtxTransformed[MAX_VERTS]); extern ALIGN(16, XVECTOR4 g_vecProjected[MAX_VERTS]); extern float g_vtxProjected5[1000][5]; extern float g_vtxProjected5Clipped[2000][5]; extern VECTOR2 g_fVtxTxtCoords[MAX_VERTS]; extern uint32_t g_dwVtxDifColor[MAX_VERTS]; //extern uint32_t g_dwVtxFlags[MAX_VERTS]; // Z_POS Z_NEG etc extern RenderTexture g_textures[MAX_TEXTURES]; extern TLITVERTEX g_vtxBuffer[1000]; extern unsigned short g_vtxIndex[1000]; extern TLITVERTEX g_clippedVtxBuffer[2000]; extern int g_clippedVtxCount; extern uint8_t g_oglVtxColors[1000][4]; extern uint32_t g_clipFlag[MAX_VERTS]; extern uint32_t g_clipFlag2[MAX_VERTS]; extern float g_fFogCoord[MAX_VERTS]; extern TLITVERTEX g_texRectTVtx[4]; extern EXTERNAL_VERTEX g_vtxForExternal[MAX_VERTS]; //#define INIT_VERTEX_METHOD_2 /* * Global variables */ /************************************************************************/ /* Don't move */ /************************************************************************/ extern uint32_t gRSPnumLights; extern Light gRSPlights[16]; extern ALIGN(16, Matrix gRSPworldProjectTransported); extern ALIGN(16, Matrix gRSPworldProject); extern N64Light gRSPn64lights[16]; extern ALIGN(16, Matrix gRSPmodelViewTop); extern ALIGN(16, Matrix gRSPmodelViewTopTranspose); extern float gRSPfFogMin; extern float gRSPfFogMax; extern float gRSPfFogDivider; /************************************************************************/ /* Don't move */ /************************************************************************/ typedef struct { /************************************************************************/ /* Don't move */ /************************************************************************/ union { struct { float fAmbientLightR; float fAmbientLightG; float fAmbientLightB; float fAmbientLightA; }; float fAmbientColors[4]; }; /************************************************************************/ /* Don't move above */ /************************************************************************/ bool bTextureEnabled; uint32_t curTile; float fTexScaleX; float fTexScaleY; RenderShadeMode shadeMode; bool bCullFront; bool bCullBack; bool bLightingEnable; bool bTextureGen; bool bFogEnabled; bool bZBufferEnabled; uint32_t ambientLightColor; uint32_t ambientLightIndex; uint32_t projectionMtxTop; uint32_t modelViewMtxTop; uint32_t numVertices; uint32_t maxVertexID; int nVPLeftN, nVPTopN, nVPRightN, nVPBottomN, nVPWidthN, nVPHeightN, maxZ; int clip_ratio_negx, clip_ratio_negy, clip_ratio_posx, clip_ratio_posy; int clip_ratio_left, clip_ratio_top, clip_ratio_right, clip_ratio_bottom; int real_clip_scissor_left, real_clip_scissor_top, real_clip_scissor_right, real_clip_scissor_bottom; float real_clip_ratio_negx, real_clip_ratio_negy, real_clip_ratio_posx, real_clip_ratio_posy; Matrix projectionMtxs[RICE_MATRIX_STACK]; Matrix modelviewMtxs[RICE_MATRIX_STACK]; bool bWorldMatrixIsUpdated; bool bMatrixIsUpdated; bool bCombinedMatrixIsUpdated; bool bLightIsUpdated; uint32_t segments[16]; int DKRCMatrixIndex; int DKRVtxCount; bool DKRBillBoard; uint32_t dwDKRVtxAddr; uint32_t dwDKRMatrixAddr; Matrix DKRMatrixes[4]; XVECTOR4 DKRBaseVec; int ucode; int vertexMult; bool bNearClip; bool bRejectVtx; bool bProcessDiffuseColor; bool bProcessSpecularColor; float vtxXMul; float vtxXAdd; float vtxYMul; float vtxYAdd; // Texture coordinates computation constants float tex0scaleX; float tex0scaleY; float tex1scaleX; float tex1scaleY; float tex0OffsetX; float tex0OffsetY; float tex1OffsetX; float tex1OffsetY; float texGenYRatio; float texGenXRatio; } RSP_Options; extern ALIGN(16, RSP_Options gRSP); typedef struct { uint32_t keyR; uint32_t keyG; uint32_t keyB; uint32_t keyA; uint32_t keyRGB; uint32_t keyRGBA; float fKeyA; bool bFogEnableInBlender; uint32_t fogColor; uint32_t primitiveColor; uint32_t envColor; uint32_t primitiveDepth; uint32_t primLODMin; uint32_t primLODFrac; uint32_t LODFrac; float fPrimitiveDepth; float fvFogColor[4]; float fvPrimitiveColor[4]; float fvEnvColor[4]; uint32_t fillColor; uint32_t originalFillColor; uint32_t geometryMode; uint32_t otherModeL; uint32_t otherModeH; RDP_OtherMode otherMode; Tile tiles[8]; ScissorType scissor; bool textureIsChanged; bool texturesAreReloaded; bool colorsAreReloaded; } RDP_Options; extern ALIGN(16, RDP_Options gRDP); /* * Global functions */ void InitRenderBase(); void SetFogMinMax(float fMin, float fMax, float fMul, float fOffset); void InitVertex(uint32_t dwV, uint32_t vtxIndex, bool bTexture); void InitVertexTextureConstants(); bool PrepareTriangle(uint32_t dwV0, uint32_t dwV1, uint32_t dwV2); bool IsTriangleVisible(uint32_t dwV0, uint32_t dwV1, uint32_t dwV2); extern void (*ProcessVertexData)(uint32_t dwAddr, uint32_t dwV0, uint32_t dwNum); void ProcessVertexDataNoSSE(uint32_t dwAddr, uint32_t dwV0, uint32_t dwNum); void ProcessVertexDataNEON(uint32_t dwAddr, uint32_t dwV0, uint32_t dwNum); void ProcessVertexDataExternal(uint32_t dwAddr, uint32_t dwV0, uint32_t dwNum); void SetPrimitiveColor(uint32_t dwCol, uint32_t LODMin, uint32_t LODFrac); void SetPrimitiveDepth(uint32_t z, uint32_t dwDZ); void SetVertexXYZ(uint32_t vertex, float x, float y, float z); void ModifyVertexInfo(uint32_t where, uint32_t vertex, uint32_t val); void ProcessVertexDataDKR(uint32_t dwAddr, uint32_t dwV0, uint32_t dwNum); void SetLightCol(uint32_t dwLight, uint32_t dwCol); void SetLightDirection(uint32_t dwLight, float x, float y, float z, float range); void ForceMainTextureIndex(int dwTile); void UpdateCombinedMatrix(); void ClipVertexes(); void ClipVertexesOpenGL(); void ClipVertexesForRect(); void LogTextureCoords(float fTex0S, float fTex0T, float fTex1S, float fTex1T); bool CheckTextureCoords(int tex); void ResetTextureCoordsLog(float maxs0, float maxt0, float maxs1, float maxt1); inline float ViewPortTranslatef_x(float x) { return ( (x+1) * windowSetting.vpWidthW/2) + windowSetting.vpLeftW; } inline float ViewPortTranslatef_y(float y) { return ( (1-y) * windowSetting.vpHeightW/2) + windowSetting.vpTopW; } inline float ViewPortTranslatei_x(int x) { return x*windowSetting.fMultX; } inline float ViewPortTranslatei_y(int y) { return y*windowSetting.fMultY; } inline float ViewPortTranslatei_x(float x) { return x*windowSetting.fMultX; } inline float ViewPortTranslatei_y(float y) { return y*windowSetting.fMultY; } inline float GetPrimitiveDepth() { return gRDP.fPrimitiveDepth; } inline uint32_t GetPrimitiveColor() { return gRDP.primitiveColor; } inline float* GetPrimitiveColorfv() { return gRDP.fvPrimitiveColor; } inline uint32_t GetLODFrac() { return gRDP.LODFrac; } inline void SetEnvColor(uint32_t dwCol) { gRDP.colorsAreReloaded = true; gRDP.envColor = dwCol; gRDP.fvEnvColor[0] = ((dwCol>>16)&0xFF)/255.0f; // R gRDP.fvEnvColor[1] = ((dwCol>>8)&0xFF)/255.0f; // G gRDP.fvEnvColor[2] = ((dwCol)&0xFF)/255.0f; // B gRDP.fvEnvColor[3] = ((dwCol>>24)&0xFF)/255.0f; // A } inline uint32_t GetEnvColor() { return gRDP.envColor; } inline float* GetEnvColorfv() { return gRDP.fvEnvColor; } inline void SetAmbientLight(uint32_t color) { gRSP.ambientLightColor = color; gRSP.fAmbientLightR = (float)RGBA_GETRED(gRSP.ambientLightColor); gRSP.fAmbientLightG = (float)RGBA_GETGREEN(gRSP.ambientLightColor); gRSP.fAmbientLightB = (float)RGBA_GETBLUE(gRSP.ambientLightColor); LIGHT_DUMP(TRACE1("Set Ambient Light: %08X", color)); } inline void SetLighting(bool bLighting) { gRSP.bLightingEnable = bLighting; } // Generate texture coords? inline void SetTextureGen(bool bTextureGen) { gRSP.bTextureGen = bTextureGen; } inline void SetNumLights(uint32_t dwNumLights) { gRSPnumLights = dwNumLights; DEBUGGER_PAUSE_AND_DUMP(NEXT_SET_LIGHT,TRACE1("Set Number Of Lights: %d", dwNumLights)); } inline uint32_t GetNumLights() { return gRSPnumLights; } inline COLOR GetVertexDiffuseColor(uint32_t ver) { return g_dwVtxDifColor[ver]; } inline void SetScreenMult(float fMultX, float fMultY) { windowSetting.fMultX = fMultX; windowSetting.fMultY = fMultY; } inline COLOR GetLightCol(uint32_t dwLight) { return gRSPlights[dwLight].col; } #endif glide2gl/src/000700 001750 001750 00000000000 12656647145 014166 5ustar00sergiosergio000000 000000 gles2n64/src/S2DEX2.h000664 001750 001750 00000001153 12655644434 015132 0ustar00sergiosergio000000 000000 #ifndef S2DEX2_H #define S2DEX2_H #ifdef __cplusplus extern "C" { #endif void S2DEX2_Init(void); #define S2DEX2_OBJ_RECTANGLE_R 0xDA #define S2DEX2_OBJ_MOVEMEM 0xDC #define S2DEX2_RDPHALF_0 0xE4 #define S2DEX2_OBJ_RECTANGLE 0x01 #define S2DEX2_OBJ_SPRITE 0x02 #define S2DEX2_SELECT_DL 0x04 #define S2DEX2_OBJ_LOADTXTR 0x05 #define S2DEX2_OBJ_LDTX_SPRITE 0x06 #define S2DEX2_OBJ_LDTX_RECT 0x07 #define S2DEX2_OBJ_LDTX_RECT_R 0x08 #define S2DEX2_BG_1CYC 0x09 #define S2DEX2_BG_COPY 0x0A #define S2DEX2_OBJ_RENDERMODE 0x0B #ifdef __cplusplus } #endif #endif mupen64plus-rsp-cxd4/vu/clamp.h000664 001750 001750 00000003724 12655644434 017470 0ustar00sergiosergio000000 000000 /******************************************************************************\ * Authors: Iconoclast * * Release: 2013.10.07 * * License: CC0 Public Domain Dedication * * * * To the extent possible under law, the author(s) have dedicated all copyright * * and related and neighboring rights to this software to the public domain * * worldwide. This software is distributed without any warranty. * * * * You should have received a copy of the CC0 Public Domain Dedication along * * with this software. * * If not, see . * \******************************************************************************/ #ifndef _CLAMP_H #define _CLAMP_H extern short co[N]; #ifdef ARCH_MIN_SSE2 /* * We actually need to write explicit SSE2 code for this because GCC 4.8.1 * (and possibly later versions) has a code generation bug with vectorizing * the accumulator when it's a signed short (but not when it's unsigned, for * some stupid and buggy reason). * * In addition, as of the more stable GCC 4.7.2 release, while vectorizing * the accumulator write-backs into SSE2 for me is successfully done, we save * just one extra scalar x86 instruction for every RSP vector op-code when we * use SSE2 explicitly for this particular goal instead of letting GCC do it. */ static INLINE void vector_copy(short* VD, short* VS) { __m128i xmm = _mm_load_si128((__m128i *)VS); _mm_store_si128((__m128i *)VD, xmm); } #else static INLINE void vector_copy(short* VD, short* VS) { register int i; for (i = 0; i < N; i++) VD[i] = VS[i]; } #endif #endif mupen64plus-video-gliden64/src/GLideNHQ/TxFilter.cpp000664 001750 001750 00000046262 12655644434 023240 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef __MSC__ #pragma warning(disable: 4786) #endif #include #include #include #include #include "TxFilter.h" #include "TextureFilters.h" #include "TxDbg.h" #include "bldno.h" void TxFilter::clear() { /* clear hires texture cache */ delete _txHiResCache; /* clear texture cache */ delete _txTexCache; /* free memory */ TxMemBuf::getInstance()->shutdown(); /* clear other stuff */ delete _txImage; delete _txQuantize; delete _txUtil; } TxFilter::~TxFilter() { clear(); } TxFilter::TxFilter(int maxwidth, int maxheight, int maxbpp, int options, int cachesize, const wchar_t * path, const wchar_t * texPackPath, const wchar_t * ident, dispInfoFuncExt callback) : _tex1(NULL), _tex2(NULL), _txQuantize(NULL), _txTexCache(NULL), _txHiResCache(NULL), _txUtil(NULL), _txImage(NULL) { /* HACKALERT: the emulator misbehaves and sometimes forgets to shutdown */ if ((ident && wcscmp(ident, wst("DEFAULT")) != 0 && _ident.compare(ident) == 0) && _maxwidth == maxwidth && _maxheight == maxheight && _maxbpp == maxbpp && _options == options && _cacheSize == cachesize) return; // clear(); /* gcc does not allow the destructor to be called */ /* shamelessness :P this first call to the debug output message creates * a file in the executable directory. */ INFO(0, wst("------------------------------------------------------------------\n")); #ifdef GHQCHK INFO(0, wst(" GLideNHQ Hires Texture Checker 1.02.00.%d\n"), BUILD_NUMBER); #else INFO(0, wst(" GLideNHQ version 1.00.00.%d\n"), BUILD_NUMBER); #endif INFO(0, wst(" Copyright (C) 2010 Hiroshi Morii All Rights Reserved\n")); INFO(0, wst(" email : koolsmoky(at)users.sourceforge.net\n")); INFO(0, wst(" website : http://www.3dfxzone.it/koolsmoky\n")); INFO(0, wst("\n")); INFO(0, wst(" GLideN64 GitHub : https://github.com/gonetz/GLideN64\n")); INFO(0, wst("------------------------------------------------------------------\n")); _options = options; _txImage = new TxImage(); _txQuantize = new TxQuantize(); _txUtil = new TxUtil(); /* get number of CPU cores. */ _numcore = _txUtil->getNumberofProcessors(); _initialized = 0; _tex1 = NULL; _tex2 = NULL; /* XXX: anything larger than 1024 * 1024 is overkill */ _maxwidth = maxwidth > 1024 ? 1024 : maxwidth; _maxheight = maxheight > 1024 ? 1024 : maxheight; _maxbpp = maxbpp; _cacheSize = cachesize; /* TODO: validate options and do overrides here*/ /* save path name */ if (path) _path.assign(path); /* save ROM name */ if (ident && wcscmp(ident, wst("DEFAULT")) != 0) _ident.assign(ident); if (TxMemBuf::getInstance()->init(_maxwidth, _maxheight)) { if (!_tex1) _tex1 = TxMemBuf::getInstance()->get(0); if (!_tex2) _tex2 = TxMemBuf::getInstance()->get(1); } #if !_16BPP_HACK /* initialize hq4x filter */ hq4x_init(); #endif /* initialize texture cache in bytes. 128Mb will do nicely in most cases */ _txTexCache = new TxTexCache(_options, _cacheSize, _path.c_str(), _ident.c_str(), callback); /* hires texture */ #if HIRES_TEXTURE _txHiResCache = new TxHiResCache(_maxwidth, _maxheight, _maxbpp, _options, _path.c_str(), texPackPath, _ident.c_str(), callback); if (_txHiResCache->empty()) _options &= ~HIRESTEXTURES_MASK; #endif if (_tex1 && _tex2) _initialized = 1; } boolean TxFilter::filter(uint8 *src, int srcwidth, int srcheight, uint16 srcformat, uint64 g64crc, GHQTexInfo *info) { uint8 *texture = src; uint8 *tmptex = _tex1; if (srcformat == GL_RGBA) srcformat = GL_RGBA8; uint16 destformat = srcformat; /* We need to be initialized first! */ if (!_initialized) return 0; /* find cached textures */ if (_cacheSize) { /* calculate checksum of source texture */ if (!g64crc) g64crc = (uint64)(_txUtil->checksumTx(texture, srcwidth, srcheight, srcformat)); DBG_INFO(80, wst("filter: crc:%08X %08X %d x %d gfmt:%x\n"), (uint32)(g64crc >> 32), (uint32)(g64crc & 0xffffffff), srcwidth, srcheight, srcformat); #if 0 /* use hirestex to retrieve cached textures. */ /* check if we have it in cache */ if (!(g64crc & 0xffffffff00000000) && /* we reach here only when there is no hires texture for this crc */ _txTexCache->get(g64crc, info)) { DBG_INFO(80, wst("cache hit: %d x %d gfmt:%x\n"), info->width, info->height, info->format); return 1; /* yep, we've got it */ } #endif } /* Leave small textures alone because filtering makes little difference. * Moreover, some filters require at least 4 * 4 to work. * Bypass _options to do ARGB8888->16bpp if _maxbpp=16 or forced color reduction. */ if ((srcwidth >= 4 && srcheight >= 4) && ((_options & (FILTER_MASK|ENHANCEMENT_MASK)) || (srcformat == GL_RGBA8 && (_maxbpp < 32 || _options & FORCE16BPP_TEX)))) { if (srcformat != GL_RGBA8) { if (!_txQuantize->quantize(texture, tmptex, srcwidth, srcheight, srcformat, GL_RGBA8)) { DBG_INFO(80, wst("Error: unsupported format! gfmt:%x\n"), srcformat); return 0; } texture = tmptex; destformat = GL_RGBA8; } switch (destformat) { case GL_RGBA8: /* * prepare texture enhancements (x2, x4 scalers) */ int scale = 1, num_filters = 0; uint32 filter = 0; const uint32 enhancement = (_options & ENHANCEMENT_MASK); switch (enhancement) { case NO_ENHANCEMENT: // Do nothing break; case HQ4X_ENHANCEMENT: if (srcwidth <= (_maxwidth >> 2) && srcheight <= (_maxheight >> 2)) { filter |= HQ4X_ENHANCEMENT; scale = 4; num_filters++; } else if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) { filter |= HQ2X_ENHANCEMENT; scale = 2; num_filters++; } break; case BRZ3X_ENHANCEMENT: xbrz::init(); if (srcwidth <= (_maxwidth / 3) && srcheight <= (_maxheight / 3)) { filter |= BRZ3X_ENHANCEMENT; scale = 3; num_filters++; } else if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) { filter |= BRZ2X_ENHANCEMENT; scale = 2; num_filters++; } break; case BRZ4X_ENHANCEMENT: xbrz::init(); if (srcwidth <= (_maxwidth >> 2) && srcheight <= (_maxheight >> 2)) { filter |= BRZ4X_ENHANCEMENT; scale = 4; num_filters++; } else if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) { filter |= BRZ2X_ENHANCEMENT; scale = 2; num_filters++; } break; case BRZ5X_ENHANCEMENT: xbrz::init(); if (srcwidth <= (_maxwidth / 5) && srcheight <= (_maxheight / 5)) { filter |= BRZ5X_ENHANCEMENT; scale = 5; num_filters++; } else if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) { filter |= BRZ2X_ENHANCEMENT; scale = 2; num_filters++; } break; case BRZ6X_ENHANCEMENT: xbrz::init(); if (srcwidth <= (_maxwidth / 6) && srcheight <= (_maxheight / 6)) { filter |= BRZ6X_ENHANCEMENT; scale = 6; num_filters++; } else if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) { filter |= BRZ2X_ENHANCEMENT; scale = 2; num_filters++; } break; default: if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) { filter |= enhancement; scale = 2; num_filters++; } } /* * prepare texture filters */ if (_options & (SMOOTH_FILTER_MASK|SHARP_FILTER_MASK)) { filter |= (_options & (SMOOTH_FILTER_MASK|SHARP_FILTER_MASK)); num_filters++; } /* * execute texture enhancements and filters */ while (num_filters > 0) { tmptex = (texture == _tex1) ? _tex2 : _tex1; uint8 *_texture = texture; uint8 *_tmptex = tmptex; unsigned int numcore = _numcore; unsigned int blkrow = 0; while (numcore > 1 && blkrow == 0) { blkrow = (srcheight >> 2) / numcore; numcore--; } if (blkrow > 0 && numcore > 1) { std::thread *thrd[MAX_NUMCORE]; unsigned int i; int blkheight = blkrow << 2; unsigned int srcStride = (srcwidth * blkheight) << 2; unsigned int destStride = srcStride * scale * scale; for (i = 0; i < numcore - 1; i++) { thrd[i] = new std::thread(std::bind(filter_8888, (uint32*)_texture, srcwidth, blkheight, (uint32*)_tmptex, filter)); _texture += srcStride; _tmptex += destStride; } thrd[i] = new std::thread(std::bind(filter_8888, (uint32*)_texture, srcwidth, srcheight - blkheight * i, (uint32*)_tmptex, filter)); for (i = 0; i < numcore; i++) { thrd[i]->join(); delete thrd[i]; } } else { filter_8888((uint32*)_texture, srcwidth, srcheight, (uint32*)_tmptex, filter); } if (filter & ENHANCEMENT_MASK) { srcwidth *= scale; srcheight *= scale; filter &= ~ENHANCEMENT_MASK; scale = 1; } texture = tmptex; num_filters--; } /* * texture (re)conversions */ if (destformat == GL_RGBA8) { if (srcformat == GL_RGBA8 && (_maxbpp < 32 || _options & FORCE16BPP_TEX)) srcformat = GL_RGBA4; if (srcformat != GL_RGBA8) { tmptex = (texture == _tex1) ? _tex2 : _tex1; if (!_txQuantize->quantize(texture, tmptex, srcwidth, srcheight, GL_RGBA8, srcformat)) { DBG_INFO(80, wst("Error: unsupported format! gfmt:%x\n"), srcformat); return 0; } texture = tmptex; destformat = srcformat; } } break; #if !_16BPP_HACK case GL_RGBA4: int scale = 1; tmptex = (texture == _tex1) ? _tex2 : _tex1; switch (_options & ENHANCEMENT_MASK) { case HQ4X_ENHANCEMENT: if (srcwidth <= (_maxwidth >> 2) && srcheight <= (_maxheight >> 2)) { hq4x_4444((uint8*)texture, (uint8*)tmptex, srcwidth, srcheight, srcwidth, srcwidth * 4 * 2); scale = 4; }/* else if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) { hq2x_16((uint8*)texture, srcwidth * 2, (uint8*)tmptex, srcwidth * 2 * 2, srcwidth, srcheight); scale = 2; }*/ break; case HQ2X_ENHANCEMENT: if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) { hq2x_16((uint8*)texture, srcwidth * 2, (uint8*)tmptex, srcwidth * 2 * 2, srcwidth, srcheight); scale = 2; } break; case HQ2XS_ENHANCEMENT: if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) { hq2xS_16((uint8*)texture, srcwidth * 2, (uint8*)tmptex, srcwidth * 2 * 2, srcwidth, srcheight); scale = 2; } break; case LQ2X_ENHANCEMENT: if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) { lq2x_16((uint8*)texture, srcwidth * 2, (uint8*)tmptex, srcwidth * 2 * 2, srcwidth, srcheight); scale = 2; } break; case LQ2XS_ENHANCEMENT: if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) { lq2xS_16((uint8*)texture, srcwidth * 2, (uint8*)tmptex, srcwidth * 2 * 2, srcwidth, srcheight); scale = 2; } break; case X2SAI_ENHANCEMENT: if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) { Super2xSaI_4444((uint16*)texture, (uint16*)tmptex, srcwidth, srcheight, srcwidth); scale = 2; } break; case X2_ENHANCEMENT: if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) { Texture2x_16((uint8*)texture, srcwidth * 2, (uint8*)tmptex, srcwidth * 2 * 2, srcwidth, srcheight); scale = 2; } } if (scale) { srcwidth *= scale; srcheight *= scale; texture = tmptex; } if (_options & SMOOTH_FILTER_MASK) { tmptex = (texture == _tex1) ? _tex2 : _tex1; SmoothFilter_4444((uint16*)texture, srcwidth, srcheight, (uint16*)tmptex, (_options & SMOOTH_FILTER_MASK)); texture = tmptex; } else if (_options & SHARP_FILTER_MASK) { tmptex = (texture == _tex1) ? _tex2 : _tex1; SharpFilter_4444((uint16*)texture, srcwidth, srcheight, (uint16*)tmptex, (_options & SHARP_FILTER_MASK)); texture = tmptex; } break; case GL_RGB5_A1: break; case GL_RGB: break; #endif /* _16BPP_HACK */ } } /* fill in the texture info. */ info->data = texture; info->width = srcwidth; info->height = srcheight; info->is_hires_tex = 0; setTextureFormat(destformat, info); /* cache the texture. */ if (_cacheSize) _txTexCache->add(g64crc, info); DBG_INFO(80, wst("filtered texture: %d x %d gfmt:%x\n"), info->width, info->height, info->format); return 1; } boolean TxFilter::hirestex(uint64 g64crc, uint64 r_crc64, uint16 *palette, GHQTexInfo *info) { /* NOTE: Rice CRC32 sometimes return the same value for different textures. * As a workaround, Glide64 CRC32 is used for the key for NON-hires * texture cache. * * r_crc64 = hi:palette low:texture * (separate crc. doesn't necessary have to be rice crc) * g64crc = texture + palette glide64 crc32 * (can be any other crc if robust) */ DBG_INFO(80, wst("hirestex: r_crc64:%08X %08X, g64crc:%08X %08X\n"), (uint32)(r_crc64 >> 32), (uint32)(r_crc64 & 0xffffffff), (uint32)(g64crc >> 32), (uint32)(g64crc & 0xffffffff)); #if HIRES_TEXTURE /* check if we have it in hires memory cache. */ if ((_options & HIRESTEXTURES_MASK) && r_crc64) { if (_txHiResCache->get(r_crc64, info)) { DBG_INFO(80, wst("hires hit: %d x %d gfmt:%x\n"), info->width, info->height, info->format); /* TODO: Enable emulation for special N64 combiner modes. There are few ways * to get this done. Also applies for CI textures below. * * Solution 1. Load the hiresolution textures in ARGB8888 (or A8, IA88) format * to cache. When a cache is hit, then we take the modes passed in from Glide64 * (also TODO) and apply the modification. Then we do color reduction or format * conversion or compression if desired and stuff it into the non-hires texture * cache. * * Solution 2. When a cache is hit and if the combiner modes are present, * convert the texture to ARGB4444 and pass it back to Glide64 to process. * If a texture is compressed, it needs to be decompressed first. Then add * the processed texture to the non-hires texture cache. * * Solution 3. Hybrid of the above 2. Load the textures in ARGB8888 (A8, IA88) * format. Convert the texture to ARGB4444 and pass it back to Glide64 when * the combiner modes are present. Get the processed texture back from Glide64 * and compress if desired and add it to the non-hires texture cache. * * Solution 4. Take the easy way out and forget about this whole thing. */ return 1; /* yep, got it */ } if (_txHiResCache->get((r_crc64 & 0xffffffff), info)) { DBG_INFO(80, wst("hires hit: %d x %d gfmt:%x\n"), info->width, info->height, info->format); /* for true CI textures, we use the passed in palette to convert to * ARGB1555 and add it to memory cache. * * NOTE: we do this AFTER all other texture cache searches because * only a few texture packs actually use true CI textures. * * NOTE: the pre-converted palette from Glide64 is in RGBA5551 format. * A comp comes before RGB comp. */ // TODO: deal with palette textures if (palette && info->format == GL_COLOR_INDEX8_EXT) { DBG_INFO(80, wst("found GL_COLOR_INDEX8_EXT format. Need conversion!!\n")); int width = info->width; int height = info->height; uint16 format = info->format; /* XXX: avoid collision with zlib compression buffer in TxHiResTexture::get */ uint8 *texture = info->data; uint8 *tmptex = (texture == _tex1) ? _tex2 : _tex1; /* use palette and convert to 16bit format */ _txQuantize->P8_16BPP((uint32*)texture, (uint32*)tmptex, info->width, info->height, (uint32*)palette); texture = tmptex; format = GL_RGB5_A1; /* fill in the required info to return */ info->data = texture; info->width = width; info->height = height; info->is_hires_tex = 1; setTextureFormat(format, info); /* XXX: add to hires texture cache!!! */ _txHiResCache->add(r_crc64, info); DBG_INFO(80, wst("GL_COLOR_INDEX8_EXT loaded as gfmt:%x!\n"), format); } return 1; } } #endif /* check if we have it in memory cache */ if (_cacheSize && g64crc) { if (_txTexCache->get(g64crc, info)) { DBG_INFO(80, wst("cache hit: %d x %d gfmt:%x\n"), info->width, info->height, info->format); return 1; /* yep, we've got it */ } } DBG_INFO(80, wst("no cache hits.\n")); return 0; } uint64 TxFilter::checksum64(uint8 *src, int width, int height, int size, int rowStride, uint8 *palette) { if (_options & (HIRESTEXTURES_MASK|DUMP_TEX)) return _txUtil->checksum64(src, width, height, size, rowStride, palette); return 0; } boolean TxFilter::dmptx(uint8 *src, int width, int height, int rowStridePixel, uint16 gfmt, uint16 n64fmt, uint64 r_crc64) { if (!_initialized) return 0; if (!(_options & DUMP_TEX)) return 0; DBG_INFO(80, wst("gfmt = %02x n64fmt = %02x\n"), gfmt, n64fmt); DBG_INFO(80, wst("hirestex: r_crc64:%08X %08X\n"), (uint32)(r_crc64 >> 32), (uint32)(r_crc64 & 0xffffffff)); if (gfmt != GL_RGBA && gfmt != GL_RGBA8) { if (!_txQuantize->quantize(src, _tex1, rowStridePixel, height, gfmt, GL_RGBA8)) return 0; src = _tex1; } if (!_path.empty() && !_ident.empty()) { /* dump it to disk */ FILE *fp = NULL; tx_wstring tmpbuf; /* create directories */ tmpbuf.assign(_path + wst("/texture_dump")); tmpbuf.append(wst("/")); tmpbuf.append(_ident); tmpbuf.append(wst("/GLideNHQ")); if (!osal_path_existsW(tmpbuf.c_str()) && osal_mkdirp(tmpbuf.c_str()) != 0) return 0; if ((n64fmt >> 8) == 0x2) { wchar_t wbuf[256]; tx_swprintf(wbuf, 256, wst("/%ls#%08X#%01X#%01X#%08X_ciByRGBA.png"), _ident.c_str(), (uint32)(r_crc64 & 0xffffffff), (n64fmt >> 8), (n64fmt & 0xf), (uint32)(r_crc64 >> 32)); tmpbuf.append(wbuf); } else { wchar_t wbuf[256]; tx_swprintf(wbuf, 256, wst("/%ls#%08X#%01X#%01X_all.png"), _ident.c_str(), (uint32)(r_crc64 & 0xffffffff), (n64fmt >> 8), (n64fmt & 0xf)); tmpbuf.append(wbuf); } #ifdef WIN32 if ((fp = _wfopen(tmpbuf.c_str(), wst("wb"))) != NULL) { #else char cbuf[MAX_PATH]; wcstombs(cbuf, tmpbuf.c_str(), MAX_PATH); if ((fp = fopen(cbuf, "wb")) != NULL) { #endif _txImage->writePNG(src, fp, width, height, (rowStridePixel << 2), 0x0003, 0); fclose(fp); return 1; } } return 0; } boolean TxFilter::reloadhirestex() { DBG_INFO(80, wst("Reload hires textures from texture pack.\n")); if (_txHiResCache->load(0)) { if (_txHiResCache->empty()) _options &= ~HIRESTEXTURES_MASK; else _options |= HIRESTEXTURES_MASK; return 1; } return 0; } libretro-common/glsym/rglgen.py000664 001750 001750 00000011070 12655644434 020011 0ustar00sergiosergio000000 000000 #!/usr/bin/env python3 """ License statement applies to this file (glgen.py) only. """ """ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ import sys import os import re banned_ext = [ 'AMD', 'APPLE', 'EXT', 'NV', 'NVX', 'ATI', '3DLABS', 'SUN', 'SGI', 'SGIX', 'SGIS', 'INTEL', '3DFX', 'IBM', 'MESA', 'GREMEDY', 'OML', 'PGI', 'I3D', 'INGL', 'MTX', 'QCOM', 'IMG', 'ANGLE', 'SUNX', 'INGR' ] def noext(sym): for ext in banned_ext: if sym.endswith(ext): return False return True def find_gl_symbols(lines): typedefs = [] syms = [] for line in lines: m = re.search(r'^typedef.+PFN(\S+)PROC.+$', line) g = re.search(r'^.+(gl\S+)\W*\(.+\).*$', line) if m and noext(m.group(1)): typedefs.append(m.group(0).replace('PFN', 'RGLSYM').replace('GLDEBUGPROC', 'RGLGENGLDEBUGPROC')) if g and noext(g.group(1)): syms.append(g.group(1)) return (typedefs, syms) def generate_defines(gl_syms): res = [] for line in gl_syms: res.append('#define {} __rglgen_{}'.format(line, line)) return res def generate_declarations(gl_syms): return ['RGLSYM' + x.upper() + 'PROC ' + '__rglgen_' + x + ';' for x in gl_syms] def generate_macros(gl_syms): return [' SYM(' + x.replace('gl', '') + '),' for x in gl_syms] def dump(f, lines): f.write('\n'.join(lines)) f.write('\n\n') if __name__ == '__main__': if len(sys.argv) > 4: for banned in sys.argv[4:]: banned_ext.append(banned) with open(sys.argv[1], 'r') as f: lines = f.readlines() typedefs, syms = find_gl_symbols(lines) overrides = generate_defines(syms) declarations = generate_declarations(syms) externs = ['extern ' + x for x in declarations] macros = generate_macros(syms) with open(sys.argv[2], 'w') as f: f.write('#ifndef RGLGEN_DECL_H__\n') f.write('#define RGLGEN_DECL_H__\n') f.write('#ifdef __cplusplus\n') f.write('extern "C" {\n') f.write('#endif\n') f.write('#ifdef GL_APIENTRY\n') f.write('typedef void (GL_APIENTRY *RGLGENGLDEBUGPROC)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*);\n') f.write('#else\n') f.write('#ifndef APIENTRY\n') f.write('#define APIENTRY\n') f.write('#endif\n') f.write('#ifndef APIENTRYP\n') f.write('#define APIENTRYP APIENTRY *\n') f.write('#endif\n') f.write('typedef void (APIENTRY *RGLGENGLDEBUGPROCARB)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*);\n') f.write('typedef void (APIENTRY *RGLGENGLDEBUGPROC)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*);\n') f.write('#endif\n') f.write('#ifndef GL_OES_EGL_image\n') f.write('typedef void *GLeglImageOES;\n') f.write('#endif\n') f.write('#if !defined(GL_OES_fixed_point) && !defined(HAVE_OPENGLES2)\n') f.write('typedef GLint GLfixed;\n') f.write('#endif\n') dump(f, typedefs) dump(f, overrides) dump(f, externs) f.write('struct rglgen_sym_map { const char *sym; void *ptr; };\n') f.write('extern const struct rglgen_sym_map rglgen_symbol_map[];\n') f.write('#ifdef __cplusplus\n') f.write('}\n') f.write('#endif\n') f.write('#endif\n') with open(sys.argv[3], 'w') as f: f.write('#include "glsym.h"\n') f.write('#include \n') f.write('#define SYM(x) { "gl" #x, &(gl##x) }\n') f.write('const struct rglgen_sym_map rglgen_symbol_map[] = {\n') dump(f, macros) f.write(' { NULL, NULL },\n') f.write('};\n') dump(f, declarations) gles2n64/src/S2DEX2.c000664 001750 001750 00000004136 12655644434 015131 0ustar00sergiosergio000000 000000 #include "OpenGL.h" #include "S2DEX.h" #include "S2DEX2.h" #include "F3D.h" #include "F3DEX.h" #include "F3DEX2.h" #include "GBI.h" #include "gSP.h" #include "gDP.h" #include "RSP.h" #include "Types.h" void S2DEX2_Init(void) { // Set GeometryMode flags GBI_InitFlags( F3DEX2 ); GBI.PCStackSize = 18; // GBI Command Command Value Command Function GBI_SetGBI( G_SPNOOP, F3DEX2_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_BG_1CYC, S2DEX2_BG_1CYC, S2DEX_BG_1Cyc ); GBI_SetGBI( G_BG_COPY, S2DEX2_BG_COPY, S2DEX_BG_Copy ); GBI_SetGBI( G_OBJ_RECTANGLE, S2DEX2_OBJ_RECTANGLE, S2DEX_Obj_Rectangle ); GBI_SetGBI( G_OBJ_SPRITE, S2DEX2_OBJ_SPRITE, S2DEX_Obj_Sprite ); GBI_SetGBI( G_OBJ_MOVEMEM, S2DEX2_OBJ_MOVEMEM, S2DEX_Obj_MoveMem ); GBI_SetGBI( G_DL, F3DEX2_DL, F3D_DList ); GBI_SetGBI( G_SELECT_DL, S2DEX2_SELECT_DL, S2DEX_Select_DL ); GBI_SetGBI( G_OBJ_RENDERMODE, S2DEX2_OBJ_RENDERMODE, S2DEX_Obj_RenderMode ); GBI_SetGBI( G_OBJ_RECTANGLE_R, S2DEX2_OBJ_RECTANGLE_R, S2DEX_Obj_Rectangle_R ); GBI_SetGBI( G_OBJ_LOADTXTR, S2DEX2_OBJ_LOADTXTR, S2DEX_Obj_LoadTxtr ); GBI_SetGBI( G_OBJ_LDTX_SPRITE, S2DEX2_OBJ_LDTX_SPRITE, S2DEX_Obj_LdTx_Sprite ); GBI_SetGBI( G_OBJ_LDTX_RECT, S2DEX2_OBJ_LDTX_RECT, S2DEX_Obj_LdTx_Rect ); GBI_SetGBI( G_OBJ_LDTX_RECT_R, S2DEX2_OBJ_LDTX_RECT_R, S2DEX_Obj_LdTx_Rect_R ); GBI_SetGBI( G_MOVEWORD, F3DEX2_MOVEWORD, F3DEX2_MoveWord ); GBI_SetGBI( G_SETOTHERMODE_H, F3DEX2_SETOTHERMODE_H, F3DEX2_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3DEX2_SETOTHERMODE_L, F3DEX2_SetOtherMode_L ); GBI_SetGBI( G_ENDDL, F3DEX2_ENDDL, F3D_EndDL ); GBI_SetGBI( G_RDPHALF_1, F3DEX2_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_RDPHALF_2, F3DEX2_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_LOAD_UCODE, F3DEX2_LOAD_UCODE, F3DEX_Load_uCode ); } mupen64plus-core/src/debugger/dbg_decoder_local.h000664 001750 001750 00000141461 12655644434 023175 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - dbg_debugger_local.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2010 Marshall B. Rogers * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef __DECODER_LOCAL_H__ #define __DECODER_LOCAL_H__ #include /* $NetBSD: cpuregs.h,v 1.77 2009/12/14 00:46:04 matt Exp $ */ /* * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Ralph Campbell and Rick Macklem. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. * * @(#)machConst.h 8.1 (Berkeley) 6/10/93 * * machConst.h -- * * Machine dependent constants. * * Copyright (C) 1989 Digital Equipment Corporation. * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appears in all copies. * Digital Equipment Corporation makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/machConst.h, * v 9.2 89/10/21 15:55:22 jhh Exp SPRITE (DECWRL) * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/machAddrs.h, * v 1.2 89/08/15 18:28:21 rab Exp SPRITE (DECWRL) * from: Header: /sprite/src/kernel/vm/ds3100.md/RCS/vmPmaxConst.h, * v 9.1 89/09/18 17:33:00 shirriff Exp SPRITE (DECWRL) */ #ifndef _MIPS_CPUREGS_H_ #define _MIPS_CPUREGS_H_ /* * Address space. * 32-bit mips CPUS partition their 32-bit address space into four segments: * * kuseg 0x00000000 - 0x7fffffff User virtual mem, mapped * kseg0 0x80000000 - 0x9fffffff Physical memory, cached, unmapped * kseg1 0xa0000000 - 0xbfffffff Physical memory, uncached, unmapped * kseg2 0xc0000000 - 0xffffffff kernel-virtual, mapped * * mips1 physical memory is limited to 512Mbytes, which is * doubly mapped in kseg0 (cached) and kseg1 (uncached.) * Caching of mapped addresses is controlled by bits in the TLB entry. */ #ifdef _LP64 #define MIPS_XUSEG_START (0L << 62) #define MIPS_XUSEG_P(x) (((uint64_t)(x) >> 62) == 0) #define MIPS_USEG_P(x) ((uintptr_t)(x) < 0x80000000L) #define MIPS_XSSEG_START (1L << 62) #define MIPS_XSSEG_P(x) (((uint64_t)(x) >> 62) == 1) #endif /* * MIPS addresses are signed and we defining as negative so that * in LP64 kern they get sign-extended correctly. */ #ifndef _LOCORE #define MIPS_KSEG0_START (-0x7fffffffL-1) /* 0x80000000 */ #define MIPS_KSEG1_START -0x60000000L /* 0xa0000000 */ #define MIPS_KSEG2_START -0x40000000L /* 0xc0000000 */ #define MIPS_MAX_MEM_ADDR -0x42000000L /* 0xbe000000 */ #define MIPS_RESERVED_ADDR -0x40380000L /* 0xbfc80000 */ #endif #define MIPS_PHYS_MASK 0x1fffffff #define MIPS_KSEG0_TO_PHYS(x) ((uintptr_t)(x) & MIPS_PHYS_MASK) #define MIPS_PHYS_TO_KSEG0(x) ((uintptr_t)(x) | (intptr_t)MIPS_KSEG0_START) #define MIPS_KSEG1_TO_PHYS(x) ((uintptr_t)(x) & MIPS_PHYS_MASK) #define MIPS_PHYS_TO_KSEG1(x) ((uintptr_t)(x) | (intptr_t)MIPS_KSEG1_START) #define MIPS_KSEG0_P(x) (((intptr_t)(x) & ~MIPS_PHYS_MASK) == MIPS_KSEG0_START) #define MIPS_KSEG1_P(x) (((intptr_t)(x) & ~MIPS_PHYS_MASK) == MIPS_KSEG1_START) #define MIPS_KSEG2_P(x) ((uintptr_t)MIPS_KSEG2_START <= (uintptr_t)(x)) /* Map virtual address to index in mips3 r4k virtually-indexed cache */ #define MIPS3_VA_TO_CINDEX(x) \ (((intptr_t)(x) & 0xffffff) | MIPS_KSEG0_START) #ifndef _LOCORE #define MIPS_XSEG_MASK (0x3fffffffffffffffLL) #define MIPS_XKSEG_START (0x3ULL << 62) #define MIPS_XKSEG_P(x) (((uint64_t)(x) >> 62) == 3) #define MIPS_XKPHYS_START (0x2ULL << 62) #define MIPS_PHYS_TO_XKPHYS_UNCACHED(x) \ (MIPS_XKPHYS_START | ((uint64_t)(CCA_UNCACHED) << 59) | (x)) #define MIPS_PHYS_TO_XKPHYS_CACHED(x) \ (mips3_xkphys_cached | (x)) #define MIPS_PHYS_TO_XKPHYS(cca,x) \ (MIPS_XKPHYS_START | ((uint64_t)(cca) << 59) | (x)) #define MIPS_XKPHYS_TO_PHYS(x) ((uint64_t)(x) & 0x07ffffffffffffffLL) #define MIPS_XKPHYS_TO_CCA(x) (((uint64_t)(x) >> 59) & 7) #define MIPS_XKPHYS_P(x) (((uint64_t)(x) >> 62) == 2) #endif /* _LOCORE */ #define CCA_UNCACHED 2 #define CCA_CACHEABLE 3 /* cacheable non-coherent */ /* CPU dependent mtc0 hazard hook */ #define COP0_SYNC /* nothing */ #define COP0_HAZARD_FPUENABLE nop; nop; nop; nop; /* * The bits in the cause register. * * Bits common to r3000 and r4000: * * MIPS_CR_BR_DELAY Exception happened in branch delay slot. * MIPS_CR_COP_ERR Coprocessor error. * MIPS_CR_IP Interrupt pending bits defined below. * (same meaning as in CAUSE register). * MIPS_CR_EXC_CODE The exception type (see exception codes below). * * Differences: * r3k has 4 bits of execption type, r4k has 5 bits. */ #define MIPS_CR_BR_DELAY 0x80000000 #define MIPS_CR_COP_ERR 0x30000000 #define MIPS1_CR_EXC_CODE 0x0000003C /* four bits */ #define MIPS3_CR_EXC_CODE 0x0000007C /* five bits */ #define MIPS_CR_IP 0x0000FF00 #define MIPS_CR_EXC_CODE_SHIFT 2 /* * The bits in the status register. All bits are active when set to 1. * * R3000 status register fields: * MIPS_SR_COP_USABILITY Control the usability of the four coprocessors. * MIPS_SR_TS TLB shutdown. * * MIPS_SR_INT_IE Master (current) interrupt enable bit. * * Differences: * r3k has cache control is via frobbing SR register bits, whereas the * r4k cache control is via explicit instructions. * r3k has a 3-entry stack of kernel/user bits, whereas the * r4k has kernel/supervisor/user. */ #define MIPS_SR_COP_USABILITY 0xf0000000 #define MIPS_SR_COP_0_BIT 0x10000000 #define MIPS_SR_COP_1_BIT 0x20000000 /* r4k and r3k differences, see below */ #define MIPS_SR_MX 0x01000000 /* MIPS64 */ #define MIPS_SR_PX 0x00800000 /* MIPS64 */ #define MIPS_SR_BEV 0x00400000 /* Use boot exception vector */ #define MIPS_SR_TS 0x00200000 /* r4k and r3k differences, see below */ #define MIPS_SR_INT_IE 0x00000001 /*#define MIPS_SR_MBZ 0x0f8000c0*/ /* Never used, true for r3k */ /*#define MIPS_SR_INT_MASK 0x0000ff00*/ /* * The R2000/R3000-specific status register bit definitions. * all bits are active when set to 1. * * MIPS_SR_PARITY_ERR Parity error. * MIPS_SR_CACHE_MISS Most recent D-cache load resulted in a miss. * MIPS_SR_PARITY_ZERO Zero replaces outgoing parity bits. * MIPS_SR_SWAP_CACHES Swap I-cache and D-cache. * MIPS_SR_ISOL_CACHES Isolate D-cache from main memory. * Interrupt enable bits defined below. * MIPS_SR_KU_OLD Old kernel/user mode bit. 1 => user mode. * MIPS_SR_INT_ENA_OLD Old interrupt enable bit. * MIPS_SR_KU_PREV Previous kernel/user mode bit. 1 => user mode. * MIPS_SR_INT_ENA_PREV Previous interrupt enable bit. * MIPS_SR_KU_CUR Current kernel/user mode bit. 1 => user mode. */ #define MIPS1_PARITY_ERR 0x00100000 #define MIPS1_CACHE_MISS 0x00080000 #define MIPS1_PARITY_ZERO 0x00040000 #define MIPS1_SWAP_CACHES 0x00020000 #define MIPS1_ISOL_CACHES 0x00010000 #define MIPS1_SR_KU_OLD 0x00000020 /* 2nd stacked KU/IE*/ #define MIPS1_SR_INT_ENA_OLD 0x00000010 /* 2nd stacked KU/IE*/ #define MIPS1_SR_KU_PREV 0x00000008 /* 1st stacked KU/IE*/ #define MIPS1_SR_INT_ENA_PREV 0x00000004 /* 1st stacked KU/IE*/ #define MIPS1_SR_KU_CUR 0x00000002 /* current KU */ /* backwards compatibility */ #define MIPS_SR_PARITY_ERR MIPS1_PARITY_ERR #define MIPS_SR_CACHE_MISS MIPS1_CACHE_MISS #define MIPS_SR_PARITY_ZERO MIPS1_PARITY_ZERO #define MIPS_SR_SWAP_CACHES MIPS1_SWAP_CACHES #define MIPS_SR_ISOL_CACHES MIPS1_ISOL_CACHES #define MIPS_SR_KU_OLD MIPS1_SR_KU_OLD #define MIPS_SR_INT_ENA_OLD MIPS1_SR_INT_ENA_OLD #define MIPS_SR_KU_PREV MIPS1_SR_KU_PREV #define MIPS_SR_KU_CUR MIPS1_SR_KU_CUR #define MIPS_SR_INT_ENA_PREV MIPS1_SR_INT_ENA_PREV /* * R4000 status register bit definitons, * where different from r2000/r3000. */ #define MIPS3_SR_XX 0x80000000 #define MIPS3_SR_RP 0x08000000 #define MIPS3_SR_FR 0x04000000 #define MIPS3_SR_RE 0x02000000 #define MIPS3_SR_DIAG_DL 0x01000000 /* QED 52xx */ #define MIPS3_SR_DIAG_IL 0x00800000 /* QED 52xx */ #define MIPS3_SR_PX 0x00800000 /* MIPS64 */ #define MIPS3_SR_SR 0x00100000 #define MIPS3_SR_NMI 0x00080000 /* MIPS32/64 */ #define MIPS3_SR_DIAG_CH 0x00040000 #define MIPS3_SR_DIAG_CE 0x00020000 #define MIPS3_SR_DIAG_PE 0x00010000 #define MIPS3_SR_EIE 0x00010000 /* TX79/R5900 */ #define MIPS3_SR_KX 0x00000080 #define MIPS3_SR_SX 0x00000040 #define MIPS3_SR_UX 0x00000020 #define MIPS3_SR_KSU_MASK 0x00000018 #define MIPS3_SR_KSU_USER 0x00000010 #define MIPS3_SR_KSU_SUPER 0x00000008 #define MIPS3_SR_KSU_KERNEL 0x00000000 #define MIPS3_SR_ERL 0x00000004 #define MIPS3_SR_EXL 0x00000002 #ifdef MIPS3_5900 #undef MIPS_SR_INT_IE #define MIPS_SR_INT_IE 0x00010001 /* XXX */ #endif #define MIPS_SR_SOFT_RESET MIPS3_SR_SOFT_RESET #define MIPS_SR_DIAG_CH MIPS3_SR_DIAG_CH #define MIPS_SR_DIAG_CE MIPS3_SR_DIAG_CE #define MIPS_SR_DIAG_PE MIPS3_SR_DIAG_PE #define MIPS_SR_KX MIPS3_SR_KX #define MIPS_SR_SX MIPS3_SR_SX #define MIPS_SR_UX MIPS3_SR_UX #define MIPS_SR_KSU_MASK MIPS3_SR_KSU_MASK #define MIPS_SR_KSU_USER MIPS3_SR_KSU_USER #define MIPS_SR_KSU_SUPER MIPS3_SR_KSU_SUPER #define MIPS_SR_KSU_KERNEL MIPS3_SR_KSU_KERNEL #define MIPS_SR_ERL MIPS3_SR_ERL #define MIPS_SR_EXL MIPS3_SR_EXL /* * The interrupt masks. * If a bit in the mask is 1 then the interrupt is enabled (or pending). */ #define MIPS_INT_MASK 0xff00 #define MIPS_INT_MASK_5 0x8000 #define MIPS_INT_MASK_4 0x4000 #define MIPS_INT_MASK_3 0x2000 #define MIPS_INT_MASK_2 0x1000 #define MIPS_INT_MASK_1 0x0800 #define MIPS_INT_MASK_0 0x0400 #define MIPS_HARD_INT_MASK 0xfc00 #define MIPS_SOFT_INT_MASK_1 0x0200 #define MIPS_SOFT_INT_MASK_0 0x0100 /* * mips3 CPUs have on-chip timer at INT_MASK_5. Each platform can * choose to enable this interrupt. */ #if defined(MIPS3_ENABLE_CLOCK_INTR) #define MIPS3_INT_MASK MIPS_INT_MASK #define MIPS3_HARD_INT_MASK MIPS_HARD_INT_MASK #else #define MIPS3_INT_MASK (MIPS_INT_MASK & ~MIPS_INT_MASK_5) #define MIPS3_HARD_INT_MASK (MIPS_HARD_INT_MASK & ~MIPS_INT_MASK_5) #endif /* * The bits in the context register. */ #define MIPS1_CNTXT_PTE_BASE 0xFFE00000 #define MIPS1_CNTXT_BAD_VPN 0x001FFFFC #define MIPS3_CNTXT_PTE_BASE 0xFF800000 #define MIPS3_CNTXT_BAD_VPN2 0x007FFFF0 /* * The bits in the MIPS3 config register. * * bit 0..5: R/W, Bit 6..31: R/O */ /* kseg0 coherency algorithm - see MIPS3_TLB_ATTR values */ #define MIPS3_CONFIG_K0_MASK 0x00000007 /* * R/W Update on Store Conditional * 0: Store Conditional uses coherency algorithm specified by TLB * 1: Store Conditional uses cacheable coherent update on write */ #define MIPS3_CONFIG_CU 0x00000008 #define MIPS3_CONFIG_DB 0x00000010 /* Primary D-cache line size */ #define MIPS3_CONFIG_IB 0x00000020 /* Primary I-cache line size */ #define MIPS3_CONFIG_CACHE_L1_LSIZE(config, bit) \ (((config) & (bit)) ? 32 : 16) #define MIPS3_CONFIG_DC_MASK 0x000001c0 /* Primary D-cache size */ #define MIPS3_CONFIG_DC_SHIFT 6 #define MIPS3_CONFIG_IC_MASK 0x00000e00 /* Primary I-cache size */ #define MIPS3_CONFIG_IC_SHIFT 9 #define MIPS3_CONFIG_C_DEFBASE 0x1000 /* default base 2^12 */ /* Cache size mode indication: available only on Vr41xx CPUs */ #define MIPS3_CONFIG_CS 0x00001000 #define MIPS3_CONFIG_C_4100BASE 0x0400 /* base is 2^10 if CS=1 */ #define MIPS3_CONFIG_CACHE_SIZE(config, mask, base, shift) \ ((base) << (((config) & (mask)) >> (shift))) /* External cache enable: Controls L2 for R5000/Rm527x and L3 for Rm7000 */ #define MIPS3_CONFIG_SE 0x00001000 /* Block ordering: 0: sequential, 1: sub-block */ #define MIPS3_CONFIG_EB 0x00002000 /* ECC mode - 0: ECC mode, 1: parity mode */ #define MIPS3_CONFIG_EM 0x00004000 /* BigEndianMem - 0: kernel and memory are little endian, 1: big endian */ #define MIPS3_CONFIG_BE 0x00008000 /* Dirty Shared coherency state - 0: enabled, 1: disabled */ #define MIPS3_CONFIG_SM 0x00010000 /* Secondary Cache - 0: present, 1: not present */ #define MIPS3_CONFIG_SC 0x00020000 /* System Port width - 0: 64-bit, 1: 32-bit (QED RM523x), 2,3: reserved */ #define MIPS3_CONFIG_EW_MASK 0x000c0000 #define MIPS3_CONFIG_EW_SHIFT 18 /* Secondary Cache port width - 0: 128-bit data path to S-cache, 1: reserved */ #define MIPS3_CONFIG_SW 0x00100000 /* Split Secondary Cache Mode - 0: I/D mixed, 1: I/D separated by SCAddr(17) */ #define MIPS3_CONFIG_SS 0x00200000 /* Secondary Cache line size */ #define MIPS3_CONFIG_SB_MASK 0x00c00000 #define MIPS3_CONFIG_SB_SHIFT 22 #define MIPS3_CONFIG_CACHE_L2_LSIZE(config) \ (0x10 << (((config) & MIPS3_CONFIG_SB_MASK) >> MIPS3_CONFIG_SB_SHIFT)) /* Write back data rate */ #define MIPS3_CONFIG_EP_MASK 0x0f000000 #define MIPS3_CONFIG_EP_SHIFT 24 /* System clock ratio - this value is CPU dependent */ #define MIPS3_CONFIG_EC_MASK 0x70000000 #define MIPS3_CONFIG_EC_SHIFT 28 /* Master-Checker Mode - 1: enabled */ #define MIPS3_CONFIG_CM 0x80000000 /* * The bits in the MIPS4 config register. */ /* kseg0 coherency algorithm - see MIPS3_TLB_ATTR values */ #define MIPS4_CONFIG_K0_MASK MIPS3_CONFIG_K0_MASK #define MIPS4_CONFIG_DN_MASK 0x00000018 /* Device number */ #define MIPS4_CONFIG_CT 0x00000020 /* CohPrcReqTar */ #define MIPS4_CONFIG_PE 0x00000040 /* PreElmReq */ #define MIPS4_CONFIG_PM_MASK 0x00000180 /* PreReqMax */ #define MIPS4_CONFIG_EC_MASK 0x00001e00 /* SysClkDiv */ #define MIPS4_CONFIG_SB 0x00002000 /* SCBlkSize */ #define MIPS4_CONFIG_SK 0x00004000 /* SCColEn */ #define MIPS4_CONFIG_BE 0x00008000 /* MemEnd */ #define MIPS4_CONFIG_SS_MASK 0x00070000 /* SCSize */ #define MIPS4_CONFIG_SC_MASK 0x00380000 /* SCClkDiv */ #define MIPS4_CONFIG_RESERVED 0x03c00000 /* Reserved wired 0 */ #define MIPS4_CONFIG_DC_MASK 0x1c000000 /* Primary D-Cache size */ #define MIPS4_CONFIG_IC_MASK 0xe0000000 /* Primary I-Cache size */ #define MIPS4_CONFIG_DC_SHIFT 26 #define MIPS4_CONFIG_IC_SHIFT 29 #define MIPS4_CONFIG_CACHE_SIZE(config, mask, base, shift) \ ((base) << (((config) & (mask)) >> (shift))) #define MIPS4_CONFIG_CACHE_L2_LSIZE(config) \ (((config) & MIPS4_CONFIG_SB) ? 128 : 64) /* * Location of exception vectors. * * Common vectors: reset and UTLB miss. */ #define MIPS_RESET_EXC_VEC MIPS_PHYS_TO_KSEG1(0x1FC00000) #define MIPS_UTLB_MISS_EXC_VEC MIPS_PHYS_TO_KSEG0(0) /* * MIPS-1 general exception vector (everything else) */ #define MIPS1_GEN_EXC_VEC MIPS_PHYS_TO_KSEG0(0x0080) /* * MIPS-III exception vectors */ #define MIPS3_XTLB_MISS_EXC_VEC MIPS_PHYS_TO_KSEG0(0x0080) #define MIPS3_CACHE_ERR_EXC_VEC MIPS_PHYS_TO_KSEG0(0x0100) #define MIPS3_GEN_EXC_VEC MIPS_PHYS_TO_KSEG0(0x0180) /* * TX79 (R5900) exception vectors */ #define MIPS_R5900_COUNTER_EXC_VEC MIPS_PHYS_TO_KSEG0(0x0080) #define MIPS_R5900_DEBUG_EXC_VEC MIPS_PHYS_TO_KSEG0(0x0100) /* * MIPS32/MIPS64 (and some MIPS3) dedicated interrupt vector. */ #define MIPS3_INTR_EXC_VEC MIPS_PHYS_TO_KSEG0(0x0200) /* * Coprocessor 0 registers: * * v--- width for mips I,III,32,64 * (3=32bit, 6=64bit, i=impl dep) * 0 MIPS_COP_0_TLB_INDEX 3333 TLB Index. * 1 MIPS_COP_0_TLB_RANDOM 3333 TLB Random. * 2 MIPS_COP_0_TLB_LOW 3... r3k TLB entry low. * 2 MIPS_COP_0_TLB_LO0 .636 r4k TLB entry low. * 3 MIPS_COP_0_TLB_LO1 .636 r4k TLB entry low, extended. * 4 MIPS_COP_0_TLB_CONTEXT 3636 TLB Context. * 5 MIPS_COP_0_TLB_PG_MASK .333 TLB Page Mask register. * 6 MIPS_COP_0_TLB_WIRED .333 Wired TLB number. * 8 MIPS_COP_0_BAD_VADDR 3636 Bad virtual address. * 9 MIPS_COP_0_COUNT .333 Count register. * 10 MIPS_COP_0_TLB_HI 3636 TLB entry high. * 11 MIPS_COP_0_COMPARE .333 Compare (against Count). * 12 MIPS_COP_0_STATUS 3333 Status register. * 13 MIPS_COP_0_CAUSE 3333 Exception cause register. * 14 MIPS_COP_0_EXC_PC 3636 Exception PC. * 15 MIPS_COP_0_PRID 3333 Processor revision identifier. * 15/1 MIPS_COP_0_EBASE ..33 Exception Base * 16 MIPS_COP_0_CONFIG 3333 Configuration register. * 16/1 MIPS_COP_0_CONFIG1 ..33 Configuration register 1. * 16/2 MIPS_COP_0_CONFIG2 ..33 Configuration register 2. * 16/3 MIPS_COP_0_CONFIG3 ..33 Configuration register 3. * 17 MIPS_COP_0_LLADDR .336 Load Linked Address. * 18 MIPS_COP_0_WATCH_LO .336 WatchLo register. * 19 MIPS_COP_0_WATCH_HI .333 WatchHi register. * 20 MIPS_COP_0_TLB_XCONTEXT .6.6 TLB XContext register. * 23 MIPS_COP_0_DEBUG .... Debug JTAG register. * 24 MIPS_COP_0_DEPC .... DEPC JTAG register. * 25 MIPS_COP_0_PERFCNT ..36 Performance Counter register. * 26 MIPS_COP_0_ECC .3ii ECC / Error Control register. * 27 MIPS_COP_0_CACHE_ERR .3ii Cache Error register. * 28/0 MIPS_COP_0_TAG_LO .3ii Cache TagLo register (instr). * 28/1 MIPS_COP_0_DATA_LO ..ii Cache DataLo register (instr). * 28/2 MIPS_COP_0_TAG_LO ..ii Cache TagLo register (data). * 28/3 MIPS_COP_0_DATA_LO ..ii Cache DataLo register (data). * 29/0 MIPS_COP_0_TAG_HI .3ii Cache TagHi register (instr). * 29/1 MIPS_COP_0_DATA_HI ..ii Cache DataHi register (instr). * 29/2 MIPS_COP_0_TAG_HI ..ii Cache TagHi register (data). * 29/3 MIPS_COP_0_DATA_HI ..ii Cache DataHi register (data). * 30 MIPS_COP_0_ERROR_PC .636 Error EPC register. * 31 MIPS_COP_0_DESAVE .... DESAVE JTAG register. */ #ifdef _LOCORE #define _(n) __CONCAT($,n) #else #define _(n) n #endif #define MIPS_COP_0_TLB_INDEX _(0) #define MIPS_COP_0_TLB_RANDOM _(1) /* Name and meaning of TLB bits for $2 differ on r3k and r4k. */ #define MIPS_COP_0_TLB_CONTEXT _(4) /* $5 and $6 new with MIPS-III */ #define MIPS_COP_0_BAD_VADDR _(8) #define MIPS_COP_0_TLB_HI _(10) #define MIPS_COP_0_STATUS _(12) #define MIPS_COP_0_CAUSE _(13) #define MIPS_COP_0_EXC_PC _(14) #define MIPS_COP_0_PRID _(15) /* MIPS-I */ #define MIPS_COP_0_TLB_LOW _(2) /* MIPS-III */ #define MIPS_COP_0_TLB_LO0 _(2) #define MIPS_COP_0_TLB_LO1 _(3) #define MIPS_COP_0_TLB_PG_MASK _(5) #define MIPS_COP_0_TLB_WIRED _(6) #define MIPS_COP_0_COUNT _(9) #define MIPS_COP_0_COMPARE _(11) #define MIPS_COP_0_CONFIG _(16) #define MIPS_COP_0_LLADDR _(17) #define MIPS_COP_0_WATCH_LO _(18) #define MIPS_COP_0_WATCH_HI _(19) #define MIPS_COP_0_TLB_XCONTEXT _(20) #define MIPS_COP_0_ECC _(26) #define MIPS_COP_0_CACHE_ERR _(27) #define MIPS_COP_0_TAG_LO _(28) #define MIPS_COP_0_TAG_HI _(29) #define MIPS_COP_0_ERROR_PC _(30) /* MIPS32/64 */ #define MIPS_COP_0_DEBUG _(23) #define MIPS_COP_0_DEPC _(24) #define MIPS_COP_0_PERFCNT _(25) #define MIPS_COP_0_DATA_LO _(28) #define MIPS_COP_0_DATA_HI _(29) #define MIPS_COP_0_DESAVE _(31) /* * Values for the code field in a break instruction. */ #define MIPS_BREAK_INSTR 0x0000000d #define MIPS_BREAK_VAL_MASK 0x03ff0000 #define MIPS_BREAK_VAL_SHIFT 16 #define MIPS_BREAK_KDB_VAL 512 #define MIPS_BREAK_SSTEP_VAL 513 #define MIPS_BREAK_BRKPT_VAL 514 #define MIPS_BREAK_SOVER_VAL 515 #define MIPS_BREAK_KDB (MIPS_BREAK_INSTR | \ (MIPS_BREAK_KDB_VAL << MIPS_BREAK_VAL_SHIFT)) #define MIPS_BREAK_SSTEP (MIPS_BREAK_INSTR | \ (MIPS_BREAK_SSTEP_VAL << MIPS_BREAK_VAL_SHIFT)) #define MIPS_BREAK_BRKPT (MIPS_BREAK_INSTR | \ (MIPS_BREAK_BRKPT_VAL << MIPS_BREAK_VAL_SHIFT)) #define MIPS_BREAK_SOVER (MIPS_BREAK_INSTR | \ (MIPS_BREAK_SOVER_VAL << MIPS_BREAK_VAL_SHIFT)) /* * Mininum and maximum cache sizes. */ #define MIPS_MIN_CACHE_SIZE (16 * 1024) #define MIPS_MAX_CACHE_SIZE (256 * 1024) #define MIPS3_MAX_PCACHE_SIZE (32 * 1024) /* max. primary cache size */ /* * The floating point version and status registers. */ #define MIPS_FPU_ID $0 #define MIPS_FPU_CSR $31 /* * The floating point coprocessor status register bits. */ #define MIPS_FPU_ROUNDING_BITS 0x00000003 #define MIPS_FPU_ROUND_RN 0x00000000 #define MIPS_FPU_ROUND_RZ 0x00000001 #define MIPS_FPU_ROUND_RP 0x00000002 #define MIPS_FPU_ROUND_RM 0x00000003 #define MIPS_FPU_STICKY_BITS 0x0000007c #define MIPS_FPU_STICKY_INEXACT 0x00000004 #define MIPS_FPU_STICKY_UNDERFLOW 0x00000008 #define MIPS_FPU_STICKY_OVERFLOW 0x00000010 #define MIPS_FPU_STICKY_DIV0 0x00000020 #define MIPS_FPU_STICKY_INVALID 0x00000040 #define MIPS_FPU_ENABLE_BITS 0x00000f80 #define MIPS_FPU_ENABLE_INEXACT 0x00000080 #define MIPS_FPU_ENABLE_UNDERFLOW 0x00000100 #define MIPS_FPU_ENABLE_OVERFLOW 0x00000200 #define MIPS_FPU_ENABLE_DIV0 0x00000400 #define MIPS_FPU_ENABLE_INVALID 0x00000800 #define MIPS_FPU_EXCEPTION_BITS 0x0003f000 #define MIPS_FPU_EXCEPTION_INEXACT 0x00001000 #define MIPS_FPU_EXCEPTION_UNDERFLOW 0x00002000 #define MIPS_FPU_EXCEPTION_OVERFLOW 0x00004000 #define MIPS_FPU_EXCEPTION_DIV0 0x00008000 #define MIPS_FPU_EXCEPTION_INVALID 0x00010000 #define MIPS_FPU_EXCEPTION_UNIMPL 0x00020000 #define MIPS_FPU_COND_BIT 0x00800000 #define MIPS_FPU_FLUSH_BIT 0x01000000 /* r4k, MBZ on r3k */ #define MIPS1_FPC_MBZ_BITS 0xff7c0000 #define MIPS3_FPC_MBZ_BITS 0xfe7c0000 /* * Constants to determine if have a floating point instruction. */ #define MIPS_OPCODE_SHIFT 26 #define MIPS_OPCODE_C1 0x11 /* * The low part of the TLB entry. */ #define MIPS1_TLB_PFN 0xfffff000 #define MIPS1_TLB_NON_CACHEABLE_BIT 0x00000800 #define MIPS1_TLB_DIRTY_BIT 0x00000400 #define MIPS1_TLB_VALID_BIT 0x00000200 #define MIPS1_TLB_GLOBAL_BIT 0x00000100 #define MIPS3_TLB_PFN 0x3fffffc0 #define MIPS3_TLB_ATTR_MASK 0x00000038 #define MIPS3_TLB_ATTR_SHIFT 3 #define MIPS3_TLB_DIRTY_BIT 0x00000004 #define MIPS3_TLB_VALID_BIT 0x00000002 #define MIPS3_TLB_GLOBAL_BIT 0x00000001 #define MIPS1_TLB_PHYS_PAGE_SHIFT 12 #define MIPS3_TLB_PHYS_PAGE_SHIFT 6 #define MIPS1_TLB_PF_NUM MIPS1_TLB_PFN #define MIPS3_TLB_PF_NUM MIPS3_TLB_PFN #define MIPS1_TLB_MOD_BIT MIPS1_TLB_DIRTY_BIT #define MIPS3_TLB_MOD_BIT MIPS3_TLB_DIRTY_BIT /* * MIPS3_TLB_ATTR values - coherency algorithm: * 0: cacheable, noncoherent, write-through, no write allocate * 1: cacheable, noncoherent, write-through, write allocate * 2: uncached * 3: cacheable, noncoherent, write-back (noncoherent) * 4: cacheable, coherent, write-back, exclusive (exclusive) * 5: cacheable, coherent, write-back, exclusive on write (sharable) * 6: cacheable, coherent, write-back, update on write (update) * 7: uncached, accelerated (gather STORE operations) */ #define MIPS3_TLB_ATTR_WT 0 /* IDT */ #define MIPS3_TLB_ATTR_WT_WRITEALLOCATE 1 /* IDT */ #define MIPS3_TLB_ATTR_UNCACHED 2 /* R4000/R4400, IDT */ #define MIPS3_TLB_ATTR_WB_NONCOHERENT 3 /* R4000/R4400, IDT */ #define MIPS3_TLB_ATTR_WB_EXCLUSIVE 4 /* R4000/R4400 */ #define MIPS3_TLB_ATTR_WB_SHARABLE 5 /* R4000/R4400 */ #define MIPS3_TLB_ATTR_WB_UPDATE 6 /* R4000/R4400 */ #define MIPS4_TLB_ATTR_UNCACHED_ACCELERATED 7 /* R10000 */ /* * The high part of the TLB entry. */ #define MIPS1_TLB_VPN 0xfffff000 #define MIPS1_TLB_PID 0x00000fc0 #define MIPS1_TLB_PID_SHIFT 6 #define MIPS3_TLB_VPN2 0xffffe000 #define MIPS3_TLB_ASID 0x000000ff #define MIPS1_TLB_VIRT_PAGE_NUM MIPS1_TLB_VPN #define MIPS3_TLB_VIRT_PAGE_NUM MIPS3_TLB_VPN2 #define MIPS3_TLB_PID MIPS3_TLB_ASID #define MIPS_TLB_VIRT_PAGE_SHIFT 12 /* * r3000: shift count to put the index in the right spot. */ #define MIPS1_TLB_INDEX_SHIFT 8 /* * The first TLB that write random hits. */ #define MIPS1_TLB_FIRST_RAND_ENTRY 8 #define MIPS3_TLB_WIRED_UPAGES 1 /* * The number of process id entries. */ #define MIPS1_TLB_NUM_PIDS 64 #define MIPS3_TLB_NUM_ASIDS 256 /* * Patch codes to hide CPU design differences between MIPS1 and MIPS3. */ /* XXX simonb: this is before MIPS3_PLUS is defined (and is ugly!) */ #if !(defined(MIPS3) || defined(MIPS4) || defined(MIPS32) || defined(MIPS64)) \ && defined(MIPS1) /* XXX simonb must be neater! */ #define MIPS_TLB_PID_SHIFT MIPS1_TLB_PID_SHIFT #define MIPS_TLB_NUM_PIDS MIPS1_TLB_NUM_PIDS #endif #if (defined(MIPS3) || defined(MIPS4) || defined(MIPS32) || defined(MIPS64)) \ && !defined(MIPS1) /* XXX simonb must be neater! */ #define MIPS_TLB_PID_SHIFT 0 #define MIPS_TLB_NUM_PIDS MIPS3_TLB_NUM_ASIDS #endif #if !defined(MIPS_TLB_PID_SHIFT) #define MIPS_TLB_PID_SHIFT \ ((MIPS_HAS_R4K_MMU) ? 0 : MIPS1_TLB_PID_SHIFT) #define MIPS_TLB_NUM_PIDS \ ((MIPS_HAS_R4K_MMU) ? MIPS3_TLB_NUM_ASIDS : MIPS1_TLB_NUM_PIDS) #endif /* * CPU processor revision IDs for company ID == 0 (non mips32/64 chips) */ #define MIPS_R2000 0x01 /* MIPS R2000 ISA I */ #define MIPS_R3000 0x02 /* MIPS R3000 ISA I */ #define MIPS_R6000 0x03 /* MIPS R6000 ISA II */ #define MIPS_R4000 0x04 /* MIPS R4000/R4400 ISA III */ #define MIPS_R3LSI 0x05 /* LSI Logic R3000 derivative ISA I */ #define MIPS_R6000A 0x06 /* MIPS R6000A ISA II */ #define MIPS_R3IDT 0x07 /* IDT R3041 or RC36100 ISA I */ #define MIPS_R10000 0x09 /* MIPS R10000 ISA IV */ #define MIPS_R4200 0x0a /* NEC VR4200 ISA III */ #define MIPS_R4300 0x0b /* NEC VR4300 ISA III */ #define MIPS_R4100 0x0c /* NEC VR4100 ISA III */ #define MIPS_R12000 0x0e /* MIPS R12000 ISA IV */ #define MIPS_R14000 0x0f /* MIPS R14000 ISA IV */ #define MIPS_R8000 0x10 /* MIPS R8000 Blackbird/TFP ISA IV */ #define MIPS_RC32300 0x18 /* IDT RC32334,332,355 ISA 32 */ #define MIPS_R4600 0x20 /* QED R4600 Orion ISA III */ #define MIPS_R4700 0x21 /* QED R4700 Orion ISA III */ #define MIPS_R3SONY 0x21 /* Sony R3000 based ISA I */ #define MIPS_R4650 0x22 /* QED R4650 ISA III */ #define MIPS_TX3900 0x22 /* Toshiba TX39 family ISA I */ #define MIPS_R5000 0x23 /* MIPS R5000 ISA IV */ #define MIPS_R3NKK 0x23 /* NKK R3000 based ISA I */ #define MIPS_RC32364 0x26 /* IDT RC32364 ISA 32 */ #define MIPS_RM7000 0x27 /* QED RM7000 ISA IV */ #define MIPS_RM5200 0x28 /* QED RM5200s ISA IV */ #define MIPS_TX4900 0x2d /* Toshiba TX49 family ISA III */ #define MIPS_R5900 0x2e /* Toshiba R5900 (EECore) ISA --- */ #define MIPS_RC64470 0x30 /* IDT RC64474/RC64475 ISA III */ #define MIPS_TX7900 0x38 /* Toshiba TX79 ISA III+*/ #define MIPS_R5400 0x54 /* NEC VR5400 ISA IV */ #define MIPS_R5500 0x55 /* NEC VR5500 ISA IV */ #define MIPS_LOONGSON2 0x63 /* ICT Loongson-2 ISA III */ /* * CPU revision IDs for some prehistoric processors. */ /* For MIPS_R3000 */ #define MIPS_REV_R2000A 0x16 /* R2000A uses R3000 proc revision */ #define MIPS_REV_R3000 0x20 #define MIPS_REV_R3000A 0x30 /* For MIPS_TX3900 */ #define MIPS_REV_TX3912 0x10 #define MIPS_REV_TX3922 0x30 #define MIPS_REV_TX3927 0x40 /* For MIPS_R4000 */ #define MIPS_REV_R4000_A 0x00 #define MIPS_REV_R4000_B 0x22 #define MIPS_REV_R4000_C 0x30 #define MIPS_REV_R4400_A 0x40 #define MIPS_REV_R4400_B 0x50 #define MIPS_REV_R4400_C 0x60 /* For MIPS_TX4900 */ #define MIPS_REV_TX4927 0x22 /* For MIPS_LOONGSON2 */ #define MIPS_REV_LOONGSON2E 0x02 #define MIPS_REV_LOONGSON2F 0x03 /* * CPU processor revision IDs for company ID == 1 (MIPS) */ #define MIPS_4Kc 0x80 /* MIPS 4Kc ISA 32 */ #define MIPS_5Kc 0x81 /* MIPS 5Kc ISA 64 */ #define MIPS_20Kc 0x82 /* MIPS 20Kc ISA 64 */ #define MIPS_4Kmp 0x83 /* MIPS 4Km/4Kp ISA 32 */ #define MIPS_4KEc 0x84 /* MIPS 4KEc ISA 32 */ #define MIPS_4KEmp 0x85 /* MIPS 4KEm/4KEp ISA 32 */ #define MIPS_4KSc 0x86 /* MIPS 4KSc ISA 32 */ #define MIPS_M4K 0x87 /* MIPS M4K ISA 32 Rel 2 */ #define MIPS_25Kf 0x88 /* MIPS 25Kf ISA 64 */ #define MIPS_5KE 0x89 /* MIPS 5KE ISA 64 Rel 2 */ #define MIPS_4KEc_R2 0x90 /* MIPS 4KEc_R2 ISA 32 Rel 2 */ #define MIPS_4KEmp_R2 0x91 /* MIPS 4KEm/4KEp_R2 ISA 32 Rel 2 */ #define MIPS_4KSd 0x92 /* MIPS 4KSd ISA 32 Rel 2 */ #define MIPS_24K 0x93 /* MIPS 24Kc/24Kf ISA 32 Rel 2 */ #define MIPS_34K 0x95 /* MIPS 34K ISA 32 R2 MT */ #define MIPS_24KE 0x96 /* MIPS 24KEc ISA 32 Rel 2 */ #define MIPS_74K 0x97 /* MIPS 74Kc/74Kf ISA 32 Rel 2 */ /* * Alchemy (company ID 3) use the processor ID field to donote the CPU core * revision and the company options field do donate the SOC chip type. */ /* CPU processor revision IDs */ #define MIPS_AU_REV1 0x01 /* Alchemy Au1000 (Rev 1) ISA 32 */ #define MIPS_AU_REV2 0x02 /* Alchemy Au1000 (Rev 2) ISA 32 */ /* CPU company options IDs */ #define MIPS_AU1000 0x00 #define MIPS_AU1500 0x01 #define MIPS_AU1100 0x02 #define MIPS_AU1550 0x03 /* * CPU processor revision IDs for company ID == 4 (SiByte) */ #define MIPS_SB1 0x01 /* SiByte SB1 ISA 64 */ /* * CPU processor revision IDs for company ID == 5 (SandCraft) */ #define MIPS_SR7100 0x04 /* SandCraft SR7100 ISA 64 */ /* * CPU processor revision IDs for company ID == 12 (RMI) */ #define MIPS_XLR732 0x00 /* RMI XLR732-C ISA 64 */ #define MIPS_XLR716 0x02 /* RMI XLR716-C ISA 64 */ #define MIPS_XLR532 0x08 /* RMI XLR532-C ISA 64 */ #define MIPS_XLR516 0x0a /* RMI XLR516-C ISA 64 */ #define MIPS_XLR508 0x0b /* RMI XLR508-C ISA 64 */ #define MIPS_XLR308 0x0f /* RMI XLR308-C ISA 64 */ #define MIPS_XLS616 0x40 /* RMI XLS616 ISA 64 */ #define MIPS_XLS416 0x44 /* RMI XLS416 ISA 64 */ #define MIPS_XLS608 0x4A /* RMI XLS608 ISA 64 */ #define MIPS_XLS408 0x4E /* RMI XLS406 ISA 64 */ #define MIPS_XLS404 0x4F /* RMI XLS404 ISA 64 */ #define MIPS_XLS408LITE 0x88 /* RMI XLS408-Lite ISA 64 */ #define MIPS_XLS404LITE 0x8C /* RMI XLS404-Lite ISA 64 */ #define MIPS_XLS208 0x8E /* RMI XLS208 ISA 64 */ #define MIPS_XLS204 0x8F /* RMI XLS204 ISA 64 */ #define MIPS_XLS108 0xCE /* RMI XLS108 ISA 64 */ #define MIPS_XLS104 0xCF /* RMI XLS104 ISA 64 */ /* * FPU processor revision ID */ #define MIPS_SOFT 0x00 /* Software emulation ISA I */ #define MIPS_R2360 0x01 /* MIPS R2360 FPC ISA I */ #define MIPS_R2010 0x02 /* MIPS R2010 FPC ISA I */ #define MIPS_R3010 0x03 /* MIPS R3010 FPC ISA I */ #define MIPS_R6010 0x04 /* MIPS R6010 FPC ISA II */ #define MIPS_R4010 0x05 /* MIPS R4010 FPC ISA II */ #define MIPS_R31LSI 0x06 /* LSI Logic derivate ISA I */ #define MIPS_R3TOSH 0x22 /* Toshiba R3000 based FPU ISA I */ #endif /* _MIPS_CPUREGS_H_ */ /* $NetBSD: cpu.h,v 1.94 2009/12/14 00:46:04 matt Exp $ */ /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Ralph Campbell and Rick Macklem. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. * * @(#)cpu.h 8.4 (Berkeley) 1/4/94 */ #ifndef _CPU_H_ #define _CPU_H_ /* * bitfield defines for cpu_cp0flags */ #define MIPS_CP0FL_USE __BIT(0) /* use these flags */ #define MIPS_CP0FL_ECC __BIT(1) #define MIPS_CP0FL_CACHE_ERR __BIT(2) #define MIPS_CP0FL_EIRR __BIT(3) #define MIPS_CP0FL_EIMR __BIT(4) #define MIPS_CP0FL_EBASE __BIT(5) #define MIPS_CP0FL_CONFIG __BIT(6) #define MIPS_CP0FL_CONFIGn(n) (__BIT(7) << ((n) & 7)) /* * cpu_cidflags defines, by company */ /* * RMI company-specific cpu_cidflags */ #define MIPS_CIDFL_RMI_TYPE __BITS(0,2) #define CIDFL_RMI_TYPE_XLR 0 #define CIDFL_RMI_TYPE_XLS 1 #define CIDFL_RMI_TYPE_XLP 2 #define CPU_INFO_ITERATOR int #define CPU_INFO_FOREACH(cii, ci) \ (void)(cii), ci = &cpu_info_store; ci != NULL; ci = ci->ci_next /* * CTL_MACHDEP definitions. */ #define CPU_CONSDEV 1 /* dev_t: console terminal device */ #define CPU_BOOTED_KERNEL 2 /* string: booted kernel name */ #define CPU_ROOT_DEVICE 3 /* string: root device name */ #define CPU_LLSC 4 /* OS/CPU supports LL/SC instruction */ /* * Platform can override, but note this breaks userland compatibility * with other mips platforms. */ #ifndef CPU_MAXID #define CPU_MAXID 5 /* number of valid machdep ids */ #endif #ifdef _KERNEL #if defined(_LKM) || defined(_STANDALONE) /* Assume all CPU architectures are valid for LKM's and standlone progs */ #define MIPS1 1 #define MIPS3 1 #define MIPS4 1 #define MIPS32 1 #define MIPS64 1 #endif #if (MIPS1 + MIPS3 + MIPS4 + MIPS32 + MIPS64) == 0 #error at least one of MIPS1, MIPS3, MIPS4, MIPS32 or MIPS64 must be specified #endif /* Shortcut for MIPS3 or above defined */ #if defined(MIPS3) || defined(MIPS4) || defined(MIPS32) || defined(MIPS64) #define MIPS3_PLUS 1 #else #undef MIPS3_PLUS #endif /* * Macros to find the CPU architecture we're on at run-time, * or if possible, at compile-time. */ #define CPU_ARCH_MIPSx 0 /* XXX unknown */ #define CPU_ARCH_MIPS1 (1 << 0) #define CPU_ARCH_MIPS2 (1 << 1) #define CPU_ARCH_MIPS3 (1 << 2) #define CPU_ARCH_MIPS4 (1 << 3) #define CPU_ARCH_MIPS5 (1 << 4) #define CPU_ARCH_MIPS32 (1 << 5) #define CPU_ARCH_MIPS64 (1 << 6) /* Note: must be kept in sync with -ffixed-?? Makefile.mips. */ #define MIPS_CURLWP $23 #define MIPS_CURLWP_QUOTED "$23" #define MIPS_CURLWP_CARD 23 #define MIPS_CURLWP_FRAME(x) FRAME_S7(x) #ifndef _LOCORE #define curlwp mips_curlwp #define curcpu() (curlwp->l_cpu) #define curpcb ((struct pcb *)lwp_getpcb(curlwp)) #define fpcurlwp (curcpu()->ci_fpcurlwp) #define cpu_number() (0) #define cpu_proc_fork(p1, p2) ((void)((p2)->p_md.md_abi = (p1)->p_md.md_abi)) /* XXX simonb * Should the following be in a cpu_info type structure? * And how many of these are per-cpu vs. per-system? (Ie, * we can assume that all cpus have the same mmu-type, but * maybe not that all cpus run at the same clock speed. * Some SGI's apparently support R12k and R14k in the same * box.) */ #define CPU_MIPS_R4K_MMU 0x0001 #define CPU_MIPS_NO_LLSC 0x0002 #define CPU_MIPS_CAUSE_IV 0x0004 #define CPU_MIPS_HAVE_SPECIAL_CCA 0x0008 /* Defaults to '3' if not set. */ #define CPU_MIPS_CACHED_CCA_MASK 0x0070 #define CPU_MIPS_CACHED_CCA_SHIFT 4 #define CPU_MIPS_DOUBLE_COUNT 0x0080 /* 1 cp0 count == 2 clock cycles */ #define CPU_MIPS_USE_WAIT 0x0100 /* Use "wait"-based cpu_idle() */ #define CPU_MIPS_NO_WAIT 0x0200 /* Inverse of previous, for mips32/64 */ #define CPU_MIPS_D_CACHE_COHERENT 0x0400 /* D-cache is fully coherent */ #define CPU_MIPS_I_D_CACHE_COHERENT 0x0800 /* I-cache funcs don't need to flush the D-cache */ #define CPU_MIPS_NO_LLADDR 0x1000 #define CPU_MIPS_HAVE_MxCR 0x2000 /* have mfcr, mtcr insns */ #define MIPS_NOT_SUPP 0x8000 #endif /* !_LOCORE */ #if ((MIPS1 + MIPS3 + MIPS4 + MIPS32 + MIPS64) == 1) || defined(_LOCORE) #if defined(MIPS1) # define CPUISMIPS3 0 # define CPUIS64BITS 0 # define CPUISMIPS32 0 # define CPUISMIPS64 0 # define CPUISMIPSNN 0 # define MIPS_HAS_R4K_MMU 0 # define MIPS_HAS_CLOCK 0 # define MIPS_HAS_LLSC 0 # define MIPS_HAS_LLADDR 0 #elif defined(MIPS3) || defined(MIPS4) # define CPUISMIPS3 1 # define CPUIS64BITS 1 # define CPUISMIPS32 0 # define CPUISMIPS64 0 # define CPUISMIPSNN 0 # define MIPS_HAS_R4K_MMU 1 # define MIPS_HAS_CLOCK 1 # if defined(_LOCORE) # if !defined(MIPS3_5900) && !defined(MIPS3_4100) # define MIPS_HAS_LLSC 1 # else # define MIPS_HAS_LLSC 0 # endif # else /* _LOCORE */ # define MIPS_HAS_LLSC (mips_has_llsc) # endif /* _LOCORE */ # define MIPS_HAS_LLADDR ((mips_cpu_flags & CPU_MIPS_NO_LLADDR) == 0) #elif defined(MIPS32) # define CPUISMIPS3 1 # define CPUIS64BITS 0 # define CPUISMIPS32 1 # define CPUISMIPS64 0 # define CPUISMIPSNN 1 # define MIPS_HAS_R4K_MMU 1 # define MIPS_HAS_CLOCK 1 # define MIPS_HAS_LLSC 1 # define MIPS_HAS_LLADDR ((mips_cpu_flags & CPU_MIPS_NO_LLADDR) == 0) #elif defined(MIPS64) # define CPUISMIPS3 1 # define CPUIS64BITS 1 # define CPUISMIPS32 0 # define CPUISMIPS64 1 # define CPUISMIPSNN 1 # define MIPS_HAS_R4K_MMU 1 # define MIPS_HAS_CLOCK 1 # define MIPS_HAS_LLSC 1 # define MIPS_HAS_LLADDR ((mips_cpu_flags & CPU_MIPS_NO_LLADDR) == 0) #endif #else /* run-time test */ #ifndef _LOCORE #define MIPS_HAS_R4K_MMU (mips_has_r4k_mmu) #define MIPS_HAS_LLSC (mips_has_llsc) #define MIPS_HAS_LLADDR ((mips_cpu_flags & CPU_MIPS_NO_LLADDR) == 0) /* This test is ... rather bogus */ #define CPUISMIPS3 ((cpu_arch & \ (CPU_ARCH_MIPS3 | CPU_ARCH_MIPS4 | CPU_ARCH_MIPS32 | CPU_ARCH_MIPS64)) != 0) /* And these aren't much better while the previous test exists as is... */ #define CPUISMIPS32 ((cpu_arch & CPU_ARCH_MIPS32) != 0) #define CPUISMIPS64 ((cpu_arch & CPU_ARCH_MIPS64) != 0) #define CPUISMIPSNN ((cpu_arch & (CPU_ARCH_MIPS32 | CPU_ARCH_MIPS64)) != 0) #define CPUIS64BITS ((cpu_arch & \ (CPU_ARCH_MIPS3 | CPU_ARCH_MIPS4 | CPU_ARCH_MIPS64)) != 0) #define MIPS_HAS_CLOCK (cpu_arch >= CPU_ARCH_MIPS3) #else /* !_LOCORE */ #define MIPS_HAS_LLSC 0 #endif /* !_LOCORE */ #endif /* run-time test */ #ifndef _LOCORE /* * A port must provde CLKF_USERMODE() for use in machine-independent code. * These differ on r4000 and r3000 systems; provide them in the * port-dependent file that includes this one, using the macros below. */ /* mips1 versions */ #define MIPS1_CLKF_USERMODE(framep) ((framep)->sr & MIPS_SR_KU_PREV) /* mips3 versions */ #define MIPS3_CLKF_USERMODE(framep) ((framep)->sr & MIPS_SR_KSU_USER) #define CLKF_PC(framep) ((framep)->pc) #define CLKF_INTR(framep) (0) #if defined(MIPS3_PLUS) && !defined(MIPS1) /* XXX bogus! */ #define CLKF_USERMODE(framep) MIPS3_CLKF_USERMODE(framep) #endif #if !defined(MIPS3_PLUS) && defined(MIPS1) /* XXX bogus! */ #define CLKF_USERMODE(framep) MIPS1_CLKF_USERMODE(framep) #endif #if defined(MIPS3_PLUS) && defined(MIPS1) /* XXX bogus! */ #define CLKF_USERMODE(framep) \ ((CPUISMIPS3) ? MIPS3_CLKF_USERMODE(framep): MIPS1_CLKF_USERMODE(framep)) #endif /* * This is used during profiling to integrate system time. It can safely * assume that the process is resident. */ #define PROC_PC(p) \ (((struct frame *)(p)->p_md.md_regs)->f_regs[37]) /* XXX PC */ /* * Preempt the current process if in interrupt from user mode, * or after the current trap/syscall if in system mode. */ /* * Give a profiling tick to the current process when the user profiling * buffer pages are invalid. On the MIPS, request an ast to send us * through trap, marking the proc as needing a profiling tick. */ #define cpu_need_proftick(l) \ do { \ (l)->l_pflag |= LP_OWEUPC; \ aston(l); \ } while (/*CONSTCOND*/0) /* * Notify the current lwp (l) that it has a signal pending, * process as soon as possible. */ #define cpu_signotify(l) aston(l) #define aston(l) ((l)->l_md.md_astpending = 1) #endif /* ! _LOCORE */ #endif /* _KERNEL */ #endif /* _CPU_H_ */ /* $NetBSD: mips_opcode.h,v 1.13 2009/08/06 04:34:50 msaitoh Exp $ */ /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Ralph Campbell. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. * * @(#)mips_opcode.h 8.1 (Berkeley) 6/10/93 */ /* * Define the instruction formats and opcode values for the * MIPS instruction set. */ /* * Define the instruction formats. */ typedef union { unsigned word; struct { unsigned imm: 16; unsigned rt: 5; unsigned rs: 5; unsigned op: 6; } IType; struct { unsigned target: 26; unsigned op: 6; } JType; struct { unsigned func: 6; unsigned shamt: 5; unsigned rd: 5; unsigned rt: 5; unsigned rs: 5; unsigned op: 6; } RType; struct { unsigned func: 6; unsigned fd: 5; unsigned fs: 5; unsigned ft: 5; unsigned fmt: 4; unsigned : 1; /* always '1' */ unsigned op: 6; /* always '0x11' */ } FRType; } InstFmt; /* * Values for the 'op' field. */ #define OP_SPECIAL 000 #define OP_BCOND 001 #define OP_J 002 #define OP_JAL 003 #define OP_BEQ 004 #define OP_BNE 005 #define OP_BLEZ 006 #define OP_BGTZ 007 #define OP_ADDI 010 #define OP_ADDIU 011 #define OP_SLTI 012 #define OP_SLTIU 013 #define OP_ANDI 014 #define OP_ORI 015 #define OP_XORI 016 #define OP_LUI 017 #define OP_COP0 020 #define OP_COP1 021 #define OP_COP2 022 #define OP_COP3 023 #define OP_BEQL 024 /* MIPS-II, for r4000 port */ #define OP_BNEL 025 /* MIPS-II, for r4000 port */ #define OP_BLEZL 026 /* MIPS-II, for r4000 port */ #define OP_BGTZL 027 /* MIPS-II, for r4000 port */ #define OP_DADDI 030 /* MIPS-II, for r4000 port */ #define OP_DADDIU 031 /* MIPS-II, for r4000 port */ #define OP_LDL 032 /* MIPS-II, for r4000 port */ #define OP_LDR 033 /* MIPS-II, for r4000 port */ #define OP_SPECIAL2 034 /* QED opcodes */ #define OP_LB 040 #define OP_LH 041 #define OP_LWL 042 #define OP_LW 043 #define OP_LBU 044 #define OP_LHU 045 #define OP_LWR 046 #define OP_LHU 045 #define OP_LWR 046 #define OP_LWU 047 /* MIPS-II, for r4000 port */ #define OP_SB 050 #define OP_SH 051 #define OP_SWL 052 #define OP_SW 053 #define OP_SDL 054 /* MIPS-II, for r4000 port */ #define OP_SDR 055 /* MIPS-II, for r4000 port */ #define OP_SWR 056 #define OP_CACHE 057 /* MIPS-II, for r4000 port */ #define OP_LL 060 #define OP_LWC0 OP_LL /* backwards source compatibility */ #define OP_LWC1 061 #define OP_LWC2 062 #define OP_LWC3 063 #define OP_LLD 064 /* MIPS-II, for r4000 port */ #define OP_LDC1 065 #define OP_LD 067 /* MIPS-II, for r4000 port */ #define OP_SC 070 #define OP_SWC0 OP_SC /* backwards source compatibility */ #define OP_SWC1 071 #define OP_SWC2 072 #define OP_SWC3 073 #define OP_SCD 074 /* MIPS-II, for r4000 port */ #define OP_SDC1 075 #define OP_SD 077 /* MIPS-II, for r4000 port */ /* * Values for the 'func' field when 'op' == OP_SPECIAL. */ #define OP_SLL 000 #define OP_SRL 002 #define OP_SRA 003 #define OP_SLLV 004 #define OP_SRLV 006 #define OP_SRAV 007 #define OP_JR 010 #define OP_JALR 011 #define OP_SYSCALL 014 #define OP_BREAK 015 #define OP_SYNC 017 /* MIPS-II, for r4000 port */ #define OP_MFHI 020 #define OP_MTHI 021 #define OP_MFLO 022 #define OP_MTLO 023 #define OP_DSLLV 024 /* MIPS-II, for r4000 port */ #define OP_DSRLV 026 /* MIPS-II, for r4000 port */ #define OP_DSRAV 027 /* MIPS-II, for r4000 port */ #define OP_MULT 030 #define OP_MULTU 031 #define OP_DIV 032 #define OP_DIVU 033 #define OP_DMULT 034 /* MIPS-II, for r4000 port */ #define OP_DMULTU 035 /* MIPS-II, for r4000 port */ #define OP_DDIV 036 /* MIPS-II, for r4000 port */ #define OP_DDIVU 037 /* MIPS-II, for r4000 port */ #define OP_ADD 040 #define OP_ADDU 041 #define OP_SUB 042 #define OP_SUBU 043 #define OP_AND 044 #define OP_OR 045 #define OP_XOR 046 #define OP_NOR 047 #define OP_SLT 052 #define OP_SLTU 053 #define OP_DADD 054 /* MIPS-II, for r4000 port */ #define OP_DADDU 055 /* MIPS-II, for r4000 port */ #define OP_DSUB 056 /* MIPS-II, for r4000 port */ #define OP_DSUBU 057 /* MIPS-II, for r4000 port */ #define OP_TGE 060 /* MIPS-II, for r4000 port */ #define OP_TGEU 061 /* MIPS-II, for r4000 port */ #define OP_TLT 062 /* MIPS-II, for r4000 port */ #define OP_TLTU 063 /* MIPS-II, for r4000 port */ #define OP_TEQ 064 /* MIPS-II, for r4000 port */ #define OP_TNE 066 /* MIPS-II, for r4000 port */ #define OP_DSLL 070 /* MIPS-II, for r4000 port */ #define OP_DSRL 072 /* MIPS-II, for r4000 port */ #define OP_DSRA 073 /* MIPS-II, for r4000 port */ #define OP_DSLL32 074 /* MIPS-II, for r4000 port */ #define OP_DSRL32 076 /* MIPS-II, for r4000 port */ #define OP_DSRA32 077 /* MIPS-II, for r4000 port */ /* * Values for the 'func' field when 'op' == OP_SPECIAL2. */ #define OP_MAD 000 /* QED */ #define OP_MADU 001 /* QED */ #define OP_MUL 002 /* QED */ /* * Values for the 'func' field when 'op' == OP_BCOND. */ #define OP_BLTZ 000 #define OP_BGEZ 001 #define OP_BLTZL 002 /* MIPS-II, for r4000 port */ #define OP_BGEZL 003 /* MIPS-II, for r4000 port */ #define OP_TGEI 010 /* MIPS-II, for r4000 port */ #define OP_TGEIU 011 /* MIPS-II, for r4000 port */ #define OP_TLTI 012 /* MIPS-II, for r4000 port */ #define OP_TLTIU 013 /* MIPS-II, for r4000 port */ #define OP_TEQI 014 /* MIPS-II, for r4000 port */ #define OP_TNEI 016 /* MIPS-II, for r4000 port */ #define OP_BLTZAL 020 /* MIPS-II, for r4000 port */ #define OP_BGEZAL 021 #define OP_BLTZALL 022 #define OP_BGEZALL 023 /* * Values for the 'rs' field when 'op' == OP_COPz. */ #define OP_MF 000 #define OP_DMF 001 /* MIPS-II, for r4000 port */ #define OP_CF 002 #define OP_MFH 003 #define OP_MT 004 #define OP_DMT 005 /* MIPS-II, for r4000 port */ #define OP_CT 006 #define OP_MTH 007 #define OP_BCx 010 #define OP_BCy 014 /* * Values for the 'rt' field when 'op' == OP_COPz. */ #define COPz_BC_TF_MASK 0x01 #define COPz_BC_TRUE 0x01 #define COPz_BC_FALSE 0x00 #define COPz_BCL_TF_MASK 0x02 /* MIPS-II, for r4000 port */ #define COPz_BCL_TRUE 0x02 /* MIPS-II, for r4000 port */ #define COPz_BCL_FALSE 0x00 /* MIPS-II, for r4000 port */ #endif /* __DECODER_LOCAL_H__ */ mupen64plus-rsp-hle/RELEASE000664 001750 001750 00000003607 12655644434 016502 0ustar00sergiosergio000000 000000 RSP High-Level Emulation plugin for Mupen64Plus ----------------------------------------------- Mupen64Plus-rsp-hle v2.0 - July 4, 2013 ------------------------------------------------- - Add support for MusyX ucode detection - support JPEG decoding used in Pokemon Stadium Japan - lots of refactoring to clean up code - Project files for Visual Studio 2012 - Makefile changes - add support for PowerPC and MinGW32 builds - add cross-compiling support to build Win32 executables (MXE) under Linux Mupen64Plus-rsp-hle v1.99.5 - March 10, 2012 ------------------------------------------------- - Handle JPEG decompression, used in Ogre Battle 64 and Pokemon Stadium - updated RSP plugin for new Mupen64plus 2.0 API versioning scheme - bugfix: #102 - Missing backgrounds in Ogre Battle 64 - many makefile fixes and improvements Mupen64Plus-rsp-hle v1.99.4 - November 22, 2010 ------------------------------------------------- - merged all big-endian fixes from mupen64gc project - makefile fixes and improvements Mupen64Plus-rsp-hle v1.99.3 - February 13, 2010 ------------------------------------------------- - Makefile improvement: added OS type GNU/kFreeBSD Mupen64Plus-rsp-hle v1.99.2 - January 6, 2010 ------------------------------------------------- - new feature: added MSVC8 project file for RSP-HLE plugin, fixed a few minor incompatibilities - Makefile improvements: - throw error if OS/CPU not supported - use DESTDIR in install/uninstall paths - Allow user-specified CC/CXX/LD paths - use C++ compiler to link instead of LD, because the compiler knows where the standard C++ libs are Mupen64Plus-rsp-hle v1.99.1 - December 14, 2009 ------------------------------------------------- - Converted to new Mupen64Plus 2.0 API - Refactored build system to separate source and object files - Refactored all code to remove win32-specific things, unnecessary functions, and clean up mupen64plus-rsp-hle/src/mp3.c000664 001750 001750 00000074167 12655644434 017142 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-rsp-hle - mp3.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * Copyright (C) 2009 Richard Goedeken * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include "arithmetics.h" #include "hle_internal.h" #include "memory.h" static void InnerLoop(struct hle_t* hle, uint32_t outPtr, uint32_t inPtr, uint32_t t6, uint32_t t5, uint32_t t4); static const uint16_t DeWindowLUT [0x420] = { 0x0000, 0xFFF3, 0x005D, 0xFF38, 0x037A, 0xF736, 0x0B37, 0xC00E, 0x7FFF, 0x3FF2, 0x0B37, 0x08CA, 0x037A, 0x00C8, 0x005D, 0x000D, 0x0000, 0xFFF3, 0x005D, 0xFF38, 0x037A, 0xF736, 0x0B37, 0xC00E, 0x7FFF, 0x3FF2, 0x0B37, 0x08CA, 0x037A, 0x00C8, 0x005D, 0x000D, 0x0000, 0xFFF2, 0x005F, 0xFF1D, 0x0369, 0xF697, 0x0A2A, 0xBCE7, 0x7FEB, 0x3CCB, 0x0C2B, 0x082B, 0x0385, 0x00AF, 0x005B, 0x000B, 0x0000, 0xFFF2, 0x005F, 0xFF1D, 0x0369, 0xF697, 0x0A2A, 0xBCE7, 0x7FEB, 0x3CCB, 0x0C2B, 0x082B, 0x0385, 0x00AF, 0x005B, 0x000B, 0x0000, 0xFFF1, 0x0061, 0xFF02, 0x0354, 0xF5F9, 0x0905, 0xB9C4, 0x7FB0, 0x39A4, 0x0D08, 0x078C, 0x038C, 0x0098, 0x0058, 0x000A, 0x0000, 0xFFF1, 0x0061, 0xFF02, 0x0354, 0xF5F9, 0x0905, 0xB9C4, 0x7FB0, 0x39A4, 0x0D08, 0x078C, 0x038C, 0x0098, 0x0058, 0x000A, 0x0000, 0xFFEF, 0x0062, 0xFEE6, 0x033B, 0xF55C, 0x07C8, 0xB6A4, 0x7F4D, 0x367E, 0x0DCE, 0x06EE, 0x038F, 0x0080, 0x0056, 0x0009, 0x0000, 0xFFEF, 0x0062, 0xFEE6, 0x033B, 0xF55C, 0x07C8, 0xB6A4, 0x7F4D, 0x367E, 0x0DCE, 0x06EE, 0x038F, 0x0080, 0x0056, 0x0009, 0x0000, 0xFFEE, 0x0063, 0xFECA, 0x031C, 0xF4C3, 0x0671, 0xB38C, 0x7EC2, 0x335D, 0x0E7C, 0x0652, 0x038E, 0x006B, 0x0053, 0x0008, 0x0000, 0xFFEE, 0x0063, 0xFECA, 0x031C, 0xF4C3, 0x0671, 0xB38C, 0x7EC2, 0x335D, 0x0E7C, 0x0652, 0x038E, 0x006B, 0x0053, 0x0008, 0x0000, 0xFFEC, 0x0064, 0xFEAC, 0x02F7, 0xF42C, 0x0502, 0xB07C, 0x7E12, 0x3041, 0x0F14, 0x05B7, 0x038A, 0x0056, 0x0050, 0x0007, 0x0000, 0xFFEC, 0x0064, 0xFEAC, 0x02F7, 0xF42C, 0x0502, 0xB07C, 0x7E12, 0x3041, 0x0F14, 0x05B7, 0x038A, 0x0056, 0x0050, 0x0007, 0x0000, 0xFFEB, 0x0064, 0xFE8E, 0x02CE, 0xF399, 0x037A, 0xAD75, 0x7D3A, 0x2D2C, 0x0F97, 0x0520, 0x0382, 0x0043, 0x004D, 0x0007, 0x0000, 0xFFEB, 0x0064, 0xFE8E, 0x02CE, 0xF399, 0x037A, 0xAD75, 0x7D3A, 0x2D2C, 0x0F97, 0x0520, 0x0382, 0x0043, 0x004D, 0x0007, 0xFFFF, 0xFFE9, 0x0063, 0xFE6F, 0x029E, 0xF30B, 0x01D8, 0xAA7B, 0x7C3D, 0x2A1F, 0x1004, 0x048B, 0x0377, 0x0030, 0x004A, 0x0006, 0xFFFF, 0xFFE9, 0x0063, 0xFE6F, 0x029E, 0xF30B, 0x01D8, 0xAA7B, 0x7C3D, 0x2A1F, 0x1004, 0x048B, 0x0377, 0x0030, 0x004A, 0x0006, 0xFFFF, 0xFFE7, 0x0062, 0xFE4F, 0x0269, 0xF282, 0x001F, 0xA78D, 0x7B1A, 0x271C, 0x105D, 0x03F9, 0x036A, 0x001F, 0x0046, 0x0006, 0xFFFF, 0xFFE7, 0x0062, 0xFE4F, 0x0269, 0xF282, 0x001F, 0xA78D, 0x7B1A, 0x271C, 0x105D, 0x03F9, 0x036A, 0x001F, 0x0046, 0x0006, 0xFFFF, 0xFFE4, 0x0061, 0xFE2F, 0x022F, 0xF1FF, 0xFE4C, 0xA4AF, 0x79D3, 0x2425, 0x10A2, 0x036C, 0x0359, 0x0010, 0x0043, 0x0005, 0xFFFF, 0xFFE4, 0x0061, 0xFE2F, 0x022F, 0xF1FF, 0xFE4C, 0xA4AF, 0x79D3, 0x2425, 0x10A2, 0x036C, 0x0359, 0x0010, 0x0043, 0x0005, 0xFFFF, 0xFFE2, 0x005E, 0xFE10, 0x01EE, 0xF184, 0xFC61, 0xA1E1, 0x7869, 0x2139, 0x10D3, 0x02E3, 0x0346, 0x0001, 0x0040, 0x0004, 0xFFFF, 0xFFE2, 0x005E, 0xFE10, 0x01EE, 0xF184, 0xFC61, 0xA1E1, 0x7869, 0x2139, 0x10D3, 0x02E3, 0x0346, 0x0001, 0x0040, 0x0004, 0xFFFF, 0xFFE0, 0x005B, 0xFDF0, 0x01A8, 0xF111, 0xFA5F, 0x9F27, 0x76DB, 0x1E5C, 0x10F2, 0x025E, 0x0331, 0xFFF3, 0x003D, 0x0004, 0xFFFF, 0xFFE0, 0x005B, 0xFDF0, 0x01A8, 0xF111, 0xFA5F, 0x9F27, 0x76DB, 0x1E5C, 0x10F2, 0x025E, 0x0331, 0xFFF3, 0x003D, 0x0004, 0xFFFF, 0xFFDE, 0x0057, 0xFDD0, 0x015B, 0xF0A7, 0xF845, 0x9C80, 0x752C, 0x1B8E, 0x1100, 0x01DE, 0x0319, 0xFFE7, 0x003A, 0x0003, 0xFFFF, 0xFFDE, 0x0057, 0xFDD0, 0x015B, 0xF0A7, 0xF845, 0x9C80, 0x752C, 0x1B8E, 0x1100, 0x01DE, 0x0319, 0xFFE7, 0x003A, 0x0003, 0xFFFE, 0xFFDB, 0x0053, 0xFDB0, 0x0108, 0xF046, 0xF613, 0x99EE, 0x735C, 0x18D1, 0x10FD, 0x0163, 0x0300, 0xFFDC, 0x0037, 0x0003, 0xFFFE, 0xFFDB, 0x0053, 0xFDB0, 0x0108, 0xF046, 0xF613, 0x99EE, 0x735C, 0x18D1, 0x10FD, 0x0163, 0x0300, 0xFFDC, 0x0037, 0x0003, 0xFFFE, 0xFFD8, 0x004D, 0xFD90, 0x00B0, 0xEFF0, 0xF3CC, 0x9775, 0x716C, 0x1624, 0x10EA, 0x00EE, 0x02E5, 0xFFD2, 0x0033, 0x0003, 0xFFFE, 0xFFD8, 0x004D, 0xFD90, 0x00B0, 0xEFF0, 0xF3CC, 0x9775, 0x716C, 0x1624, 0x10EA, 0x00EE, 0x02E5, 0xFFD2, 0x0033, 0x0003, 0xFFFE, 0xFFD6, 0x0047, 0xFD72, 0x0051, 0xEFA6, 0xF16F, 0x9514, 0x6F5E, 0x138A, 0x10C8, 0x007E, 0x02CA, 0xFFC9, 0x0030, 0x0003, 0xFFFE, 0xFFD6, 0x0047, 0xFD72, 0x0051, 0xEFA6, 0xF16F, 0x9514, 0x6F5E, 0x138A, 0x10C8, 0x007E, 0x02CA, 0xFFC9, 0x0030, 0x0003, 0xFFFE, 0xFFD3, 0x0040, 0xFD54, 0xFFEC, 0xEF68, 0xEEFC, 0x92CD, 0x6D33, 0x1104, 0x1098, 0x0014, 0x02AC, 0xFFC0, 0x002D, 0x0002, 0xFFFE, 0xFFD3, 0x0040, 0xFD54, 0xFFEC, 0xEF68, 0xEEFC, 0x92CD, 0x6D33, 0x1104, 0x1098, 0x0014, 0x02AC, 0xFFC0, 0x002D, 0x0002, 0x0030, 0xFFC9, 0x02CA, 0x007E, 0x10C8, 0x138A, 0x6F5E, 0x9514, 0xF16F, 0xEFA6, 0x0051, 0xFD72, 0x0047, 0xFFD6, 0xFFFE, 0x0003, 0x0030, 0xFFC9, 0x02CA, 0x007E, 0x10C8, 0x138A, 0x6F5E, 0x9514, 0xF16F, 0xEFA6, 0x0051, 0xFD72, 0x0047, 0xFFD6, 0xFFFE, 0x0003, 0x0033, 0xFFD2, 0x02E5, 0x00EE, 0x10EA, 0x1624, 0x716C, 0x9775, 0xF3CC, 0xEFF0, 0x00B0, 0xFD90, 0x004D, 0xFFD8, 0xFFFE, 0x0003, 0x0033, 0xFFD2, 0x02E5, 0x00EE, 0x10EA, 0x1624, 0x716C, 0x9775, 0xF3CC, 0xEFF0, 0x00B0, 0xFD90, 0x004D, 0xFFD8, 0xFFFE, 0x0003, 0x0037, 0xFFDC, 0x0300, 0x0163, 0x10FD, 0x18D1, 0x735C, 0x99EE, 0xF613, 0xF046, 0x0108, 0xFDB0, 0x0053, 0xFFDB, 0xFFFE, 0x0003, 0x0037, 0xFFDC, 0x0300, 0x0163, 0x10FD, 0x18D1, 0x735C, 0x99EE, 0xF613, 0xF046, 0x0108, 0xFDB0, 0x0053, 0xFFDB, 0xFFFE, 0x0003, 0x003A, 0xFFE7, 0x0319, 0x01DE, 0x1100, 0x1B8E, 0x752C, 0x9C80, 0xF845, 0xF0A7, 0x015B, 0xFDD0, 0x0057, 0xFFDE, 0xFFFF, 0x0003, 0x003A, 0xFFE7, 0x0319, 0x01DE, 0x1100, 0x1B8E, 0x752C, 0x9C80, 0xF845, 0xF0A7, 0x015B, 0xFDD0, 0x0057, 0xFFDE, 0xFFFF, 0x0004, 0x003D, 0xFFF3, 0x0331, 0x025E, 0x10F2, 0x1E5C, 0x76DB, 0x9F27, 0xFA5F, 0xF111, 0x01A8, 0xFDF0, 0x005B, 0xFFE0, 0xFFFF, 0x0004, 0x003D, 0xFFF3, 0x0331, 0x025E, 0x10F2, 0x1E5C, 0x76DB, 0x9F27, 0xFA5F, 0xF111, 0x01A8, 0xFDF0, 0x005B, 0xFFE0, 0xFFFF, 0x0004, 0x0040, 0x0001, 0x0346, 0x02E3, 0x10D3, 0x2139, 0x7869, 0xA1E1, 0xFC61, 0xF184, 0x01EE, 0xFE10, 0x005E, 0xFFE2, 0xFFFF, 0x0004, 0x0040, 0x0001, 0x0346, 0x02E3, 0x10D3, 0x2139, 0x7869, 0xA1E1, 0xFC61, 0xF184, 0x01EE, 0xFE10, 0x005E, 0xFFE2, 0xFFFF, 0x0005, 0x0043, 0x0010, 0x0359, 0x036C, 0x10A2, 0x2425, 0x79D3, 0xA4AF, 0xFE4C, 0xF1FF, 0x022F, 0xFE2F, 0x0061, 0xFFE4, 0xFFFF, 0x0005, 0x0043, 0x0010, 0x0359, 0x036C, 0x10A2, 0x2425, 0x79D3, 0xA4AF, 0xFE4C, 0xF1FF, 0x022F, 0xFE2F, 0x0061, 0xFFE4, 0xFFFF, 0x0006, 0x0046, 0x001F, 0x036A, 0x03F9, 0x105D, 0x271C, 0x7B1A, 0xA78D, 0x001F, 0xF282, 0x0269, 0xFE4F, 0x0062, 0xFFE7, 0xFFFF, 0x0006, 0x0046, 0x001F, 0x036A, 0x03F9, 0x105D, 0x271C, 0x7B1A, 0xA78D, 0x001F, 0xF282, 0x0269, 0xFE4F, 0x0062, 0xFFE7, 0xFFFF, 0x0006, 0x004A, 0x0030, 0x0377, 0x048B, 0x1004, 0x2A1F, 0x7C3D, 0xAA7B, 0x01D8, 0xF30B, 0x029E, 0xFE6F, 0x0063, 0xFFE9, 0xFFFF, 0x0006, 0x004A, 0x0030, 0x0377, 0x048B, 0x1004, 0x2A1F, 0x7C3D, 0xAA7B, 0x01D8, 0xF30B, 0x029E, 0xFE6F, 0x0063, 0xFFE9, 0xFFFF, 0x0007, 0x004D, 0x0043, 0x0382, 0x0520, 0x0F97, 0x2D2C, 0x7D3A, 0xAD75, 0x037A, 0xF399, 0x02CE, 0xFE8E, 0x0064, 0xFFEB, 0x0000, 0x0007, 0x004D, 0x0043, 0x0382, 0x0520, 0x0F97, 0x2D2C, 0x7D3A, 0xAD75, 0x037A, 0xF399, 0x02CE, 0xFE8E, 0x0064, 0xFFEB, 0x0000, 0x0007, 0x0050, 0x0056, 0x038A, 0x05B7, 0x0F14, 0x3041, 0x7E12, 0xB07C, 0x0502, 0xF42C, 0x02F7, 0xFEAC, 0x0064, 0xFFEC, 0x0000, 0x0007, 0x0050, 0x0056, 0x038A, 0x05B7, 0x0F14, 0x3041, 0x7E12, 0xB07C, 0x0502, 0xF42C, 0x02F7, 0xFEAC, 0x0064, 0xFFEC, 0x0000, 0x0008, 0x0053, 0x006B, 0x038E, 0x0652, 0x0E7C, 0x335D, 0x7EC2, 0xB38C, 0x0671, 0xF4C3, 0x031C, 0xFECA, 0x0063, 0xFFEE, 0x0000, 0x0008, 0x0053, 0x006B, 0x038E, 0x0652, 0x0E7C, 0x335D, 0x7EC2, 0xB38C, 0x0671, 0xF4C3, 0x031C, 0xFECA, 0x0063, 0xFFEE, 0x0000, 0x0009, 0x0056, 0x0080, 0x038F, 0x06EE, 0x0DCE, 0x367E, 0x7F4D, 0xB6A4, 0x07C8, 0xF55C, 0x033B, 0xFEE6, 0x0062, 0xFFEF, 0x0000, 0x0009, 0x0056, 0x0080, 0x038F, 0x06EE, 0x0DCE, 0x367E, 0x7F4D, 0xB6A4, 0x07C8, 0xF55C, 0x033B, 0xFEE6, 0x0062, 0xFFEF, 0x0000, 0x000A, 0x0058, 0x0098, 0x038C, 0x078C, 0x0D08, 0x39A4, 0x7FB0, 0xB9C4, 0x0905, 0xF5F9, 0x0354, 0xFF02, 0x0061, 0xFFF1, 0x0000, 0x000A, 0x0058, 0x0098, 0x038C, 0x078C, 0x0D08, 0x39A4, 0x7FB0, 0xB9C4, 0x0905, 0xF5F9, 0x0354, 0xFF02, 0x0061, 0xFFF1, 0x0000, 0x000B, 0x005B, 0x00AF, 0x0385, 0x082B, 0x0C2B, 0x3CCB, 0x7FEB, 0xBCE7, 0x0A2A, 0xF697, 0x0369, 0xFF1D, 0x005F, 0xFFF2, 0x0000, 0x000B, 0x005B, 0x00AF, 0x0385, 0x082B, 0x0C2B, 0x3CCB, 0x7FEB, 0xBCE7, 0x0A2A, 0xF697, 0x0369, 0xFF1D, 0x005F, 0xFFF2, 0x0000, 0x000D, 0x005D, 0x00C8, 0x037A, 0x08CA, 0x0B37, 0x3FF2, 0x7FFF, 0xC00E, 0x0B37, 0xF736, 0x037A, 0xFF38, 0x005D, 0xFFF3, 0x0000, 0x000D, 0x005D, 0x00C8, 0x037A, 0x08CA, 0x0B37, 0x3FF2, 0x7FFF, 0xC00E, 0x0B37, 0xF736, 0x037A, 0xFF38, 0x005D, 0xFFF3, 0x0000, 0x0000 }; static void MP3AB0(int32_t* v) { /* Part 2 - 100% Accurate */ static const uint16_t LUT2[8] = { 0xFEC4, 0xF4FA, 0xC5E4, 0xE1C4, 0x1916, 0x4A50, 0xA268, 0x78AE }; static const uint16_t LUT3[4] = { 0xFB14, 0xD4DC, 0x31F2, 0x8E3A }; int i; for (i = 0; i < 8; i++) { v[16 + i] = v[0 + i] + v[8 + i]; v[24 + i] = ((v[0 + i] - v[8 + i]) * LUT2[i]) >> 0x10; } /* Part 3: 4-wide butterflies */ for (i = 0; i < 4; i++) { v[0 + i] = v[16 + i] + v[20 + i]; v[4 + i] = ((v[16 + i] - v[20 + i]) * LUT3[i]) >> 0x10; v[8 + i] = v[24 + i] + v[28 + i]; v[12 + i] = ((v[24 + i] - v[28 + i]) * LUT3[i]) >> 0x10; } /* Part 4: 2-wide butterflies - 100% Accurate */ for (i = 0; i < 16; i += 4) { v[16 + i] = v[0 + i] + v[2 + i]; v[18 + i] = ((v[0 + i] - v[2 + i]) * 0xEC84) >> 0x10; v[17 + i] = v[1 + i] + v[3 + i]; v[19 + i] = ((v[1 + i] - v[3 + i]) * 0x61F8) >> 0x10; } } void mp3_task(struct hle_t* hle, unsigned int index, uint32_t address) { uint32_t t6;/* = 0x08A0; - I think these are temporary storage buffers */ uint32_t t5;/* = 0x0AC0; */ uint32_t t4;/* = (w1 & 0x1E); */ /* Initialization Code */ uint32_t readPtr; /* s5 */ uint32_t writePtr; /* s6 */ uint32_t tmp; int cnt, cnt2; /* I think these are temporary storage buffers */ t6 = 0x08A0; t5 = 0x0AC0; t4 = index; writePtr = readPtr = address; /* Just do that for efficiency... may remove and use directly later anyway */ memcpy(hle->mp3_buffer + 0xCE8, hle->dram + readPtr, 8); /* This must be a header byte or whatnot */ readPtr += 8; for (cnt = 0; cnt < 0x480; cnt += 0x180) { uint32_t inPtr, outPtr; /* DMA: 0xCF0 <- RDRAM[s5] : 0x180 */ memcpy(hle->mp3_buffer + 0xCF0, hle->dram + readPtr, 0x180); inPtr = 0xCF0; /* s7 */ outPtr = 0xE70; /* s3 */ /* --------------- Inner Loop Start -------------------- */ for (cnt2 = 0; cnt2 < 0x180; cnt2 += 0x40) { t6 &= 0xFFE0; t5 &= 0xFFE0; t6 |= t4; t5 |= t4; InnerLoop(hle, outPtr, inPtr, t6, t5, t4); t4 = (t4 - 2) & 0x1E; tmp = t6; t6 = t5; t5 = tmp; inPtr += 0x40; outPtr += 0x40; } /* --------------- Inner Loop End -------------------- */ memcpy(hle->dram + writePtr, hle->mp3_buffer + 0xe70, 0x180); writePtr += 0x180; readPtr += 0x180; } } static void InnerLoop(struct hle_t* hle, uint32_t outPtr, uint32_t inPtr, uint32_t t6, uint32_t t5, uint32_t t4) { /* Part 1: 100% Accurate */ /* 0, 1, 3, 2, 7, 6, 4, 5, 7, 6, 4, 5, 0, 1, 3, 2 */ static const uint16_t LUT6[16] = { 0xFFB2, 0xFD3A, 0xF10A, 0xF854, 0xBDAE, 0xCDA0, 0xE76C, 0xDB94, 0x1920, 0x4B20, 0xAC7C, 0x7C68, 0xABEC, 0x9880, 0xDAE8, 0x839C }; int i; uint32_t t0; uint32_t t1; uint32_t t2; uint32_t t3; int32_t v2 = 0, v4 = 0, v6 = 0, v8 = 0; uint32_t offset; uint32_t addptr; int x; int32_t mult6; int32_t mult4; int tmp; int32_t hi0; int32_t hi1; int32_t v[32]; v[0] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x00 ^ S16)); v[31] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x3E ^ S16)); v[0] += v[31]; v[1] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x02 ^ S16)); v[30] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x3C ^ S16)); v[1] += v[30]; v[2] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x06 ^ S16)); v[28] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x38 ^ S16)); v[2] += v[28]; v[3] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x04 ^ S16)); v[29] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x3A ^ S16)); v[3] += v[29]; v[4] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x0E ^ S16)); v[24] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x30 ^ S16)); v[4] += v[24]; v[5] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x0C ^ S16)); v[25] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x32 ^ S16)); v[5] += v[25]; v[6] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x08 ^ S16)); v[27] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x36 ^ S16)); v[6] += v[27]; v[7] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x0A ^ S16)); v[26] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x34 ^ S16)); v[7] += v[26]; v[8] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x1E ^ S16)); v[16] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x20 ^ S16)); v[8] += v[16]; v[9] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x1C ^ S16)); v[17] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x22 ^ S16)); v[9] += v[17]; v[10] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x18 ^ S16)); v[19] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x26 ^ S16)); v[10] += v[19]; v[11] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x1A ^ S16)); v[18] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x24 ^ S16)); v[11] += v[18]; v[12] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x10 ^ S16)); v[23] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x2E ^ S16)); v[12] += v[23]; v[13] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x12 ^ S16)); v[22] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x2C ^ S16)); v[13] += v[22]; v[14] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x16 ^ S16)); v[20] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x28 ^ S16)); v[14] += v[20]; v[15] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x14 ^ S16)); v[21] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x2A ^ S16)); v[15] += v[21]; /* Part 2-4 */ MP3AB0(v); /* Part 5 - 1-Wide Butterflies - 100% Accurate but need SSVs!!! */ t0 = t6 + 0x100; t1 = t6 + 0x200; t2 = t5 + 0x100; t3 = t5 + 0x200; /* 0x13A8 */ v[1] = 0; v[11] = ((v[16] - v[17]) * 0xB504) >> 0x10; v[16] = -v[16] - v[17]; v[2] = v[18] + v[19]; /* ** Store v[11] -> (T6 + 0)** */ *(int16_t *)(hle->mp3_buffer + ((t6 + (short)0x0))) = (short)v[11]; v[11] = -v[11]; /* ** Store v[16] -> (T3 + 0)** */ *(int16_t *)(hle->mp3_buffer + ((t3 + (short)0x0))) = (short)v[16]; /* ** Store v[11] -> (T5 + 0)** */ *(int16_t *)(hle->mp3_buffer + ((t5 + (short)0x0))) = (short)v[11]; /* 0x13E8 - Verified.... */ v[2] = -v[2]; /* ** Store v[2] -> (T2 + 0)** */ *(int16_t *)(hle->mp3_buffer + ((t2 + (short)0x0))) = (short)v[2]; v[3] = (((v[18] - v[19]) * 0x16A09) >> 0x10) + v[2]; /* ** Store v[3] -> (T0 + 0)** */ *(int16_t *)(hle->mp3_buffer + ((t0 + (short)0x0))) = (short)v[3]; /* 0x1400 - Verified */ v[4] = -v[20] - v[21]; v[6] = v[22] + v[23]; v[5] = ((v[20] - v[21]) * 0x16A09) >> 0x10; /* ** Store v[4] -> (T3 + 0xFF80) */ *(int16_t *)(hle->mp3_buffer + ((t3 + (short)0xFF80))) = (short)v[4]; v[7] = ((v[22] - v[23]) * 0x2D413) >> 0x10; v[5] = v[5] - v[4]; v[7] = v[7] - v[5]; v[6] = v[6] + v[6]; v[5] = v[5] - v[6]; v[4] = -v[4] - v[6]; /* *** Store v[7] -> (T1 + 0xFF80) */ *(int16_t *)(hle->mp3_buffer + ((t1 + (short)0xFF80))) = (short)v[7]; /* *** Store v[4] -> (T2 + 0xFF80) */ *(int16_t *)(hle->mp3_buffer + ((t2 + (short)0xFF80))) = (short)v[4]; /* *** Store v[5] -> (T0 + 0xFF80) */ *(int16_t *)(hle->mp3_buffer + ((t0 + (short)0xFF80))) = (short)v[5]; v[8] = v[24] + v[25]; v[9] = ((v[24] - v[25]) * 0x16A09) >> 0x10; v[2] = v[8] + v[9]; v[11] = ((v[26] - v[27]) * 0x2D413) >> 0x10; v[13] = ((v[28] - v[29]) * 0x2D413) >> 0x10; v[10] = v[26] + v[27]; v[10] = v[10] + v[10]; v[12] = v[28] + v[29]; v[12] = v[12] + v[12]; v[14] = v[30] + v[31]; v[3] = v[8] + v[10]; v[14] = v[14] + v[14]; v[13] = (v[13] - v[2]) + v[12]; v[15] = (((v[30] - v[31]) * 0x5A827) >> 0x10) - (v[11] + v[2]); v[14] = -(v[14] + v[14]) + v[3]; v[17] = v[13] - v[10]; v[9] = v[9] + v[14]; /* ** Store v[9] -> (T6 + 0x40) */ *(int16_t *)(hle->mp3_buffer + ((t6 + (short)0x40))) = (short)v[9]; v[11] = v[11] - v[13]; /* ** Store v[17] -> (T0 + 0xFFC0) */ *(int16_t *)(hle->mp3_buffer + ((t0 + (short)0xFFC0))) = (short)v[17]; v[12] = v[8] - v[12]; /* ** Store v[11] -> (T0 + 0x40) */ *(int16_t *)(hle->mp3_buffer + ((t0 + (short)0x40))) = (short)v[11]; v[8] = -v[8]; /* ** Store v[15] -> (T1 + 0xFFC0) */ *(int16_t *)(hle->mp3_buffer + ((t1 + (short)0xFFC0))) = (short)v[15]; v[10] = -v[10] - v[12]; /* ** Store v[12] -> (T2 + 0x40) */ *(int16_t *)(hle->mp3_buffer + ((t2 + (short)0x40))) = (short)v[12]; /* ** Store v[8] -> (T3 + 0xFFC0) */ *(int16_t *)(hle->mp3_buffer + ((t3 + (short)0xFFC0))) = (short)v[8]; /* ** Store v[14] -> (T5 + 0x40) */ *(int16_t *)(hle->mp3_buffer + ((t5 + (short)0x40))) = (short)v[14]; /* ** Store v[10] -> (T2 + 0xFFC0) */ *(int16_t *)(hle->mp3_buffer + ((t2 + (short)0xFFC0))) = (short)v[10]; /* 0x14FC - Verified... */ /* Part 6 - 100% Accurate */ v[0] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x00 ^ S16)); v[31] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x3E ^ S16)); v[0] -= v[31]; v[1] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x02 ^ S16)); v[30] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x3C ^ S16)); v[1] -= v[30]; v[2] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x06 ^ S16)); v[28] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x38 ^ S16)); v[2] -= v[28]; v[3] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x04 ^ S16)); v[29] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x3A ^ S16)); v[3] -= v[29]; v[4] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x0E ^ S16)); v[24] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x30 ^ S16)); v[4] -= v[24]; v[5] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x0C ^ S16)); v[25] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x32 ^ S16)); v[5] -= v[25]; v[6] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x08 ^ S16)); v[27] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x36 ^ S16)); v[6] -= v[27]; v[7] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x0A ^ S16)); v[26] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x34 ^ S16)); v[7] -= v[26]; v[8] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x1E ^ S16)); v[16] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x20 ^ S16)); v[8] -= v[16]; v[9] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x1C ^ S16)); v[17] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x22 ^ S16)); v[9] -= v[17]; v[10] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x18 ^ S16)); v[19] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x26 ^ S16)); v[10] -= v[19]; v[11] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x1A ^ S16)); v[18] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x24 ^ S16)); v[11] -= v[18]; v[12] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x10 ^ S16)); v[23] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x2E ^ S16)); v[12] -= v[23]; v[13] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x12 ^ S16)); v[22] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x2C ^ S16)); v[13] -= v[22]; v[14] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x16 ^ S16)); v[20] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x28 ^ S16)); v[14] -= v[20]; v[15] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x14 ^ S16)); v[21] = *(int16_t *)(hle->mp3_buffer + inPtr + (0x2A ^ S16)); v[15] -= v[21]; for (i = 0; i < 16; i++) v[0 + i] = (v[0 + i] * LUT6[i]) >> 0x10; v[0] = v[0] + v[0]; v[1] = v[1] + v[1]; v[2] = v[2] + v[2]; v[3] = v[3] + v[3]; v[4] = v[4] + v[4]; v[5] = v[5] + v[5]; v[6] = v[6] + v[6]; v[7] = v[7] + v[7]; v[12] = v[12] + v[12]; v[13] = v[13] + v[13]; v[15] = v[15] + v[15]; MP3AB0(v); /* Part 7: - 100% Accurate + SSV - Unoptimized */ v[0] = (v[17] + v[16]) >> 1; v[1] = ((v[17] * (int)((short)0xA57E * 2)) + (v[16] * 0xB504)) >> 0x10; v[2] = -v[18] - v[19]; v[3] = ((v[18] - v[19]) * 0x16A09) >> 0x10; v[4] = v[20] + v[21] + v[0]; v[5] = (((v[20] - v[21]) * 0x16A09) >> 0x10) + v[1]; v[6] = (((v[22] + v[23]) << 1) + v[0]) - v[2]; v[7] = (((v[22] - v[23]) * 0x2D413) >> 0x10) + v[0] + v[1] + v[3]; /* 0x16A8 */ /* Save v[0] -> (T3 + 0xFFE0) */ *(int16_t *)(hle->mp3_buffer + ((t3 + (short)0xFFE0))) = (short) - v[0]; v[8] = v[24] + v[25]; v[9] = ((v[24] - v[25]) * 0x16A09) >> 0x10; v[10] = ((v[26] + v[27]) << 1) + v[8]; v[11] = (((v[26] - v[27]) * 0x2D413) >> 0x10) + v[8] + v[9]; v[12] = v[4] - ((v[28] + v[29]) << 1); /* ** Store v12 -> (T2 + 0x20) */ *(int16_t *)(hle->mp3_buffer + ((t2 + (short)0x20))) = (short)v[12]; v[13] = (((v[28] - v[29]) * 0x2D413) >> 0x10) - v[12] - v[5]; v[14] = v[30] + v[31]; v[14] = v[14] + v[14]; v[14] = v[14] + v[14]; v[14] = v[6] - v[14]; v[15] = (((v[30] - v[31]) * 0x5A827) >> 0x10) - v[7]; /* Store v14 -> (T5 + 0x20) */ *(int16_t *)(hle->mp3_buffer + ((t5 + (short)0x20))) = (short)v[14]; v[14] = v[14] + v[1]; /* Store v[14] -> (T6 + 0x20) */ *(int16_t *)(hle->mp3_buffer + ((t6 + (short)0x20))) = (short)v[14]; /* Store v[15] -> (T1 + 0xFFE0) */ *(int16_t *)(hle->mp3_buffer + ((t1 + (short)0xFFE0))) = (short)v[15]; v[9] = v[9] + v[10]; v[1] = v[1] + v[6]; v[6] = v[10] - v[6]; v[1] = v[9] - v[1]; /* Store v[6] -> (T5 + 0x60) */ *(int16_t *)(hle->mp3_buffer + ((t5 + (short)0x60))) = (short)v[6]; v[10] = v[10] + v[2]; v[10] = v[4] - v[10]; /* Store v[10] -> (T2 + 0xFFA0) */ *(int16_t *)(hle->mp3_buffer + ((t2 + (short)0xFFA0))) = (short)v[10]; v[12] = v[2] - v[12]; /* Store v[12] -> (T2 + 0xFFE0) */ *(int16_t *)(hle->mp3_buffer + ((t2 + (short)0xFFE0))) = (short)v[12]; v[5] = v[4] + v[5]; v[4] = v[8] - v[4]; /* Store v[4] -> (T2 + 0x60) */ *(int16_t *)(hle->mp3_buffer + ((t2 + (short)0x60))) = (short)v[4]; v[0] = v[0] - v[8]; /* Store v[0] -> (T3 + 0xFFA0) */ *(int16_t *)(hle->mp3_buffer + ((t3 + (short)0xFFA0))) = (short)v[0]; v[7] = v[7] - v[11]; /* Store v[7] -> (T1 + 0xFFA0) */ *(int16_t *)(hle->mp3_buffer + ((t1 + (short)0xFFA0))) = (short)v[7]; v[11] = v[11] - v[3]; /* Store v[1] -> (T6 + 0x60) */ *(int16_t *)(hle->mp3_buffer + ((t6 + (short)0x60))) = (short)v[1]; v[11] = v[11] - v[5]; /* Store v[11] -> (T0 + 0x60) */ *(int16_t *)(hle->mp3_buffer + ((t0 + (short)0x60))) = (short)v[11]; v[3] = v[3] - v[13]; /* Store v[3] -> (T0 + 0x20) */ *(int16_t *)(hle->mp3_buffer + ((t0 + (short)0x20))) = (short)v[3]; v[13] = v[13] + v[2]; /* Store v[13] -> (T0 + 0xFFE0) */ *(int16_t *)(hle->mp3_buffer + ((t0 + (short)0xFFE0))) = (short)v[13]; v[2] = (v[5] - v[2]) - v[9]; /* Store v[2] -> (T0 + 0xFFA0) */ *(int16_t *)(hle->mp3_buffer + ((t0 + (short)0xFFA0))) = (short)v[2]; /* 0x7A8 - Verified... */ /* Step 8 - Dewindowing */ addptr = t6 & 0xFFE0; offset = 0x10 - (t4 >> 1); for (x = 0; x < 8; x++) { int32_t v0; int32_t v18; v2 = v4 = v6 = v8 = 0; for (i = 7; i >= 0; i--) { v2 += ((int) * (int16_t *)(hle->mp3_buffer + (addptr) + 0x00) * (short)DeWindowLUT[offset + 0x00] + 0x4000) >> 0xF; v4 += ((int) * (int16_t *)(hle->mp3_buffer + (addptr) + 0x10) * (short)DeWindowLUT[offset + 0x08] + 0x4000) >> 0xF; v6 += ((int) * (int16_t *)(hle->mp3_buffer + (addptr) + 0x20) * (short)DeWindowLUT[offset + 0x20] + 0x4000) >> 0xF; v8 += ((int) * (int16_t *)(hle->mp3_buffer + (addptr) + 0x30) * (short)DeWindowLUT[offset + 0x28] + 0x4000) >> 0xF; addptr += 2; offset++; } v0 = v2 + v4; v18 = v6 + v8; /* Clamp(v0); */ /* Clamp(v18); */ /* clamp??? */ *(int16_t *)(hle->mp3_buffer + (outPtr ^ S16)) = v0; *(int16_t *)(hle->mp3_buffer + ((outPtr + 2)^S16)) = v18; outPtr += 4; addptr += 0x30; offset += 0x38; } offset = 0x10 - (t4 >> 1) + 8 * 0x40; v2 = v4 = 0; for (i = 0; i < 4; i++) { v2 += ((int) * (int16_t *)(hle->mp3_buffer + (addptr) + 0x00) * (short)DeWindowLUT[offset + 0x00] + 0x4000) >> 0xF; v2 += ((int) * (int16_t *)(hle->mp3_buffer + (addptr) + 0x10) * (short)DeWindowLUT[offset + 0x08] + 0x4000) >> 0xF; addptr += 2; offset++; v4 += ((int) * (int16_t *)(hle->mp3_buffer + (addptr) + 0x00) * (short)DeWindowLUT[offset + 0x00] + 0x4000) >> 0xF; v4 += ((int) * (int16_t *)(hle->mp3_buffer + (addptr) + 0x10) * (short)DeWindowLUT[offset + 0x08] + 0x4000) >> 0xF; addptr += 2; offset++; } mult6 = *(int32_t *)(hle->mp3_buffer + 0xCE8); mult4 = *(int32_t *)(hle->mp3_buffer + 0xCEC); if (t4 & 0x2) { v2 = (v2 **(uint32_t *)(hle->mp3_buffer + 0xCE8)) >> 0x10; *(int16_t *)(hle->mp3_buffer + (outPtr ^ S16)) = v2; } else { v4 = (v4 **(uint32_t *)(hle->mp3_buffer + 0xCE8)) >> 0x10; *(int16_t *)(hle->mp3_buffer + (outPtr ^ S16)) = v4; mult4 = *(uint32_t *)(hle->mp3_buffer + 0xCE8); } addptr -= 0x50; for (x = 0; x < 8; x++) { int32_t v0; int32_t v18; v2 = v4 = v6 = v8 = 0; offset = (0x22F - (t4 >> 1) + x * 0x40); for (i = 0; i < 4; i++) { v2 += ((int) * (int16_t *)(hle->mp3_buffer + (addptr) + 0x20) * (short)DeWindowLUT[offset + 0x00] + 0x4000) >> 0xF; v2 -= ((int) * (int16_t *)(hle->mp3_buffer + ((addptr + 2)) + 0x20) * (short)DeWindowLUT[offset + 0x01] + 0x4000) >> 0xF; v4 += ((int) * (int16_t *)(hle->mp3_buffer + (addptr) + 0x30) * (short)DeWindowLUT[offset + 0x08] + 0x4000) >> 0xF; v4 -= ((int) * (int16_t *)(hle->mp3_buffer + ((addptr + 2)) + 0x30) * (short)DeWindowLUT[offset + 0x09] + 0x4000) >> 0xF; v6 += ((int) * (int16_t *)(hle->mp3_buffer + (addptr) + 0x00) * (short)DeWindowLUT[offset + 0x20] + 0x4000) >> 0xF; v6 -= ((int) * (int16_t *)(hle->mp3_buffer + ((addptr + 2)) + 0x00) * (short)DeWindowLUT[offset + 0x21] + 0x4000) >> 0xF; v8 += ((int) * (int16_t *)(hle->mp3_buffer + (addptr) + 0x10) * (short)DeWindowLUT[offset + 0x28] + 0x4000) >> 0xF; v8 -= ((int) * (int16_t *)(hle->mp3_buffer + ((addptr + 2)) + 0x10) * (short)DeWindowLUT[offset + 0x29] + 0x4000) >> 0xF; addptr += 4; offset += 2; } v0 = v2 + v4; v18 = v6 + v8; /* Clamp(v0); */ /* Clamp(v18); */ /* clamp??? */ *(int16_t *)(hle->mp3_buffer + ((outPtr + 2)^S16)) = v0; *(int16_t *)(hle->mp3_buffer + ((outPtr + 4)^S16)) = v18; outPtr += 4; addptr -= 0x50; } tmp = outPtr; hi0 = mult6; hi1 = mult4; hi0 = (int)hi0 >> 0x10; hi1 = (int)hi1 >> 0x10; for (i = 0; i < 8; i++) { /* v0 */ int32_t vt = (*(int16_t *)(hle->mp3_buffer + ((tmp - 0x40)^S16)) * hi0); *(int16_t *)((uint8_t *)hle->mp3_buffer + ((tmp - 0x40)^S16)) = clamp_s16(vt); /* v17 */ vt = (*(int16_t *)(hle->mp3_buffer + ((tmp - 0x30)^S16)) * hi0); *(int16_t *)((uint8_t *)hle->mp3_buffer + ((tmp - 0x30)^S16)) = clamp_s16(vt); /* v2 */ vt = (*(int16_t *)(hle->mp3_buffer + ((tmp - 0x1E)^S16)) * hi1); *(int16_t *)((uint8_t *)hle->mp3_buffer + ((tmp - 0x1E)^S16)) = clamp_s16(vt); /* v4 */ vt = (*(int16_t *)(hle->mp3_buffer + ((tmp - 0xE)^S16)) * hi1); *(int16_t *)((uint8_t *)hle->mp3_buffer + ((tmp - 0xE)^S16)) = clamp_s16(vt); tmp += 2; } } mupen64plus-core/src/r4300/ops.h000664 001750 001750 00000020145 12655644434 017362 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - ops.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_R4300_OPS_H #define M64P_R4300_OPS_H typedef struct _cpu_instruction_table { /* All jump/branch instructions (except JR and JALR) have three versions: * - JUMPNAME() which for jumps inside the current block. * - JUMPNAME_OUT() which jumps outside the current block. * - JUMPNAME_IDLE() which does busy wait optimization. * * Busy wait optimization is used when a jump jumps to itself, * and the instruction on the delay slot is a NOP. * The program is waiting for the next interrupt, so we can just * increase Count until the point where the next interrupt happens. */ // Load and store instructions void (*LB)(void); void (*LBU)(void); void (*LH)(void); void (*LHU)(void); void (*LW)(void); void (*LWL)(void); void (*LWR)(void); void (*SB)(void); void (*SH)(void); void (*SW)(void); void (*SWL)(void); void (*SWR)(void); void (*LD)(void); void (*LDL)(void); void (*LDR)(void); void (*LL)(void); void (*LWU)(void); void (*SC)(void); void (*SD)(void); void (*SDL)(void); void (*SDR)(void); void (*SYNC)(void); // Arithmetic instructions (ALU immediate) void (*ADDI)(void); void (*ADDIU)(void); void (*SLTI)(void); void (*SLTIU)(void); void (*ANDI)(void); void (*ORI)(void); void (*XORI)(void); void (*LUI)(void); void (*DADDI)(void); void (*DADDIU)(void); // Arithmetic instructions (3-operand) void (*ADD)(void); void (*ADDU)(void); void (*SUB)(void); void (*SUBU)(void); void (*SLT)(void); void (*SLTU)(void); void (*AND)(void); void (*OR)(void); void (*XOR)(void); void (*NOR)(void); void (*DADD)(void); void (*DADDU)(void); void (*DSUB)(void); void (*DSUBU)(void); // Multiply and divide instructions void (*MULT)(void); void (*MULTU)(void); void (*DIV)(void); void (*DIVU)(void); void (*MFHI)(void); void (*MTHI)(void); void (*MFLO)(void); void (*MTLO)(void); void (*DMULT)(void); void (*DMULTU)(void); void (*DDIV)(void); void (*DDIVU)(void); // Jump and branch instructions void (*J)(void); void (*J_OUT)(void); void (*J_IDLE)(void); void (*JAL)(void); void (*JAL_OUT)(void); void (*JAL_IDLE)(void); void (*JR)(void); void (*JALR)(void); void (*BEQ)(void); void (*BEQ_OUT)(void); void (*BEQ_IDLE)(void); void (*BNE)(void); void (*BNE_OUT)(void); void (*BNE_IDLE)(void); void (*BLEZ)(void); void (*BLEZ_OUT)(void); void (*BLEZ_IDLE)(void); void (*BGTZ)(void); void (*BGTZ_OUT)(void); void (*BGTZ_IDLE)(void); void (*BLTZ)(void); void (*BLTZ_OUT)(void); void (*BLTZ_IDLE)(void); void (*BGEZ)(void); void (*BGEZ_OUT)(void); void (*BGEZ_IDLE)(void); void (*BLTZAL)(void); void (*BLTZAL_OUT)(void); void (*BLTZAL_IDLE)(void); void (*BGEZAL)(void); void (*BGEZAL_OUT)(void); void (*BGEZAL_IDLE)(void); void (*BEQL)(void); void (*BEQL_OUT)(void); void (*BEQL_IDLE)(void); void (*BNEL)(void); void (*BNEL_OUT)(void); void (*BNEL_IDLE)(void); void (*BLEZL)(void); void (*BLEZL_OUT)(void); void (*BLEZL_IDLE)(void); void (*BGTZL)(void); void (*BGTZL_OUT)(void); void (*BGTZL_IDLE)(void); void (*BLTZL)(void); void (*BLTZL_OUT)(void); void (*BLTZL_IDLE)(void); void (*BGEZL)(void); void (*BGEZL_OUT)(void); void (*BGEZL_IDLE)(void); void (*BLTZALL)(void); void (*BLTZALL_OUT)(void); void (*BLTZALL_IDLE)(void); void (*BGEZALL)(void); void (*BGEZALL_OUT)(void); void (*BGEZALL_IDLE)(void); void (*BC1TL)(void); void (*BC1TL_OUT)(void); void (*BC1TL_IDLE)(void); void (*BC1FL)(void); void (*BC1FL_OUT)(void); void (*BC1FL_IDLE)(void); // Shift instructions void (*SLL)(void); void (*SRL)(void); void (*SRA)(void); void (*SLLV)(void); void (*SRLV)(void); void (*SRAV)(void); void (*DSLL)(void); void (*DSRL)(void); void (*DSRA)(void); void (*DSLLV)(void); void (*DSRLV)(void); void (*DSRAV)(void); void (*DSLL32)(void); void (*DSRL32)(void); void (*DSRA32)(void); // COP0 instructions void (*MTC0)(void); void (*MFC0)(void); void (*TLBR)(void); void (*TLBWI)(void); void (*TLBWR)(void); void (*TLBP)(void); void (*CACHE)(void); void (*ERET)(void); // COP1 instructions void (*LWC1)(void); void (*SWC1)(void); void (*MTC1)(void); void (*MFC1)(void); void (*CTC1)(void); void (*CFC1)(void); void (*BC1T)(void); void (*BC1T_OUT)(void); void (*BC1T_IDLE)(void); void (*BC1F)(void); void (*BC1F_OUT)(void); void (*BC1F_IDLE)(void); void (*DMFC1)(void); void (*DMTC1)(void); void (*LDC1)(void); void (*SDC1)(void); void (*CVT_S_D)(void); void (*CVT_S_W)(void); void (*CVT_S_L)(void); void (*CVT_D_S)(void); void (*CVT_D_W)(void); void (*CVT_D_L)(void); void (*CVT_W_S)(void); void (*CVT_W_D)(void); void (*CVT_L_S)(void); void (*CVT_L_D)(void); void (*ROUND_W_S)(void); void (*ROUND_W_D)(void); void (*ROUND_L_S)(void); void (*ROUND_L_D)(void); void (*TRUNC_W_S)(void); void (*TRUNC_W_D)(void); void (*TRUNC_L_S)(void); void (*TRUNC_L_D)(void); void (*CEIL_W_S)(void); void (*CEIL_W_D)(void); void (*CEIL_L_S)(void); void (*CEIL_L_D)(void); void (*FLOOR_W_S)(void); void (*FLOOR_W_D)(void); void (*FLOOR_L_S)(void); void (*FLOOR_L_D)(void); void (*ADD_S)(void); void (*ADD_D)(void); void (*SUB_S)(void); void (*SUB_D)(void); void (*MUL_S)(void); void (*MUL_D)(void); void (*DIV_S)(void); void (*DIV_D)(void); void (*ABS_S)(void); void (*ABS_D)(void); void (*MOV_S)(void); void (*MOV_D)(void); void (*NEG_S)(void); void (*NEG_D)(void); void (*SQRT_S)(void); void (*SQRT_D)(void); void (*C_F_S)(void); void (*C_F_D)(void); void (*C_UN_S)(void); void (*C_UN_D)(void); void (*C_EQ_S)(void); void (*C_EQ_D)(void); void (*C_UEQ_S)(void); void (*C_UEQ_D)(void); void (*C_OLT_S)(void); void (*C_OLT_D)(void); void (*C_ULT_S)(void); void (*C_ULT_D)(void); void (*C_OLE_S)(void); void (*C_OLE_D)(void); void (*C_ULE_S)(void); void (*C_ULE_D)(void); void (*C_SF_S)(void); void (*C_SF_D)(void); void (*C_NGLE_S)(void); void (*C_NGLE_D)(void); void (*C_SEQ_S)(void); void (*C_SEQ_D)(void); void (*C_NGL_S)(void); void (*C_NGL_D)(void); void (*C_LT_S)(void); void (*C_LT_D)(void); void (*C_NGE_S)(void); void (*C_NGE_D)(void); void (*C_LE_S)(void); void (*C_LE_D)(void); void (*C_NGT_S)(void); void (*C_NGT_D)(void); // Special instructions void (*SYSCALL)(void); // Exception instructions void (*TEQ)(void); // Emulator helper functions void (*NOP)(void); // No operation (used to nullify R0 writes) void (*RESERVED)(void); // Reserved instruction handler void (*NI)(void); // Not implemented instruction handler void (*FIN_BLOCK)(void); // Handler for the end of a block void (*NOTCOMPILED)(void); // Handler for not yet compiled code void (*NOTCOMPILED2)(void); // TODOXXX } cpu_instruction_table; #endif /* M64P_R4300_OPS_H_*/ libretro/SDL_opengles.h000664 001750 001750 00000002111 12655644434 016223 0ustar00sergiosergio000000 000000 /* SDL - Simple DirectMedia Layer Copyright (C) 1997-2012 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Sam Lantinga slouken@libsdl.org */ /** @file SDL_opengl.h * This is a simple file to encapsulate the OpenGL API headers */ #ifndef _SDL_OPENGLES2_LIBRETRO_H #define _SDL_OPENGLES2_LIBRETRO_H #include "opengl_state_machine.h" #include "glsym/rglgen.h" #endif gles2rice/src/VectorMath.h000664 001750 001750 00000013731 12655644434 016617 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - VectorMath.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Rice1964 * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef VECTORMATH_H #define VECTORMATH_H /****************************************************************************** * 4x4 matrix ******************************************************************************/ typedef struct _MATRIX { union { struct { float _11, _12, _13, _14; float _21, _22, _23, _24; float _31, _32, _33, _34; float _41, _42, _43, _44; }; float m[4][4]; }; } MATRIX; typedef struct XMATRIX : public MATRIX { public: XMATRIX(); XMATRIX( const float * ); XMATRIX( const MATRIX & ); XMATRIX( float _11, float _12, float _13, float _14, float _21, float _22, float _23, float _24, float _31, float _32, float _33, float _34, float _41, float _42, float _43, float _44 ); float& operator () ( unsigned int Row, unsigned int Col ); float operator () ( unsigned int Row, unsigned int Col ) const; operator float* (); operator const float* () const; // assignment operators XMATRIX& operator *= ( const XMATRIX & ); XMATRIX& operator += ( const XMATRIX & ); XMATRIX& operator -= ( const XMATRIX & ); XMATRIX& operator *= ( float ); XMATRIX& operator /= ( float ); // unary operators XMATRIX operator + () const; XMATRIX operator - () const; // binary operators XMATRIX operator * ( const XMATRIX & ) const; XMATRIX operator + ( const XMATRIX & ) const; XMATRIX operator - ( const XMATRIX & ) const; XMATRIX operator * ( float ) const; XMATRIX operator / ( float ) const; friend XMATRIX operator * ( float, const XMATRIX & ); bool operator == ( const XMATRIX & ) const; bool operator != ( const XMATRIX & ) const; } XMATRIX, *LPXMATRIX; /****************************************************************************** * 3d vector ******************************************************************************/ typedef struct _VECTOR3 { float x; float y; float z; } VECTOR3; class XVECTOR3 : public VECTOR3 { public: XVECTOR3(); XVECTOR3( const float *f ); XVECTOR3( const VECTOR3 &v ); XVECTOR3( float _x, float _y, float _z ); // casting inline operator float* (); inline operator const float* () const; // assignment operators inline XVECTOR3& operator += ( const XVECTOR3 &op ); inline XVECTOR3& operator -= ( const XVECTOR3 &op ); inline XVECTOR3& operator *= ( float op ); inline XVECTOR3& operator /= ( float op ); // unary operators inline XVECTOR3 operator + () const; inline XVECTOR3 operator - () const; // binary operators inline XVECTOR3 operator + ( const XVECTOR3 &op ) const; inline XVECTOR3 operator - ( const XVECTOR3 &op ) const; inline XVECTOR3 operator * ( float op ) const; inline XVECTOR3 operator / ( float op ) const; friend XVECTOR3 operator * ( float, const XVECTOR3& ); inline bool operator == ( const XVECTOR3 &op ) const; inline bool operator != ( const XVECTOR3 &op ) const; }; /****************************************************************************** * 4d vector ******************************************************************************/ typedef struct _VECTOR4 { float x; float y; float z; float w; } VECTOR4; class XVECTOR4 : public VECTOR4 { public: XVECTOR4(); XVECTOR4( const float *f ); XVECTOR4( const VECTOR4 &v ); XVECTOR4( float _x, float _y, float _z, float _w ); // casting inline operator float* (); inline operator const float* () const; // assignment operators inline XVECTOR4& operator += ( const XVECTOR4 &op ); inline XVECTOR4& operator -= ( const XVECTOR4 &op ); inline XVECTOR4& operator *= ( float op ); inline XVECTOR4& operator /= ( float op ); // unary operators inline XVECTOR4 operator + () const; inline XVECTOR4 operator - () const; // binary operators inline XVECTOR4 operator + ( const XVECTOR4 &op ) const; inline XVECTOR4 operator - ( const XVECTOR4 &op ) const; inline XVECTOR4 operator * ( float op ) const; inline XVECTOR4 operator / ( float op ) const; friend XVECTOR4 operator * ( float, const XVECTOR4& ); inline bool operator == ( const XVECTOR4 &op ) const; inline bool operator != ( const XVECTOR4 &op ) const; }; XVECTOR4 Vec3Transform(XVECTOR4 *pOut, const XVECTOR3 *pV, const XMATRIX *pM); XMATRIX* MatrixTranspose(XMATRIX* pOut, const XMATRIX* pM); #endif libretro/opengl_state_machine.h000664 001750 001750 00000017014 12655644434 020065 0ustar00sergiosergio000000 000000 #ifndef OPENGL_STATE_MACHINE_H__ #define OPENGL_STATE_MACHINE_H__ #include #ifdef __cplusplus extern "C" { #endif #ifdef HAVE_OPENGLES2 typedef GLfloat GLdouble; typedef GLclampf GLclampd; #endif #ifndef GL_FOG #define GL_FOG 0x0B60 #endif #ifndef GL_ALPHA_TEST #define GL_ALPHA_TEST 0x0BC0 #endif enum { SGL_DEPTH_TEST, SGL_BLEND, SGL_POLYGON_OFFSET_FILL, SGL_FOG, SGL_CULL_FACE, SGL_ALPHA_TEST, SGL_SCISSOR_TEST, SGL_CAP_MAX }; void sglEnable(GLenum cap); void sglDisable(GLenum cap); GLboolean sglIsEnabled(GLenum cap); void sglDrawArrays(GLenum mode, GLint first, GLsizei count); void sglEnableVertexAttribArray(GLuint index); void sglDisableVertexAttribArray(GLuint index); void sglVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalize, GLsizei stride, const GLvoid* pointer); void sglVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); void sglVertexAttrib4fv(GLuint index, GLfloat* v); void sglGenerateMipmap(GLenum target); void sglCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); void sglGenTextures(GLsizei n, GLuint *textures); void sglUniform1f(GLint location, GLfloat v0); void sglUniform1i(GLint location, GLint v0); void sglUniform2f(GLint location, GLfloat v0, GLfloat v1); void sglUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); void sglUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); void sglUniform4fv(GLint location, GLsizei count, const GLfloat *value); int sglGetUniformLocation(GLuint program, const GLchar *name); void sglGetShaderInfoLog(GLuint shader, GLsizei maxLength, GLsizei *length, GLchar *infoLog); void sglGetProgramInfoLog(GLuint shader, GLsizei maxLength, GLsizei *length, GLchar *infoLog); void sglBindFramebuffer(GLenum target, GLuint framebuffer); void sglBlendFunc(GLenum sfactor, GLenum dfactor); void sglBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); void sglClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); void sglClearDepth(GLdouble value); void sglColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); void sglCullFace(GLenum mode); void sglDepthFunc(GLenum func); void sglDepthMask(GLboolean flag); void sglDepthRange(GLclampd nearVal, GLclampd farVal); void sglFrontFace(GLenum mode); void sglPolygonOffset(GLfloat factor, GLfloat units); void sglScissor(GLint x, GLint y, GLsizei width, GLsizei height); void sglUseProgram(GLuint program); void sglViewport(GLint x, GLint y, GLsizei width, GLsizei height); void sglBindBuffer(GLenum target, GLuint buffer); void sglActiveTexture(GLenum texture); void sglBindTexture(GLenum target, GLuint texture); void sglDeleteTextures(GLsizei n, const GLuint *textures); void sglDeleteShader(GLuint shader); void sglDeleteProgram(GLuint program); GLuint sglCreateShader(GLenum shaderType); GLuint sglCreateProgram(void); void sglShaderSource(GLuint shader, GLsizei count, const GLchar **string, const GLint *length); void sglCompileShader(GLuint shader); void sglGetShaderiv(GLuint shader, GLenum pname, GLint *params); void sglGetProgramiv(GLuint program, GLenum pname, GLint *params); void sglAttachShader(GLuint program, GLuint shader); void sglLinkProgram(GLuint program); void sglBindAttribLocation(GLuint program, GLuint index, const GLchar *name); void sglGenRenderbuffers(GLsizei n, GLuint *renderbuffers); void sglRenderbufferStorage(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height); void sglBindRenderbuffer(GLenum target, GLuint renderbuffer); void sglFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); GLenum sglCheckFramebufferStatus(GLenum target); void sglDeleteFramebuffers(GLsizei n, GLuint *framebuffers); void sglBindFramebuffer(GLenum target, GLuint framebuffer); void sglGenFramebuffers(GLsizei n, GLuint *ids); void sglFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); void sglDeleteRenderbuffers(GLsizei n, GLuint *renderbuffers); void sglBufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); void sglBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); void sglGenBuffers(GLsizei n, GLuint * buffers); void sglDeleteBuffers(GLsizei n, const GLuint *buffers); void sglTexCoord2f(float S, float t); #ifndef NO_TRANSLATE #define glEnable(T) sglEnable(S##T) #define glDisable(T) sglDisable(S##T) #define glIsEnabled(T) sglIsEnabled(S##T) #define glEnableVertexAttribArray sglEnableVertexAttribArray #define glDisableVertexAttribArray sglDisableVertexAttribArray #define glVertexAttribPointer sglVertexAttribPointer #define glVertexAttrib4f sglVertexAttrib4f #define glVertexAttrib4fv sglVertexAttrib4fv #define glBindFramebuffer sglBindFramebuffer #define glBlendFunc sglBlendFunc #define glBlendFuncSeparate sglBlendFuncSeparate #define glClearColor sglClearColor #define glClearDepth sglClearDepth #define glClearDepthf sglClearDepth #define glColorMask sglColorMask #define glCullFace sglCullFace #define glDepthFunc sglDepthFunc #define glDepthMask sglDepthMask #define glDepthRange sglDepthRange #define glFrontFace sglFrontFace #define glPolygonOffset sglPolygonOffset #define glScissor sglScissor #define glUseProgramARB sglUseProgram #define glUseProgram sglUseProgram #define glViewport sglViewport #define glActiveTextureARB sglActiveTexture #define glActiveTexture sglActiveTexture #define glBindTexture sglBindTexture #define glGenerateMipmap sglGenerateMipmap #define glUniform1i sglUniform1i #define glGetUniformLocation sglGetUniformLocation #define glUniform1f sglUniform1f #define glUniform2f sglUniform2f #define glUniform3f sglUniform3f #define glUniform4f sglUniform4f #define glUniform4fv sglUniform4fv #define glGetShaderInfoLog sglGetShaderInfoLog #define glGetProgramInfoLog sglGetProgramInfoLog #define glDeleteProgram sglDeleteProgram #define glDeleteShader sglDeleteShader #define glCreateShader sglCreateShader #define glCreateProgram sglCreateProgram #define glShaderSource sglShaderSource #define glCompileShader sglCompileShader #define glGetShaderiv sglGetShaderiv #define glGetProgramiv sglGetProgramiv #define glAttachShader sglAttachShader #define glLinkProgram sglLinkProgram #define glBindAttribLocation sglBindAttribLocation #define glDeleteRenderbuffers sglDeleteRenderbuffers #define glDeleteFramebuffers sglDeleteFramebuffers #define glGenFramebuffers sglGenFramebuffers #define glGenRenderbuffers sglGenRenderbuffers #define glGenTextures sglGenTextures #define glBindBuffer sglBindBuffer #define glBindRenderbuffer sglBindRenderbuffer #define glRenderbufferStorage sglRenderbufferStorage #define glFramebufferRenderbuffer sglFramebufferRenderbuffer #define glCheckFramebufferStatus sglCheckFramebufferStatus #define glCheckFramebufferStatusEXT sglCheckFramebufferStatus #define glDeleteFramebuffers sglDeleteFramebuffers #define glDeleteTextures sglDeleteTextures #define glFramebufferTexture2D sglFramebufferTexture2D #define glCompressedTexImage2DARB sglCompressedTexImage2D #define glCompressedTexImage2D sglCompressedTexImage2D #define glTexCoord2f sglTexCoord2f #define glDrawArrays sglDrawArrays #define glBufferData sglBufferData #define glBufferSubData sglBufferSubData #define glGenBuffers sglGenBuffers #define glDeleteBuffers sglDeleteBuffers #endif void sglEnter(void); void sglExit(void); void *retro_gl_init(void); int retro_return(int just_flipping); #ifdef __cplusplus } #endif #endif mupen64plus-core/src/pi/flashram.h000664 001750 001750 00000003745 12655644434 020225 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - flashram.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_PI_FLASHRAM_H #define M64P_PI_FLASHRAM_H #include struct pi_controller; enum { FLASHRAM_SIZE = 0x20000 }; enum flashram_mode { FLASHRAM_MODE_NOPES = 0, FLASHRAM_MODE_ERASE, FLASHRAM_MODE_WRITE, FLASHRAM_MODE_READ, FLASHRAM_MODE_STATUS }; struct flashram { /* external sram storage */ void* user_data; void (*save)(void*); uint8_t* data; enum flashram_mode mode; uint64_t status; unsigned int erase_offset; unsigned int write_pointer; }; void init_flashram(struct flashram *flashram); void init_flashram(struct flashram* flashram); void flashram_save(struct flashram* flashram); void format_flashram(uint8_t* flash); int read_flashram_status(void* opaque, uint32_t address, uint32_t* value); int write_flashram_command(void* opaque, uint32_t address, uint32_t value, uint32_t mask); void dma_read_flashram(struct pi_controller* pi); void dma_write_flashram(struct pi_controller* pi); #endif mupen64plus-video-gliden64/README.md000664 001750 001750 00000000124 12655644434 020113 0ustar00sergiosergio000000 000000 GLideN64 ======== A new generation, open-source graphics plugin for N64 emulators. mupen64plus-core/src/api/retro_inline.h000664 001750 001750 00000003253 12655644434 021254 0ustar00sergiosergio000000 000000 /* Copyright (C) 2010-2015 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (retro_inline.h). * --------------------------------------------------------------------------------------- * * Permission is hereby granted, free of charge, * to any person obtaining a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __LIBRETRO_SDK_INLINE_H #define __LIBRETRO_SDK_INLINE_H #ifndef INLINE #if !defined(__cplusplus) && defined(_WIN32) #define INLINE _inline #elif defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L #define INLINE inline #elif defined(__GNUC__) #define INLINE __inline__ #else #define INLINE #endif #endif #endif libretro/opengl_state_machine.c000664 001750 001750 00000040253 12655644434 020061 0ustar00sergiosergio000000 000000 #include #include #define NO_TRANSLATE 1 #include #include "opengl_state_machine.h" #include "plugin/plugin.h" #include "api/libretro.h" #include // mupen64 defines #ifndef GFX_ANGRYLION #define GFX_ANGRYLION 3 #endif #ifndef GLES #define HAVE_LEGACY_GL #endif extern cothread_t main_thread; extern bool flip_only; extern int stop; extern enum gfx_plugin_type gfx_plugin; struct retro_hw_render_callback hw_render; //forward declarations // static int CapState[SGL_CAP_MAX]; static const int CapTranslate[SGL_CAP_MAX] = { GL_DEPTH_TEST, GL_BLEND, GL_POLYGON_OFFSET_FILL, GL_FOG, GL_CULL_FACE, GL_ALPHA_TEST, GL_SCISSOR_TEST }; #ifndef HAVE_SHARED_CONTEXT #define MAX_ATTRIB 8 #define MAX_TEXTURE 32 #define ATTRIB_INITER(X) { X, X, X, X, X, X, X, X } static GLint VertexAttribPointer_enabled[MAX_ATTRIB] = ATTRIB_INITER(0); static GLuint Framebuffer_framebuffer = 0; static GLenum BlendFunc_srcRGB = GL_ONE, BlendFunc_srcAlpha = GL_ONE; static GLenum BlendFunc_dstRGB = GL_ZERO, BlendFunc_dstAlpha = GL_ZERO; static GLclampf ClearColor_red = 0.0f, ClearColor_green = 0.0f, ClearColor_blue = 0.0f, ClearColor_alpha = 0.0f; static GLdouble ClearDepth_value = 1.0; static GLboolean ColorMask_red = GL_TRUE; static GLboolean ColorMask_green = GL_TRUE; static GLboolean ColorMask_blue = GL_TRUE; static GLboolean ColorMask_alpha = GL_TRUE; static GLenum CullFace_mode = GL_BACK; static GLenum DepthFunc_func = GL_LESS; static GLboolean DepthMask_flag = GL_TRUE; static GLclampd DepthRange_zNear = 0.0, DepthRange_zFar = 1.0; static GLenum FrontFace_mode = GL_CCW; static GLfloat PolygonOffset_factor = 0.0f, PolygonOffset_units = 0.0f; static GLint Scissor_x = 0, Scissor_y = 0; static GLsizei Scissor_width = 640, Scissor_height = 480; static GLuint UseProgram_program = 0; static GLint Viewport_x = 0, Viewport_y = 0; static GLsizei Viewport_width = 640, Viewport_height = 480; static GLenum ActiveTexture_texture = 0; static GLuint BindTexture_ids[MAX_TEXTURE]; #endif extern void vbo_draw(void); extern void vbo_disable(); #ifndef GLIDE64_MK2 static void gl_vbo_draw(void) { vbo_draw(); } #else static void gl_vbo_draw(void) { if (gfx_plugin != GFX_GLIDE64) return; vbo_draw(); } #endif void sglGenerateMipmap(GLenum target) { glGenerateMipmap(target); } void sglUniform1f(GLint location, GLfloat v0) { glUniform1f(location, v0); } void sglUniform1i(GLint location, GLint v0) { glUniform1i(location, v0); } void sglUniform2f(GLint location, GLfloat v0, GLfloat v1) { glUniform2f(location, v0, v1); } void sglUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) { glUniform3f(location, v0, v1, v2); } void sglUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) { glUniform4f(location, v0, v1, v2, v3); } void sglUniform4fv(GLint location, GLsizei count, const GLfloat *value) { glUniform4fv(location, count, value); } void sglDeleteShader(GLuint shader) { glDeleteShader(shader); } void sglDeleteProgram(GLuint program) { glDeleteProgram(program); } GLuint sglCreateShader(GLenum shaderType) { return glCreateShader(shaderType); } GLuint sglCreateProgram(void) { return glCreateProgram(); } void sglCompileShader(GLuint shader) { glCompileShader(shader); } void sglLinkProgram(GLuint program) { glLinkProgram(program); } void sglAttachShader(GLuint program, GLuint shader) { glAttachShader(program, shader); } void sglGetShaderiv(GLuint shader, GLenum pname, GLint *params) { glGetShaderiv(shader, pname, params); } void sglGetProgramiv(GLuint shader, GLenum pname, GLint *params) { glGetProgramiv(shader, pname, params); } void sglShaderSource(GLuint shader, GLsizei count, const GLchar **string, const GLint *length) { return glShaderSource(shader, count, string, length); } void sglBindAttribLocation(GLuint program, GLuint index, const GLchar *name) { glBindAttribLocation(program, index, name); } void sglGetShaderInfoLog(GLuint shader, GLsizei maxLength, GLsizei *length, GLchar *infoLog) { glGetShaderInfoLog(shader, maxLength, length, infoLog); } void sglGetProgramInfoLog(GLuint shader, GLsizei maxLength, GLsizei *length, GLchar *infoLog) { glGetProgramInfoLog(shader, maxLength, length, infoLog); } GLint sglGetUniformLocation(GLuint program, const GLchar *name) { return glGetUniformLocation(program, name); } void sglEnable(GLenum cap) { gl_vbo_draw(); glEnable(CapTranslate[cap]); CapState[cap] = 1; } void sglDisable(GLenum cap) { gl_vbo_draw(); glDisable(CapTranslate[cap]); CapState[cap] = 0; } GLboolean sglIsEnabled(GLenum cap) { return CapState[cap] ? GL_TRUE : GL_FALSE; } void sglEnableVertexAttribArray(GLuint index) { gl_vbo_draw(); #ifndef HAVE_SHARED_CONTEXT VertexAttribPointer_enabled[index] = 1; #endif glEnableVertexAttribArray(index); } void sglDisableVertexAttribArray(GLuint index) { #ifndef HAVE_SHARED_CONTEXT VertexAttribPointer_enabled[index] = 0; #endif glDisableVertexAttribArray(index); } void sglVertexAttribPointer(GLuint name, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer) { glVertexAttribPointer(name, size, type, normalized, stride, pointer); } void sglVertexAttrib4f(GLuint name, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { glVertexAttrib4f(name, x, y, z, w); } void sglVertexAttrib4fv(GLuint name, GLfloat* v) { glVertexAttrib4fv(name, v); } void sglBindFramebuffer(GLenum target, GLuint framebuffer) { gl_vbo_draw(); if (!stop) glBindFramebuffer(GL_FRAMEBUFFER, framebuffer ? framebuffer : hw_render.get_current_framebuffer()); } void sglBlendFunc(GLenum sfactor, GLenum dfactor) { gl_vbo_draw(); #ifndef HAVE_SHARED_CONTEXT BlendFunc_srcRGB = BlendFunc_srcAlpha = sfactor; BlendFunc_dstRGB = BlendFunc_dstAlpha = dfactor; #endif glBlendFunc(sfactor, dfactor); } void sglBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) { gl_vbo_draw(); #ifndef HAVE_SHARED_CONTEXT BlendFunc_srcRGB = srcRGB; BlendFunc_dstRGB = dstRGB; BlendFunc_srcAlpha = srcAlpha; BlendFunc_dstAlpha = dstAlpha; #endif glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); } void sglClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { gl_vbo_draw(); glClearColor(red, green, blue, alpha); #ifndef HAVE_SHARED_CONTEXT ClearColor_red = red; ClearColor_green = green; ClearColor_blue = blue; ClearColor_alpha = alpha; #endif } void sglClearDepthf(GLdouble depth) { gl_vbo_draw(); #ifdef GLES glClearDepthf(depth); #else glClearDepth(depth); #endif } void sglClearDepth(GLdouble depth) { gl_vbo_draw(); sglClearDepthf(depth); #ifndef HAVE_SHARED_CONTEXT ClearDepth_value = depth; #endif } void sglColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { gl_vbo_draw(); glColorMask(red, green, blue, alpha); #ifndef HAVE_SHARED_CONTEXT ColorMask_red = red; ColorMask_green = green; ColorMask_blue = blue; ColorMask_alpha = alpha; #endif } void sglCullFace(GLenum mode) { gl_vbo_draw(); glCullFace(mode); #ifndef HAVE_SHARED_CONTEXT CullFace_mode = mode; #endif } void sglDepthFunc(GLenum func) { gl_vbo_draw(); glDepthFunc(func); #ifndef HAVE_SHARED_CONTEXT DepthFunc_func = func; #endif } void sglDepthMask(GLboolean flag) { gl_vbo_draw(); glDepthMask(flag); #ifndef HAVE_SHARED_CONTEXT DepthMask_flag = flag; #endif } void sglDepthRangef(GLclampd zNear, GLclampd zFar) { #ifdef GLES glDepthRangef(zNear, zFar); #else glDepthRange(zNear, zFar); #endif } void sglDepthRange(GLclampd zNear, GLclampd zFar) { sglDepthRangef(zNear, zFar); #ifndef HAVE_SHARED_CONTEXT DepthRange_zNear = zNear; DepthRange_zFar = zFar; #endif } void sglFrontFace(GLenum mode) { gl_vbo_draw(); glFrontFace(mode); #ifndef HAVE_SHARED_CONTEXT FrontFace_mode = mode; #endif } void sglPolygonOffset(GLfloat factor, GLfloat units) { gl_vbo_draw(); glPolygonOffset(factor, units); #ifndef HAVE_SHARED_CONTEXT PolygonOffset_factor = factor; PolygonOffset_units = units; #endif } void sglScissor(GLint x, GLint y, GLsizei width, GLsizei height) { gl_vbo_draw(); glScissor(x, y, width, height); #ifndef HAVE_SHARED_CONTEXT Scissor_x = x; Scissor_y = y; Scissor_width = width; Scissor_height = height; #endif } void sglUseProgram(GLuint program) { gl_vbo_draw(); glUseProgram(program); #ifndef HAVE_SHARED_CONTEXT UseProgram_program = program; #endif } void sglViewport(GLint x, GLint y, GLsizei width, GLsizei height) { gl_vbo_draw(); glViewport(x, y, width, height); #ifndef HAVE_SHARED_CONTEXT Viewport_x = x; Viewport_y = y; Viewport_width = width; Viewport_height = height; #endif } void sglActiveTexture(GLenum texture) { gl_vbo_draw(); glActiveTexture(texture); #ifndef HAVE_SHARED_CONTEXT ActiveTexture_texture = texture - GL_TEXTURE0; #endif } void sglBindTexture(GLenum target, GLuint texture) { gl_vbo_draw(); glBindTexture(target, texture); #ifndef HAVE_SHARED_CONTEXT BindTexture_ids[ActiveTexture_texture] = texture; #endif } void sglDeleteRenderbuffers(GLsizei n, GLuint *renderbuffers) { glDeleteRenderbuffers(n, renderbuffers); } void sglGenFramebuffers(GLsizei n, GLuint *ids) { glGenFramebuffers(n, ids); } void sglGenRenderbuffers(GLsizei n, GLuint *renderbuffers) { glGenRenderbuffers(n, renderbuffers); } void sglGenTextures(GLsizei n, GLuint *textures) { glGenTextures(n, textures); } void sglBindRenderbuffer(GLenum target, GLuint renderbuffer) { glBindRenderbuffer(target, renderbuffer); } void sglRenderbufferStorage(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height) { glRenderbufferStorage(target, internalFormat, width, height); } void sglFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) { glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); } GLenum sglCheckFramebufferStatus(GLenum target) { return glCheckFramebufferStatus(target); } void sglDeleteFramebuffers(GLsizei n, GLuint *framebuffers) { glDeleteFramebuffers(n, framebuffers); } void sglDeleteTextures(GLsizei n, const GLuint *textures) { glDeleteTextures(n, textures); } void sglFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { glFramebufferTexture2D(target, attachment, textarget, texture, level); } void sglBindBuffer(GLenum target, GLuint buffer) { gl_vbo_draw(); glBindBuffer(target, buffer); } void sglCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) { glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data); } void sglTexCoord2f(GLfloat s, GLfloat t) { #ifdef HAVE_LEGACY_GL glTexCoord2f(s, t); #endif } void sglDrawArrays(GLenum mode, GLint first, GLsizei count) { glDrawArrays(mode, first, count); } void sglBufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage) { glBufferData(target, size, data, usage); } void sglBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data) { glBufferSubData(target, offset, size, data); } void sglGenBuffers(GLsizei n, GLuint *buffers) { glGenBuffers(n, buffers); } void sglDeleteBuffers(GLsizei n, const GLuint *buffers) { glDeleteBuffers(n, buffers); } #if 0 struct tex_map { unsigned address; GLuint tex; }; static struct tex_map *texture_map; static size_t texture_map_size; static size_t texture_map_cap; static GLuint find_tex_from_address(unsigned address) { size_t i; for (i = 0; i < texture_map_size; i++) { if (texture_map[i].address == address) return texture_map[i].tex; } return 0; } static void delete_tex_from_address(unsigned address) { size_t i; for (i = 0; i < texture_map_size; i++) { if (texture_map[i].address == address) { glDeleteTextures(1, &texture_map[i].tex); memmove(texture_map + i, texture_map + i + 1, (texture_map_size - (i + 1)) * sizeof(*texture_map)); texture_map_size--; return; } } glDeleteTextures(1, &address); } #endif extern int InitGfx(void); extern void gles2n64_reset(void); extern void reinit_gfx_plugin(void); static int gotsym; static void context_reset(void) { if (!gotsym && gfx_plugin != GFX_ANGRYLION) gotsym = (rglgen_resolve_symbols(hw_render.get_proc_address), 1); reinit_gfx_plugin(); #ifdef HAVE_SHARED_CONTEXT sglBindFramebuffer(GL_FRAMEBUFFER, 0); #endif } void *retro_gl_init(void) { if (gfx_plugin == GFX_ANGRYLION) return NULL; #ifdef GLES #if defined(GLES31) hw_render.context_type = RETRO_HW_CONTEXT_OPENGLES_VERSION; hw_render.version_major = 3; hw_render.version_minor = 1; #elif defined(GLES3) hw_render.context_type = RETRO_HW_CONTEXT_OPENGLES3; #else hw_render.context_type = RETRO_HW_CONTEXT_OPENGLES2; #endif #else #ifdef CORE hw_render.context_type = RETRO_HW_CONTEXT_OPENGL_CORE; hw_render.version_major = 3; hw_render.version_minor = 1; #else hw_render.context_type = RETRO_HW_CONTEXT_OPENGL; #endif #endif hw_render.context_reset = context_reset; hw_render.depth = true; hw_render.bottom_left_origin = true; hw_render.cache_context = true; return &hw_render; } #ifndef HAVE_SHARED_CONTEXT void sglEnter(void) { int i; if (gfx_plugin == GFX_ANGRYLION || stop) return; if (!gotsym) gotsym = (rglgen_resolve_symbols(hw_render.get_proc_address), 1); for (i = 0; i < MAX_ATTRIB; i ++) { if (VertexAttribPointer_enabled[i]) glEnableVertexAttribArray(i); else glDisableVertexAttribArray(i); } sglBindFramebuffer(GL_FRAMEBUFFER, Framebuffer_framebuffer); glBlendFuncSeparate(BlendFunc_srcRGB, BlendFunc_dstRGB, BlendFunc_srcAlpha, BlendFunc_dstAlpha); glClearColor(ClearColor_red, ClearColor_green, ClearColor_blue, ClearColor_alpha); sglClearDepthf(ClearDepth_value); glColorMask(ColorMask_red, ColorMask_green, ColorMask_blue, ColorMask_alpha); glCullFace(CullFace_mode); glDepthFunc(DepthFunc_func); glDepthMask(DepthMask_flag); sglDepthRangef(DepthRange_zNear, DepthRange_zFar); glFrontFace(FrontFace_mode); glPolygonOffset(PolygonOffset_factor, PolygonOffset_units); glScissor(Scissor_x, Scissor_y, Scissor_width, Scissor_height); glUseProgram(UseProgram_program); glViewport(Viewport_x, Viewport_y, Viewport_width, Viewport_height); for(i = 0; i != SGL_CAP_MAX; i ++) { if (CapState[i]) glEnable(CapTranslate[i]); else glDisable(CapTranslate[i]); } for (i = 0; i < MAX_TEXTURE; i ++) { glActiveTexture(GL_TEXTURE0 + i); glBindTexture(GL_TEXTURE_2D, BindTexture_ids[i]); } glActiveTexture(GL_TEXTURE0 + ActiveTexture_texture); glBindBuffer(GL_ARRAY_BUFFER, 0); } void sglExit(void) { int i; if (gfx_plugin == GFX_ANGRYLION || stop) return; for (i = 0; i < SGL_CAP_MAX; i ++) glDisable(CapTranslate[i]); glBlendFunc(GL_ONE, GL_ZERO); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glCullFace(GL_BACK); glDepthMask(GL_TRUE); sglDepthRangef(0, 1); glFrontFace(GL_CCW); glPolygonOffset(0, 0); glUseProgram(0); // Clear textures for (i = 0; i < MAX_TEXTURE; i ++) { glActiveTexture(GL_TEXTURE0 + i); glBindTexture(GL_TEXTURE_2D, 0); } glActiveTexture(GL_TEXTURE0); for (i = 0; i < MAX_ATTRIB; i ++) glDisableVertexAttribArray(i); glBindFramebuffer(GL_FRAMEBUFFER, 0); } #endif extern bool frame_dupe; #ifdef SINGLE_THREAD extern retro_video_refresh_t video_cb; extern uint32_t screen_width; extern uint32_t screen_height; bool emu_step_render(void); int retro_return(int just_flipping) { vbo_disable(); flip_only = just_flipping; if (just_flipping) { #ifndef HAVE_SHARED_CONTEXT sglExit(); #endif emu_step_render(); #ifndef HAVE_SHARED_CONTEXT sglEnter(); #endif } stop = 1; return 0; } #else int retro_return(int just_flipping) { if (stop) return 0; vbo_disable(); flip_only = just_flipping; co_switch(main_thread); return 0; } #endif mupen64plus-core/src/pi/flashram.c000664 001750 001750 00000014303 12655644434 020210 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - flashram.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "flashram.h" #include "pi_controller.h" #include "../api/m64p_types.h" #include "../api/callbacks.h" #include "../memory/memory.h" #include "../ri/ri_controller.h" #include static void flashram_command(struct pi_controller *pi, uint32_t command) { unsigned int i; struct flashram *flashram = &pi->flashram; uint8_t *dram = (uint8_t*)pi->ri->rdram.dram; switch (command & 0xff000000) { case 0x4b000000: flashram->erase_offset = (command & 0xffff) * 128; break; case 0x78000000: flashram->mode = FLASHRAM_MODE_ERASE; flashram->status = 0x1111800800c20000LL; break; case 0xa5000000: flashram->erase_offset = (command & 0xffff) * 128; flashram->status = 0x1111800400c20000LL; break; case 0xb4000000: flashram->mode = FLASHRAM_MODE_WRITE; break; case 0xd2000000: // execute switch (flashram->mode) { case FLASHRAM_MODE_NOPES: case FLASHRAM_MODE_READ: break; case FLASHRAM_MODE_ERASE: { for (i=flashram->erase_offset; i<(flashram->erase_offset+128); ++i) flashram->data[i^S8] = 0xff; flashram_save(flashram); } break; case FLASHRAM_MODE_WRITE: { for(i = 0; i < 128; ++i) flashram->data[(flashram->erase_offset+i)^S8]= dram[(flashram->write_pointer+i)^S8]; flashram_save(flashram); } break; case FLASHRAM_MODE_STATUS: break; default: DebugMessage(M64MSG_WARNING, "unknown flashram command with mode:%x", (int)flashram->mode); break; } flashram->mode = FLASHRAM_MODE_NOPES; break; case 0xe1000000: flashram->mode = FLASHRAM_MODE_STATUS; flashram->status = 0x1111800100c20000LL; break; case 0xf0000000: flashram->mode = FLASHRAM_MODE_READ; flashram->status = 0x11118004f0000000LL; break; default: DebugMessage(M64MSG_WARNING, "unknown flashram command: %x", (int)command); break; } } void init_flashram(struct flashram* flashram) { flashram->mode = FLASHRAM_MODE_NOPES; flashram->status = 0; flashram->erase_offset = 0; flashram->write_pointer = 0; } void flashram_save(struct flashram* flashram) { flashram->save(flashram->user_data); } void format_flashram(uint8_t* flash) { memset(flash, 0xff, FLASHRAM_SIZE); } int read_flashram_status(void* opaque, uint32_t address, uint32_t* value) { struct pi_controller* pi = (struct pi_controller*)opaque; if ((pi->use_flashram == -1) || ((address & 0xffff) != 0)) { DebugMessage(M64MSG_ERROR, "unknown read in read_flashram_status()"); return -1; } pi->use_flashram = 1; *value = pi->flashram.status >> 32; return 0; } int write_flashram_command(void* opaque, uint32_t address, uint32_t value, uint32_t mask) { struct pi_controller* pi = (struct pi_controller*)opaque; if ((pi->use_flashram == -1) || ((address & 0xffff) != 0)) { DebugMessage(M64MSG_ERROR, "unknown write in write_flashram_command()"); return -1; } pi->use_flashram = 1; flashram_command(pi, value & mask); return 0; } void dma_read_flashram(struct pi_controller *pi) { unsigned int dram_addr, cart_addr; unsigned int i, length; struct flashram* flashram = &pi->flashram; uint32_t *dram = pi->ri->rdram.dram; uint8_t *mem = flashram->data; switch (flashram->mode) { case FLASHRAM_MODE_STATUS: dram[pi->regs[PI_DRAM_ADDR_REG]/4] = (uint32_t)(flashram->status >> 32); dram[pi->regs[PI_DRAM_ADDR_REG]/4+1] = (uint32_t)(flashram->status); break; case FLASHRAM_MODE_READ: length = (pi->regs[PI_WR_LEN_REG] & 0xffffff) + 1; dram_addr = pi->regs[PI_DRAM_ADDR_REG]; cart_addr = ((pi->regs[PI_CART_ADDR_REG]-0x08000000)&0xffff)*2; for (i = 0; i < length; ++i) ((uint8_t*)dram)[(dram_addr+i)^S8] = mem[(cart_addr+i)^S8]; break; default: DebugMessage(M64MSG_WARNING, "unknown dma_read_flashram: %x", flashram->mode); break; } } void dma_write_flashram(struct pi_controller *pi) { struct flashram *flashram = &pi->flashram; switch (flashram->mode) { case FLASHRAM_MODE_WRITE: flashram->write_pointer = pi->regs[PI_DRAM_ADDR_REG]; break; default: DebugMessage(M64MSG_ERROR, "unknown dma_write_flashram: %x", flashram->mode); break; } } mupen64plus-video-gliden64/projects/cmake/000700 001750 001750 00000000000 12656647145 021537 5ustar00sergiosergio000000 000000 glide2gl/src/Glide64/glide64_rdp.c000664 001750 001750 00000251127 12655644434 017654 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** #include #include "Gfx_1.3.h" #include "m64p.h" #include "3dmath.h" #include "Util.h" #include "Combine.h" #include "TexCache.h" #include "FBtoScreen.h" #include "CRC.h" #include "GBI.h" #include "Glide64_UCode.h" #include "../../libretro/SDL.h" #ifdef __LIBRETRO__ // Prefix API #define VIDEO_TAG(X) glide64##X #define ReadScreen2 VIDEO_TAG(ReadScreen2) #define PluginStartup VIDEO_TAG(PluginStartup) #define PluginShutdown VIDEO_TAG(PluginShutdown) #define PluginGetVersion VIDEO_TAG(PluginGetVersion) #define CaptureScreen VIDEO_TAG(CaptureScreen) #define ChangeWindow VIDEO_TAG(ChangeWindow) #define CloseDLL VIDEO_TAG(CloseDLL) #define DllTest VIDEO_TAG(DllTest) #define DrawScreen VIDEO_TAG(DrawScreen) #define GetDllInfo VIDEO_TAG(GetDllInfo) #define InitiateGFX VIDEO_TAG(InitiateGFX) #define MoveScreen VIDEO_TAG(MoveScreen) #define RomClosed VIDEO_TAG(RomClosed) #define RomOpen VIDEO_TAG(RomOpen) #define ShowCFB VIDEO_TAG(ShowCFB) #define SetRenderingCallback VIDEO_TAG(SetRenderingCallback) #define UpdateScreen VIDEO_TAG(UpdateScreen) #define ViStatusChanged VIDEO_TAG(ViStatusChanged) #define ViWidthChanged VIDEO_TAG(ViWidthChanged) #define ReadScreen VIDEO_TAG(ReadScreen) #define FBGetFrameBufferInfo VIDEO_TAG(FBGetFrameBufferInfo) #define FBRead VIDEO_TAG(FBRead) #define FBWrite VIDEO_TAG(FBWrite) #define ProcessDList VIDEO_TAG(ProcessDList) #define ProcessRDPList VIDEO_TAG(ProcessRDPList) #define ResizeVideoOutput VIDEO_TAG(ResizeVideoOutput) #endif //angrylion's macro, helps to cut overflowed values. #define SIGN16(x) (int16_t)(x) #ifdef __GNUC__ #define align(x) __attribute__ ((aligned(x))) #else #define align(x) #endif const char *ACmp[] = { "NONE", "THRESHOLD", "UNKNOWN", "DITHER" }; const char *Mode0[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIORNMENT", "1", "NOISE", "0", "0", "0", "0", "0", "0", "0", "0" }; const char *Mode1[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIORNMENT", "CENTER", "K4", "0", "0", "0", "0", "0", "0", "0", "0" }; const char *Mode2[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIORNMENT", "SCALE", "COMBINED_ALPHA", "T0_ALPHA", "T1_ALPHA", "PRIM_ALPHA", "SHADE_ALPHA", "ENV_ALPHA", "LOD_FRACTION", "PRIM_LODFRAC", "K5", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" }; const char *Mode3[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIORNMENT", "1", "0" }; const char *Alpha0[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIORNMENT", "1", "0" }; #define Alpha1 Alpha0 const char *Alpha2[] = { "LOD_FRACTION", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIORNMENT", "PRIM_LODFRAC", "0" }; #define Alpha3 Alpha0 const char *FBLa[] = { "G_BL_CLR_IN", "G_BL_CLR_MEM", "G_BL_CLR_BL", "G_BL_CLR_FOG" }; const char *FBLb[] = { "G_BL_A_IN", "G_BL_A_FOG", "G_BL_A_SHADE", "G_BL_0" }; const char *FBLc[] = { "G_BL_CLR_IN", "G_BL_CLR_MEM", "G_BL_CLR_BL", "G_BL_CLR_FOG"}; const char *FBLd[] = { "G_BL_1MA", "G_BL_A_MEM", "G_BL_1", "G_BL_0" }; const char *str_zs[] = { "G_ZS_PIXEL", "G_ZS_PRIM" }; const char *str_yn[] = { "NO", "YES" }; const char *str_offon[] = { "OFF", "ON" }; const char *str_cull[] = { "DISABLE", "FRONT", "BACK", "BOTH" }; // I=intensity probably const char *str_format[] = { "RGBA", "YUV", "CI", "IA", "I", "?", "?", "?" }; const char *str_size[] = { "4bit", "8bit", "16bit", "32bit" }; const char *str_cm[] = { "WRAP/NO CLAMP", "MIRROR/NO CLAMP", "WRAP/CLAMP", "MIRROR/CLAMP" }; const char *str_lod[] = { "1", "2", "4", "8", "16", "32", "64", "128", "256", "512", "1024", "2048" }; const char *str_aspect[] = { "1x8", "1x4", "1x2", "1x1", "2x1", "4x1", "8x1" }; const char *str_filter[] = { "Point Sampled", "Average (box)", "Bilinear" }; const char *str_tlut[] = { "TT_NONE", "TT_UNKNOWN", "TT_RGBA_16", "TT_IA_16" }; const char *str_dither[] = { "Pattern", "~Pattern", "Noise", "None" }; const char *CIStatus[] = { "ci_main", "ci_zimg", "ci_unknown", "ci_useless", "ci_old_copy", "ci_copy", "ci_copy_self", "ci_zcopy", "ci_aux", "ci_aux_copy" }; //static variables uint32_t frame_count; // frame counter int ucode_error_report = true; uint8_t microcode[4096]; uint32_t uc_crc; //forward decls static void CopyFrameBuffer (int32_t buffer); static void apply_shading(VERTEX *vptr); // ** UCODE FUNCTIONS ** #include "ucode.h" #include "glide64_gDP.h" #include "glide64_gSP.h" #include "ucode00.h" #include "ucode01.h" #include "ucode02.h" #include "ucode03.h" #include "ucode04.h" #include "ucode05.h" #include "ucode06.h" #include "ucode07.h" #include "ucode08.h" #include "ucode09.h" #include "ucode09rdp.h" #include "turbo3D.h" static int reset = 0; int old_ucode = -1; void rdp_new(void) { unsigned i, cpu; cpu = 0; rdp.vtx1 = (VERTEX*)calloc(256, sizeof(VERTEX)); rdp.vtx2 = (VERTEX*)calloc(256, sizeof(VERTEX)); rdp.vtx = (VERTEX*)calloc(MAX_VTX, sizeof(VERTEX)); rdp.frame_buffers = (COLOR_IMAGE*)calloc(NUMTEXBUF+2, sizeof(COLOR_IMAGE)); rdp.vtxbuf = 0; rdp.vtxbuf2 = 0; rdp.vtx_buffer = 0; rdp.n_global = 0; for (i = 0; i < MAX_TMU; i++) { rdp.cache[i] = (CACHE_LUT*)calloc(MAX_CACHE, sizeof(CACHE_LUT)); rdp.cur_cache[i] = 0; } if (perf_get_cpu_features_cb) cpu = perf_get_cpu_features_cb(); _gSPVertex = gSPVertex_G64; } void rdp_setfuncs(void) { if (settings.hacks & hack_Makers) { if (log_cb) log_cb(RETRO_LOG_INFO, "Applying Mischief Makers function pointer table tweak...\n"); gfx_instruction[0][191] = uc0_tri1_mischief; } } void rdp_free(void) { int i; if (rdp.vtx1) free(rdp.vtx1); if (rdp.vtx2) free(rdp.vtx2); for (i = 0; i < MAX_TMU; i++) { if (rdp.cache[i]) { free(rdp.cache[i]); rdp.cache[i] = NULL; } } if (rdp.vtx) free(rdp.vtx); if (rdp.frame_buffers) free(rdp.frame_buffers); rdp.vtx = rdp.vtx1 = rdp.vtx2 = NULL; rdp.frame_buffers = NULL; } void rdp_reset(void) { int i; reset = 1; // set all vertex numbers for (i = 0; i < MAX_VTX; i++) rdp.vtx[i].number = i; g_gdp.__clip.xh = 0; g_gdp.__clip.yh = 0; g_gdp.__clip.xl = 320; g_gdp.__clip.yl = 240; rdp.vi_org_reg = *gfx_info.VI_ORIGIN_REG; rdp.view_scale[2] = 32.0f * 511.0f; rdp.view_trans[2] = 32.0f * 511.0f; rdp.clip_ratio = 1.0f; rdp.lookat[0][0] = rdp.lookat[1][1] = 1.0f; rdp.allow_combine = 1; g_gdp.flags = UPDATE_SCISSOR | UPDATE_COMBINE | UPDATE_ZBUF_ENABLED | UPDATE_CULL_MODE; rdp.fog_mode = FOG_MODE_ENABLED; rdp.maincimg[0].addr = rdp.maincimg[1].addr = rdp.last_drawn_ci_addr = 0x7FFFFFFF; } static uint32_t d_ul_x, d_ul_y, d_lr_x, d_lr_y; static void DrawPartFrameBufferToScreen(void) { FB_TO_SCREEN_INFO fb_info; fb_info.addr = rdp.cimg; fb_info.size = g_gdp.fb_size; fb_info.width = rdp.ci_width; fb_info.height = rdp.ci_height; fb_info.ul_x = d_ul_x; fb_info.lr_x = d_lr_x; fb_info.ul_y = d_ul_y; fb_info.lr_y = d_lr_y; fb_info.opaque = 0; DrawFrameBufferToScreen(&fb_info); memset(gfx_info.RDRAM+rdp.cimg, 0, (rdp.ci_width*rdp.ci_height) << g_gdp.fb_size >> 1); } #define RGBA16TO32(color) \ ((color&1)?0xFF:0) | \ ((uint32_t)(((color & 0xF800) >> 11)) << 24) | \ ((uint32_t)(((color & 0x07C0) >> 6)) << 16) | \ ((uint32_t)(((color & 0x003E) >> 1)) << 8) /* defined in glitchmain.c */ extern uint16_t *frameBuffer; static void CopyFrameBuffer(int32_t buffer) { // don't bother to write the stuff in asm... the slow part is the read from video card, // not the copy. uint32_t height = rdp.ci_lower_bound; uint32_t width = rdp.ci_width;//*gfx_info.VI_WIDTH_REG; if (fb_emulation_enabled) { int ind = (rdp.ci_count > 0) ? (rdp.ci_count-1) : 0; height = rdp.frame_buffers[ind].height; } if (rdp.scale_x < 1.1f) { uint16_t * ptr_src = (uint16_t*)frameBuffer; if (grLfbReadRegion(buffer, (uint32_t)rdp.offset_x, (uint32_t)rdp.offset_y,//rdp.ci_upper_bound, width, height, width<<1, ptr_src)) { uint16_t c; uint32_t y, x; uint16_t *ptr_dst = (uint16_t*)(gfx_info.RDRAM+rdp.cimg); uint32_t *ptr_dst32 = (uint32_t*)(gfx_info.RDRAM+rdp.cimg); for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { c = ptr_src[x + y * width]; if ((settings.frame_buffer & fb_read_alpha) && c <= 0) {} else c = (c&0xFFC0) | ((c&0x001F) << 1) | 1; if (g_gdp.fb_size == 2) ptr_dst[(x + y * width)^1] = c; else ptr_dst32[x + y * width] = RGBA16TO32(c); } } } } else { GrLfbInfo_t info; float scale_x = (settings.scr_res_x - rdp.offset_x*2.0f) / max(width, rdp.vi_width); float scale_y = (settings.scr_res_y - rdp.offset_y*2.0f) / max(height, rdp.vi_height); FRDP("width: %d, height: %d, ul_y: %d, lr_y: %d, scale_x: %f, scale_y: %f, ci_width: %d, ci_height: %d\n",width, height, rdp.ci_upper_bound, rdp.ci_lower_bound, scale_x, scale_y, rdp.ci_width, rdp.ci_height); info.size = sizeof(GrLfbInfo_t); if (grLfbLock (GR_LFB_READ_ONLY, buffer, GR_LFBWRITEMODE_565, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { int y, x, x_start, y_start, x_end, y_end, read_alpha; uint16_t c; uint16_t *ptr_src = (uint16_t*)info.lfbPtr; uint16_t *ptr_dst = (uint16_t*)(gfx_info.RDRAM+rdp.cimg); uint32_t *ptr_dst32 = (uint32_t*)(gfx_info.RDRAM+rdp.cimg); uint32_t stride = info.strideInBytes>>1; read_alpha = settings.frame_buffer & fb_read_alpha; if ((settings.hacks&hack_PMario) && rdp.ci_count > 0 && rdp.frame_buffers[rdp.ci_count-1].status != CI_AUX) read_alpha = false; x_start = 0; y_start = 0; x_end = width; y_end = height; if (settings.hacks&hack_BAR) x_start = 80, y_start = 24, x_end = 240, y_end = 86; for (y = y_start; y < y_end; y++) { for (x = x_start; x < x_end; x++) { c = ptr_src[(int)(x*scale_x + rdp.offset_x) + (int)(y * scale_y + rdp.offset_y) * stride]; c = (c&0xFFC0) | ((c&0x001F) << 1) | 1; if (read_alpha && c == 1) c = 0; if (g_gdp.fb_size <= 2) ptr_dst[(x + y * width)^1] = c; else ptr_dst32[x + y * width] = RGBA16TO32(c); } } // Unlock the backbuffer grLfbUnlock (GR_LFB_READ_ONLY, buffer); LRDP("LfbLock. Framebuffer copy complete.\n"); } else { LRDP("Framebuffer copy failed.\n"); } } } static void copyWhiteToRDRAM(void) { uint16_t *ptr_dst; uint32_t *ptr_dst32; uint32_t y, x; if(g_gdp.fb_width == 0) return; ptr_dst = (uint16_t*)(gfx_info.RDRAM + rdp.cimg); ptr_dst32 = (uint32_t*)(gfx_info.RDRAM + rdp.cimg); for(y = 0; y < rdp.ci_height; y++) { for(x = 0; x < g_gdp.fb_width; x++) { if(g_gdp.fb_size == 2) ptr_dst[(x + y * g_gdp.fb_width) ^ 1] = 0xFFFF; else ptr_dst32[x + y * g_gdp.fb_width] = 0xFFFFFFFF; } } } /****************************************************************** Function: ProcessDList Purpose: This function is called when there is a Dlist to be processed. (High level GFX list) input: none output: none *******************************************************************/ void DetectFrameBufferUsage(void); uint32_t fbreads_front = 0; uint32_t fbreads_back = 0; int cpu_fb_read_called = false; int cpu_fb_write_called = false; int cpu_fb_write = false; int cpu_fb_ignore = false; int CI_SET = true; uint32_t swapped_addr = 0; uint32_t ucode5_texshiftaddr = 0; uint32_t ucode5_texshiftcount = 0; uint16_t ucode5_texshift = 0; int depth_buffer_fog; extern bool frame_dupe; EXPORT void CALL ProcessDList(void) { uint32_t dlist_start, dlist_length, a; no_dlist = false; update_screen_count = 0; ChangeSize(); if (reset) { reset = 0; if (settings.autodetect_ucode) { // Thanks to ZeZu for ucode autodetection!!! uint32_t startUcode = *(uint32_t*)(gfx_info.DMEM+0xFD0); memcpy (microcode, gfx_info.RDRAM+startUcode, 4096); microcheck (); } else memset (microcode, 0, 4096); } else if ( ((old_ucode == ucode_S2DEX) && (settings.ucode == ucode_F3DEX)) || settings.force_microcheck) { uint32_t startUcode = *(uint32_t*)(gfx_info.DMEM+0xFD0); memcpy (microcode, gfx_info.RDRAM+startUcode, 4096); microcheck (); } if (exception) return; //* Set states *// if (settings.swapmode > 0) SwapOK = true; rdp.updatescreen = 1; rdp.model_i = 0; // 0 matrices so far in stack //stack_size can be less then 32! Important for Silicon Vally. Thanks Orkin! rdp.model_stack_size = min(32, (*(uint32_t*)(gfx_info.DMEM+0x0FE4))>>6); if (rdp.model_stack_size == 0) rdp.model_stack_size = 32; rdp.fb_drawn = rdp.fb_drawn_front = false; g_gdp.flags = 0x7FFFFFFF; // All but clear cache rdp.geom_mode = 0; rdp.maincimg[1] = rdp.maincimg[0]; rdp.skip_drawing = false; rdp.s2dex_tex_loaded = false; rdp.bg_image_height = 0xFFFF; fbreads_front = fbreads_back = 0; rdp.fog_multiplier = rdp.fog_offset = 0; g_gdp.other_modes.z_source_sel = 0; if (rdp.vi_org_reg != *gfx_info.VI_ORIGIN_REG) rdp.tlut_mode = 0; //is it correct? rdp.scissor_set = false; ucode5_texshiftaddr = ucode5_texshiftcount = 0; cpu_fb_write = false; cpu_fb_read_called = false; cpu_fb_write_called = false; cpu_fb_ignore = false; d_ul_x = 0xffff; d_ul_y = 0xffff; d_lr_x = 0; d_lr_y = 0; depth_buffer_fog = true; //analyze possible frame buffer usage if (fb_emulation_enabled) DetectFrameBufferUsage(); if (!(settings.hacks&hack_Lego) || rdp.num_of_ci > 1) rdp.last_bg = 0; //* End of set states *// // Get the start of the display list and the length of it dlist_start = *(uint32_t*)(gfx_info.DMEM+0xFF0); dlist_length = *(uint32_t*)(gfx_info.DMEM+0xFF4); // Do nothing if dlist is empty if (dlist_start == 0) return; if (cpu_fb_write == true) DrawPartFrameBufferToScreen(); if ((settings.hacks&hack_Tonic) && dlist_length < 16) { gdp_full_sync(rdp.cmd0, rdp.cmd1); FRDP_E("DLIST is too short!\n"); return; } // Start executing at the start of the display list rdp.pc_i = 0; rdp.pc[rdp.pc_i] = dlist_start; rdp.dl_count = -1; rdp.halt = 0; if (settings.ucode == ucode_Turbo3d) Turbo3D(); else { // MAIN PROCESSING LOOP do { // Get the address of the next command a = rdp.pc[rdp.pc_i] & BMASK; // Load the next command and its input rdp.cmd0 = ((uint32_t*)gfx_info.RDRAM)[a>>2]; // \ Current command, 64 bit rdp.cmd1 = ((uint32_t*)gfx_info.RDRAM)[(a>>2)+1]; // / // cmd2 and cmd3 are filled only when needed, by the function that needs them #ifdef LOG_COMMANDS // Output the address before the command FRDP ("%08lx (c0:%08lx, c1:%08lx): ", a, rdp.cmd0, rdp.cmd1); #endif // Go to the next instruction rdp.pc[rdp.pc_i] = (a+8) & BMASK; // Process this instruction gfx_instruction[settings.ucode][rdp.cmd0>>24](rdp.cmd0, rdp.cmd1); // check DL counter if (rdp.dl_count != -1) { rdp.dl_count --; if (rdp.dl_count == 0) { rdp.dl_count = -1; LRDP("End of DL\n"); rdp.pc_i --; } } } while (!rdp.halt); } if (fb_emulation_enabled) { rdp.scale_x = rdp.scale_x_bak; rdp.scale_y = rdp.scale_y_bak; } if(settings.hacks & hack_OOT && !frame_dupe) copyWhiteToRDRAM(); /* Subscreen delay fix */ else if (settings.frame_buffer & fb_ref) CopyFrameBuffer (GR_BUFFER_BACKBUFFER); if ((settings.hacks&hack_TGR2) && rdp.vi_org_reg != *gfx_info.VI_ORIGIN_REG && CI_SET) { newSwapBuffers (); CI_SET = false; } } static void ys_memrect(uint32_t w0, uint32_t w1) { uint32_t off_x, off_y; uint32_t y, width, tex_width; uint8_t *texaddr, *fbaddr; uint32_t tile = (uint16_t)((w1 & 0x07000000) >> 24); uint32_t lr_x = (uint16_t)((w0 & 0x00FFF000) >> 14); uint32_t lr_y = (uint16_t)((w0 & 0x00000FFF) >> 2); uint32_t ul_x = (uint16_t)((w1 & 0x00FFF000) >> 14); uint32_t ul_y = (uint16_t)((w1 & 0x00000FFF) >> 2); if (lr_y > g_gdp.__clip.yl) lr_y = g_gdp.__clip.yl; off_x = ((rdp.cmd2 & 0xFFFF0000) >> 16) >> 5; off_y = (rdp.cmd2 & 0x0000FFFF) >> 5; width = lr_x - ul_x; tex_width = g_gdp.tile[tile].line << 3; texaddr = (uint8_t*)(gfx_info.RDRAM + rdp.addr[g_gdp.tile[tile].tmem] + tex_width*off_y + off_x); fbaddr = (uint8_t*)(gfx_info.RDRAM + rdp.cimg + ul_x); for (y = ul_y; y < lr_y; y++) { uint8_t *src = (uint8_t*)(texaddr + (y - ul_y) * tex_width); uint8_t *dst = (uint8_t*)(fbaddr + y * rdp.ci_width); memcpy (dst, src, width); } } static void pm_palette_mod(void) { int8_t i; uint8_t envr = (uint8_t)(g_gdp.env_color.r * 0.0039215689f * 31.0f); uint8_t envg = (uint8_t)(g_gdp.env_color.g * 0.0039215689f * 31.0f); uint8_t envb = (uint8_t)(g_gdp.env_color.b * 0.0039215689f * 31.0f); uint16_t env16 = (uint16_t)((envr<<11)|(envg<<6)|(envb<<1)|1); uint16_t prmr = (uint8_t)(g_gdp.prim_color.r * 0.0039215689f * 31.0f); uint16_t prmg = (uint8_t)(g_gdp.prim_color.g * 0.0039215689f * 31.0f); uint16_t prmb = (uint8_t)(g_gdp.prim_color.b * 0.0039215689f * 31.0f); uint16_t prim16 = (uint16_t)((prmr << 11)|(prmg << 6)|(prmb << 1)|1); uint16_t *dst = (uint16_t*)(gfx_info.RDRAM+rdp.cimg); for (i = 0; i < 16; i++) dst[i^1] = (rdp.pal_8[i]&1) ? prim16 : env16; //LRDP("Texrect palette modification\n"); } static void pd_zcopy(uint32_t w0, uint32_t w1) { int x; uint16_t ul_x = (uint16_t)((w1 & 0x00FFF000) >> 14); uint16_t lr_x = (uint16_t)((w0 & 0x00FFF000) >> 14) + 1; uint16_t ul_u = (uint16_t)((rdp.cmd2 & 0xFFFF0000) >> 21) + 1; uint16_t *ptr_dst = (uint16_t*)(gfx_info.RDRAM+rdp.cimg); uint16_t width = lr_x - ul_x; uint16_t * ptr_src = ((uint16_t*)g_gdp.tmem)+ul_u; for (x = 0; x < width; x++) { uint16_t c = ptr_src[x]; c = ((c << 8) & 0xFF00) | (c >> 8); ptr_dst[(ul_x+x)^1] = c; } } static void DrawDepthBufferFog(void) { FB_TO_SCREEN_INFO fb_info; if (rdp.zi_width < 200) return; fb_info.addr = g_gdp.zb_address; fb_info.size = 2; fb_info.width = rdp.zi_width; fb_info.height = rdp.ci_height; fb_info.ul_x = g_gdp.__clip.xh; fb_info.lr_x = g_gdp.__clip.xl; fb_info.ul_y = g_gdp.__clip.yh; fb_info.lr_y = g_gdp.__clip.yl; fb_info.opaque = 0; DrawDepthBufferToScreen(&fb_info); } static void apply_shading(VERTEX *vptr) { int i; for (i = 0; i < 4; i++) { vptr[i].shade_mod = 0; apply_shade_mods (&vptr[i]); } } static void rdp_texrect(uint32_t w0, uint32_t w1) { float ul_x, ul_y, lr_x, lr_y; int i; int32_t off_x_i, off_y_i; uint32_t prev_tile; int32_t tilenum; float Z, dsdx, dtdy, s_ul_x, s_lr_x, s_ul_y, s_lr_y, off_size_x, off_size_y; struct { float ul_u, ul_v, lr_u, lr_v; } texUV[2]; //struct for texture coordinates VERTEX *vptr = NULL, vstd[4]; if (!rdp.LLE) { uint32_t a = rdp.pc[rdp.pc_i]; uint8_t cmdHalf1 = gfx_info.RDRAM[a+3]; uint8_t cmdHalf2 = gfx_info.RDRAM[a+11]; a >>= 2; if ( (cmdHalf1 == 0xE1 && cmdHalf2 == 0xF1) || (cmdHalf1 == 0xB4 && cmdHalf2 == 0xB3) || (cmdHalf1 == 0xB3 && cmdHalf2 == 0xB2) ) { //gSPTextureRectangle rdp.cmd2 = ((uint32_t*)gfx_info.RDRAM)[a+1]; rdp.cmd3 = ((uint32_t*)gfx_info.RDRAM)[a+3]; rdp.pc[rdp.pc_i] += 16; } else { //gDPTextureRectangle if (settings.hacks&hack_ASB) rdp.cmd2 = 0; else rdp.cmd2 = ((uint32_t*)gfx_info.RDRAM)[a+0]; rdp.cmd3 = ((uint32_t*)gfx_info.RDRAM)[a+1]; rdp.pc[rdp.pc_i] += 8; } } if ((settings.hacks&hack_Yoshi) && settings.ucode == ucode_S2DEX) { ys_memrect(w0, w1); return; } if (rdp.skip_drawing || (!fb_emulation_enabled && (rdp.cimg == g_gdp.zb_address))) { if ((settings.hacks&hack_PMario) && rdp.ci_status == CI_USELESS) pm_palette_mod (); return; } if ((settings.ucode == ucode_PerfectDark) && rdp.ci_count > 0 && (rdp.frame_buffers[rdp.ci_count-1].status == CI_ZCOPY)) { pd_zcopy(w0, w1); LRDP("Depth buffer copied.\n"); return; } if ((rdp.othermode_l >> 16) == 0x3c18 && rdp.cycle1 == 0x03ffffff && rdp.cycle2 == 0x01ff1fff) //depth image based fog { if (!depth_buffer_fog) return; if (settings.fog) DrawDepthBufferFog(); depth_buffer_fog = false; return; } // FRDP ("rdp.cycle1 %08lx, rdp.cycle2 %08lx\n", rdp.cycle1, rdp.cycle2); if (g_gdp.other_modes.cycle_type == 2) { ul_x = (int16_t)((w1 & 0x00FFF000) >> 14); ul_y = (int16_t)((w1 & 0x00000FFF) >> 2); lr_x = (int16_t)((w0 & 0x00FFF000) >> 14); lr_y = (int16_t)((w0 & 0x00000FFF) >> 2); } else { ul_x = ((int16_t)((w1 & 0x00FFF000) >> 12)) / 4.0f; ul_y = ((int16_t)(w1 & 0x00000FFF)) / 4.0f; lr_x = ((int16_t)((w0 & 0x00FFF000) >> 12)) / 4.0f; lr_y = ((int16_t)(w0 & 0x00000FFF)) / 4.0f; } if (ul_x >= lr_x) { FRDP("Wrong Texrect: ul_x: %f, lr_x: %f\n", ul_x, lr_x); return; } if (((rdp.othermode_h & RDP_CYCLE_TYPE) >> 20) > 1) { lr_x += 1.0f; lr_y += 1.0f; } else if (lr_y - ul_y < 1.0f) lr_y = ceilf(lr_y); if (settings.increase_texrect_edge) { if (floor(lr_x) != lr_x) lr_x = ceilf(lr_x); if (floor(lr_y) != lr_y) lr_y = ceilf(lr_y); } //*/ // framebuffer workaround for Zelda: MM LOT if ((rdp.othermode_l & 0xFFFF0000) == 0x0f5a0000) return; /*Gonetz*/ //hack for Zelda MM. it removes black texrects which cover all geometry in "Link meets Zelda" cut scene if ((settings.hacks&hack_Zelda) && g_gdp.ti_address >= rdp.cimg && g_gdp.ti_address < rdp.ci_end) { FRDP("Wrong Texrect. texaddr: %08lx, cimg: %08lx, cimg_end: %08lx\n", rdp.cur_cache[0]->addr, rdp.cimg, rdp.cimg+rdp.ci_width*rdp.ci_height*2); return; } //hack for Banjo2. it removes black texrects under Banjo if (settings.hacks&hack_Banjo2 && (!fb_hwfbe_enabled && ((rdp.cycle1 << 16) | (rdp.cycle2 & 0xFFFF)) == 0xFFFFFFFF && (rdp.othermode_l & 0xFFFF0000) == 0x00500000)) return; /*remove motion blur in night vision */ if ( ( settings.ucode == ucode_PerfectDark) && (rdp.maincimg[1].addr != rdp.maincimg[0].addr) && (g_gdp.ti_address >= rdp.maincimg[1].addr) && (g_gdp.ti_address < (rdp.maincimg[1].addr+rdp.ci_width * rdp.ci_height* g_gdp.fb_size)) ) { if (fb_emulation_enabled) { /* FRDP("Wrong Texrect. texaddr: %08lx, cimg: %08lx, cimg_end: %08lx\n", * g_gdp.ti_address, rdp.maincimg[1], rdp.maincimg[1]+rdp.ci_width * rdp.ci_height * g_gdp.fb_size); */ if (rdp.ci_count > 0 && rdp.frame_buffers[rdp.ci_count-1].status == CI_COPY_SELF) return; } } tilenum = (uint16_t)((w1 & 0x07000000) >> 24); rdp.texrecting = 1; prev_tile = rdp.cur_tile; rdp.cur_tile = tilenum; Z = set_sprite_combine_mode (); rdp.texrecting = 0; if (!rdp.cur_cache[0]) { rdp.cur_tile = prev_tile; return; } // **** // ** Texrect offset by Gugaman ** // //integer representation of texture coordinate. //needed to detect and avoid overflow after shifting off_x_i = (rdp.cmd2 >> 16) & 0xFFFF; off_y_i = rdp.cmd2 & 0xFFFF; dsdx = (float)((int16_t)((rdp.cmd3 & 0xFFFF0000) >> 16)) / 1024.0f; dtdy = (float)((int16_t)(rdp.cmd3 & 0x0000FFFF)) / 1024.0f; if (off_x_i & 0x8000) //check for sign bit off_x_i |= ~0xffff; //make it negative //the same as for off_x_i if (off_y_i & 0x8000) off_y_i |= ~0xffff; if (((rdp.othermode_h & RDP_CYCLE_TYPE) >> 20) == G_CYC_COPY) dsdx /= 4.0f; s_ul_x = ul_x * rdp.scale_x + rdp.offset_x; s_lr_x = lr_x * rdp.scale_x + rdp.offset_x; s_ul_y = ul_y * rdp.scale_y + rdp.offset_y; s_lr_y = lr_y * rdp.scale_y + rdp.offset_y; if ( ((rdp.cmd0>>24)&0xFF) == G_TEXRECTFLIP ) //texrectflip { off_size_x = (lr_y - ul_y - 1) * dsdx; off_size_y = (lr_x - ul_x - 1) * dtdy; } else { off_size_x = (lr_x - ul_x - 1) * dsdx; off_size_y = (lr_y - ul_y - 1) * dtdy; } //calculate texture coordinates for (i = 0; i < 2; i++) { texUV[i].ul_u = texUV[i].ul_v = texUV[i].lr_u = texUV[i].lr_v = 0; if (rdp.cur_cache[i] && (rdp.tex & (i+1))) { unsigned tilenum = rdp.cur_tile + i; float maxs = 1; float maxt = 1; int x_i = off_x_i; int y_i = off_y_i; int32_t shifter = g_gdp.tile[tilenum].shift_s; //shifting if (shifter) { if (shifter < 11) { x_i = SIGN16(x_i); x_i >>= shifter; maxs = 1.0f/(float)(1 << shifter); } else { uint8_t iShift = (16 - shifter); x_i <<= SIGN16(iShift); maxs = (float)(1 << iShift); } } shifter = g_gdp.tile[tilenum].shift_t; if (shifter) { if (shifter < 11) { y_i = SIGN16(y_i); y_i >>= shifter; maxt = 1.0f/(float)(1 << shifter); } else { uint8_t iShift = (16 - shifter); y_i <<= SIGN16(iShift); maxt = (float)(1 << iShift); } } texUV[i].ul_u = x_i / 32.0f; texUV[i].ul_v = y_i / 32.0f; texUV[i].ul_u -= rdp.tiles[tilenum].f_ul_s; texUV[i].ul_v -= rdp.tiles[tilenum].f_ul_t; texUV[i].lr_u = texUV[i].ul_u + off_size_x * maxs; texUV[i].lr_v = texUV[i].ul_v + off_size_y * maxt; texUV[i].ul_u = rdp.cur_cache[i]->c_off + rdp.cur_cache[i]->c_scl_x * texUV[i].ul_u; texUV[i].lr_u = rdp.cur_cache[i]->c_off + rdp.cur_cache[i]->c_scl_x * texUV[i].lr_u; texUV[i].ul_v = rdp.cur_cache[i]->c_off + rdp.cur_cache[i]->c_scl_y * texUV[i].ul_v; texUV[i].lr_v = rdp.cur_cache[i]->c_off + rdp.cur_cache[i]->c_scl_y * texUV[i].lr_v; } } rdp.cur_tile = prev_tile; // **** FRDP (" scissor: (%d, %d) -> (%d, %d)\n", rdp.scissor.ul_x, rdp.scissor.ul_y, rdp.scissor.lr_x, rdp.scissor.lr_y); CCLIP2 (s_ul_x, s_lr_x, texUV[0].ul_u, texUV[0].lr_u, texUV[1].ul_u, texUV[1].lr_u, (float)rdp.scissor.ul_x, (float)rdp.scissor.lr_x); CCLIP2 (s_ul_y, s_lr_y, texUV[0].ul_v, texUV[0].lr_v, texUV[1].ul_v, texUV[1].lr_v, (float)rdp.scissor.ul_y, (float)rdp.scissor.lr_y); memset(vstd, 0, sizeof(VERTEX) * 4); vstd[0].x = s_ul_x; vstd[0].y = s_ul_y; vstd[0].z = Z; vstd[0].q = 1.0f; vstd[0].u[0] = texUV[0].ul_u; vstd[0].v[0] = texUV[0].ul_v; vstd[0].u[1] = texUV[1].ul_u; vstd[0].v[1] = texUV[1].ul_v; vstd[0].coord[0] = 0; vstd[0].coord[1] = 0; vstd[0].coord[2] = 0; vstd[0].coord[3] = 0; vstd[0].f = 255.0f; vstd[1].x = s_lr_x; vstd[1].y = s_ul_y; vstd[1].z = Z; vstd[1].q = 1.0f; vstd[1].u[0] = texUV[0].lr_u; vstd[1].v[0] = texUV[0].ul_v; vstd[1].u[1] = texUV[1].lr_u; vstd[1].v[1] = texUV[1].ul_v; vstd[1].coord[0] = 0; vstd[1].coord[1] = 0; vstd[1].coord[2] = 0; vstd[1].coord[3] = 0; vstd[1].f = 255.0f; vstd[2].x = s_ul_x; vstd[2].y = s_lr_y; vstd[2].z = Z; vstd[2].q = 1.0f; vstd[2].u[0] = texUV[0].ul_u; vstd[2].v[0] = texUV[0].lr_v; vstd[2].u[1] = texUV[1].ul_u; vstd[2].v[1] = texUV[1].lr_v; vstd[2].coord[0] = 0; vstd[2].coord[1] = 0; vstd[2].coord[2] = 0; vstd[2].coord[3] = 0; vstd[2].f = 255.0f; vstd[3].x = s_lr_x; vstd[3].y = s_lr_y; vstd[3].z = Z; vstd[3].q = 1.0f; vstd[3].u[0] = texUV[0].lr_u; vstd[3].v[0] = texUV[0].lr_v; vstd[3].u[1] = texUV[1].lr_u; vstd[3].v[1] = texUV[1].lr_v; vstd[3].coord[0] = 0; vstd[3].coord[1] = 0; vstd[3].coord[2] = 0; vstd[3].coord[3] = 0; vstd[3].f = 255.0f; if ( ((rdp.cmd0>>24)&0xFF) == G_TEXRECTFLIP ) { vstd[1].u[0] = texUV[0].ul_u; vstd[1].v[0] = texUV[0].lr_v; vstd[1].u[1] = texUV[1].ul_u; vstd[1].v[1] = texUV[1].lr_v; vstd[2].u[0] = texUV[0].lr_u; vstd[2].v[0] = texUV[0].ul_v; vstd[2].u[1] = texUV[1].lr_u; vstd[2].v[1] = texUV[1].ul_v; } vptr = (VERTEX*)vstd; apply_shading(vptr); #if 0 if (fullscreen) #endif { if (rdp.fog_mode >= FOG_MODE_BLEND) { float fog = 1.0f/ g_gdp.fog_color.a; if (rdp.fog_mode != FOG_MODE_BLEND) fog = 1.0f / ((~g_gdp.fog_color.total)&0xFF); for (i = 0; i < 4; i++) vptr[i].f = fog; grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT, g_gdp.fog_color.total); } ConvertCoordsConvert (vptr, 4); grDrawVertexArrayContiguous (GR_TRIANGLE_STRIP, 4, vptr); } } static void rdp_setscissor(uint32_t w0, uint32_t w1) { gdp_set_scissor(w0, w1); /* clipper resolution is 320x240, scale based on computer resolution */ /* TODO/FIXME - all these values are different from Angrylion's */ g_gdp.__clip.xh = (uint32_t)(((w0 & 0x00FFF000) >> 14)); g_gdp.__clip.yh = (uint32_t)(((w0 & 0x00000FFF) >> 2)); g_gdp.__clip.xl = (uint32_t)(((w1 & 0x00FFF000) >> 14)); g_gdp.__clip.yl = (uint32_t)(((w1 & 0x00000FFF) >> 2)); rdp.ci_upper_bound = g_gdp.__clip.yh; rdp.ci_lower_bound = g_gdp.__clip.yl; rdp.scissor_set = true; if (rdp.view_scale[0] == 0) //viewport is not set? { rdp.view_scale[0] = (g_gdp.__clip.xl >> 1) * rdp.scale_x; rdp.view_scale[1] = (g_gdp.__clip.yl >> 1) * -rdp.scale_y; rdp.view_trans[0] = rdp.view_scale[0]; rdp.view_trans[1] = -rdp.view_scale[1]; g_gdp.flags |= UPDATE_VIEWPORT; } } #define F3DEX2_SETOTHERMODE(cmd,sft,len,data) { \ rdp.cmd0 = (cmd<<24) | ((32-(sft)-(len))<<8) | (((len)-1)); \ rdp.cmd1 = data; \ gfx_instruction[settings.ucode][cmd](rdp.cmd0, rdp.cmd1); \ } #define SETOTHERMODE(cmd,sft,len,data) { \ rdp.cmd0 = (cmd<<24) | ((sft)<<8) | (len); \ rdp.cmd1 = data; \ gfx_instruction[settings.ucode][cmd](rdp.cmd0, rdp.cmd1); \ } static void rdp_setothermode(uint32_t w0, uint32_t w1) { gdp_set_other_modes(w0, w1); if ((settings.ucode == ucode_F3DEX2) || (settings.ucode == ucode_CBFD)) { int cmd0 = rdp.cmd0; F3DEX2_SETOTHERMODE(0xE2, 0, 32, rdp.cmd1); // SETOTHERMODE_L F3DEX2_SETOTHERMODE(0xE3, 0, 32, cmd0 & 0x00FFFFFF); // SETOTHERMODE_H } else { int cmd0 = rdp.cmd0; SETOTHERMODE(0xB9, 0, 32, rdp.cmd1); // SETOTHERMODE_L SETOTHERMODE(0xBA, 0, 32, cmd0 & 0x00FFFFFF); // SETOTHERMODE_H } } void load_palette (uint32_t addr, uint16_t start, uint16_t count) { uint16_t i, p; uint16_t *dpal = (uint16_t*)(rdp.pal_8 + start); uint16_t end = start+count; for (i=start; i>= 4; end = start + (count >> 4); if (end == start) // it can be if count < 16 end = start + 1; for (p = start; p < end; p++) rdp.pal_8_crc[p] = CRC32( 0xFFFFFFFF, &rdp.pal_8[(p << 4)], 32 ); rdp.pal_256_crc = CRC32( 0xFFFFFFFF, rdp.pal_8_crc, 64 ); } static void rdp_loadtlut(uint32_t w0, uint32_t w1) { uint32_t tile = (w1 >> 24) & 0x07; uint16_t start = g_gdp.tile[tile].tmem - 256; // starting location in the palettes uint16_t count = ((uint16_t)(w1 >> 14) & 0x3FF) + 1; // number to copy if (g_gdp.ti_address + (count<<1) > BMASK) count = (uint16_t)((BMASK - g_gdp.ti_address) >> 1); if (start+count > 256) count = 256-start; load_palette (g_gdp.ti_address, start, count); g_gdp.ti_address += count << 1; } static void rdp_settilesize(uint32_t w0, uint32_t w1) { int tilenum = gdp_set_tile_size_wrap(w0, w1); rdp.last_tile_size = tilenum; /* TODO - should get rid of this eventually */ rdp.tiles[tilenum].f_ul_s = (float)g_gdp.tile[tilenum].sl / 4.0f; rdp.tiles[tilenum].f_ul_t = (float)g_gdp.tile[tilenum].tl / 4.0f; /* TODO - Wrong values being used by Glide64 - unify this * later so that it uses the same values as Angrylion */ g_gdp.tile[tilenum].sh = (((uint16_t)(w0 >> 14)) & 0x03ff); g_gdp.tile[tilenum].th = (((uint16_t)(w0 >> 2 )) & 0x03ff); g_gdp.tile[tilenum].sl = (((uint16_t)(w1 >> 14)) & 0x03ff); g_gdp.tile[tilenum].tl = (((uint16_t)(w1 >> 2 )) & 0x03ff); /* handle wrapping */ if (g_gdp.tile[tilenum].sl < g_gdp.tile[tilenum].sh) g_gdp.tile[tilenum].sl += 0x400; if (g_gdp.tile[tilenum].tl < g_gdp.tile[tilenum].th) g_gdp.tile[tilenum].tl += 0x400; } static void rdp_loadblock(uint32_t w0, uint32_t w1) { // lr_s specifies number of 64-bit words to copy // 10.2 format gDPLoadBlock( ((w1 >> 24) & 0x07), (w0 >> 14) & 0x3FF, /* ul_s */ (w0 >> 2) & 0x3FF, /* ul_t */ (w1 >> 14) & 0x3FF, /* lr_s */ (w1 & 0x0FFF) /* dxt */ ); } static void rdp_loadtile(uint32_t w0, uint32_t w1) { uint32_t tile, offs, height, width; uint16_t ul_s, ul_t, lr_s, lr_t; int line_n; if (rdp.skip_drawing) return; rdp.timg.set_by = 1; // load tile tile = (uint32_t)((w1 >> 24) & 0x07); rdp.addr[g_gdp.tile[tile].tmem] = g_gdp.ti_address; ul_s = (uint16_t)((w0 >> 14) & 0x03FF); ul_t = (uint16_t)((w0 >> 2 ) & 0x03FF); lr_s = (uint16_t)((w1 >> 14) & 0x03FF); lr_t = (uint16_t)((w1 >> 2 ) & 0x03FF); if (lr_s < ul_s || lr_t < ul_t) return; if ((settings.hacks&hack_Tonic) && tile == 7) { g_gdp.tile[0].sh = ul_s; g_gdp.tile[0].th = ul_t; g_gdp.tile[0].sl = lr_s; g_gdp.tile[0].tl = lr_t; } height = lr_t - ul_t + 1; // get height width = lr_s - ul_s + 1; #ifdef TEXTURE_FILTER LOAD_TILE_INFO &info = rdp.load_info[g_gdp.tile[tile].tmem]; info.tile_ul_s = ul_s; info.tile_ul_t = ul_t; info.tile_width = (g_gdp.tile[tile].ms ? min((uint16_t)width, 1 << g_gdp.tile[tile].ms) : (uint16_t)width); info.tile_height = (g_gdp.tile[tile].mt ? min((uint16_t)height, 1 << g_gdp.tile[tile].mt) : (uint16_t)height); if (settings.hacks&hack_MK64) { if (info.tile_width%2) info.tile_width--; if (info.tile_height%2) info.tile_height--; } info.tex_width = g_gdp.ti_width; info.tex_size = g_gdp.ti_size; #endif line_n = g_gdp.ti_width << g_gdp.tile[tile].size >> 1; offs = ul_t * line_n; offs += ul_s << g_gdp.tile[tile].size >> 1; offs += g_gdp.ti_address; if (offs >= BMASK) return; if (g_gdp.ti_size == G_IM_SIZ_32b) { LoadTile32b(tile, ul_s, ul_t, width, height); } else { uint8_t *dst, *end; uint32_t wid_64; // check if points to bad location if (offs + line_n*height > BMASK) height = (BMASK - offs) / line_n; if (height == 0) return; wid_64 = g_gdp.tile[tile].line; dst = ((uint8_t*)g_gdp.tmem) + (g_gdp.tile[tile].tmem << 3); end = ((uint8_t*)g_gdp.tmem) + 4096 - (wid_64<<3); loadTile((uint32_t *)gfx_info.RDRAM, (uint32_t *)dst, wid_64, height, line_n, offs, (uint32_t *)end); } //FRDP("loadtile: tile: %d, ul_s: %d, ul_t: %d, lr_s: %d, lr_t: %d\n", tile, ul_s, ul_t, lr_s, lr_t); } static void rdp_settile(uint32_t w0, uint32_t w1) { rdp.last_tile = gdp_set_tile(w0, w1); } static void rdp_fillrect(uint32_t w0, uint32_t w1) { int32_t s_ul_x, s_lr_x, s_ul_y, s_lr_y; int pd_multiplayer; uint32_t ul_x = ((w1 & 0x00FFF000) >> 14); uint32_t ul_y = (w1 & 0x00000FFF) >> 2; uint32_t lr_x = ((w0 & 0x00FFF000) >> 14) + 1; uint32_t lr_y = ((w0 & 0x00000FFF) >> 2) + 1; if ((ul_x > lr_x) || (ul_y > lr_y)) { //LRDP("Fillrect. Wrong coordinates. Skipped\n"); return; } pd_multiplayer = (settings.ucode == ucode_PerfectDark) && (((rdp.othermode_h & RDP_CYCLE_TYPE) >> 20) == 3) && (g_gdp.fill_color.total == 0xFFFCFFFC); if ((rdp.cimg == g_gdp.zb_address) || (fb_emulation_enabled && rdp.ci_count > 0 && rdp.frame_buffers[rdp.ci_count-1].status == CI_ZIMG) || pd_multiplayer) { //LRDP("Fillrect - cleared the depth buffer\n"); //if (fullscreen) { if (!(settings.hacks&hack_Hyperbike) || rdp.ci_width > 64) //do not clear main depth buffer for aux depth buffers { update_scissor(false); grDepthMask (FXTRUE); grColorMask (FXFALSE, FXFALSE); grBufferClear (0, 0, g_gdp.fill_color.total ? g_gdp.fill_color.total & 0xFFFF : 0xFFFF); grColorMask (FXTRUE, FXTRUE); g_gdp.flags |= UPDATE_ZBUF_ENABLED; } //if (settings.frame_buffer&fb_depth_clear) { uint32_t zi_width_in_dwords, *dst, x, y; ul_x = min(max(ul_x, g_gdp.__clip.xh), g_gdp.__clip.xl); lr_x = min(max(lr_x, g_gdp.__clip.xh), g_gdp.__clip.xl); ul_y = min(max(ul_y, g_gdp.__clip.yh), g_gdp.__clip.yl); lr_y = min(max(lr_y, g_gdp.__clip.yh), g_gdp.__clip.yl); zi_width_in_dwords = rdp.ci_width >> 1; ul_x >>= 1; lr_x >>= 1; dst = (uint32_t*)(gfx_info.RDRAM+rdp.cimg); dst += ul_y * zi_width_in_dwords; for (y = ul_y; y < lr_y; y++) { for (x = ul_x; x < lr_x; x++) dst[x] = g_gdp.fill_color.total; dst += zi_width_in_dwords; } } } return; } if (rdp.skip_drawing) { //LRDP("Fillrect skipped\n"); return; } // Update scissor //if (fullscreen) update_scissor(false); if (settings.decrease_fillrect_edge && ((rdp.othermode_h & RDP_CYCLE_TYPE) >> 20) == 0) { lr_x--; lr_y--; } s_ul_x = (uint32_t)(ul_x * rdp.scale_x + rdp.offset_x); s_lr_x = (uint32_t)(lr_x * rdp.scale_x + rdp.offset_x); s_ul_y = (uint32_t)(ul_y * rdp.scale_y + rdp.offset_y); s_lr_y = (uint32_t)(lr_y * rdp.scale_y + rdp.offset_y); if (s_lr_x < 0) s_lr_x = 0; if (s_lr_y < 0) s_lr_y = 0; if ((uint32_t)s_ul_x > settings.res_x) s_ul_x = settings.res_x; if ((uint32_t)s_ul_y > settings.res_y) s_ul_y = settings.res_y; FRDP (" - %d, %d, %d, %d\n", s_ul_x, s_ul_y, s_lr_x, s_lr_y); { VERTEX v[4], vout[4]; float Z; grFogMode (GR_FOG_DISABLE, g_gdp.fog_color.total); Z = (((rdp.othermode_h & RDP_CYCLE_TYPE) >> 20) == 3) ? 0.0f : set_sprite_combine_mode(); memset(v, 0, sizeof(VERTEX) * 4); // Draw the vertices v[0].x = (float)s_ul_x; v[0].y = (float)s_ul_y; v[0].z = Z; v[0].q = 1.0f; v[1].x = (float)s_lr_x; v[1].y = (float)s_ul_y; v[1].z = Z; v[1].q = 1.0f; v[2].x = (float)s_ul_x; v[2].y = (float)s_lr_y; v[2].z = Z; v[2].q = 1.0f; v[3].x = (float)s_lr_x; v[3].y = (float)s_lr_y; v[3].z = Z; v[3].q = 1.0f; if (((rdp.othermode_h & RDP_CYCLE_TYPE) >> 20) == 3) { uint32_t color = g_gdp.fill_color.total; if ((settings.hacks&hack_PMario) && rdp.ci_count > 0 && rdp.frame_buffers[rdp.ci_count-1].status == CI_AUX) { //background of auxiliary frame buffers must have zero alpha. //make it black, set 0 alpha to plack pixels on frame buffer read color = 0; } else if (g_gdp.fb_size < 3) { color = ((color&1)?0xFF:0) | ((uint32_t)((float)((color&0xF800) >> 11) / 31.0f * 255.0f) << 24) | ((uint32_t)((float)((color&0x07C0) >> 6) / 31.0f * 255.0f) << 16) | ((uint32_t)((float)((color&0x003E) >> 1) / 31.0f * 255.0f) << 8); } grConstantColorValue (color); grColorCombine (GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE, FXFALSE); grAlphaCombine (GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE, FXFALSE); grAlphaBlendFunction (GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_ONE, GR_BLEND_ZERO); grAlphaTestFunction (GR_CMP_ALWAYS, 0x00, 0); grStippleMode(GR_STIPPLE_DISABLE); grCullMode(GR_CULL_DISABLE); grFogMode (GR_FOG_DISABLE, g_gdp.fog_color.total); grDepthBufferFunction (GR_CMP_ALWAYS); grDepthMask (FXFALSE); g_gdp.flags |= UPDATE_COMBINE | UPDATE_CULL_MODE | UPDATE_FOG_ENABLED | UPDATE_ZBUF_ENABLED; } else { uint32_t cmb_mode_c = (rdp.cycle1 << 16) | (rdp.cycle2 & 0xFFFF); uint32_t cmb_mode_a = (rdp.cycle1 & 0x0FFF0000) | ((rdp.cycle2 >> 16) & 0x00000FFF); if (cmb_mode_c == 0x9fff9fff || cmb_mode_a == 0x09ff09ff) //shade apply_shading(v); if ((rdp.othermode_l & RDP_FORCE_BLEND) && ((rdp.othermode_l >> 16) == 0x0550)) //special blender mode for Bomberman64 { grAlphaCombine (GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE, FXFALSE); grConstantColorValue((cmb.ccolor & 0xFFFFFF00) | g_gdp.fog_color.a); g_gdp.flags |= UPDATE_COMBINE; } } vout[0] = v[0]; vout[1] = v[2]; vout[2] = v[1]; vout[3] = v[3]; grDrawVertexArrayContiguous(GR_TRIANGLE_STRIP, 4, &vout[0]); } } static void rdp_setprimcolor(uint32_t w0, uint32_t w1) { gdp_set_prim_color(w0, w1); /* TODO/FIXME - different value from the one Angrylion sets. */ g_gdp.primitive_lod_min = (w0 >> 8) & 0xFF; } static void rdp_setcombine(uint32_t w0, uint32_t w1) { gdp_set_combine(w0, w1); rdp.cycle1 = (g_gdp.combine.sub_a_rgb0 << 0) | (g_gdp.combine.sub_b_rgb0 << 4) | (g_gdp.combine.mul_rgb0 << 8) | (g_gdp.combine.add_rgb0 << 13) | (g_gdp.combine.sub_a_a0 << 16) | (g_gdp.combine.sub_b_a0 << 19)| (g_gdp.combine.mul_a0 << 22)| (g_gdp.combine.add_a0 << 25); rdp.cycle2 = (g_gdp.combine.sub_a_rgb1 << 0) | (g_gdp.combine.sub_b_rgb1 << 4) | (g_gdp.combine.mul_rgb1 << 8) | (g_gdp.combine.add_rgb1 << 13) | (g_gdp.combine.sub_a_a1 << 16)| (g_gdp.combine.sub_b_a1 << 19)| (g_gdp.combine.mul_a1 << 22)| (g_gdp.combine.add_a1 << 25); } static void rdp_settextureimage(uint32_t w0, uint32_t w1) { gdp_set_texture_image(w0, w1); /* TODO/FIXME - all different values from the ones Angrylion sets. */ g_gdp.ti_format = (uint8_t)((w0 >> 21) & 0x07); g_gdp.ti_width = (uint16_t)(1 + (w0 & 0x00000FFF)); g_gdp.ti_address = RSP_SegmentToPhysical(w1); if (ucode5_texshiftaddr) { if (g_gdp.ti_format == G_IM_FMT_RGBA) { uint16_t * t = (uint16_t*)(gfx_info.RDRAM+ucode5_texshiftaddr); ucode5_texshift = t[ucode5_texshiftcount^1]; g_gdp.ti_address += ucode5_texshift; } else { ucode5_texshiftaddr = 0; ucode5_texshift = 0; ucode5_texshiftcount = 0; } } rdp.s2dex_tex_loaded = true; if (rdp.ci_count > 0 && rdp.frame_buffers[rdp.ci_count-1].status == CI_COPY_SELF && (g_gdp.ti_address >= rdp.cimg) && (g_gdp.ti_address < rdp.ci_end)) { if (!rdp.fb_drawn) { CopyFrameBuffer(GR_BUFFER_BACKBUFFER); rdp.fb_drawn = true; } } } static void rdp_setdepthimage(uint32_t w0, uint32_t w1) { gdp_set_mask_image(w0, w1); /* TODO/FIXME - different from Angrylion's value */ g_gdp.zb_address = RSP_SegmentToPhysical(w1); rdp.zi_width = rdp.ci_width; } int SwapOK = true; void RestoreScale(void) { rdp.scale_x = rdp.scale_x_bak; rdp.scale_y = rdp.scale_y_bak; rdp.view_scale[0] *= rdp.scale_x; rdp.view_scale[1] *= rdp.scale_y; rdp.view_trans[0] *= rdp.scale_x; rdp.view_trans[1] *= rdp.scale_y; g_gdp.flags |= UPDATE_VIEWPORT | UPDATE_SCISSOR; } static void rdp_setcolorimage(uint32_t w0, uint32_t w1) { gdp_set_color_image(w0, w1); if (fb_emulation_enabled && (rdp.num_of_ci < NUMTEXBUF)) { COLOR_IMAGE *cur_fb = (COLOR_IMAGE*)&rdp.frame_buffers[rdp.ci_count]; COLOR_IMAGE *prev_fb = (COLOR_IMAGE*)&rdp.frame_buffers[rdp.ci_count?rdp.ci_count-1:0]; COLOR_IMAGE *next_fb = (COLOR_IMAGE*)&rdp.frame_buffers[rdp.ci_count+1]; switch (cur_fb->status) { case CI_MAIN: if (rdp.ci_count == 0) { if (rdp.ci_status == CI_AUX) //for PPL { float sx, sy; sx = rdp.scale_x; sy = rdp.scale_y; rdp.scale_x = 1.0f; rdp.scale_y = 1.0f; CopyFrameBuffer (GR_BUFFER_BACKBUFFER); rdp.scale_x = sx; rdp.scale_y = sy; } { if ((rdp.num_of_ci > 1) && (next_fb->status == CI_AUX) && (next_fb->width >= cur_fb->width)) { rdp.scale_x = 1.0f; rdp.scale_y = 1.0f; } } } //else if (rdp.ci_status == CI_AUX && !rdp.copy_ci_index) // CloseTextureBuffer(); rdp.skip_drawing = false; break; case CI_COPY: if (!rdp.motionblur || (settings.frame_buffer&fb_motionblur)) { if (cur_fb->width == rdp.ci_width) { { if (!rdp.fb_drawn || prev_fb->status == CI_COPY_SELF) { CopyFrameBuffer (GR_BUFFER_BACKBUFFER); rdp.fb_drawn = true; } memcpy(gfx_info.RDRAM+cur_fb->addr,gfx_info.RDRAM+rdp.cimg, (cur_fb->width*cur_fb->height)<size>>1); } } } else memset(gfx_info.RDRAM+cur_fb->addr, 0, cur_fb->width * cur_fb->height * g_gdp.fb_size); rdp.skip_drawing = true; break; case CI_AUX_COPY: rdp.skip_drawing = false; if (!rdp.fb_drawn) { CopyFrameBuffer (GR_BUFFER_BACKBUFFER); rdp.fb_drawn = true; } break; case CI_OLD_COPY: if (!rdp.motionblur || (settings.frame_buffer&fb_motionblur)) { if (cur_fb->width == rdp.ci_width) memcpy(gfx_info.RDRAM+cur_fb->addr, gfx_info.RDRAM+rdp.maincimg[1].addr, (cur_fb->width*cur_fb->height)<size>>1); //rdp.skip_drawing = true; } else memset(gfx_info.RDRAM+cur_fb->addr, 0, (cur_fb->width*cur_fb->height) << g_gdp.fb_size >> 1); break; /* else if (rdp.frame_buffers[rdp.ci_count].status == ci_main_i) { // CopyFrameBuffer (); rdp.scale_x = rdp.scale_x_bak; rdp.scale_y = rdp.scale_y_bak; rdp.skip_drawing = false; } */ case CI_AUX: if ( cur_fb->format != 0) rdp.skip_drawing = true; else { rdp.skip_drawing = false; { if (cur_fb->format != 0) rdp.skip_drawing = true; if (rdp.ci_count == 0) { // if (rdp.num_of_ci > 1) // { rdp.scale_x = 1.0f; rdp.scale_y = 1.0f; // } } else if ( (prev_fb->status == CI_MAIN) && (prev_fb->width == cur_fb->width)) // for Pokemon Stadium CopyFrameBuffer (GR_BUFFER_BACKBUFFER); } } cur_fb->status = CI_AUX; break; case CI_ZIMG: rdp.skip_drawing = true; break; case CI_ZCOPY: if (settings.ucode != ucode_PerfectDark) rdp.skip_drawing = true; break; case CI_USELESS: rdp.skip_drawing = true; break; case CI_COPY_SELF: rdp.skip_drawing = false; break; default: rdp.skip_drawing = false; } if ((rdp.ci_count > 0) && (prev_fb->status >= CI_AUX)) //for Pokemon Stadium { if ( prev_fb->format == 0) CopyFrameBuffer (GR_BUFFER_BACKBUFFER); else if ((settings.hacks&hack_Knockout) && prev_fb->width < 100) CopyFrameBuffer (GR_BUFFER_TEXTUREBUFFER_EXT); } if (cur_fb->status == CI_COPY) { if (!rdp.motionblur && (rdp.num_of_ci > rdp.ci_count+1) && (next_fb->status != CI_AUX)) RestoreScale(); } if ((cur_fb->status == CI_MAIN) && (rdp.ci_count > 0)) { int i; int to_org_res = true; for (i = rdp.ci_count + 1; i < rdp.num_of_ci; i++) { if ((rdp.frame_buffers[i].status != CI_MAIN) && (rdp.frame_buffers[i].status != CI_ZIMG) && (rdp.frame_buffers[i].status != CI_ZCOPY)) { to_org_res = false; break; } } if (to_org_res) { LRDP("return to original scale\n"); rdp.scale_x = rdp.scale_x_bak; rdp.scale_y = rdp.scale_y_bak; } } rdp.ci_status = cur_fb->status; rdp.ci_count++; } rdp.ocimg = rdp.cimg; rdp.cimg = RSP_SegmentToPhysical(w1); rdp.ci_width = (w0 & 0xFFF) + 1; if (fb_emulation_enabled && rdp.ci_count > 0) rdp.ci_height = rdp.frame_buffers[rdp.ci_count-1].height; else if (rdp.ci_width == 32) rdp.ci_height = 32; else rdp.ci_height = g_gdp.__clip.yl; if (g_gdp.zb_address == rdp.cimg) { rdp.zi_width = rdp.ci_width; // int zi_height = min((int)rdp.zi_width*3/4, (int)rdp.vi_height); // rdp.zi_words = rdp.zi_width * zi_height; } rdp.ci_end = rdp.cimg + ((rdp.ci_width*rdp.ci_height) << (g_gdp.fb_size-1)); if (g_gdp.fb_format != G_IM_FMT_RGBA) //can't draw into non RGBA buffer { if (g_gdp.fb_format > 2) rdp.skip_drawing = true; return; } else { if (!fb_emulation_enabled) rdp.skip_drawing = false; } CI_SET = true; if (settings.swapmode > 0) { int viSwapOK; if (g_gdp.zb_address == rdp.cimg) rdp.updatescreen = 1; viSwapOK = ((settings.swapmode == 2) && (rdp.vi_org_reg == *gfx_info.VI_ORIGIN_REG)) ? false : true; if ((g_gdp.zb_address != rdp.cimg) && (rdp.ocimg != rdp.cimg) && SwapOK && viSwapOK ) { if (fb_emulation_enabled) rdp.maincimg[0] = rdp.frame_buffers[rdp.main_ci_index]; else rdp.maincimg[0].addr = rdp.cimg; rdp.last_drawn_ci_addr = (settings.swapmode == 2) ? swapped_addr : rdp.maincimg[0].addr; swapped_addr = rdp.cimg; newSwapBuffers(); rdp.vi_org_reg = *gfx_info.VI_ORIGIN_REG; SwapOK = false; } } } static void rsp_reserved0(uint32_t w0, uint32_t w1) { } static void rsp_uc5_reserved0(uint32_t w0, uint32_t w1) { ucode5_texshiftaddr = RSP_SegmentToPhysical(w1); ucode5_texshiftcount = 0; } static void rsp_reserved1(uint32_t w0, uint32_t w1) { } static void rsp_reserved2(uint32_t w0, uint32_t w1) { } static void rsp_reserved3(uint32_t w0, uint32_t w1) { } /****************************************************************** Function: FrameBufferRead Purpose: This function is called to notify the dll that the frame buffer memory is beening read at the given address. DLL should copy content from its render buffer to the frame buffer in N64 RDRAM DLL is responsible to maintain its own frame buffer memory addr list DLL should copy 4KB block content back to RDRAM frame buffer. Emulator should not call this function again if other memory is read within the same 4KB range input: addr rdram address val val size 1 = uint8_t, 2 = uint16_t, 4 = uint32_t output: none *******************************************************************/ EXPORT void CALL FBRead(uint32_t addr) { uint32_t a; if (cpu_fb_ignore) return; if (cpu_fb_write_called) { cpu_fb_ignore = true; cpu_fb_write = false; return; } cpu_fb_read_called = true; a = RSP_SegmentToPhysical(addr); if (!rdp.fb_drawn && (a >= rdp.cimg) && (a < rdp.ci_end)) { fbreads_back++; //if (fbreads_back > 2) //&& (rdp.ci_width <= 320)) { CopyFrameBuffer (GR_BUFFER_BACKBUFFER); rdp.fb_drawn = true; } } if (!rdp.fb_drawn_front && (a >= rdp.maincimg[1].addr) && (a < rdp.maincimg[1].addr + rdp.ci_width*rdp.ci_height*2)) { fbreads_front++; //if (fbreads_front > 2)//&& (rdp.ci_width <= 320)) { uint32_t cimg = rdp.cimg; rdp.cimg = rdp.maincimg[1].addr; if (fb_emulation_enabled) { uint32_t h; rdp.ci_width = rdp.maincimg[1].width; rdp.ci_count = 0; h = rdp.frame_buffers[0].height; rdp.frame_buffers[0].height = rdp.maincimg[1].height; CopyFrameBuffer(GR_BUFFER_FRONTBUFFER); rdp.frame_buffers[0].height = h; } else { CopyFrameBuffer(GR_BUFFER_FRONTBUFFER); } rdp.cimg = cimg; rdp.fb_drawn_front = true; } } } /****************************************************************** Function: FrameBufferWrite Purpose: This function is called to notify the dll that the frame buffer has been modified by CPU at the given address. input: addr rdram address val val size 1 = uint8_t, 2 = uint16_t, 4 = uint32_t output: none *******************************************************************/ EXPORT void CALL FBWrite(uint32_t addr, uint32_t size) { uint32_t a, shift_l, shift_r; if (cpu_fb_ignore) return; if (cpu_fb_read_called) { cpu_fb_ignore = true; cpu_fb_write = false; return; } cpu_fb_write_called = true; a = RSP_SegmentToPhysical(addr); if (a < rdp.cimg || a > rdp.ci_end) return; cpu_fb_write = true; shift_l = (a-rdp.cimg) >> 1; shift_r = shift_l+2; d_ul_x = min(d_ul_x, shift_l%rdp.ci_width); d_ul_y = min(d_ul_y, shift_l/rdp.ci_width); d_lr_x = max(d_lr_x, shift_r%rdp.ci_width); d_lr_y = max(d_lr_y, shift_r/rdp.ci_width); } /************************************************************************ Function: FBGetFrameBufferInfo Purpose: This function is called by the emulator core to retrieve frame buffer information from the video plugin in order to be able to notify the video plugin about CPU frame buffer read/write operations size: = 1 byte = 2 word (16 bit) <-- this is N64 default depth buffer format = 4 dword (32 bit) when frame buffer information is not available yet, set all values in the FrameBufferInfo structure to 0 input: FrameBufferInfo pinfo[6] pinfo is pointed to a FrameBufferInfo structure which to be filled in by this function output: Values are return in the FrameBufferInfo structure Plugin can return up to 6 frame buffer info ************************************************************************/ ///* EXPORT void CALL FBGetFrameBufferInfo(void *p) { int i; FrameBufferInfo * pinfo = (FrameBufferInfo *)p; memset(pinfo,0,sizeof(FrameBufferInfo)*6); if (!(settings.frame_buffer&fb_get_info)) return; if (fb_emulation_enabled) { int info_index; pinfo[0].addr = rdp.maincimg[1].addr; pinfo[0].size = rdp.maincimg[1].size; pinfo[0].width = rdp.maincimg[1].width; pinfo[0].height = rdp.maincimg[1].height; info_index = 1; for (i = 0; i < rdp.num_of_ci && info_index < 6; i++) { COLOR_IMAGE *cur_fb = (COLOR_IMAGE*)&rdp.frame_buffers[i]; if ( cur_fb->status == CI_MAIN || cur_fb->status == CI_COPY_SELF || cur_fb->status == CI_OLD_COPY ) { pinfo[info_index].addr = cur_fb->addr; pinfo[info_index].size = cur_fb->size; pinfo[info_index].width = cur_fb->width; pinfo[info_index].height = cur_fb->height; info_index++; } } } else { pinfo[0].addr = rdp.maincimg[0].addr; pinfo[0].size = g_gdp.fb_size; pinfo[0].width = rdp.ci_width; pinfo[0].height = rdp.ci_width*3/4; pinfo[1].addr = rdp.maincimg[1].addr; pinfo[1].size = g_gdp.fb_size; pinfo[1].width = rdp.ci_width; pinfo[1].height = rdp.ci_width*3/4; } } #include "ucodeFB.h" void DetectFrameBufferUsage(void) { uint32_t ci, zi; int i, previous_ci_was_read, all_zimg; uint32_t dlist_start = *(uint32_t*)(gfx_info.DMEM+0xFF0); // Do nothing if dlist is empty if (dlist_start == 0) return; ci = rdp.cimg; zi = g_gdp.zb_address; rdp.main_ci_last_tex_addr = 0; rdp.main_ci = 0; rdp.main_ci_end = 0; rdp.main_ci_bg = 0; rdp.ci_count = 0; rdp.main_ci_index = 0; rdp.copy_ci_index = 0; rdp.copy_zi_index = 0; rdp.zimg_end = 0; rdp.tmpzimg = 0; rdp.motionblur = false; previous_ci_was_read = rdp.read_previous_ci; rdp.read_previous_ci = false; rdp.read_whole_frame = false; rdp.swap_ci_index = rdp.black_ci_index = -1; SwapOK = true; // Start executing at the start of the display list rdp.pc_i = 0; rdp.pc[rdp.pc_i] = dlist_start; rdp.dl_count = -1; rdp.halt = 0; rdp.scale_x_bak = rdp.scale_x; rdp.scale_y_bak = rdp.scale_y; do { // Get the address of the next command uint32_t a = rdp.pc[rdp.pc_i] & BMASK; // Load the next command and its input rdp.cmd0 = ((uint32_t*)gfx_info.RDRAM)[a>>2]; // \ Current command, 64 bit rdp.cmd1 = ((uint32_t*)gfx_info.RDRAM)[(a>>2)+1]; // / // Output the address before the command // Go to the next instruction rdp.pc[rdp.pc_i] = (a+8) & BMASK; if ((uintptr_t)((void*)(gfx_instruction_lite[settings.ucode][rdp.cmd0>>24]))) gfx_instruction_lite[settings.ucode][rdp.cmd0>>24](rdp.cmd0, rdp.cmd1); // check DL counter if (rdp.dl_count != -1) { rdp.dl_count --; if (rdp.dl_count == 0) { rdp.dl_count = -1; LRDP("End of DL\n"); rdp.pc_i --; } } }while (!rdp.halt); SwapOK = true; if (rdp.ci_count > NUMTEXBUF) //overflow { rdp.cimg = ci; g_gdp.zb_address = zi; rdp.num_of_ci = rdp.ci_count; rdp.scale_x = rdp.scale_x_bak; rdp.scale_y = rdp.scale_y_bak; return; } if (rdp.black_ci_index > 0 && rdp.black_ci_index < rdp.copy_ci_index) rdp.frame_buffers[rdp.black_ci_index].status = CI_MAIN; if (rdp.frame_buffers[rdp.ci_count-1].status == CI_UNKNOWN) { if (rdp.ci_count > 1) rdp.frame_buffers[rdp.ci_count-1].status = CI_AUX; else rdp.frame_buffers[rdp.ci_count-1].status = CI_MAIN; } if ((rdp.ci_count > 0 && rdp.frame_buffers[rdp.ci_count-1].status == CI_AUX) && (rdp.frame_buffers[rdp.main_ci_index].width < 320) && (rdp.frame_buffers[rdp.ci_count-1].width > rdp.frame_buffers[rdp.main_ci_index].width)) { for (i = 0; i < rdp.ci_count; i++) { if (rdp.frame_buffers[i].status == CI_MAIN) rdp.frame_buffers[i].status = CI_AUX; else if (rdp.frame_buffers[i].addr == rdp.frame_buffers[rdp.ci_count-1].addr) rdp.frame_buffers[i].status = CI_MAIN; // FRDP("rdp.frame_buffers[%d].status = %d\n", i, rdp.frame_buffers[i].status); } rdp.main_ci_index = rdp.ci_count-1; } all_zimg = true; for (i = 0; i < rdp.ci_count; i++) { if (rdp.frame_buffers[i].status != CI_ZIMG) { all_zimg = false; break; } } if (all_zimg) { for (i = 0; i < rdp.ci_count; i++) rdp.frame_buffers[i].status = CI_MAIN; } #ifndef NDEBUG LRDP("detect fb final results: \n"); for (i = 0; i < rdp.ci_count; i++) { FRDP("rdp.frame_buffers[%d].status = %s, addr: %08lx, height: %d\n", i, CIStatus[rdp.frame_buffers[i].status], rdp.frame_buffers[i].addr, rdp.frame_buffers[i].height); } #endif rdp.cimg = ci; g_gdp.zb_address = zi; rdp.num_of_ci = rdp.ci_count; if (rdp.read_previous_ci && previous_ci_was_read) { if (!fb_hwfbe_enabled || !rdp.copy_ci_index) rdp.motionblur = true; } if (rdp.motionblur || fb_hwfbe_enabled || (rdp.frame_buffers[rdp.copy_ci_index].status == CI_AUX_COPY)) { rdp.scale_x = rdp.scale_x_bak; rdp.scale_y = rdp.scale_y_bak; } if ((rdp.read_previous_ci || previous_ci_was_read) && !rdp.copy_ci_index) rdp.read_whole_frame = true; if (rdp.read_whole_frame) { { if (rdp.motionblur) { if (settings.frame_buffer&fb_motionblur) CopyFrameBuffer (GR_BUFFER_BACKBUFFER); else memset(gfx_info.RDRAM+rdp.cimg, 0, rdp.ci_width * rdp.ci_height * g_gdp.fb_size); } else //if (ci_width == rdp.frame_buffers[rdp.main_ci_index].width) { if (rdp.maincimg[0].height > 65) //for 1080 { uint32_t h; rdp.cimg = rdp.maincimg[0].addr; rdp.ci_width = rdp.maincimg[0].width; rdp.ci_count = 0; h = rdp.frame_buffers[0].height; rdp.frame_buffers[0].height = rdp.maincimg[0].height; CopyFrameBuffer (GR_BUFFER_BACKBUFFER); rdp.frame_buffers[0].height = h; } else //conker { CopyFrameBuffer (GR_BUFFER_BACKBUFFER); } } } } rdp.ci_count = 0; rdp.maincimg[0] = rdp.frame_buffers[rdp.main_ci_index]; //rdp.scale_x = rdp.scale_x_bak; //rdp.scale_y = rdp.scale_y_bak; } /******************************************* * ProcessRDPList * ******************************************* * based on sources of ziggy's z64 * *******************************************/ static uint32_t rdp_cmd_ptr = 0; static uint32_t rdp_cmd_cur = 0; static uint32_t rdp_cmd_data[0x1000]; #define XSCALE(x) ((float)(x)/(1<<18)) #define YSCALE(y) ((float)(y)/(1<<2)) #define ZSCALE(z) ((g_gdp.other_modes.z_source_sel == 1) ? (float)(g_gdp.prim_color.z) : (float)((uint32_t)(z))/0xffff0000) #define PERSP_EN ((rdp.othermode_h & RDP_PERSP_TEX_ENABLE)) #define WSCALE(z) 1.0f/(PERSP_EN? ((float)((uint32_t)(z) + 0x10000)/0xffff0000) : 1.0f) #define CSCALE(c) (((c)>0x3ff0000? 0x3ff0000:((c)<0? 0 : (c)))>>18) #define _PERSP(w) ( w ) #define PERSP(s, w) ( ((int64_t)(s) << 20) / (_PERSP(w)? _PERSP(w):1) ) #define SSCALE(s, _w) (PERSP_EN ? (float)(PERSP(s, _w))/(1 << 10) : (float)(s)/(1<<21)) #define TSCALE(s, w) (PERSP_EN ? (float)(PERSP(s, w))/(1 << 10) : (float)(s)/(1<<21)) static void lle_triangle(uint32_t w0, uint32_t w1, int shade, int texture, int zbuffer, uint32_t *rdp_cmd) { int j; int xleft, xright, xleft_inc, xright_inc; VERTEX vtxbuf[12], *vtx; int32_t nbVtxs; int32_t yl, ym, yh; /* triangle edge y-coordinates */ int32_t xl, xh, xm; /* triangle edge x-coordinates */ int32_t dxldy, dxhdy, dxmdy; /* triangle edge inverse-slopes */ uint32_t w2, w3, w4, w5, w6, w7; int r = 0xff; int g = 0xff; int b = 0xff; int a = 0xff; int z = 0xffff0000; int s = 0; int t = 0; int w = 0x30000; int drdx = 0, dgdx = 0, dbdx = 0, dadx = 0, dzdx = 0, dsdx = 0, dtdx = 0, dwdx = 0; int drde = 0, dgde = 0, dbde = 0, dade = 0, dzde = 0, dsde = 0, dtde = 0, dwde = 0; int flip = (w0 & 0x800000) ? 1 : 0; uint32_t * shade_base = rdp_cmd + 8; uint32_t * texture_base = rdp_cmd + 8; uint32_t * zbuffer_base = rdp_cmd + 8; if (shade) { texture_base += 16; zbuffer_base += 16; } if (texture) { zbuffer_base += 16; } w2 = rdp_cmd[2]; w3 = rdp_cmd[3]; w4 = rdp_cmd[4]; w5 = rdp_cmd[5]; w6 = rdp_cmd[6]; w7 = rdp_cmd[7]; /* triangle edge y-coordinates */ yl = (w0 & 0x3fff); ym = ((w1 >> 16) & 0x3fff); yh = ((w1 >> 0) & 0x3fff); /* triangle edge x-coordinates */ xl = (int32_t)(w2); xh = (int32_t)(w4); xm = (int32_t)(w6); /* triangle edge inverse-slopes */ dxldy = (int32_t)(w3); dxhdy = (int32_t)(w5); dxmdy = (int32_t)(w7); rdp.cur_tile = (w0 >> 16) & 0x7; if (yl & (0x800<<2)) yl |= 0xfffff000<<2; if (ym & (0x800<<2)) ym |= 0xfffff000<<2; if (yh & (0x800<<2)) yh |= 0xfffff000<<2; yh &= ~3; if (shade) { r = (shade_base[0] & 0xffff0000) | ((shade_base[+4 ] >> 16) & 0x0000ffff); g = ((shade_base[0 ] << 16) & 0xffff0000) | (shade_base[4 ] & 0x0000ffff); b = (shade_base[1 ] & 0xffff0000) | ((shade_base[5 ] >> 16) & 0x0000ffff); a = ((shade_base[1 ] << 16) & 0xffff0000) | (shade_base[5 ] & 0x0000ffff); drdx = (shade_base[2 ] & 0xffff0000) | ((shade_base[6 ] >> 16) & 0x0000ffff); dgdx = ((shade_base[2 ] << 16) & 0xffff0000) | (shade_base[6 ] & 0x0000ffff); dbdx = (shade_base[3 ] & 0xffff0000) | ((shade_base[7 ] >> 16) & 0x0000ffff); dadx = ((shade_base[3 ] << 16) & 0xffff0000) | (shade_base[7 ] & 0x0000ffff); drde = (shade_base[8 ] & 0xffff0000) | ((shade_base[12] >> 16) & 0x0000ffff); dgde = ((shade_base[8 ] << 16) & 0xffff0000) | (shade_base[12] & 0x0000ffff); dbde = (shade_base[9 ] & 0xffff0000) | ((shade_base[13] >> 16) & 0x0000ffff); dade = ((shade_base[9 ] << 16) & 0xffff0000) | (shade_base[13] & 0x0000ffff); } if (texture) { s = (texture_base[0 ] & 0xffff0000) | ((texture_base[4 ] >> 16) & 0x0000ffff); t = ((texture_base[0 ] << 16) & 0xffff0000) | (texture_base[4 ] & 0x0000ffff); w = (texture_base[1 ] & 0xffff0000) | ((texture_base[5 ] >> 16) & 0x0000ffff); // w = abs(w); dsdx = (texture_base[2 ] & 0xffff0000) | ((texture_base[6 ] >> 16) & 0x0000ffff); dtdx = ((texture_base[2 ] << 16) & 0xffff0000) | (texture_base[6 ] & 0x0000ffff); dwdx = (texture_base[3 ] & 0xffff0000) | ((texture_base[7 ] >> 16) & 0x0000ffff); dsde = (texture_base[8 ] & 0xffff0000) | ((texture_base[12] >> 16) & 0x0000ffff); dtde = ((texture_base[8 ] << 16) & 0xffff0000) | (texture_base[12] & 0x0000ffff); dwde = (texture_base[9 ] & 0xffff0000) | ((texture_base[13] >> 16) & 0x0000ffff); } if (zbuffer) { z = zbuffer_base[0]; dzdx = zbuffer_base[1]; dzde = zbuffer_base[2]; } xh <<= 2; xm <<= 2; xl <<= 2; r <<= 2; g <<= 2; b <<= 2; a <<= 2; dsde >>= 2; dtde >>= 2; dsdx >>= 2; dtdx >>= 2; dzdx >>= 2; dzde >>= 2; dwdx >>= 2; dwde >>= 2; nbVtxs = 0; vtx = (VERTEX*)&vtxbuf[nbVtxs++]; memset(vtxbuf, 0, sizeof(vtxbuf)); xleft = xm; xright = xh; xleft_inc = dxmdy; xright_inc = dxhdy; while (yh xright-0x10000))) { xleft += xleft_inc; xright += xright_inc; s += dsde; t += dtde; w += dwde; r += drde; g += dgde; b += dbde; a += dade; z += dzde; yh++; } j = ym-yh; if (j > 0) { int dx = (xleft-xright)>>16; if ((!flip && xleft < xright) || (flip/* && xleft > xright*/)) { if (shade) { vtx->r = CSCALE(r+drdx*dx); vtx->g = CSCALE(g+dgdx*dx); vtx->b = CSCALE(b+dbdx*dx); vtx->a = CSCALE(a+dadx*dx); } if (texture) { vtx->ou = SSCALE(s+dsdx*dx, w+dwdx*dx); vtx->ov = TSCALE(t+dtdx*dx, w+dwdx*dx); } vtx->x = XSCALE(xleft); vtx->y = YSCALE(yh); vtx->z = ZSCALE(z+dzdx*dx); vtx->w = WSCALE(w+dwdx*dx); vtx = &vtxbuf[nbVtxs++]; } if ((!flip/* && xleft < xright*/) || (flip && xleft > xright)) { if (shade) { vtx->r = CSCALE(r); vtx->g = CSCALE(g); vtx->b = CSCALE(b); vtx->a = CSCALE(a); } if (texture) { vtx->ou = SSCALE(s, w); vtx->ov = TSCALE(t, w); } vtx->x = XSCALE(xright); vtx->y = YSCALE(yh); vtx->z = ZSCALE(z); vtx->w = WSCALE(w); vtx = &vtxbuf[nbVtxs++]; } xleft += xleft_inc*j; xright += xright_inc*j; s += dsde*j; t += dtde*j; if (w + dwde*j) w += dwde*j; else w += dwde*(j-1); r += drde*j; g += dgde*j; b += dbde*j; a += dade*j; z += dzde*j; // render ... } if (xl != xh) xleft = xl; //if (yl-ym > 0) { int dx = (xleft-xright)>>16; if ((!flip && xleft <= xright) || (flip/* && xleft >= xright*/)) { if (shade) { vtx->r = CSCALE(r+drdx*dx); vtx->g = CSCALE(g+dgdx*dx); vtx->b = CSCALE(b+dbdx*dx); vtx->a = CSCALE(a+dadx*dx); } if (texture) { vtx->ou = SSCALE(s+dsdx*dx, w+dwdx*dx); vtx->ov = TSCALE(t+dtdx*dx, w+dwdx*dx); } vtx->x = XSCALE(xleft); vtx->y = YSCALE(ym); vtx->z = ZSCALE(z+dzdx*dx); vtx->w = WSCALE(w+dwdx*dx); vtx = &vtxbuf[nbVtxs++]; } if ((!flip/* && xleft <= xright*/) || (flip && xleft >= xright)) { if (shade) { vtx->r = CSCALE(r); vtx->g = CSCALE(g); vtx->b = CSCALE(b); vtx->a = CSCALE(a); } if (texture) { vtx->ou = SSCALE(s, w); vtx->ov = TSCALE(t, w); } vtx->x = XSCALE(xright); vtx->y = YSCALE(ym); vtx->z = ZSCALE(z); vtx->w = WSCALE(w); vtx = &vtxbuf[nbVtxs++]; } } xleft_inc = dxldy; xright_inc = dxhdy; j = yl-ym; //j--; // ? xleft += xleft_inc*j; xright += xright_inc*j; s += dsde*j; t += dtde*j; w += dwde*j; r += drde*j; g += dgde*j; b += dbde*j; a += dade*j; z += dzde*j; while (yl>ym && !((!flip && xleft < xright+0x10000) || (flip && xleft > xright-0x10000))) { xleft -= xleft_inc; xright -= xright_inc; s -= dsde; t -= dtde; w -= dwde; r -= drde; g -= dgde; b -= dbde; a -= dade; z -= dzde; j--; yl--; } // render ... if (j >= 0) { int dx = (xleft-xright)>>16; if ((!flip && xleft <= xright) || (flip/* && xleft >= xright*/)) { if (shade) { vtx->r = CSCALE(r+drdx*dx); vtx->g = CSCALE(g+dgdx*dx); vtx->b = CSCALE(b+dbdx*dx); vtx->a = CSCALE(a+dadx*dx); } if (texture) { vtx->ou = SSCALE(s+dsdx*dx, w+dwdx*dx); vtx->ov = TSCALE(t+dtdx*dx, w+dwdx*dx); } vtx->x = XSCALE(xleft); vtx->y = YSCALE(yl); vtx->z = ZSCALE(z+dzdx*dx); vtx->w = WSCALE(w+dwdx*dx); vtx = &vtxbuf[nbVtxs++]; } if ((!flip/* && xleft <= xright*/) || (flip && xleft >= xright)) { if (shade) { vtx->r = CSCALE(r); vtx->g = CSCALE(g); vtx->b = CSCALE(b); vtx->a = CSCALE(a); } if (texture) { vtx->ou = SSCALE(s, w); vtx->ov = TSCALE(t, w); } vtx->x = XSCALE(xright); vtx->y = YSCALE(yl); vtx->z = ZSCALE(z); vtx->w = WSCALE(w); vtx = &vtxbuf[nbVtxs++]; } } //if (fullscreen) { int k; update (); for (k = 0; k < nbVtxs-1; k++) { VERTEX * v = (VERTEX*)&vtxbuf[k]; v->x = v->x * rdp.scale_x + rdp.offset_x; v->y = v->y * rdp.scale_y + rdp.offset_y; // v->z = 1.0f;///v->w; v->q = 1.0f/v->w; v->u[1] = v->u[0] = v->ou; v->v[1] = v->v[0] = v->ov; if (rdp.tex >= 1 && rdp.cur_cache[0]) { draw_tri_uv_calculation_update_shift(rdp.cur_tile, 0, v); v->u[0] /= v->w; v->v[0] /= v->w; } if (rdp.tex >= 2 && rdp.cur_cache[1]) { draw_tri_uv_calculation_update_shift(rdp.cur_tile, 1, v); v->u[1] /= v->w; v->v[1] /= v->w; } apply_shade_mods (v); } grCullMode(GR_CULL_DISABLE); ConvertCoordsConvert (vtxbuf, nbVtxs); grDrawVertexArrayContiguous (GR_TRIANGLE_STRIP, nbVtxs-1, vtxbuf); } } #define rdp_triangle(w0, w1, shade, texture, zbuffer, wptr) lle_triangle(w0, w1, shade, texture, zbuffer, (wptr)) static void rdp_trifill(uint32_t w0, uint32_t w1) { rdp_triangle(w0, w1, 0, 0, 0, rdp_cmd_data + rdp_cmd_cur); } static void rdp_trishade(uint32_t w0, uint32_t w1) { rdp_triangle(w0, w1, 1, 0, 0, rdp_cmd_data + rdp_cmd_cur); } static void rdp_tritxtr(uint32_t w0, uint32_t w1) { rdp_triangle(w0, w1, 0, 1, 0, rdp_cmd_data + rdp_cmd_cur); } static void rdp_trishadetxtr(uint32_t w0, uint32_t w1) { rdp_triangle(w0, w1, 1, 1, 0, rdp_cmd_data + rdp_cmd_cur); } static void rdp_trifillz(uint32_t w0, uint32_t w1) { rdp_triangle(w0, w1, 0, 0, 1, rdp_cmd_data + rdp_cmd_cur); } static void rdp_trishadez(uint32_t w0, uint32_t w1) { rdp_triangle(w0, w1, 1, 0, 1, rdp_cmd_data + rdp_cmd_cur); } static void rdp_tritxtrz(uint32_t w0, uint32_t w1) { rdp_triangle(w0, w1, 0, 1, 1, rdp_cmd_data + rdp_cmd_cur); } static void rdp_trishadetxtrz(uint32_t w0, uint32_t w1) { rdp_triangle(w0, w1, 1, 1, 1, rdp_cmd_data + rdp_cmd_cur); } static rdp_instr rdp_command_table[64] = { /* 0x00 */ gdp_no_op, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, /* 0x10 */ gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, /* 0x20 */ gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, rdp_texrect, rdp_texrect, gdp_load_sync, gdp_pipe_sync, gdp_tile_sync, gdp_full_sync, gdp_set_key_gb, gdp_set_key_r, gdp_set_convert, rdp_setscissor, gdp_set_prim_depth, rdp_setothermode, /* 0x30 */ rdp_loadtlut, gdp_invalid, rdp_settilesize, rdp_loadblock, rdp_loadtile, rdp_settile, rdp_fillrect, gdp_set_fill_color, gdp_set_fog_color, gdp_set_blend_color, rdp_setprimcolor, gdp_set_env_color, rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage }; static const uint32_t rdp_command_length[64] = { 8, // 0x00, No Op 8, // 0x01, ??? 8, // 0x02, ??? 8, // 0x03, ??? 8, // 0x04, ??? 8, // 0x05, ??? 8, // 0x06, ??? 8, // 0x07, ??? 32, // 0x08, Non-Shaded Triangle 32+16, // 0x09, Non-Shaded, Z-Buffered Triangle 32+64, // 0x0a, Textured Triangle 32+64+16, // 0x0b, Textured, Z-Buffered Triangle 32+64, // 0x0c, Shaded Triangle 32+64+16, // 0x0d, Shaded, Z-Buffered Triangle 32+64+64, // 0x0e, Shaded+Textured Triangle 32+64+64+16, // 0x0f, Shaded+Textured, Z-Buffered Triangle 8, // 0x10, ??? 8, // 0x11, ??? 8, // 0x12, ??? 8, // 0x13, ??? 8, // 0x14, ??? 8, // 0x15, ??? 8, // 0x16, ??? 8, // 0x17, ??? 8, // 0x18, ??? 8, // 0x19, ??? 8, // 0x1a, ??? 8, // 0x1b, ??? 8, // 0x1c, ??? 8, // 0x1d, ??? 8, // 0x1e, ??? 8, // 0x1f, ??? 8, // 0x20, ??? 8, // 0x21, ??? 8, // 0x22, ??? 8, // 0x23, ??? 16, // 0x24, Texture_Rectangle 16, // 0x25, Texture_Rectangle_Flip 8, // 0x26, Sync_Load 8, // 0x27, Sync_Pipe 8, // 0x28, Sync_Tile 8, // 0x29, Sync_Full 8, // 0x2a, Set_Key_GB 8, // 0x2b, Set_Key_R 8, // 0x2c, Set_Convert 8, // 0x2d, Set_Scissor 8, // 0x2e, Set_Prim_Depth 8, // 0x2f, Set_Other_Modes 8, // 0x30, Load_TLUT 8, // 0x31, ??? 8, // 0x32, Set_Tile_Size 8, // 0x33, Load_Block 8, // 0x34, Load_Tile 8, // 0x35, Set_Tile 8, // 0x36, Fill_Rectangle 8, // 0x37, Set_Fill_Color 8, // 0x38, Set_Fog_Color 8, // 0x39, Set_Blend_Color 8, // 0x3a, Set_Prim_Color 8, // 0x3b, Set_Env_Color 8, // 0x3c, Set_Combine 8, // 0x3d, Set_Texture_Image 8, // 0x3e, Set_Mask_Image 8 // 0x3f, Set_Color_Image }; static void rdphalf_1(uint32_t w0, uint32_t w1) { uint32_t cmd = rdp.cmd1 >> 24; if (cmd >= G_TRI_FILL && cmd <= G_TRI_SHADE_TXTR_ZBUFF) //triangle command { rdp_cmd_ptr = 0; rdp_cmd_cur = 0; do { uint32_t a; rdp_cmd_data[rdp_cmd_ptr++] = rdp.cmd1; // check DL counter if (rdp.dl_count != -1) { rdp.dl_count --; if (rdp.dl_count == 0) { rdp.dl_count = -1; LRDP("End of DL\n"); rdp.pc_i --; } } // Get the address of the next command a = rdp.pc[rdp.pc_i] & BMASK; // Load the next command and its input rdp.cmd0 = ((uint32_t*)gfx_info.RDRAM)[a>>2]; // \ Current command, 64 bit rdp.cmd1 = ((uint32_t*)gfx_info.RDRAM)[(a>>2)+1]; // / // Go to the next instruction rdp.pc[rdp.pc_i] = (a+8) & BMASK; }while ((rdp.cmd0 >> 24) != 0xb3); rdp_cmd_data[rdp_cmd_ptr++] = rdp.cmd1; cmd = (rdp_cmd_data[rdp_cmd_cur] >> 24) & 0x3f; rdp.cmd0 = rdp_cmd_data[rdp_cmd_cur+0]; rdp.cmd1 = rdp_cmd_data[rdp_cmd_cur+1]; rdp_command_table[cmd](rdp.cmd0, rdp.cmd1); } } static void rdphalf_2(uint32_t w0, uint32_t w1) { } static void rdphalf_cont(uint32_t w0, uint32_t w1) { } static INLINE uint32_t READ_RDP_DATA(uint32_t address) { if ((*(uint32_t*)gfx_info.DPC_STATUS_REG) & 0x1) /* XBUS_DMEM_DMA enabled */ return ((uint32_t*)gfx_info.DMEM)[(address & 0xfff) >> 2]; return ((uint32_t*)gfx_info.RDRAM)[address >> 2]; } /****************************************************************** Function: ProcessRDPList Purpose: This function is called when there is a Dlist to be processed. (Low level GFX list) input: none output: none *******************************************************************/ EXPORT void CALL ProcessRDPList(void) { int32_t i; uint32_t cmd, cmd_length; int32_t length = (*(uint32_t*)gfx_info.DPC_END_REG) - (*(uint32_t*)gfx_info.DPC_CURRENT_REG); rdp_cmd_ptr = 0; rdp_cmd_cur = 0; if ((*(uint32_t*)gfx_info.DPC_END_REG) <= (*(uint32_t*)gfx_info.DPC_CURRENT_REG)) return; if (length < 0) { (*(uint32_t*)gfx_info.DPC_CURRENT_REG) = (*(uint32_t*)gfx_info.DPC_END_REG); return; } // load command data for (i=0; i < length; i += 4) rdp_cmd_data[rdp_cmd_ptr++] = READ_RDP_DATA(((*(uint32_t*)gfx_info.DPC_CURRENT_REG) & 0x1fffffff) + i); (*(uint32_t*)gfx_info.DPC_CURRENT_REG) = (*(uint32_t*)gfx_info.DPC_END_REG); cmd = (rdp_cmd_data[0] >> 24) & 0x3f; cmd_length = (rdp_cmd_ptr + 1) * 4; // check if more data is needed if (cmd_length < rdp_command_length[cmd]) return; rdp.LLE = true; while (rdp_cmd_cur < rdp_cmd_ptr) { uint32_t w0, w1; cmd = (rdp_cmd_data[rdp_cmd_cur] >> 24) & 0x3f; if (((rdp_cmd_ptr-rdp_cmd_cur) * 4) < rdp_command_length[cmd]) return; // execute the command rdp.cmd0 = rdp_cmd_data[rdp_cmd_cur+0]; rdp.cmd1 = rdp_cmd_data[rdp_cmd_cur+1]; rdp.cmd2 = rdp_cmd_data[rdp_cmd_cur+2]; rdp.cmd3 = rdp_cmd_data[rdp_cmd_cur+3]; w0 = rdp.cmd0; w1 = rdp.cmd1; rdp_command_table[cmd](w0, w1); rdp_cmd_cur += rdp_command_length[cmd] / 4; } rdp.LLE = false; (*(uint32_t*)gfx_info.DPC_START_REG) = (*(uint32_t*)gfx_info.DPC_END_REG); (*(uint32_t*)gfx_info.DPC_STATUS_REG) &= ~0x0002; rdp_cmd_cur = 0; rdp_cmd_ptr = 0; } mupen64plus-video-gliden64/licenses/gles2n64/LICENSE000664 001750 001750 00000016725 12655644434 023030 0ustar00sergiosergio000000 000000 GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. mupen64plus-video-gliden64/src/CRC.cpp000664 001750 001750 00000003035 12655644434 020542 0ustar00sergiosergio000000 000000 #include "Types.h" #define CRC32_POLYNOMIAL 0x04C11DB7 unsigned int CRCTable[ 256 ]; u32 Reflect( u32 ref, char ch ) { u32 value = 0; // Swap bit 0 for bit 7 // bit 1 for bit 6, etc. for (int i = 1; i < (ch + 1); ++i) { if(ref & 1) value |= 1 << (ch - i); ref >>= 1; } return value; } void CRC_BuildTable() { u32 crc; for (int i = 0; i < 256; ++i) { crc = Reflect( i, 8 ) << 24; for (int j = 0; j < 8; ++j) crc = (crc << 1) ^ (crc & (1 << 31) ? CRC32_POLYNOMIAL : 0); CRCTable[i] = Reflect( crc, 32 ); } } u32 CRC_Calculate( u32 crc, const void * buffer, u32 count ) { u8 *p; u32 orig = crc; p = (u8*) buffer; while (count--) crc = (crc >> 8) ^ CRCTable[(crc & 0xFF) ^ *p++]; return crc ^ orig; } u32 CRC_CalculatePalette(u32 crc, const void * buffer, u32 count ) { u8 *p; u32 orig = crc; p = (u8*) buffer; while (count--) { crc = (crc >> 8) ^ CRCTable[(crc & 0xFF) ^ *p++]; crc = (crc >> 8) ^ CRCTable[(crc & 0xFF) ^ *p++]; p += 6; } return crc ^ orig; } u32 textureCRC(u8 * addr, u32 height, u32 stride) { const u32 width = stride / 8; const u32 line = stride % 8; u64 crc = 0; u64 twopixel_crc; u32 * pixelpos = (u32*)addr; for (; height; height--) { int col = 0; for (u32 i = width; i; --i) { twopixel_crc = i * ((u64)(pixelpos[1] & 0xFFFEFFFE) + (u64)(pixelpos[0] & 0xFFFEFFFE) + crc); crc = (twopixel_crc >> 32) + twopixel_crc; pixelpos += 2; } crc = (height * crc >> 32) + height * crc; pixelpos = (u32*)((u8*)pixelpos + line); } return crc&0xFFFFFFFF; } mupen64plus-core/src/pi/cart_rom.h000664 001750 001750 00000004062 12655644434 020227 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - cart_rom.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_PI_CART_ROM_H #define M64P_PI_CART_ROM_H #include #include #ifndef ROM_ADDR #define ROM_ADDR(a) ((a & 0x03fffffc)) #endif struct cart_rom { uint8_t* rom; size_t rom_size; uint32_t last_write; }; void connect_cart_rom(struct cart_rom* cart_rom, uint8_t* rom, size_t rom_size); void init_cart_rom(struct cart_rom* cart_rom); int read_cart_rom(void* opaque, uint32_t address, uint32_t* value); int write_cart_rom(void* opaque, uint32_t address, uint32_t value, uint32_t mask); #endif mupen64plus-core/src/main/cheat.h000664 001750 001750 00000003600 12655644434 020016 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - cheat.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2008 Okaygo * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef CHEAT_H #define CHEAT_H #include "api/m64p_types.h" #define ENTRY_BOOT 0 #define ENTRY_VI 1 void cheat_apply_cheats(int entry); void cheat_init(void); void cheat_uninit(void); int cheat_add_new(const char *name, m64p_cheat_code *code_list, int num_codes); int cheat_set_enabled(const char *name, int enabled); void cheat_delete_all(void); #endif // #define CHEAT_H mupen64plus-core/src/si/000700 001750 001750 00000000000 12656647145 016240 5ustar00sergiosergio000000 000000 glide2gl/src/Glide64/GlideExtensions.h000664 001750 001750 00000004565 12655644434 020664 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define GR_BUFFER_TEXTUREBUFFER_EXT 0x6 #define GR_BUFFER_TEXTUREAUXBUFFER_EXT 0x7 #ifndef GR_PIXFMT_RGB_565 #define GR_PIXFMT_RGB_565 0x03 #endif #define GR_PIXFMT_ARGB_1555 0x0004 #define GR_PIXFMT_ARGB_8888 0x0005 #define GR_CMBX_ZERO 0x00 #define GR_CMBX_TEXTURE_ALPHA 0x01 #define GR_CMBX_ALOCAL 0x02 #define GR_CMBX_AOTHER 0x03 #define GR_CMBX_B 0x04 #define GR_CMBX_CONSTANT_ALPHA 0x05 #define GR_CMBX_CONSTANT_COLOR 0x06 #define GR_CMBX_DETAIL_FACTOR 0x07 #define GR_CMBX_ITALPHA 0x08 #define GR_CMBX_ITRGB 0x09 #define GR_CMBX_LOCAL_TEXTURE_ALPHA 0x0a #define GR_CMBX_LOCAL_TEXTURE_RGB 0x0b #define GR_CMBX_LOD_FRAC 0x0c #define GR_CMBX_OTHER_TEXTURE_ALPHA 0x0d #define GR_CMBX_OTHER_TEXTURE_RGB 0x0e #define GR_CMBX_TEXTURE_RGB 0x0f #define GR_CMBX_TMU_CALPHA 0x10 #define GR_CMBX_TMU_CCOLOR 0x11 #define GR_FUNC_MODE_ZERO 0x00 #define GR_FUNC_MODE_X 0x01 #define GR_FUNC_MODE_ONE_MINUS_X 0x02 #define GR_FUNC_MODE_NEGATIVE_X 0x03 #define GR_FUNC_MODE_X_MINUS_HALF 0x04 #define GR_TEXFMT_ARGB_8888 0x12 #define GR_LOD_LOG2_2048 0xb #define GR_LOD_LOG2_1024 0xa #define GR_LOD_LOG2_512 0x9 #define GR_TEXTURE_UMA_EXT 0x06 mupen64plus-core/src/main/000700 001750 001750 00000000000 12656647145 016551 5ustar00sergiosergio000000 000000 mupen64plus-core/src/pi/cart_rom.c000664 001750 001750 00000004673 12655644434 020232 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - cart_rom.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "cart_rom.h" #include "pi_controller.h" void connect_cart_rom(struct cart_rom* cart_rom, uint8_t* rom, size_t rom_size) { cart_rom->rom = rom; cart_rom->rom_size = rom_size; } void init_cart_rom(struct cart_rom* cart_rom) { cart_rom->last_write = 0; } int read_cart_rom(void* opaque, uint32_t address, uint32_t* value) { struct pi_controller* pi = (struct pi_controller*)opaque; uint32_t addr = ROM_ADDR(address); if (pi->cart_rom.last_write != 0) { *value = pi->cart_rom.last_write; pi->cart_rom.last_write = 0; } else { *value = *(uint32_t*)(pi->cart_rom.rom + addr); } return 0; } int write_cart_rom(void* opaque, uint32_t address, uint32_t value, uint32_t mask) { struct pi_controller* pi = (struct pi_controller*)opaque; pi->cart_rom.last_write = value & mask; return 0; } mupen64plus-core/src/main/cheat.c000664 001750 001750 00000037112 12655644434 020016 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - cheat.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2009 Richard Goedeken * * Copyright (C) 2008 Okaygo * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // gameshark and xploder64 reference: http://doc.kodewerx.net/hacking_n64.html #include "api/m64p_types.h" #include "api/callbacks.h" #include "api/config.h" #include "memory/memory.h" #include "cheat.h" #include "main.h" #include "rom.h" #include "list.h" #include "eventloop.h" #include #include #include /* Local definitions */ #define CHEAT_CODE_MAGIC_VALUE 0xDEAD0000 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) typedef struct cheat_code { unsigned int address; int value; int old_value; struct list_head list; } cheat_code_t; typedef struct cheat { char *name; int enabled; int was_enabled; struct list_head cheat_codes; struct list_head list; } cheat_t; /* Local variables */ static LIST_HEAD(active_cheats); extern unsigned int frame_dupe; /* Private functions */ static uint16_t read_address_16bit(unsigned int address) { return *(uint16_t*)(((uint8_t*)g_rdram + ((address & 0xFFFFFF)^S16))); } static uint8_t read_address_8bit(unsigned int address) { return *(unsigned char *)(((unsigned char*)g_rdram + ((address & 0xFFFFFF)^S8))); } static void update_address_16bit(unsigned int address, unsigned short new_value) { *(uint16_t *)(((uint8_t*)g_rdram + ((address & 0xFFFFFF)^S16))) = new_value; } static void update_address_8bit(unsigned int address, unsigned char new_value) { *(uint8_t *)(((uint8_t*)g_rdram + ((address & 0xFFFFFF)^S8))) = new_value; } static int address_equal_to_8bit(unsigned int address, unsigned char value) { unsigned char value_read; value_read = *(unsigned char *)(((unsigned char*)g_rdram + ((address & 0xFFFFFF)^S8))); return value_read == value; } static int address_equal_to_16bit(unsigned int address, unsigned short value) { unsigned short value_read; value_read = *(unsigned short *)(((unsigned char*)g_rdram + ((address & 0xFFFFFF)^S16))); return value_read == value; } // individual application - returns 0 if we are supposed to skip the next cheat // (only really used on conditional codes) static int execute_cheat(unsigned int address, unsigned short value, int *old_value) { switch (address & 0xFF000000) { case 0x80000000: case 0x88000000: case 0xA0000000: case 0xA8000000: case 0xF0000000: // if pointer to old value is valid and uninitialized, write current value to it if(old_value && (*old_value == CHEAT_CODE_MAGIC_VALUE)) *old_value = (int) read_address_8bit(address); update_address_8bit(address,(unsigned char) value); return 1; case 0x81000000: case 0x89000000: case 0xA1000000: case 0xA9000000: case 0xF1000000: // if pointer to old value is valid and uninitialized, write current value to it if(old_value && (*old_value == CHEAT_CODE_MAGIC_VALUE)) *old_value = (int) read_address_16bit(address); update_address_16bit(address,value); return 1; case 0xD0000000: case 0xD8000000: return address_equal_to_8bit(address,(unsigned char) value); case 0xD1000000: case 0xD9000000: return address_equal_to_16bit(address,value); case 0xD2000000: case 0xDB000000: return !(address_equal_to_8bit(address,(unsigned char) value)); case 0xD3000000: case 0xDA000000: return !(address_equal_to_16bit(address,value)); case 0xEE000000: // most likely, this doesnt do anything. execute_cheat(0xF1000318, 0x0040, NULL); execute_cheat(0xF100031A, 0x0000, NULL); return 1; } return 1; } static cheat_t *find_or_create_cheat(const char *name) { cheat_t *cheat; int found = 0; list_for_each_entry_t(cheat, &active_cheats, cheat_t, list) { if (strcmp(cheat->name, name) == 0) { found = 1; break; } } if (found) { /* delete any pre-existing cheat codes */ cheat_code_t *code, *safe; list_for_each_entry_safe_t(code, safe, &cheat->cheat_codes, cheat_code_t, list) { list_del(&code->list); free(code); } cheat->enabled = 0; cheat->was_enabled = 0; } else { cheat = malloc(sizeof(*cheat)); cheat->name = strdup(name); cheat->enabled = 0; cheat->was_enabled = 0; INIT_LIST_HEAD(&cheat->cheat_codes); list_add_tail(&cheat->list, &active_cheats); } return cheat; } // public functions void cheat_init(void) { } void cheat_uninit(void) { } void cheat_apply_cheats(int entry) { cheat_t *cheat; cheat_code_t *code; int skip; int execute_next; #if 0 if (( strncmp((char *)ROM_HEADER.Name, (const char *)"BANJO KAZOOIE 2", 15) == 0 || strncmp((char *)ROM_HEADER.Name, (const char *)"BANJO TOOIE", 11) == 0 ) && entry == ENTRY_VI) { execute_cheat(0x8107913C, 0x0000, NULL); execute_cheat(0x8107913E, 0x0000, NULL); } #endif // If game is Pokemon Snap, apply controller fix if (strncmp((char *)ROM_HEADER.Name, "POKEMON SNAP", 12) == 0 && entry == ENTRY_VI) { if (sl(ROM_HEADER.CRC1) == 0xCA12B547 && sl(ROM_HEADER.CRC2) == 0x71FA4EE4) { // Pokemon Snap (U) execute_cheat(0xD1382D1C, 0x0002, NULL); execute_cheat(0x80382D0F, 0x0000, NULL); } else if (sl(ROM_HEADER.CRC1) == 0x7BB18D40 && sl(ROM_HEADER.CRC2) == 0x83138559) { // Pokemon Snap (A) execute_cheat(0xD1382D1C, 0x0002, NULL); execute_cheat(0x80382D0F, 0x0000, NULL); } else if (sl(ROM_HEADER.CRC1) == 0x39119872 && sl(ROM_HEADER.CRC2) == 0x07722E9F) { // Pokemon Snap Station (U) execute_cheat(0xD1382D1C, 0x0002, NULL); execute_cheat(0x80382D0F, 0x0000, NULL); } else if (sl(ROM_HEADER.CRC1) == 0xEC0F690D && sl(ROM_HEADER.CRC2) == 0x32A7438C) { // Pokemon Snap (J) (V1.0) execute_cheat(0xD136D22C, 0x802A, NULL); execute_cheat(0x8036D21F, 0x0000, NULL); } else if (sl(ROM_HEADER.CRC1) == 0xE0044E9E && sl(ROM_HEADER.CRC2) == 0xCD659D0D) { // Pokemon Snap (J) (V1.1) execute_cheat(0xD136D22C, 0x802A, NULL); execute_cheat(0x8036D21F, 0x0000, NULL); } else if (sl(ROM_HEADER.CRC1) == 0x5753720D && sl(ROM_HEADER.CRC2) == 0x2A8A884D) { // Pokemon Snap (G) execute_cheat(0xD1381BDC, 0x802C, NULL); execute_cheat(0x80381BCF, 0x0000, NULL); } else { // Pokemon Snap (E) + (F) + (I) + (S) execute_cheat(0xD1381BFC, 0x802C, NULL); execute_cheat(0x80381BEF, 0x0000, NULL); } } if (list_empty(&active_cheats)) return; list_for_each_entry_t(cheat, &active_cheats, cheat_t, list) { if (cheat->enabled) { cheat->was_enabled = 1; switch(entry) { case ENTRY_BOOT: list_for_each_entry_t(code, &cheat->cheat_codes, cheat_code_t, list) { // code should only be written once at boot time if((code->address & 0xF0000000) == 0xF0000000) execute_cheat(code->address, code->value, &code->old_value); } break; case ENTRY_VI: skip = 0; execute_next = 0; list_for_each_entry_t(code, &cheat->cheat_codes, cheat_code_t, list) { if (skip) { skip = 0; continue; } if (execute_next) { execute_next = 0; // if code needs GS button pressed, don't save old value if(((code->address & 0xFF000000) == 0xD8000000 || (code->address & 0xFF000000) == 0xD9000000 || (code->address & 0xFF000000) == 0xDA000000 || (code->address & 0xFF000000) == 0xDB000000)) execute_cheat(code->address, code->value, NULL); else execute_cheat(code->address, code->value, &code->old_value); continue; } // conditional cheat codes if((code->address & 0xF0000000) == 0xD0000000) { // if code needs GS button pressed and it's not, skip it if(((code->address & 0xFF000000) == 0xD8000000 || (code->address & 0xFF000000) == 0xD9000000 || (code->address & 0xFF000000) == 0xDA000000 || (code->address & 0xFF000000) == 0xDB000000) && !event_gameshark_active()) { // skip next code skip = 1; continue; } if (execute_cheat(code->address, code->value, NULL)) { // if condition true, execute next cheat code execute_next = 1; } else { // if condition false, skip next code skip = 1; continue; } } // GS button triggers cheat code else if((code->address & 0xFF000000) == 0x88000000 || (code->address & 0xFF000000) == 0x89000000 || (code->address & 0xFF000000) == 0xA8000000 || (code->address & 0xFF000000) == 0xA9000000) { if(event_gameshark_active()) execute_cheat(code->address, code->value, NULL); } // normal cheat code else { // exclude boot-time cheat codes if((code->address & 0xF0000000) != 0xF0000000) execute_cheat(code->address, code->value, &code->old_value); } } break; default: break; } } // if cheat was enabled, but is now disabled, restore old memory values else if (cheat->was_enabled) { cheat->was_enabled = 0; switch(entry) { case ENTRY_VI: list_for_each_entry_t(code, &cheat->cheat_codes, cheat_code_t, list) { // set memory back to old value and clear saved copy of old value if(code->old_value != CHEAT_CODE_MAGIC_VALUE) { execute_cheat(code->address, code->old_value, NULL); code->old_value = CHEAT_CODE_MAGIC_VALUE; } } break; default: break; } } } } void cheat_delete_all(void) { cheat_t *cheat, *safe_cheat; cheat_code_t *code, *safe_code; if (list_empty(&active_cheats)) return; list_for_each_entry_safe_t(cheat, safe_cheat, &active_cheats, cheat_t, list) { free(cheat->name); list_for_each_entry_safe_t(code, safe_code, &cheat->cheat_codes, cheat_code_t, list) { list_del(&code->list); free(code); } list_del(&cheat->list); free(cheat); } } int cheat_set_enabled(const char *name, int enabled) { cheat_t *cheat = NULL; if (list_empty(&active_cheats)) return 0; list_for_each_entry_t(cheat, &active_cheats, cheat_t, list) { if (strcmp(name, cheat->name) == 0) { cheat->enabled = enabled; return 1; } } return 0; } int cheat_add_new(const char *name, m64p_cheat_code *code_list, int num_codes) { cheat_t *cheat; int i, j; /* create a new cheat function or erase the codes in an existing cheat function */ cheat = find_or_create_cheat(name); if (cheat == NULL) return 0; cheat->enabled = 1; /* default for new cheats is enabled */ for (i = 0; i < num_codes; i++) { /* if this is a 'patch' code, convert it and dump out all of the individual codes */ if ((code_list[i].address & 0xFFFF0000) == 0x50000000 && i < num_codes - 1) { int code_count = ((code_list[i].address & 0xFF00) >> 8); int incr_addr = code_list[i].address & 0xFF; int incr_value = code_list[i].value; int cur_addr = code_list[i+1].address; int cur_value = code_list[i+1].value; i += 1; for (j = 0; j < code_count; j++) { cheat_code_t *code = malloc(sizeof(*code)); code->address = cur_addr; code->value = cur_value; code->old_value = CHEAT_CODE_MAGIC_VALUE; list_add_tail(&code->list, &cheat->cheat_codes); cur_addr += incr_addr; cur_value += incr_value; } } else { /* just a normal code */ cheat_code_t *code = malloc(sizeof(*code)); code->address = code_list[i].address; code->value = code_list[i].value; code->old_value = CHEAT_CODE_MAGIC_VALUE; list_add_tail(&code->list, &cheat->cheat_codes); } } return 1; } mupen64plus-core/src/plugin/rumble_via_input_plugin.h000664 001750 001750 00000003273 12655644434 024234 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - rumble_via_input_plugin.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_PLUGIN_RUMBLE_VIA_INPUT_PLUGIN_H #define M64P_PLUGIN_RUMBLE_VIA_INPUT_PLUGIN_H enum rumble_action; void rvip_rumble(void* opaque, enum rumble_action action); #endif libretro-common/include/glsym/glsym.h000664 001750 001750 00000003070 12655644434 021111 0ustar00sergiosergio000000 000000 /* Copyright (C) 2010-2015 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this libretro SDK code part (glsym). * --------------------------------------------------------------------------------------- * * Permission is hereby granted, free of charge, * to any person obtaining a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __LIBRETRO_SDK_GLSYM_H__ #define __LIBRETRO_SDK_GLSYM_H__ #include "rglgen.h" #ifndef HAVE_PSGL #ifdef HAVE_OPENGLES2 #include "glsym_es2.h" #else #include "glsym_gl.h" #endif #endif #endif mupen64plus-core/tools/savestate_convert.txt000664 001750 001750 00000002745 12655644434 022517 0ustar00sergiosergio000000 000000 ============================================================================== savestate_convert.txt - Mupen64Plus - July 12th, 2008 This conversion tool was written to help users migrate their savestate files when there are changes to the savestate file format which break backward compatibility. To compile the conversion tool, open a console window, go to the root of your Mupen64Plus source code, and type: gcc -o savestate_convert -lz tools/savestate_convert.c This will create a small command-line application called 'savestate_convert'. This program takes only one command-line parameter, which is a path to the savestate file that you want to update. The old savestate file will be overwritten with the new one, so you may wish to first make a backup copy of the savestate file. If you update a savestate file to a newer version, older versions of Mupen64Plus will not be able to load it. If you wish to update all of the savestate files in your home directory, you may do so with the following bash command: for file in ~/.mupen64plus/save/*.st*; do ./savestate_convert "${file}"; done ============================================================================== Savestate File Format History: version 0: - Original (Unversioned) file format - used by Mupen64 v0.5 and Mupen64Plus up to v1.4 version 1.0: - bugfix: TLB was not being entirely saved and restored - added small header with magic number and version number - introduced in rev 758 of Mupen64Plus SVN repository (trunk) glide2gl/src/Glide64/Combine.h000664 001750 001750 00000012112 12655644434 017117 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** #ifndef COMBINE_H #define COMBINE_H // texture MOD types #define TMOD_TEX_INTER_COLOR_USING_FACTOR 1 #define TMOD_TEX_INTER_COL_USING_COL1 2 #define TMOD_FULL_COLOR_SUB_TEX 3 #define TMOD_COL_INTER_COL1_USING_TEX 4 #define TMOD_COL_INTER_COL1_USING_TEXA 5 #define TMOD_COL_INTER_COL1_USING_TEXA__MUL_TEX 6 #define TMOD_COL_INTER_TEX_USING_TEXA 7 #define TMOD_COL2_INTER__COL_INTER_COL1_USING_TEX__USING_TEXA 8 #define TMOD_TEX_SCALE_FAC_ADD_FAC 9 #define TMOD_TEX_SUB_COL_MUL_FAC_ADD_TEX 10 #define TMOD_TEX_SCALE_COL_ADD_COL 11 #define TMOD_TEX_ADD_COL 12 #define TMOD_TEX_SUB_COL 13 #define TMOD_TEX_SUB_COL_MUL_FAC 14 #define TMOD_COL_INTER_TEX_USING_COL1 15 #define TMOD_COL_MUL_TEXA_ADD_TEX 16 #define TMOD_COL_INTER_TEX_USING_TEX 17 #define TMOD_TEX_INTER_NOISE_USING_COL 18 #define TMOD_TEX_INTER_COL_USING_TEXA 19 #define TMOD_TEX_MUL_COL 20 #define TMOD_TEX_SCALE_FAC_ADD_COL 21 #define COMBINE_EXT_COLOR 1 #define COMBINE_EXT_ALPHA 2 #define TEX_COMBINE_EXT_COLOR 1 #define TEX_COMBINE_EXT_ALPHA 2 typedef struct { uint32_t ccolor; // constant color to set at the end, color and alpha uint32_t c_fnc, c_fac, c_loc, c_oth; // grColorCombine flags uint32_t a_fnc, a_fac, a_loc, a_oth; // grAlphaCombine flags uint32_t tex, tmu0_func, tmu0_fac, tmu0_invert, tmu1_func, tmu1_fac, tmu1_invert; uint32_t tmu0_a_func, tmu0_a_fac, tmu0_a_invert, tmu1_a_func, tmu1_a_fac, tmu1_a_invert; int dc0_lodbias, dc1_lodbias; uint8_t dc0_detailscale, dc1_detailscale; float dc0_detailmax, dc1_detailmax; float lodbias0, lodbias1; uint32_t abf1, abf2; uint32_t mod_0, modcolor_0, modcolor1_0, modcolor2_0, modfactor_0; uint32_t mod_1, modcolor_1, modcolor1_1, modcolor2_1, modfactor_1; //combine extensions uint32_t c_ext_a, c_ext_a_mode, c_ext_b, c_ext_b_mode, c_ext_c, c_ext_d; int c_ext_c_invert, c_ext_d_invert; uint32_t a_ext_a, a_ext_a_mode, a_ext_b, a_ext_b_mode, a_ext_c, a_ext_d; int a_ext_c_invert, a_ext_d_invert; uint32_t t0c_ext_a, t0c_ext_a_mode, t0c_ext_b, t0c_ext_b_mode, t0c_ext_c, t0c_ext_d; int t0c_ext_c_invert, t0c_ext_d_invert; uint32_t t0a_ext_a, t0a_ext_a_mode, t0a_ext_b, t0a_ext_b_mode, t0a_ext_c, t0a_ext_d; int t0a_ext_c_invert, t0a_ext_d_invert; uint32_t t1c_ext_a, t1c_ext_a_mode, t1c_ext_b, t1c_ext_b_mode, t1c_ext_c, t1c_ext_d; int t1c_ext_c_invert, t1c_ext_d_invert; uint32_t t1a_ext_a, t1a_ext_a_mode, t1a_ext_b, t1a_ext_b_mode, t1a_ext_c, t1a_ext_d; int t1a_ext_c_invert, t1a_ext_d_invert; uint32_t tex_ccolor; uint8_t cmb_ext_use; uint8_t tex_cmb_ext_use; uint32_t shade_mod_hash; } COMBINE; extern COMBINE cmb; void Combine(void); void CombineBlender(void); void CountCombine(void); void InitCombine(void); void ColorCombinerToExtension(void); void AlphaCombinerToExtension(void); void TexColorCombinerToExtension(int32_t tmu); void TexAlphaCombinerToExtension(int32_t tmu); #endif //COMBINE _H mupen64plus-core/src/plugin/rumble_via_input_plugin.c000664 001750 001750 00000004350 12655644434 024224 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - rumble_via_input_plugin.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "rumble_via_input_plugin.h" #include "plugin.h" #include "si/rumblepak.h" #include void rvip_rumble(void* opaque, enum rumble_action action) { int channel = *(int*)opaque; static const uint8_t rumble_cmd_header[] = { 0x23, 0x01, /* T=0x23, R=0x01 */ 0x03, /* PIF_CMD_PAK_WRITE */ 0xc0, 0x1b, /* address=0xc000 | crc=0x1b */ }; uint8_t cmd[0x26]; uint8_t rumble_data = (action == RUMBLE_START) ? 0x01 : 0x00; /* build rumble command */ memcpy(cmd, rumble_cmd_header, 5); memset(cmd + 5, rumble_data, 0x20); cmd[0x25] = 0; /* dummy data CRC */ if (input.controllerCommand) input.controllerCommand(channel, cmd); } mupen64plus-rsp-hle/src/memory.h000664 001750 001750 00000011662 12655644434 017747 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-rsp-hle - memory.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef MEMORY_H #define MEMORY_H #include #include #include #include #include "hle_internal.h" #ifdef MSB_FIRST #define S 0 #define S16 0 #define S8 0 #else #define S 1 #define S16 2 #define S8 3 #endif enum { TASK_TYPE = 0xfc0, TASK_FLAGS = 0xfc4, TASK_UCODE_BOOT = 0xfc8, TASK_UCODE_BOOT_SIZE = 0xfcc, TASK_UCODE = 0xfd0, TASK_UCODE_SIZE = 0xfd4, TASK_UCODE_DATA = 0xfd8, TASK_UCODE_DATA_SIZE = 0xfdc, TASK_DRAM_STACK = 0xfe0, TASK_DRAM_STACK_SIZE = 0xfe4, TASK_OUTPUT_BUFF = 0xfe8, TASK_OUTPUT_BUFF_SIZE = 0xfec, TASK_DATA_PTR = 0xff0, TASK_DATA_SIZE = 0xff4, TASK_YIELD_DATA_PTR = 0xff8, TASK_YIELD_DATA_SIZE = 0xffc }; static INLINE unsigned int align(unsigned int x, unsigned amount) { --amount; return (x + amount) & ~amount; } #define u8(buffer, address) ((uint8_t*)((buffer) + ((address) ^ S8))) #define u16(buffer, address) ((uint16_t*)((buffer) + ((address) ^ S16))) #define u32(buffer, address) ((uint32_t*)((buffer) + (address))) void load_u8 (uint8_t* dst, const unsigned char* buffer, unsigned address, size_t count); void load_u16(uint16_t* dst, const unsigned char* buffer, unsigned address, size_t count); #define load_u32(dst, buffer, address, count) memcpy((dst), u32((buffer), (address)), (count) * sizeof(uint32_t)) void store_u16(unsigned char* buffer, unsigned address, const uint16_t* src, size_t count); void store_u32(unsigned char* buffer, unsigned address, const uint32_t* src, size_t count); #define store_u32(buffer, address, src, count) memcpy(u32((buffer), (address)), (src), (count) * sizeof(uint32_t)) /* convenient functions for DMEM access */ #define dmem_u8(hle, address) (u8((hle)->dmem, (address) & 0xFFF) #define dmem_u16(hle, address) (u16((hle)->dmem, (address) & 0xfff); #define dmem_u32(hle, address) (u32((hle)->dmem, (address) & 0xfff)) #define dmem_load_u8(hle, dst, address, count) load_u8((dst), (hle)->dmem, (address) & 0xfff, (count)) #define dmem_load_u16(hle, dst, address, count) load_u16((dst), (hle)->dmem, (address) & 0xfff, (count)) #define dmem_load_u32(hle, dst, address, count) load_u32((dst), (hle)->dmem, (address) & 0xfff, (count)) #define dmem_store_u16(hle, src, address, count) store_u16((hle)->dmem, (address) & 0xfff, (src), (count)) #define dmem_store_u32(hle, src, address, count) store_u32((hle)->dmem, (address) & 0xfff, (src), (count)) /* convenient functions DRAM access */ #define dram_u8(hle, address) (u8((hle)->dram, (address) & 0xffffff)) #define dram_u16(hle, address) (u16((hle)->dram, (address) & 0xffffff)) #define dram_u32(hle, address) (u32((hle)->dram, (address) & 0xffffff)) #define dram_load_u8(hle, dst, address, count) load_u8((dst), (hle)->dram, (address) & 0xffffff, (count)) #define dram_load_u16(hle, dst, address, count) load_u16((dst), (hle)->dram, (address) & 0xffffff, (count)) #define dram_load_u32(hle, dst, address, count) load_u32((dst), (hle)->dram, (address) & 0xffffff, (count)) #define dram_store_u8(hle, src, address, count) store_u8((hle)->dram, (address) & 0xffffff, (src), (count)) #define dram_store_u16(hle, src, address, count) store_u16((hle)->dram, (address) & 0xffffff, (src), (count)) #define dram_store_u32(hle, src, address, count) store_u32((hle)->dram, (address) & 0xffffff, (src), (count)) #endif glide2gl/src/Glide64/Glide64_UCode.h000664 001750 001750 00000014242 12655644434 020026 0ustar00sergiosergio000000 000000 #ifndef _GLIDE64_UCODE_H #define _GLIDE64_UCODE_H #define UCODE_CRUISN_EXOTICA 0x485abff2 #define UCODE_NBA_SHOWTIME 0xb62f900f #define UCODE_NAGANO_OLYMPICS 0xee47381b #define UCODE_TAMIYA_RACING_64_PROTO 0xd802ec04 #define UCODE_HEY_YOU_PIKACHU 0xde7d67d4 #define UCODE_CLAYFIGHTER_63 0x05165579 #define UCODE_TONIC_TROUBLE 0x1a62dc2f #define UCODE_RAKUGA_KIDS 0x9551177b #define UCODE_ZELDA_OOT 0x5d3099f1 #define UCODE_ZELDA_MAJORAS_MASK 0x22099872 #define UCODE_PAPER_MARIO 0x21f91834 #define UCODE_CRUISN_USA 0x3a1c2b34 #define UCODE_COMMAND_AND_CONQUER 0x168e9cd5 #define UCODE_GAUNTLET_LEGENDS 0x65201989 #define UCODE_BOTTOM_OF_THE_9TH 0x65201989 #define UCODE_BLUES_BROTHERS_2000 0x65201989 #define UCODE_ASTEROIDS_HYPER_64 0x65201989 #define UCODE_CASTLEVANIA_64 0x65201989 #define UCODE_CASTLEVANIA_64_LOD 0x65201989 #define UCODE_GEX_3_DEEP_COVER_GECKO 0x65201989 #define UCODE_BOKUJO_MONOGATARI_2 0x65201989 #define UCODE_AIR_BOARDER_64 0xe89c2b92 #define UCODE_WIPEOUT_64 0xe89c2b92 #define UCODE_1080_SNOWBOARDING 0x64ed27e5 #define UCODE_GOLDENEYE_007 0xae08d5b9 #define UCODE_PERFECT_DARK 0x47d46e86 #define UCODE_WETRIX 0xa346a5cc #define UCODE_QUAKE_64 0xa346a5cc #define UCODE_STAR_FOX_64 0xa346a5cc #define UCODE_STAR_WARS_SHADOW_OF_THE_EMPIRE 0x5b5d36e3 #define UCODE_STARCRAFT_64 0x377359b6 #define UCODE_STAR_WARS_ROGUE_SQUADRON 0x86b1593e #define UCODE_SUPER_MARIO_64 0x3a1cbac3 #define UCODE_TETRISPHERE 0x3f7247fb #define UCODE_CONKERS_BAD_FUR_DAY 0xba86cb1d #define UCODE_KILLER_INSTINCT_GOLD 0xe41ec47e #define UCODE_MISCHIEF_MAKERS 0xe41ec47e #define UCODE_MORTAL_KOMBAT_TRILOGY 0xe41ec47e #define UCODE_DIDDY_KONG_RACING 0x63be08b1 #define UCODE_FZERO_X 0x9551177b #define UCODE_JET_FORCE_GEMINI 0x0d7cbffb #define UCODE_MICKEYS_SPEEDWAY_USA 0x0d7cbffb #define UCODE_FIFA_RTWC_98 0xb54e7f93 #define UCODE_JEOPARDY 0xb54e7f93 #define UCODE_DUKE_NUKEM_64 0xb54e7f93 #define UCODE_ROBOTECH_CRYSTAL_DREAMS_PROTO 0xb54e7f93 #define UCODE_BIOHAZARD_2 0x95cd0062 #define UCODE_EXTREME_G 0xc46dbc3d #define UCODE_FIGHTING_FORCE_64_CRC1 0x327b933d #define UCODE_FIGHTING_FORCE_64_CRC2 0xb1821ed3 #define UCODE_FROGGER_2 0xee47381b #define UCODE_RAMPAGE 0xee47381b #define UCODE_ONEGAI_MONSTER 0x64ed27e5 #define UCODE_DUAL_HEROES 0xee47381b #define UCODE_HEXEN_64 0xee47381b #define UCODE_CHAMELEON_TWIST 0xee47381b #define UCODE_BANJO_KAZOOIE 0xee47381b #define UCODE_MACE_THE_DARK_AGE 0xee47381b #define UCODE_KIRBY_64_CRYSTAL_SHARDS 0xbc45382e #define UCODE_SUPER_SMASH_BROS 0xbc45382e #define UCODE_DOOM_64 0x7f2d0a2e #define UCODE_TUROK_1 0x7f2d0a2e #define UCODE_DONKEY_KONG_64 0x1a62dbaf #define UCODE_YOSHIS_STORY_CRC1 0x6bb745c9 #define UCODE_YOSHIS_STORY_CRC2 0x5df1408c #define UCODE_WAVERACE_64 0x5b5d3763 #define UCODE_MARIO_KART_64 0x8805ffea #define UCODE_BLAST_CORPS 0x5d1d6f53 #define UCODE_PILOTWINGS_64 0x5d1d6f53 #define UCODE_PUYO_PUYO_4 0x299d5072 #define UCODE_POKEMON_SNAP 0x2f71d1d5 #define UCODE_BANGAIOH 0x299d5072 #define UCODE_SCOOBY_DOO 0xc901ce73 #define UCODE_MARIO_GOLF_64 0xc901ce73 #define UCODE_SHADOWGATE_64 0xc901ce73 #define UCODE_MARIO_TENNIS 0xc901ce73 #define UCODE_MEGA_MAN_64 0xc901ce73 #define UCODE_RIDGE_RACER_64 0xc901ce73 #define UCODE_DR_MARIO_64 0xc901ce73 #define UCODE_TARZAN 0xc901ce73 #define UCODE_MINI_RACERS_CRC1 0x1517a281 #define UCODE_MINI_RACERS_CRC2 0x832fcb99 #define UCODE_DERBY_STALLION_64 0xc901cef3 #define UCODE_KAKUTOU_DENSHOU 0xc901cef3 #define UCODE_LEGO_RACERS 0xc901cef3 #define UCODE_40WINKS 0xc901cef3 #define UCODE_PAPERBOY 0xc901cef3 #define UCODE_NUCLEAR_STRIKE_64 0xc901cef3 #define UCODE_MORTAL_KOMBAT_MYTHOLOGIES 0x5414030c #define UCODE_ARMORINES_PROJECT 0xcfa35a45 #define UCODE_EIKU_NO_SAINT_ANDREWS 0x6e4d50af #define UCODE_GANBARE_GOEMON_2 0x93d11f7b #define UCODE_RACING_SIMULATION_2 0x93d11f7b #define UCODE_EXTREME_G_2 0x1a1e1920 #define UCODE_EMOS_NUMBER_JOURNEY 0x64ed27e5 #define UCODE_EARTHWORM_JIM_3D 0x64ed27e5 #define UCODE_POKEMON_PUZZLE_LEAGUE 0x64ed27e5 #define UCODE_DEZAEMON3D 0x60c1dcc4 #define UCODE_MORITA_SHOUGI_64 0xd5d68b1f #define UCODE_ANIMAL_CROSSING 0x21f91874 #define UCODE_MADDEN_64 0xee47381b #define UCODE_DUAL_HEROES 0xee47381b #define UCODE_MADDEN_NFL_99 0xee47381b #define UCODE_GASP_FIGHTERS_NEXTSTREAM 0xee47381b #define UCODE_KING_HILL_64 0x65201a09 #define UCODE_IGGY_RECKIN_BALLS 0x5ef4e34a #define UCODE_REVOLT 0x1a1e18a0 #define UCODE_KNIFE_EDGE 0x1a1e18a0 #define UCODE_OFF_ROAD_CHALLENGE 0xa346a5cc #define UCODE_ODT_PROTO 0x9551177b #define UCODE_LAST_LEGION_UX 0xff372492 extern void microcheck(void); #endif glide2gl/src/Glide64/Combine.c000664 001750 001750 00001653571 12655644434 017137 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** #include "Gfx_1.3.h" #include "Util.h" #include "Combine.h" #include "GBI.h" #define HAVE_ASSUME_COMBINE_EXT float percent_org, percent, r, g, b; static uint32_t lod_frac; static uint32_t cc_lookup[257]; static uint32_t ac_lookup[257]; COMBINE cmb; //**************************************************************** // Macros //**************************************************************** #define MOD_0(mode) cmb.mod_0 = mode #define MOD_0_COL(color) cmb.modcolor_0 = color #define MOD_0_COL1(color) cmb.modcolor1_0 = color #define MOD_0_COL2(color) cmb.modcolor2_0 = color #define MOD_0_FAC(factor) cmb.modfactor_0 = factor #define MOD_1(mode) cmb.mod_1 = mode #define MOD_1_COL(color) cmb.modcolor_1 = color #define MOD_1_COL1(color) cmb.modcolor1_1 = color #define MOD_1_COL2(color) cmb.modcolor2_1 = color #define MOD_1_FAC(factor) cmb.modfactor_1 = factor #define A_BLEND(f1,f2) cmb.abf1=f1,cmb.abf2=f2 // To make a color or alpha combine #define CCMB(fnc,fac,loc,oth) \ cmb.c_fnc = fnc, \ cmb.c_fac = fac, \ cmb.c_loc = loc, \ cmb.c_oth = oth #define ACMB(fnc,fac,loc,oth) \ cmb.a_fnc = fnc, \ cmb.a_fac = fac, \ cmb.a_loc = loc, \ cmb.a_oth = oth #define CCMBEXT(a,a_mode,b,b_mode,c,c_invert,d,d_invert) \ cmb.c_ext_a = a, \ cmb.c_ext_a_mode = a_mode, \ cmb.c_ext_b = b, \ cmb.c_ext_b_mode = b_mode, \ cmb.c_ext_c = c, \ cmb.c_ext_c_invert = c_invert, \ cmb.c_ext_d= d, \ cmb.c_ext_d_invert = d_invert, \ cmb.cmb_ext_use |= COMBINE_EXT_COLOR #define ACMBEXT(a,a_mode,b,b_mode,c,c_invert,d,d_invert) \ cmb.a_ext_a = a, \ cmb.a_ext_a_mode = a_mode, \ cmb.a_ext_b = b, \ cmb.a_ext_b_mode = b_mode, \ cmb.a_ext_c = c, \ cmb.a_ext_c_invert = c_invert, \ cmb.a_ext_d= d, \ cmb.a_ext_d_invert = d_invert, \ cmb.cmb_ext_use |= COMBINE_EXT_ALPHA #define T0CCMBEXT(a,a_mode,b,b_mode,c,c_invert,d,d_invert) \ cmb.t0c_ext_a = a, \ cmb.t0c_ext_a_mode = a_mode, \ cmb.t0c_ext_b = b, \ cmb.t0c_ext_b_mode = b_mode, \ cmb.t0c_ext_c = c, \ cmb.t0c_ext_c_invert = c_invert, \ cmb.t0c_ext_d= d, \ cmb.t0c_ext_d_invert = d_invert, \ cmb.tex_cmb_ext_use |= TEX_COMBINE_EXT_COLOR #define T0ACMBEXT(a,a_mode,b,b_mode,c,c_invert,d,d_invert) \ cmb.t0a_ext_a = a, \ cmb.t0a_ext_a_mode = a_mode, \ cmb.t0a_ext_b = b, \ cmb.t0a_ext_b_mode = b_mode, \ cmb.t0a_ext_c = c, \ cmb.t0a_ext_c_invert = c_invert, \ cmb.t0a_ext_d= d, \ cmb.t0a_ext_d_invert = d_invert, \ cmb.tex_cmb_ext_use |= TEX_COMBINE_EXT_ALPHA #define T1CCMBEXT(a,a_mode,b,b_mode,c,c_invert,d,d_invert) \ cmb.t1c_ext_a = a, \ cmb.t1c_ext_a_mode = a_mode, \ cmb.t1c_ext_b = b, \ cmb.t1c_ext_b_mode = b_mode, \ cmb.t1c_ext_c = c, \ cmb.t1c_ext_c_invert = c_invert, \ cmb.t1c_ext_d= d, \ cmb.t1c_ext_d_invert = d_invert, \ cmb.tex_cmb_ext_use |= TEX_COMBINE_EXT_COLOR #define T1ACMBEXT(a,a_mode,b,b_mode,c,c_invert,d,d_invert) \ cmb.t1a_ext_a = a, \ cmb.t1a_ext_a_mode = a_mode, \ cmb.t1a_ext_b = b, \ cmb.t1a_ext_b_mode = b_mode, \ cmb.t1a_ext_c = c, \ cmb.t1a_ext_c_invert = c_invert, \ cmb.t1a_ext_d= d, \ cmb.t1a_ext_d_invert = d_invert, \ cmb.tex_cmb_ext_use |= TEX_COMBINE_EXT_ALPHA // To use textures #define USE_T0() \ cmb.tex |= 1, \ cmb.tmu0_func = GR_COMBINE_FUNCTION_LOCAL #define USE_T1() \ cmb.tex |= 2, \ cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER, \ cmb.tmu0_fac = GR_COMBINE_FACTOR_ONE; #define T0_ADD_T1() \ cmb.tex |= 3, \ cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, \ cmb.tmu0_fac = GR_COMBINE_FACTOR_ONE #define T0_MUL_T1() \ cmb.tex |= 3, \ cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER, \ cmb.tmu0_fac = GR_COMBINE_FACTOR_LOCAL #define T0_MUL_T1_ADD_T0() \ cmb.tex |= 3, \ cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, \ cmb.tmu0_fac = GR_COMBINE_FACTOR_LOCAL #define T0A_MUL_T1() \ cmb.tex |= 3, \ cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER, \ cmb.tmu0_fac = GR_COMBINE_FACTOR_LOCAL_ALPHA #define T0_MUL_T1A() \ cmb.tex |= 3, \ cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL_ALPHA, \ cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER, \ cmb.tmu0_fac = GR_COMBINE_FACTOR_LOCAL #define T0_INTER_T1_USING_FACTOR(factor) \ if (factor == 0xFF) { \ USE_T1(); \ } \ else if (factor == 0x00) { \ USE_T0(); \ }\ else {\ cmb.tex |= 3, \ cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_func = GR_COMBINE_FUNCTION_BLEND, \ cmb.tmu0_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR, \ percent = factor / 255.0f, \ cmb.dc0_detailmax = cmb.dc1_detailmax = percent; \ } #define T1_INTER_T0_USING_FACTOR(factor) /* inverse of above */\ if (factor == 0xFF) { \ USE_T0(); \ } \ else if (factor == 0x00) { \ USE_T1(); \ }\ else {\ cmb.tex |= 3, \ cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_func = GR_COMBINE_FUNCTION_BLEND, \ cmb.tmu0_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR, \ percent = (255 - factor) / 255.0f, \ cmb.dc0_detailmax = cmb.dc1_detailmax = percent; \ } #define T0_INTER_T1_USING_T0() \ cmb.tex |= 3, \ cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_func = GR_COMBINE_FUNCTION_BLEND, \ cmb.tmu0_fac = GR_COMBINE_FACTOR_LOCAL #define T1_INTER_T0_USING_T0() \ cmb.tex |= 3, \ cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_func = GR_COMBINE_FUNCTION_BLEND, \ cmb.tmu0_fac = GR_COMBINE_FACTOR_ONE_MINUS_LOCAL #define T0_INTER_T1_USING_T1() \ cmb.tex |= 3, \ cmb.t1c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB, \ cmb.t1c_ext_a_mode = GR_FUNC_MODE_ZERO, \ cmb.t1c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB, \ cmb.t1c_ext_b_mode = GR_FUNC_MODE_ZERO, \ cmb.t1c_ext_c = GR_CMBX_ZERO, \ cmb.t1c_ext_c_invert = 0, \ cmb.t1c_ext_d= GR_CMBX_B, \ cmb.t1c_ext_d_invert = 0, \ cmb.t0c_ext_a = GR_CMBX_OTHER_TEXTURE_RGB, \ cmb.t0c_ext_a_mode = GR_FUNC_MODE_X, \ cmb.t0c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB, \ cmb.t0c_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X, \ cmb.t0c_ext_c = GR_CMBX_OTHER_TEXTURE_RGB, \ cmb.t0c_ext_c_invert = 0, \ cmb.t0c_ext_d= GR_CMBX_B, \ cmb.t0c_ext_d_invert = 0, \ cmb.tex_cmb_ext_use |= TEX_COMBINE_EXT_COLOR; #define T0_INTER_T1_USING_T1A() \ cmb.tex |= 3, \ cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_func = GR_COMBINE_FUNCTION_BLEND, \ cmb.tmu0_fac = GR_COMBINE_FACTOR_OTHER_ALPHA #define T0_INTER_T1_USING_PRIM() \ cmb.tex |= 3, \ cmb.t1c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB, \ cmb.t1c_ext_a_mode = GR_FUNC_MODE_ZERO, \ cmb.t1c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB, \ cmb.t1c_ext_b_mode = GR_FUNC_MODE_ZERO, \ cmb.t1c_ext_c = GR_CMBX_ZERO, \ cmb.t1c_ext_c_invert = 0, \ cmb.t1c_ext_d= GR_CMBX_B, \ cmb.t1c_ext_d_invert = 0, \ cmb.t0c_ext_a = GR_CMBX_OTHER_TEXTURE_RGB, \ cmb.t0c_ext_a_mode = GR_FUNC_MODE_X, \ cmb.t0c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB, \ cmb.t0c_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X, \ cmb.t0c_ext_c = GR_CMBX_TMU_CCOLOR, \ cmb.t0c_ext_c_invert = 0, \ cmb.t0c_ext_d= GR_CMBX_B, \ cmb.t0c_ext_d_invert = 0, \ cmb.tex_ccolor = g_gdp.prim_color.total, \ cmb.tex_cmb_ext_use |= TEX_COMBINE_EXT_COLOR; #define T1_INTER_T0_USING_PRIM() /* inverse of above */\ cmb.tex |= 3, \ cmb.t1c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB, \ cmb.t1c_ext_a_mode = GR_FUNC_MODE_ZERO, \ cmb.t1c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB, \ cmb.t1c_ext_b_mode = GR_FUNC_MODE_ZERO, \ cmb.t1c_ext_c = GR_CMBX_ZERO, \ cmb.t1c_ext_c_invert = 0, \ cmb.t1c_ext_d= GR_CMBX_B, \ cmb.t1c_ext_d_invert = 0, \ cmb.t0c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB, \ cmb.t0c_ext_a_mode = GR_FUNC_MODE_X, \ cmb.t0c_ext_b = GR_CMBX_OTHER_TEXTURE_RGB, \ cmb.t0c_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X, \ cmb.t0c_ext_c = GR_CMBX_TMU_CCOLOR, \ cmb.t0c_ext_c_invert = 0, \ cmb.t0c_ext_d= GR_CMBX_B, \ cmb.t0c_ext_d_invert = 0, \ cmb.tex_ccolor = g_gdp.prim_color.total, \ cmb.tex_cmb_ext_use |= TEX_COMBINE_EXT_COLOR; #define T0_INTER_T1_USING_ENV() \ cmb.tex |= 3, \ cmb.t1c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB, \ cmb.t1c_ext_a_mode = GR_FUNC_MODE_ZERO, \ cmb.t1c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB, \ cmb.t1c_ext_b_mode = GR_FUNC_MODE_ZERO, \ cmb.t1c_ext_c = GR_CMBX_ZERO, \ cmb.t1c_ext_c_invert = 0, \ cmb.t1c_ext_d= GR_CMBX_B, \ cmb.t1c_ext_d_invert = 0, \ cmb.t0c_ext_a = GR_CMBX_OTHER_TEXTURE_RGB, \ cmb.t0c_ext_a_mode = GR_FUNC_MODE_X, \ cmb.t0c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB, \ cmb.t0c_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X, \ cmb.t0c_ext_c = GR_CMBX_TMU_CCOLOR, \ cmb.t0c_ext_c_invert = 0, \ cmb.t0c_ext_d= GR_CMBX_B, \ cmb.t0c_ext_d_invert = 0, \ cmb.tex_ccolor = g_gdp.env_color.total, \ cmb.tex_cmb_ext_use |= TEX_COMBINE_EXT_COLOR; #define T1_INTER_T0_USING_ENV() /* inverse of above */\ cmb.tex |= 3, \ cmb.t1c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB, \ cmb.t1c_ext_a_mode = GR_FUNC_MODE_ZERO, \ cmb.t1c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB, \ cmb.t1c_ext_b_mode = GR_FUNC_MODE_ZERO, \ cmb.t1c_ext_c = GR_CMBX_ZERO, \ cmb.t1c_ext_c_invert = 0, \ cmb.t1c_ext_d= GR_CMBX_B, \ cmb.t1c_ext_d_invert = 0, \ cmb.t0c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB, \ cmb.t0c_ext_a_mode = GR_FUNC_MODE_X, \ cmb.t0c_ext_b = GR_CMBX_OTHER_TEXTURE_RGB, \ cmb.t0c_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X, \ cmb.t0c_ext_c = GR_CMBX_TMU_CCOLOR, \ cmb.t0c_ext_c_invert = 0, \ cmb.t0c_ext_d= GR_CMBX_B, \ cmb.t0c_ext_d_invert = 0, \ cmb.tex_ccolor = g_gdp.env_color.total, \ cmb.tex_cmb_ext_use |= TEX_COMBINE_EXT_COLOR; #define T0_INTER_T1_USING_SHADEA() \ cmb.tex |= 3, \ cmb.t1c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB, \ cmb.t1c_ext_a_mode = GR_FUNC_MODE_ZERO, \ cmb.t1c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB, \ cmb.t1c_ext_b_mode = GR_FUNC_MODE_ZERO, \ cmb.t1c_ext_c = GR_CMBX_ZERO, \ cmb.t1c_ext_c_invert = 0, \ cmb.t1c_ext_d= GR_CMBX_B, \ cmb.t1c_ext_d_invert = 0, \ cmb.t0c_ext_a = GR_CMBX_OTHER_TEXTURE_RGB, \ cmb.t0c_ext_a_mode = GR_FUNC_MODE_X, \ cmb.t0c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB, \ cmb.t0c_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X, \ cmb.t0c_ext_c = GR_CMBX_ITALPHA, \ cmb.t0c_ext_c_invert = 0, \ cmb.t0c_ext_d= GR_CMBX_B, \ cmb.t0c_ext_d_invert = 0, \ cmb.tex_cmb_ext_use |= TEX_COMBINE_EXT_COLOR; #define T1_INTER_T0_USING_SHADEA() \ cmb.tex |= 3, \ cmb.t1c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB, \ cmb.t1c_ext_a_mode = GR_FUNC_MODE_ZERO, \ cmb.t1c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB, \ cmb.t1c_ext_b_mode = GR_FUNC_MODE_ZERO, \ cmb.t1c_ext_c = GR_CMBX_ZERO, \ cmb.t1c_ext_c_invert = 0, \ cmb.t1c_ext_d= GR_CMBX_B, \ cmb.t1c_ext_d_invert = 0, \ cmb.t0c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB, \ cmb.t0c_ext_a_mode = GR_FUNC_MODE_X, \ cmb.t0c_ext_b = GR_CMBX_OTHER_TEXTURE_RGB, \ cmb.t0c_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X, \ cmb.t0c_ext_c = GR_CMBX_ITALPHA, \ cmb.t0c_ext_c_invert = 0, \ cmb.t0c_ext_d= GR_CMBX_B, \ cmb.t0c_ext_d_invert = 0, \ cmb.tex_cmb_ext_use |= TEX_COMBINE_EXT_COLOR; #define T1_SUB_T0() \ cmb.tex |= 3, \ cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, \ cmb.tmu0_fac = GR_COMBINE_FACTOR_ONE #define T1_SUB_T0_MUL_T0() \ cmb.tex |= 3, \ cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, \ cmb.tmu0_fac = GR_COMBINE_FACTOR_LOCAL #define T1_MUL_PRIMLOD_ADD_T0() \ cmb.tex |= 3, \ cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, \ cmb.tmu0_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR, \ percent = lod_frac / 255.0f, \ cmb.dc0_detailmax = cmb.dc1_detailmax = percent #define T1_MUL_PRIMA_ADD_T0() \ cmb.tex |= 3, \ cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, \ cmb.tmu0_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR, \ percent = (float)g_gdp.prim_color.a, \ cmb.dc0_detailmax = cmb.dc1_detailmax = percent #define T1_MUL_ENVA_ADD_T0() \ cmb.tex |= 3, \ cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, \ cmb.tmu0_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR, \ percent = (float)g_gdp.env_color.a, \ cmb.dc0_detailmax = cmb.dc1_detailmax = percent #define T0_SUB_PRIM_MUL_PRIMLOD_ADD_T1() \ T0_ADD_T1(); \ MOD_0 (TMOD_TEX_SUB_COL_MUL_FAC); \ MOD_0_COL (g_gdp.prim_color.total & 0xFFFFFF00); \ MOD_0_FAC (lod_frac & 0xFF); #define T1_SUB_PRIM_MUL_PRIMLOD_ADD_T0() \ T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, \ GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, \ GR_CMBX_DETAIL_FACTOR, 0, \ GR_CMBX_ZERO, 0); \ T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, \ GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, \ GR_CMBX_ZERO, 1, \ GR_CMBX_ZERO, 0); \ cmb.tex_ccolor = g_gdp.prim_color.total; \ cmb.tex |= 3; \ percent = lod_frac / 255.0f; \ cmb.dc0_detailmax = cmb.dc1_detailmax = percent; #define PRIM_INTER_T0_USING_SHADEA() \ cmb.tex |= 1, \ cmb.t0c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB, \ cmb.t0c_ext_a_mode = GR_FUNC_MODE_X, \ cmb.t0c_ext_b = GR_CMBX_TMU_CCOLOR, \ cmb.t0c_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X, \ cmb.t0c_ext_c = GR_CMBX_ITALPHA, \ cmb.t0c_ext_c_invert = 0, \ cmb.t0c_ext_d= GR_CMBX_B, \ cmb.t0c_ext_d_invert = 0, \ cmb.tex_ccolor = g_gdp.prim_color.total, \ cmb.tex_cmb_ext_use |= TEX_COMBINE_EXT_COLOR; #define A_USE_T0() \ cmb.tex |= 1, \ cmb.tmu0_a_func = GR_COMBINE_FUNCTION_LOCAL #define A_USE_T1() \ cmb.tex |= 2, \ cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_a_func = GR_COMBINE_FUNCTION_SCALE_OTHER, \ cmb.tmu0_a_fac = GR_COMBINE_FACTOR_ONE; #define A_T0_ADD_T1() \ cmb.tex |= 3, \ cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_a_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, \ cmb.tmu0_a_fac = GR_COMBINE_FACTOR_ONE #define A_T1_SUB_T0() \ cmb.tex |= 3, \ cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_a_func = GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, \ cmb.tmu0_a_fac = GR_COMBINE_FACTOR_ONE #define A_T0_SUB_T1() \ cmb.tex |= 3, \ cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_a_func = GR_COMBINE_FUNCTION_BLEND_LOCAL, \ cmb.tmu0_a_fac = GR_COMBINE_FACTOR_OTHER_ALPHA #define A_T0_MUL_T1() \ cmb.tex |= 3, \ cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_a_func = GR_COMBINE_FUNCTION_SCALE_OTHER, \ cmb.tmu0_a_fac = GR_COMBINE_FACTOR_LOCAL #define A_T0_INTER_T1_USING_T0A() \ cmb.tex |= 3, \ cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_a_func = GR_COMBINE_FUNCTION_BLEND, \ cmb.tmu0_a_fac = GR_COMBINE_FACTOR_LOCAL_ALPHA #define A_T1_INTER_T0_USING_T0A() \ cmb.tex |= 3, \ cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_a_func = GR_COMBINE_FUNCTION_BLEND, \ cmb.tmu0_a_fac = GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA #define A_T0_INTER_T1_USING_T1A() \ cmb.tex |= 3, \ cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_a_func = GR_COMBINE_FUNCTION_BLEND, \ cmb.tmu0_a_fac = GR_COMBINE_FACTOR_OTHER_ALPHA #define A_T0_INTER_T1_USING_FACTOR(factor) \ if (factor == 0xFF) { \ A_USE_T1(); \ } \ else if (factor == 0x00) { \ A_USE_T0(); \ }\ else { \ cmb.tex |= 3, \ cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_a_func = GR_COMBINE_FUNCTION_BLEND, \ cmb.tmu0_a_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR, \ percent = factor / 255.0f, \ cmb.dc0_detailmax = cmb.dc1_detailmax = percent; \ } #define A_T1_INTER_T0_USING_FACTOR(factor) /* inverse of above */\ if (factor == 0xFF) { \ A_USE_T0(); \ } \ else if (factor == 0x00) { \ A_USE_T1(); \ }\ else { \ cmb.tex |= 3, \ cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_a_func = GR_COMBINE_FUNCTION_BLEND, \ cmb.tmu0_a_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR, \ percent = (255 - factor) / 255.0f, \ cmb.dc0_detailmax = cmb.dc1_detailmax = percent; \ } #define A_T0_INTER_T1_USING_SHADEA() \ cmb.tex |= 3, \ cmb.t1a_ext_a = GR_CMBX_LOCAL_TEXTURE_ALPHA, \ cmb.t1a_ext_a_mode = GR_FUNC_MODE_ZERO, \ cmb.t1a_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA, \ cmb.t1a_ext_b_mode = GR_FUNC_MODE_ZERO, \ cmb.t1a_ext_c = GR_CMBX_ZERO, \ cmb.t1a_ext_c_invert = 0, \ cmb.t1a_ext_d= GR_CMBX_B, \ cmb.t1a_ext_d_invert = 0, \ cmb.t0a_ext_a = GR_CMBX_OTHER_TEXTURE_ALPHA, \ cmb.t0a_ext_a_mode = GR_FUNC_MODE_X, \ cmb.t0a_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA, \ cmb.t0a_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X, \ cmb.t0a_ext_c = GR_CMBX_ITALPHA, \ cmb.t0a_ext_c_invert = 0, \ cmb.t0a_ext_d= GR_CMBX_B, \ cmb.t0a_ext_d_invert = 0, \ cmb.tex_cmb_ext_use |= TEX_COMBINE_EXT_ALPHA; #define A_T1_MUL_PRIMLOD_ADD_T0() \ cmb.tex |= 3, \ cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_a_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, \ cmb.tmu0_a_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR, \ percent = lod_frac / 255.0f, \ cmb.dc0_detailmax = cmb.dc1_detailmax = percent #define A_T1_MUL_PRIMA_ADD_T0() \ cmb.tex |= 3, \ cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_a_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, \ cmb.tmu0_a_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR, \ percent = (float)g_gdp.prim_color.a, \ cmb.dc0_detailmax = cmb.dc1_detailmax = percent #define A_T1_MUL_ENVA_ADD_T0() \ cmb.tex |= 3, \ cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL, \ cmb.tmu0_a_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, \ cmb.tmu0_a_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR, \ percent = (float)g_gdp.env_color.a, \ cmb.dc0_detailmax = cmb.dc1_detailmax = percent // Bright red, sets up a bright red combine #ifdef BRIGHT_RED // Bright red, sets up a bright red combine during the alpha stage #define BrightRed() { \ CCMB (GR_COMBINE_FUNCTION_LOCAL, \ GR_COMBINE_FACTOR_NONE, \ GR_COMBINE_LOCAL_CONSTANT, \ GR_COMBINE_OTHER_NONE); \ ACMB (GR_COMBINE_FUNCTION_LOCAL, \ GR_COMBINE_FACTOR_NONE, \ GR_COMBINE_LOCAL_CONSTANT, \ GR_COMBINE_OTHER_NONE); \ cmb.ccolor = 0xFF0000FF; \ } #else #define BrightRed() #endif #define CC(color) cmb.ccolor=(color)&0xFFFFFF00 #define CC_BYTE(byte) { cmb.ccolor=(byte<<8)|(byte<<16)|(byte<<24); } #define CC_C1MULC2(color1, color2) { \ cmb.ccolor=(uint8_t)( ((color1 & 0xFF000000) >> 24) * (((color2 & 0xFF000000) >> 24) /255.0f) ) << 24 | \ (uint8_t)( ((color1 & 0x00FF0000) >> 16) * (((color2 & 0x00FF0000) >> 16) /255.0f) ) << 16 | \ (uint8_t)( ((color1 & 0x0000FF00) >> 8) * (((color2 & 0x0000FF00) >> 8) /255.0f) ) << 8 ; \ } #define CC_C1SUBC2(color1, color2) { \ cmb.ccolor=(uint8_t)( max(0, (int)((color1 & 0xFF000000) >> 24) - (int)((color2 & 0xFF000000) >> 24)) ) << 24 | \ (uint8_t)( max(0, (int)((color1 & 0x00FF0000) >> 16) - (int)((color2 & 0x00FF0000) >> 16)) ) << 16 | \ (uint8_t)( max(0, (int)((color1 & 0x0000FF00) >> 8) - (int)((color2 & 0x0000FF00) >> 8)) ) << 8 ; \ } #define CC_COLMULBYTE(color, byte) { \ float factor = byte/255.0f; \ cmb.ccolor = (uint8_t)( ((color & 0xFF000000) >> 24) * factor ) << 24 | \ (uint8_t)( ((color & 0x00FF0000) >> 16) * factor ) << 16 | \ (uint8_t)( ((color & 0x0000FF00) >> 8) * factor ) << 8 ; \ } #define CC_PRIM() CC(g_gdp.prim_color.total) #define CC_ENV() CC(g_gdp.env_color.total) #define CC_1SUBPRIM() CC((~g_gdp.prim_color.total)) #define CC_1SUBENV() CC((~g_gdp.env_color.total)) #define CC_PRIMA() CC_BYTE((g_gdp.prim_color.total &0xFF)) #define CC_ENVA() CC_BYTE((g_gdp.env_color.total & 0xFF)) #define CC_1SUBPRIMA() CC_BYTE(((~g_gdp.prim_color.total)&0xFF)) #define CC_1SUBENVA() CC_BYTE(((~g_gdp.env_color.total) & 0xFF)) #define CC_PRIMLOD() CC_BYTE(g_gdp.primitive_lod_frac) #define CC_K5() CC_BYTE(g_gdp.k5) #define CC_PRIMMULENV() CC_C1MULC2(g_gdp.prim_color.total, g_gdp.env_color.total) #define CC_PRIMSUBENV() CC_C1SUBC2(g_gdp.prim_color.total, g_gdp.env_color.total) #define XSHADE(color, flag) { \ rdp.col[0] *= (float)((color & 0xFF000000) >> 24) / 255.0f; \ rdp.col[1] *= (float)((color & 0x00FF0000) >> 16) / 255.0f; \ rdp.col[2] *= (float)((color & 0x0000FF00) >> 8) / 255.0f; \ rdp.cmb_flags |= flag; \ } #define XSHADE1M(color, flag) { \ rdp.col[0] *= 1.0f-((float)color.r / 255.0f); \ rdp.col[1] *= 1.0f-((float)color.g / 255.0f); \ rdp.col[2] *= 1.0f-((float)color.b / 255.0f); \ rdp.cmb_flags |= flag; \ } #define XSHADEC1MC2(color1, color2, flag) { \ rdp.col[0] *= (float)( max(0, (int)color1.r - (int)color2.r) )/255.0f; \ rdp.col[1] *= (float)( max(0, (int)color1.g - (int)color2.g) )/255.0f; \ rdp.col[2] *= (float)( max(0, (int)color1.b - (int)color2.b) )/255.0f; \ rdp.cmb_flags |= flag; \ } #define XSHADE_BYTE(byte, flag) { \ float tmpcol = (float)byte / 255.0f; \ rdp.col[0] *= tmpcol; \ rdp.col[1] *= tmpcol; \ rdp.col[2] *= tmpcol; \ rdp.cmb_flags |= flag; \ } #define MULSHADE(color) XSHADE(color, CMB_MULT) #define MULSHADE_PRIM() MULSHADE(g_gdp.prim_color.total) #define MULSHADE_ENV() MULSHADE(g_gdp.env_color.total) #define MULSHADE_1MPRIM() XSHADE1M(g_gdp.prim_color, CMB_MULT) #define MULSHADE_1MENV() XSHADE1M(g_gdp.env_color, CMB_MULT) #define MULSHADE_PRIMSUBENV() XSHADEC1MC2(g_gdp.prim_color, g_gdp.env_color, CMB_MULT) #define MULSHADE_ENVSUBPRIM() XSHADEC1MC2(g_gdp.env_color, g_gdp.prim_color, CMB_MULT) #define MULSHADE_BYTE(byte) XSHADE_BYTE(byte, CMB_MULT) #define MULSHADE_PRIMA() MULSHADE_BYTE((g_gdp.prim_color.total & 0xFF)) #define MULSHADE_ENVA() MULSHADE_BYTE((g_gdp.env_color.total & 0xFF)) #define MULSHADE_1MENVA() MULSHADE_BYTE(((~g_gdp.env_color.total) & 0xFF)) #define MULSHADE_PRIMLOD() MULSHADE_BYTE((g_gdp.primitive_lod_frac & 0xFF)) #define MULSHADE_K5() MULSHADE_BYTE(g_gdp.k5) #define SETSHADE(color) XSHADE(color, CMB_SET) #define SETSHADE_PRIM() SETSHADE(g_gdp.prim_color.total) #define SETSHADE_ENV() SETSHADE(g_gdp.env_color.total) #define SETSHADE_BYTE(byte) XSHADE_BYTE(byte, CMB_SET) #define SETSHADE_PRIMA() SETSHADE_BYTE((g_gdp.prim_color.total & 0xFF)) #define SETSHADE_ENVA() SETSHADE_BYTE((g_gdp.env_color.total & 0xFF)) #define SETSHADE_1MPRIMA() SETSHADE_BYTE(((~g_gdp.prim_color.total) & 0xFF)) #define SETSHADE_PRIMLOD() SETSHADE_BYTE((g_gdp.primitive_lod_frac & 0xFF)) #define SETSHADE_1MPRIMLOD() SETSHADE_BYTE(((~g_gdp.primitive_lod_frac) & 0xFF)) #define SETSHADE_1MPRIM() XSHADE1M(g_gdp.prim_color, CMB_SET) #define SETSHADE_1MENV() XSHADE1M(g_gdp.env_color, CMB_SET) #define SETSHADE_PRIMSUBENV() XSHADEC1MC2(g_gdp.prim_color, g_gdp.env_color, CMB_SET) #define SETSHADE_ENVSUBPRIM() XSHADEC1MC2(g_gdp.env_color, g_gdp.prim_color, CMB_SET) #define SETSHADE_SHADE_A() { \ rdp.cmb_flags = CMB_SETSHADE_SHADEALPHA; \ } #define XSHADEADD(color, flag) { \ rdp.coladd[0] *= (float)color.r / 255.0f; \ rdp.coladd[1] *= (float)color.g / 255.0f; \ rdp.coladd[2] *= (float)color.b / 255.0f; \ rdp.cmb_flags |= flag; \ } #define XSHADEC1MC2ADD(color1, color2, flag) { \ rdp.coladd[0] *= (float)( max(0, (int)color1.r - (int)color2.r)) / 255.0f; \ rdp.coladd[1] *= (float)( max(0, (int)color1.g - (int)color2.g)) / 255.0f; \ rdp.coladd[2] *= (float)( max(0, (int)color1.b - (int)color2.b)) / 255.0f; \ rdp.cmb_flags |= flag; \ } #define SUBSHADE_PRIM() XSHADEADD(g_gdp.prim_color, CMB_SUB) #define SUBSHADE_ENV() XSHADEADD(g_gdp.env_color, CMB_SUB) #define SUBSHADE_PRIMSUBENV() XSHADEC1MC2ADD(g_gdp.prim_color, g_gdp.env_color, CMB_SUB) #define ADDSHADE_PRIM() XSHADEADD(g_gdp.prim_color, CMB_ADD) #define ADDSHADE_ENV() XSHADEADD(g_gdp.env_color, CMB_ADD) #define ADDSHADE_PRIMSUBENV() XSHADEC1MC2ADD(g_gdp.prim_color, g_gdp.env_color, CMB_ADD) #define SUBSHADE_PRIMMULENV() { \ rdp.coladd[0] *= (float)( g_gdp.prim_color.r * g_gdp.env_color.r )/255.0f/255.0f; \ rdp.coladd[1] *= (float)( g_gdp.prim_color.g * g_gdp.env_color.g )/255.0f/255.0f; \ rdp.coladd[2] *= (float)( g_gdp.prim_color.b * g_gdp.env_color.b )/255.0f/255.0f; \ rdp.cmb_flags |= CMB_SUB; \ } #define COLSUBSHADE_PRIM() { \ rdp.coladd[0] *= (float)(g_gdp.prim_color.r) / 255.0f; \ rdp.coladd[1] *= (float)(g_gdp.prim_color.g) / 255.0f; \ rdp.coladd[2] *= (float)(g_gdp.prim_color.b) / 255.0f; \ rdp.cmb_flags |= CMB_COL_SUB_OWN; \ } #define INTERSHADE_2(color,factor) { \ rdp.col_2[0] = color.r / 255.0f; \ rdp.col_2[1] = color.g / 255.0f; \ rdp.col_2[2] = color.b / 255.0f; \ rdp.shade_factor = (factor) / 255.0f; \ rdp.cmb_flags_2 = CMB_INTER; \ } #define MULSHADE_SHADEA() rdp.cmb_flags |= CMB_MULT_OWN_ALPHA; #define CA(color) cmb.ccolor|=(color)&0xFF #define CA_PRIM() CA(g_gdp.prim_color.total) #define CA_ENV() CA(g_gdp.env_color.total) #define CA_INVPRIM() cmb.ccolor|=0xFF-(g_gdp.prim_color.total & 0xFF) #define CA_INVENV() cmb.ccolor|=0xFF-(g_gdp.env_color.total & 0xFF) #define CA_ENV1MPRIM() cmb.ccolor|= (uint32_t)(((g_gdp.env_color.total & 0xFF)/255.0f) * (((~(g_gdp.prim_color.total & 0xFF)) & 0xff)/255.0f) * 255.0f); #define CA_PRIMENV() cmb.ccolor |= (uint32_t)(((g_gdp.env_color.total & 0xFF)/255.0f) * ((g_gdp.prim_color.total & 0xFF)/255.0f) * 255.0f); #define CA_PRIMLOD() cmb.ccolor |= g_gdp.primitive_lod_frac; #define CA_PRIM_MUL_PRIMLOD() cmb.ccolor |= (int)(((g_gdp.prim_color.total & 0xFF) * g_gdp.primitive_lod_frac) / 255.0f); #define CA_ENV_MUL_PRIMLOD() cmb.ccolor |= (int)(((g_gdp.env_color.total & 0xFF) * g_gdp.primitive_lod_frac) / 255.0f); #define XSHADE_A(color, flag) { \ rdp.col[3] *= (float)(color & 0xFF) / 255.0f; \ rdp.cmb_flags |= flag; \ } #define XSHADE1M_A(color, flag) { \ rdp.col[3] *= 1.0f-((float)color.a / 255.0f); \ rdp.cmb_flags |= flag; \ } #define XSHADEC1MC2_A(color1, color2, flag) { \ rdp.col[3] *= (float)( max(0, (int)color1.a - (int)color2.a) ) / 255.0f; \ rdp.cmb_flags |= flag; \ } #define MULSHADE_A_PRIM() XSHADE_A(g_gdp.prim_color.total, CMB_A_MULT) #define MULSHADE_A_1MPRIM() XSHADE1M_A(g_gdp.prim_color, CMB_A_MULT) #define MULSHADE_A_ENV() XSHADE_A(g_gdp.env_color.total, CMB_A_MULT) #define MULSHADE_A_PRIMSUBENV() XSHADEC1MC2_A(g_gdp.prim_color, g_gdp.env_color, CMB_A_MULT) #define MULSHADE_A_ENVSUBPRIM() XSHADEC1MC2_A(g_gdp.env_color, g_gdp.prim_color, CMB_A_MULT) #define SETSHADE_A(color) XSHADE_A(color, CMB_A_SET) #define SETSHADE_A_PRIM() SETSHADE_A(g_gdp.prim_color.total) #define SETSHADE_A_ENV() SETSHADE_A(g_gdp.env_color.total) #define SETSHADE_A_PRIMSUBENV() XSHADEC1MC2_A(g_gdp.prim_color, g_gdp.env_color, CMB_A_SET) #define SETSHADE_A_INVENV() XSHADE1M_A(g_gdp.env_color, CMB_A_SET) #define XSHADEADD_A(color, flag) { \ rdp.coladd[3] *= (float)color.a / 255.0f; \ rdp.cmb_flags |= flag; \ } #define SUBSHADE_A_PRIM() XSHADEADD_A(g_gdp.prim_color, CMB_A_SUB) #define SUBSHADE_A_ENV() XSHADEADD_A(g_gdp.env_color, CMB_A_SUB) #define ADDSHADE_A_PRIM() XSHADEADD_A(g_gdp.prim_color, CMB_A_ADD) #define ADDSHADE_A_ENV() XSHADEADD_A(g_gdp.env_color, CMB_A_ADD) //**************************************************************** // Combine Functions //**************************************************************** // These are in a somewhat ordered way, using the A constants below. T0 comes before // T1 comes before PRIM, ... except for CMB, which always comes at the end, where // the CMB comes first in the name. T0 and T1 are always interleaved, because they use the // same function. // Keep going in alphabetical order, but do not break the order of variables! // ex: A*C + B*C -> T0_MUL_PRIM_ADD_ENV_MUL_PRIM, // Although prim comes before env, we have already used prim as C, so it must stay as C // and would NOT become T0_MUL_PRIM_ADD_PRIM_MUL_ENV // // New version ordered by: // t0 // prim // env // shade static void cc_one(void) { CCMB (GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE); cmb.ccolor= (0xFFFFFF00) & 0xFFFFFF00; } static void cc_zero(void) { CCMB (GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE); cmb.ccolor= (0x00000000) & 0xFFFFFF00; } static void cc_t0(void) { if ((rdp.othermode_l & RDP_FORCE_BLEND) && (((rdp.othermode_h & RDP_CYCLE_TYPE) >> 20) < G_CYC_COPY)) { uint32_t blend_mode = (rdp.othermode_l >> 16); if (blend_mode == 0xa500) { uint32_t r, g, b, rgb; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); r = g_gdp.blend_color.r * g_gdp.fog_color.a; g = g_gdp.blend_color.g * g_gdp.fog_color.a; b = g_gdp.blend_color.b * g_gdp.fog_color.a; rgb = (r << 24) | (g << 16) | (b << 8); cmb.ccolor= (rgb) & 0xFFFFFF00; return; } else if (blend_mode == 0x55f0) //cmem*afog + cfog*1ma { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_CONSTANT); cmb.ccolor= (g_gdp.fog_color.total) & 0xFFFFFF00; A_USE_T0(); return; } } CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); USE_T0(); } static void cc_t0a(void) { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_CONSTANT); USE_T0(); A_USE_T0(); cmb.ccolor= (0xFFFFFF00) & 0xFFFFFF00; } static void cc_t1(void) //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); USE_T1(); } static void cc_t0_mul_t1(void) { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); T0_MUL_T1(); } static void cc_t0_mul_t1_add_t0() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); T0_MUL_T1_ADD_T0(); } /* static void cc_t1_inter__env_inter_t0_using_k5__using_t1a() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); uint32_t col1 = (g_gdp.k5 << 24) | (g_gdp.k5 << 16) | (g_gdp.k5 << 8); MOD_0 (TMOD_COL_INTER_TEX_USING_COL1); MOD_0_COL (g_gdp.env_color.total & 0xFFFFFF00); MOD_0_COL1 (col1 & 0xFFFFFF00); cmb.tex |= 3; cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL; cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL; cmb.tmu0_func = GR_COMBINE_FUNCTION_BLEND; cmb.tmu0_fac = GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA; } */ static void cc_t1_inter_t0_using_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); T1_INTER_T0_USING_ENV(); } static void cc_prim() { CCMB (GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE); CC_PRIM(); } static void cc_env() { CCMB (GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE); CC_ENV(); } static void cc_scale() { CCMB (GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE); cmb.ccolor= (g_gdp.key_scale.total) & 0xFFFFFF00; } static void cc_shade() { CCMB (GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_NONE); } static void cc_one_mul_shade() { { CCMB (GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_NONE); } } static void cc_shadea() { CCMB (GR_COMBINE_FUNCTION_LOCAL_ALPHA, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_NONE); } static void cc_t0_mul_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); USE_T0(); } static void cc_t0_mul_prima() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIMA(); USE_T0(); } static void cc_t1_mul_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); if ((rdp.cycle1 & 0xFFFF) == (rdp.cycle2 & 0xFFFF)) // 1 cycle, use t0 { USE_T0(); } else { USE_T1(); } } static void cc_t0a_mul_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); A_USE_T0(); } //Added by Gonetz static void cc__t1_inter_t0_using_enva__mul_prim() { uint8_t factor = g_gdp.env_color.a; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); T1_INTER_T0_USING_FACTOR (factor); } static void cc__t0_inter_one_using_t1__mul_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); cmb.tex |= 3; cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL; cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL; cmb.tmu0_fac = GR_COMBINE_FACTOR_ONE_MINUS_LOCAL; } static void cc__t0_inter_one_using_primlod__mul_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ONE_MINUS_X, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_B, 0); cmb.tex |= 1; percent = lod_frac / 255.0f; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; } static void cc__t1_inter_one_using_env__mul_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); T1CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, 1, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); cmb.tex |= 2; cmb.tex_ccolor = g_gdp.env_color.total; } static void cc__t1_inter_one_using_enva__mul_t0() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); T1CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_TMU_CALPHA, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, 0, GR_CMBX_ZERO, 0); cmb.tex |= 3; cmb.tex_ccolor = 0xFFFFFF00 | (g_gdp.env_color.total & 0xFF); } //Added by Gonetz static void cc_prim_mul_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); SETSHADE_PRIM(); } static void cc_prim_mul_prima() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); SETSHADE_PRIMA(); } static void cc_t1_mul_prima() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIMA(); USE_T1(); } static void cc_t1_mul_enva() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_ENVA(); USE_T1(); } static void cc_t0_mul_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_ENV(); USE_T0(); } static void cc_t1_mul_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_ENV(); USE_T1(); } //Added by Gonetz static void cc_t0_mul_enva() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_ENVA(); USE_T0(); } static void cc_t0_mul_scale() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); cmb.ccolor= (g_gdp.key_scale.total) & 0xFFFFFF00; USE_T0(); } static void cc_t0_mul_enva_add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); SETSHADE_PRIM(); CC_ENVA(); USE_T0(); } static void cc_t0_mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); USE_T0(); } static void cc_f1_sky() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); MULSHADE_SHADEA(); MULSHADE_ENVSUBPRIM(); ADDSHADE_PRIM(); cmb.ccolor= (0xFFFFFFFF) & 0xFFFFFF00; } static void cc_t0_mul_shadea() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); SETSHADE_SHADE_A(); USE_T0(); } static void cc_t0_mul_k5() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_K5(); USE_T0(); } static void cc_t1_mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); USE_T1(); } //Added by Gonetz static void cc__t0_add_t1__mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T0_ADD_T1(); } static void cc__t0_mul_shade__add__t1_mul_shade() { //combiner is used in Spiderman. It seems that t0 is used instead of t1 #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); cmb.tex |= 1; CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ZERO, 1, GR_CMBX_B, 0); } #ifndef HAVE_ASSUME_COMBINE_EXT else { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); USE_T0(); } #endif } static void cc__t0_mul_prim__inter_env_using_enva() { uint32_t enva = g_gdp.env_color.total & 0xFF; if (enva == 0xFF) cc_env(); else if (enva == 0) cc_t0_mul_prim(); else #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, GR_CMBX_TMU_CCOLOR, 0, GR_CMBX_ZERO, 0); cmb.tex |= 1; cmb.tex_ccolor = g_gdp.prim_color.total; CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_X, GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_CONSTANT_COLOR, 0, GR_CMBX_B, 0); SETSHADE_ENV(); CC_ENVA(); } #ifndef HAVE_ASSUME_COMBINE_EXT else { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); SETSHADE_PRIM(); INTERSHADE_2 (g_gdp.env_color, g_gdp.env_color.a); USE_T0(); MOD_0 (TMOD_TEX_INTER_COLOR_USING_FACTOR); MOD_0_COL (g_gdp.env_color.total & 0xFFFFFF00); MOD_0_FAC (g_gdp.env_color.total & 0xFF); } #endif } static void cc__t1_inter_t0_using_t1__mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_B, 0, GR_CMBX_B, 0); cmb.tex |= 3; } #ifndef HAVE_ASSUME_COMBINE_EXT else { T0_INTER_T1_USING_FACTOR (0x7F); } #endif } //Added by Gonetz static void cc__t1_inter_t0_using_enva__mul_shade() { uint8_t factor = g_gdp.env_color.a; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T1_INTER_T0_USING_FACTOR (factor); } //Added by Gonetz static void cc__t1_inter_t0_using_shadea__mul_shade() { #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); T1_INTER_T0_USING_SHADEA(); } #ifndef HAVE_ASSUME_COMBINE_EXT else { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); USE_T0(); } #endif } //Added by Gonetz static void cc__t0_inter_one_using_prim__mul_shade() { // (1-t0)*prim+t0, (cmb-0)*shade+0 CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ONE_MINUS_X, GR_CMBX_LOCAL_TEXTURE_RGB, 0, GR_CMBX_B, 0); cmb.tex |= 1; cmb.tex_ccolor = g_gdp.prim_color.total; } static void cc__t0_inter_one_using_primlod__mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ONE_MINUS_X, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_B, 0); cmb.tex |= 1; percent = lod_frac / 255.0f; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; } //Added by Gonetz static void cc__t0_inter_env_using_enva__mul_shade() { // (env-t0)*env_a+t0, (cmb-0)*shade+0 CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_TMU_CALPHA, 0, GR_CMBX_B, 0); cmb.tex |= 1; cmb.tex_ccolor = g_gdp.env_color.total; } //Added by Gonetz static void cc__t0_inter_env_using_shadea__mul_shade() { // (env-t0)*shade_a+t0, (cmb-0)*shade+0 T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITALPHA, 0, GR_CMBX_B, 0); cmb.tex |= 1; cmb.tex_ccolor = g_gdp.env_color.total; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); } static void cc__t0_mul_prim_add_env__mul_shade() { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_TMU_CCOLOR, 0, GR_CMBX_ZERO, 0); cmb.tex |= 1; cmb.tex_ccolor = g_gdp.prim_color.total; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); CC_ENV(); } static void cc__t1_sub_t0_mul_primlod_add_prim__mul_shade() { T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_ZERO, 0); cmb.tex |= 3; percent = lod_frac / 255.0f; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); CC_PRIM(); } static void cc__t1_sub_prim_mul_t0__mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_LOCAL_TEXTURE_RGB, 0, GR_CMBX_ZERO, 0); cmb.tex_ccolor = g_gdp.prim_color.total; cmb.tex |= 3; } static void cc__t1_sub_t0_mul_t0_add_shade__mul_shade() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_LOCAL_TEXTURE_RGB, 0, GR_CMBX_ITRGB, 0); cmb.tex |= 3; } static void cc__one_sub_shade_mul_t0_add_shade__mul_shade() { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, GR_FUNC_MODE_ONE_MINUS_X, GR_CMBX_LOCAL_TEXTURE_RGB, 0, GR_CMBX_B, 0); cmb.tex |= 1; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); } static void cc__t0_sub_prim_mul_t1_add_t1__mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); if (g_gdp.prim_color.total & 0xFFFFFF00) { MOD_0 (TMOD_TEX_SUB_COL); MOD_0_COL (g_gdp.prim_color.total & 0xFFFFFF00); } T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, 0, GR_CMBX_B, 0); cmb.tex |= 3; } static void cc__t1_sub_env_mul_t0_add_t0__mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.env_color.total; cmb.tex |= 3; } static void cc__t0_mul_prima_add_prim_mul__shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, GR_CMBX_TMU_CALPHA, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.prim_color.total; cmb.tex |= 1; } static void cc__t0_inter_prim_using_prima__inter_env_using_enva() { T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_TMU_CALPHA, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.prim_color.total; cmb.tex |= 1; CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_X, GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_CONSTANT_COLOR, 0, GR_CMBX_B, 0); CC_ENVA(); SETSHADE_ENV(); } static void cc_prim_inter_t1_mul_shade_using_texa() { T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); cmb.tex |= 3; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_TEXTURE_ALPHA, 0, GR_CMBX_B, 0); } static void cc__prim_inter_t0_using_t0a__mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.prim_color.total; cmb.tex |= 1; } static void cc__prim_inter_t0_using_t0a__inter_env_using_enva() { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.prim_color.total; cmb.tex |= 1; CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_X, GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_CONSTANT_COLOR, 0, GR_CMBX_B, 0); CC_ENVA(); SETSHADE_ENV(); } // ** A*B ** static void cc__prim_inter_t0_using_shadea__mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); PRIM_INTER_T0_USING_SHADEA(); } static void cc_t0_sub_shade_mul_shadea_add_shade(); static void cc__shade_inter_t0_using_shadea__mul_shade() { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITALPHA, 0, GR_CMBX_B, 0); cmb.tex |= 1; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); } static void cc__prim_inter_env_using_enva__mul_shade(void) { uint32_t rgba[4]; const float ea = (float)g_gdp.env_color.a; rgba[0] = (uint32_t) (g_gdp.env_color.r * ea + g_gdp.prim_color.r * (1.0f - ea)); rgba[1] = (uint32_t) (g_gdp.env_color.g * ea + g_gdp.prim_color.g * (1.0f - ea)); rgba[2] = (uint32_t) (g_gdp.env_color.b * ea + g_gdp.prim_color.b * (1.0f - ea)); CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); cmb.ccolor= (rgba[0] << 24) | (rgba[1] << 16) | (rgba[2] << 8); } //Added by Gonetz static void cc_prim_mul_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); SETSHADE_ENV(); } static void cc_prim_mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); } static void cc_prim_mul_shadea() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); SETSHADE_SHADE_A(); CC_PRIM(); } static void cc_env_mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); } static void cc_env_mul_enva() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_OTHER_ALPHA, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); CA_ENV(); } static void cc_scale_mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); cmb.ccolor= (g_gdp.key_scale.total) & 0xFFFFFF00; } // ** A+B ** static void cc_t0_add_prim() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); USE_T0(); } static void cc__t0_mul_t1__add_prim() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); T0_MUL_T1(); } static void cc_t0_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_ENV(); USE_T0(); } //Added by Gonetz static void cc__t0_mul_t1__add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_ENV(); T0_MUL_T1(); } static void cc__t0_mul_t1__add_env_mul__t0_mul_t1__add_env() { T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.env_color.total; cmb.tex |= 3; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, GR_CMBX_TEXTURE_RGB, 0, GR_CMBX_ZERO, 0); } static void cc_t0_add_shade() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); USE_T0(); } static void cc__t0_mul_t1__add_shade() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T0_MUL_T1(); } static void cc_prim_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); SETSHADE_PRIM(); } static void cc_t0_add_prim_mul_one_sub_t0_add_t0() //Aded by Gonetz { T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, 1, GR_CMBX_B, 0); CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); cmb.tex_ccolor = g_gdp.prim_color.total; cmb.tex |= 1; } static void cc_one_sub_prim_mul_t0_add_prim(); static void cc__one_sub_prim_mul_t0_add_prim__mul_prima_add__one_sub_prim_mul_t0_add_prim() //Aded by Gonetz { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, GR_CMBX_TMU_CCOLOR, 1, GR_CMBX_B, 0); CCMBEXT(GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.prim_color.total; CC_PRIMA(); cmb.tex |= 3; //hw frame buffer allocated as tile1, but not used in combiner } static void cc_prim_add_shade() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); } static void cc_env_add_shade() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); } static void cc_shade_add_shade() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_ITERATED); } // ** A-B ** static void cc__t0_inter_t1_using_enva__sub_env(void) //Aded by Gonetz { uint8_t factor = g_gdp.env_color.a; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_ENV(); T0_INTER_T1_USING_FACTOR (factor); } static void cc_t0_sub__shade_mul_center(void) { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE(g_gdp.key_center.total); USE_T0(); } // ** A-B*C ** static void cc_env_sub__t0_sub_t1_mul_primlod__mul_prim(void) //Aded by Gonetz { T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); cmb.tex |= 3; CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); SETSHADE_PRIM(); SETSHADE_PRIMLOD(); CC_ENV(); } static void cc_env_sub__t0_mul_scale_add_env__mul_prim(void) { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, GR_CMBX_TMU_CCOLOR, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.key_scale.total; cmb.tex |= 1; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, GR_CMBX_CONSTANT_COLOR, 0, GR_CMBX_B, 0); SETSHADE_ENV(); CC_PRIM(); } static void cc_one_sub__one_sub_t0_mul_enva_add_prim__mul_prim(void) //Aded by Gonetz { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ONE_MINUS_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.prim_color.total; cmb.tex |= 1; percent = (float)g_gdp.env_color.a; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; CCMBEXT(GR_CMBX_ZERO, GR_FUNC_MODE_X, GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_CONSTANT_COLOR, 0, GR_CMBX_ZERO, 1); CC_PRIM(); } // ** A+B*C ** //Aded by Gonetz static void cc_t0_add_env_mul_k5(void) { float scale; uint8_t r, g, b; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); scale = g_gdp.k5 / 255.0f; r = (uint8_t)(g_gdp.env_color.r * scale); g = (uint8_t)(g_gdp.env_color.g * scale); b = (uint8_t)(g_gdp.env_color.b * scale); cmb.ccolor= (r << 24) | (g << 16) | (b << 8); USE_T0(); } static void cc_t0_add_shade_mul_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE_ENV(); USE_T0(); } static void cc__t1_mul_t0_add_t0__add_prim_mul_shade() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE_PRIM(); cmb.tex |= 3; cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL; cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL; cmb.tmu0_fac = GR_COMBINE_FACTOR_LOCAL; } static void cc__t0_sub_env_mul_enva__add_prim_mul_shade() { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_ZERO, 0); cmb.tex_ccolor = g_gdp.env_color.total; cmb.tex |= 1; percent = (float)g_gdp.env_color.a; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_X, GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_CONSTANT_COLOR, 0, GR_CMBX_B, 0); CC_PRIM(); } // ** A*B+C ** //Added by Gonetz static void cc_t0_mul_prim_add_t1() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_TMU_CCOLOR, 0, GR_CMBX_B, 0); cmb.tex |= 3; cmb.tex_ccolor = g_gdp.prim_color.total; } static void cc_shirt() { // (t1-0)*prim+0, (1-t0)*t1+cmb CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); /* T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_TMU_CCOLOR, 0, GR_CMBX_ZERO, 0); //*/ //* T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); //*/ T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, 1, GR_CMBX_B, 0); cmb.tex |= 3; cmb.tex_ccolor = g_gdp.prim_color.total; } static void cc_t1_mul_prim_add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); SETSHADE_PRIM(); CC_PRIM(); USE_T0(); } //Added by Gonetz static void cc_t0_mul_prim_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); SETSHADE_PRIM(); CC_ENV(); USE_T0(); } //Added by Gonetz static void cc_t1_mul_prim_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); SETSHADE_PRIM(); CC_ENV(); USE_T1(); } static void cc__t0_add_primlod__mul_prim_add_env() { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_B, 0); CC_PRIMLOD(); cmb.tex_ccolor = cmb.ccolor; CC_ENV(); SETSHADE_PRIM(); cmb.tex |= 1; } //Added by Gonetz static void cc_t0_mul_prim_mul_shade_add_prim_mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE_PRIM(); USE_T0(); } //Added by Gonetz static void cc__t0_inter_t1_using_primlod__mul_prim_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); SETSHADE_PRIM(); CC_ENV(); T0_INTER_T1_USING_FACTOR (lod_frac); } static void cc__t1_sub_prim_mul_enva_add_t0__mul_prim_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); SETSHADE_ENV(); T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_ZERO, 0); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); cmb.tex_ccolor = g_gdp.prim_color.total; cmb.tex |= 3; percent = (float)g_gdp.env_color.a; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; } //Added by Gonetz static void cc__t0_inter_t1_using_primlod__mul_shade_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); T0_INTER_T1_USING_FACTOR (lod_frac); } //Added by Gonetz static void cc__t1_sub_prim_mul_primlod_add_t0__mul_prim_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); SETSHADE_PRIM(); CC_ENV(); T1_SUB_PRIM_MUL_PRIMLOD_ADD_T0(); } //Aded by Gonetz static void cc__t0_mul_t1__mul_prim_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); MULSHADE_PRIM(); T0_MUL_T1(); } //Aded by Gonetz static void cc__t0_mul_t1__sub_prim_mul_env_add_shade() { T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_TMU_CCOLOR, 0, GR_CMBX_ZERO, 0); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.env_color.total; cmb.tex |= 3; CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ZERO, 1, GR_CMBX_TEXTURE_RGB, 0); CC_PRIMMULENV(); } static void cc__t0_sub_prim_mul_t1_add_t1__mul_env_add_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); if (g_gdp.prim_color.total & 0xFFFFFF00) { MOD_0 (TMOD_TEX_SUB_COL); MOD_0_COL (g_gdp.prim_color.total & 0xFFFFFF00); } T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, 0, GR_CMBX_B, 0); cmb.tex |= 3; } static void cc__t0_mul_t1__mul_shade_add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); T0_MUL_T1(); } static void cc__t0_mul_shadea_add_env__mul_shade_add_prim() { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, GR_CMBX_ITALPHA, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.env_color.total; cmb.tex |= 1; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_B, 0); CC_PRIM(); } static void cc__t0_mul_t1__mul_shade_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); T0_MUL_T1(); } //Added by Gonetz static void cc__t0_add_t1__mul_shade_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); T0_ADD_T1(); } static void cc__t1_mul_prima_add_t0__mul_shade_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); T1_MUL_PRIMA_ADD_T0(); } static void cc__t0_inter_t1_using_enva__mul_shade_add_prim() { uint8_t factor = g_gdp.env_color.a; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); T0_INTER_T1_USING_FACTOR (factor); } static void cc__t0_inter_t1_using_enva__mul_shade_add_env(void) { uint8_t factor = g_gdp.env_color.a; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); T0_INTER_T1_USING_FACTOR (factor); } //Added by Gonetz static void cc_t0_mul_primlod_add_prim(void) { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); SETSHADE_PRIM(); CC_PRIMLOD(); USE_T0(); } static void cc__t0_mul_primlod__add__prim_mul_shade(void) { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); MULSHADE_PRIM (); CC_PRIMLOD(); USE_T0(); } //Added by Gonetz static void cc_t0_mul_primlod_add_prim_mul_shade_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); MULSHADE_PRIM (); ADDSHADE_ENV(); CC_PRIMLOD(); USE_T0(); } //Added by Gonetz static void cc_t1_mul_primlod_add_prim_mul_shade_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); MULSHADE_PRIM (); ADDSHADE_ENV(); CC_PRIMLOD(); USE_T1(); } static void cc__t0_inter_t1_using_primlod__mul_shade_add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); T0_INTER_T1_USING_FACTOR (lod_frac); } static void cc__t1_inter_t0_using_primlod__mul_shade_add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); T1_INTER_T0_USING_FACTOR (lod_frac); } //Added by Gonetz static void cc__t1_sub_t0_mul_primlod_add_prim__mul_shade_add_shade() { T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_ZERO, 0); cmb.tex |= 3; percent = lod_frac / 255.0f; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ITRGB, 0); CC_PRIM(); } //Added by Gonetz static void cc__t0_inter_t1_using_half__mul_prim_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); SETSHADE_PRIM(); CC_ENV(); T0_INTER_T1_USING_FACTOR (0x7F); } //Added by Gonetz static void cc__t0_inter_t1_using_t1__mul_prim_add_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); T0_INTER_T1_USING_T1(); } //Added by Gonetz static void cc_one_sub_t1_mul_t0a_add_t0_mul_env_add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); MOD_0 (TMOD_TEX_MUL_COL); MOD_0_COL (g_gdp.env_color.total & 0xFFFFFF00); cmb.tex |= 3; cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL; cmb.tmu1_invert = 1; cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL; cmb.tmu0_fac = GR_COMBINE_FACTOR_LOCAL_ALPHA; } //Added by Gonetz static void cc__t0_inter_t1_using_t1__mul_shade_add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); T0_INTER_T1_USING_T1(); } //Added by Gonetz static void cc_t0_mul_prim_add_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); USE_T0(); } static void cc_t1_mul_prim_add_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); USE_T1(); } //Added by Gonetz static void cc_t0_mul_env_add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); SETSHADE_ENV(); CC_PRIM(); USE_T0(); } //Added by Gonetz static void cc_t1_mul_env_add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); SETSHADE_ENV(); CC_PRIM(); USE_T1(); } static void cc_t0_mul_scale_add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); SETSHADE (g_gdp.key_scale.total); CC_PRIM(); USE_T0(); } //Added by Gonetz static void cc__t0_mul_t1__mul_env_add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); SETSHADE_ENV(); CC_PRIM(); T0_MUL_T1(); } //Added by Gonetz static void cc__t0_add__t1_mul_scale__mul_env_sub_center_add_prim() { // (t1-0)*scale+t0, (env-center)*cmb+prim CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_C1SUBC2(g_gdp.env_color.total, g_gdp.key_center.total); SETSHADE_PRIM(); MOD_1 (TMOD_TEX_MUL_COL); MOD_1_COL (g_gdp.key_scale.total & 0xFFFFFF00); T0_ADD_T1(); } //Added by Gonetz static void cc__t1_sub_t0__mul_env_add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); SETSHADE_ENV(); CC_PRIM(); T1_SUB_T0(); } //Added by Gonetz static void cc_t0_mul_env_add_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); USE_T0(); } static void cc_t0_mul_shade_add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); USE_T0(); } static void cc__t0_mul_enva_add_t1__mul_shade_add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_B, 0); cmb.tex |= 3; percent = (float)g_gdp.env_color.a; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; } static void cc_t0_mul_shade_add_prima() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIMA(); USE_T0(); } static void cc_t1_mul_shade_add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); USE_T1(); } static void cc_t0_mul_shade_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); USE_T0(); } static void cc__t0_add_prim__mul_shade_add_t0() { CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, 0, GR_CMBX_B, 0); CC_PRIM(); USE_T0(); } static void cc__t0_add_prim__mul_shade_add_t1() { T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_B, 0); cmb.tex |= 3; CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_B, 0); CC_PRIM(); } static void cc__t0_add_primlod__mul_shade_add_env() { T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_B, 0); CC_PRIMLOD(); cmb.tex_ccolor = cmb.ccolor; CC_ENV(); cmb.tex |= 1; } static void cc__t0_mul_prima_add_prim_mul__shade_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, GR_CMBX_TMU_CALPHA, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.prim_color.total; cmb.tex |= 1; } //Added by Gonetz static void cc_t0_mul_shadea_add_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_LOCAL_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); USE_T0(); } static void cc_prim_mul_prima_add_prim() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_LOCAL_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); CA_PRIM(); SETSHADE_PRIM(); } static void cc_prim_mul_prima_add_t0() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); SETSHADE_PRIM(); SETSHADE_PRIMA(); USE_T0(); } static void cc_prim_mul_env_add_t0() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); SETSHADE_PRIM(); SETSHADE_ENV(); USE_T0(); } static void cc_prim_mul_shade_add_t0() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE_PRIM (); USE_T0(); } static void cc_prim_mul_shade_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); MULSHADE_PRIM (); } static void cc_env_mul_shade_add_env() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); MULSHADE_ENV (); } // ** A*B+C*D ** static void cc_t0_mul_prim_add_one_sub_prim_mul_shade() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); MULSHADE_1MPRIM(); USE_T0(); } static void cc_t0_mul_prim_add_shade_sub_env_mul_prim() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); SUBSHADE_ENV(); MULSHADE_PRIM (); USE_T0(); } static void cc_t0_mul_prim_add_shade_mul_shadea_mul_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); MULSHADE_PRIM (); MULSHADE_SHADEA(); USE_T0(); } static void cc__t0_mul_t1__mul_prim_add_prim_mul_shade() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); MULSHADE_PRIM (); CC_PRIM(); T0_MUL_T1(); } static void cc_t0_mul_env_add_prim_mul_shade() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); MULSHADE_PRIM (); CC_ENV(); USE_T0(); } static void cc_t0_mul_enva_add_prim_mul_shade() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); MULSHADE_PRIM (); CC_ENVA(); USE_T0(); } static void cc_t0_mul_shade_add_prim_mul_env() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIMMULENV(); USE_T0(); } static void cc_prim_mul_env_add_one_sub_prim_mul_shade() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); MULSHADE_1MPRIM(); CC_PRIMMULENV(); } // ** A*B*C ** static void cc_t0_mul_prim_mul_prim() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); SETSHADE_PRIM(); SETSHADE_PRIM(); USE_T0(); } static void cc_t0_mul_prim_mul_prima() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); SETSHADE_PRIM(); SETSHADE_PRIMA(); USE_T0(); } static void cc_t0_mul_enva_mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE_ENVA(); USE_T0(); } static void cc_t0_mul_primlod_mul_prim() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_COLMULBYTE (g_gdp.prim_color.total, g_gdp.primitive_lod_frac); USE_T0(); } static void cc_t0_mul_primlod_mul_shade() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE_PRIMLOD(); USE_T0(); } static void cc__t0_mul_t1__mul_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); T0_MUL_T1(); } static void cc__t1_mul_t1_add_t0__mul_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_OTHER_TEXTURE_RGB, 0, GR_CMBX_B, 0); cmb.tex |= 3; } static void cc__t0_mul_t1__mul_prima() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIMA(); T0_MUL_T1(); } static void cc__t0_mul_t1__mul_env() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_ENV(); T0_MUL_T1(); } static void cc__t0_mul_t1__mul_enva() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_ENVA(); T0_MUL_T1(); } static void cc__t0_mul_t1__mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T0_MUL_T1(); } static void cc__t0a_mul_t1__mul_prim() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); T0A_MUL_T1(); } static void cc__t0_mul_t1a__mul_shade() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T0_MUL_T1A(); } static void cc__t0a_mul_t1__mul_shade() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T0A_MUL_T1(); } static void cc_t0_mul_prim_mul_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); SETSHADE_PRIM(); SETSHADE_ENV(); // notice that setshade multiplies USE_T0(); } static void cc_t0_mul_prim_mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE_PRIM (); USE_T0(); } static void cc_t0_mul_prim_mul_shadea() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); SETSHADE_PRIM(); MULSHADE_SHADEA(); USE_T0(); } static void cc_t0_mul_prima_mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE_PRIMA(); USE_T0(); } static void cc_t1_mul__one_sub_prim_mul_shade_add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE_1MPRIM(); ADDSHADE_PRIM(); USE_T1(); } static void cc_t0_mul_one_sub_env_mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE_1MENV(); USE_T0(); } static void cc_t1_mul_prim_mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE_PRIM (); USE_T1(); } //Added by Gonetz static void cc_t0_mul_1mprim_mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE_1MPRIM(); USE_T0(); } static void cc_t0_mul_env_mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE_ENV (); USE_T0(); } static void cc_t0_mul_scale_mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE (g_gdp.key_scale.total); USE_T0(); } static void cc_t0_mul_shade_mul_shadea() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE_SHADEA(); USE_T0(); } static void cc_prim_mul_env_mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); MULSHADE_PRIM (); } static void cc_prim_mul_one_sub_env_mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_1SUBENV(); MULSHADE_PRIM (); } // ** A*B*C+D ** static void cc_t0_mul_prim_mul_shade_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); MULSHADE_PRIM (); USE_T0(); } //Added by Gonetz static void cc_t0_mul_prim_mul_shadea_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_LOCAL_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); CC_ENV(); SETSHADE_ENV(); MULSHADE_A_PRIM(); USE_T0(); } // (A*B+C)*D static void cc__t0_mul_prim_add_shade__mul_env() { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, GR_CMBX_TMU_CCOLOR, 0, GR_CMBX_B, 0); cmb.tex |= 1; cmb.tex_ccolor = g_gdp.prim_color.total; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, GR_CMBX_CONSTANT_COLOR, 0, GR_CMBX_ZERO, 0); CC_ENV(); } static void cc__t0a_mul_prim_add_t0__mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MOD_0 (TMOD_COL_MUL_TEXA_ADD_TEX); MOD_0_COL (g_gdp.prim_color.total & 0xFFFFFF00); USE_T0(); } static void cc__t0a_mul_env_add_t0__mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MOD_0 (TMOD_COL_MUL_TEXA_ADD_TEX); MOD_0_COL (g_gdp.env_color.total & 0xFFFFFF00); USE_T0(); } static void cc__prim_mul_shade_add_env__mul_shade() //Aded by Gonetz { T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); cmb.tex |= 1; cmb.tex_ccolor = g_gdp.prim_color.total; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); CC_ENV(); } // ** A*B*C+D*E ** //Added by Gonetz static void cc__t0_sub_t1__mul_prim_mul_shade_add_prim_mul_env() { T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); cmb.tex |= 3; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIMMULENV(); MULSHADE_PRIM (); } static void cc__t0_mul_prim_mul_env__add__prim_mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIMMULENV(); MULSHADE_PRIM (); USE_T0(); } static void cc__t1_mul_prim_mul_env__add__prim_mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIMMULENV(); MULSHADE_PRIM (); USE_T1(); } //Added by Gonetz static void cc_t0_mul_one_sub_prim_mul_shade_add_prim_mul_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIMMULENV(); MULSHADE_1MPRIM(); USE_T0(); } //Added by Gonetz static void cc_t0_mul_one_sub_prim_mul_shadea_add_prim_mul_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIMMULENV(); SETSHADE_1MPRIM(); MULSHADE_SHADEA(); USE_T0(); } //Added by Gonetz static void cc_t0_mul_one_sub_env_mul_shade_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); MULSHADE_1MENV(); USE_T0(); } static void cc_t0_mul_prima_mul_shade_add_prim_mul_one_sub_prima() //Aded by Gonetz { uint8_t fac; uint8_t col[3]; uint32_t rgb; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); MULSHADE_PRIMA(); USE_T0(); fac = 255 - (uint8_t)(g_gdp.prim_color.total&0xFF); col[0] = g_gdp.prim_color.r * fac; col[1] = g_gdp.prim_color.g * fac; col[2] = g_gdp.prim_color.b * fac; rgb = col[0] << 24 | col[1] << 16 | col[2] << 8 | fac; cmb.ccolor= rgb & 0xFFFFFF00; } // ** A*(1-B)+C ** static void cc_t0_mul_1menv_add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); SETSHADE_1MENV(); USE_T0(); } // ** (A+B)*C ** static void cc_t0_mul_scale_add_prim__mul_shade() //Aded by Gonetz { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_TMU_CCOLOR, 0, GR_CMBX_ZERO, 0); cmb.tex |= 1; cmb.tex_ccolor = g_gdp.key_scale.total; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); CC_PRIM(); } static void cc__t0_mul_t1_add_prim__mul_shade() //Aded by Gonetz { CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); CC_PRIM(); T0_MUL_T1(); } static void cc_t0_mul__prim_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); SETSHADE_PRIM(); ADDSHADE_ENV(); USE_T0(); } static void cc_t0_mul__prim_mul_primlod_add_env() //Aded by Gonetz { float prim_lod; // forest behind window, Dobutsu no Mori. // (prim-0)*prim_lod+env, (t1-0)*cmb+0 //actually, the game uses t0 instead of t1 here. t1 does not set at all this moment. CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); prim_lod = g_gdp.primitive_lod_frac / 65025.0f; rdp.col[0] *= g_gdp.prim_color.r * prim_lod; rdp.col[1] *= g_gdp.prim_color.g * prim_lod; rdp.col[2] *= g_gdp.prim_color.b * prim_lod; rdp.cmb_flags = CMB_SET; ADDSHADE_ENV(); USE_T0(); } // ** (A-B)*C ** static void cc__t0_mul_prim_add_shade__sub_env_mul_shade() { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, GR_CMBX_TMU_CCOLOR, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.prim_color.total; cmb.tex |= 1; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); CC_ENV(); } static void cc_t0_sub_prim_mul_shadea() //Aded by Gonetz { // * not guaranteed to work if another iterated alpha is set CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, GR_COMBINE_FACTOR_LOCAL_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); SETSHADE_PRIM(); USE_T0(); } static void cc__t0_sub_env_mul_shade__sub_prim_mul_shade() { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); cmb.tex_ccolor = g_gdp.env_color.total; cmb.tex |= 1; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ITRGB, 0); CC_PRIM(); } static void cc_t0_sub_prim_mul_shade() { CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); CC_PRIM(); USE_T0(); } static void cc__t0_mul_t1__sub_prim_mul_shade() { CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); CC_PRIM(); T0_MUL_T1(); } static void cc_t0_sub_env_mul_shade() { CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); CC_ENV(); USE_T0(); } static void cc__t0_mul_prima_add_t0__sub_center_mul_scale() { uint32_t prima = g_gdp.prim_color.a; T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_TMU_CCOLOR, 0, GR_CMBX_B, 0); cmb.tex_ccolor = (prima<<24)|(prima<<16)|(prima<<8)|prima; cmb.tex |= 1; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); cmb.ccolor= (g_gdp.key_center.total) & 0xFFFFFF00; SETSHADE(g_gdp.key_scale.total); } static void cc__t1_inter_t0_using_primlod__sub_shade_mul_prim() { CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_CONSTANT_COLOR, 0, GR_CMBX_ZERO, 0); CC_PRIM(); T1_INTER_T0_USING_FACTOR (lod_frac); } static void cc__t0_inter_t1_using_enva__sub_shade_mul_prim() { uint8_t factor = g_gdp.env_color.a; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_CONSTANT_COLOR, 0, GR_CMBX_ZERO, 0); CC_PRIM(); T0_INTER_T1_USING_FACTOR (factor); } static void cc_t0_sub_shade_mul_shadea() //Aded by Gonetz { // * not guaranteed to work if another iterated alpha is set CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, GR_COMBINE_FACTOR_LOCAL_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); USE_T0(); } static void cc_one_sub_t0_mul_prim() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_BLEND_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE); CC_PRIM(); USE_T0(); } static void cc_one_sub_prim_mul_prima() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); cmb.ccolor= (~g_gdp.prim_color.total) & 0xFFFFFF00; SETSHADE_PRIMA(); } static void cc_shade_sub_prim_mul_t0() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); USE_T0(); } static void cc_shade_sub_prim_mul_env() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); SUBSHADE_PRIM(); } static void cc_shade_sub_env_mul_t0() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); USE_T0(); } static void cc_shade_sub_prim_mul__t0_inter_t1_using_primlod() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); T0_INTER_T1_USING_FACTOR (lod_frac); } static void cc_shade_sub_env_mul__t0_inter_t1_using_primlod() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); T0_INTER_T1_USING_FACTOR (lod_frac); } static void cc_shade_sub_env_mul_prim() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); SUBSHADE_ENV(); } static void cc_shade_sub__prim_mul_prima() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_C1MULC2 (g_gdp.prim_color.total, (g_gdp.prim_color.total&0xFF)); } static void cc_one_sub__t0_mul_t1__mul_shade() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_BLEND, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); cmb.ccolor= (0) & 0xFFFFFF00; T0_MUL_T1(); } static void cc_one_sub__t0_mul_shadea__mul_shade() //Aded by Gonetz { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ITALPHA, 0, GR_CMBX_ZERO, 0); cmb.tex |= 1; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_ONE_MINUS_X, GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); } static void cc_one_sub_env_mul_t0() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_ENV(); USE_T0(); } static void cc_one_sub_env_mul__t0_inter_t1_using_primlod() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_ENV(); T0_INTER_T1_USING_FACTOR (lod_frac); } static void cc_one_sub_env_mul_prim() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); SETSHADE_PRIM(); } static void cc_one_sub_env_mul_shade() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); } // ** (1-A)*B + A*C ** static void cc_t0_mul_env_add_1mt0_mul_shade() { CCMB (GR_COMBINE_FUNCTION_BLEND, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); USE_T0(); } // ** (1-A)*B+C ** static void cc_one_sub_shade_mul__t1_sub_prim_mul_primlod_add_t0__add_shade() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T1_SUB_PRIM_MUL_PRIMLOD_ADD_T0(); } // ** (1-A)*B*C ** static void cc_one_sub_t0_mul_prim_mul_shade() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_BLEND_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_NONE); MULSHADE_PRIM (); USE_T0(); } // ** (A-B)*C*D ** static void cc_prim_sub_env_mul_t0_mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_ITERATED); MULSHADE_PRIMSUBENV(); USE_T0(); } // ** (A-B)*C+D ** static void cc_t0_sub_t1_mul_prim_mul_shade_add_t1() //Aded by Gonetz { T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, 0, GR_CMBX_B, 0); cmb.tex |= 3; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); MULSHADE_PRIM (); } static void cc_t0_sub_prim_mul_t0a_add_prim() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); USE_T0(); } static void cc_t0_sub_prim_mul_t1_add_shade() //Aded by Gonetz { T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_OTHER_TEXTURE_RGB, 0, GR_CMBX_ZERO, 0); cmb.tex |= 3; cmb.tex_ccolor = g_gdp.prim_color.total; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 1, GR_CMBX_B, 0); } static void cc_t0_sub_prim_mul_primlod_add_prim() //Aded by Gonetz { CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_CONSTANT_COLOR, 0, GR_CMBX_B, 0); SETSHADE_PRIM(); CC_PRIMLOD(); USE_T0(); } static void cc_t0_sub_prim_mul_prima_add_prim() //Aded by Gonetz { // * not guaranteed to work if another iterated alpha is set CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); SETSHADE_PRIM(); SETSHADE_1MPRIMA(); CC_PRIMA(); USE_T0(); } static void cc_t0_sub_prim_mul_shadea_add_prim() //Aded by Gonetz { // * not guaranteed to work if another iterated alpha is set CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_LOCAL_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); SETSHADE_PRIM(); USE_T0(); } static void cc_t0_sub_prim_mul_env_add_shade() //Aded by Gonetz { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); cmb.tex |= 1; cmb.tex_ccolor = g_gdp.prim_color.total; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, GR_CMBX_CONSTANT_COLOR, 0, GR_CMBX_B, 0); CC_ENV(); } static void cc__t0_inter_t1_using_shadea__sub_prim_mul_env_add_shade() //Aded by Gonetz { CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, GR_CMBX_CONSTANT_COLOR, 0, GR_CMBX_B, 0); //have to pass shade alpha to combiner ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_ZERO, 0); CC_ENV(); SUBSHADE_PRIMMULENV(); T0_INTER_T1_USING_SHADEA(); } static void cc_t0_sub_prim_mul_env_add_prim() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); SETSHADE_PRIM(); SETSHADE_1MENV(); USE_T0(); } static void cc_t0_sub_prim_mul_enva_add_prim() //Aded by Gonetz41 { CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_CONSTANT_COLOR, 0, GR_CMBX_B, 0); SETSHADE_PRIM(); CC_ENVA(); USE_T0(); } static void cc_t0_sub_prim_mul_primlod_add_env() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_ENV(); MOD_0 (TMOD_TEX_SUB_COL_MUL_FAC); MOD_0_COL (g_gdp.prim_color.total & 0xFFFFFF00); MOD_0_FAC (lod_frac & 0xFF); USE_T0(); } static void cc_t0_sub__prim_mul_env() //Aded by Gonetz { if ( (g_gdp.prim_color.total & 0xFFFFFF00) == 0xFFFFFF00 && (g_gdp.env_color.total & 0xFFFFFF00) == 0xFFFFFF00) { CCMB (GR_COMBINE_FUNCTION_BLEND_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE); CC_PRIM(); } else { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); SETSHADE_PRIM(); SETSHADE_ENV(); } USE_T0(); } static void cc__t0_mul_t1__sub_prim_mul__t0t1a__add_prim() //Aded by Gonetz { // * not guaranteed to work if another iterated alpha is set CCMB (GR_COMBINE_FUNCTION_BLEND, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); T0_MUL_T1(); A_T0_MUL_T1(); } static void cc__t1_inter_t0_using_enva__sub_prim_mul_prima_add_prim() //Aded by Gonetz { uint8_t factor = g_gdp.env_color.a; // * not guaranteed to work if another iterated alpha is set CCMB (GR_COMBINE_FUNCTION_BLEND, GR_COMBINE_FACTOR_LOCAL_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); CA_PRIM(); T1_INTER_T0_USING_FACTOR (factor); } static void cc_t0_sub_prim_mul_shade_add_env() { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); cmb.tex |= 1; cmb.tex_ccolor = g_gdp.prim_color.total; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_B, 0); CC_ENV(); } static void cc_t1_sub_prim_mul_shade_add_env() { T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); cmb.tex |= 2; cmb.tex_ccolor = g_gdp.prim_color.total; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_B, 0); CC_ENV(); } static void cc_t1_sub_k4_mul_prima_add_t0() { T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_DETAIL_FACTOR, 1, GR_CMBX_ZERO, 0); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); cmb.tex |= 3; CC_BYTE (g_gdp.k4); cmb.tex_ccolor = cmb.ccolor; percent = (float)g_gdp.prim_color.a; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; CCMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_CONSTANT_COLOR, 0, GR_CMBX_B, 0); } static void cc__t0_sub_prim_mul_shade_add_env__mul_shade() { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); cmb.tex |= 1; cmb.tex_ccolor = g_gdp.prim_color.total; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); CC_ENV(); } static void cc__t0_sub_prim_mul_shade_add_env__mul_shadea() { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); cmb.tex |= 1; cmb.tex_ccolor = g_gdp.prim_color.total; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, 0, GR_CMBX_ZERO, 0); CC_ENV(); } static void cc__t0_mul_shade__sub_env_mul_shadea_add_env() //Aded by Gonetz { if (g_gdp.tile[rdp.cur_tile].format == 4) { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_OTHER_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); } else if (g_gdp.tile[rdp.cur_tile].format == 2) { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); USE_T0(); } else { cc_t0(); } } static void cc_t0_sub_env_mul_k5_add_prim() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); MOD_0 (TMOD_TEX_SUB_COL_MUL_FAC); MOD_0_COL (g_gdp.env_color.total & 0xFFFFFF00); MOD_0_FAC (g_gdp.k5); USE_T0(); } static void cc_t0_sub_k4_mul_k5_add_t0(void) //Aded by Gonetz { uint32_t temp; CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, 0, GR_CMBX_B, 0); temp = g_gdp.primitive_lod_frac; g_gdp.primitive_lod_frac = g_gdp.k4; SETSHADE_PRIMLOD(); g_gdp.primitive_lod_frac = temp; CC_K5(); USE_T0(); } static void cc__t0_inter_t1_using_t0__sub_shade_mul_prima_add_shade() //Aded by Gonetz { cmb.tex |= 3; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_CONSTANT_COLOR, 0, GR_CMBX_B, 0); CC_PRIMA(); T0_INTER_T1_USING_T0(); } static void cc_t0_sub__prim_mul_shade__mul_enva_add__prim_mul_shade() //Aded by Gonetz { // * not guaranteed to work if another iterated alpha is set CCMB (GR_COMBINE_FUNCTION_BLEND, GR_COMBINE_FACTOR_LOCAL_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE_PRIM (); SETSHADE_A_ENV(); USE_T0(); } static void cc_t0_sub_env_mul_t0_add_env() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_BLEND, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_ENV(); USE_T0(); //(t0-env)*t0+env = t0*t0 + (1-t0)*env } static void cc_t0_sub_env_mul_prima_add_env() //Aded by Gonetz { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_B, 0); cmb.tex |= 1; percent = (float)g_gdp.prim_color.a; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); } static void cc_t0_sub_env_mul_k5_add_env() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_BLEND, GR_COMBINE_FACTOR_LOCAL_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); cmb.ccolor = (g_gdp.env_color.total&0xFFFFFF00) | g_gdp.k5; USE_T0(); } static void cc_t0_sub_env_mul_prim_add_shade() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); MOD_0 (TMOD_TEX_SUB_COL); MOD_0_COL (g_gdp.env_color.total & 0xFFFFFF00); USE_T0(); } static void cc_t0_sub_env_mul_shade_add_prim() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); cmb.tex |= 1; cmb.tex_ccolor = g_gdp.env_color.total; } static void cc__t0_sub_t1_mul_enva_add_shade__sub_env_mul_prim() // (t0-t1)*env_a+shade, (cmb-env)*prim+0 { T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_TMU_CCOLOR, 0, GR_CMBX_ITRGB, 0); cmb.tex |= 3; CC_COLMULBYTE(g_gdp.prim_color.total, (g_gdp.env_color.total&0xFF)); cmb.tex_ccolor = cmb.ccolor; CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 1, GR_CMBX_TEXTURE_RGB, 0); MULSHADE_PRIM (); CC_PRIMMULENV(); } static void cc__t0_inter_t1_using_primlod__sub_env_mul_shade_add_prim() //Aded by Gonetz { if (!(g_gdp.env_color.total&0xFFFFFF00)) { cc__t0_inter_t1_using_primlod__mul_shade_add_prim(); return; } if (!(g_gdp.prim_color.total&0xFFFFFF00)) { CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); CC_ENV(); T0_INTER_T1_USING_FACTOR (lod_frac); return; } cc__t0_inter_t1_using_primlod__mul_shade_add_prim(); } static void cc__t0_sub_env_mul_shade_add_prim__mul_shade() //Aded by Gonetz { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); cmb.tex_ccolor = g_gdp.env_color.total; cmb.tex |= 1; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); CC_PRIM(); } static void cc__t0_sub_env_mul_shade_add_prim__mul_shadea() //Aded by Gonetz { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.prim_color.total; cmb.tex |= 1; MOD_0 (TMOD_TEX_SUB_COL); MOD_0_COL (g_gdp.env_color.total & 0xFFFFFF00); CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, GR_CMBX_ITALPHA, 0, GR_CMBX_ZERO, 0); } static void cc__t0_inter_t1_using_primlod__sub_env_mul_shade_add_env() { // (t1-t0)*primlod+t0, (cmb-env)*shade+env CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, 0, GR_CMBX_B, 0); CC_ENV(); T0_INTER_T1_USING_FACTOR (lod_frac); } static void cc_t0_sub_env_mul_enva_add_prim() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); MOD_0 (TMOD_TEX_SUB_COL_MUL_FAC); MOD_0_COL (g_gdp.env_color.total & 0xFFFFFF00); MOD_0_FAC (g_gdp.env_color.total & 0xFF); USE_T0(); } static void cc_one_sub_t0_mul_prim_add_t0() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); USE_T0(); //(1-t)*prim+t == (1-prim)*t+prim } static void cc_one_sub_t1_mul_prim_add_t1() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); USE_T1(); //(1-t)*prim+t == (1-prim)*t+prim } static void cc_one_sub_t1_mul_env_add_t1() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_ENV(); USE_T1(); //(1-t)*env+t == (1-env)*t+env } static void cc_one_sub_t0_mul_primlod_add_t0() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIMLOD(); USE_T0(); //(1-t)*primlod+t == (1-primlod)*t+primlod } static void cc_one_sub_t0_mul_prima_add_t0() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); USE_T0(); //(1-t)*prima+t == (1-prima)*t+prima } static void cc_one_sub__t0_inter_t1_using_enva__mul_prim_add__t0_inter_t1_using_enva() //Aded by Gonetz { uint8_t factor = g_gdp.env_color.a; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); T0_INTER_T1_USING_FACTOR (factor); //(1-t)*prim+t == (1-prim)*t+prim } static void cc_one_sub_t0_mul_shade_add_t0() { CCMB (GR_COMBINE_FUNCTION_BLEND, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); cmb.ccolor= (0xFFFFFFFF) & 0xFFFFFF00; USE_T0(); } static void cc_one_sub_prim_mul_t0_add_prim() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); USE_T0(); } static void cc_one_sub_prim_mul_t0a_add_prim() { CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_ONE_MINUS_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_ZERO, GR_CMBX_TEXTURE_ALPHA, 0, GR_CMBX_B, 0); CC_PRIM(); USE_T0(); } static void cc_one_sub_prim_mul__t0_inter_t1_using_primlod__add_prim() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); T0_INTER_T1_USING_FACTOR (lod_frac); } static void cc__one_sub_prim_mul_shade__mul_t0_add__prim_mul_shade() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE_PRIM(); USE_T0(); } static void cc_one_sub_shade_mul__t0_inter_t1_using_primlod__add_shade() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T0_INTER_T1_USING_FACTOR (lod_frac); } static void cc_one_sub_prim_mul_t1_add_prim() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); USE_T1(); } static void cc_one_sub_prim_mul_env_add_prim() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); SETSHADE_ENV(); } static void cc_t0_sub_prim_mul_shade_add_shade() //Aded by Gonetz { CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ITRGB, 0); CC_PRIM(); USE_T0(); } static void cc__t0_mul_t0__sub_prim_mul_shade_add_shade() //Aded by Gonetz { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, 0, GR_CMBX_ZERO, 0); cmb.tex |= 1; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ITRGB, 0); CC_PRIM(); } static void cc__t0_mul_t1__sub_prim_mul_shade_add_shade() //Aded by Gonetz { CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ITRGB, 0); CC_PRIM(); T0_MUL_T1(); } static void cc__t0_mul_t1__sub_env_mul_shade_add_shade() //Aded by Gonetz { CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ITRGB, 0); CC_ENV(); T0_MUL_T1(); } static void cc_one_sub_prim_mul_shade_add_shade() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_1SUBPRIM(); } static void cc_t0_inter_env_using_prima() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); USE_T0(); MOD_0 (TMOD_TEX_INTER_COLOR_USING_FACTOR); MOD_0_COL (g_gdp.env_color.total & 0xFFFFFF00); MOD_0_FAC (g_gdp.prim_color.total & 0xFF); } static void cc_t0_inter_env_using_enva() { //(env-t0)*env_a+t0 CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_TMU_CALPHA, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.env_color.total; cmb.tex |= 1; } static void cc_t0_inter_noise_using_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); USE_T0(); MOD_0 (TMOD_TEX_INTER_NOISE_USING_COL); MOD_0_COL (g_gdp.prim_color.total); rdp.noise = NOISE_MODE_TEXTURE; } static void cc_t0_inter_noise_using_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); USE_T0(); MOD_0 (TMOD_TEX_INTER_NOISE_USING_COL); MOD_0_COL (g_gdp.env_color.total); rdp.noise = NOISE_MODE_TEXTURE; } static void cc_t0_sub_env_mul_enva_add_env() { CCMB (GR_COMBINE_FUNCTION_BLEND, GR_COMBINE_FACTOR_LOCAL_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_ENV(); CA_ENV(); USE_T0(); } //Added by Gonetz static void cc_one_sub_prim_mul__t0_mul_t1__add__prim_mul_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_1SUBPRIM(); SETSHADE_PRIM(); SETSHADE_ENV(); T0_MUL_T1(); } //Added by Gonetz static void cc_one_sub_prim_mul__t0_mul_t1__add__prim_mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_1SUBPRIM(); MULSHADE_PRIM(); T0_MUL_T1(); } //Added by Gonetz static void cc_one_sub_prim_mul__t0_inter_t1_using_enva__add_prim() { uint8_t factor = g_gdp.env_color.a; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_1SUBPRIM(); SETSHADE_PRIM(); T0_INTER_T1_USING_FACTOR (factor); } static void cc_one_sub_env_mul__t0_inter_t1_using_primlod__add_env() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_ENV(); T0_INTER_T1_USING_FACTOR (lod_frac); } static void cc_one_sub_env_mul__t1_sub_prim_mul_primlod_add_t0__add_env() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_ENV(); T1_SUB_PRIM_MUL_PRIMLOD_ADD_T0(); } static void cc_one_sub_env_mul_t0_add_prim_mul_env() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_1SUBENV(); SETSHADE_PRIM(); SETSHADE_ENV(); USE_T0(); } static void cc_one_sub_env_mul_t0_add_env() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_ENV(); USE_T0(); } static void cc_one_sub_env_mul_t0_add_shade() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_1SUBENV(); USE_T0(); } static void cc_one_sub_env_mul_prim_add_env() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); SETSHADE_PRIM(); } static void cc_one_sub_env_mul_prim_add_shade() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_1SUBENV(); CC_C1MULC2 (g_gdp.prim_color.total, cmb.ccolor); } static void cc_one_sub_env_mul_shade_add_env() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); } static void cc_one_sub_env_mul_prim_add__t0_inter_t1_using_env() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); SETSHADE_PRIM(); SETSHADE_1MENV(); T0_INTER_T1_USING_ENV(); } static void cc_one_sub_shade_mul_t0_add_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); USE_T0(); } static void cc_one_sub_shade_mul__t0_mul_shadea__add_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, 0, GR_CMBX_ZERO, 0); cmb.tex |= 1; } static void cc_one_sub_shade_mul_env_add_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); } static void cc_one_sub_shade_mul_shadea_add_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_LOCAL_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); cmb.ccolor= (0xFFFFFFFF) & 0xFFFFFF00; } ///* static void cc_t0_sub_env_mul_prim_add_env() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); SETSHADE_1MPRIM(); SETSHADE_ENV(); CC_PRIM(); USE_T0(); //(t0-env)*prim+env == t0*prim + env*(1-prim) } //*/ static void cc__t0_inter_t1_using_t1a__sub_env_mul_enva_add_env() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_BLEND, GR_COMBINE_FACTOR_LOCAL_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); cmb.ccolor = g_gdp.env_color.total; T0_INTER_T1_USING_T1A(); } static void cc_t0_sub_shade_mul_t0a_add_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); USE_T0(); A_USE_T0(); } static void cc_t0_sub_shade_mul_prima_add_shade() //Aded by Gonetz { // * not guaranteed to work if another iterated alpha is set CCMB (GR_COMBINE_FUNCTION_BLEND, GR_COMBINE_FACTOR_LOCAL_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); SETSHADE_A_PRIM(); USE_T0(); } static void cc_t0_sub_shade_mul_shadea_add_shade() //Aded by Gonetz { // * not guaranteed to work if another iterated alpha is set CCMB (GR_COMBINE_FUNCTION_BLEND, GR_COMBINE_FACTOR_LOCAL_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); USE_T0(); } static void cc__t0_mul_t1_add_env__mul_shadea_add_shade() { T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.env_color.total; cmb.tex |= 3; // * not guaranteed to work if another iterated alpha is set CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_LOCAL_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); } static void cc_prim_sub_t0_mul_env_add_t0() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_1SUBENV(); SETSHADE_PRIM(); SETSHADE_ENV(); USE_T0(); //(prim-t0)*env+t0 == prim*env + t0*(1-env) } static void cc_prim_sub_t0_mul_t1_add_t0() //Aded by Gonetz { T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_OTHER_TEXTURE_RGB, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.prim_color.total; cmb.tex |= 3; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); } static void cc_env_sub_t0_mul_prim_add_t0() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_1SUBPRIM(); SETSHADE_PRIM(); SETSHADE_ENV(); USE_T0(); //(env-t0)*prim+t0 == prim*env + t0*(1-prim) } static void cc_env_sub_t0_mul_shade_add_t0() //Aded by Gonetz { CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, 0, GR_CMBX_B, 0); CC_ENV(); USE_T0(); } static void cc_prim_sub_env_mul_t0_add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); SETSHADE_PRIMSUBENV(); USE_T0(); } static void cc_prim_sub_env_mul_t0_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); SETSHADE_ENV(); USE_T0(); } static void cc__prim_sub_env_mul_t0_add_env__add_primlod() { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.env_color.total; cmb.tex |= 1; SETSHADE_PRIMSUBENV(); CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 1, GR_CMBX_TEXTURE_RGB, 0); CC_PRIMLOD(); } static void cc__prim_sub_env_mul_t0_add_env__add_shadea() { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.env_color.total; cmb.tex |= 1; SETSHADE_PRIMSUBENV(); CCMBEXT(GR_CMBX_ITALPHA, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 1, GR_CMBX_TEXTURE_RGB, 0); } static void cc_prim_sub_env_mul__t0_mul_t1a__add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); SETSHADE_ENV(); T0_MUL_T1A(); } static void cc_prim_sub_env_mul__t0_mul_prim__add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); SETSHADE_ENV(); T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_TMU_CCOLOR, 0, GR_CMBX_ZERO, 0); cmb.tex_ccolor = g_gdp.prim_color.total; cmb.tex |= 1; } static void cc_prim_sub_env_mul_t0_mul_shade_add_env() { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_TMU_CCOLOR, 0, GR_CMBX_ZERO, 0); CC_PRIMSUBENV(); cmb.tex_ccolor = cmb.ccolor; cmb.tex |= 1; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); } static void cc_prim_sub_env_mul__t0_sub_t0_mul_prima__add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); SETSHADE_ENV(); cmb.tex |= 1; cmb.tmu0_func = GR_COMBINE_FUNCTION_BLEND_LOCAL; cmb.tmu0_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR; percent = (float)g_gdp.prim_color.a; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; } static void cc_prim_sub_env_mul__one_sub_t0_mul_primlod_add_prim__add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); SETSHADE_PRIM(); T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ONE_MINUS_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.prim_color.total; cmb.tex |= 1; cmb.dc0_detailmax = cmb.dc1_detailmax = lod_frac / 255.0f; } static void cc_prim_sub_env_mul__t0_add_t1a__add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); SETSHADE_ENV(); cmb.tex |= 3; cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL_ALPHA; cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL; cmb.tmu0_fac = GR_COMBINE_FACTOR_ONE; } static void cc_prim_sub_env_mul__t0_sub_prim_mul_enva_add_t0__add_env() { // (t0-prim)*env_a+t0, (prim-env)*cmb+env CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); SETSHADE_PRIM(); USE_T0(); MOD_0 (TMOD_TEX_SUB_COL_MUL_FAC_ADD_TEX); MOD_0_COL (g_gdp.prim_color.total & 0xFFFFFF00); MOD_0_FAC (g_gdp.env_color.total & 0xFF); } static void cc_prim_sub_env_mul__t1_sub_prim_mul_enva_add_t0__add_env() { //(t1-prim)*env_a+t0, (prim-env)*cmb+env CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); SETSHADE_PRIM(); if (g_gdp.tile[rdp.cur_tile].format > 2) { T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); } else { T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_ZERO, 0); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); } cmb.tex_ccolor = g_gdp.prim_color.total; cmb.tex |= 3; cmb.dc0_detailmax = cmb.dc1_detailmax = (g_gdp.env_color.total&0xFF) / 255.0f; } static void cc_prim_sub_env_mul__t1_sub_prim_mul_prima_add_t0__add_env() { // (t1-prim)*prim_a+t0, (prim-env)*cmb+env CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); SETSHADE_PRIM(); T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.prim_color.total; cmb.tex |= 3; cmb.dc0_detailmax = cmb.dc1_detailmax = (g_gdp.prim_color.total&0xFF) / 255.0f; } static void cc__prim_sub_env_mul_t0_add_env__mul_primlod() { float factor; uint8_t r, g, b; CCMB (GR_COMBINE_FUNCTION_BLEND, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); factor = g_gdp.primitive_lod_frac / 255.0f; r = (uint8_t)((uint8_t)g_gdp.prim_color.r * factor); g = (uint8_t)((uint8_t)g_gdp.prim_color.g * factor); b = (uint8_t)((uint8_t)g_gdp.prim_color.b * factor); cmb.ccolor = (r << 24) | (g << 16) | (b << 8); SETSHADE_ENV(); MULSHADE_PRIMLOD(); USE_T0(); } static void cc__prim_sub_env_mul_t0_add_env__mul_k5() { float factor; uint8_t r, g, b; CCMB (GR_COMBINE_FUNCTION_BLEND, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); factor = g_gdp.k5 / 255.0f; r = (uint8_t)((uint8_t)g_gdp.prim_color.r * factor); g = (uint8_t)((uint8_t)g_gdp.prim_color.g * factor); b = (uint8_t)((uint8_t)g_gdp.prim_color.b * factor); cmb.ccolor= (r << 24) | (g << 16) | (b << 8); SETSHADE_ENV(); MULSHADE_K5(); USE_T0(); } static void cc_prim_sub_env_mul_t1_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); SETSHADE_ENV(); if (((rdp.othermode_h & RDP_CYCLE_TYPE) >> 20) == G_CYC_1CYCLE || ((settings.hacks&hack_KI) && (rdp.cycle2 & 0x0FFFFFFF) == 0x01FF1FFF)) { USE_T0(); } else { USE_T1(); } } static void cc_prim_sub_env_mul_t1_add_env_mul_t0() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); MOD_1 (TMOD_COL_INTER_COL1_USING_TEX); MOD_1_COL (g_gdp.env_color.total & 0xFFFFFF00); MOD_1_COL1 (g_gdp.prim_color.total & 0xFFFFFF00); T0_MUL_T1(); } static void cc_prim_sub_env_mul_t0a_add_t0() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); CC_PRIMSUBENV(); T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0, GR_CMBX_B, 0); cmb.tex_ccolor = cmb.ccolor; cmb.tex |= 1; } //Added by Gonetz static void cc_prim_sub_env_mul_t0a_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); SETSHADE_PRIM(); USE_T0(); } //Added by Gonetz static void cc_prim_sub_env_mul_t1a_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); SETSHADE_PRIM(); USE_T1(); } //Added by Gonetz static void cc_prim_sub_env_mul__t0_mul_t1__add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); SETSHADE_ENV(); T0_MUL_T1(); } //Added by Gonetz static void cc_prim_sub_env_mul__t0_add_t1__add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); SETSHADE_ENV(); T0_ADD_T1(); } //Added by Gonetz static void cc_prim_sub_env_mul__t0_mul_enva__add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); SETSHADE_PRIMSUBENV(); SETSHADE_ENVA(); USE_T0(); } //Added by Gonetz static void cc_prim_sub_env_mul__t0_mul_shade__add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); MULSHADE_PRIMSUBENV(); USE_T0(); } //Added by Gonetz static void cc_prim_sub_env_mul__prim_inter_t0_using_shadea__add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); SETSHADE_PRIM(); PRIM_INTER_T0_USING_SHADEA(); } //Added by Gonetz static void cc_prim_sub_env_mul__t0_sub_prim_mul_primlod_add_t0__add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); SETSHADE_ENV(); T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.prim_color.total; cmb.tex |= 1; percent = lod_frac / 255.0f; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; } static void cc_prim_sub_env_mul__t0_sub_prim_mul_primlod_add_shade__add_env() { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_ITRGB, 0); CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_TEXTURE_RGB, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.prim_color.total; CC_PRIM(); SETSHADE_ENV(); cmb.tex |= 1; percent = lod_frac / 255.0f; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; } static void cc_prim_sub_env_mul__t0_sub_shade_mul_primlod_add_shade__add_env() { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_B, 0); CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_TEXTURE_RGB, 0, GR_CMBX_B, 0); CC_PRIM(); SETSHADE_ENV(); cmb.tex |= 1; percent = lod_frac / 255.0f; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; } //Added by Gonetz static void cc_lavatex_sub_prim_mul_shade_add_lavatex() { CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, 0, GR_CMBX_B, 0); CC_PRIM(); T0_SUB_PRIM_MUL_PRIMLOD_ADD_T1(); } //Added by Gonetz static void cc_prim_sub_env_mul__t0_sub_prim_mul_primlod_add_t1__add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); SETSHADE_ENV(); T0_SUB_PRIM_MUL_PRIMLOD_ADD_T1(); } //Added by Gonetz static void cc_prim_sub_env_mul__t1_sub_prim_mul_primlod_add_t0__add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); SETSHADE_ENV(); T1_SUB_PRIM_MUL_PRIMLOD_ADD_T0(); } //Added by Gonetz static void cc_prim_sub_env_mul__t0_inter_t1_using_t1__add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); SETSHADE_ENV(); T0_INTER_T1_USING_T1(); } //Added by Gonetz static void cc_prim_sub_env_mul__t0_inter_t1_using_enva_alpha__add_env() { uint8_t factor = g_gdp.env_color.a; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); SETSHADE_ENV(); T0_INTER_T1_USING_FACTOR (factor); A_T0_INTER_T1_USING_FACTOR (factor); } //Added by Gonetz static void cc__env_inter_prim_using_t0__sub_shade_mul_t0a_add_shade() { uint32_t pse; T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_B, 0); CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_TEXTURE_ALPHA, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.env_color.total; cmb.tex |= 1; pse = (g_gdp.prim_color.total>>24) - (g_gdp.env_color.total>>24); percent = pse / 255.0f; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; } //Added by Gonetz static void cc_prim_sub_env_mul_shade_add_t0() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE_PRIMSUBENV(); USE_T0(); } //Added by Gonetz static void cc_prim_sub_env_mul_prima_add_t0() { if (g_gdp.prim_color.total != 0x000000ff) { CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_CONSTANT_ALPHA, 0, GR_CMBX_TEXTURE_RGB, 0); CC_PRIM(); SETSHADE_ENV(); } else if ((g_gdp.prim_color.total&0xFFFFFF00) - (g_gdp.env_color.total&0xFFFFFF00) == 0) { cc_t0(); return; } else { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_ENV(); } USE_T0(); } //Added by Gonetz static void cc_prim_sub_env_mul_shade_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); MULSHADE_PRIMSUBENV(); } static void cc_prim_sub_env_mul_shadea_add_env() { // * not guaranteed to work if another iterated alpha is set CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_OTHER_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); SETSHADE_PRIM(); } //Added by Gonetz static void cc_prim_sub_env_mul__t0_inter_t1_using_prima__add_env() { uint8_t factor = g_gdp.prim_color.a; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); SETSHADE_PRIM(); T0_INTER_T1_USING_FACTOR (factor); } //Added by Gonetz static void cc_prim_sub_env_mul__t1_inter_t0_using_prima__add_env() { uint8_t factor = g_gdp.prim_color.a; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); SETSHADE_PRIM(); T1_INTER_T0_USING_FACTOR (factor); } static void cc_prim_sub_env_mul__t0_inter_t1_using_enva__add_env() { uint8_t factor = g_gdp.env_color.a; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); SETSHADE_PRIM(); T0_INTER_T1_USING_FACTOR (factor); } static void cc_prim_sub_center_mul__t0_inter_t1_using_enva__add_env() { uint8_t factor = g_gdp.env_color.a; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_C1SUBC2 (g_gdp.prim_color.total, g_gdp.key_center.total); SETSHADE_ENV(); T0_INTER_T1_USING_FACTOR (factor); } static void cc_prim_sub_env_mul__t1_inter_t0_using_enva__add_env() { uint8_t factor = g_gdp.env_color.a; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); SETSHADE_PRIM(); T1_INTER_T0_USING_FACTOR (factor); } static void cc_prim_sub_env_mul__t0_mul_enva_add_t1__add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); SETSHADE_PRIM(); T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_B, 0); cmb.tex |= 3; percent = (float)g_gdp.env_color.a; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; } static void cc_prim_sub_env_mul__t1_mul_enva_add_t0__add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); SETSHADE_PRIM(); T1_MUL_ENVA_ADD_T0(); } //Added by Gonetz static void cc_prim_sub_env_mul_primlod_add__t0_inter_t1_using_primlod() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIMSUBENV(); CC_COLMULBYTE(cmb.ccolor, g_gdp.primitive_lod_frac); T0_INTER_T1_USING_FACTOR (lod_frac); } static void cc_prim_sub_env_mul__t0_inter_t1_using_primlod__add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); SETSHADE_PRIM(); T0_INTER_T1_USING_FACTOR (lod_frac); } static void cc_prim_sub_env_mul__t1_inter_t0_using_primlod__add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); SETSHADE_PRIM(); T1_INTER_T0_USING_FACTOR (lod_frac); } static void cc_prim_sub_env_mul__t1_mul_primlod_add_t0__add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); SETSHADE_PRIM(); T1_MUL_PRIMLOD_ADD_T0(); } static void cc_prim_sub_env_mul__t1_sub_prim_mul_t0_add_t0__add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); SETSHADE_PRIM(); T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.prim_color.total; cmb.tex |= 3; } //Added by Gonetz static void cc__prim_sub_env_mul_prim_add_t0__mul_prim() { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_X, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); cmb.tex |= 1; SETSHADE_PRIMSUBENV(); SETSHADE_PRIM(); CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, GR_CMBX_CONSTANT_COLOR, 0, GR_CMBX_ZERO, 0); CC_PRIM() ; } //Added by Gonetz static void cc_prim_sub_env_mul_prim_add_env() { CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_CONSTANT_COLOR, 0, GR_CMBX_B, 0); SETSHADE_ENV(); CC_PRIM(); } static void cc_prim_sub_env_mul_primlod_add_env() { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); cmb.tex |= 1; CC_PRIMLOD(); cmb.tex_ccolor = cmb.ccolor; CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_TEXTURE_RGB, 0, GR_CMBX_B, 0); SETSHADE_PRIM(); CC_ENV(); } //Added by Gonetz static void cc_prim_sub_env_mul_enva_add_t0() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); SETSHADE_PRIMSUBENV(); SETSHADE_ENVA(); USE_T0(); } static void cc_prim_sub_env_mul_enva_add_env() { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); cmb.tex |= 1; CC_ENVA(); cmb.tex_ccolor = cmb.ccolor; CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_TEXTURE_RGB, 0, GR_CMBX_B, 0); SETSHADE_PRIM(); CC_ENV(); } //Added by Gonetz static void cc_prim_sub_shade_mul_t0_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); COLSUBSHADE_PRIM(); USE_T0(); } //Added by Gonetz static void cc_prim_sub_shade_mul__t1_sub_prim_mul_primlod_add_t0__add_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); T1_SUB_PRIM_MUL_PRIMLOD_ADD_T0(); } static void cc_prim_sub_shade_mul_t1a_add_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); USE_T1(); } //Added by Gonetz static void cc_prim_sub_shade_mul_t0_add_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); USE_T0(); } //Added by Gonetz static void cc_prim_sub_shade_mul_t1_add_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); USE_T1(); } //Added by Gonetz static void cc_prim_sub_shade_mul__t0a_mul_t1__add_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); T0A_MUL_T1(); } //Added by Gonetz static void cc_prim_sub_shade_mul__t0_inter_t1_using_enva__add_shade() { uint8_t factor = g_gdp.env_color.a; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); T0_INTER_T1_USING_FACTOR (factor); } //Added by Gonetz static void cc_prim_sub_shade_mul__t0_inter_t1_using_shadea__add_shade() { CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_TEXTURE_RGB, 0, GR_CMBX_B, 0); CC_PRIM(); T0_INTER_T1_USING_SHADEA(); } //Added by Gonetz static void cc_prim_sub_shade_mul_prima_add_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_OTHER_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); CA_PRIM(); } //Added by Gonetz static void cc_prim_sub_shade_mul_env_add_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIMMULENV(); MULSHADE_1MENV(); } //Added by Gonetz static void cc_prim_sub_shade_mul_shadea_add_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_LOCAL_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); } static void cc_env_sub_prim_mul_t0_add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); SETSHADE_PRIM(); USE_T0(); } static void cc_env_sub_prim_mul_t1_add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); SETSHADE_PRIM(); USE_T1(); } static void cc_env_sub_prim_mul_t0a_add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); SETSHADE_PRIM(); A_USE_T0(); } static void cc_env_sub_prim_mul_t1a_add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); SETSHADE_PRIM(); A_USE_T1(); } static void cc_env_sub_prim_mul__t0_add_t1__add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); SETSHADE_PRIM(); T0_ADD_T1(); } static void cc_env_sub_prim_mul__t0_mul_t1__add_prim() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); SETSHADE_PRIM(); T0_MUL_T1(); } static void cc_env_sub_prim_mul__t0t1a__add_prim() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); SETSHADE_PRIM(); A_T0_MUL_T1(); } static void cc_env_sub_prim_mul__t0_inter_t1_using_t1__add_prim() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); SETSHADE_PRIM(); T0_INTER_T1_USING_T1(); } static void cc_env_sub_prim_mul__t0_inter_t1_using_half__add_prim() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); SETSHADE_PRIM(); T0_INTER_T1_USING_FACTOR (0x7F); } static void cc_env_sub_prim_mul__t1_inter_t0_using_t0__add_prim() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); SETSHADE_PRIM(); T1_INTER_T0_USING_T0(); } static void cc_env_sub_shade_mul__t0_mul_t1__add_shade() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); T0_MUL_T1(); } static void cc_env_sub_prim_mul__t0a_mul_t1a__add_prim() { CCMB (GR_COMBINE_FUNCTION_BLEND, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); SETSHADE_ENV(); A_T0_MUL_T1(); } static void cc_env_sub_prim_mul_prima_add_prim() //Aded by Gonetz { // * not guaranteed to work if another iterated alpha is set CCMB (GR_COMBINE_FUNCTION_BLEND, GR_COMBINE_FACTOR_LOCAL_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); CA_PRIM(); SETSHADE_ENV(); } static void cc_env_sub_prim_mul_enva_add_prim() //Aded by Gonetz { // * not guaranteed to work if another iterated alpha is set CCMB (GR_COMBINE_FUNCTION_BLEND, GR_COMBINE_FACTOR_OTHER_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); CA_ENV(); SETSHADE_PRIM(); } static void cc__t0_sub_env_mul_shade__sub_prim_mul_shade_add_prim() { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); cmb.tex_ccolor = g_gdp.env_color.total; cmb.tex |= 1; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, 0, GR_CMBX_B, 0); CC_PRIM(); } static void cc_env_sub_prim_mul_shade_add_prim() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); MULSHADE_ENVSUBPRIM(); } static void cc_env_sub_prim_mul_shadea_add_prim() //Added by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); SETSHADE_ENVSUBPRIM(); MULSHADE_SHADEA(); } static void cc_env_sub_prim_mul__t0_inter_t1_using_prima__add_prim() { uint8_t factor = g_gdp.prim_color.a; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); SETSHADE_PRIM(); T0_INTER_T1_USING_FACTOR (factor); } static void cc_env_sub_prim_mul__t0_inter_t1_using_primlod__add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); SETSHADE_PRIM(); T0_INTER_T1_USING_FACTOR (lod_frac); } static void cc_env_sub_primshade_mul_t0_add_primshade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); MULSHADE_PRIM(); USE_T0(); } static void cc_env_sub_primshade_mul_t1_add_primshade() { // cc_prim_mul_shade(); // return; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); MULSHADE_PRIM(); USE_T0(); } static void cc_env_sub_shade_mul_t0_add_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); USE_T0(); } static void cc__env_sub_shade_mul_t0_add_shade__mul_prim() { T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_LOCAL_TEXTURE_RGB, 0, GR_CMBX_B, 0); cmb.tex |= 1; cmb.tex_ccolor = g_gdp.prim_color.total; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, GR_CMBX_CONSTANT_COLOR, 0, GR_CMBX_ZERO, 0); CC_PRIM() ; } static void cc_env_sub_shade_mul_t1_add_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); USE_T1(); } //Added by Gonetz static void cc_env_sub_shade_mul__t0_inter_t1_using_shadea__add_shade() { CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_TEXTURE_RGB, 0, GR_CMBX_B, 0); CC_ENV(); T0_INTER_T1_USING_SHADEA(); } //Added by Gonetz static void cc_env_sub_shade_mul_enva_add_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_OTHER_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); cmb.ccolor = g_gdp.env_color.total; } //Added by Gonetz static void cc_shade_sub_t0_mul_shadea_add_t0() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE_SHADEA(); USE_T0(); } static void cc__t0_mul_shade_mul_shadea__add__t1_mul_one_sub_shadea() { // (t0-0)*shade+0, (cmb-t0)*shadea+t0 T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ITALPHA, 1, GR_CMBX_ZERO, 0); T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_B, 0); MULSHADE_SHADEA(); cmb.tex |= 3; CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_TEXTURE_RGB, 0); } static void cc_shade_sub_prim_mul__t0_inter_t1_using_primlod__add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); T0_INTER_T1_USING_FACTOR (lod_frac); } static void cc_shade_sub_prim_mul_t0_add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); USE_T0(); } //Added by Gonetz static void cc_shade_sub_prim_mul_t1_add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); USE_T1(); } //Added by Gonetz static void cc_shade_sub_env_mul__t0_mul_t1__add__t0_mul_t1() { CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_TEXTURE_RGB, 0, GR_CMBX_TEXTURE_RGB, 0); CC_ENV(); T0_MUL_T1(); } //Added by Gonetz static void cc_shade_sub_env_mul_t0_add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); SUBSHADE_ENV(); USE_T0(); } //Added by Gonetz static void cc_shade_sub_env_mul__t0_inter_t1_using_primlod__add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIM(); SUBSHADE_ENV(); T0_INTER_T1_USING_FACTOR (lod_frac); } //Added by Gonetz static void cc_shade_sub_env_mul__t0_inter_t1_using_primlod__add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); T0_INTER_T1_USING_FACTOR (lod_frac); } //Added by Gonetz static void cc_shade_sub_env_mul__t0_mul_t1__add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); T0_MUL_T1(); } //Added by Gonetz static void cc_shade_sub_env_mul__t1_sub_prim_mul_primlod_add_t0__add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); SETSHADE_ENV(); T1_SUB_PRIM_MUL_PRIMLOD_ADD_T0(); } //Added by Gonetz static void cc_shade_sub_env_mul_t0_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); USE_T0(); } //Added by Gonetz static void cc_shade_sub_env_mul_t0_mul_prim_add_prim_mul_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_PRIMMULENV(); SUBSHADE_ENV(); MULSHADE_PRIM(); USE_T0(); } //Added by Gonetz static void cc_shade_sub_env_mul_t1_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENV(); USE_T1(); } //Added by Gonetz static void cc_shade_sub_env_mul_prim_add_t0() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); SUBSHADE_ENV(); MULSHADE_PRIM(); USE_T0(); } static void cc__t0_add_prim_mul_shade__mul_shade_add_env() { T1CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_B, 0); CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.prim_color.total; CC_ENV(); cmb.tex |= 1; } static void cc__t0_add_prim_mul_shade__mul_shade() { T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_B, 0); CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); cmb.tex_ccolor = g_gdp.prim_color.total; cmb.tex |= 1; } //Added by Gonetz static void cc_shade_sub_env_mul_prim_add_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); SUBSHADE_ENV(); MULSHADE_PRIM(); CC_ENV(); } //Added by Gonetz static void cc_shade_sub_env_mul_prima_add_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); SUBSHADE_ENV(); MULSHADE_PRIMA(); CC_PRIM(); } static void cc_shade_sub_env_mul_k5_add_prim() { uint32_t temp; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); SUBSHADE_ENV(); temp = g_gdp.prim_color.total; g_gdp.prim_color.total = g_gdp.k5; g_gdp.prim_color.r = (g_gdp.prim_color.total & 0xFF000000) >> 24; g_gdp.prim_color.g = (g_gdp.prim_color.total & 0x00FF0000) >> 16; g_gdp.prim_color.b = (g_gdp.prim_color.total & 0x0000FF00) >> 8; g_gdp.prim_color.a = (g_gdp.prim_color.total & 0x000000FF); MULSHADE_PRIMA(); g_gdp.prim_color.total = temp; g_gdp.prim_color.r = (g_gdp.prim_color.total & 0xFF000000) >> 24; g_gdp.prim_color.g = (g_gdp.prim_color.total & 0x00FF0000) >> 16; g_gdp.prim_color.b = (g_gdp.prim_color.total & 0x0000FF00) >> 8; g_gdp.prim_color.a = (g_gdp.prim_color.total & 0x000000FF); CC_PRIM(); } // ** A inter B using C ** static void cc_t0_inter_t1_using_t1a() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); T0_INTER_T1_USING_T1A(); } static void cc_t0_inter_t1_using_prima() { uint8_t factor = g_gdp.prim_color.a; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); T0_INTER_T1_USING_FACTOR (factor); } static void cc_t1_inter_t0_using_prima() { uint8_t factor = g_gdp.prim_color.a; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); T1_INTER_T0_USING_FACTOR (factor); } static void cc_t1_inter_t0_using_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); T1_INTER_T0_USING_PRIM(); } static void cc_t0_inter_t1_using_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); T0_INTER_T1_USING_ENV(); } static void cc_t0_inter_t1_using_enva() { uint8_t factor = g_gdp.env_color.a; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); T0_INTER_T1_USING_FACTOR (factor); } static void cc__t0_inter_t1_using_prim__inter_env_using_enva() { // (t1-t0)*prim+t0, (env-cmb)*env_a+cmb T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_TMU_CCOLOR, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.prim_color.total; cmb.tex |= 3; CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_CONSTANT_ALPHA, 0, GR_CMBX_B, 0); cmb.ccolor = g_gdp.env_color.total; } static void cc__t0_inter_t1_using_shade__inter_env_using_enva() { // (t1-t0)*shade+t0, (env-cmb)*env_a+cmb T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, 0, GR_CMBX_B, 0); cmb.tex |= 3; CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_CONSTANT_ALPHA, 0, GR_CMBX_B, 0); cmb.ccolor = g_gdp.env_color.total; } //Added by Gonetz static void cc_t0_inter_t1_using_shade() { T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, 0, GR_CMBX_B, 0); cmb.tex |= 3; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); } //Added by Gonetz static void cc_t1_inter_t0_using_shade() { T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, 0, GR_CMBX_B, 0); cmb.tex |= 3; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); } //Added by Gonetz static void cc_t1_inter_t0_using_shadea() { CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); T1_INTER_T0_USING_SHADEA(); } //Added by Gonetz static void cc_t0_inter_t1_using_primlod() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); T0_INTER_T1_USING_FACTOR (lod_frac); } //Added by Gonetz static void cc_t1_inter_t0_using_primlod() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); T1_INTER_T0_USING_FACTOR (lod_frac); } //Added by Gonetz static void cc_t1_inter_t0_using_t0() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); T1_INTER_T0_USING_T0(); } //Added by Gonetz static void cc_t0_inter_t1_using_k5() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); T0_INTER_T1_USING_FACTOR (g_gdp.k5); } static void cc_t0_inter_env_using_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); USE_T0(); MOD_0 (TMOD_TEX_INTER_COL_USING_COL1); MOD_0_COL (g_gdp.env_color.total & 0xFFFFFF00); MOD_0_COL1 (g_gdp.prim_color.total & 0xFFFFFF00); } //Added by Gonetz static void cc_t0_inter_prim_using_primlod() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); USE_T0(); MOD_0 (TMOD_TEX_INTER_COLOR_USING_FACTOR); MOD_0_COL (g_gdp.prim_color.total & 0xFFFFFF00); MOD_0_FAC (lod_frac & 0xFF); } static void cc_t0_inter_shade_using_t0a() { CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_X, GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_TEXTURE_ALPHA, 0, GR_CMBX_B, 0); USE_T0(); A_USE_T0(); } static void cc_t0_inter_shade_using_primlod() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIMLOD(); cmb.ccolor=(~cmb.ccolor)&0xFFFFFF00; MULSHADE_PRIMLOD(); USE_T0(); //(shade-t0)*primlod+t0 = t0*(1-primlod)+shade*primlod } //Added by Gonetz static void cc__env_inter_t0_using_primlod__mul_prim() { //((t0-env)*primlod+env)*prim = t0*prim*primlod+env*prim*(1-primlod); CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); cmb.ccolor = ((((cmb.ccolor & 0xFF000000) >> 24) * (lod_frac & 0xFF))<<24) | ((((cmb.ccolor & 0x00FF0000) >> 16) * (lod_frac & 0xFF))<<16) | ((((cmb.ccolor & 0x0000FF00) >> 8) * (lod_frac & 0xFF))<<8); SETSHADE_PRIM(); SETSHADE_ENV(); SETSHADE_1MPRIMLOD(); USE_T0(); } //Added by Gonetz static void cc__env_inter_t0_using_shadea__mul_shade() { //((t0-env)*shadea+env)*shade T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITALPHA, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.env_color.total; cmb.tex |= 1; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); } //Added by Gonetz static void cc_env_inter_prim_using_primlod() { if (g_gdp.prim_color.total&0xFFFFFF00) { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); SETSHADE_PRIMSUBENV(); SETSHADE_PRIMLOD(); CC_ENV(); } else { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); SETSHADE_ENV(); SETSHADE_PRIMLOD(); CC_ENV(); } } static void cc_prim_inter__t0_mul_t1_add_env__using_shadea() { T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.env_color.total; cmb.tex |= 3; // * not guaranteed to work if another iterated alpha is set CCMB (GR_COMBINE_FUNCTION_BLEND, GR_COMBINE_FACTOR_LOCAL_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); SETSHADE_PRIM(); } static void cc_env_inter__prim_inter_shade_using_t0__using_shadea() { T0CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_LOCAL_TEXTURE_RGB, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.prim_color.total; cmb.tex |= 1; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITALPHA, 0, GR_CMBX_B, 0); CC_ENV(); } static void cc_shade_inter__prim_inter_shade_using_t0__using_shadea() { T0CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_LOCAL_TEXTURE_RGB, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.prim_color.total; cmb.tex |= 1; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITALPHA, 0, GR_CMBX_B, 0); } // ** (A-B)*C+D*E ** static void cc_one_sub_env_mul_prim_add__t0_mul_env() //Aded by Gonetz { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); SETSHADE_1MENV(); SETSHADE_PRIM(); USE_T0(); } // ** ((A-B)*C+D)*E ** static void cc_t0_sub_env_mul_prim_mul_shade_add_prim_mul_shade() //Aded by Gonetz { //(t0-env)*shade+shade, (cmb-0)*prim+0 T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); cmb.tex_ccolor = g_gdp.env_color.total; cmb.tex |= 1; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, 0, GR_CMBX_ZERO, 0); CC_PRIM(); } static void cc__t1_sub_prim_mul_t0_add_env__mul_shade() //Aded by Gonetz { // (t1-prim)*t0+env, (cmb-0)*shade+0 T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_LOCAL_TEXTURE_RGB, 0, GR_CMBX_ZERO, 0); cmb.tex_ccolor = g_gdp.prim_color.total; cmb.tex |= 3; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); CC_ENV(); } // ** (A inter B using C) * D ** //Added by Gonetz static void cc__t0_inter_t1_using_prima__mul_prim() { uint8_t factor = g_gdp.prim_color.a; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); T0_INTER_T1_USING_FACTOR (factor); CC_PRIM(); } //Added by Gonetz static void cc__t1_inter_t0_using_prima__mul_prim() { uint8_t factor = g_gdp.prim_color.a; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); T1_INTER_T0_USING_FACTOR (factor); CC_PRIM(); } //Added by Gonetz static void cc__t0_inter_t1_using_prim__mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T0_INTER_T1_USING_PRIM(); } //Added by Gonetz static void cc__t0_inter_t1_using_prima__mul_shade() { uint8_t factor = g_gdp.prim_color.a; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T0_INTER_T1_USING_FACTOR (factor); } //Added by Gonetz static void cc__t1_inter_t0_using_prima__mul_shade() { uint8_t factor = g_gdp.prim_color.a; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T1_INTER_T0_USING_FACTOR (factor); } static void cc__t0_inter_t1_using_env__mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T0_INTER_T1_USING_ENV(); } static void cc__t0_inter_t1_using_enva__mul_shade() { uint8_t factor = g_gdp.env_color.a; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T0_INTER_T1_USING_FACTOR (factor); } static void cc__t0_inter_t1_using_enva__mul_prim() { uint8_t factor = g_gdp.env_color.a; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); T0_INTER_T1_USING_FACTOR (factor); } //Added by Gonetz static void cc__t0_inter_t1_using_enva__mul_env() { uint8_t factor = g_gdp.env_color.a; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_ENV(); T0_INTER_T1_USING_FACTOR (factor); } //Added by Gonetz static void cc__t0_inter_t1_using_primlod__mul_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); T0_INTER_T1_USING_FACTOR (lod_frac); } //Added by Gonetz static void cc__t0_inter_t1_using_primlod__mul_prima() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIMA(); T0_INTER_T1_USING_FACTOR (lod_frac); } //Added by Gonetz static void cc__t1_mul_primlod_add_t0__mul_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); T1_MUL_PRIMLOD_ADD_T0(); } //Added by Gonetz static void cc__t0_inter_t1_using_primlod__mul_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_ENV(); T0_INTER_T1_USING_FACTOR (lod_frac); } //Added by Gonetz static void cc__t1_mul_primlod_add_t0__mul_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_ENV(); T1_MUL_PRIMLOD_ADD_T0(); } //Added by Gonetz static void cc__t1_inter_t0_using_prim__mul_env() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_ENV(); T1_INTER_T0_USING_PRIM(); } static void cc__one_sub_shade_mul_t0_add_shade__mul_prim() { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, GR_FUNC_MODE_ONE_MINUS_X, GR_CMBX_LOCAL_TEXTURE_RGB, 0, GR_CMBX_B, 0); cmb.tex |= 1; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, GR_CMBX_CONSTANT_COLOR, 0, GR_CMBX_ZERO, 0); CC_PRIM(); } static void cc__one_sub_shade_mul_t0_add_shade__mul_env() { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, GR_FUNC_MODE_ONE_MINUS_X, GR_CMBX_LOCAL_TEXTURE_RGB, 0, GR_CMBX_B, 0); cmb.tex |= 1; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, GR_CMBX_CONSTANT_COLOR, 0, GR_CMBX_ZERO, 0); CC_ENV(); } static void cc__t1_inter_t0_using_prim__mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T1_INTER_T0_USING_PRIM(); } static void cc__t0_inter_t1_using_primlod__mul_shade() { //* if ((rdp.othermode_h & RDP_TEX_LOD_ENABLE) && (rdp.mipmap_level == 0) && !(settings.hacks&hack_Fifa98)) { cc_t0_mul_shade(); return; } //*/ if (settings.ucode == 7) lod_frac = g_gdp.primitive_lod_frac; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T0_INTER_T1_USING_FACTOR (lod_frac); } static void cc__t1_inter_t0_using_primlod__mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T1_INTER_T0_USING_FACTOR (lod_frac); } static void cc__t0_inter_t1_using_half__mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T0_INTER_T1_USING_FACTOR (0x7F); } static void cc__t0_inter_t1_using_t0__mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T0_INTER_T1_USING_T0(); } static void cc__t0_inter_t1_using_t1a__mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T0_INTER_T1_USING_T1A(); } static void cc__t0_inter_t1_using_shadea__mul_shade() { CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); T0_INTER_T1_USING_SHADEA(); } static void cc__t0_inter_t1_using_k5__mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T0_INTER_T1_USING_FACTOR (g_gdp.k5); } static void cc__t1_inter_t0_using_k5__mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T1_INTER_T0_USING_FACTOR (g_gdp.k5); } static void cc_t0_inter_prim_using_prima() { T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_TMU_CALPHA, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.prim_color.total; cmb.tex |= 1; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); } static void cc__t0_inter_prim_using_t0a__mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MOD_0 (TMOD_TEX_INTER_COL_USING_TEXA); MOD_0_COL (g_gdp.prim_color.total & 0xFFFFFF00); USE_T0(); } static void cc__env_inter_prim_using_t0__mul_prim() { // (prim-env)*t0+env, (cmb-0)*prim+0 CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); MOD_0 (TMOD_COL_INTER_COL1_USING_TEX); MOD_0_COL (g_gdp.env_color.total & 0xFFFFFF00); MOD_0_COL1 (g_gdp.prim_color.total & 0xFFFFFF00); USE_T0(); } static void cc__env_inter_prim_using_t0__mul_shade() { // amazing... mace actually uses the blender as part of the combine if ((rdp.othermode_l & 0xFFFF0000) == 0x03820000 || (rdp.othermode_l & 0xFFFF0000) == 0x00910000) { // blender: // 1ST = CLR_IN * A_IN + CLR_BL * 1MA // OUT = 1ST * 0 + 1ST * 1 CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MOD_0 (TMOD_COL2_INTER__COL_INTER_COL1_USING_TEX__USING_TEXA); MOD_0_COL (g_gdp.env_color.total & 0xFFFFFF00); MOD_0_COL1 (g_gdp.prim_color.total & 0xFFFFFF00); MOD_0_COL2 (g_gdp.blend_color.total & 0xFFFFFF00); USE_T0(); return; } //(prim-env)*t0+env, (shade-0)*cmb+0 MOD_0 (TMOD_COL_INTER_COL1_USING_TEX); MOD_0_COL (g_gdp.env_color.total & 0xFFFFFF00); MOD_0_COL1 (g_gdp.prim_color.total & 0xFFFFFF00); USE_T0(); CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); } static void cc__env_inter_one_using_t0__mul_shade() { //(one-env)*t0+env, (cmb-0)*shade+0 T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ONE_MINUS_X, GR_CMBX_LOCAL_TEXTURE_RGB, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.env_color.total&0xFFFFFF00; cmb.tex |= 1; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); } static void cc_env_inter_one_using__one_sub_t0_mul_primlod() { // (noise-t0)*primlod+0, (1-env)*cmb+env T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_ZERO, 0); cmb.tex_ccolor = rand()&0xFFFFFF00; cmb.tex |= 1; percent = lod_frac / 255.0f; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; cmb.tex |= 1; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_ENV(); } static void cc__env_inter_prim_using_prima__mul_shade() { int r = (((g_gdp.prim_color.r - g_gdp.env_color.r) * g_gdp.prim_color.a) / 256) + g_gdp.env_color.r; int g = (((g_gdp.prim_color.g - g_gdp.env_color.g) * g_gdp.prim_color.a) / 256) + g_gdp.env_color.g; int b = (((g_gdp.prim_color.b - g_gdp.env_color.b) * g_gdp.prim_color.a) / 256) + g_gdp.env_color.b; cmb.ccolor = (r << 24) | (g << 16) | (b << 8); CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); } static void cc__prim_inter_t0_using_env__mul_shade() { // (t0-prim)*env+prim, (cmb-0)*shade+0 if ((g_gdp.prim_color.total & 0xFFFFFF00) == 0) { cc_t0_mul_env_mul_shade(); } else { uint32_t onesubenv; T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_TMU_CCOLOR, 0, GR_CMBX_ZERO, 0); cmb.tex_ccolor = g_gdp.env_color.total & 0xFFFFFF00; cmb.tex |= 1; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); onesubenv = ~g_gdp.env_color.total; CC_C1MULC2(g_gdp.prim_color.total, onesubenv); } } static void cc__one_inter_prim_using_t1__mul_shade() { if ((settings.hacks&hack_BAR) && rdp.cur_tile == 1) { T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_LOCAL_TEXTURE_RGB, 0, GR_CMBX_ZERO, 1); cmb.tex |= 1; } else { T1CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_LOCAL_TEXTURE_RGB, 0, GR_CMBX_ZERO, 1); T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); cmb.tex |= 2; } cmb.tex_ccolor = g_gdp.prim_color.total | 0xFF; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); } static void cc_prim_sub__prim_sub_t0_mul_prima__mul_shade() { // (prim-t0)*prim_a+0, (prim-cmb)*shade+0 T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_TMU_CALPHA, 0, GR_CMBX_ZERO, 0); cmb.tex_ccolor = g_gdp.prim_color.total; cmb.tex |= 1; CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); CC_PRIM(); } static void cc__prim_inter_env_using_t0__mul_shade() { // (env-prim)*t0+prim, (cmb-0)*shade+0 CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MOD_0 (TMOD_COL_INTER_COL1_USING_TEX); MOD_0_COL (g_gdp.prim_color.total & 0xFFFFFF00); MOD_0_COL1 (g_gdp.env_color.total & 0xFFFFFF00); USE_T0(); } static void cc__prim_inter_one_using_env__mul_shade() { // (one-prim)*env+prim, (cmb-0)*shade+0 if ((g_gdp.prim_color.total&0xFFFFFF00) == 0) { cc_env_mul_shade(); return; } if ((g_gdp.env_color.total&0xFFFFFF00) == 0) { cc_prim_mul_shade(); return; } if ((g_gdp.prim_color.total&0xFFFFFF00) == 0xFFFFFF00 || (g_gdp.env_color.total&0xFFFFFF00) == 0xFFFFFF00) { cc_shade(); return; } CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_1SUBPRIM(); CC_C1MULC2 (cmb.ccolor, g_gdp.env_color.total); cmb.ccolor=(uint8_t)( (int)((cmb.ccolor & 0xFF000000) >> 24) + g_gdp.prim_color.r) << 24 | (uint8_t)( (int)((cmb.ccolor & 0x00FF0000) >> 16) + g_gdp.prim_color.g ) << 16 | (uint8_t)( (int)((cmb.ccolor & 0x0000FF00) >> 8) + g_gdp.prim_color.b ) << 8 ; } static void cc__env_inter_prim_using_t0a__mul_t0() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); MOD_0 (TMOD_COL_INTER_COL1_USING_TEXA__MUL_TEX); MOD_0_COL (g_gdp.env_color.total & 0xFFFFFF00); MOD_0_COL1 (g_gdp.prim_color.total & 0xFFFFFF00); USE_T0(); } static void cc__env_inter_prim_using_t0a__mul_prim() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CC_PRIM(); MOD_0 (TMOD_COL_INTER_COL1_USING_TEXA); MOD_0_COL (g_gdp.env_color.total & 0xFFFFFF00); MOD_0_COL1 (g_gdp.prim_color.total & 0xFFFFFF00); USE_T0(); } static void cc__env_inter_prim_using__t0_sub_shade_mul_primlod_add_env() { // (t0-shade)*lodf+env, (prim-env)*cmb+env T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_B, 0); cmb.tex_ccolor = g_gdp.env_color.total; percent = lod_frac / 255.0f; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; cmb.tex |= 1; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_PRIM(); SETSHADE_ENV(); } static void cc__prim_inter_t0_using_t0__mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MOD_0 (TMOD_COL_INTER_TEX_USING_TEX); MOD_0_COL (g_gdp.prim_color.total & 0xFFFFFF00); USE_T0(); } static void cc__env_inter_t0_using_t0a__mul_shade() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MOD_0 (TMOD_COL_INTER_TEX_USING_TEXA); MOD_0_COL (g_gdp.env_color.total & 0xFFFFFF00); USE_T0(); } static void cc__env_inter_t0_using_prima__mul_shade() { uint32_t prima; CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MOD_0 (TMOD_COL_INTER_TEX_USING_COL1); MOD_0_COL (g_gdp.env_color.total & 0xFFFFFF00); prima = g_gdp.prim_color.total & 0xFF; MOD_0_COL1 ((prima<<24)|(prima|16)|(prima<<8)); USE_T0(); } static void cc_shade_mul_prima() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_ITERATED); MULSHADE_PRIMA(); } static void cc_shade_mul_shadea() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_ITERATED); MULSHADE_SHADEA(); } static void cc__t0_mul_shade__inter_env_using_enva() { // (t0-0)*shade+0, (env-cmb)*env_a+cmb ** INC ** uint32_t enva = g_gdp.env_color.total&0xFF; if (enva == 0xFF) cc_env(); else if (enva == 0) cc_t0_mul_shade(); else { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, GR_CMBX_ITRGB, 0, GR_CMBX_B, 0); cmb.tex |= 1; CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); MULSHADE_1MENVA(); CC_COLMULBYTE(g_gdp.env_color.total, (g_gdp.env_color.total&0xFF)); cmb.tex_ccolor = cmb.ccolor; } } static void cc__t0_mul_shade__inter_one_using_enva() { CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_RGB, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CC_ENVA(); MULSHADE_1MENVA(); USE_T0(); } static void cc__t0_mul_shade__inter_one_using_shadea() { T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ITRGB, 0, GR_CMBX_ZERO, 0); cmb.tex |= 1; CCMBEXT(GR_CMBX_ZERO, GR_FUNC_MODE_X, GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_ONE_MINUS_X, GR_CMBX_ITALPHA, 0, GR_CMBX_B, 0); } static void cc__prim_mul_shade__inter_env_using_enva() { CCMB (GR_COMBINE_FUNCTION_BLEND, GR_COMBINE_FACTOR_LOCAL_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); MULSHADE_PRIM(); SETSHADE_A_ENV(); } static void cc__prim_mul_shade__inter_env_using__prim_mul_shade_alpha() { CCMB (GR_COMBINE_FUNCTION_BLEND, GR_COMBINE_FACTOR_LOCAL_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CC_ENV(); MULSHADE_PRIM(); MULSHADE_A_PRIM(); } //**************************************************************** static void ac_one() { ACMB (GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE); cmb.ccolor |= 0xFF; } static void ac_t0() { if ((rdp.othermode_l & RDP_FORCE_BLEND) && (((rdp.othermode_h & RDP_CYCLE_TYPE) >> 20) < G_CYC_COPY)) { uint32_t blend_mode = (rdp.othermode_l >> 16); if (blend_mode == 0x0550) { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA(g_gdp.fog_color.total); } else if (blend_mode == 0x55f0) //cmem*afog + cfog*1ma { ACMB (GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE); CA(~g_gdp.fog_color.total); } else { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); } } else { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); } A_USE_T0(); } static void ac_zero() { if (cmb.tex > 0) { ac_t0(); return; } ACMB (GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE); cmb.ccolor &= 0xFFFFFF00; } static void ac_t1() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); if ((settings.hacks&hack_BAR) && g_gdp.tile[rdp.cur_tile].format == 3) A_USE_T0(); else A_USE_T1(); } static void ac_prim() { ACMB (GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE); CA_PRIM(); } static void ac_primlod() { ACMB (GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE); CA_PRIMLOD(); } static void ac_one_sub_t0() { ACMB (GR_COMBINE_FUNCTION_BLEND_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE); CA (0xFF); A_USE_T0(); } static void ac_one_sub_prim() { ACMB (GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE); CA_INVPRIM(); } static void ac_env() { ACMB (GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE); CA_ENV(); } static void ac_shade() { ACMB (GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_NONE); } // ** A+B ** static void ac_t0_add_t1() //Aded by Gonetz { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); A_T0_ADD_T1(); } static void ac__t0_mul_prim__add__t1_mul_primlod() //Aded by Gonetz { if (lod_frac == 0) { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); A_USE_T0(); } else if ((g_gdp.prim_color.total&0xFF) == 0) { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIMLOD(); A_USE_T1(); } else if ((g_gdp.prim_color.total&0xFF) == 0xFF) { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); A_T1_MUL_PRIMLOD_ADD_T0(); } else { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); A_T0_ADD_T1(); } } static void ac_t0_add_prim() //Aded by Gonetz { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); A_USE_T0(); } static void ac_t0_add_env() //Aded by Gonetz { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_ENV(); A_USE_T0(); } static void ac_t1_add_env() //Added by Gonetz { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_ENV(); A_USE_T1(); } static void ac__t0_add_t1__add_prim() //Aded by Gonetz { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); A_T0_ADD_T1(); } static void ac_prim_add_shade() //Aded by Gonetz { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CA_PRIM(); } static void ac_env_add_shade() //Aded by Gonetz { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CA_ENV(); } // ** A*B ** static void ac_t0_mul_t0() //Added by Gonetz { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); A_USE_T0(); } static void ac_t0_mul_t1() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); A_T0_MUL_T1(); } static void ac_t0_mul_t1_add_t1() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0, GR_CMBX_B, 0); cmb.tex |= 3; } static void ac_t0_mul_t1_add_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); A_T0_MUL_T1(); } static void ac_t0_mul_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); A_USE_T0(); } static void ac_t0_mul_prim_mul_primlod() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM_MUL_PRIMLOD(); A_USE_T0(); } static void ac_t1_mul_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); if (((rdp.othermode_h & RDP_CYCLE_TYPE) >> 20) == G_CYC_1CYCLE) A_USE_T0(); else A_USE_T1(); } //Added by Gonetz static void ac__t1_sub_one_mul_primlod_add_t0__mul_prim() { T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (0xFF) ; percent = lod_frac / 255.0f; ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); cmb.dc0_detailmax = cmb.dc1_detailmax = percent; cmb.tex |= 3; } static void ac__t0_sub_t1_mul_enva_add_t0__mul_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_TMU_CALPHA, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (g_gdp.env_color.total&0xFF) ; cmb.tex |= 3; } static void ac__t0_sub_one_mul_enva_add_t0__mul_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); T0ACMBEXT(GR_CMBX_ITALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_TMU_CALPHA, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); SETSHADE_A(0xFF); cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (g_gdp.env_color.total&0xFF) ; cmb.tex |= 1; } static void ac__t0_sub_t1_mul_primlod_add_t0__mul_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); cmb.tex |= 3; percent = lod_frac / 255.0f; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; } static void ac__t1_sub_prim_mul_primlod_add_t0__mul_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); cmb.tex |= 3; cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (g_gdp.prim_color.total&0xFF); percent = lod_frac / 255.0f; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; } static void ac__t1_sub_t0_mul_enva_add_t1__mul_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_TMU_CALPHA, 0, GR_CMBX_B, 0); cmb.tex |= 3; cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (g_gdp.env_color.total&0xFF); } static void ac__t1_sub_t0_mul_primlod__mul_env_add_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_TMU_CALPHA, 0, GR_CMBX_ZERO, 0); cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (uint32_t)((g_gdp.env_color.total&0xFF)* g_gdp.primitive_lod_frac/255.0f); cmb.tex |= 3; } static void ac__t0_sub_one_mul_enva_add_t1__mul_prim() { T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_TMU_CALPHA, 0, GR_CMBX_B, 0); cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (g_gdp.env_color.total&0xFF) ; cmb.tex |= 3; ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITALPHA, 0, GR_CMBX_ZERO, 0); CA_ENV(); SETSHADE_A_PRIM(); } static void ac__t1_mul_prima_add_t0__mul_env() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_ENV(); A_T1_MUL_PRIMA_ADD_T0(); } static void ac__t1_mul_enva_add_t0__mul_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); A_T1_MUL_ENVA_ADD_T0(); } static void ac_t0_mul_primlod() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIMLOD(); A_USE_T0(); } static void ac_t1_mul_primlod() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIMLOD(); A_USE_T1(); } //Added by Gonetz static void ac__t0_add_t1__mul_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); A_T0_ADD_T1(); } //Added by Gonetz static void ac__t0_add_t1__mul_primlod() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIMLOD(); A_T0_ADD_T1(); } //Added by Gonetz static void ac__t0_mul_t1__mul_primlod() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIMLOD(); A_T0_MUL_T1(); } static void ac_t0_mul_env() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_ENV(); A_USE_T0(); } static void ac_t0_mul_env_mul_primlod() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_ENV_MUL_PRIMLOD(); A_USE_T0(); } static void ac_t1_mul_env() //Added by Gonetz { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_ENV(); // if ((settings.hacks&hack_Powerpuff) && (rdp.last_tile == 0)) if (((rdp.othermode_h & RDP_CYCLE_TYPE) >> 20) == G_CYC_1CYCLE) A_USE_T0(); else A_USE_T1(); } static void ac__t1_sub_one_mul_primlod_add_t0__mul_env() { T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (0xFF) ; percent = lod_frac / 255.0f; ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_ENV(); cmb.dc0_detailmax = cmb.dc1_detailmax = percent; cmb.tex |= 3; } static void ac_t0_mul_shade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); A_USE_T0(); } static void ac_t1_mul_shade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); A_USE_T1(); } //Added by Gonetz static void ac__t0_add_t1__mul_shade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); A_T0_ADD_T1(); } static void ac__t0_mul_primlod_add_t0__mul_shade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); cmb.tex |= 1; percent = lod_frac / 255.0f; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; } static void ac__t1_mul_prima_add_t0__mul_shade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); A_T1_MUL_PRIMA_ADD_T0(); } //Added by Gonetz static void ac__t0_sub_t1__mul_shade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); cmb.tex |= 3; } static void ac__t1_mul_t1_add_t1__mul_shade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); cmb.tex |= 2; } static void ac__t1_mul_enva_add_t0__mul_shade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); A_T1_MUL_ENVA_ADD_T0(); } static void ac__t1_sub_one_mul_primlod_add_t0__mul_shade() { T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (0xFF) ; percent = lod_frac / 255.0f; ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); cmb.dc0_detailmax = cmb.dc1_detailmax = percent; cmb.tex |= 3; } static void ac__t1_sub_shade_mul_primlod_add_t0__mul_shade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); cmb.tex |= 3; percent = lod_frac / 255.0f; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; } //Added by Gonetz static void ac_prim_mul_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CA_PRIM(); SETSHADE_A_PRIM(); } //Added by Gonetz static void ac_prim_mul_primlod() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CA_PRIMLOD(); SETSHADE_A_PRIM(); } static void ac_prim_mul_env() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CA_ENV(); SETSHADE_A_PRIM(); } static void ac__prim_sub_one_mul_primlod_add_t0__mul_env() { T0ACMBEXT(GR_CMBX_ITALPHA, GR_FUNC_MODE_X, GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); SETSHADE_A_PRIM(); cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (0xFF) ; percent = lod_frac / 255.0f; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; cmb.tex |= 1; ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_ENV(); } static void ac_prim_mul_shade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CA_PRIM(); } static void ac_env_mul_shade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CA_ENV(); } static void ac_primlod_mul_shade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CA_PRIMLOD(); } // ** A-B ** static void ac_prim_sub_t0() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); A_USE_T0(); MOD_0 (TMOD_FULL_COLOR_SUB_TEX); MOD_0_COL (g_gdp.prim_color.total); } // ** A*B+C ** static void ac_t0_mul_prim_add_t0() { ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_CONSTANT_ALPHA, 0, GR_CMBX_B, 0); CA_PRIM(); A_USE_T0(); } static void ac_t1_mul_prim_add_t0() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); A_T1_MUL_PRIMA_ADD_T0(); } static void ac__t0_inter_t1_using_t1a__mul_prim_add__t0_inter_t1_using_t1a() { ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_CONSTANT_ALPHA, 0, GR_CMBX_B, 0); CA_PRIM(); A_T0_INTER_T1_USING_T1A(); } static void ac__t1_inter_t0_using_t0a__mul_prim_add__t1_inter_t0_using_t0a() { ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_CONSTANT_ALPHA, 0, GR_CMBX_B, 0); CA_PRIM(); A_T1_INTER_T0_USING_T0A(); } //Added by Gonetz static void ac_t0_mul_prim_add_env() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); SETSHADE_A_PRIM(); CA_ENV(); A_USE_T0(); } //Added by Gonetz static void ac__t0_add_t1__mul_prim_add_env() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); SETSHADE_A_PRIM(); CA_ENV(); A_T0_ADD_T1(); } //Aded by Gonetz static void ac__t0_inter_t1_using_enva__mul_prim_add_env() { uint8_t factor = g_gdp.env_color.a; ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); SETSHADE_A_PRIM(); CA_ENV(); A_T0_INTER_T1_USING_FACTOR (factor); } //Aded by Gonetz static void ac_t0_mul_primlod_add_t0() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); cmb.tex |= 1; percent = lod_frac / 255.0f; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; } #ifndef HAVE_ASSUME_COMBINE_EXT else { A_USE_T0(); } #endif } //Aded by Gonetz static void ac_t1_mul_primlod_add_t0() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); A_T1_MUL_PRIMLOD_ADD_T0(); } //Aded by Gonetz static void ac_t0_mul_primlod_add_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CA_PRIMLOD(); SETSHADE_A_PRIM(); A_USE_T0(); } static void ac_t0_mul_primlod_add_env() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CA_PRIMLOD(); SETSHADE_A_ENV(); A_USE_T0(); } //Aded by Gonetz static void ac__t0_add_t1__mul_primlod_add_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CA_PRIMLOD(); SETSHADE_A_PRIM(); A_T0_ADD_T1(); } //Added by Gonetz static void ac_t0_mul_env_add_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); SETSHADE_A_ENV(); CA_PRIM(); A_USE_T0(); } //Added by Gonetz static void ac_t1_mul_prim_add_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); SETSHADE_A_PRIM(); CA_PRIM(); A_USE_T1(); } //Added by Gonetz static void ac_prim_mul_shade_add_shade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CA_PRIM(); } //Added by Gonetz static void ac_t0_mul_shade_add_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CA_PRIM(); A_USE_T0(); } static void ac_t0_mul_shade_add_env() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CA_ENV(); A_USE_T0(); } static void ac_one_sub_prim_mul__t0_mul_t1__add__prim_mul_shade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CA_INVPRIM(); MULSHADE_A_PRIM(); A_T0_MUL_T1(); } // ** A*B+C*D ** static void ac_t0_mul_prim_add_shade_mul_one_minus_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); MULSHADE_A_1MPRIM(); CA_PRIM(); A_USE_T0(); } // ** (A*B+C)*D ** static void ac__t0_mul_primlod_add_shade__mul_shade() { #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_B, 0); cmb.tex |= 1; percent = lod_frac / 255.0f; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, GR_CMBX_ITALPHA, 0, GR_CMBX_ZERO, 0); } #ifndef HAVE_ASSUME_COMBINE_EXT else { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); A_USE_T0(); } #endif } static void ac__t1_mul_primlod_add_shade__mul_shade() { #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_B, 0); cmb.tex |= 2; percent = lod_frac / 255.0f; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, GR_CMBX_ITALPHA, 0, GR_CMBX_ZERO, 0); } #ifndef HAVE_ASSUME_COMBINE_EXT else { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); A_USE_T1(); } #endif } // ** ((A-B)*C+D)+E ** static void ac__t0_sub_t1_mul_prim_add_shade__mul_shade() //(t0-t1)*prim+shade, (cmb-0)*shade+0 { #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_TMU_CALPHA, 0, GR_CMBX_ZERO, 0); cmb.tex |= 3; cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (g_gdp.prim_color.total&0xFF); ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, 0, GR_CMBX_ZERO, 0); } #ifndef HAVE_ASSUME_COMBINE_EXT else { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CA_PRIM(); A_T1_SUB_T0(); } #endif } static void ac__t1_sub_t0_mul_prim_add_shade__mul_shade() //(t1-t0)*prim+shade, (cmb-0)*shade+0 { #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_TMU_CALPHA, 0, GR_CMBX_ZERO, 0); cmb.tex |= 3; cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (g_gdp.prim_color.total&0xFF); ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, 0, GR_CMBX_ZERO, 0); } #ifndef HAVE_ASSUME_COMBINE_EXT else { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CA_PRIM(); A_T1_SUB_T0(); } #endif } // ** A*B*C ** static void ac__t0_mul_t1__mul_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); A_T0_MUL_T1(); } static void ac__t0_mul_t1__mul_env() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_ENV(); A_T0_MUL_T1(); } static void ac__t0_mul_t1__mul_env_mul_shade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE_A_ENV(); A_T0_MUL_T1(); } static void ac__t0_mul_t1__mul_prim_mul_shade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE_A_PRIM(); A_T0_MUL_T1(); } static void ac__t0_mul_t1__mul_shade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); A_T0_MUL_T1(); } static void ac__t0_add_prim_mul_shade__mul_shade() { // (shade-0)*prim+t0, (cmb-0)*shade+0 #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { T0ACMBEXT(GR_CMBX_ITALPHA, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_TMU_CALPHA, 0, GR_CMBX_B, 0); cmb.tex |= 1; cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (g_gdp.prim_color.total&0xFF); ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, GR_CMBX_ITALPHA, 0, GR_CMBX_ZERO, 0); } #ifndef HAVE_ASSUME_COMBINE_EXT else { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE_A_PRIM(); A_USE_T0(); } #endif } //Added by Gonetz static void ac_t0_mul_prim_mul_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); SETSHADE_A_PRIM(); SETSHADE_A_PRIM(); A_USE_T0(); } static void ac_t0_mul_prim_mul_env() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIMENV(); A_USE_T0(); } static void ac_t0_mul_prim_mul_shade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE_A_PRIM(); A_USE_T0(); } static void ac_t1_mul_prim_mul_shade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE_A_PRIM(); A_USE_T1(); } static void ac_t0_mul_env_mul_shade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE_A_ENV(); A_USE_T0(); } static void ac_t1_mul_env_mul_shade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE_A_ENV(); A_USE_T1(); } static void ac_t0_mul_primlod_mul_prim() //Aded by Gonetz { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); cmb.ccolor |= (uint32_t)(lod_frac * (g_gdp.prim_color.total&0xFF) / 255); A_USE_T0(); } // ** (A+B)*C ** static void ac_prim_add_env_mul_t0() //Aded by Gonetz { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); SETSHADE_A_PRIM(); ADDSHADE_A_ENV(); A_USE_T0(); } static void ac_t1_add_prim_mul_env() //Aded by Gonetz { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CA_ENV(); SETSHADE_A_PRIM(); SETSHADE_A_ENV(); A_USE_T1(); //(t1+prim)*env = t1*env + prim*env } // ** (A-B)*C ** static void ac_t0_sub_prim_mul_shade() { T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITALPHA, 0, GR_CMBX_ZERO, 0); cmb.tex |= 1; cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (g_gdp.prim_color.total&0xFF); ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); } static void ac_t0_sub_prim_mul_shade_mul_env() { T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITALPHA, 0, GR_CMBX_ZERO, 0); cmb.tex |= 1; cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (g_gdp.prim_color.total&0xFF); ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_CONSTANT_ALPHA, 0, GR_CMBX_ZERO, 0); CA_ENV(); } static void ac_t0_sub_shade_mul_prim() { T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_TMU_CALPHA, 0, GR_CMBX_ZERO, 0); cmb.tex |= 1; cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (g_gdp.prim_color.total&0xFF); ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); } static void ac__t0_mul_t1__sub_prim_mul_shade() //Aded by Gonetz { ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITALPHA, 0, GR_CMBX_ZERO, 0); CA_PRIM(); A_T0_MUL_T1(); } static void ac__one_sub_t1_mul_t0_add_shade__sub_prim_mul_shade() //Aded by Gonetz { // (1-t1)*t0+shade, (cmb-prim)*shade+0 T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_ONE_MINUS_X, GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0, GR_CMBX_B, 0); cmb.tex |= 3; ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITALPHA, 0, GR_CMBX_ZERO, 0); CA_PRIM(); } static void ac__t1_mul_primlod_add_t0__sub_prim_mul_shade() { #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITALPHA, 0, GR_CMBX_ZERO, 0); CA_PRIM(); } #ifndef HAVE_ASSUME_COMBINE_EXT else { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); } #endif A_T1_MUL_PRIMLOD_ADD_T0(); } static void ac__t1_mul_primlod_add_t0__sub_env_mul_prim() //Aded by Gonetz { #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITALPHA, 0, GR_CMBX_ZERO, 0); CA_ENV(); SETSHADE_A_PRIM(); } #ifndef HAVE_ASSUME_COMBINE_EXT else { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); } #endif A_T1_MUL_PRIMLOD_ADD_T0(); } static void ac__t1_mul_prima_add_t0__sub_env_mul_shade() //Aded by Gonetz { #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITALPHA, 0, GR_CMBX_ZERO, 0); CA_ENV(); } #ifndef HAVE_ASSUME_COMBINE_EXT else { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); } #endif A_T1_MUL_PRIMA_ADD_T0(); } static void ac_one_sub_t0_mul_prim() //Aded by Gonetz { ACMB (GR_COMBINE_FUNCTION_BLEND_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE); CA_PRIM(); A_USE_T0(); } static void ac_one_sub_t0_mul_shade() //Aded by Gonetz { { ac_zero(); } } static void ac_one_sub_prim_mul_t0() //Aded by Gonetz { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); A_USE_T0(); } static void ac_one_sub_env_mul_t0() //Aded by Gonetz { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_ENV(); A_USE_T0(); } static void ac_one_sub_shade_mul_t0() //Aded by Gonetz { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); A_USE_T0(); } static void ac_one_sub_shade_mul_env() //Aded by Gonetz { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CA_ENV(); } static void ac_prim_sub_shade_mul_t0() //Aded by Gonetz { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CA_PRIM(); A_USE_T0(); } static void ac_prim_sub_shade_mul_prim() //Aded by Gonetz { #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { ACMBEXT(GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_CONSTANT_ALPHA, 0, GR_CMBX_ZERO, 0); CA_PRIM(); } #ifndef HAVE_ASSUME_COMBINE_EXT else { if (!(g_gdp.prim_color.total & 0xFF)) { ac_zero(); } else { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CA_PRIM(); } } #endif } static void ac_shade_sub_env_mul_t0() //Aded by Gonetz { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CA_ENV(); A_USE_T0(); } // ** (A-B)*C*D ** static void ac_one_sub_t0_mul_prim_mul_shade() //Aded by Gonetz { ACMB (GR_COMBINE_FUNCTION_BLEND_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_NONE); MULSHADE_A_PRIM(); A_USE_T0(); } // ** (A+B)*C*D ** static void ac_one_plus_env_mul_prim_mul_shade() { #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { ACMBEXT(GR_CMBX_ZERO, GR_FUNC_MODE_ONE_MINUS_X, GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, 0, GR_CMBX_ZERO, 0); MULSHADE_A_PRIM(); CA_ENV(); } #ifndef HAVE_ASSUME_COMBINE_EXT else { ac_prim_mul_shade(); } #endif } // ** (A-B)*C+A ** static void ac__t0_mul_t1__sub_env_mul_prim_add__t0_mul_t1() //Aded by Gonetz { ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITALPHA, 0, GR_CMBX_TEXTURE_ALPHA, 0); CA_ENV(); SETSHADE_A_PRIM(); A_T0_MUL_T1(); } // ** (A-B)*C+D ** static void ac__t0_sub_prim_mul_shade_add_shade__mul_env() //Aded by Gonetz { T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITALPHA, 0, GR_CMBX_ITALPHA, 0); cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (g_gdp.prim_color.total&0xFF) ; cmb.tex |= 1; ACMBEXT(GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_ALPHA, 0, GR_CMBX_ZERO, 0); CA_ENV(); } static void ac_t0_sub_t1_mul_env_add_env() //Aded by Gonetz { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_ENV(); A_T0_SUB_T1(); } static void ac_t0_sub_one_mul_enva_add_t1() //Aded by Gonetz { #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_TMU_CALPHA, 0, GR_CMBX_B, 0); cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (g_gdp.env_color.total&0xFF) ; cmb.tex |= 3; ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_ENV(); } #ifndef HAVE_ASSUME_COMBINE_EXT else { ac__t0_mul_t1__mul_env(); } #endif } static void ac_t1_sub_one_mul_enva_add_t0() //Aded by Gonetz { #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_B, 0); T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_TMU_CALPHA, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (g_gdp.env_color.total&0xFF) ; SETSHADE_A (0xFF); cmb.tex |= 3; ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); } #ifndef HAVE_ASSUME_COMBINE_EXT else { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); A_USE_T0(); } #endif } static void ac_t1_sub_one_mul_primlod_add_t0() //Aded by Gonetz { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (0xFF) ; percent = lod_frac / 255.0f; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; cmb.tex |= 3; } #ifndef HAVE_ASSUME_COMBINE_EXT else { // A_T0_MUL_T1(); // A_T1_MUL_PRIMLOD_ADD_T0(); cmb.tmu1_a_func = GR_COMBINE_FUNCTION_BLEND_LOCAL; cmb.tmu1_a_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR; percent = (255 - lod_frac) / 255.0f; cmb.tmu0_a_func = GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA; cmb.tmu0_a_fac = GR_COMBINE_FACTOR_OTHER_ALPHA; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; cmb.tex |= 3; } #endif } static void ac_t1_sub_prim_mul_shade_add_prim() //Aded by Gonetz { #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITALPHA, 0, GR_CMBX_B, 0); T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (g_gdp.prim_color.total&0xFF) ; cmb.tex |= 2; ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_ZERO, GR_FUNC_MODE_X, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); } #ifndef HAVE_ASSUME_COMBINE_EXT else { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CA_PRIM(); MOD_1 (TMOD_TEX_SUB_COL); MOD_1_COL (g_gdp.prim_color.total & 0xFF); A_USE_T1(); } #endif } static void ac_t0_sub_env_mul_prim_add_env() //Aded by Gonetz { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); SETSHADE_A_PRIM(); CA_ENV1MPRIM(); A_USE_T0(); //(t0-env)*prim+env == t0*prim + env*(1-prim) } static void ac_t0_sub_env_mul_shadea_add_env() //Aded by Gonetz { #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); cmb.tex |= 1; ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITALPHA, 0, GR_CMBX_B, 0); CA_ENV(); } #ifndef HAVE_ASSUME_COMBINE_EXT else { ac_t0_mul_shade(); } #endif } static void ac__one_sub_t0_mul_t1_add_t0__mul_prim() //Aded by Gonetz { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); cmb.tex |= 3; cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL; cmb.tmu0_a_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL; cmb.tmu0_a_fac = GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA; } static void ac_one_sub_t0_mul_prim_add_t0() //Aded by Gonetz { ACMB (GR_COMBINE_FUNCTION_BLEND, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); SETSHADE_A_PRIM(); CA (0xFF); A_USE_T0(); } static void ac_one_sub_t0_mul_env_add_t0() //Aded by Gonetz { ACMB (GR_COMBINE_FUNCTION_BLEND, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); SETSHADE_A_ENV(); CA (0xFF); A_USE_T0(); } static void ac_one_sub_t0_mul_primlod_add_prim() //Aded by Gonetz { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); SETSHADE_A_PRIM(); CA_PRIMLOD(); A_USE_T0(); } static void ac_prim_sub_t0_mul_env_add_t0() //Aded by Gonetz { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CA_INVENV(); SETSHADE_A_PRIM(); SETSHADE_A_ENV(); A_USE_T0(); //(prim-t0)*env+t0 = prim*env + t0*(1-env) } static void ac_prim_sub_env_mul_t0_add_env() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CA_PRIM(); SETSHADE_A_ENV(); A_USE_T0(); } static void ac_prim_sub_env_mul_t1_add_env() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CA_PRIM(); SETSHADE_A_ENV(); A_USE_T1(); } static void ac_prim_sub_env_mul_t0_add_one() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CA (0xFF); SETSHADE_A_PRIMSUBENV(); A_USE_T0(); } //Added by Gonetz static void ac_prim_sub_env_mul_shade_add_env() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CA_ENV(); MULSHADE_A_PRIMSUBENV(); } //Added by Gonetz static void ac_prim_sub_env_mul_shade_add_env_mul_t1() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CA_ENV(); MULSHADE_A_PRIMSUBENV(); A_USE_T1(); } //Added by Gonetz static void ac_prim_sub_shade_mul_t0_add_shade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CA_PRIM(); A_USE_T0(); } //Added by Gonetz static void ac_one_sub_shade_mul_t1_add_shade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); A_USE_T1(); } //Added by Gonetz static void ac_one_sub_env_mul_shade_add_env() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CA_ENV(); } //Added by Gonetz static void ac_env_sub_prim_mul_t0_add_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CA_ENV(); SETSHADE_A_PRIM(); A_USE_T0(); } static void ac_one_sub_t1_add_t0_mul_env() { #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_TMU_CALPHA, 0, GR_CMBX_B, 1); cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (g_gdp.env_color.total&0xFF); cmb.tex |= 3; ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); } #ifndef HAVE_ASSUME_COMBINE_EXT else { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_ENV(); A_T0_ADD_T1(); cmb.tmu1_a_invert = FXTRUE; } #endif } static void ac_env_sub_prim_mul_shade_add_prim() //Added by Gonetz { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CA_PRIM(); MULSHADE_A_ENVSUBPRIM(); } static void ac_env_sub_primshade_mul_t1_add_primshade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CA_ENV(); MULSHADE_A_PRIM(); A_USE_T1(); } static void ac_one_sub_prim_mul_t0_add_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CA (0xFF); SETSHADE_A_PRIM(); A_USE_T0(); } static void ac_one_sub_prim_mul_t0_add__prim_mul_env() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT); CA_INVPRIM(); SETSHADE_A_PRIM(); SETSHADE_A_ENV(); A_USE_T0(); } static void ac_shade_sub_t0_mul_primlod_add_prim() { #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { T0ACMBEXT(GR_CMBX_ITALPHA, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_TMU_CALPHA, 0, GR_CMBX_ZERO, 0); cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (lod_frac&0xFF); cmb.tex |= 1; ACMBEXT(GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 1, GR_CMBX_TEXTURE_ALPHA, 0); CA_PRIM(); } #ifndef HAVE_ASSUME_COMBINE_EXT else { ac_t0(); } #endif } static void ac_shade_sub_env_mul_t0_add_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); SUBSHADE_A_ENV(); CA_PRIM(); A_USE_T0(); } // ** A inter B using C ** static void ac_t0_inter_t1_using_prima() { uint8_t factor = g_gdp.prim_color.a; ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); A_T0_INTER_T1_USING_FACTOR (factor); } static void ac_t1_inter_t0_using_prima() { uint8_t factor = g_gdp.prim_color.a; ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); A_T1_INTER_T0_USING_FACTOR (factor); } static void ac_t0_inter_t1_using_primlod() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); A_T0_INTER_T1_USING_FACTOR (lod_frac); } static void ac_t0_inter_t1_using_enva() { uint8_t factor = g_gdp.env_color.a; ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); A_T0_INTER_T1_USING_FACTOR (factor); } static void ac_t1_inter_t0_using_enva() { uint8_t factor = g_gdp.env_color.a; ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); A_T1_INTER_T0_USING_FACTOR (factor); } //Added by Gonetz static void ac_t0_inter_t1_using_t0a() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); A_T0_INTER_T1_USING_T0A(); } //Added by Gonetz static void ac_t0_inter_t1_using_t1a() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); A_T0_INTER_T1_USING_T1A(); } //Added by Gonetz static void ac_t0_inter_t1_using_shadea() { #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); } #ifndef HAVE_ASSUME_COMBINE_EXT else { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE); } #endif A_T0_INTER_T1_USING_SHADEA(); } // ** (A inter B using C) * D ** static void ac__t0_inter_t1_using_primlod__mul_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); A_T0_INTER_T1_USING_FACTOR (lod_frac); } static void ac__t1_mul_primlod_add_t0__mul_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); A_T1_MUL_PRIMLOD_ADD_T0(); } static void ac__t0_inter_t1_using_primlod__mul_env() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_ENV(); A_T0_INTER_T1_USING_FACTOR (lod_frac); } static void ac__t1_mul_primlod_add_t0__mul_env() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_ENV(); A_T1_MUL_PRIMLOD_ADD_T0(); } static void ac__t0_inter_t1_using_primlod__mul_shade() { if (settings.hacks & hack_Makers) { //rolling rock issue - it has zero shade alpha and thus rejected by alpha compare ac_t0_inter_t1_using_primlod(); return; } ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); A_T0_INTER_T1_USING_FACTOR (lod_frac); } static void ac__t1_mul_primlod_add_t0__mul_shade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); A_T1_MUL_PRIMLOD_ADD_T0(); } //Added by Gonetz static void ac__t0_inter_t1_using_prima__mul_env() { uint8_t factor = g_gdp.prim_color.a; ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_ENV(); A_T0_INTER_T1_USING_FACTOR (factor); } //Added by Gonetz static void ac__t1_inter_t0_using_t0a__mul_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); A_T1_INTER_T0_USING_T0A(); } static void ac__t1_inter_t0_using_primlod__mul_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); A_T0_INTER_T1_USING_FACTOR (lod_frac); } static void ac__t1_inter_t0_using_prima__mul_env() { uint8_t factor = g_gdp.prim_color.a; ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_ENV(); A_T1_INTER_T0_USING_FACTOR (factor); } //Added by Gonetz static void ac__t0_inter_t1_using_prima__mul_shade() { uint8_t factor = g_gdp.prim_color.a; ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); A_T0_INTER_T1_USING_FACTOR (factor); } static void ac__t1_inter_t0_using_prima__mul_shade() { uint8_t factor = g_gdp.prim_color.a; ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); A_T1_INTER_T0_USING_FACTOR (factor); } static void ac__t0_inter_t1_using_enva__mul_prim() { uint8_t factor = g_gdp.env_color.a; ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); A_T0_INTER_T1_USING_FACTOR (factor); } static void ac__env_sub_one_mul_t1_add_t0__mul_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { T1ACMBEXT(GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0, GR_CMBX_ZERO, 0); T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_ZERO, 1, GR_CMBX_ZERO, 0); SETSHADE_A(0xFF); cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (g_gdp.env_color.total&0xFF) ; cmb.tex |= 3; } #ifndef HAVE_ASSUME_COMBINE_EXT else { uint8_t factor = g_gdp.env_color.a; A_T0_INTER_T1_USING_FACTOR (factor); } #endif } static void ac__t0_inter_t1_using_enva__mul_primlod() { uint8_t factor = g_gdp.env_color.a; ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIMLOD(); A_T0_INTER_T1_USING_FACTOR (factor); } static void ac__t1_mul_enva_add_t0__sub_prim_mul_shade() { #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITALPHA, 0, GR_CMBX_ZERO, 0); CA_PRIM(); } #ifndef HAVE_ASSUME_COMBINE_EXT else { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); MULSHADE_A_PRIM(); } #endif A_T1_MUL_ENVA_ADD_T0(); } //Added by Gonetz static void ac__t0_inter_t1_using_t0a__mul_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); A_T0_INTER_T1_USING_T0A(); } //Added by Gonetz static void ac__t0_inter_t1_using_t1a__mul_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); A_T0_INTER_T1_USING_T1A(); } static void ac__t0_inter_t1_using_t1a__mul_shade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); A_T0_INTER_T1_USING_T1A(); } //Added by Gonetz static void ac__t0_inter_t1_using_shadea__mul_prim() { #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_CONSTANT_ALPHA, 0, GR_CMBX_ZERO, 0); A_T0_INTER_T1_USING_SHADEA(); } #ifndef HAVE_ASSUME_COMBINE_EXT else { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); A_T0_INTER_T1_USING_FACTOR (0x7F); } #endif CA_PRIM(); } //Added by Gonetz static void ac__t0_inter_t1_using_shadea__mul_env(void) { #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_CONSTANT_ALPHA, 0, GR_CMBX_ZERO, 0); A_T0_INTER_T1_USING_SHADEA(); } #ifndef HAVE_ASSUME_COMBINE_EXT else { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); A_T0_INTER_T1_USING_FACTOR (0x7F); } #endif CA_ENV(); } static void ac__t0_inter_t1_using_primlod__sub_env_mul_shade_add_shade(void) { #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_ITALPHA, 0, GR_CMBX_ALOCAL, 0); CA_ENV(); A_T0_INTER_T1_USING_FACTOR (lod_frac); } #ifndef HAVE_ASSUME_COMBINE_EXT else { ac__t0_inter_t1_using_primlod__mul_shade(); } #endif } //Added by Gonetz static void ac__t0_inter_t1_using_enva__mul_shade() { uint8_t factor = g_gdp.env_color.a; ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); A_T0_INTER_T1_USING_FACTOR (factor); } static void ac__t0_inter_t1_using_primlod__mul_prim_add_env() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CA_ENV(); SETSHADE_A_PRIM(); A_T0_INTER_T1_USING_FACTOR (lod_frac); } //Added by Gonetz static void ac__t0_inter_t1_using_primlod__mul_shade_add_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); CA_PRIM(); A_T0_INTER_T1_USING_FACTOR (lod_frac); } //Added by Gonetz static void ac__t0_inter_t1_using_primlod__mul_env_add__t0_inter_t1_using_primlod() { #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { ACMBEXT(GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_ALPHA, 0, GR_CMBX_B, 0); CA_ENV(); } #ifndef HAVE_ASSUME_COMBINE_EXT else { ACMB (GR_COMBINE_FUNCTION_BLEND, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); SETSHADE_A_ENV(); CA (0xFF); } #endif A_T0_INTER_T1_USING_FACTOR (lod_frac); } static void ac__t1_sub_one_mul_enva_add_t0__mul_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (0xFF) ; cmb.tex |= 3; cmb.dc0_detailmax = cmb.dc1_detailmax = (g_gdp.env_color.total&0xFF) / 255.0f; } #ifndef HAVE_ASSUME_COMBINE_EXT else { // (t1-1)*env+t0, (cmb-0)*prim+0 A_T0_MUL_T1(); MOD_1 (TMOD_TEX_SCALE_FAC_ADD_FAC); MOD_1_FAC (g_gdp.env_color.total & 0xFF); } #endif } static void ac__one_inter_t0_using_prim__mul_env() { #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_B, 0); cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (0xFF) ; cmb.tex |= 1; cmb.dc0_detailmax = cmb.dc1_detailmax = (g_gdp.prim_color.total&0xFF) / 255.0f; ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_CONSTANT_ALPHA, 0, GR_CMBX_ZERO, 0); CA_ENV(); } #ifndef HAVE_ASSUME_COMBINE_EXT else { ac_t0_mul_prim_add_env(); } #endif } static void ac__t1_sub_one_mul_enva_add_t0__mul_shade() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE); CA_PRIM(); #ifndef HAVE_ASSUME_COMBINE_EXT if (cmb.combine_ext) #endif { T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, GR_CMBX_DETAIL_FACTOR, 0, GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | 0xFF ; percent = (float)g_gdp.env_color.a; cmb.dc0_detailmax = cmb.dc1_detailmax = percent; cmb.tex |= 3; } #ifndef HAVE_ASSUME_COMBINE_EXT else { uint8_t factor = (uint8_t)g_gdp.env_color.a; A_T0_INTER_T1_USING_FACTOR (factor); } #endif } static void ac_zero_sub_prim_mul_t0_add_prim() { ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_ITERATED); SETSHADE_A (0); CA_PRIM(); A_USE_T0(); } static void ac_one_sub_t0_mul_primshade() { ACMB (GR_COMBINE_FUNCTION_BLEND_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_NONE); MULSHADE_A_PRIM(); A_USE_T0(); } //**************************************************************** // Combine List // // 3/13/02: I have converted the combine descriptions, now using // the correct values for each slot, instead of a one-for-all- // slot version. All of the descriptions marked with 'z' have // not yet been converted or checked. I have not totally redone // the modes, because they should be for the most part correct // as they are, even with the wrong descriptions. [Dave2001] //**************************************************************** typedef void (*cmb_func)(); typedef struct { uint32_t key; cmb_func func; } COMBINER; static COMBINER color_cmb_list[] = { // { #CCSTART } // intro, Aidyn Chronicles. Added by Gonetz // (0-cmb)*env+cmb, (t1-t0)*0+t0 {0x05083812, cc_t0}, //terminal, Spacestation Silicon Valley. Added by Gonetz // (0-0)*0+cmb, (0-0)*0+prim {0x1fff7fff, cc_prim}, //chip in Spacestation Silicon Valley intro. Added by Gonetz // (0-0)*0+cmb, (prim-0)*shade+0 {0x1fffe4f3, cc_prim_mul_shade}, // car, beetle adventure racing. Added by Gonetz // (t1-t0)*t0+t0, (cmb-shade)*prima+shade **can work incorrect** {0x21128a40, cc__t0_inter_t1_using_t0__sub_shade_mul_prima_add_shade}, // Treasure opening, zelda // (t1-prim)*t0+t0, (prim-env)*cmb+env {0x2132a053, cc_prim_sub_env_mul__t1_sub_prim_mul_t0_add_t0__add_env}, // yellow carpet, Pokemon Stadium 2 // (t1-env)*t0+t0, (cmb-0)*shade+0 {0x2152e4f0, cc__t1_sub_env_mul_t0_add_t0__mul_shade}, // Water, doubut no mori // (t1-0)*t0+t0, (prim-0)*shade+cmb {0x21f204f3, cc__t1_mul_t0_add_t0__add_prim_mul_shade}, // enemy transparent, paper mario. Addd by Gonetz // (t1-t0)*t1+t0, (env-prim)*cmb+prim {0x22126035, cc_env_sub_prim_mul__t0_inter_t1_using_t1__add_prim}, // snowhead temple, zelda 2. Addd by Gonetz // (t1-t0)*t1+t0, (cmb-0)*shade+prim {0x221264f0, cc__t0_inter_t1_using_t1__mul_shade_add_prim}, // snowhead temple entrance, zelda 2. Addd by Gonetz // (t1-t0)*t1+t0, (cmb-0)*prim+shade {0x221283f0, cc__t0_inter_t1_using_t1__mul_prim_add_shade}, // teleportation, Spacestation Silicon Valley. Added by Gonetz // (t1-t0)*t1+t0, (prim-env)*cmb+env {0x2212a053, cc_prim_sub_env_mul__t0_inter_t1_using_t1__add_env}, // pokemon fainted, Pokemon Stadium 2 // (prim-t0)*t1+t0 {0x22132213, cc_prim_sub_t0_mul_t1_add_t0}, // attack, Ogre Battle 64 // (1-t0)*t1+t0, (cmb-0)*prim+0 {0x2216e3f0, cc__t0_inter_one_using_t1__mul_prim}, // Some gannon spell, zelda // (t1-0)*t1+t0, (prim-0)*cmb+0 {0x22f2e0f3, cc__t1_mul_t1_add_t0__mul_prim}, // battle tanks 2 [Ogy] // (1-0)*t1+t0, (env-prim)*cmb+prim {0x22f66035, cc_env_sub_prim_mul__t0_add_t1__add_prim}, // GASP Fighters // (1-0)*t1+t0, (shade-0)*cmb+0 {0x22f6e0f4, cc__t0_add_t1__mul_shade}, // parts of a car, F1 World Grand Prix. Added by Gonetz // (1-0)*t1+t0, (cmb-0)*shade+0 {0x22f6e4f0, cc__t0_add_t1__mul_shade}, // ???, zelda // (noise-0)*t1+t0, (prim-env)*cmb+env {0x22f7a053, cc_prim_sub_env_mul__t0_add_t1__add_env}, // flashing arrow over buoy, wave race. Added by Gonetz // (t1-t0)*prim+t0, (env-cmb)*enva+cmb ** INC ** {0x23120c05, cc__t0_inter_t1_using_prim__inter_env_using_enva}, // ground, zelda2. Added by Gonetz // (t1-t0)*prim+t0, (cmb-0)*shade+0 {0x2312e4f0, cc__t0_inter_t1_using_prim__mul_shade}, // wwf rules // (env-t0)*prim+t0 {0x23152315, cc_t0_inter_env_using_prim}, // Paper Mario // (1-t0)*prim+t0, (1-t0)*t0+cmb ** INC ** {0x23160116, cc_t0_add_prim_mul_one_sub_t0_add_t0}, // intro, castlevania. Added by Gonetz // (1-t0)*prim+t0 {0x23162316, cc_one_sub_t0_mul_prim_add_t0}, // Explosions, aerofighter's assault // (1-t0)*prim+t0, (shade-0)*cmb+0 {0x2316e0f4, cc_t0_mul_shade}, //beetle adventure racing. Added by Gonetz // (1-t0)*prim+t0, (cmb-0)*shade+0 **INC** {0x2316e4f0, cc__t0_inter_one_using_prim__mul_shade}, // Unknown player background, smash bros // (noise-t0)*prim+t0 ** INC ** // {0x23172317, cc_t0}, {0x23172317, cc_t0_inter_noise_using_prim}, // paper mario. Added by Gonetz // (noise-prim)*prim+t0 ** INC ** {0x23372337, cc_t0_add_prim}, // strange mirror in stone temple, zelda 2. Added by Gonetz // (prim-env)*prim+t0, (cmb-0)*prim+0 ** INC ** {0x2353e3f0, cc__prim_sub_env_mul_prim_add_t0__mul_prim}, // Gilded sword, zelda 2. Added by Gonetz // (shade-env)*prim+t0, (cmb-0)*shade+env ** INC ** {0x2354a4f0, cc__t0_add_prim_mul_shade__mul_shade_add_env}, // Razor sword, zelda 2. Added by Gonetz // (shade-env)*prim+t0, (cmb-0)*shade+0 ** INC ** {0x2354e4f0, cc__t0_add_prim_mul_shade__mul_shade}, // menu, Mischief Makers. Added by Gonetz // (0-env)*prim+t0, (cmb-0)*shade+0 {0x235f235f, cc_t0_sub__prim_mul_env}, // Deadly Arts logo. Added by Gonetz // (t0-0)*prim+t0 {0x23f123f1, cc_t0_mul_prim}, // pokemon attack, Pokemon Stadium 2. Added by Gonetz // (shade-0)*prim+t0, (cmb-0)*shade+0 ** INC ** {0x23f4e4f0, cc_t0_mul_shade}, // Mischief Makers logo. Added by Gonetz // (env-0)*prim+t0 {0x23f523f5, cc_prim_mul_env_add_t0}, // Taken out bomb, zelda // (1-0)*prim+t0 {0x23f623f6, cc_t0_add_prim}, // waterfall, Dobutsu_no_Mori // (1-0)*prim+t0, (cmb-0)*shade+t0 {0x23f624f0, cc__t0_add_prim__mul_shade_add_t0}, // waterfall, Dobutsu_no_Mori // (1-0)*prim+t0, (cmb-0)*shade+t1 {0x23f644f0, cc__t0_add_prim__mul_shade_add_t1}, // Jabu-Jabu's Belly, zelda // (noise-0)*prim+t0 {0x23f723f7, cc_t0_add_prim}, // carmagedon // (0-0)*prim+t0 {0x23ff23ff, cc_t0}, // water, diddy kong racing. Added by Gonetz // (t1-t0)*shade+t0, (env-cmb)*env_a+cmb **INC** {0x24120c05, cc__t0_inter_t1_using_shade__inter_env_using_enva}, // Advertisement hoarding, Mia Soccer. Added by Gonetz // (t1-t0)*shade+t0, (1-0)*cmb+0 {0x2412e0f6, cc_t0_inter_t1_using_shade}, // ground, f-zero x // (prim-t0)*shade+t0 ** INC ** {0x24132413, cc__one_sub_prim_mul_shade__mul_t0_add__prim_mul_shade}, // intro, F1 Racing Championship. Added by Gonetz // (env-t0)*shade+t0 ** INC * {0x24152415, cc_one_sub_t0_mul_shade_add_t0}, // Sky, pilotwings // (1-t0)*shade+t0 {0x24162416, cc_one_sub_t0_mul_shade_add_t0}, // zelda 2 [Ogy]. Added by Gonetz // (prim-env)*shade+t0, (prim-prim)*shade+cmb ** INC ** ? {0x24530433, cc_prim_sub_env_mul_shade_add_t0}, // waves, Dr. Mario // (0-center)*shade+t0 {0x246f246f, cc_t0_sub__shade_mul_center}, // lums, Rayman2. Added by Gonetz // (t0-0)*shade+t0 ** INC ** {0x24f124f1, cc_t0}, //this one works better // {0x24f124f1, cc_t0_mul_shade}, // Goemon, mystical ninja. Added by Gonetz // (prim-0)*shade+t0 {0x24f324f3, cc_prim_mul_shade_add_t0}, // Sky, waverace //z (t1-t0)*env+t0 ** INC ** {0x25122512, cc_t0_inter_t1_using_env}, // Rare logo, Jet Force. Added by Gonetz // (t1-t0)*env+t0, (cmb-0)*prim+0 ** INC ** {0x2512e3f0, cc__t0_inter_t1_using_enva__mul_prim}, // ridge recer, unimp log. Added by Gonetz // (t1-t0)*env+t0, (cmb-0)*shade+0 ** INC ** {0x2512e4f0, cc__t0_inter_t1_using_env__mul_shade}, // menu, Mischief Makers. Added by Gonetz //(prim-t0)*env+t0 ** INC ** {0x25132513, cc_one_sub_env_mul_t0_add_prim_mul_env}, // Battle border, quest64 // (1-t0)*env+t0 {0x25162516, cc_one_sub_env_mul_t0_add_env}, // Paper Mario // (noise-t0)*env+t0 {0x25172517, cc_t0_inter_noise_using_env}, // the lamp in the bomb shop in town, zelda 2 [Ogy]. Added by Gonetz // (t0-t1)*env+t0, (1-env)*prim+cmb ** INC ** {0x25210356, cc_one_sub_env_mul_prim_add__t0_inter_t1_using_env}, // Darmani's necklace, zelda 2 [Ogy]. Added by Gonetz // (prim-shade)*env+t0, (cmb-0)*shade+0 ** INC ** {0x2543e4f0, cc_t0_mul_shade_add_prim_mul_env}, // {0x2543e4f0, cc_t0_mul_shade}, // mystical ninja. Added by Gonetz // (1-0)*env+t0 {0x25f625f6, cc_t0_add_env}, // smoke, Starshot. Added by Gonetz // (1-0)*env+t0, (1-0)*cmb+0 {0x25f6e0f6, cc_t0_add_env}, // mega shock, Paper Mario. Added by Gonetz // (t1-0)*scale+t0, (env-center)*cmb+prim {0x26f26065, cc__t0_add__t1_mul_scale__mul_env_sub_center_add_prim}, // character select, Duck Dodgers. Added by Gonetz // (prim-t0)*t0_alpha+t0, (cmb-0)*shade+0 **INC** {0x2813e4f0, cc__t0_inter_prim_using_t0a__mul_shade}, // intro, Duck Dodgers. Added by Gonetz // (shade-t0)*t0_alpha+t0 **INC** {0x28142814, cc_t0_inter_shade_using_t0a}, // vermilion gym torches, Pokemon Stadium 2. // (prim-env)*t0_a+t0, (cmb-cmb)*cmb+cmb {0x28530000, cc_prim_sub_env_mul_t0a_add_t0}, // F1 World Grand Prix. Added by Gonetz // (prim-0)*t0_a+t0, (cmb-0)*shade+0 ** INC ** {0x28f3e4f0, cc__t0a_mul_prim_add_t0__mul_shade}, // battle tanks 2 [Ogy] // (env-0)*t0_a+t0, (cmb-0)*shade+0 {0x28f5e4f0, cc__t0a_mul_env_add_t0__mul_shade}, // blastcorps, unimp log. Added by Gonetz // (t1-t0)*t1_alpha+t0 {0x29122912, cc_t0_inter_t1_using_t1a}, // paper mario. Added by Gonetz // (t1-t0)*t1_alpha+t0, (cmb-env)*env_a+env {0x2912ac50, cc__t0_inter_t1_using_t1a__sub_env_mul_enva_add_env}, // Rally 2000. Added by Gonetz // (t1-t0)*t1_alpha+t0, (cmb-0)*shade+0 {0x2912e4f0, cc__t0_inter_t1_using_t1a__mul_shade}, // ??? in zelda ending, zelda // (1-0)*t1_alpha+t0, (prim-env)*cmb+env {0x29f6a053, cc_prim_sub_env_mul__t0_add_t1a__add_env}, // Sky, zelda //z (t1-t0)*prim_a+t0 {0x2a122a12, cc_t0_inter_t1_using_prima}, // battle tanks [Ogy] // (t1-t0)*prim_a+t0, (env-prim)*cmb+prim {0x2a126035, cc_env_sub_prim_mul__t0_inter_t1_using_prima__add_prim}, // clothes, zelda 2. Added by Gonetz // (t1-t0)*prim_a+t0, (prim-env)*cmb+env {0x2a12a053, cc_prim_sub_env_mul__t0_inter_t1_using_prima__add_env}, // N64 BIOS // (t1-t0)*prim_a+t0, (cmb-0)*shade+0 {0x2a12e0f4, cc__t0_inter_t1_using_prima__mul_shade}, // flame, Doraemon 2. Added by Gonetz // (t1-t0)*prim_a+t0, (cmb-0)*prim+0 {0x2a12e3f0, cc__t0_inter_t1_using_prima__mul_prim}, // logo, PD. Added by Gonetz // (t1-t0)*prim_a+t0, (cmb-0)*shade+0 {0x2a12e4f0, cc__t0_inter_t1_using_prima__mul_shade}, // Pikachu // (prim-t0)*prim_a+t0, (env-cmb)*enva+cmb {0x2a130c05, cc__t0_inter_prim_using_prima__inter_env_using_enva}, // 1080 snowboarding [Ogy] - 7/03/02 fixed by Dave2001. 15 Mar 2005 fixed by Gonetz. // (prim-t0)*prim_a+t0 {0x2a132a13, cc_t0_inter_prim_using_prima}, // menu background, Paper Mario // (prim-t0)*prim_a+t0, (prim-t1)*prim_a+t1 {0x2a134a23, cc_t0_inter_prim_using_prima}, // {0x2a134a23, cc_t0}, // Mickey USA // (prim-t0)*prim_a+t0, (cmb-0)*shade+0 ** INC ** {0x2a13e4f0, cc_t0_mul_shade}, // gunfire, Sin and Punishmen. Added by Gonetz // (env-t0)*prima+t0 **INC** {0x2a152a15, cc_t0_inter_env_using_prima}, // Mystical Ninja // (0-t0)*prima+t0, (prim-env)*cmb+env ** INC ** {0x2a1fa053, cc_prim_sub_env_mul__t0_sub_t0_mul_prima__add_env}, // foresight attack, Pokemon Stadium 2. // (t1-prim)*prim_a+t0, (prim-env)*cmb+env {0x2a32a053, cc_prim_sub_env_mul__t1_sub_prim_mul_prima_add_t0__add_env}, // arena, Pokemon Stadium 2. Added by Gonetz // (shade-prim)*prim_a+t0 ** INC ** {0x2a342a34, cc_t0_mul_shade}, // Torches, Paper Mario // (t1-k4)*prim_a+t0, (t1-k4)*cmb_a+cmb ** INC ** {0x2a720772, cc_t1_sub_k4_mul_prima_add_t0}, // GASP Fighters. Added by Gonetz // (t0-0)*prim_a+t0, (cmb-center)*scale+0 ** INC ** {0x2af1e660, cc__t0_mul_prima_add_t0__sub_center_mul_scale}, // F1 World Grand Prix. Added by Gonetz // (t1-0)*prim_a+t0, (cmb-0)*shade+env {0x2af2a4f0, cc__t1_mul_prima_add_t0__mul_shade_add_env}, // tidal wave, Paper Mario. Added by Gonetz // (prim-0)*prim_a+t0 {0x2af32af3, cc_prim_mul_prima_add_t0}, //Spacestation Silicon Valley intro. Added by Gonetz // (t1-t0)*shade_alpha+t0, (prim-shade)*cmb+shade ** INC ** {0x2b128043, cc_prim_sub_shade_mul__t0_inter_t1_using_shadea__add_shade}, // water, Rocket Robot in Wheels // (t1-t0)*shade_alpha+t0, (env-shade)*cmb+shade ** INC ** {0x2b128045, cc_env_sub_shade_mul__t0_inter_t1_using_shadea__add_shade}, // arena, Pokemon Stadium 2 // (t1-t0)*shade_alpha+t0, (cmb-prim)*env+shade ** INC ** {0x2b128530, cc__t0_inter_t1_using_shadea__sub_prim_mul_env_add_shade}, // Rocket Robot in Wheels intro // (t1-t0)*shade_a+t0, (shade-0)*cmb+0 ** INC ** {0x2b12e0f4, cc__t0_inter_t1_using_shadea__mul_shade}, // water, Mickey USA // (t1-t0)*shade_a+t0, (cmb-0)*shade+0 ** INC ** {0x2b12e4f0, cc__t0_inter_t1_using_shadea__mul_shade}, // Extreme G. Added by Gonetz // (shade-t0)*shade_alpha+t0 {0x2b142b14, cc_shade_sub_t0_mul_shadea_add_t0}, // Jet Force Gemini. Added by Gonetz // (shade-t0)*shade_alpha+t0, (cmb-0)*prim+0 ** INC ** {0x2b14e3f0, cc_t0_mul_prim_add_shade_mul_shadea_mul_prim}, // V8-2 // (env-t0)*shade_alpha+t0, (cmb-0)*shade+0 ** INC ** {0x2b15e4f0, cc__t0_inter_env_using_shadea__mul_shade}, // Earthquake pokemon attack, Pokemon Stadium 2 [gokuss4]. Added by Gonetz // (t1-0)*shade_alpha+t0, (prim-env)*cmb+env ** INC ** {0x2bf2a053, cc_prim_sub_env_mul__t0_add_t1__add_env}, // pads, Pokemon Stadium 2. Added by Gonetz // (0-0)*shade_alpha+t0, (prim-env)*cmba+env {0x2bffa753, cc_prim_sub_env_mul_t0a_add_env}, // paper mario. Added by Gonetz // (t1-t0)*env_a+t0, (1-cmb)*prim+cmb {0x2c120306, cc_one_sub__t0_inter_t1_using_enva__mul_prim_add__t0_inter_t1_using_enva}, // Amoeba boss, water temple, zelda // (t1-t0)*env_a+t0, (cmb-env)*prim+t0 ** INC ** {0x2c122350, cc__t0_inter_t1_using_enva__sub_env}, // paper mario. Added by Gonetz // (t1-t0)*env_a+t0 {0x2c122c12, cc_t0_inter_t1_using_enva}, // paper mario. Added by Gonetz // (t1-t0)*env_a+t0, (1-prim)*cmb+prim {0x2c126036, cc_one_sub_prim_mul__t0_inter_t1_using_enva__add_prim}, //Arena, Pokemon Stadium 2 // (t1-t0)*env_a+t0, (cmb-0)*shade+prim {0x2c1264f0, cc__t0_inter_t1_using_enva__mul_shade_add_prim}, // water, jet force. Added by Gonetz // (t1-t0)*env_a+t0, (prim-shade)*cmb+shade {0x2c128043, cc_prim_sub_shade_mul__t0_inter_t1_using_enva__add_shade}, // Faries, zelda //z (t1-t0)*env_a+t0, (prim-env)*cmb+env {0x2c12a053, cc_prim_sub_env_mul__t0_inter_t1_using_enva__add_env}, // paper mario. Added by Gonetz // (t1-t0)*env_a+t0, (prim-center)*cmb+env {0x2c12a063, cc_prim_sub_center_mul__t0_inter_t1_using_enva__add_env}, // pads, Pokemon Stadium 2. Added by Gonetz // (t1-t0)*env_a+t0, (cmb-prim)*shade+env ** INC ** {0x2c12a430, cc__t0_inter_t1_using_enva__mul_shade_add_env}, // Scary dead thing boss, zelda // (t1-t0)*env_a+t0, (cmb-t1)*cmb_a+env {0x2c12a720, cc__t0_inter_t1_using_enva__mul_env}, // something in a menu, PokemonStadium2, [Raziel64] // (t1-t0)*env_a+t0, (prim-env)*cmb_a+env {0x2c12a753, cc_prim_sub_env_mul__t0_inter_t1_using_enva_alpha__add_env}, // Arena, pokemon Stadium // (t1-t0)*env_a+t0, (cmb-shade)*prim+0 {0x2c12e340, cc__t0_inter_t1_using_enva__sub_shade_mul_prim}, // Water in zora's place, zelda // (t1-t0)*env_a+t0, (cmb-0)*prim+0 {0x2c12e3f0, cc__t0_inter_t1_using_enva__mul_prim}, // Ground, zelda //z (t1-t0)*env_a+t0, (cmb-k5)*shade+cmb_a {0x2c12e4f0, cc__t0_inter_t1_using_enva__mul_shade}, // zelda, uninmp log. Added by Gonetz //(t1-t0)*env_a+t0, (cmb-0)*env+0 {0x2c12e5f0, cc__t0_inter_t1_using_enva__mul_env}, // Spheres, waverace //z (env-t0)*env_a+t0 {0x2c152c15, cc_t0_inter_env_using_enva},//cc_t0, // backgrounds, Mario Golf. Added by Gonetz // (env-t0)*env_a+t0, (shade-0)*cmb+0 {0x2c15e0f4, cc__t0_inter_env_using_enva__mul_shade}, // ground on Volcano level, DKR, [Raziel64] // (env-t0)*env_a+t0, (cmb-0)*shade+0 {0x2c15e4f0, cc__t0_inter_env_using_enva__mul_shade}, // Nintendo 'N', zelda //z (t0-prim)*env_a+t0, (prim-env)*cmb+env {0x2c31a053, cc_prim_sub_env_mul__t0_sub_prim_mul_enva_add_t0__add_env}, // Nintendo title & saria's song, zelda //z (t1-prim)*env_a+t0, (prim-env)*cmb+env {0x2c32a053, cc_prim_sub_env_mul__t1_sub_prim_mul_enva_add_t0__add_env}, // Hover boots flying, zelda // (t1-prim)*env_a+t0, (prim-0)*cmb+env {0x2c32a0f3, cc__t1_sub_prim_mul_enva_add_t0__mul_prim_add_env}, // star beam, paper mario // (prim-env)*env_a+t0 {0x2c532c53, cc_prim_sub_env_mul_enva_add_t0}, // Kotake & koume's hair, zelda // (t1-0)*env_a+t0, (prim-env)*cmb+env {0x2cf2a053, cc_prim_sub_env_mul__t1_mul_enva_add_t0__add_env}, //Goldeneye, [Jeremy]. Added by Gonetz // (t0-t0)*lodf+t0, (cmb-0)*prim+0 {0x2d11e3f0, cc_t0_mul_prim}, // Pilot wings // (t1-t0)*lodf+t0, (one-cmb)*prim+cmb {0x2d120306, cc_one_sub_prim_mul__t0_inter_t1_using_primlod__add_prim}, // Pilot wings // (t1-t0)*lodf+t0, (one-cmb)*shade+cmb {0x2d120406, cc_one_sub_shade_mul__t0_inter_t1_using_primlod__add_shade}, // Indy Racing 2000. Added by Gonetz // (t1-t0)*lodf+t0, (env-cmb)*prima+cmb ** INC ** {0x2d120a05, cc_t0_inter_t1_using_primlod}, // (t1-t0)*lodf+t0 {0x2d122d12, cc_t0_inter_t1_using_primlod}, //broken wall, beetle adventure racing. Added by Gonetz // (t1-t0)*lodf+t0, (shade-prim)*cmb+prim {0x2d126034, cc_shade_sub_prim_mul__t0_inter_t1_using_primlod__add_prim}, //Intro, CBFD. Added by Gonetz // (t1-t0)*lodf+t0, (shade-env)*cmb+prim // {0x2d126054, cc_shade_sub_env_mul_t0_add_prim}, {0x2d126054, cc_shade_sub_env_mul__t0_inter_t1_using_primlod__add_prim}, // bassmasters 2000 [Ogy] // (t1-t0)*lodf+t0, (env-0)*cmb+prim ** INC ** {0x2d1260f5, cc_t0_mul_env_add_prim}, // sign, CBFD. Added by Gonetz // (t1-t0)*lodf+t0, (cmb-env)*shade+prim ** INC ** {0x2d126450, cc__t0_inter_t1_using_primlod__sub_env_mul_shade_add_prim}, // {0x2d126450, cc_t0_sub_env_mul_shade_add_prim}, // landscape, Cruis'n Exotica. Added by Gonetz // (t1-t0)*lodf+t0, (cmb-0)*shade+prim {0x2d1264f0, cc__t0_inter_t1_using_primlod__mul_shade_add_prim}, // blast corps [Ogy] // (t1-t0)*lodf+t0, (0-0)*0+shade {0x2d129fff, cc__t0_inter_t1_using_primlod__mul_shade}, // End of level, zelda // (t1-t0)*lodf+t0, (prim-env)*cmb+env {0x2d12a053, cc_prim_sub_env_mul__t0_inter_t1_using_primlod__add_env}, // Rocket Robot in Wheels intro // (t1-t0)*lodf+t0, (shade-env)*cmb+env {0x2d12a054, cc_shade_sub_env_mul__t0_inter_t1_using_primlod__add_env}, // basket, Fox Sport // (t1-t0)*lodf+t0, (prim-env)*t0+env {0x2d12a153, cc_prim_sub_env_mul__t0_inter_t1_using_primlod__add_env}, // paper mario. Added by Gonetz // (t1-t0)*lodf+t0, (cmb-0)*prim+env ** INC ** {0x2d12a3f0, cc__t0_inter_t1_using_primlod__mul_prim_add_env}, // Tony Hawk Pro Skater // (t1-t0)*lodf+t0, (cmb-0)*shade+env {0x2d12a4f0, cc__t0_inter_t1_using_primlod__mul_shade_add_env}, // part of a building, Spiderman. Added by Gonetz // (t1-t0)*lodf+t0, (cmb-env)*cmba+env ** INC ** {0x2d12a750, cc_t0_inter_t1_using_primlod}, // Mike Piazza's Strike Zone // (t1-t0)*lodf+t0, (shade-prim)*cmb+0 {0x2d12e034, cc_shade_sub_prim_mul__t0_inter_t1_using_primlod}, // intro, F1 Racing Championship. Added by Gonetz // (t1-t0)*lodf+t0, (shade-env)*cmb+0 {0x2d12e054, cc_shade_sub_env_mul__t0_inter_t1_using_primlod}, // stands, F1 Racing Championship. Added by Gonetz // (t1-t0)*lodf+t0, (1-env)*cmb+0 {0x2d12e056, cc_one_sub_env_mul__t0_inter_t1_using_primlod}, // court, Mario Tennis. Added by Gonetz // (t1-t0)*lodf+t0, (prim-0)*cmb+0 {0x2d12e0f3, cc__t0_inter_t1_using_primlod__mul_prim}, // Rocket Robot in Wheels intro // (t1-t0)*lodf+t0, (shade-0)*cmb+0 {0x2d12e0f4, cc__t0_inter_t1_using_primlod__mul_shade}, // Pilot wings // (t1-t0)*lodf+t0, (cmb-0)*t0+0 ** INC ** {0x2d12e1f0, cc_t0_inter_t1_using_primlod}, // cars wheels, SF Rush 2049. Added by Gonetz // (t1-t0)*lodf+t0, (cmb-0)*prim+0 {0x2d12e3f0, cc__t0_inter_t1_using_primlod__mul_prim}, // Bridge, sf rush // (t1-t0)*lodf+t0, (cmb-0)*shade+0 // {0x2d12e4f0, cc_t0_mul_shade}, {0x2d12e4f0, cc__t0_inter_t1_using_primlod__mul_shade}, // blast corps [Ogy] // (t1-t0)*lodf+t0, (t0-0)*shade+0 {0x2d12e4f1, cc_t0_mul_shade}, // field, Mike Piazza's Strike Zone // (t1-t0)*lodf+t0, (cmb-prim)*env+0 ** INC ** {0x2d12e530, cc__t0_inter_t1_using_primlod__mul_env}, // radar, Perfect Dark // (t1-t0)*lodf+t0, (cmb-0)*env+0 {0x2d12e5f0, cc__t0_inter_t1_using_primlod__mul_env}, // planet, Blast Corps // (t1-t0)*lodf+t0, (cmb-0)*prima+0 {0x2d12eaf0, cc__t0_inter_t1_using_primlod__mul_prima}, // zelda 2. Added by Gonetz // (t0-t0)*primlod+t0, (prim-env)*cmb+env {0x2e11a053, cc_prim_sub_env_mul_t0_add_env}, // zelda 2. Added by Gonetz // (t1-t0)*primlod+t0, (0-0)*shade+cmb {0x2e1204ff, cc_t0_inter_t1_using_primlod}, // zelda 2. Added by Gonetz // (t1-t0)*primlod+t0, (env-prim)*primlod+cmb {0x2e120d35, cc_prim_sub_env_mul_primlod_add__t0_inter_t1_using_primlod}, // lamppost, Ridge Racer. Added by Gonetz // (t1-t0)*primlod+t0 {0x2e122e12, cc_t0_inter_t1_using_primlod}, // Hearts, zelda //z (t1-t0)*primlod+t0, (shade-prim)*cmb+prim {0x2e126034, cc_shade_sub_prim_mul__t0_inter_t1_using_primlod__add_prim}, // Sunny Day, Pokemon Stadium 2 [gokuss4]. Added by Gonetz // (t1-t0)*primlod+t0, (env-prim)*cmb+prim {0x2e126035, cc_env_sub_prim_mul__t0_inter_t1_using_primlod__add_prim}, // snowhead temple, zelda 2. Added by Gonetz // (t1-t0)*primlod+t0, (cmb-env)*shade+prim ** INC ** {0x2e126450, cc__t0_inter_t1_using_primlod__mul_shade_add_prim}, // snow on a wall, snowhead temple, zelda 2. Added by Gonetz // (t1-t0)*primlod+t0, (cmb-0)*shade+prim {0x2e1264f0, cc__t0_inter_t1_using_primlod__mul_shade_add_prim}, // Morning Sun, Pokemon Stadium 2 [gokuss4]. Added by Gonetz // (t1-t0)*primlod+t0, (cmb-0)*0+prim {0x2e127ff0, cc_prim}, // arena, Pokemon Stadium 2. Added by Gonetz // (t1-t0)*primlod+t0, (cmb-prim)*shade+shade ** INC ** {0x2e128430, cc__t0_inter_t1_using_primlod__mul_shade}, // Pokemon Stadium 2. Added by Gonetz // (t1-t0)*primlod+t0, (cmb-env)*cmb+env ** INC ** {0x2e12a050, cc_t0_inter_t1_using_primlod}, // End of level heart, zelda // (t1-t0)*primlod+t0, (prim-env)*cmb+env {0x2e12a053, cc_prim_sub_env_mul__t0_inter_t1_using_primlod__add_env}, // Huge turtle appearance, zelda 2. Added by Gonetz // (t1-t0)*primlod+t0, (1-env)*cmb+env {0x2e12a056, cc_one_sub_env_mul__t0_inter_t1_using_primlod__add_env}, // frozen octorok, zelda 2. Added by Gonetz // (t1-t0)*primlod+t0, (prim-env)*t1+env {0x2e12a253, cc_prim_sub_env_mul_t1_add_env}, // fall headwaters, zelda 2. Added by Gonetz // (t1-t0)*primlod+t0, (cmb-env)*shade+env ** INC ** {0x2e12a450, cc__t0_inter_t1_using_primlod__sub_env_mul_shade_add_env}, // Fissure attack, pokemon stadium 2 // (t1-t0)*primlod+t0, (prim-env)*cmb_a+env {0x2e12a753, cc_prim_sub_env_mul__t0_inter_t1_using_primlod__add_env}, // zelda 2. Added by Gonetz // (t1-t0)*primlod+t0, (cmb-0)*t1+0 ** INC ** ? {0x2e12e2f0, cc_t0_inter_t1_using_primlod}, // zelda 2. Added by Gonetz // (t1-t0)*primlod+t0, (cmb-0)*prim+0 {0x2e12e3f0, cc__t0_inter_t1_using_primlod__mul_prim}, // sky, PGA European Tour // (t1-t0)*primlod+t0, (cmb-env)*shade+0 ** INC ** {0x2e12e450, cc__t0_inter_t1_using_primlod__mul_shade}, // Kirby's pool, smash bros // (t1-t0)*primlod+t0, (cmb-0)*shade+0 {0x2e12e4f0, cc__t0_inter_t1_using_primlod__mul_shade}, //Spacestation Silicon Valley intro. Added by Gonetz // (prim-t0)*primlod+t0, (cmb-0)*shade+0 **INC** {0x2e132e13, cc_t0_inter_prim_using_primlod}, // explosions, daikatana. Added by Gonetz // (prim-t0)*primlod+t0, (cmb-0)*shade+0 **INC** {0x2e13e4f0, cc_t0_mul_shade}, //Mike Piazza's Strike Zone logo. Added by Gonetz // (shade-t0)*primlod+t0 {0x2e142e14, cc_t0_inter_shade_using_primlod}, // Cartridge color (transfer pak), Pokemon Stadium 2 [gokuss4]. Added by Gonetz // (1-t0)*primlod+t0 {0x2e162e16, cc_one_sub_t0_mul_primlod_add_t0}, // pokemon attack, Pokemon Stadium 2. Added by Gonetz // (1-t0)*primlod+t0, (prim-0)*cmb+0 {0x2e16e0f3, cc__t0_inter_one_using_primlod__mul_prim}, // Spider Web attack, Pokemon Stadium 2. // (1-t0)*primlod+t0, (cmb-0)*prim+0 {0x2e16e3f0, cc__t0_inter_one_using_primlod__mul_prim}, // pokemon attack, Pokemon Stadium 2. Added by Gonetz // (1-t0)*primlod+t0, (cmb-0)*shade+0 {0x2e16e4f0, cc__t0_inter_one_using_primlod__mul_shade}, // zelda 2. Added by Gonetz // (t1-t1)*primlod+t0, (prim-env)*cmb+env {0x2e22a053, cc_prim_sub_env_mul_t0_add_env}, // Shadow Ball, Pokemon Stadium 2 [gokuss4]. Added by Gonetz // (0-t1)*primlod+t0, (prim-env)*cmb+env ** INC ** {0x2e2fa053, cc_prim_sub_env_mul_t0_add_env}, // Skulltula coin solid, zelda // (t0-prim)*primlod+t0, (prim-env)*cmb+env {0x2e31a053, cc_prim_sub_env_mul__t0_sub_prim_mul_primlod_add_t0__add_env}, // Triforce lines, zelda // (t1-prim)*primlod+t0, (prim-shade)*cmb+shade {0x2e328043, cc_prim_sub_shade_mul__t1_sub_prim_mul_primlod_add_t0__add_shade}, // moon when majora defeated, zelda 2. Added by Gonetz // (t1-prim)*primlod+t0, (1-shade)*cmb+shade {0x2e328046, cc_one_sub_shade_mul__t1_sub_prim_mul_primlod_add_t0__add_shade}, // Fire, zelda //z (t1-prim)*primlod+t0, (prim-env)*cmb+env ** INC ** {0x2e32a053, cc_prim_sub_env_mul__t1_sub_prim_mul_primlod_add_t0__add_env}, // zelda 2 [Ogy]. Added by Gonetz // (t1-prim)*primlod+t0, (shade-env)*cmb+env {0x2e32a054, cc_shade_sub_env_mul__t1_sub_prim_mul_primlod_add_t0__add_env}, // Scary face, pokemon stadium 2 // (t1-prim)*primlod+t0, (1-env)*cmb+env {0x2e32a056, cc_one_sub_env_mul__t1_sub_prim_mul_primlod_add_t0__add_env}, // zelda 2. Added by Gonetz // (t1-prim)*primlod+t0, (prim-0)*cmb+env {0x2e32a0f3, cc__t1_sub_prim_mul_primlod_add_t0__mul_prim_add_env}, // zelda 2. Added by Gonetz // (t1-0)*primlod+t0, (prim-env)*cmb+env {0x2ef2a053, cc_prim_sub_env_mul__t1_mul_primlod_add_t0__add_env}, // zelda 2. Added by Gonetz // (t1-0)*primlod+t0, (cmb-0)*prim+0 {0x2ef2e3f0, cc__t1_mul_primlod_add_t0__mul_prim}, // zelda 2. Added by Gonetz // (t1-0)*primlod+t0, (cmb-0)*env+0 {0x2ef2e5f0, cc__t1_mul_primlod_add_t0__mul_env}, // gun, Doom64. Added by Gonetz // (1-0)*primlod+t0, (cmb-0)*prim+env {0x2ef6a3f0, cc__t0_add_primlod__mul_prim_add_env}, // walls, Doom64. Added by Gonetz // (1-0)*primlod+t0, (cmb-0)*shade+env {0x2ef6a4f0, cc__t0_add_primlod__mul_shade_add_env}, // Pokemon Stadium 2. Added by Gonetz // (noise-0)*primlod+t0, (prim-env)*cmb+env ** INC ** {0x2ef7a053, cc_prim_sub_env_mul_t0_add_env}, // Tony Hawk's Pro Skater. Added by Gonetz // (t1-t0)*k5+t0 {0x2f122f12, cc_t0_inter_t1_using_k5}, // F1 World Grand Prix. Added by Gonetz // (t1-t0)*k5+t0, (cmb-0)*shade+0 **INC** {0x2f12e4f0, cc__t0_inter_t1_using_k5__mul_shade}, // Turok 3 [scorpiove]. Added by Gonetz // (t0-k4)*k5+t0 {0x2f712f71, cc_t0}, // THPS 3 // (env-0)*k5+t0, {0x2ff52ff5, cc_t0_add_env_mul_k5}, // super bowling // (0-0)*k5+t0, {0x2fff0000, cc_t0}, // super bowling // (0-0)*k5+t0 {0x2fff2fff, cc_t0}, // Moonlight attack, pokemon stadium 2 // (t1-t0)*0+t0, (prim-env)*cmb+env {0x3f12a053, cc_prim_sub_env_mul_t0_add_env}, //C&C shadows //(1-env)*0+t0 {0x3f563f56, cc_t0}, // RARE logo, blast corps. Added by Gonetz // (t0-0)*0+t0 {0x3ff13ff1, cc_t0}, // the ground below the scarecrow in the trading post in town, zelda 2 [Ogy]. Added by Gonetz // (t1-0)*0+t0, (cmb-0)*shade+0 {0x3ff2e4f0, cc_t0_mul_shade}, // intro, background, Dezaemon 3D // (1-0)*0+t0 {0x3ff63ff6, cc_t0}, // intro of WWF WrestleMania 2000 // ((0-0)*0+t0, (env-cmb)*prim+cmb {0x3fff0305, cc_env_sub_t0_mul_prim_add_t0}, // pistol fire, Turok // ((0-0)*0+t0, (env-cmb)*shade+cmb {0x3fff0405, cc_env_sub_t0_mul_shade_add_t0}, // Tony Hawk's Pro Skater. Added by Gonetz // ((0-0)*0+t0, (t1-0)*shade+cmb ** INC ** {0x3fff04f2, cc_t0}, // Dr. Mario [Ogy]. Added by Gonetz // ((0-0)*0+t0, (prim-cmb)*env+cmb {0x3fff0503, cc_prim_sub_t0_mul_env_add_t0}, // Stained glass, quest64 // (0-0)*0+t0, (1-0)*env+cmb {0x3fff05f6, cc_t0_add_env}, // Health bar, killer instinct gold // (0-0)*0+t0, (prim-env)*prim_a+cmb {0x3fff0a53, cc_prim_sub_env_mul_prima_add_t0}, // Runes, Turok - Dinosaur Hunter. Added by Gonetz // (0-0)*0+t0, (env-cmb)*env_a+cmb {0x3fff0c05, cc_t0_inter_env_using_enva}, // intro, Mission Impossible. Added by Gonetz // (k5-k5)*0+t0, (0-0)*scale+t0 {0x3fff26ff, cc_t0}, // V8-2 // (0-0)*0+t0, (t0-k4)*k5+t0 {0x3fff2f71, cc_t0_sub_k4_mul_k5_add_t0}, // TM, mario //z (k5-k5)*0+t0 {0x3fff3fff, cc_t0}, // Intro, CBFD. Added by Gonetz // ((0-0)*0+t0, (shade-env)*cmb+prim {0x3fff6054, cc_shade_sub_env_mul_t0_add_prim}, // Text, Mia Soccer. Added by Gonetz // ((0-0)*0+t0, (0-0)*0+prim {0x3fff7fff, cc_t0}, // paper mario. Added by Gonetz // ((0-0)*0+t0, (prim-env)*cmb+env {0x3fffa053, cc_prim_sub_env_mul_t0_add_env}, // Objects in arena, pokemon stadium 2 // (0-0)*0+t0, (cmb-prim)*shade+env {0x3fffa430, cc_t0_mul_prim}, // intro, F1 Racing Championship. Added by Gonetz // (0-0)*0+t0, (shade-env)*cmb+0 {0x3fffe054, cc_shade_sub_env_mul_t0}, // stands, F1 Racing Championship. Added by Gonetz // (0-0)*0+t0, (1-env)*cmb+0 {0x3fffe056, cc_one_sub_env_mul_t0}, // ? (from log) // (0-0)*0+t0, (prim-0)*cmb+0 {0x3fffe0f3, cc_t0_mul_prim}, // background, GASP Fighters // (0-0)*0+t0, (shade-0)*cmb+0 {0x3fffe0f4, cc_t0_mul_shade}, // zelda 2 [Ogy]. Added by Gonetz // (0-0)*0+t0, (env-0)*cmb+0 {0x3fffe0f5, cc_t0_mul_env}, // logo, v-rally 99 // (0-0)*0+t0, (prim-0)*t0+0 {0x3fffe1f3, cc_t0_mul_prim}, // target hit, zelda 2. Added by Gonetz // (0-0)*0+t0, (cmb-0)*prim+0 {0x3fffe3f0, cc_t0_mul_prim}, // Ms. Pac-Man intro background. Added by Gonetz // (0-0)*0+t0, (cmb-0)*shade+0 {0x3fffe4f0, cc_t0_mul_shade}, // Wonder Project J2 logo. Added by Gonetz // (0-0)*0+t0, (t0-0)*shade+0 {0x3fffe4f1, cc_t0_mul_shade}, // tire trace, Monster truck madness. Added by Gonetz // (0-0)*0+t0, (cmb-0)*env+0 {0x3fffe5f0, cc_t0_mul_env}, // Gauntlet Legends intro. Added by Gonetz // (0-0)*0+t0, (cmb-0)*ecale+0 {0x3fffe6f0, cc_t0}, // tire trace, beetle adventure racing. Added by Gonetz // (t1-t0)*t0+t1, (cmb-t0)*shade+t1 **INC** {0x41124410, cc__t0_inter_t1_using_t0__mul_shade}, // Paper Mario. Added by Gonetz // (t0-t1)*t0+t1 **INC** {0x41214121, cc_t1_inter_t0_using_t0}, // Powered Star Beam, Paper Mario. Added by Gonetz // (t0-t1)*t0+t1, (env-prim)*cmb+prim **INC** {0x41216035, cc_env_sub_prim_mul__t1_inter_t0_using_t0__add_prim}, // wetrix raiseland [Raziel64]. Added by Gonetz // (prim-t1)*t0+t1, (env-t0)*cmb+cmb **INC** {0x41230015, cc_env_sub_prim_mul__t0_mul_t1__add_prim}, // SCARS. Added by Gonetz // (t1-t0)*t0+t1, (cmb-t0)*shade+t1 **INC** {0x41250b03, cc__t0_inter_t1_using_half__mul_shade}, //beetle adventure racing. Added by Gonetz //(t0-t1)*t1+t1, (cmb-0)*shade+0 **INC** {0x4221e4f0, cc__t1_inter_t0_using_t1__mul_shade}, // cianwood gym walls, pokemon stadium 2 //(t0-prim)*t1+t1, (cmb-0)*env+shade {0x423185f0, cc__t0_sub_prim_mul_t1_add_t1__mul_env_add_shade}, // cianwood gym walls, pokemon stadium 2 //(t0-prim)*t1+t1, (cmb-0)*shade+0 {0x4231e4f0, cc__t0_sub_prim_mul_t1_add_t1__mul_shade}, // paper mario. Added by Gonetz // (t0-t0)*prim+t1, (t1-cmb)*cmb+env **INC** weird {0x4311a002, cc_env}, // background, Wetrix level 1, [Raziel64]. Added by Gonetz // (t0-t1)*prim+t1 {0x43214321, cc_t1_inter_t0_using_prim}, // Mario Party3 Tidal Toss // (t0-t1)*prim+t1, (cmb-0)*shade+0 **INC** {0x4321e4f0, cc__t1_inter_t0_using_prim__mul_shade}, // grass, ISS 2k. Added by Gonetz // (t0-t1)*prim+t1, (cmb-0)*env+0 **INC** {0x4321e5f0, cc__t1_inter_t0_using_prim__mul_env}, // intro, Paper Mario // (t0-0)*prim+t1 {0x43f143f1, cc_t0_mul_prim_add_t1}, // F1 World Grand Prix. Added by Gonetz // (t0-0)*prim+t1, (cmb-0)*shade+env **INC** {0x43f1a4f0, cc__t0_add_t1__mul_shade_add_env}, // field, ISS64. Added by Gonetz // (t0-t1)*shade+t1, (cmb-t1)*prim+t1 ** INC ** {0x44214320, cc_t0_sub_t1_mul_prim_mul_shade_add_t1}, // {0x44214320, cc__t0_add_t1__mul_prim}, // field, Top gear hyper-bike // (t0-t1)*shade+t1 {0x44214421, cc_t1_inter_t0_using_shade}, // water, goemon great adventure // (t0-t1)*env+t1 ** INC ** {0x45214521, cc_t1_inter_t0_using_env}, // characters, Ogre Battle. Added by Gonetz // (1-t1)*env+t1, (1-cmb)*prim+cmb ** INC ** {0x45260306, cc_one_sub_t1_mul_prim_add_t1}, // characters, Ogre Battle. Added by Gonetz // (1-t1)*env+t1 {0x45264526, cc_one_sub_t1_mul_env_add_t1}, // characters, Ogre Battle. Added by Gonetz // (1-t1)*env+t1, (cmb-0)*prim+0 ** INC ** {0x4526e3f0, cc__t1_inter_one_using_env__mul_prim}, // explosion, body harvest. Added by Gonetz // (t0-t1)*scale+t1, (env-prim)*cmb+prim ** INC ** {0x46216035, cc_env_sub_prim_mul__t0_inter_t1_using_half__add_prim}, // Water, AeroGauge. Added by Gonetz // (t0-t1)*prima+t1, (0-0)*0+cmb {0x4a214a21, cc_t1_inter_t0_using_prima}, // flame, castlevania 2. Added by Gonetz // (t0-t1)*prima+t1, (prim-env)*cmb+env {0x4a21a053, cc_prim_sub_env_mul__t1_inter_t0_using_prima__add_env}, // shadows, Mario Tennis. Added by Gonetz // (t0-t1)*prima+t1, (prim-0)*cmb+0 {0x4a21e0f3, cc__t1_inter_t0_using_prima__mul_prim}, // menu, Mario Golf. Added by Gonetz // (t0-t1)*prima+t1, (shade-0)*cmb+0 {0x4a21e0f4, cc__t1_inter_t0_using_prima__mul_shade}, // intro, castlevania 2. Added by Gonetz // (t0-t1)*prima+t1, (cmb-0)*prim+0 {0x4a21e3f0, cc__t1_inter_t0_using_prima__mul_prim}, // water on map, Ogre Battle64. Added by Gonetz // (t0-t1)*prima+t1, (cmb-0)*shade+0 {0x4a21e4f0, cc__t1_inter_t0_using_prima__mul_shade}, // Ice, Paper Mario // (t0-t1)*shade_a+t1 {0x4b214b21, cc_t1_inter_t0_using_shadea}, // Grass, Beetle Adventure Racing // (t0-t1)*shade_a+t1, (cmb-0)*shade+0 {0x4b21e4f0, cc__t1_inter_t0_using_shadea__mul_shade}, // Ground at kotake & koume, zelda // (t1-t0)*env_a+t0, (prim-env)*cmb+env {0x4c12a053, cc_prim_sub_env_mul__t0_inter_t1_using_enva__add_env}, // Tony Hawk's Pro Skater. Added by Gonetz // (t0-t1)*env_a+t1, (cmb-0)*shade+cmb ** INC ** {0x4c2104f0, cc__t1_inter_t0_using_enva__mul_shade}, // bikes, xg2. Added by Gonetz // (t0-t1)*env_a+t1, (cmb-prim)*prima+prim {0x4c216a30, cc__t1_inter_t0_using_enva__sub_prim_mul_prima_add_prim}, // Yoshi Story // (t0-t1)*env_a+t1, (prim-env)*cmb+env {0x4c21a053, cc_prim_sub_env_mul__t1_inter_t0_using_enva__add_env}, // arena, Pokemon Stadium 1. Added by Gonetz // (t0-t1)*env_a+t1, (cmb-0)*prim+0 {0x4c21e3f0, cc__t1_inter_t0_using_enva__mul_prim}, // "end of chapter" text, paper mario. Added by Gonetz // (1-t1)*env_a+t1, (cmb-0)*t1+0 {0x4c26e2f0, cc__t1_inter_one_using_enva__mul_t0}, // Zelda opening door, zelda // (t0-prim)*env_a+t1, (prim-env)*t0+env {0x4c31a053, cc_prim_sub_env_mul_t0_add_env}, // arena, Pokemon Stadium 2 // (t0-0)*env_a+t1, (cmb-0)*shade+prim {0x4cf164f0, cc__t0_mul_enva_add_t1__mul_shade_add_prim}, // Kotake & koume magic poof, zelda // (t0-0)*env_a+t1, (prim-env)*cmb+env {0x4cf1a053, cc_prim_sub_env_mul__t0_mul_enva_add_t1__add_env}, // ground in stone temple, zelda 2. Added by Gonetz // (t1-t0)*primlod+t1, (cmb-0)*prim+0 {0x4e12e3f0, cc__t0_inter_t1_using_primlod__mul_prim}, // pokemon attack, Pokemon Stadium 2. Added by Gonetz // (noise-t0)*primlod+t1, (prim-env)*cmb+env ** INC ** {0x4e17a053, cc_prim_sub_env_mul__t0_inter_t1_using_primlod__add_env}, // menu, pokemon stadium 1, [Raziel64] // (t0-t1)*lodf+t1, (prim-env)*cmb+env {0x4e214e21, cc_t1_inter_t0_using_primlod}, // Pokemon backgrounds, pokemon stadium 2 // (t0-t1)*primlod+t1, (cmb-0)*shade+prim {0x4e2164f0, cc__t1_inter_t0_using_primlod__mul_shade_add_prim}, // Pokemon backgrounds, pokemon stadium 2 // (t0-t1)*lodf+t1, (prim-env)*cmb+env {0x4e21a053, cc_prim_sub_env_mul__t1_inter_t0_using_primlod__add_env}, // zelda 2 [Ogy]. Added by Gonetz // (t0-t1)*primlod+t1, (t1-cmb)*prim+env ** INC ** {0x4e21a302, cc_env_sub__t0_sub_t1_mul_primlod__mul_prim}, // Magnitude, pokemon stadium 2 // (t0-t1)*primlod+t1, (prim-env)*cmb_a+env {0x4e21a753, cc_prim_sub_env_mul__t1_inter_t0_using_primlod__add_env}, // Arena, pokemon stadium 2 // (t0-t1)*primlod+t1, (cmb-shade)*prim+0 {0x4e21e340, cc__t1_inter_t0_using_primlod__sub_shade_mul_prim}, // zelda 2 [Ogy]. Added by Gonetz // (t0-t1)*primlod+t1, (cmb-0)*shade+0 {0x4e21e4f0, cc__t1_inter_t0_using_primlod__mul_shade}, // lava in snowhead temple, zelda 2. Added by Gonetz // (t0-prim)*primlod+t1, (cmb-prim)*shade+cmb ** INC ** {0x4e310430, cc_lavatex_sub_prim_mul_shade_add_lavatex}, // Skulltula coin, zelda // (t0-prim)*primlod+t1, (prim-env)*cmb+env {0x4e31a053, cc_prim_sub_env_mul__t0_sub_prim_mul_primlod_add_t1__add_env}, // Pokemon background, pokemon stadium 2 // (noise-shade)*primlod+t1, (prim-env)*cmb+env {0x4e47a053, cc_prim_sub_env_mul_t1_add_env}, // Reflect, Pokemon Stadium 2 [gokuss4]. Added by Gonetz // (t0-0)*primlod+t1, (prim-env)*cmb+env {0x4ef1a053, cc_prim_sub_env_mul__t0_add_t1__add_env}, //beetle adventure racing. Added by Gonetz //(t0-t1)*k5+t1, (cmb-0)*shade+0 {0x4f21e4f0, cc__t1_inter_t0_using_k5__mul_shade}, // Spiderman. Added by Gonetz //(t0-t1)*k5+t1, (cmb-0)*env+0 {0x4f21e5f0, cc_t1_mul_env}, // N64 logo, Ogre Battle. Added by Gonetz //(0-0)*0+t1 {0x5fff5fff, cc_t1}, // reversing light, Monster truck madness. Added by Gonetz //(0-0)*0+t0, (0-0)*0+prim {0x5fff7fff, cc_prim}, // battle tanks [Ogy] // (0-0)*0+t1, (env-shade)*cmb+shade {0x5fff8045, cc_env_sub_shade_mul_t1_add_shade}, // minigame, pokemon stadium 1. Added by Gonetz // (0-0)*0+t1, (prim-env)*cmb+env {0x5fffa053, cc_prim_sub_env_mul_t1_add_env}, // F1 World Grand Prix. Added by Gonetz // (t0-prim)*t0+prim, (cmb-0)*shade {0x6131e4f0, cc__prim_inter_t0_using_t0__mul_shade}, // aerofighter's assault [Ogy] // (shade-prim)*t0+prim {0x61346134, cc_shade_sub_prim_mul_t0_add_prim}, // pilot wings // (shade-prim)*t0+prim, (cmb-shade)*shadea+shade {0x61348b40, cc_shade_inter__prim_inter_shade_using_t0__using_shadea}, // club blow, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz // (shade-prim)*t0+prim, (cmb-env)*cmb_a+env ** INC ** {0x6134a750, cc_shade_sub_prim_mul_t0_add_prim}, // sky, Killer Instinct // (shade-prim)*t0+prim, (cmb-env)*shade_a+env ** INC ** {0x6134ab50, cc_env_inter__prim_inter_shade_using_t0__using_shadea}, // lava, beetle adventure racing // (shade-prim)*t0+prim, (cmb-0)*t1+0 ** INC ** {0x6134e2f0, cc_shade_sub_prim_mul_t0_add_prim}, // Monster truck madness intro. Added by Gonetz // (env-prim)*t0+prim, (cmb-0)*scale+cmb ** INC ** {0x613506f0, cc_env_sub_prim_mul_t0_add_prim}, // pokemon attack, Pokemon stadium 1 // (env-prim)*t0+prim, (cmb-0)*0+cmb {0x61351ff0, cc_env_sub_prim_mul_t0_add_prim}, // Paper Mario, fortune teller spheres // (env-prim)*t0+prim, (cmb-0)*t1+t0 ** INC ** {0x613522f0, cc_t0_mul_t1_add_t0}, // Later hearts, zelda // (env-prim)*t0+prim {0x61356135, cc_env_sub_prim_mul_t0_add_prim}, // Mission Impossible. Added by Gonetz // (env-prim)*t0+prim, (shade-0)*cmb+0 ** INC ** {0x6135e0f4, cc__prim_inter_env_using_t0__mul_shade}, // crashing other vehicle, Monster truck madness [Raziel64]. Added by Gonetz // (env-prim)*t0+prim, (cmb-0)*t0+0 ** INC ** {0x6135e1f0, cc_env_sub_prim_mul_t0_add_prim}, // Tony Hawk's Pro Skater. Added by Gonetz // (env-prim)*t0+prim, (cmb-0)*t1+0 ** INC ** {0x6135e2f0, cc_env_sub_prim_mul_t0_add_prim}, // aerofighter's assault [Ogy] // (env-prim)*t0+prim, (cmb-0)*shade+0 ** INC ** {0x6135e4f0, cc__prim_inter_env_using_t0__mul_shade}, // "time out", paper mario. Added by Gonetz // (1-prim)*t0+prim, (1-cmb)*enva+cmb ** INC ** {0x61360c06, cc_one_sub_prim_mul_t0_add_prim}, // intro, paper mario. Added by Gonetz // (1-prim)*t0+prim, (cmb-0)*prima+t0 ** INC ** {0x61362af0, cc__one_sub_prim_mul_t0_add_prim__mul_prima_add__one_sub_prim_mul_t0_add_prim}, // paper mario. Added by Gonetz // (1-prim)*t0+prim {0x61366136, cc_one_sub_prim_mul_t0_add_prim}, // arena, Pokemon Stadium 2. Added by Gonetz // (1-prim)*t0+prim, (cmb-env)*shade+shade ** INC ** {0x61368450, cc_t0_mul_shade}, // F1 World Grand Prix. Added by Gonetz // (1-prim)*t0+prim, (cmb-0)*shade+0 ** INC ** {0x6136e4f0, cc_t0_mul_shade}, // Xena. Added by Gonetz // (0-prim)*t0+prim {0x613f613f, cc_one_sub_t0_mul_prim}, // Kirby64 end [Raziel64]. Added by Gonetz // (prim-env)*t0+prim {0x61536153, cc_prim_sub_env_mul_t0_add_prim}, // Xena. Added by Gonetz // (shade-env)*t0+prim {0x61546154, cc_shade_sub_env_mul_t0_add_prim}, // Karts, mario kart //z (one-env)*t0+prim {0x61566156, cc_t0_mul_1menv_add_prim}, // Famista64. Added by Gonetz //(t0-0)*t0+prim {0x61f161f1, cc_t0_mul_prim}, // Pokemon Stadium 2. Added by Gonetz //(shade-0)*t0+prim {0x61f461f4, cc_t0_mul_shade_add_prim}, // Doom. Added by Gonetz //(1-0)*t0+prim {0x61f661f6, cc_t0_add_prim}, // tire trace, beetle adventure racing. Added by Gonetz // (shade-prim)*t1+prim, (cmb-0)*t1+0 **INC** {0x6234e2f0, cc_shade_sub_prim_mul_t1_add_prim}, // Text, turok // (env-prim)*t1+prim {0x62356235, cc_env_sub_prim_mul_t1_add_prim}, // Pokemon Stadium 2, [gokuss4]. Added by Gonetz // (env-prim)*t1+prim, (cmb-0)*t1+0 // Hack alert! {0x6235e2f0, cc_t1}, // bike trace, xg2 intro. Added by Gonetz // (1-prim)*t1+prim {0x62366236, cc_one_sub_prim_mul_t1_add_prim}, // aerofighter's assault [Ogy] // (1-prim)*t1+prim, (cmb-0)*0+env {0x6236bff0, cc_one_sub_prim_mul_t1_add_prim}, // Tennis court, mario tennis // (t0-0)*t1+prim {0x62f162f1, cc__t0_mul_t1__add_prim}, // Arena, Pokemon Stadium 2 // (t0-0)*t1+prim, (cmb-0)*shade+0 {0x62f1e4f0, cc__t0_mul_t1_add_prim__mul_shade}, // Rush2. Added by Gonetz // (prim-prim)*prim+prim {0x63336333, cc_prim}, //Bowser in final battle, Paper Mario. Added by Gonetz // (t1-0)*prim+prim {0x63f263f2, cc_t1_mul_prim_add_prim}, // wetrix, icelayer, [Raziel64]. Added by Gonetz // (t0-prim)*shade+prim ** INC ** {0x64316431, cc_t0_mul_shade}, // KI. Added by Gonetz // (env-prim)*shade+prim {0x64356435, cc_env_sub_prim_mul_shade_add_prim}, // xg2. Added by Gonetz // (1-prim)*shade+prim, (t0-0)*cmb+0 ** INC ** {0x6436e0f1, cc_t1_mul__one_sub_prim_mul_shade_add_prim}, // Intro, CBFD. Added by Gonetz // (t0-env)*shade+prim {0x64516451, cc_t0_sub_env_mul_shade_add_prim}, // sword in final battle, zelda 2. Added by Gonetz // (t0-env)*shade+prim, (cmb-0)*shade+0 ** INC ** {0x6451e4f0, cc__t0_sub_env_mul_shade_add_prim__mul_shade}, // attack, Pokemon Stadium 2. // (t0-env)*shade+prim, (cmb-0)*shade_a+0 ** INC ** {0x6451ebf0, cc__t0_sub_env_mul_shade_add_prim__mul_shadea}, // Road Rush. Added by Gonetz // (t0-0)*shade+prim {0x64f164f1, cc_t0_mul_shade_add_prim}, // paper mario. Added by Gonetz // (1-0)*shade+prim {0x64f664f6, cc_prim_add_shade}, // Character select, smash bros // (t0-prim)*env+prim {0x65316531, cc_t0_sub_prim_mul_env_add_prim}, // Clear screen intro, banjo kazooie // (t0-prim)*env+prim, (cmb-0)*shade+0 // {0x6531e4f0, cc_t0_mul_env_mul_shade}, {0x6531e4f0, cc__prim_inter_t0_using_env__mul_shade}, // Dragonfly feet, banjo kazooie // (1-prim)*env+prim, (cmb-0)*shade+0 {0x6536e4f0, cc__prim_inter_one_using_env__mul_shade}, // Lava piranha atack, Paper Mario // (t1-k4)*env+prim ** INC ** {0x65726572, cc_t1_mul_env_add_prim}, // zelda 2 [Ogy]. Added by Gonetz // (t0-0)*env+prim, (1-t1)*t0a+cmb ** INC ** {0x65f10826, cc_one_sub_t1_mul_t0a_add_t0_mul_env_add_prim}, // clocks while warping through time, zelda 2 // (t0-0)*env+prim, (cmb-0)*0+cmb {0x65f11ff0, cc_t0_mul_env_add_prim}, // Helicopter, Nuclear Strike. Added by Gonetz // (t0-0)*env+prim {0x65f165f1, cc_t0_mul_env_add_prim}, // Mystical Ninja // (1-0)*env+prim {0x65f665f6, cc_prim_add_env}, // duke nukem: zero hour [Ogy] // (noise-0)*env+prim ** INC ** {0x65f765f7, cc_prim_add_env}, // "terminator", CBFD // (0-0)*env+prim {0x65ff65ff, cc_prim}, // Cliffs, Taz express. Added by Gonetz // (t0-0)*scale+prim {0x66f166f1, cc_t0_mul_scale_add_prim}, // Taz express. Added by Gonetz // (t0-0)*scale+prim, (cmb-0)*shade+0 {0x66f1e4f0, cc_t0_mul_scale_add_prim__mul_shade}, // NFL Quarterback Club 98 Menu [CpUMasteR] // (prim-0)*scale+prim {0x66f366f3, cc_prim}, // Pikachu // (t0-prim)*t0_a+prim, (env-cmb)*enva+cmb {0x68310c05, cc__prim_inter_t0_using_t0a__inter_env_using_enva}, // Character, dual heroes // (t0-prim)*t0_a+prim {0x68316831, cc_t0_sub_prim_mul_t0a_add_prim}, // Indy Racing 2000. Added by Gonetz // (t0-prim)*t0_a+prim, (cmb-0)*shade+0 ** INC ** {0x6831e4f0, cc__prim_inter_t0_using_t0a__mul_shade}, // text, Sin and Punishmen. Added by Gonetz // (env-prim)*t0_a+prim ** INC ** {0x68356835, cc_env_sub_prim_mul_t0a_add_prim}, // arena, Pokemon Stadium 2 // (1-prim)*t0_a+prim {0x68366836, cc_one_sub_prim_mul_t0a_add_prim}, // menu, PD. Added by Gonetz // (env-prim)*t1_a+prim {0x69356935, cc_env_sub_prim_mul_t1a_add_prim}, // {0x69356935, cc_t1}, //xg2. Added by Gonetz // (t0-prim)*prima+prim {0x6a316a31, cc_t0_sub_prim_mul_prima_add_prim}, // menu, battle phoenix 64. Added by Gonetz // (env-prim)*prima+prim {0x6a356a35, cc_env_sub_prim_mul_prima_add_prim}, // ground, KI. Added by Gonetz // (shade-env)*prima+prim {0x6a546a54, cc_shade_sub_env_mul_prima_add_prim}, // F1 World Grand Prix. Added by Gonetz // (t0-0)*prima+prim, (shade-0)*cmb+env **INC** {0x6af1a0f4, cc__t0_mul_prima_add_prim_mul__shade_add_env}, //broken wall, beetle adventure racing. Added by Gonetz // (t0-0)*prima+prim, (cmb-0)*shade+0 **INC** {0x6af1e4f0, cc__t0_mul_prima_add_prim_mul__shade}, // Genie, diddy kong racing // (t0-prim)*shade_alpha+prim, (env-cmb)*shade+cmb // {0x6b310405, cc_env_sub__prim_inter_t0_using_shadea__mul_shade_add_env}, {0x6b310405, cc_t0_mul_shadea}, // Extreme G. Added by Gonetz // (t0-prim)*shade_alpha+prim ** INC ** {0x6b316b31, cc_t0_sub_prim_mul_shadea_add_prim}, // water block, Paper Mario. Added by Gonetz // (t0-prim)*shade_alpha+prim, (prim-env)*cmb+env ** INC ** {0x6b31a053, cc_prim_sub_env_mul__prim_inter_t0_using_shadea__add_env}, // water, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz // (t0-prim)*shade_alpha+prim, (cmb-0)*shade+0 ** INC ** {0x6b31e4f0, cc__prim_inter_t0_using_shadea__mul_shade}, // F1 World Grand Prix sky. Added by Gonetz // (env-prim)*shade_alpha+prim, (shade-cmb)*cmb_a+cmb ** INC ** {0x6b350704, cc_f1_sky}, // lullaby, Paper Mario. Added by Gonetz // (env-prim)*shade_alpha+prim {0x6b356b35, cc_env_sub_prim_mul_shadea_add_prim}, // Some gannon spell, zelda // (noise-t0)*env_a+prim, (0-prim)*cmb+1 ** INC ** {0x6c17c03f, cc_one_sub__one_sub_t0_mul_enva_add_prim__mul_prim}, //Goldeneye, [Jeremy]. Added by Gonetz // (t0-prim)*env_a+prim {0x6c316c31, cc_t0_sub_prim_mul_enva_add_prim}, // button, Sin and Punishmen. Added by Gonetz // (env-prim)*env_a+prim {0x6c356c35, cc_env_sub_prim_mul_enva_add_prim}, // frame buffer effect, Glover2 // (env-prim)*env_a+prim, (cmb-0)*shade+0 {0x6c35e4f0, cc__prim_inter_env_using_enva__mul_shade}, // fallen stars at star summit, Paper Mario. Added by Gonetz // (t0-env)*env_a+prim, (1-0)*primlod+cmb {0x6c510ef6, cc_t0_sub_env_mul_enva_add_prim}, // focus, Paper Mario. Added by Gonetz // (t0-env)*env_a+prim, (cmb-shade)*shadea+shade ** INC ** {0x6c518b40, cc_t0_sub_shade_mul_shadea_add_shade}, // Ring, pokemon stadium 2 // (t0-0)*env_a+prim, (1-0)*cmb+0 {0x6cf1e0f6, cc_t0_mul_enva_add_prim}, // Jet Force // (noise-0)*env_a+prim {0x6cf76cf7, cc_prim}, // snowhead temple, zelda 2. Added by Gonetz // (t1-t0)*primlod+prim, (cmb-0)*shade+shade {0x6e1284f0, cc__t1_sub_t0_mul_primlod_add_prim__mul_shade_add_shade}, // zelda 2. Added by Gonetz // (t1-t0)*primlod+prim, (cmb-0)*shade+0 ** INC ** {0x6e12e4f0, cc__t1_sub_t0_mul_primlod_add_prim__mul_shade}, // mini games quiz monitor backround, Pokemon Stadium 2 // (noise-t0)*primlod+prim, (prim-env)*cmb+env ** INC ** {0x6e17a053, cc_prim_sub_env_mul__one_sub_t0_mul_primlod_add_prim__add_env}, // Morning Sun attack, pokemon stadium 2 // (t0-prim)*primlod+prim, (prim-env)*0+cmb {0x6e311f53, cc_t0_sub_prim_mul_primlod_add_prim}, // sky, daikatana. Added by Gonetz // (t0-prim)*primlod+prim, (cmb-0)*shade+0 {0x6e31e4f0, cc_t0_mul_shade}, // ball's track, NFL Blitz. Added by Gonetz // (t0-0)*primlod+prim {0x6ef16ef1, cc_t0_mul_primlod_add_prim}, // Earthquake pokemon attack, Pokemon Stadium 2 [gokuss4]. Added by Gonetz // (t0-0)*primlod+prim, (cmb-env)*cmb_a+env ** INC ** {0x6ef1a750, cc_t0_mul_primlod_add_prim}, // mini games quiz monitor backround, Pokemon Stadium 2 // (noise-0)*primlod+prim, (env-cmb)*cmb_a+cmb ** INC ** // use cmb_a which is ac_t0_mul_t1 {0x6ef70705, cc_env_sub_prim_mul__t0a_mul_t1a__add_prim}, // rope, CBFD // (t0-env)*k5+prim {0x6f516f51, cc_t0_sub_env_mul_k5_add_prim}, // super bowling // (0-0)*k5+prim {0x6fff6fff, cc_prim}, // intro, Aidyn Chronicles. Added by Gonetz // (0-0)*0+prim, (0-0)*0+prim {0x79fb7788, cc_prim}, // Encore attack, Pokemon Stadium 2 // (t0-0)*0+prim, (cmb-0)*shade+0 {0x7ff1e4f0, cc_prim_mul_shade}, // Menu, megaman // (1-0)*0+prim {0x7ff67ff6, cc_prim}, // sky, PGA European Tour // (0-0)*0+prim, (env-0)*t0+cmb {0x7fff01f5, cc_t1_mul_env_add_prim}, // WWF No Mercy? // ((0-0)*0+prim, (env-cmb)*shade+cmb {0x7fff0405, cc_env_sub_prim_mul_shade_add_prim}, // sky, Spiderman. Added by Gonetz // (0-0)*0+prim, (t1-0)*shade+cmb {0x7fff04f2, cc_t1_mul_shade_add_prim}, // ball's shadow, ISS 2k. Added by Gonetz // (0-0)*0+prim, (1-cmb)*env+cmb {0x7fff0506, cc_one_sub_prim_mul_env_add_prim}, // Necklace, quest64 // (0-0)*0+prim, (1-0)*env+cmb {0x7fff05f6, cc_prim_add_env}, // Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz // (0-0)*0+prim, (1-cmb)*cmba+cmb ** INC ** {0x7fff0706, cc_prim}, // Dobutsu no Mori. Added by Gonetz //(k5-k5)*0+prim, (cmb-0)*0+cmb {0x7fff1ff0, cc_prim}, // Intro background, starfox //z (k5-k5)*0+prim {0x7fff7fff, cc_prim}, // train smoke, Dobutsu No Mori. Added by Gonetz //(0-0)*0+prim, (shade-0)*cmb+0 {0x7fffe0f4, cc_prim_mul_shade}, // Donald Duck intro. Added by Gonetz //(0-0)*0+prim, (cmb-0)*prim+0 {0x7fffe3f0, cc_prim_mul_prim}, // Ms. Pac-Man intro. Added by Gonetz //(0-0)*0+prim, (cmb-0)*shade+0 {0x7fffe4f0, cc_prim_mul_shade}, // zelda 2. Added by Gonetz //(t1-t0)*t0+shade, (cmb-0)*shade+0 {0x8112e4f0, cc__t1_sub_t0_mul_t0_add_shade__mul_shade}, // branches, Beetle Adventure Racing //(t0-shade)*t0+shade, (t0-cmb)*prim+cmb **INC** {0x81410301, cc_t0_mul_prim}, // Namco logo, Famista 64 //(prim-shade)*t0+shade, (env-cmb)*t0+cmb **INC** {0x81430105, cc_prim_sub_shade_mul_t0_add_shade}, // pikachu, hey you pikachu //(prim-shade)*t0+shade, (env-cmb)*enva+cmb **INC** {0x81430c05, cc_prim_sub_shade_mul_t0_add_shade}, // Mario's head, mario //Added by Gonetz //(prim-shade)*t0+shade {0x81438143, cc_prim_sub_shade_mul_t0_add_shade}, // Iguana background, turok // (env-shade)*t0+shade {0x81458145, cc_env_sub_shade_mul_t0_add_shade}, //attack, Pokemon Stadium 2 // (env-shade)*t0+shade, (cmb-0)*prim+0 {0x8145e3f0, cc__env_sub_shade_mul_t0_add_shade__mul_prim}, // Bubbles in Jabu-Jabu's belly, zelda // (1-shade)*t0+shade {0x81468146, cc_one_sub_shade_mul_t0_add_shade}, // saffron city, Pokemon Stadium 2 // (1-shade)*t0+shade, (cmb-0)*prim+0 {0x8146e3f0, cc__one_sub_shade_mul_t0_add_shade__mul_prim}, // duck dodgers intro. Added by Gonetz // (1-shade)*t0+shade, (cmb-0)*shade+0 {0x8146e4f0, cc__one_sub_shade_mul_t0_add_shade__mul_shade}, // saffron city, Pokemon Stadium 2 // (1-shade)*t0+shade, (cmb-0)*prima+0 {0x8146eaf0, cc__one_sub_shade_mul_t0_add_shade__mul_env}, // intro, Madden Footbal // (1-env)*t0+shade {0x81568156, cc_one_sub_env_mul_t0_add_shade}, // sky in doom. Added by Gonetz // (prim-0)*t0+shade, (cmb-0)*primlod+env **INC** {0x81f3aef0, cc_t0_mul_prim_add_shade}, // commercial? in IIS98. Added by Gonetz // (1-0)*t0+shade {0x81f681f6, cc_t0_add_shade}, //attack, Pokemon Stadium 2 //(t0-prim)*t1+shade {0x82318231, cc_t0_sub_prim_mul_t1_add_shade}, //beetle adventure racing. Added by Gonetz //(prim-shade)*t1+shade, (cmb-0)*t1+0 **INC** {0x8243e2f0, cc_prim_sub_shade_mul_t1_add_shade}, //Arena, Pokemon Stadium 2 //(t0-0)*t1+shade {0x82f182f1, cc__t0_mul_t1__add_shade}, //Arena, Pokemon Stadium 2 //(t0-0)*t1+shade, (cmb-0)*prim+0 {0x82f1e3f0, cc__t0_mul_t1__mul_prim_add_prim_mul_shade}, // Scorpion fire breath, MK4 [Jeremy]. Added by Gonetz // (t0-shade)*prim+shade {0x83418341, cc_t0_mul_prim_add_one_sub_prim_mul_shade}, // Menu background, wwf no mercy // (env-shade)*prim+shade {0x83458345, cc_prim_mul_env_add_one_sub_prim_mul_shade}, // Pokemon selection window background, pokemon stadium 2 // (noise-shade)*prim+shade {0x83478347, cc_shade}, // crown of king of ikana, zelda 2. Added by Gonetz // (t0-env)*prim+shade {0x83518351, cc_t0_sub_env_mul_prim_add_shade}, // crown of king of ikana, zelda 2. Added by Gonetz // (t0-env)*prim+shade, (cmb-0)*cmb+0 ** INC ** {0x8351e0f0, cc_t0_sub_env_mul_prim_add_shade}, // salesman's shirt in the bomb shop in town, zelda 2 [Ogy]. Added by Gonetz // (t0-env)*prim+shade, (cmb-0)*shade+0 ** INC ** {0x8351e4f0, cc_t0_mul_prim_mul_shade}, // intro, Madden Footbal // (1-env)*prim+shade {0x83568356, cc_one_sub_env_mul_prim_add_shade}, // Buss hunter 64. Added by Gonetz // (t0-0)*prim+shade {0x83f183f1, cc_t0_mul_prim_add_shade}, // huge water lilies, zelda 2 [Ogy]. Added by Gonetz // (t0-0)*prim+shade, (cmb-env)*shade+0 ** INC ** {0x83f1e450, cc__t0_mul_prim_add_shade__sub_env_mul_shade}, // cynnabar gym fire shield, pokemon stadium 2 // (t0-0)*prim+shade, (cmb-0)*env+0 ** INC ** {0x83f1e5f0, cc__t0_mul_prim_add_shade__mul_env}, // Objects in arena, pokemon stadium 2 // (t1-0)*prim+shade, (cmb-0)*prim_a+0 - not going to bother with prim_a since it is FF {0x83f2eaf0, cc_t1_mul_prim_add_shade}, // Pokemon Stadium 2. Added by Gonetz // (t0-prim)*shade+shade ** INC ** {0x84318431, cc_t0_mul_shade}, // big N, Pokemon Stadium 2. Added by Gonetz // (1-prim)*shade+shade ** INC ** {0x84368436, cc_one_sub_prim_mul_shade_add_shade}, //Arena, Pokemon Stadium 2 //(t0-env)*shade+shade {0x84518451, cc_t0_sub_prim_mul_shade_add_shade}, //Arena, Pokemon Stadium 2 //(t0-env)*shade+shade, (cmb-0)*prim+0 {0x8451e3f0, cc_t0_sub_env_mul_prim_mul_shade_add_prim_mul_shade}, // arena, PokemonStadium2, [Raziel64] // (t0-0)*shade+shade, (cmb-0)*prim+0 {0x84f1e3f0, cc_t0_mul_prim_mul_shade_add_prim_mul_shade}, // Spiderman. Added by Gonetz // (1-0)*shade+shade {0x84f684f6, cc_shade_add_shade}, // the "gekko" ( a monster in a room above the 3rd room of woodfall temple ), zelda 2 [Ogy]. Added by Gonetz // (t0-prim)*env+shade ** INC ** {0x85318531, cc_t0_sub_prim_mul_env_add_shade}, // flower, zelda 2. Added by Gonetz // (t0-prim)*env+shade, (cmb-0)*shade+0 ** INC ** {0x8531e4f0, cc_t0_sub_prim_mul_env_add_shade}, // Robotron 64, [scorpiove] // (env-shade)*env+shade ** INC ** {0x85458545, cc_one_sub_env_mul_shade_add_env}, // Enemy dying, quest64 // (1-shade)*env+shade **changed by Gonetz {0x85468546, cc_one_sub_shade_mul_env_add_shade}, // Arena, Pokemon Stadium // (t0-0)*env+shade, (cmb-0)*prim+0 {0x85f1e3f0, cc__t0_mul_prim_mul_env__add__prim_mul_shade}, // Clouds, Pokemon Stadium // (t1-0)*env+shade, (cmb-0)*prim+0 {0x85f2e3f0, cc__t1_mul_prim_mul_env__add__prim_mul_shade}, // Sky, Beetle Adventure Racing ** INC ** //(t0-shade)*t0_a+shade, (env-cmb)*enva+cmb {0x88410c05, cc_t0_sub_shade_mul_t0a_add_shade}, // Mario's eyes, mario //z (t0-shade)*t0_a+shade {0x88418841, cc_t0_sub_shade_mul_t0a_add_shade}, //beetle adventure racing. Added by Gonetz // (prim-shade)*t0_a+shade, (t1-0)*cmb+0 **INC** {0x8843e0f2, cc_prim_sub_shade_mul__t0a_mul_t1__add_shade}, // blast corps [Ogy] // (prim-shade)*t1_a+shade {0x89438943, cc_prim_sub_shade_mul_t1a_add_shade}, //broken wall, beetle adventure racing. Added by Gonetz // (t0-shade)*prima+shade, (1-0)*0+cmb {0x8a411ff6, cc_t0_sub_shade_mul_prima_add_shade}, // menu, battle phoenix 64. Added by Gonetz // (t0-shade)*prima+shade {0x8a418a41, cc_t0_add_shade}, // intro, castlevania 2. Added by Gonetz // (prim-shade)*prim_a+shade {0x8a438a43, cc_prim_sub_shade_mul_prima_add_shade}, // Pilot wings // (t0-shade)*shade_a+shade, (cmb-0)*shade+0 {0x8b41e4f0, cc__shade_inter_t0_using_shadea__mul_shade}, // ? // (1-shade)*shade_a+shade {0x8b468b46, cc_one_sub_shade_mul_shadea_add_shade}, // Pilot wings, sky in congratulations // (t0-0)*shade_a+shade, {0x8bf18bf1, cc_t0_mul_shadea_add_shade}, // arena, Pokemon Stadium. Added by Gonetz // (t0-t1)*env_a+shade, (cmb-env)*prim+0 ** INC ** {0x8c21e350, cc__t0_sub_t1_mul_enva_add_shade__sub_env_mul_prim}, //diddy kong racing background fill. Added by Gonetz ** Modified by Dave2001 // (env-shade)*env_a+shade, (cmb-0)*prim+0 {0x8c458c45, cc_shade}, // note: previous combiner used other_alpha; doesn't work //diddy kong racing. Added by Gonetz // (env-shade)*env_a+shade, (cmb-0)*prim+0 ** INC ** {0x8c45e3f0, cc_prim_mul_shade}, // sky, Pokemon Stadium, [Raziel64] // (t0-0)*env_a+shade, (cmb-env)*prim+0 ** INC ** {0x8cf1e350, cc_t0_mul_prim_add_shade_sub_env_mul_prim}, // zelda 2 [Ogy]. Added by Gonetz // (t0-prim)*primlod+shade, (prim-env)*cmb+env ** INC ** {0x8e31a053, cc_prim_sub_env_mul__t0_sub_prim_mul_primlod_add_shade__add_env}, // fallen leaves, Dobutsu no Mori. Added by Gonetz // (t0-shade)*primlod+shade, (prim-env)*cmb+env ** INC ** {0x8e41a053, cc_prim_sub_env_mul__t0_sub_shade_mul_primlod_add_shade__add_env}, // the icicle above the part just before the entrance to the mountain village, zelda 2 [Ogy]. Added by Gonetz // (t0-prim)*0+shade, (prim-env)*cmb+env ** INC ** ? {0x9f31a053, cc_prim_sub_env_mul_shade_add_env}, // background on level 3-1, kirby 64 [Raziel64]. Added by Gonetz // (0-env)*0+shade {0x9f5f9f5f, cc_shade}, // Spotlight, smash bros // (1-0)*0+shade {0x9ff69ff6, cc_shade}, // water, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz // (0-0)*0+shade, (cmb-cmb)*cmb+cmb {0x9fff0000, cc_shade}, // menu, Dr.Mario. Added by Gonetz // (0-0)*0+shade, (prim-cmb)*env+cmb {0x9fff0503, cc_prim_sub_shade_mul_env_add_shade}, // pikachu, hey you pikachu. Added by Gonetz // (0-0)*0+shade, (env-cmb)*enva+cmb {0x9fff0c05, cc_env_sub_shade_mul_enva_add_shade}, // mega shock, paper mario //(0-0)*0+shade, (env-prim)*cmb+prim {0x9fff6035, cc_env_sub_prim_mul_shade_add_prim}, // Super Mario 64 logo background //z (k5-k5)*0+shade {0x9fff9fff, cc_shade}, // Zelda 2 final movie. Added by Gonetz // (0-0)*0+shade, (prim-0)*cmb+0 {0x9fffe0f3, cc_prim_mul_shade}, // tree shadow, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz // (0-0)*0+shade, (env-0)*cmb+0 {0x9fffe0f5, cc_env_mul_shade}, // N64 logo, Aidyn Chronicles. Added by Gonetz // (0-0)*0+shade, (cmb-0)*prim+0 {0x9fffe3f0, cc_prim_mul_shade}, // Hand, smash bros // (0-0)*0+shade, (cmb-0)*env+0 {0x9fffe5f0, cc_env_mul_shade}, // Lave piranha atack, Paper Mario // (t1-t0)*t0+env, (cmb-t1)*t0+prim ** INC ** {0xa1126120, cc__t0_mul_t1__mul_env_add_prim}, //Arena, Pokemon Stadium 2 // (t1-prim)*t0+env, (cmb-0)*shade+0 {0xa132e4f0, cc__t1_sub_prim_mul_t0_add_env__mul_shade}, // Kirby64 end [Raziel64]. Added by Gonetz // (prim-shade)*t0+env {0xa143a143, cc_prim_sub_shade_mul_t0_add_env}, // Superman [scorpiove]. Added by Gonetz // (t0-env)*t0+env {0xa151a151, cc_t0_sub_env_mul_t0_add_env}, // powder keg, zelda 2. Added by Gonetz // (prim-env)*t0+env, (0-0)*shade_a+cmb {0xa1530bff, cc__prim_sub_env_mul_t0_add_env__add_shadea}, // pokemon attack, Pokemon Stadium 2. Added by Gonetz // (prim-env)*t0+env, (0-0)*prim_lod+cmb {0xa1530ef6, cc__prim_sub_env_mul_t0_add_env__add_primlod}, //attack, Pokemon Stadium 2 // (prim-env)*t0+env, (0-0)*prim_lod+cmb {0xa1530eff, cc_prim_sub_env_mul_t0_add_env}, // Kotake & koume defeated, going into sky, zelda // (prim-env)*t0+env, (prim-env)*0+cmb {0xa1531f53, cc_prim_sub_env_mul_t0_add_env}, // water, Dobutsu no Mori. Added by Gonetz // (prim-env)*t0+env, (cmb-0)*shade+t0 {0xa15324f0, cc_t0_add_shade_mul_env}, //sky, beetle adventure racing. Added by Gonetz // (prim-env)*t0+env, (cmb-shade)*t1+shade **INC** can't be done in one step {0xa1538240, cc__env_inter_prim_using_t0__sub_shade_mul_t0a_add_shade}, //couple's mask, zelda2. Added by Gonetz // (prim-env)*t0+env, (prim-cmb)*shade+shade **INC** can't be done in one step {0xa1538403, cc_t0_mul_shade}, // stadium, Pokemon Stadium 2. Added by Gonetz // (prim-env)*t0+env, (cmb-0)*shade+shade **INC** can't be done in one step {0xa15384f0, cc_t0_mul_shade}, //clothes on girl in inn, zelda2. Added by Gonetz // (prim-env)*t0+env, (cmb-prim)*env+shade **INC** can't be done in one step {0xa1538530, cc_t0_mul_env_add_shade}, // Getting light arrows for the first time, zelda // (prim-env)*t0+env, (prim-env)*cmb+env ** INC ** {0xa153a053, cc_prim_sub_env_mul_t0_add_env}, // Fire, starfox // (prim-env)*t0+env {0xa153a153, cc_prim_sub_env_mul_t0_add_env}, // a spell, Fushigi no Dungeon: Fuurai no Shiren 2 // (prim-env)*t0+env, (cmb-env)*enva+env {0xa153ac50, cc_prim_sub_env_mul__t0_mul_enva__add_env}, // wizrobe's attack, zelda 2. Added by Gonetz. // (prim-env)*t0+env, (cmb-0)*cmb+0 {0xa153e0f0, cc_prim_sub_env_mul_t0_add_env}, // dress, zelda 2. Added by Gonetz. // also for Great Farie's hair - changed to use texture mod by Dave2001. // (prim-env)*t0+env, (shade-0)*cmb+0 {0xa153e0f4, cc__env_inter_prim_using_t0__mul_shade}, // Start menu, paper mario // (prim-env)*t0+env, (cmb-0)*t0+0 {0xa153e1f0, cc_prim_sub_env_mul_t0_add_env}, // {0xa153e0f4, cc_prim_sub_env_mul_t0_add_env}, // Jellyfish tentacles in Jabu-Jabu's belly, zelda // (prim-env)*t0+env, (cmb-0)*prim+0 {0xa153e3f0, cc__env_inter_prim_using_t0__mul_prim}, // Dust, zelda //z (prim-env)*t0+env, (cmb-0)*shade+0 ** INC ** {0xa153e4f0, cc__env_inter_prim_using_t0__mul_shade}, //{0xa153e4f0, cc_prim_sub_env_mul_t0_add_env}, // roof, Kirby 64. Added by Gonetz // (prim-env)*t0+env, (cmb-0)*env+0 ** INC ** {0xa153e5f0, cc_prim_sub_env_mul_t0_add_env}, // hall of fame, Pokemon Stadium // (prim-env)*t0+env, (cmb-0)*primlod+0 {0xa153eef0, cc__prim_sub_env_mul_t0_add_env__mul_primlod}, // Something weird in intro, monster truck madness // (prim-env)*t0+env, (cmb-0)*k5+0 {0xa153eff0, cc__prim_sub_env_mul_t0_add_env__mul_k5}, // clothes, kirby 64. Added by Gonetz // (shade-env)*t0+env {0xa154a154, cc_shade_sub_env_mul_t0_add_env}, // field, Derby Stallion // (shade-env)*t0+env, (cmb-0)*prim+0 ** INC ** {0xa154e3f0, cc_shade_sub_env_mul_t0_mul_prim_add_prim_mul_env}, // background, level 3-5, kirby 64, [Raziel64] // (shade-env)*t0+env, (cmb-0)*shade+0 ** INC ** {0xa154e4f0, cc_shade_sub_env_mul_t0_add_env}, // pokemon attack, Pokemon Stadium 2. Added by Gonetz // (one-env)*t0+env {0xa156a156, cc_one_sub_env_mul_t0_add_env}, // Arena, Pokemon Stadium 2. // (one-env)*t0+env, (cmb-0)*shade+0 {0xa156e4f0, cc__env_inter_one_using_t0__mul_shade}, //Arena, Pokemon Stadium 2 // (t1-0)*t0+env, (cmb-0)*cmb+0 ** INC ** {0xa1f2e0f0, cc__t0_mul_t1__add_env_mul__t0_mul_t1__add_env}, // quake 2 intro // (prim-0)*t0+env, (prim-0)*primlod+cmb ** INC ** {0xa1f30ef3, cc_t0_mul_prim_add_env}, // Kotake or koume's hair, zelda // (prim-0)*t0+env {0xa1f3a1f3, cc_t0_mul_prim_add_env}, // track, ridge racer. Added by Gonetz // (t0-env)*t1+env, (cmb-0)*shade+0 ** INC ** {0xa251e4f0, cc__t0_mul_t1__mul_shade}, // lava, beetle adventure racing // (t0-env)*t1+env, (cmb-0)*enva+0 ** INC ** {0xa251ecf0, cc__t0_mul_t1__mul_enva}, // Ded Moroz, Paper Mario // (prim-env)*t1+env, (1-cmb)*t1+cmb ** INC ** {0xa2530206, cc_prim_sub_env_mul_t1_add_env}, // text, monster truck madness // (prim-env)*t1+env {0xa253a253, cc_prim_sub_env_mul_t1_add_env}, // car position, Top Gear Rally. Added by Gonetz // (prim-env)*t1+env, (cmb-t0)*t1+0 ** INC ** {0xa253e210, cc_prim_sub_env_mul_t1_add_env_mul_t0}, // text, Top Gear Rally. Added by Gonetz // (prim-env)*t1+env, (cmb-0)*t1+0 ** INC ** {0xa253e2f0, cc_prim_sub_env_mul_t1_add_env_mul_t0}, // {0xa253e2f0, cc_prim_sub_env_mul_t1_add_env}, // a pole in the cut-scene that appears after you receive odolwa's mask, zelda 2 [Ogy]. Added by Gonetz // (prim-env)*t1+env, (cmb-0)*shade+0 ** INC ** {0xa253e4f0, cc_t1_mul_prim_mul_shade}, // Quake 2 intro. Added by Gonetz // (t0-0)*t1+env, (t0-0)*primlod+cmb ** INC ** {0xa2f10ef1, cc__t0_mul_t1__add_env}, // silver cave, pokemon stadium 2 // (t0-0)*t1+env, (cmb-prim)*shadea+prim {0xa2f16b30, cc_prim_inter__t0_mul_t1_add_env__using_shadea}, // silver cave, pokemon stadium 2 // (t0-0)*t1+env, (cmb-0)*shadea+shade {0xa2f18bf0, cc__t0_mul_t1_add_env__mul_shadea_add_shade}, // Quake64. Added by Gonetz // (t0-0)*t1+env {0xa2f1a2f1, cc__t0_mul_t1__add_env}, // Quake II. Added by Gonetz ** INC ** // (t0-0)*t1+env, (cmb-0)*prim+env {0xa2f1a3f0, cc__t0_mul_t1__mul_prim_add_env}, // Dr Mario [Ogy]. Added by Gonetz // (t0-env)*prim+env // {0xa351a351, cc_t0_mul_prim_add_env}, {0xa351a351, cc_t0_sub_env_mul_prim_add_env}, // menu, Dr.Mario. Added by Gonetz // (prim-env)*prim+env {0xa353a353, cc_prim_sub_env_mul_prim_add_env}, // Razor sword, zelda 2. Added by Gonetz // (shade-env)*prim+env, (cmb-0)*shade+0 ** INC ** {0xa354e4f0, cc_shade_sub_env_mul_prim_add_env}, // bomberman 64-2 intro. Added by Gonetz // (1-env)*prim+env {0xa356a356, cc_one_sub_env_mul_prim_add_env}, // thing that escapes from the well, zelda // (noise-env)*prim+env {0xa357a357, cc_prim_add_env}, // Bongo Bongo, zelda // (noise-env)*prim+env, (cmb-0)*shade+0 {0xa357e4f0, cc_env_mul_shade}, // paper mario. Added by Gonetz // (t0-0)*prim+env {0xa3f1a3f1, cc_t0_mul_prim_add_env}, // paper mario. Added by Gonetz // (t0-0)*prim+env, (t0-env)*prim+0 {0xa3f1e351, cc_t0_mul_prim_add_env}, // paper mario. Added by Gonetz // (t0-0)*prim+env, (t0-0)*prim+0 {0xa3f1e3f1, cc_t0_mul_prim}, // mahogany town statue, Pokemon Stadium 2 // (t0-0)*prim+env, (cmb-0)*shade+0 {0xa3f1e4f0, cc__t0_mul_prim_add_env__mul_shade}, // squirt, paper mario. Added by Gonetz // (t1-0)*prim+env, (1-cmb)*t1+cmb {0xa3f20206, cc_t1_mul_prim_add_env}, // paper mario. Added by Gonetz // (shade-0)*prim+env {0xa3f4a3f4, cc_prim_mul_shade_add_env}, // Sharpen attack, pokemon stadium 2 // (shade-0)*prim+env, (cmb-0)*shade+0 {0xa3f4e4f0, cc__prim_mul_shade_add_env__mul_shade}, // Doraemon 2. Added by Gonetz // (1-0)*prim+env {0xa3f6a3f6, cc_prim_add_env}, // Pokemon Stadium 2, [Jeremy]. Added by Gonetz // (noise-0)*prim+env ** INC ** ? {0xa3f7a3f7, cc_prim_add_env}, // monsters, Pokemon Stadium. Added by Gonetz // (t0-t1)*shade+env, (cmb-0)*prim+0 ** INC ** {0xa421e3f0, cc__t0_sub_t1__mul_prim_mul_shade_add_prim_mul_env}, // background, pokemon stadium 2 // (t0-prim)*shade+env {0xa431a431, cc_t0_sub_prim_mul_shade_add_env}, // Arena, pokemon stadium 2 // (t0-prim)*shade+env, (cmb-0)*shade+0 {0xa431e4f0, cc__t0_sub_prim_mul_shade_add_env__mul_shade}, // Trophy, pokemon stadium 2 // (t0-prim)*shade+env, (cmb-0)*shade_a+0 {0xa431ebf0, cc__t0_sub_prim_mul_shade_add_env__mul_shadea}, // Buildings, pokemon stadium 2 // (t1-prim)*shade+env {0xa432a432, cc_t1_sub_prim_mul_shade_add_env}, // bomberman 64 [Ogy] // (t0-env)*shade+env {0xa451a451, cc_t0_mul_shade_add_env}, // kirby drill, kirby 64. Added by Gonetz // (prim-env)*shade+env {0xa453a453, cc_prim_sub_env_mul_shade_add_env}, // ball, ISS98 intro. Added by Gonetz // (t0-0)*shade+env {0xa4f1a4f1, cc_t0_mul_shade_add_env}, // waterfall, Dobutsu_no_Mori // (prim-0)*shade+env, (t0-0)*primlod+cmb {0xa4f30ef1, cc_t0_mul_primlod_add_prim_mul_shade_add_env}, // waterfall, Dobutsu_no_Mori // (prim-0)*shade+env, (t1-0)*primlod+cmb {0xa4f30ef2, cc_t1_mul_primlod_add_prim_mul_shade_add_env}, // score, ISS98 intro. Added by Gonetz // (prim-0)*shade+env {0xa4f3a4f3, cc_prim_mul_shade_add_env}, // magic fist, Rayman2. Added by Gonetz // (env-0)*shade+env {0xa4f5a4f5, cc_env_mul_shade_add_env}, // gunfire, Quake64. Added by Gonetz // (1-0)*shade+env {0xa4f6a4f6, cc_env_add_shade}, // flame, Paper Mario. Added by Gonetz // (t0-center)*scale+env, (0-prim)*cmb+env {0xa661a03f, cc_env_sub__t0_mul_scale_add_env__mul_prim}, // N64 BIOS // (t0-env)*t0_a+env, cmb*shade {0xa851e0f4, cc__env_inter_t0_using_t0a__mul_shade}, // pink car, f-zero x // (t0-env)*t0_a+env, cmb*shade {0xa851e4f0, cc__env_inter_t0_using_t0a__mul_shade}, // PokemonStadium1, [Raziel64] // (prim-env)*t0_a+env, (cmb-cmb)*cmb+cmb {0xa8530000, cc_prim_sub_env_mul_t0a_add_env}, // N64 logo, Ogre Battle // (prim-env)*t0_a+env {0xa853a853, cc_prim_sub_env_mul_t0a_add_env}, // Mud Slap, Pokemon Stadium 2 [gokuss4]. Added by Gonetz // (prim-env)*t0_a+env, (cmb-0)*cmb+0 {0xa853e0f0, cc_prim_sub_env_mul_t0a_add_env}, // Tree background, mace // (prim-env)*t0_a+env, (cmb-0)*t0+0 {0xa853e1f0, cc__env_inter_prim_using_t0a__mul_t0}, //attack, Pokemon Stadium 2 // (prim-env)*t0_a+env, (cmb-0)*prim+0 {0xa853e3f0, cc__env_inter_prim_using_t0a__mul_prim}, // logo, Deadly Arts. Added by Gonetz // (prim-env)*t1_a+env {0xa953a953, cc_prim_sub_env_mul_t1a_add_env}, // MarioGolf text "Birdie Put" // (t0-env)*prim_a+env {0xaa51aa51, cc_t0_sub_env_mul_prima_add_env}, // N64 BIOS // (t0-env)*prim_a+env, (shade-0)*cmb+0 {0xaa51e0f4, cc__env_inter_t0_using_prima__mul_shade}, // N64 BIOS // (prim-env)*prima+env, (shade-0)*cmb+0 {0xaa53e0f4, cc__env_inter_prim_using_prima__mul_shade}, // Girl, PD intro. Added by Gonetz // (t0-env)*shade_alpha+env, (cmb-0)*shade+0 ** INC ** {0xab51e4f0, cc__env_inter_t0_using_shadea__mul_shade}, // Some gannon spell, zelda // (prim-env)*shade_alpha+env {0xab53ab53, cc_prim_sub_env_mul_shadea_add_env}, //Arena, Pokemon Stadium 2 // (t0-0)*shade_alpha+env, (cmb-0)*shade+prim {0xabf164f0, cc__t0_mul_shadea_add_env__mul_shade_add_prim}, // Boxes, Taz express. Added by Gonetz // (t0-env)*env_a+env {0xac51ac51, cc_t0_sub_env_mul_enva_add_env}, // paper mario. Added by Gonetz // (t0-env)*env_a+env, (cmb-0)*shade+0 **INC** {0xac51e4f0, cc_t0_mul_env_mul_shade}, // goal, Monster Truck Madness 64 // (noise-0)*env_a+env, (cmb-0)*t1+0 **INC** {0xacf7e2f0, cc_t1_mul_env}, // sword on forge, zelda 2. Added by Gonetz // (t1-t1)*lodf+env, (t1-t0)*cmb+prim {0xae226012, cc__t1_sub_t0__mul_env_add_prim}, // menu background, Pokemon Stadium 2, [Raziel64] // (t0-prim)*lodf+env {0xae31ae31, cc_t0_sub_prim_mul_primlod_add_env}, // odd mushroom, zelda oot. Added by Gonetz // (t0-shade)*lodf+env, (prim-env)*cmb+env ** INC ** {0xae41a053, cc__env_inter_prim_using__t0_sub_shade_mul_primlod_add_env}, // {0xae41a053, cc_prim_sub_env_mul__t0_mul_shade__add_env}, // Morning Sun, Pokemon Stadium 2 [gokuss4]. Added by Gonetz // (t0-env)*lodf+env, (cmb-0)*prim+0 {0xae51e3f0, cc__env_inter_t0_using_primlod__mul_prim}, //Spacestation Silicon Valley intro. Added by Gonetz // (prim-env)*lodf+env {0xae53ae53, cc_env_inter_prim_using_primlod}, // Doom, intro. Added by Gonetz // (t0-0)*lodf+env, (t0-0)*lodf+env {0xaef1aef1, cc_t0_add_env}, // Dobutsu no Mori. Added by Gonetz // (prim-0)*lodf+env {0xaef3aef3, cc_prim_add_env}, // forest behind window, Dobutsu no Mori. Added by Gonetz // (prim-0)*prim_lod+env, (t1-0)*cmb+0 {0xaef3e0f2, cc_t0_mul__prim_mul_primlod_add_env }, // tony hawks 2 menu // (t0-rnv)*k5+env, (cmb-t1)*t1_a+t1 ** INC ** (correct combiner does not work because of black t1) {0xaf514920, cc_t0_sub_env_mul_k5_add_env}, // intro, Mission Impossible. Added by Gonetz // (k5-k5)*0+env, (0-0)*scale+env {0xbfffa6ff, cc_env}, // Something blocking the screen, waverace //z (k5-k5)*0+env {0xbfffbfff, cc_env}, // Derby Stallion . Added by Gonetz // (0-0)*0+env, (cmb-0)*prim+0 {0xbfffe3f0, cc_prim_mul_env}, // zelda 2 [Ogy]. Added by Gonetz // (k5-k5)*0+env, ((cmb-0)*shade+0 {0xbfffe4f0, cc_env_mul_shade}, // flame, paper mario. Added by Gonetz // (t0-t1)*t0+1, (0-prim)*cmb+env **INC** weird {0xc121a03f, cc__t0_inter_t1_using_half__mul_prim_add_env}, // tube near big monster on level 5, Kirby64 [Raziel64] // (prim-env)*t0+1, (cmb-0)*shade+0 ** INC ** {0xc153e4f0, cc_prim_sub_env_mul_t0_mul_shade}, // paper mario. Added by Gonetz // (0-env)*t0+1, (prim-cmb)*t0+prim **INC** {0xc15f6103, cc_env_sub_prim_mul_t0_add_prim}, // HAL, smash bros // (0-0)*0+1 {0xdfffdfff, cc_one}, // arena, Pokemon Stadium 1, [Raziel64] // (0-0)*0+1, (cmb-0)*prim+0 {0xdfffe3f0, cc_prim}, // skis, Spacestation Silicon Valley. Added by Gonetz // (shade-0)*cmb+0, (t1-t0)*primlod+t0 {0xe0f42d12, cc_t0_inter_t1_using_primlod}, // paper mario. Added by Gonetz // (1-t1)*t0+0, (env-prim)*cmb+prim ** INC ** {0xe1266035, cc_env_sub_prim_mul__t0_mul_t1__add_prim}, // ground, zelda 2. Added by Gonetz. // (t1-prim)*t0+0, (cmb-0)*shade+0 {0xe132e4f0, cc__t1_sub_prim_mul_t0__mul_shade}, // carmagedon // (shade-prim)*t0+0 {0xe134e134, cc_shade_sub_prim_mul_t0}, // skeleton, castlevania 2. Added by Gonetz // (1-prim)*t0+0, (cmb-0)*shade+0 {0xe136e4f0, cc_t0_mul_1mprim_mul_shade}, // Starshot logo. Added by Gonetz // (shade-env)*t0+0, (1-0)*cmb+cmb {0xe15400f6, cc_shade_sub_env_mul_t0}, // Kirby morfing, smash bros. Added by Gonetz // (shade-env)*t0+0 {0xe154e154, cc_shade_sub_env_mul_t0}, // menu, PGA euro tour. Added by Gonetz // (1-env)*t0+0 {0xe156e156, cc_one_sub_env_mul_t0}, // paper mario. Added by Gonetz // (t0-0)*t0+0, (1-cmb)*prim+cmb {0xe1f10306, cc_one_sub_t0_mul_prim_add_t0}, // F1 World Grand Prix. Added by Gonetz // (t0-0)*t0+0, (shade-prim)*cmb+prim {0xe1f16034, cc_shade_sub_prim_mul_t0_add_prim}, // paper mario. Added by Gonetz // (t0-0)*t0+0, (env-prim)*cmb+prim {0xe1f16035, cc_env_sub_prim_mul_t0_add_prim}, // sparkles, F1 World Grand Prix. Added by Gonetz // (t0-0)*t0+0, (1-prim)*cmb+prim {0xe1f16036, cc_one_sub_prim_mul_t0_add_prim}, // rocket team basket, Pokemon Stadium 2 // (t0-0)*t0+0, (cmb-prim)*shade+shade {0xe1f18430, cc__t0_mul_t0__sub_prim_mul_shade_add_shade}, // Tony Hawk's Pro Skater. Added by Gonetz // (t0-0)*t0+0, (cmb-0)*t0+0 {0xe1f1e1f0, cc_t0}, // something in upper left corner, mario tennis // (t0-0)*t0+0 {0xe1f1e1f1, cc_t0}, // zelda 2. Added by Gonetz // (t0-0)*t0+0, (cmb-0)*prim+0 {0xe1f1e3f0, cc_t0_mul_prim}, // zelda 2 final movie. Added by Gonetz // (t0-0)*t0+0, (cmb-0)*shade+0 {0xe1f1e4f0, cc_t0_mul_shade}, // paper mario. Added by Gonetz // (t0-t1)*t0+1, (env-cmb)*prima+cmb ** INC ** {0xe1f20a05, cc_t1_mul_prima}, // terrain, SCARS. Added by Gonetz // (t1-0)*t0+0, (env-prim)*cmb+prim {0xe1f26035, cc_env_sub_prim_mul__t0_mul_t1__add_prim}, // Trees, Zelda 2 // (t1-0)*t0+0, (cmb-0)*shade+prim {0xe1f264f0, cc__t0_mul_t1__mul_shade_add_prim}, // terrain, SCARS. Added by Gonetz // (t1-0)*t0+0, (env-shade)*cmb+shade {0xe1f28045, cc_env_sub_shade_mul__t0_mul_t1__add_shade}, // arena, Pokemon Stadium 2. Added by Gonetz // (t1-0)*t0+0, (cmb-prim)*shade+shade ** INC ** {0xe1f28430, cc__t0_mul_t1__sub_prim_mul_shade_add_shade}, // arena, Pokemon Stadium 2 // (t1-0)*t0+0, (cmb-env)*shade+shade {0xe1f28450, cc__t0_mul_t1__sub_env_mul_shade_add_shade}, // Zelda 2, [Ogy]. Added by Gonetz // (t1-0)*t0+0, (cmb-prim)*env+shade ** INC ** {0xe1f28530, cc__t0_mul_t1__sub_prim_mul_env_add_shade}, // pokemon attack, Pokemon Stadium 2. Added by Gonetz // (t1-0)*t0+0, (prim-env)*cmb+env {0xe1f2a053, cc_prim_sub_env_mul__t0_mul_t1__add_env}, // paper mario. Added by Gonetz // (t1-0)*t0+0, (cmb-0)*prim+env {0xe1f2a3f0, cc__t0_mul_t1__mul_prim_add_env}, // Sand, pokemon stadium 2 // (t1-0)*t0+0, (cmb-prim)*shade+env ** INC ** {0xe1f2a430, cc__t0_mul_t1__mul_shade}, // grass, Mission Impossible. Added by Gonetz // (t1-0)*t0+0, (shade-0)*cmb+0 {0xe1f2e0f4, cc__t0_mul_t1__mul_shade}, // flag, Monako Grand Prix // (t1-0)*t0+0 {0xe1f2e1f2, cc_t0_mul_t1}, // lighthouse's beam, zelda 2. Added by Gonetz // (t1-0)*t0+0, (cmb-0)*prim+0 {0xe1f2e3f0, cc__t0_mul_t1__mul_prim}, // Bottom of wings, pilotwings // (t1-0)*t0+0, (cmb-0)*shade+0 {0xe1f2e4f0, cc__t0_mul_t1__mul_shade}, // zelda 2. Added by Gonetz // (t1-0)*t0+0, (cmb-0)*prima+0 {0xe1f2eaf0, cc__t0_mul_t1__mul_prima}, // lava, Roadsters. Added by Gonetz // (prim-0)*t0+0, (1-prim)*t0+cmb {0xe1f30136, cc_t0}, // sky, Pokemon Stadium 2. Added by Gonetz // (prim-0)*t0+0, (cmb-0)*shadea+env {0xe1f3abf0, cc_t0_mul_prim_mul_shadea_add_env}, // cars, Indy Racing 2000. Added by Gonetz // (prim-0)*t0+0, (shade-0)*cmb+0 {0xe1f3e0f4, cc_t0_mul_prim_mul_shade}, // Sign shadows, zelda //z (prim-k5)*t0+cmb_a {0xe1f3e1f3, cc_t0_mul_prim}, // Table, mace // (prim-0)*t0+0, (cmb-0)*shade+0 {0xe1f3e4f0, cc_t0_mul_prim_mul_shade}, // Gauntlet Legends intro // (prim-0)*t0+0, (cmb-0)*prima+0 {0xe1f3eaf0, cc_t0_mul_prim_mul_prima}, // walls, beetle adventure racing. Added by Gonetz // (shade-0)*t0+0, (prim-0)*t0+cmb {0xe1f401f3, cc_t0_mul_shade}, // cars, ridge racer. Added by Gonetz // (shade-0)*t0+0, (prim-cmb)*cmb_a+cmb **INC** {0xe1f40703, cc_t0_mul_shade}, // water block, Paper Mario. Added by Gonetz // (shade-0)*t0+0, (prim-env)*cmb+env {0xe1f4a053, cc_prim_sub_env_mul__t0_mul_shade__add_env}, // a lot in TWINE. Added by Gonetz // (shade-0)*t0+0, (cmb-0)*prim+env {0xe1f4a3f0, cc_t0_mul_prim_mul_shade_add_env}, // Xena. Added by Gonetz // (shade-0)*t0+0, (env-0)*cmb+0 {0xe1f4e0f5, cc_t0_mul_env_mul_shade}, // Starshot logo. Added by Gonetz // (shade-0)*t0+0, (1-0)*cmb+0 {0xe1f4e0f6, cc_t0_mul_shade}, // Duck Dodgers intro. Added by Gonetz // (shade-0)*t0+0 {0xe1f4e1f4, cc_t0_mul_shade}, // shadow, Mission Impossible. Added by Gonetz // (shade-0)*t0+0, (cmb-0)*prim+0 {0xe1f4e3f0, cc_t0_mul_prim_mul_shade}, // Tony Hawk's Pro Skater 3. Added by Gonetz // (env-0)*t0+0, (t1-0)*shade+cmb ** INC ** {0xe1f504f2, cc__t0_add_t1__mul_shade}, // text, tonic trouble. Added by Gonetz // (env-0)*t0+0 {0xe1f5e1f5, cc_t0_mul_env}, // powder keg, zelda 2. Added by Gonetz // (env-0)*t0+0, (cmb-0)*shade+0 {0xe1f5e4f0, cc_t0_mul_env_mul_shade}, // Buss rush // (1-0)*t0+0, (0-cmb)*0+cmb {0xe1f61f0f, cc_t0}, // water, Starshot. Added by Gonetz // (1-0)*t0+0, (1-0)*cmb+0 {0xe1f6e0f6, cc_t0}, // bomberman 64 [Ogy] // (1-0)*t0+0 {0xe1f6e1f6, cc_t0}, // Mermaid attack, Mystical Ninja // (noise-0)*t0+0 {0xe1f7e1f7, cc_t0}, // paper mario. Added by Gonetz * changed because of odd palette copy // (t0-0)*t1+0, (shade-env)*cmb+cmb **INC** ? {0xe2f10054, cc_shade_sub_env_mul__t0_mul_t1__add__t0_mul_t1}, // Duck Dodgers Starring Daffy Duck text background // (t0-0)*t1+0, (shade-cmb)*prim+cmb {0xe2f10304, cc_one_sub_prim_mul__t0_mul_t1__add__prim_mul_shade}, // water, PGA European Tour // (t0-0)*t1+0, (env-cmb)*prim+cmb {0xe2f10305, cc_one_sub_prim_mul__t0_mul_t1__add__prim_mul_env}, // Grass, mario golf // (t0-0)*t1+0, (cmb-t0)*cmb_a+t0 {0xe2f12710, cc_t0_mul_t1}, // xg2, Added by Gonetz // (t0-0)*t1+0, (env-prim)*cmb+prim {0xe2f16035, cc_env_sub_prim_mul__t0_mul_t1__add_prim}, // poo, CBFD, Added by Gonetz // (t0-0)*t1+0, (cmb-env)*shade+prim ** INC ** {0xe2f16450, cc__t0_mul_t1__mul_shade_add_prim}, // the champion stage, Pokemon Stadium 2 // (t0-0)*t1+0, (cmb-0)*shade+prim {0xe2f164f0, cc__t0_mul_t1__mul_shade_add_prim}, // sky, xg2, Added by Gonetz // (t0-0)*t1+0, (cmb-prim)*cmb_a+prim {0xe2f16730, cc__t0_mul_t1__sub_prim_mul__t0t1a__add_prim }, // Sin and Punishment, [scorpiove], Added by Gonetz // (t0-0)*t1+0, (env-prim)*cmb_a+prim {0xe2f16735, cc_env_sub_prim_mul__t0t1a__add_prim}, // cianwood gym walls, pokemon stadium 2 // (t0-0)*t1+0, (cmb-prim)*shade+shade {0xe2f18430, cc__t0_mul_t1__sub_prim_mul_shade_add_shade}, // light, Ridge Racer. Added by Gonetz // (t0-0)*t1+0, (prim-env)*cmb+env {0xe2f1a053, cc_prim_sub_env_mul__t0_mul_t1__add_env}, // Waterfall, duck dodgers. Added by Gonetz // (t0-0)*t1+0, (shade-env)*cmb+env {0xe2f1a054, cc_shade_sub_env_mul__t0_mul_t1__add_env}, // Arena, Pokemon Stadium 2 ** INC ** // (t0-0)*t1+0, (cmb-prim)*shade+env {0xe2f1a430, cc__t0_mul_t1__mul_shade_add_env}, // bikes, xg2 // (t0-0)*t1+0, (shade-0)*cmb+0 {0xe2f1e0f4, cc__t0_mul_t1__mul_shade}, // Sky background, xg2 // (t0-0)*t1+0 {0xe2f1e2f1, cc_t0_mul_t1}, // statistics, Banjo 2. Added by Gonetz // (t0-0)*t1+0, (cmb-0)*prim+0 {0xe2f1e3f0, cc__t0_mul_t1__mul_prim}, // the champion stage, Pokemon Stadium 2 // (t0-0)*t1+0, (cmb-prim)*shade+0 {0xe2f1e430, cc__t0_mul_t1__sub_prim_mul_shade}, // Water, pilotwings // (t0-0)*t1+0, (cmb-0)*shade+0 {0xe2f1e4f0, cc__t0_mul_t1__mul_shade}, //beetle adventure racing. A dded by Gonetz // (t0-0)*t1+0, (cmb-0)*env+0 {0xe2f1e5f0, cc__t0_mul_t1__mul_env}, //fall headwaters, zelda 2. Added by Gonetz // (t1-0)*t1+0, (cmb-0)*shade+0 {0xe2f2e4f0, cc_t1_mul_shade}, //text, Paper Mario // (prim-0)*t1+0 {0xe2f3e2f3, cc_t1_mul_prim}, //terrain, Beetle Adventure Racing. Added by Gonetz // (shade-0)*t1+0 {0xe2f4e2f4, cc_t1_mul_shade}, // Transfer pack, Pokemon Stadium 2 // (noise-0)*t1+0, (prim-env)*cmb+env {0xe2f7a053, cc_prim_sub_env_mul_t1_add_env}, // lens of truth, zelda 2 [Ogy]. Added by Gonetz // (1-t0)*prim+0 {0xe316e316, cc_one_sub_t0_mul_prim}, //C&C pointer //(shade-env)*prim+0 {0xe354e354, cc_shade_sub_env_mul_prim}, //C&C shadows //(1-env)*prim+0 {0xe356e356, cc_one_sub_env_mul_prim}, // Magnitude, pokemon stadium 2 // (t0-0)*prim+0, (t0-0)*env+cmb {0xe3f105f1, cc_t0_mul__prim_add_env}, // night vision, jet force gemini // (t0-0)*prim+0, (noise-0)*env+cmb {0xe3f105f7, cc_t0_mul_prim_add_env}, // Smoke, diddy kong racing // (t0-0)*prim+0, (env-cmb)*env_alpha+cmb {0xe3f10c05, cc__t0_mul_prim__inter_env_using_enva}, // battle menu, Paper Mario. Added by Gonetz // (t0-0)*prim+0, (t0-env)*env_alpha+cmb ** INC ** {0xe3f10c51, cc_t0_mul_prim}, // stalactites, Beetle adventure Racing. Added by Gonetz // (t0-0)*prim+0, (cmb-shade)*t1_alpha+shade ** INC ** {0xe3f18940, cc_t0_mul_prim_add_shade }, // ? in Jabu-Jabu's belly, submitted by gokuss4 // {0xe4f1a053, (t0-0)*prim+0, (prim-env)*cmb+env {0xe3f1a053, cc_prim_sub_env_mul__t0_mul_prim__add_env}, // kirby drill, kirby 64. Added by Gonetz // (t0-0)*prim+0, (cmb-env)*shade+env **INC** {0xe3f1a450, cc_t0_mul_prim_mul_shade_add_env}, // ? sign, zelda 2. Added by Gonetz // (t0-0)*prim+0, (cmb-0)*cmb+0 ** INC ** {0xe3f1e0f0, cc_t0_mul_prim}, // vehicle, Star Wars Ep.1 Racer, [Raziel64]. Added by Gonetz // (t0-0)*prim+0, (shade-0)*cmb+0 {0xe3f1e0f4, cc_t0_mul_prim_mul_shade}, // mini game, Pokemon Stadium 2 // (t0-0)*prim+0, (1-0)*cmb+0 {0xe3f1e0f6, cc_t0_mul_prim}, // magic stuff, buck bumble. Added by Gonetz // (t0-0)*prim+0, (cmb-0)*prim+0 {0xe3f1e3f0, cc_t0_mul_prim_mul_prim}, // The mario face, mario //z (t0-k5)*prim+cmb_a {0xe3f1e3f1, cc_t0_mul_prim}, // Butterflies at Jabu-Jabu's lake, zelda // (t0-0)*prim+0, (cmb-0)*shade+0 {0xe3f1e4f0, cc_t0_mul_prim_mul_shade}, // Sports shirt, Mia Soccer. Added by Gonetz // (t1-0)*prim+0, (1-t0)*t1+cmb **INC** // {0xe3f20216, cc_t0_mul_prim_add_t1}, {0xe3f20216, cc_shirt}, // Sprites, Ogre Battle. Added by Gonetz // (t1-0)*prim+0 {0xe3f2e3f2, cc_t1_mul_prim}, // F1 World Grand Prix. Added by Gonetz // (t1-0)*prim+0, (cmb-0)*shade+0 {0xe3f2e4f0, cc_t1_mul_prim_mul_shade}, // intro background, bio freaks. Added by Gonetz // (prim-0)*prim+0 {0xe3f3e3f3, cc_prim_mul_prim}, // player, Ohzumou2 // (shade-0)*prim+0, (env-cmb)*t0+cmb {0xe3f40105, cc_env_sub_primshade_mul_t0_add_primshade}, // floor in pyramides, beetle adventure racing. // (shade-0)*prim+0, (t1-0)*cmb+0 {0xe3f4e0f2, cc_t1_mul_prim_mul_shade}, // Slingshot string, zelda // (shade-0)*prim+0 {0xe3f4e3f4, cc_prim_mul_shade}, // ? // (shade-0)*prim+0, (cmb-0)*shade+0 ** INC ** {0xe3f4e4f0, cc_prim_mul_shade}, // ???, zelda // (env-0)*prim+0, (0-0)*0+cmb {0xe3f5e3f5, cc_prim_mul_env}, // Option selection, zelda //z (1-0)*prim+0 {0xe3f6e3f6, cc_prim}, // ranco monster, zelda 2. Added by Gonetz // (noise-0)*prim+0, (cmb-0)*prim_a+prim {0xe3f76af0, cc_prim_mul_prima_add_prim}, // F-1_World_Grand_Prix_II, olivieryuyu // (noise-0)*prim+0, (0-cmb)*prim_a+shade {0xe3f78a0f, cc_shade_sub__prim_mul_prima}, // zelda 2 [Ogy]. Added by Gonetz // (noise-0)*prim+0 {0xe3f7e3f7, cc_prim}, // Road rush. Added by Gonetz // (0-0)*prim+0 ** INC ** ? {0xe3ffe3ff, cc_prim}, // Letter to Kafei's mom, zelda 2. Added by Gonetz // (0-0)*prim+0, (cmb-0)*shade+0 {0xe3ffe4f0, cc_prim_mul_shade}, // Jabu-Jabu's Belly, zelda. Added by Gonetz // (1-t0)*shade+0, (cmb-0)*prim+0 {0xe416e3f0, cc_one_sub_t0_mul_prim_mul_shade}, // Arena, Pokemon Stadium 2 // (t0-prim)*shade+0 {0xe431e431, cc_t0_sub_prim_mul_shade}, // silver cave, pokemon stadium 2 // (t0-env)*shade+0, (cmb-prim)*shade+prim {0xe4516430, cc__t0_sub_env_mul_shade__sub_prim_mul_shade_add_prim}, // bomb mask, zelda 2. Added by Gonetz // (t0-env)*shade+0, (cmb-prim)*shade+shade ** INC ** {0xe4518430, cc__t0_sub_env_mul_shade__sub_prim_mul_shade}, // terrain, Top Gear Rally 2. Added by Gonetz // (t0-env)*shade+0 {0xe451e451, cc_t0_sub_env_mul_shade}, // closes, Nightmire Creatures // (1-env)*shade+0 {0xe456e456, cc_one_sub_env_mul_shade}, // water, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz // (t0-0)*shade+0, (cmb-cmb)*cmb+cmb {0xe4f10000, cc_t0_mul_shade}, // Monster truck madness intro. Added by Gonetz // (t0-0)*shade+0, (1-0)*cmb+cmb ** INC ** {0xe4f100f6, cc_t0_mul_shade}, // terrain, SCARS. Added by Gonetz // (t0-0)*shade+0, (prim-cmb)*t0+cmb ** INC ** {0xe4f10103, cc_t0_mul_shade}, // Boomerang circle, zelda // (t0-0)*shade+0, (1-cmb)*t0+cmb {0xe4f10106, cc_t0_mul_shade}, // THPS3. // (t0-0)*shade+0, (1-0)*t0+cmb {0xe4f101f6, cc_t0_mul_shade}, // ???, WWF No Mercy [CpuMaster] // (t0-0)*shade+0, (env-cmb)*prim+cmb {0xe4f10305, cc_t0_mul_one_sub_prim_mul_shade_add_prim_mul_env}, // magic bubble, zelda2. Added by Gonetz // (t0-0)*shade+0, (t1-0)*shade+cmb {0xe4f104f2, cc__t0_mul_shade__add__t1_mul_shade}, // bike select, xg2. Added by Gonetz // (t0-0)*shade+0, (1-cmb)*env+cmb ** INC ** {0xe4f10506, cc_t0_mul_shade}, // a bugs life [Ogy] // (t0-0)*shade+0, (cmb-0)*env+cmb // {0xe4f105f0, cc_t0_mul_env_mul_shade}, {0xe4f105f0, cc_t0_mul_shade}, // Wall, quest64 // (t0-0)*shade+0, (1-0)*env+cmb {0xe4f105f6, cc_t0_mul_shade_add_env}, //lava, beetle adventure racing. Added by Gonetz // (t0-0)*shade+0, (prim-cmb)*cmb_a+cmb **INC** {0xe4f10703, cc_t0_mul_shade}, // course map, Ridge Racer. Added by Gonetz // (t0-0)*shade+0, (prim-cmb)*prima+cmb **INC** {0xe4f10a03, cc_t0_mul_shade}, // arena, custom robo. Added by Gonetz // (t0-0)*shade+0, (noise-cmb)*prima+cmb **INC** {0xe4f10a07, cc_t0_mul_shade}, // arena, custom robo 2. Added by Gonetz // (t0-0)*shade+0, (0-cmb)*prima+cmb **INC** {0xe4f10a0f, cc_t0_mul_shade}, //floor in a cave, Paper mario. Added by Gonetz // (t0-0)*shade+0, (cmb-prim)*prima+cmb **INC** {0xe4f10a30, cc_t0_mul_shade}, //beetle adventure racing. Added by Gonetz // (t0-0)*shade+0, (t1-prim)*prima+cmb **INC** {0xe4f10a32, cc_t0_mul_shade}, // Monster truck madness intro. Added by Gonetz // (t0-0)*shade+0, (shade-cmb)*shade_a+cmb ** INC ** {0xe4f10b04, cc_t0_mul_shade}, // xg2 intro. Added by Gonetz // (t0-0)*shade+0, (1-cmb)*shade_a+cmb ** INC ** {0xe4f10b06, cc__t0_mul_shade__inter_one_using_shadea}, // Link's bomb, smash bros // (t0-0)*shade+0, (env-cmb)*env_a+cmb ** INC ** {0xe4f10c05, cc__t0_mul_shade__inter_env_using_enva}, // language selection, Extreme-G XG2 (E) // (t0-0)*shade+0, (1-cmb)*env_a+cmb {0xe4f10c06, cc__t0_mul_shade__inter_one_using_enva}, // A Bugs Life, [Raziel64] // (t0-0)*shade+0, (cmb-0)*k5+cmb {0xe4f10ff0, cc_t0_mul_shade}, // Bass Rush // (t0-0)*shade+0, (cmb-0)*0+cmb {0xe4f11f0f, cc_t0_mul_shade}, // car, Top Gear Rally. Added by Gonetz // (t0-0)*shade+0, (cmb-t0)*t0a+t0 **INC** {0xe4f12810, cc_t0_mul_shade}, // logo, SCARS. Added by Gonetz // (t0-0)*shade+0, (cmb-t0)*shadea+t0 **INC** {0xe4f12b10, cc__t0_mul_shade_mul_shadea__add__t1_mul_one_sub_shadea}, // ? sign, Spiderman. Added by Gonetz // (t0-0)*shade+0, (0-0)*0+t1 {0xe4f15fff, cc_t0_mul_shade}, // Major League Baseball Featuring Ken Griffey Jr. // (t0-0)*shade+0, (1-0)*cmb+prim ** INC ** {0xe4f160f6, cc_t0_mul_shade_add_prim}, // plants, CBFD. Added by Gonetz // (t0-0)*shade+0, (cmb-env)*shade+prim ** INC ** {0xe4f16450, cc_t0_sub_env_mul_shade_add_prim}, // Kirby64. Added by Gonetz // (t0-0)*shade+0, (cmb-prim)*prima+prim {0xe4f16a30, cc_t0_mul_prima_mul_shade_add_prim_mul_one_sub_prima}, // building shadow, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz // (t0-0)*shade+0, (0-0)*0+prim {0xe4f17fff, cc_prim}, // tire trace, beetle adventure racing. Added by Gonetz // (t0-0)*shade+0, (env-cmb)*t1+shade **INC** {0xe4f18205, cc_env_sub_shade_mul_t0_add_shade}, // Gold Skulltula, zelda // (t0-0)*shade+0, (prim-env)*cmb+env {0xe4f1a053, cc_prim_sub_env_mul_t0_mul_shade_add_env}, // {0xe4f1a053, cc_t0_mul_prim_mul_shade}, // fighters, GASP Fighters // (t0-0)*shade+0, (1-env)*cmb+env {0xe4f1a056, cc_t0_mul_one_sub_env_mul_shade_add_env}, // Brian, quest64 // (t0-0)*shade+0, (cmb-0)*prim+env {0xe4f1a3f0, cc_t0_mul_prim_mul_shade_add_env}, // Objects in arena, pokemon stadium 2 // (t0-0)*shade+0 // (cmb-prim)*shade+env {0xe4f1a430, cc_t0_mul_shade}, // Monster truck madness intro. Added by Gonetz // (t0-0)*shade+0, (cmb-env)*shadea+env **INC** // {0xe4f1ab50, cc_t0_mul_shade_add_env}, {0xe4f1ab50, cc__t0_mul_shade__sub_env_mul_shadea_add_env}, // Taz express. Added by Gonetz // (t0-0)*shade+0, (cmb-env)*enva+env **INC** {0xe4f1ac50, cc_t0_mul_shade_add_env}, // sky in doom. Added by Gonetz // (t0-0)*shade+0, (cmb-0)*primlod+env **INC** {0xe4f1aef0, cc_t0_mul_shade_add_env}, // fighters, GASP Fighters // (t0-0)*shade+0, (1-env)*cmb+0 {0xe4f1e056, cc_t0_mul_one_sub_env_mul_shade}, // walls, beetle adventure racing. Added by Gonetz // (t0-0)*shade+0, (t0-0)*cmb+0 **INC** {0xe4f1e0f1, cc_t0_mul_shade}, // Link's face, zelda //z (t0-k5)*shade+cmb_a, (prim-k5)*cmb+cmb_a {0xe4f1e0f3, cc_t0_mul_prim_mul_shade}, // Link's suit, zelda //z (t0-k5)*shade+cmb_a, (env-k5)*cmb+cmb_a {0xe4f1e0f5, cc_t0_mul_env_mul_shade}, // Window, starfox //z (t0-k5)*shade+cmb_a, (cmb-k5)*prim+cmb_a {0xe4f1e3f0, cc_t0_mul_prim_mul_shade}, // crystal, Doraemon 2 //(t0-0)*shade+0, (t0-0)*prim+0 {0xe4f1e3f1, cc_t0_mul_prim}, // Characters, mace // (t0-0)*shade+0, (cmb-0)*shade+0 {0xe4f1e4f0, cc_t0_mul_shade}, // Super Mario 64 logo //z (t0-k5)*shade+cmb_a {0xe4f1e4f1, cc_t0_mul_shade}, // Kokiri's hat, zelda // (t0-0)*shade+0, (cmb-0)*env+0 {0xe4f1e5f0, cc_t0_mul_env_mul_shade}, // Gauntlet Legends intro // (t0-0)*shade+0, (cmb-0)*scale+0 {0xe4f1e6f0, cc_t0_mul_scale_mul_shade}, // Something on a tree, Paper Mario. Added by Gonetz // (t0-0)*shade+0, (cmb-0)*prima+0 {0xe4f1eaf0, cc_t0_mul_prima_mul_shade}, // Course map, Ridge Racer. Added by Gonetz // (t0-0)*shade+0, (cmb-0)*shadea+0 {0xe4f1ebf0, cc_t0_mul_shade_mul_shadea}, // Dodongo skull's eyes, zelda // (t0-0)*shade+0, (cmb-0)*env_alpha+0 {0xe4f1ecf0, cc_t0_mul_enva_mul_shade}, // lava, beetle adventure racing. Added by Gonetz // (t1-0)*shade+0, (cmb-prim)*cmb_a+prim **INC** {0xe4f26730, cc_prim_inter_t1_mul_shade_using_texa}, // headlight, beetle adventure racing. Added by Gonetz // (t1-0)*shade+0, (env-cmb)*t0+shade **INC** {0xe4f28105, cc_one_sub__t0_mul_t1__mul_shade}, // bubble, Banjo-Kazooie. Added by Gonetz // (t1-0)*shade+0 {0xe4f2e4f2, cc_t1_mul_shade}, // water, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz // (prim-0)*shade+0, (cmb-cmb)*cmb+cmb {0xe4f30000, cc_prim_mul_shade}, // lamp shadow, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz // (prim-0)*shade+0, (cmb-cmb)*t0+cmb {0xe4f30100, cc_prim_mul_shade}, // Yoshi, mario golf // (prim-0)*shade+0, (env-cmb)*t0+cmb {0xe4f30105, cc_env_sub_primshade_mul_t0_add_primshade}, //Spacestation Silicon Valley intro. Added by Gonetz // (prim-0)*shade+0, (env-cmb)*t1+cmb {0xe4f30205, cc_env_sub_primshade_mul_t1_add_primshade}, // Tip of brian's hair, quest64 // (prim-0)*shade+0, (1-0)*env+cmb {0xe4f305f6, cc_prim_mul_shade_add_env}, // V8-2 menu // (prim-0)*shade+0, (env-cmb)*cmb_a+cmb {0xe4f30705, cc__prim_mul_shade__inter_env_using__prim_mul_shade_alpha}, // Background circle, xg2 // (prim-0)*shade+0, (1-cmb)*shade_a+cmb {0xe4f30b06, cc_prim_mul_shade}, // circle, waverace. Added by Gonetz // (prim-0)*shade+0, (t0-cmb)*enva+cmb {0xe4f30c01, cc_t0_sub__prim_mul_shade__mul_enva_add__prim_mul_shade}, // enemy hit, Glover2 // (prim-0)*shade+0, (env-cmb)*enva+cmb {0xe4f30c05, cc__prim_mul_shade__inter_env_using_enva}, // player, super bowling // (prim-0)*shade+0, (0-0)*k5+cmb {0xe4f30fff, cc_prim_mul_shade}, //Lure, bass rush // (prim-0)*shade+0, (0-cmb)*0+cmb {0xe4f31f0f, cc_prim_mul_shade}, // walls, beetle adventure racing. Added by Gonetz // (prim-0)*shade+0, (cmb-shade)*t1+shade **INC** {0xe4f38240, cc__one_inter_prim_using_t1__mul_shade}, // GASP fighters //(prim-0)*shade+0, (1-env)*cmb+0 {0xe4f3e056, cc_prim_mul_one_sub_env_mul_shade}, // Flag, mario kart //z (prim-k5)*shade+cmb_a {0xe4f3e4f3, cc_prim_mul_shade}, // Characters, smash bros // (prim-0)*shade+0, (cmb-0)*env+0 {0xe4f3e5f0, cc_prim_mul_env_mul_shade}, // N64 logo, ridge race. Added by Gonetz // (shade-0)*shade+0, (prim-cmb)*prima+cmb **INC** {0xe4f40a03, cc_shade}, // fighter, shield mode, bio freaks. Added by Gonetz // (shade-0)*shade+0 {0xe4f4e4f4, cc_shade}, // truck crush, Monster truck madness. Added by Gonetz // (env-0)*shade+0, (env-0)*shade+cmb {0xe4f504f5, cc_env_mul_shade}, // Course map, Ridge Racer. Added by Gonetz // (env-0)*shade+0 {0xe4f5e4f5, cc_env_mul_shade}, // lava, beetle adventure racing // (1-0)*shade+0, (prim-cmb)*cmb_a+cmb {0xe4f60703, cc_prim_sub_shade_mul_shadea_add_shade}, // the wings in the song of soaring cut-scene, zelda2 [Ogy]. Added by Gonetz // (1-0)*shade+0, (prim-0)*cmb+0 {0xe4f6e0f3, cc_prim_mul_shade}, // parts of vehicle, Star Wars Ep.I Racer. Added by Gonetz // (1-0)*shade+0, (cmb-0)*prim+0 {0xe4f6e3f0, cc_prim_mul_shade}, // Snowflakes???, mario kart. Boxer shadow (fb effect}, Knockout Kings 2000 // (1-0)*shade+0, (1-0)*shade+0 {0xe4f6e4f6, cc_one_mul_shade}, // ??? // (noise-0)*shade+0 {0xe4f7e4f7, cc_shade}, // quest64 [Ogy] // (prim-t0)*env+0, (0-0)*0+prim {0xe5137fff, cc_prim}, // field, Mike Piazza's Strike Zone // (t0-prim)*env+0 ** INC ** {0xe531e531, cc_t0_mul_env}, // Mike Piazza's Strike Zone // (shade-prim)*env+0 {0xe534e534, cc_shade_sub_prim_mul_env}, // rope, CBFD. Added by Gonetz // (t0-0)*env+0, (1-env)*prim+cmb {0xe5f10356, cc_one_sub_env_mul_prim_add__t0_mul_env}, // Bell, Pokemon Stadium 2. Added by Gonetz // (t0-0)*env+0, (shade-0)*prim+cmb {0xe5f103f4, cc_t0_mul_env_add_prim_mul_shade}, // aerofighter's assault [Ogy] // (t0-0)*env+0, (1-t0)*shade+cmb {0xe5f10416, cc_t0_mul_env_add_1mt0_mul_shade}, // foto, Armorines - Project S.W.A.R.M. Added by Gonetz // (t0-0)*env+0, (noise-0)*scale+cmb {0xe5f106f7, cc_t0_mul_env}, // Extreme G2, score. Added by Gonetz // (t0-0)*env+0, (1-cmb)*enva+cmb ** INC ** {0xe5f10c06, cc_t0_mul_env}, // many objects in Tonic Trouble // (t0-0)*env+0, (shade-0)*cmb+0 {0xe5f1e0f4, cc_t0_mul_env_mul_shade}, // Flying skull's eyes, zelda // (t0-0)*env+0, (cmb-0)*prim+0 {0xe5f1e3f0, cc_t0_mul_prim_mul_env}, // Rock spell, quest64 // (t0-0)*env+0, (cmb-0)*shade+0 {0xe5f1e4f0, cc_t0_mul_env_mul_shade}, // Text, mario //z (t0-k5)*env+cmb_a {0xe5f1e5f1, cc_t0_mul_env}, // kirby 64. Added by Gonetz // (prim-0)*env+0, (cmb-0)*shade+0 {0xe5f3e4f0, cc_prim_mul_env_mul_shade}, // wings, kirby 64. Added by Gonetz // (prim-0)*env+0 {0xe5f3e5f3, cc_prim_mul_env}, // Text, xg2 // (shade-0)*env+0, (1-cmb)*env_a+cmb {0xe5f40c06, cc_env_mul_shade}, // Text box, mario //z (shade-k5)*env+cmb_a {0xe5f4e5f4, cc_env_mul_shade}, // bomberman 64 [Ogy] // (1-0)*env+0 {0xe5f6e5f6, cc_env}, // Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz // (1-t0)*scale+0 {0xe616e616, cc_zero}, // Gauntlet Legends intro. Added by Gonetz // (t0-0)*scale+0, (cmb-0)*shade+0 {0xe6f1e4f0, cc_t0_mul_scale_mul_shade}, // shadows, Taz express. Added by Gonetz // (t0-0)*scale+0 {0xe6f1e6f1, cc_t0_mul_scale}, // shadows, Knockout Kings 2000. Added by Gonetz // (shade-0)*scale+0 {0xe6f4e6f4, cc_scale_mul_shade}, // bomberman 64 2 [Ogy]. Added by Gonetz // (1-0)*scale+0 {0xe6f6e6f6, cc_scale}, // walls, beetle adventure racing. Added by Gonetz // (t1-0)*t0_a+0, (1-t1)*cmb+t1 **INC** {0xe8f24026, cc_t1}, // house on rancho, zelda2. Added by Gonetz // (t1-0)*t0_a+0, (cmb-0)*prim+0 {0xe8f2e3f0, cc__t0a_mul_t1__mul_prim}, // zelda2 [Ogy]. Added by Gonetz // (t1-0)*t0_a+0, (cmb-0)*shade+0 {0xe8f2e4f0, cc__t0a_mul_t1__mul_shade}, // mini quiz, Pokemon Stadium 2 // (prim-0)*t0_a+0, (cmb-t1)*primlod+t1 ** INC ** {0xe8f34e20, cc_t0}, // Major League Baseball Featuring Ken Griffey Jr. // (prim-0)*t0_a+0 {0xe8f3e8f3, cc_t0a_mul_prim}, // Top Gear Hyper-Bike // (1-0)*t0_a+0 {0xe8f6e8f6, cc_t0a}, // waterfall, Dobutsu_no_Mori // (t0-0)*t1_a+0, (prim-env)*cmb+env {0xe9f1a053, cc_prim_sub_env_mul__t0_mul_t1a__add_env}, // logo, Deadly Arts. Added by Gonetz // (t0-0)*t1_a+0, (cmb-0)*shade+0 {0xe9f1e4f0, cc__t0_mul_t1a__mul_shade}, // car, Roadsters. Added by Gonetz // (prim-t0)*prim_a+0, (prim-cmb)*shade+0 ** INC ** {0xea13e403, cc_prim_sub__prim_sub_t0_mul_prima__mul_shade}, // arena, Pokemon Stadium 2. Added by Gonetz // (1-t0)*prim_a+0, (0-prim)*cmb+prim ** INC ** {0xea16603f, cc_t0_mul_prim}, // V8-2 // (1-prim)*prim_a+0 {0xea36ea36, cc_one_sub_prim_mul_prima}, // match start, Mario Tennis. Added by Gonetz // (t0-0)*prim_a+0, (1-t0)*cmb+t0 ** INC ** {0xeaf12016, cc_one_sub_t0_mul_prima_add_t0}, // blast corps [Ogy] // (t0-0)*prim_a+0 {0xeaf1eaf1, cc_t0_mul_prima}, // final battle, CBFD. Added by Gonetz // (prim-0)*prim_a+0 {0xeaf3eaf3, cc_prim_mul_prima}, // flower's stalk, Paper Mario. Added by Gonetz // (shade-0)*prim_a+0 {0xeaf4eaf4, cc_shade_mul_prima}, // blast corps [Ogy] // (noise-0)*prim_a+0, (t1-0)*shade+cmb ** INC ** {0xeaf704f2, cc_t0_mul_shade_add_prima}, // F1 World Grand Prix. Added by Gonetz // (noise-0)*prim_a+0, (t1-0)*env_a+cmb ** INC ** {0xeaf70cf2, cc_t1_mul_enva}, // shadows, killer instinct gold // (0-0)*prim_a+0 {0xeaffeaff, cc_zero}, // background, killer instinct gold // (t0-prim)*shade_a+0 {0xeb31eb31, cc_t0_sub_prim_mul_shadea}, // ground, C&C // (t0-shade)*shade_a+0 {0xeb41eb41, cc_t0_sub_shade_mul_shadea}, // Wreslters, WWF No Mercy, [CpUMasteR] // (t0-0)*shade_alpha+0, (env-cmb)*prim+cmb {0xebf10305, cc_t0_mul_one_sub_prim_mul_shadea_add_prim_mul_env}, // map, Pilot wings. Added by Gonetz // (t0-0)*shade_alpha+0, (1-cmb)*shade+cmb {0xebf10406, cc_one_sub_shade_mul__t0_mul_shadea__add_shade}, // Indy Racing 2000. Added by Gonetz // (t0-0)*shade_alpha+0, (1-0)*shade+cmb {0xebf104f6, cc_t0_mul_shadea_add_shade}, // logo, WCW-nWo Revenge // (t0-0)*shade_alpha+0, (cmb-0)*prim+0 {0xebf1e3f0, cc_t0_mul_prim_mul_shadea}, // sky, pilot wings // (t0-0)*shade_alpha+0, (1-cmb)*shade+0 {0xebf1e406, cc_one_sub__t0_mul_shadea__mul_shade}, // Wrestlers in Game, WWF No mercy [CpUMasteR] // (t0-0)*shade_alpha+0 {0xebf1ebf1, cc_t0_mul_shadea}, // flag, top gear overdrive // (prim-0)*shade_alpha+0 {0xebf3ebf3, cc_prim_mul_shadea}, // Ropes, WWF games // (shade-0)*shade_alpha+0, (env-cmb)*prim+cmb {0xebf40305, cc_shade_mul_shadea}, // Ropes, WWF games // (shade-0)*shade_alpha+0 {0xebf4ebf4, cc_shade_mul_shadea}, // arena, custom robo 2 // (noise-0)*shade_alpha+0 {0xebf7ebf7, cc_shadea}, // Baton Pass attack, Pokemon Stadium 2 // (t0-env)*enva+0, (shade-0)*prim+cmb {0xec5103f4, cc__t0_sub_env_mul_enva__add_prim_mul_shade}, // Bell, Pokemon Stadium 2. Added by Gonetz // (t0-0)*enva+0, (shade-0)*prim+cmb {0xecf103f4, cc_t0_mul_enva_add_prim_mul_shade}, // blastcorps, unimp log. Added by Gonetz // (t0-0)*enva+0 {0xecf1ecf1, cc_t0_mul_enva}, // car, Top Gear Rally. Added by Gonetz // (env-0)*enva+0 {0xecf5ecf5, cc_env_mul_enva}, // Sand attack, pokemon Stadium (J) // (noise-0)*enva+0, (prim-env)*cmb+env {0xecf7a053, cc_prim_sub_env_mul_enva_add_env}, // Walls of well through lens of truth, zelda // (prim-t0)*primlod+0 ** INC ** {0xee13ee13, cc_t0}, // JUST t0 b/c the other combiner handles the subtraction // Pokemon attack, Pokemon Stadium 2 // (noise-t0)*primlod+0, (1-env)*cmb+env ** INC ** {0xee17a056, cc_env_inter_one_using__one_sub_t0_mul_primlod}, // barrage attack, Pokemon Stadium 2 // (t0-0)*primlod+0, (prim-0)*shade+cmb {0xeef104f3, cc__t0_mul_primlod__add__prim_mul_shade}, // something on a flor in stone temple, zelda 2. Added by Gonetz // (t0-0)*primlod+0, (cmb-0)*prim+0 {0xeef1e3f0, cc_t0_mul_primlod_mul_prim}, // entrance to oceanside spider house, zelda 2. Added by Gonetz // (t0-0)*primlod+0, (cmb-0)*shade+0 {0xeef1e4f0, cc_t0_mul_primlod_mul_shade}, // Haze/(all powder status changers), Pokemon Stadium 2 [gokuss4]. Added by Gonetz // (noise-0)*primlod+0, (prim-env)*cmb+env ** INC ** {0xeef7a053, cc_prim_sub_env_mul_primlod_add_env}, // pokemon attack, Pokemon Stadium 2. Added by Gonetz // (noise-0)*primlod+0, (prim-cmb)*cmb+0 ** INC ** {0xeef7e003, cc_zero}, // Night trees, Monster truck madness. Added by Gonetz // (t0-0)*k5+0 {0xeff1eff1, cc_t0_mul_k5}, // submitted by gokuss4 // (0-0)*0+0, (0-0)*0+prim {0xfffd5fe6, cc_prim}, // intro, Bettle Adventure Racing, [Raziel64] // (0-0)*0+0, (0-0)*0+t0 {0xffff3fff, cc_t0}, // Conker's face, CBFD // (0-0)*0+0, (shade-env)*k5+prim {0xffff6f54, cc_shade_sub_env_mul_k5_add_prim}, // Boost, Beetle Adventure Racing. Added by Gonetz // (0-0)*0+0, (0-0)*0+prim {0xffff7fff, cc_prim}, // headlight, beetle adventure racing. Added by Gonetz // (0-0)*0+0, (0-0)*0+shade {0xffff9fff, cc_shade}, // intro, Bettle Adventure Racing, [Raziel64] // (0-0)*0+0, (shade-env)*t1+env {0xffffa254, cc_shade_sub_env_mul_t1_add_env}, // Fly Swooping in, Pokemon Stadium 2 [gokuss4]. Added by Gonetz // (0-0)*0+0, (1-env)*cmb_a+env {0xffffa756, cc_env}, // Waterfall, Donkey Kong 64 // (0-0)*0+0, (t0-0)*t1+0 {0xffffe1f2, cc_t0_mul_t1}, // Screen clear, banjo kazooie // (0-0)*0+0 {0xffffffff, cc_zero}, // { #CCEND } }; static COMBINER alpha_cmb_list[] = { // { #ACSTART } //Tony Hawk's Pro Skater. Added by Gonetz // (0-0)*0+0 {0x01ff01ff, ac_zero}, //terminal, Spacestation Silicon Valley. Added by Gonetz // (0-0)*0+0, (0-0)*0+prim {0x01ff07ff, ac_prim}, // kirby drill, kirby 64. Added by Gonetz // (0-0)*0+cmb, (0-0)*0+1 {0x01ff0dff, ac_one}, //chip in Spacestation Silicon Valley intro. Added by Gonetz // (0-0)*0+cmb, (prim-0)*shade+0 {0x01ff0f3b, ac_prim_mul_shade}, //Goldeneye, [Jeremy]. Added by Gonetz // (t0-t0)*lodf+t0, (cmb-0)*prim+0 {0x02090ef8, ac_t0_mul_prim}, // Indy Racing 2000. Added by Gonetz // (t1-t0)*lodf+t0, (env-cmb)*prim+cmb ** INC ** {0x020a00c5, ac_t0_inter_t1_using_primlod}, // water, Spacestation Silicon Valley. Added by Gonetz // (t1-t0)*lodf+t0, (0-shade)*0+cmb {0x020a01e7, ac_t0_inter_t1_using_primlod}, // Bridge, sf rush //z (t1-t0)*lodf+t0 {0x020a020a, ac_t0_inter_t1_using_primlod}, // explosion, body harvest. Added by Gonetz //(t1-t0)*lodf+t0, (0-0)*0+t0 {0x020a03ff, ac_t0}, // cars, PD intro. Added by Gonetz // (t1-t0)*lodf+t0, (cmb-0)*shade+prim {0x020a0738, ac__t0_inter_t1_using_primlod__mul_shade_add_prim}, // Rocket Robot in Wheels intro //(t1-t0)*lodf+t0, (0-0)*0+prim {0x020a07ff, ac_prim}, // Iguana background ground, turok // (t1-t0)*lodf+t0, (0-0)*0+shade {0x020a09ff, ac_shade}, // Ground, monster truck madness // (t1-t0)*lodf+t0, (0-0)*0+env {0x020a0bff, ac_env}, // Taz express. Added by Gonetz // (t1-t0)*lodf+t0, (0-0)*0+1 {0x020a0dff, ac_one}, // Mike Piazza's Strike Zone // (t1-t0)*lodf+t0, (cmb-0)*t0+0 {0x020a0e78, ac_t0_inter_t1_using_primlod}, // N64 logo, tetrisphere. Added by Gonetz // (t1-t0)*lodf+t0, (cmb-0)*prim+0 {0x020a0ef8, ac__t0_inter_t1_using_primlod__mul_prim}, // Ground, mace // (t1-t0)*lodf+t0, (cmb-0)*shade+0 // {0x020a0f38, ac_t0_mul_shade}, {0x020a0f38, ac__t0_inter_t1_using_primlod__mul_shade}, // blast corps [Ogy] // (t1-t0)*lodf+t0, (cmb-0)*env+0 {0x020a0f78, ac__t0_inter_t1_using_primlod__mul_env}, // blast corps [Ogy] // (t1-t0)*lodf+t0, (t0-0)*env+0 {0x020a0f79, ac_t0_mul_env}, // blast corps. Added by Gonetz // (t1-t0)*lodf+t0, (shade-0)*env+0 {0x020a0f7c, ac_env_mul_shade}, // field, Mike Piazza's Strike Zone // (t1-t0)*lodf+t0, (0-0)*0+0 {0x020a0fff, ac_t0_inter_t1_using_primlod}, // blast corps, unimp log. Added by Gonetz // (t1-t0)*t0+t0 {0x024a024a, ac_t0_inter_t1_using_t0a}, // zelda 2 [Ogy]. Added by Gonetz // (t1-t0)*t0+t0, (cmb-0)*prim+0 **INC** {0x024a0ef8, ac__t0_inter_t1_using_t0a__mul_prim}, // text in a menu, Twisted_Edge_Extreme_Snowboarding [Razeil64]. Added by Gonetz // (prim-t0)*t0+t0 **INC** {0x024b024b, ac_t0}, // enemy's shot, battle tanks 2 // (env-prim)*t0+t0 **INC** {0x025d025d, ac_t0}, //Bowser in final battle, Paper Mario. Added by Gonetz // (t1-env)*t0+t0, (cmb-env)*prim+0 ** INC ** {0x026a0ee8, ac__t0_mul_t1__mul_prim}, // paper mario. Added by Gonetz // (t1-env)*t0+t0, (cmb-0)*prim+0 ** INC ** {0x026a0ef8, ac__t0_mul_t1__mul_prim}, // V8-2 // (prim-0)*t0+t0 {0x027b027b, ac_t0_mul_prim_add_t0}, // THPS3. Added by Gonetz // (0-0)*t0+t0 {0x027f027f, ac_t0}, // zelda 2. Added by Gonetz // (0-0)*t0+t0, (cmb-0)*prim+0 {0x027f0ef8, ac_t0_mul_prim}, // Spider Web attack, Pokemon Stadium 2. // (t1-t0)*t1+t0, (cmb-0)*prim+cmb {0x028a00f8, ac__t0_inter_t1_using_t1a__mul_prim_add__t0_inter_t1_using_t1a}, // teleportation, Spacestation Silicon Valley. Added by Gonetz // (t1-t0)*t1+t0 {0x028a028a, ac_t0_inter_t1_using_t1a}, // mega shock, paper mario. Added by Gonetz // (t1-t0)*t1+t0, (cmb-0)*prim+0 {0x028a0ef8, ac__t0_inter_t1_using_t1a__mul_prim}, // mini game, Pokemon Stadium 2 // (t1-t0)*t1+t0, (cmb-0)*shade+0 {0x028a0f38, ac__t0_inter_t1_using_t1a__mul_shade}, // Magnitude, pokemon stadium 2 // (shade-t0)*t1+t0, (cmb-0)*shade+env {0x028c0b38, ac__t0_mul_t1__mul_shade}, // paper mario. Added by Gonetz // (1-t0)*t1+t0, (t1-0)*prim+0 ** INC ** {0x028e0efa, ac__one_sub_t0_mul_t1_add_t0__mul_prim}, // {0x028e0efa, ac_t1_mul_prim}, // Spider Web attack, Pokemon Stadium 2. // (1-t0)*t1+t0, (cmb-0)*shade+0 ** INC ** {0x028e0f38, ac__one_sub_t0_mul_t1_add_t0__mul_prim}, // paper mario. Added by Gonetz // (t1-env)*t1+t0, (cmb-0)*shade+0 {0x02aa0f38, ac__t0_inter_t1_using_enva__mul_shade}, // Scary dead boss thing, zelda // (env-1)*t1+t0, (cmb-0)*prim+0 * MAY need t1_inter_t0 instead... {0x02b50ef8, ac__env_sub_one_mul_t1_add_t0__mul_prim}, // first screen, castlevania. Added by Gonetz // (env-0)*t1+t0 **INC** {0x02bd02bd, ac_t0}, // enemy's shot, battle tanks 2 [Flash] // (1-0)*t1+t0, (0-0)*0+env {0x02be0bff, ac_env}, // battle tanks 2 [Ogy] // (1-0)*t1+t0, (0-0)*0+1 {0x02be0dff, ac_one}, // menu screen, Rayman2. Added by Gonetz // (1-0)*t1+t0, (cmb-0)*shade+0 {0x02be0f38, ac__t0_add_t1__mul_shade}, // Sky, zelda //z (t1-t0)*prim+t0 {0x02ca02ca, ac_t0_inter_t1_using_prima}, // F1 World Grand Prix. Added by Gonetz // (t1-t0)*prim+t0, (0-0)*0+1 {0x02ca0dff, ac_t0_inter_t1_using_prima}, // logo, PD. Added by Gonetz // (t1-t0)*prim+t0, (cmb-0)*shade+0 {0x02ca0f38, ac__t0_inter_t1_using_prima__mul_shade}, // battle tanks [Ogy] // (t1-t0)*prim+t0, (cmb-0)*env+0 {0x02ca0f78, ac__t0_inter_t1_using_prima__mul_env}, // logo, Deadly Arts. Added by Gonetz // (env-t0)*prim+t0 {0x02cd02cd, ac_one_sub_prim_mul_t0_add__prim_mul_env}, // intro, castlevania 2. Added by Gonetz // (1-t0)*prim+t0 {0x02ce02ce, ac_one_sub_t0_mul_prim_add_t0}, // intro, diddy kong racing. Added by Gonetz // (1-t0)*prim+t0, (cmb-0)*shade+0 **INC** {0x02ce0f38, ac_t0_mul_shade}, // submitted by Scorpiove, mario party 1 // (0-t0)*prim+t0 {0x02cf02cf, ac_one_sub_prim_mul_t0}, // Pokemon attack, pokemon Stadium (J) // (t1-t1)*prim+t0, (prim-0)*lod_f+env **INC** {0x02d20a3b, ac_env}, // Ground, pokemon stadium 2 // (t0-0)*prim+t0 {0x02f902f9, ac_t0_mul_prim}, // GASP Fighters // (t1-0)*prim+t0, ** INC ** {0x02fa02fa, ac_t1_mul_prim_add_t0}, // foresight attack, Pokemon Stadium 2 // (t1-0)*prim+t0, (cmb-env)*shade+0 {0x02fa0f28, ac__t1_mul_prima_add_t0__sub_env_mul_shade}, // Earthquake pokemon attack, Pokemon Stadium 2 [gokuss4]. Added by Gonetz // (t1-0)*prim+t0, (cmb-0)*shade+0 {0x02fa0f38, ac__t1_mul_prima_add_t0__mul_shade}, // Paper Mario, fortune teller // (t1-0)*prim+t0, (cmb-0)*env+0 {0x02fa0f78, ac__t1_mul_prima_add_t0__mul_env}, // Hydro Pump Attack, Pokemon Stadium. // (shade-0)*prim+t0, (cmb-0)*shade+0 {0x02fc0f38, ac__t0_add_prim_mul_shade__mul_shade}, // map, Ogre Battle 64. Added by Gonetz // (1-0)*prim+t0 {0x02fe02fe, ac_t0_add_prim}, // borders, Tony Hawk's Pro Skater 2. Added by Gonetz // (t1-t0)*shade+t0 ** INC ** {0x030a030a, ac_t0_inter_t1_using_shadea}, // Mickey USA // (t1-t0)*shade+t0, (cmb-0)*prim+0 ** INC ** {0x030a0ef8, ac__t0_inter_t1_using_shadea__mul_prim}, // Rocket Robot in Wheels intro // (t1-t0)*shade+t0, (cmb-0)*env+0 ** INC ** {0x030a0f78, ac__t0_inter_t1_using_shadea__mul_env}, // water, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz // (1-t0)*shade+t0, (cmb-0)*shade+0 ** INC ** {0x030e0f38, ac_t0_mul_shade}, // sky, f-zero x // (0-t0)*shade+t0 {0x030f030f, ac_one_sub_shade_mul_t0}, // Deku tree from kokiri villiage, zelda //z (t1-t0)*env+t0, (t1-0)*primlod+cmb {0x034a01ba, ac_t0_inter_t1_using_enva}, // Hearts, zelda //z (t1-t0)*env+t0 {0x034a034a, ac_t0_inter_t1_using_enva}, // Faries, zelda //z (t1-t0)*env+t0, (cmb-0)*prim+0 {0x034a0ef8, ac__t0_inter_t1_using_enva__mul_prim}, // zelda, waterfall. Added by Gonetz //z (t1-t0)*env+t0, (cmb-0)*shade+0 {0x034a0f38, ac__t0_inter_t1_using_enva__mul_shade}, // pokemon stadium 1. Added by Gonetz //(t1-t0)*env+t0, (cmb-0)*primlod+0 {0x034a0fb8, ac__t0_inter_t1_using_enva__mul_primlod}, // fruits, Yoshi Story. Added by Gonetz //(prim-t0)*env+t0 {0x034b034b, ac_prim_sub_t0_mul_env_add_t0}, // window, Rayman2. Added by Gonetz //(1-t0)*env+t0 {0x034e034e, ac_one_sub_t0_mul_env_add_t0}, // menu, PokemonStadium1, [Raziel64] //(1-t0)*env+t0, (cmb-0)*shade+0 ** INC ** {0x034e0f38, ac_t0_mul_shade}, // Ganon's sword swinging, zelda // (t0-t1)*env+t0, (cmb-0)*prim+0 ** INC ** {0x03510ef8, ac__t0_sub_t1_mul_enva_add_t0__mul_prim}, // Lave piranha atack, Paper Mario // (t1-prim)*env+t0, (0-cmb)*t1+0 ** INC ** {0x035a0e87, ac_t0_mul_t1}, // Reflected fire at kotake & koume's, zelda // (t0-1)*env+t0, (cmb-0)*prim+0 ** INC ** {0x03710ef8, ac__t0_sub_one_mul_enva_add_t0__mul_prim}, // thing that escapes from the well, zelda // (t1-1)*env+t0 ** INC ** {0x03720372, ac_t1_sub_one_mul_enva_add_t0}, // Sword charge, zelda // (t1-1)*env+t0, (cmb-0)*prim+0 {0x03720ef8, ac__t1_sub_one_mul_enva_add_t0__mul_prim}, // Gannon hitting the ground, zelda // (t1-1)*env+t0, (cmb-0)*shade+0 ** INC ** {0x03720f38, ac__t1_sub_one_mul_enva_add_t0__mul_shade}, // Tony Hawk's Pro Skater 3. Added by Gonetz // (t0-0)*env+t0 {0x03790379, ac_t0_mul_env}, // paper mario. Added by Gonetz // (t0-0)*env+t0, (cmb-0)*prim+0 {0x03790ef8, ac_t0_mul_prim}, // pads, Pokemon Stadium 2. Added by Gonetz // (t1-0)*env+t0, (cmb-0)*prim+env ** INC ** {0x037a0af8, ac__t0_inter_t1_using_enva__mul_prim_add_env}, // attack, Pokemon Stadium 2 // (t1-0)*env+t0, (cmb-t0)*prim+0 ** INC ** {0x037a0ec8, ac__t1_mul_enva_add_t0__mul_prim}, // Ice arrow gfx, zelda // (t1-0)*env+t0, (cmb-0)*prim+0 {0x037a0ef8, ac__t1_mul_enva_add_t0__mul_prim}, // Scary face move, pokemon stadium 2 // (t1-0)*env+t0, (cmb-prim)*shade+0 {0x037a0f18, ac__t1_mul_enva_add_t0__sub_prim_mul_shade}, // Saria's song, zelda // (t1-0)*env+t0, (cmb-0)*shade+0 {0x037a0f38, ac__t1_mul_enva_add_t0__mul_shade}, // eye drops bottle, zelda // (t0-t0)*prim_lodfrac+t0 {0x03890389, ac_t0}, // lighthouse's beam, zelda 2. Added by Gonetz // (t0-t0)*prim_lodfrac+t0, (cmb-0)*prim+0 {0x03890ef8, ac_t0_mul_prim}, // zelda 2. Added by Gonetz // (t1-t0)*primlod+t0, (cmb-0)*env+cmb ** INC ** {0x038a0178, ac__t0_inter_t1_using_primlod__mul_env_add__t0_inter_t1_using_primlod}, // Enter name letter background, zelda //z (t1-t0)*primlod+t0 {0x038a038a, ac_t0_inter_t1_using_primlod}, // Sunny Day, Pokemon Stadium 2 // (t1-t0)*primlod+t0, (cmb-0)*0+prim {0x038a07f8, ac_prim}, //attack, Pokemon Stadium 2 // (t1-t0)*primlod+t0, (cmb-env)*shade+shade ** INC ** {0x038a0928, ac__t0_inter_t1_using_primlod__sub_env_mul_shade_add_shade}, // blastcorps, unimp log. Added by Gonetz // (t1-t0)*primlod+t0, (0-0)*0+shade **INC**? {0x038a09ff, ac_t0_inter_t1_using_primlod}, // pokemon attack, pokemon monsters (J) // (t1-t0)*primlod+t0, (cmb-0)*prim+env {0x038a0af8, ac__t0_inter_t1_using_primlod__mul_prim_add_env}, // sky, PGA European Tour // (t1-t0)*primlod+t0, (0-0)*0+1 {0x038a0dff, ac_one}, // Ice surrounding enemy, zelda // (t1-t0)*primlod+t0, (env-0)*lodf+0 {0x038a0e3d, ac__t0_inter_t1_using_primlod__mul_env}, // the bridge out side the mountain smithy shop, zelda 2 [Ogy]. Added by Gonetz // (t1-t0)*primlod+t0, (cmb-0)*t0+0 {0x038a0e78, ac_t0_inter_t1_using_primlod}, // zelda 2, [Ogy]. Added by Gonetz // (t1-t0)*primlod+t0, (cmb-0)*t1+0 {0x038a0eb8, ac_t0_inter_t1_using_primlod}, // Kirby's pool, smash bros // (t1-t0)*primlod+t0, (cmb-0)*prim+0 {0x038a0ef8, ac__t0_inter_t1_using_primlod__mul_prim}, // Samus stage fire, smash bros // (t1-t0)*primlod+t0, (cmb-0)*shade+0 {0x038a0f38, ac__t0_inter_t1_using_primlod__mul_shade}, // something about ice, zelda // (t1-t0)*primlod+t0, (cmb-0)*env+0 {0x038a0f78, ac__t0_inter_t1_using_primlod__mul_env}, // Blast Corps. Added by Gonetz // (t1-t0)*primlod+t0, (shade-0)*env+0 {0x038a0f7c, ac_env_mul_shade}, // goals, J. League Tactics Soccer. Added by Gonetz // (prim-t0)*primlod+t0 ** INC ** {0x038b038b, ac_t0}, // zelda 2, [Ogy]. Added by Gonetz // (t0-t1)*primlod+t0, (cmb-0)*prim+0 {0x03910ef8, ac__t0_sub_t1_mul_primlod_add_t0__mul_prim}, // a plane in the entrance to the mountain village zelda 2, [Ogy]. Added by Gonetz // (t1-t1)*primlod+t0, (cmb-0)*prim+0 ** INC **? {0x03920ef8, ac_t0_mul_prim}, // zelda 2. Added by Gonetz // (t1-prim)*primlod+t0, (cmb-0)*prim+0 ** INC ** {0x039a0ef8, ac__t1_sub_prim_mul_primlod_add_t0__mul_prim}, // zelda 2. Added by Gonetz // (t1-shade)*primlod+t0, (cmb-0)*shade+0 ** INC ** {0x03a20f38, ac__t1_sub_shade_mul_primlod_add_t0__mul_shade}, // saffron city, Pokemon Stadium 2 // (t1-1)*primlod+t0, (cmb-0)*0+cmb {0x03b201f8, ac_t1_sub_one_mul_primlod_add_t0}, // Candle flame in ganon's castle, zelda // (t1-1)*primlod+t0 {0x03b203b2, ac_t1_sub_one_mul_primlod_add_t0}, // Fire, zelda //z (t1-1)*primlod+t0, (cmb-0)*prim+0 ** INC ** {0x03b20ef8, ac__t1_sub_one_mul_primlod_add_t0__mul_prim}, // explosion, zelda 2. Added by Gonetz // (t1-1)*primlod+t0, (t0-0)*prim+0 ** INC ** {0x03b20ef9, ac_t0_mul_prim}, // Din's fire, zelda // (t1-1)*prim_lodfrac+t0, (cmb-0)*shade+0 ** INC ** {0x03b20f38, ac__t1_sub_one_mul_primlod_add_t0__mul_shade}, // Fire cloud, zelda // (t1-1)*prim_lodfrac+t0, (cmb-0)*env+0 ** INC ** {0x03b20f78, ac__t1_sub_one_mul_primlod_add_t0__mul_env}, // zelda 2 [Ogy]. Added by Gonetz // (prim-1)*prim_lodfrac+t0, (cmb-0)*env+0 ** INC ** {0x03b30f78, ac__prim_sub_one_mul_primlod_add_t0__mul_env}, // fairy's spirit, zelda oot // (t0-0)*primlod+t0 {0x03b903b9, ac_t0_mul_primlod_add_t0}, // Scary face, pokemon stadium 2 // (t0-0)*primlod+t0, (cmb-0)*prim+0 {0x03b90ef8, ac_t0_mul_prim}, // Magnitude attack, Pokemon Stadium 2 // (t0-0)*primlod+t0, (cmb-0)*shade+0 {0x03b90f38, ac__t0_mul_primlod_add_t0__mul_shade}, // Leftovers Recovery, Pokemon Stadium 2 [gokuss4]. Added by Gonetz // (t1-0)*prim_lodfrac+t0, (cmb-env)*prim+0 ** INC ** {0x03ba0ee8, ac__t1_mul_primlod_add_t0__sub_env_mul_prim}, // zelda 2 [Ogy]. Added by Gonetz // (t1-0)*prim_lodfrac+t0, (cmb-0)*prim+0 {0x03ba0ef8, ac__t1_mul_primlod_add_t0__mul_prim}, // Mega punch attack, Pokemon Stadium 2 // (t1-0)*prim_lodfrac+t0, (cmb-prim)*shade+0 {0x03ba0f18, ac__t1_mul_primlod_add_t0__sub_prim_mul_shade}, // zelda 2 [Ogy]. Added by Gonetz // (t1-0)*prim_lodfrac+t0, (cmb-0)*shade+0 {0x03ba0f38, ac__t1_mul_primlod_add_t0__mul_shade}, // chuchu monsters, zelda 2 [Ogy]. Added by Gonetz // (t1-0)*prim_lodfrac+t0, (cmb-0)*env+0 {0x03ba0f78, ac__t1_mul_primlod_add_t0__mul_env}, // Scary face, pokemon stadium 2 // (env-0)*primlod+t0, (cmb-0)*prim+0 {0x03bd0ef8, ac_t0_mul_prim}, // ground, zelda 2. Added by Gonetz // (t1-t0)*0+t0, (cmb-0)*0+cmb {0x03ca01f8, ac_t0}, // zelda 2. Added by Gonetz // (t1-t0)*0+t0, (cmb-0)*prim+0 {0x03ca0ef8, ac_t0_mul_prim}, // smoke in a night, zelda 2. Added by Gonetz // (t1-t0)*0+t0, (cmb-0)*shade+0 {0x03ca0f38, ac_t0_mul_shade}, //the ice plane out side the mountain smithy shop, zelda 2 [Ogy]. Added by Gonetz //(t1-1)*0+t0, (cmb-0)*env+0 {0x03f20f78, ac_t0_mul_env}, //something on level 5, Kirby64 [Raziel64] //(t0-0)*0+t0 {0x03f903f9, ac_t0}, //spider house, zelda 2 [Ogy]. Added by Gonetz //(t0-0)*0+t0, (cmb-0)*prim+0 {0x03f90ef8, ac_t0_mul_prim}, //Darmani's fire spin, zelda 2 [Ogy]. Added by Gonetz //(t1-0)*0+t0, (cmb-0)*prim+0 {0x03fa0ef8, ac_t0_mul_prim}, // headlight, beetle adventure racing. Added by Gonetz //(1-0)*0+t0 {0x03fe03fe, ac_t0}, // player, super bowling // (0-0)*0+t0, {0x03ff0000, ac_t0}, // Ghost's lantern, zelda // (0-0)*0+t0, (t1-0)*prim_lod+cmb {0x03ff01ba, ac_t1_mul_primlod_add_t0}, // Hand cursor, mario //z (0-0)*0+t0 {0x03ff03ff, ac_t0}, // Taz express. Added by Gonetz // (0-0)*0+t0, (0-0)*0+t1 {0x03ff05ff, ac_t0}, // powder keg, zelda2. Added by Gonetz // (0-0)*0+t0, (0-0)*0+prim {0x03ff07ff, ac_t0}, // water, Spacestation Silicon Valley. Added by Gonetz // (0-0)*0+t0, (0-0)*0+shade {0x03ff09ff, ac_t0}, // Characters, Ogre Battle. Added by Gonetz. // (0-0)*0+t0, (cmb-0)*prim+env {0x03ff0af8, ac_t0_mul_prim_add_env}, // Monster truck madness intro. Added by Gonetz // (0-0)*0+t0, (0-0)*0+env {0x03ff0bff, ac_t0}, // Battlezone // (0-0)*0+t0, (0-0)*0+1 {0x03ff0dff, ac_t0}, // Zoras, zelda // (0-0)*0+t0, (env-0)*lodf+0 {0x03ff0e3d, ac_env}, // logo, v-rally 99 // (0-0)*0+t0, (prim-0)*t0+0 {0x03ff0e7b, ac_t0_mul_prim}, // intro, WWF-War Zone // (0-0)*0+t0, (env-0)*t0+0 {0x03ff0e7d, ac_t0_mul_env}, // Window, starfox //z (0-0)*0+t0, (cmb-0)*prim+0 {0x03ff0ef8, ac_t0_mul_prim}, //beetle adventure racing. Added by Gonetz // (0-0)*0+t0, (cmb-0)*shade+0 {0x03ff0f38, ac_t0_mul_shade}, // Wonder Project J2 logo. Added by Gonetz // (0-0)*0+t0, (t0-0)*shade+0 {0x03ff0f39, ac_t0_mul_shade}, // Saria's suit, zelda // (0-0)*0+t0, (cmb-0)*env+0 {0x03ff0f78, ac_t0_mul_env}, // Pokemon Stadium 2, [Jeremy]. Added by Gonetz // (0-0)*0+t0, (cmb-0)*primlod+0 {0x03ff0fb8, ac_t0_mul_primlod}, // Tony Hawk's Pro Skater. Added by Gonetz // (0-0)*0+t0, (0-0)*0+0 {0x03ff0fff, ac_zero}, // Spider Web attack, Pokemon Stadium 2. // (t0-t1)*t0+t1, (cmb-0)*prim+cmb **INC** {0x045100f8, ac__t1_inter_t0_using_t0a__mul_prim_add__t1_inter_t0_using_t0a}, // Powered Star Beam, Paper Mario. Added by Gonetz // (t0-t1)*t0+t1, (cmb-0)*prim+0 **INC** {0x04510ef8, ac__t1_inter_t0_using_t0a__mul_prim}, // Deadly Arts logo. Added by Gonetz // (1-0)*t0+t1, (1-0)*prim+cmb {0x047e00fe, ac__t0_add_t1__add_prim}, // Spiderman. Added by Gonetz // (1-0)*t0+t1 {0x047e047e, ac_t0_add_t1}, // water, Dobutsu no Mori. Added by Gonetz // (1-0)*t0+t1, (cmb-0)*primlod+prim {0x047e07b8, ac__t0_add_t1__mul_primlod_add_prim}, // paper mario. Added by Gonetz // (1-t0)*t1+t1, (cmb-0)*t1+0 **INC** {0x048e0eb8, ac_t0_mul_t1}, // Pokemon Stadium 2. Added by Gonetz // (t0-prim)*t1+t1, (cmb-0)*shade+0 **INC** {0x04990f38, ac_t1_mul_shade}, // waterfall, Dobutsu no Mori. Added by Gonetz // (t0-0)*t1+t1 {0x04b904b9, ac_t0_mul_t1_add_t1}, // light, Dobutsu no Mori. Added by Gonetz // (t0-0)*t1+t1, (cmb-0)*primlod+0 ** INC ** {0x04b90fb8, ac__t0_add_t1__mul_primlod}, // lava, beetle adventure racing // (t1-0)*t1+t1, (cmb-0)*shade+0 ** INC ** {0x04ba0f38, ac__t1_mul_t1_add_t1__mul_shade}, // wheels, F1 World Grand Prix. Added by Gonetz // (t0-t1)*prim+t1 {0x04d104d1, ac_t1_inter_t0_using_prima}, // intro, castlevania 2. Added by Gonetz // (t0-t1)*prim+t1, (cmb-0)*shade+0 {0x04d10f38, ac__t1_inter_t0_using_prima__mul_shade}, // flame, castlevania 2. Added by Gonetz // (t0-t1)*prim+t1, (cmb-0)*env+0 {0x04d10f78, ac__t1_inter_t0_using_prima__mul_env}, // walls, beetle adventure racing. Added by Gonetz // (t0-0)*prim+t1 **INC** {0x04f904f9, ac_t0_mul_prim}, // Reflect pokemon attack, Pokemon Stadium 2 [gokuss4]. Added by Gonetz // (t0-0)*prim+t1, (cmb-0)*prim+env **INC** {0x04f90af8, ac__t0_add_t1__mul_prim_add_env}, // Psychic pokemon attack, Pokemon Stadium 2 [gokuss4]. Added by Gonetz // (t0-0)*prim+t1, (cmb-0)*shade+0 **INC** {0x04f90f38, ac__t0_add_t1__mul_shade}, // Rayman2. Added by Gonetz // (0-0)*shade+t1, (cmb-0)*env+0 {0x053f0f78, ac_t1_mul_env}, // Ground at kotake & koume, zelda // (t1-t0)*env+t1, (cmb-0)*prim+0 ** INC ** {0x054a0ef8, ac__t1_sub_t0_mul_enva_add_t1__mul_prim}, // Tony Hawk's Pro Skater. Added by Gonetz // (t0-t1)*env+t1 {0x05510551, ac_t1_inter_t0_using_enva}, // Shiek's disappearance, zelda // (t0-1)*env+t1 {0x05710571, ac_t0_sub_one_mul_enva_add_t1}, // Kotake or koume's magic poof, zelda // (t0-1)*env+t1, (cmb-0)*prim+0 ** INC ** {0x05710ef8, ac__t0_sub_one_mul_enva_add_t1__mul_prim}, // Gauntlet Legends intro // (t0-0)*env+t1, (cmb-0)*prim+0 ** INC ** {0x05790ef8, ac__t0_add_t1__mul_prim}, // Zelda opening door, zelda // (t0-0)*env+t1, (cmb-0)*shade+0 {0x05790f38, ac_t1_mul_shade}, // paper mario. Added by Gonetz // (t1-0)*env+t1, (cmb-0)*prim+0 ** INC ** {0x057a0ef8, ac_t1_mul_prim}, // pokemon attack, Pokemon Stadium 2. Added by Gonetz // (t0-t1)*prim_lod+t1, (cmb-0)*prim+0 {0x05910ef8, ac__t1_inter_t0_using_primlod__mul_prim}, // Skulltula coin, zelda // (t0-1)*primlod+t1 ** INC ** {0x05b105b1, ac_t0_mul_t1}, // Bell, Pokemon Stadium 2. Added by Gonetz // (t0-0)*primlod+t1, (cmb-env)*prim ** INC ** {0x05b90ee8, ac__t0_add_t1__mul_prim}, // intro, Aidyn Chronicles. Added by Gonetz // (0-cmb)*0+t1, (t1-1)*0+cmb {0x05c701f2, ac_t1}, // zelda 2 [Ogy]. Added by Gonetz // (t1-t0)*0+t1, (cmb-0)*prim+0 {0x05ca0ef8, ac_t1_mul_prim}, // beaver's river, zelda 2. Added by Gonetz // (t1-0)*0+t1, (cmb-0)*prim+0 {0x05fa0ef8, ac_t1_mul_prim}, // Arena, pokemon stadium 2 // (0-0)*0+t1, (0-0)*t0+cmb {0x05ff007f, ac_t1}, // Ogre Battle, unimp log. Added by Gonetz // (0-0)*0+t1, (0-0)*0+cmb {0x05ff05ff, ac_t1}, // lullaby, Paper Mario. Added by Gonetz // (0-0)*0+t1, (cmb-0)*prim+0 {0x05ff0ef8, ac_t1_mul_prim}, // aerofighter's assault [Ogy] // (0-0)*0+t1, (cmb-0)*shade+0 {0x05ff0f38, ac_t1_mul_shade}, // magic fist, Rayman2. Added by Gonetz // (0-0)*0+t1, (cmb-0)*env+0 {0x05ff0f78, ac_t1_mul_env}, // Pokemon selection background, Pokemon stadium 2 // (env-prim)*t0+prim {0x065d065d, ac_env_sub_prim_mul_t0_add_prim}, // text background, Ganbare Goemon - Mononoke Sugoroku // (1-prim)*t0+prim {0x065e065e, ac_one_sub_prim_mul_t0_add_prim}, // shadows, star wars: ep1 racer // (0-prim)*t0+prim {0x065f065f, ac_zero_sub_prim_mul_t0_add_prim}, // lava, beetle adventure racing // (0-1)*t0+prim, (cmb-0)*prim+0 ** INC ** {0x06770ef8, ac_t0_mul_prim}, // menu, Ganbare Goemon - Mononoke Sugoroku // (t0-0)*t0+prim {0x06790679, ac_t0_add_prim}, // Water, pokemon stadium 2 // (t1-0)*t0+prim {0x067a067a, ac_t0_mul_t1_add_prim}, // Smackdown Mall Menu, WWF No Mercy // (shade-0)*t0+prim {0x067c067c, ac_t0_mul_shade_add_prim}, // flag, Top Gear Rally 2. Added by Gonetz // (env-0)*t0+prim {0x067d067d, ac_t0_mul_env_add_prim}, // Mario Tennis. Added by Gonetz // (1-0)*t0+prim {0x067e067e, ac_t0_add_prim}, // sky, PGA European Tour // (t0-0)*t1+prim {0x06b906b9, ac_t0_mul_t1_add_prim}, // lava, beetle adventure racing // (t0-0)*t1+prim, (0-0)*0+1 **INC**? {0x06b90dff, ac_one}, // Pokemon Stadium 2, [Jeremy]. Added by Gonetz // (prim-0)*t1+prim {0x06bb06bb, ac_t1_mul_prim_add_prim}, // pokemon psyattack, Pokemon Stadium 2. Added by Gonetz // (1-0)*t1+prim, (cmb-0)*env+0 {0x06be0f78, ac_t1_add_prim_mul_env}, // Rush2 2. Added by Gonetz // (prim-prim)*prim+prim {0x06db06db, ac_prim}, //Spacestation Silicon Valley intro. Added by Gonetz // (t1-prim)*shade+prim // {0x071a071a, ac_t1_mul_shade}, {0x071a071a, ac_t1_sub_prim_mul_shade_add_prim}, //KI logos. Added by Gonetz // (env-prim)*shade+prim {0x071d071d, ac_env_sub_prim_mul_shade_add_prim}, // Deadly Arts, arena. Added by Gonetz // (1-0)*shade+prim {0x073e073e, ac_prim_add_shade}, // Phantom Gannon's portal, zelda // (t1-t0)*env+prim, (cmb-0)*shade+0 ** INC ** {0x074a0f38, ac__t0_mul_t1__mul_prim_mul_shade}, // Road rush. Added by Gonetz // (t0-0)*env+prim {0x07790779, ac_t0_mul_env_add_prim}, // arena, Pokemon Stadium 2 // (shade-t0)*primlod+prim, (cmb-t0)*shade ** INC ** {0x078c0f08, ac_shade_sub_t0_mul_primlod_add_prim}, // telescope, zelda 2. Added by Gonetz // (1-t0)*primlod+prim {0x078e078e, ac_one_sub_t0_mul_primlod_add_prim}, // zelda 2 [Ogy]. Added by Gonetz // (t0-t1)*primlod+prim, (cmb-0)*t0+0 {0x07910e78, ac_t0_inter_t1_using_primlod}, // Dobutsu no Mori. Added by Gonetz // (t0-0)*primlod+prim {0x07b907b9, ac_t0_mul_primlod_add_prim}, // Lock-On attack, Pokemon Stadium 2 // (t1-t0)*0+prim, (cmb-0)*0+cmb {0x07ca01f8, ac_prim}, // water, DK64 // (0-0)*0+0, (0-t1)*0+prim {0x07d707d7, ac_prim}, // Menu, megaman // (1-0)*0+prim {0x07fe07fe, ac_prim}, // super bowling //(0-0)*0+prim, {0x07ff0000, ac_prim}, // menu, Ganbare Goemon - Mononoke Sugoroku // (0-0)*0+prim, (0-0)*0+t0 {0x07ff03ff, ac_t0}, // Intro background, starfox //z (0-0)*0+prim {0x07ff07ff, ac_prim}, // velva boss, JFG //(0-0)*0+prim, (0-0)*0+env {0x07ff0bff, ac_env}, // gem, castlevania 2. Added by Gonetz // (0-0)*0+prim, (cmb-0)*t0+0 {0x07ff0e78, ac_t0_mul_prim}, // text, Tony Hawk's Pro Skater. Added by Gonetz // (0-0)*0+prim, (cmb-0)*t1+0 {0x07ff0eb8, ac_t1_mul_prim}, //weird, but implementing this makes text unreadable // zelda 2. Added by Gonetz // (0-0)*0+prim, (cmb-0)*prim+0 {0x07ff0ef8, ac_prim_mul_prim}, // explosion, Blast Corps. Added by Gonetz // (0-0)*0+prim, (t0-0)*prim+0 {0x07ff0ef9, ac_t0_mul_prim}, // zelda 2, [Ogy]. Added by Gonetz // (0-0)*0+prim, (cmb-0)*shade+0 {0x07ff0f38, ac_prim_mul_shade}, // Fox's ears and arms, smash bros // (0-0)*0+prim, (cmb-0)*env+0 {0x07ff0f78, ac_prim_mul_env}, // monsters, Pokemon Stadium. Added by Gonetz // (0-0)*0+prim, (cmb-0)*primlod+0 {0x07ff0fb8, ac_prim_mul_primlod}, // Hydro Pump Attack, Pokemon Stadium. // (1-t1)*t0+shade, (cmb-prim)*shade+0 {0x08560f18, ac__one_sub_t1_mul_t0_add_shade__sub_prim_mul_shade}, // focus, Paper Mario. Added by Gonetz //(t0-shade)*t0+shade, (cmb-0)*prim+0 * INC ** {0x08610ef8, ac_t0_mul_prim}, // Mario's head, mario //Added by Gonetz //(prim-shade)*t0+shade {0x08630863, ac_prim_sub_shade_mul_t0_add_shade}, // Fissure attack, pokemon stadium 2 //(t1-t0)*prim+shade, (cmb-0)*shade+0 {0x08ca0f38, ac__t1_sub_t0_mul_prim_add_shade__mul_shade}, // Earthquake pokemon attack, Pokemon Stadium 2 [gokuss4]. Added by Gonetz //(t0-t1)*prim+shade, (cmb-0)*shade+0 ** INC ** {0x08d10f38, ac__t0_sub_t1_mul_prim_add_shade__mul_shade}, // ? //(t0-shade)*prim+shade {0x08e108e1, ac_t0_mul_prim_add_shade_mul_one_minus_prim}, // Paper Mario // (t0-prim)*shade+shade, (cmb-0)*env+0 {0x09190f78, ac__t0_sub_prim_mul_shade_add_shade__mul_env}, // pads, Pokemon Stadium 2. Added by Gonetz // (0-t0)*env+shade, (cmb-0)*prim+0 ** INC ** {0x094f0ef8, ac_one_sub_t0_mul_prim_mul_shade}, // sun rays, Pokemon Stadium 2. // (shade-0)*env+shade, (cmb-0)*prim+0 {0x097c0ef8, ac_one_plus_env_mul_prim_mul_shade}, // attack, Pokemon Stadium 2. // (t0-0)*primlod+shade, (cmb-0)*shade+0 {0x09b90f38, ac__t0_mul_primlod_add_shade__mul_shade}, // Huge turtle appearance, zelda 2. Added by Gonetz // (t1-0)*primlod+shade, (cmb-0)*shade+0 ** INC ** {0x09ba0f38, ac__t1_mul_primlod_add_shade__mul_shade}, // roof, Kirby 64. Added by Gonetz // (t0-0)*0+shade {0x09f909f9, ac_shade}, // water, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz // (0-0)*0+shade, (cmb-cmb)*lodf+cmb {0x09ff0000, ac_shade}, // water temple, zelda 2. Added by Gonetz // (0-0)*0+shade, (cmb-0)*prim+cmb {0x09ff00f8, ac_prim_mul_shade_add_shade}, // damaged car, SCARS. Added by Gonetz // (0-0)*0+shade, (t0-t1)*primlod+prim ** INC ** {0x09ff0791, ac_t0_mul_primlod_add_prim}, // Hyrule castle gate, zelda //z (0-0)*0+shade, (0-0)*0+prim {0x09ff07ff, ac_prim}, // Super Mario 64 logo //z (0-0)*0+shade {0x09ff09ff, ac_shade}, // terrain, SCARS. Added by Gonetz // (0-0)*0+shade, (0-0)*0+1 {0x09ff0dff, ac_one}, // terrain, SCARS. Added by Gonetz // (0-0)*0+shade, (t0-0)*t1+0 {0x09ff0eb9, ac_t0_mul_t1}, // N64 logo, Aidyn Chronicles. Added by Gonetz // (0-0)*0+shade, (cmb-0)*prim+0 {0x09ff0ef8, ac_prim_mul_shade}, // birds?, custom robo. Added by Gonetz // (0-0)*0+shade, (cmb-0)*shade+0 {0x09ff0f38, ac_shade}, // sky, Glover, [Raziel64]. Added by Gonetz // (0-0)*0+shade, (t0-0)*shade+0 {0x09ff0f39, ac_t0_mul_shade}, // Hand, smash bros // (0-0)*0+shade, (cmb-0)*env+0 {0x09ff0f78, ac_env_mul_shade}, // Conker's helicopter tail, CBFD // (0-0)*0+shade, (shade-0)*env+0 {0x09ff0f7c, ac_env_mul_shade}, // menu, PokemonStadium1, [Raziel64] // (0-0)*0+shade, (cmb-0)*primlod+0 {0x09ff0fb8, ac_primlod_mul_shade}, // Link's sword slashing, smash bros // (prim-env)*t0+env {0x0a6b0a6b, ac_prim_sub_env_mul_t0_add_env}, // Reflected beam at kotake & koume's, zelda // (prim-env)*t0+env, (cmb-0)*prim+0 ** INC ** {0x0a6b0ef8, ac_t0_mul_prim}, // teleporter, Spacestation Silicon Valley. Added by Gonetz // (prim-env)*t0+env, (cmb-0)*shade+0 ** INC ** {0x0a6b0f38, ac_t0_mul_shade}, // Ridge Racer, unimp log. Added by Gonetz // (prim-env)*t0+env, (cmb-0)*primlod+0 {0x0a6b0fb8, ac_prim_sub_env_mul_t0_add_env}, // Kotake or koume's hair, zelda // (prim-0)*t0+env {0x0a7b0a7b, ac_t0_mul_prim_add_env}, // menu, doubut no mori // (1-0)*t0+env {0x0a7e0a7e, ac_t0_add_env}, // Grass, mario golf // (env-shade)*t1+env, (0-0)*0+1 {0x0aa50dff, ac_one}, // Ridge Racer, cars select. Added by Gonetz // (prim-env)*t1+env {0x0aab0aab, ac_prim_sub_env_mul_t1_add_env}, // text, monster truck madness // (prim-env)*t1+env, (cmb-0)*t1+0 {0x0aab0eb8, ac_t1_mul_env}, // zelda 2 [Ogy]. Added by Gonetz // (1-0)*t1+env, (0-0)*0+cmb //{0x0abe0abe, ac_one}, {0x0abe0abe, ac_t1_add_env}, // arena, Pokemon Stadium 2. Added by Gonetz // (1-t0)*prim+env, (cmb-0)*shade+0 {0x0ace0f38, ac_one_sub_t0_mul_prim_mul_shade}, // intro, Bomberman 64 - 2. Added by Gonetz // (t0-env)*prim+env {0x0ae90ae9, ac_t0_sub_env_mul_prim_add_env}, // N64 logo, Ogre Battle. Added by Gonetz // (t0-0)*prim+env {0x0af90af9, ac_t0_mul_prim_add_env}, // girls, PD intro. Added by Gonetz // (t0-env)*shade+env ** INC ** {0x0b290b29, ac_t0_sub_env_mul_shadea_add_env}, // Text, Mia Soccer. Added by Gonetz // (t0-env)*shade+env, (cmb-0)*lod_fraction+0 ** INC ** {0x0b290e38, ac_t0_sub_env_mul_shadea_add_env}, // shadows, Mario Tennis. Added by Gonetz // (prim-env)*shade+env, (0-cmb)*t1+cmb ** INC ** {0x0b2b0087, ac_prim_sub_env_mul_shade_add_env_mul_t1}, // lamppost?, Ridge Racer. Added by Gonetz // (prim-env)*shade+env, (0-0)*0+cmb {0x0b2b0b2b, ac_prim_sub_env_mul_shade_add_env}, // ground, zelda2. Added by Gonetz // (1-env)*shade+env, (t1-0)*prim+0 {0x0b2e0efa, ac_t1_mul_prim}, // GASP Fighters // (t0-0)*shade+env {0x0b390b39, ac_t0_mul_shade_add_env}, // destroying stuff, golden eye // (1-0)*shade+env {0x0b3e0b3e, ac_env_add_shade}, // Torches, Paper Mario. Added by Gonetz // (t0-t1)*env+env, (0-0)*0+1 {0x0b510dff, ac_t0_sub_t1_mul_env_add_env}, // Mini Racers // (t0-0)*primlod+env {0x0bb90bb9, ac_t0_mul_primlod_add_env}, // International Track and Field 2000. Added by Gonetz // (t0-0)*0+env {0x0bf90bf9, ac_env}, // TM, mario //z (0-0)*0+env {0x0bff0bff, ac_env}, // rancho monster, zelda2. Added by Gonetz // (0-0)*0+env, (cmb-0)*t1+0 {0x0bff0eb8, ac_t1_mul_env}, // Rocket Robot in Wheels intro // (0-0)*0+env, (cmb-0)*prim+0 {0x0bff0ef8, ac_prim_mul_env}, // Background, Pokemon Snap // (prim-env)*t0+1 {0x0c6b0c6b, ac_prim_sub_env_mul_t0_add_one}, // Mario Golf // (0-1)*t0+1 {0x0c770c77, ac_one_sub_t0}, // flame, paper mario. Added by Gonetz // (1-t0)*t1+1, (cmb-t1)*t1+t1 {0x0c8e0490, ac_t0_mul_t1}, // hall of fame, Pokemon Stadium // (t0-1)*prim+1, (cmb-0)*env+0 {0x0cf10f78, ac__one_inter_t0_using_prim__mul_env}, // Ring boundary, dual heroes // (0-1)*prim+1 {0x0cf70cf7, ac_one_sub_prim}, // Kirby64, level 6, [Raziel64] // (0-0)*prim+1 {0x0cff0cff, ac_one}, // Mystical Ninja // (0-1)*env+1 {0x0d770d77, ac_one}, // Deku shield in shop, zelda // (1-1)*primlod+1 {0x0db60db6, ac_one}, // water near gorons willage. Added by Gonetz // (t1-t0)*0+1, (cmb-0)*prim+0 {0x0dca0ef8, ac_prim}, // background, kirby 64. Added by Gonetz // (t0-0)*0+1 {0x0df90df9, ac_one}, // kirby 64. Added by Gonetz // (1-0)*0+1 {0x0dfe0dfe, ac_one}, // background on level 2-1, kirby 64 [Raziel64]. Added by Gonetz // (1-0)*0+1, (0-0)*0+1 {0x0dfe0dff, ac_one}, // duck dodgers intro. Added by Gonetz // (0-0)*0+1, (cmb-cmb)*primlod+cmb {0x0dff0000, ac_one}, // duck dodgers intro. Added by Gonetz // (0-0)*0+1, (0-0)*0+t1 **INC**? {0x0dff05ff, ac_t1}, // ? // (0-0)*0+1, (0-0)*0+prim {0x0dff07ff, ac_prim}, // arena, custom robo. Added by Gonetz // (0-0)*0+1, (0-0)*0+shade {0x0dff09ff, ac_shade}, // field, Mario Golf // (0-0)*0+1, (1-env)*shade+env {0x0dff0b2e, ac_one_sub_env_mul_shade_add_env}, // battle tanks 2 [Ogy] // (0-0)*0+1, (0-0)*0+env {0x0dff0bff, ac_env}, // helmet, F1 World Grand Prix. Added by Gonetz // (0-0)*0+1, (0-1)*0+1 {0x0dff0df7, ac_one}, // secret in level 3-4, Kirby64, [Raziel64] // (0-0)*0+1, (cmb-0)*0+1 {0x0dff0df8, ac_one}, // Menu options, starfox // (0-0)*0+1 {0x0dff0dff, ac_one}, // Water, zelda //z (0-0)*0+primlod, (cmb-0)*prim+0 {0x0dff0ef8, ac_prim}, // Desert ground, zelda // (0-0)*0+1, (cmb-0)*shade+0 {0x0dff0f38, ac_shade}, // Characters, smash bros // (0-0)*0+1, (cmb-0)*env+0 {0x0dff0f78, ac_env}, // end of level 3-4, Kirby64, [Raziel64] // (0-0)*0+1, (cmb-0)*0+0 {0x0dff0ff8, ac_zero}, // Kirby64 // (0-0)*0+1, (0-0)*0+0 {0x0dff0fff, ac_zero}, // floor, Spiderman [Raziel64]. Added by Gonetz // (env-t1)*t0+0 ** INC ** {0x0e550e55, ac_t0_mul_env}, // skeleton, castlevania 2. Added by Gonetz // (1-prim)*t0+0 {0x0e5e0e5e, ac_one_sub_prim_mul_t0}, // player select, Forsaken [Raziel64]. Added by Gonetz // (prim-shade)*t0+0 {0x0e630e63, ac_prim_sub_shade_mul_t0}, // castlevania 2 [Ogy]. Added by Gonetz // (1-shade)*t0+0 {0x0e660e66, ac_one_sub_shade_mul_t0}, // GoldenEye: Helicopter rotors // (shade-env)*t0+0, (1-0)*prim+cmb {0x0e6c00fe, ac_shade_sub_env_mul_t0_add_prim}, // background, level3-4, Kirby64, [Raziel64] // (shade-env)*t0+0 {0x0e6c0e6c, ac_shade_sub_env_mul_t0}, // Goemon, mystical ninja. Added by Gonetz // (1-env)*t0+0 {0x0e6e0e6e, ac_one_sub_env_mul_t0}, // fist attack, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz // (t0-0)*t0+0, (t1-cmb)*prim+cmb {0x0e7900c2, ac_t0_inter_t1_using_prima}, // Clay Fighter [Ogy]. Added by Gonetz // (t0-0)*t0+0 {0x0e790e79, ac_t0_mul_t0}, // Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz // (t0-0)*t0+0, (prim-0)*t1+0 {0x0e790ebb, ac_t1_mul_prim}, // zelda 2 [Ogy]. Added by Gonetz // (t0-0)*t0+0, (cmb-0)*prim+0 {0x0e790ef8, ac_t0_mul_prim}, // zelda 2. Added by Gonetz // (t0-0)*t0+0, (cmb-0)*shade+0 {0x0e790f38, ac_t0_mul_shade}, // zelda 2. Added by Gonetz // (t0-0)*t0+0, (cmb-0)*env+0 {0x0e790f78, ac_t0_mul_env}, // the ice plane just before the entrance to gorons village (where tingle is), zelda 2 [Ogy]. Added by Gonetz // (t1-0)*t0+0, (cmb-0)*0+cmb {0x0e7a01f8, ac_t0_mul_t1}, // paper mario. Added by Gonetz // (t1-0)*t0+0, (cmb-env)*prim+env ** INC ** {0x0e7a0ae8, ac_t1_mul_prim}, // mini games quiz monitor backround, Pokemon Stadium 2 // (t1-0)*t0+0, (0-0)*0+1 {0x0e7a0dff, ac_one}, // Tony Hawk's Pro Skater. Added by Gonetz // (t1-0)*t0+0, (cmb-0)*t0+0 {0x0e7a0e78, ac_t0_mul_t1}, // bike trace, xg2. Added by Gonetz // (t1-0)*t0+0 {0x0e7a0e7a, ac_t0_mul_t1}, // Kotake & koume defeated, zelda // (t1-0)*t0+0, (cmb-0)*prim+0 {0x0e7a0ef8, ac__t0_mul_t1__mul_prim}, // Magnitude, pokemon stadium 2 // (t1-0)*t0+0, (cmb-env)*shade+0 {0x0e7a0f28, ac__t0_mul_t1__mul_env_mul_shade}, // Bongo Bongo, zelda // (t1-0)*t0+0, (cmb-0)*shade+0 {0x0e7a0f38, ac__t0_mul_t1__mul_shade}, // Dobutsu_no_Mori, waterfall // (t1-0)*t0+0, (cmb-0)*prim_lod+0 {0x0e7a0fb8, ac__t0_mul_t1__mul_primlod}, // Back of doors, megaman // (prim-0)*t0+0, (cmb-0)*lodfrac+0 {0x0e7b0e38, ac_t0_mul_prim}, // Karts, mario kart //z (prim-0)*t0+0 {0x0e7b0e7b, ac_t0_mul_prim}, // paper mario. Added by Gonetz // (prim-0)*t0+0, (t0-0)*prim+0 {0x0e7b0ef9, ac_t0_mul_prim}, // Table, mace // (prim-0)*t0+0, (cmb-0)*shade+0 {0x0e7b0f38, ac_t0_mul_prim_mul_shade}, // lamp shadow, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz // (shade-0)*t0+0, (cmb-cmb)*lodf+cmb {0x0e7c0000, ac_t0_mul_shade}, // Game logo, Aerofighters Assault [Raziel64] //(shade-0)*t0+0, (0-0)*0+1 {0x0e7c0dff, ac_one}, // Higher sky, waverace //z (shade-0)*t0+0 {0x0e7c0e7c, ac_t0_mul_shade}, // duck dodgers, intro. Added by Gonetz // (shade-0)*t0+0, (cmb-0)*prim+0 {0x0e7c0ef8, ac_t0_mul_prim_mul_shade}, // waterwheel in water temple, zelda 2. Added by Gonetz // (shade-0)*t0+0, (cmb-0)*env+0 {0x0e7c0f78, ac_t0_mul_env_mul_shade}, // Blowing up mine at bowser's, mario // (env-0)*t0+0 {0x0e7d0e7d, ac_t0_mul_env}, // castlevania 2, intro. Added by Gonetz // (1-0)*t0+0 {0x0e7e0e7e, ac_t0}, // moon, castlevania 2. Added by Gonetz // (1-0)*t0+0, (cmb-0)*prim+0 {0x0e7e0ef8, ac_t0_mul_prim}, //beetle adventure racing. Added by Gonetz // (1-0)*t0+0, (cmb-0)*shade+0 {0x0e7e0f38, ac_t0_mul_shade}, // lava, beetle adventure racing // (t0-prim)*t1+0, (0-0)*0+shade ** INC ** {0x0e9909ff, ac_shade}, // Rain Dance, Pokemon Stadium 2 [gokuss4]. Added by Gonetz // (t0-env)*t1+0, (cmb-0)*0+prim ** INC ** {0x0ea90ef8, ac__t0_mul_t1__mul_prim}, // Duck Dodgers Starring Daffy Duck text background // (t0-0)*t1+0, (shade-cmb)*prim+cmb {0x0eb900c4, ac_one_sub_prim_mul__t0_mul_t1__add__prim_mul_shade}, // torches, pokemon stadium 2 // (t0-0)*t1+0, (cmb-env)*prim+cmb {0x0eb900e8, ac__t0_mul_t1__sub_env_mul_prim_add__t0_mul_t1}, // airboarder 64 [Ogy] // (t0-0)*t1+0, (0-0)*0+prim {0x0eb907ff, ac_prim}, // explosion, body harvest. Added by Gonetz // (t0-0)*t1+0, (0-0)*0+shade {0x0eb909ff, ac_shade}, // Text off top, banjo kazooie // (t0-0)*t1+0 {0x0eb90eb9, ac_t0_mul_t1}, // smoke, daikatana. Added by Gonetz // (t0-0)*t1+0, (cmb-0)*prim+0 {0x0eb90ef8, ac__t0_mul_t1__mul_prim}, // Arena, Pokemon Stadium 2. // (t0-0)*t1+0, (cmb-prim)*shade+0 {0x0eb90f18, ac__t0_mul_t1__sub_prim_mul_shade}, // Water, pilotwings // (t0-0)*t1+0, (cmb-0)*shade+0 {0x0eb90f38, ac__t0_mul_t1__mul_shade}, // Tony Hawk's Pro Skater. Added by Gonetz // (t0-0)*t1+0, (cmb-0)*env+0 {0x0eb90f78, ac__t0_mul_t1__mul_env}, // light from window, Dobutsu no Mori. Added by Gonetz // (t0-0)*t1+0, (cmb-0)*primlod+0 {0x0eb90fb8, ac__t0_mul_t1__mul_primlod}, // chandelier in spider house, zelda 2. Added by Gonetz // (t1-0)*t1+0, (cmb-0)*prim+0 {0x0eba0ef8, ac_t1_mul_prim}, // cars, ridge racer. Added by Gonetz // (prim-0)*t1+0, (0-0)*0+1 {0x0ebb0dff, ac_t1_mul_prim}, // aerofighter's assault [Ogy] // (prim-0)*t1+0 {0x0ebb0ebb, ac_t1_mul_prim}, // tire trace, beetle adventure racing. Added by Gonetz // (shade-0)*t1+0 {0x0ebc0ebc, ac_t1_mul_shade}, // smoke, Starshot. Added by Gonetz // (env-0)*t1+0 {0x0ebd0ebd, ac_t1_mul_env}, // lots of things, goldeneye // (1-0)*t1+0, (0-0)*0+shade {0x0ebe09ff, ac_shade}, // zelda 2 [Ogy]. Added by Gonetz // (1-0)*t1+0, (cmb-0)*prim+0 {0x0ebe0ef8, ac_t1_mul_prim}, // walls, perfect dark. Added by Gonetz // (1-0)*t1+0, (cmb-0)*shade+0 {0x0ebe0f38, ac_t1_mul_shade}, // sand, perfect dark. Added by Gonetz // (1-0)*t1+0, (cmb-0)*env+0 {0x0ebe0f78, ac_t1_mul_env}, // light, Ridge Racer. Added by Gonetz // (1-t0)*prim+0 {0x0ece0ece, ac_one_sub_t0_mul_prim}, // exaust, star wars ep1 racer // (1-t0)*prim+0, (cmb-0)*shade+0 {0x0ece0f38, ac_one_sub_t0_mul_primshade}, // iguana, Forsaken, [Raziel64]. Added by Gonetz // (t0-shade)*prim+0 {0x0ee10ee1, ac_t0_sub_shade_mul_prim}, // stands, NASCAR 2000 // (prim-shade)*prim+0 {0x0ee30ee3, ac_prim_sub_shade_mul_prim}, // arena, Pokemon Stadium 2. Added by Gonetz // (t0-env)*prim+0 ** INC ** {0x0ee90ee9, ac_t0_mul_prim}, // lure, bass rush // (t0-0)*prim+0, (cmb-cmb)*lodf+cmb {0x0ef90000, ac_t0_mul_prim}, // explosion, body harvest. Added by Gonetz // (t0-0)*prim+0, (t0-0)*env+cmb {0x0ef90179, ac_prim_add_env_mul_t0}, // frog's eyes, zelda // (t0-0)*prim+0, (1-1)*prim_lod+cmb {0x0ef901b6, ac_t0_mul_prim}, // Monster truck madness intro. Added by Gonetz // (t0-0)*prim+0, (cmb-0)*prim_lod+cmb ** INC ** {0x0ef901b8, ac_t0_mul_prim}, // Road, zelda //z (t0-0)*prim+0, (t1-0)*primlod+cmb {0x0ef901ba, ac__t0_mul_prim__add__t1_mul_primlod}, // Track, wipeout. Addded by Gonetz // (t0-0)*prim+0, (0-0)*0+prim {0x0ef907ff, ac_t0_mul_prim}, // magic stuff, buck bumble. Added by Gonetz // (t0-0)*prim+0, (cmb-0)*prim+0 {0x0ef90ef8, ac_t0_mul_prim_mul_prim}, // The mario face, mario //z (t0-0)*prim+0 {0x0ef90ef9, ac_t0_mul_prim}, // paper mario. Added by Gonetz // (t0-0)*prim+0, (cmb-0)*shade+0 {0x0ef90f38, ac_t0_mul_prim_mul_shade}, // Pikachu's mouth, smash bros // (t0-0)*prim+0, (cmb-0)*env+0 {0x0ef90f78, ac_t0_mul_prim_mul_env}, // bomb mask, zelda 2. Added by Gonetz // (t0-0)*prim+0, (1-0)*env+0 {0x0ef90f7e, ac_t0_mul_prim}, // Charmander's tail, pokemon stadium 2 // (t0-0)*prim+0, (cmb-0)*primlod+0 {0x0ef90fb8, ac_t0_mul_prim_mul_primlod}, // stalactites, Beetle adventure Racing. Added by Gonetz // (t1-0)*prim+0, (1-cmb)*shade+cmb {0x0efa0106, ac_one_sub_shade_mul_t1_add_shade}, // Sprites, Ogre Battle. Added by Gonetz // (t1-0)*prim+0, (0-0)*0+cmb {0x0efa0efa, ac_t1_mul_prim}, // Something about kotake & koume's combined attack, zelda // (t1-0)*prim+0, (cmb-0)*shade+0 {0x0efa0f38, ac_t1_mul_prim_mul_shade}, // intro background, bio freaks. Added by Gonetz // (prim-0)*prim+0 {0x0efb0efb, ac_prim_mul_prim}, // sky, xg2. Added by Gonetz // (shade-0)*prim+0, (0-0)*0+1 {0x0efc0dff, ac_one}, // Zelda, unimp log. Added by Gonetz // (shade-0)*prim+0 {0x0efc0efc, ac_prim_mul_shade}, // ? // (shade-0)*prim+0, (cmb-0)*shade+0 ** INC ** {0x0efc0f38, ac_prim_mul_shade}, // Baby mario's hat shadow, mario golf // (env-0)*prim+0 {0x0efd0efd, ac_prim_mul_env}, // Menu, doom // (1-0)*prim+0 {0x0efe0efe, ac_prim}, // Peris Song attack, Pokemin Stadium 2 // (1-0)*prim+0, (cmb-0)*shade+0 {0x0efe0f38, ac_prim_mul_shade}, // Conker's shadow, CBFD. Added by Gonetz // (1-t0)*shade+0 {0x0f0e0f0e, ac_one_sub_t0_mul_shade}, // Rock smash, pokemon stadium 2 // (1-t0)*shade+0 {0x0f0f0ee8, ac_one_sub_t0_mul_shade}, //waterfall, Paper Mario // (t0-t1)*shade+0 {0x0f110f11, ac__t0_sub_t1__mul_shade}, // mahogany town statue, Pokemon Stadium 2 // (t0-prim)*shade+0 {0x0f190f19, ac_t0_sub_prim_mul_shade}, // silver cave, pokemon stadium 2 // (t0-prim)*shade+0, (cmb-0)*env+0 {0x0f190f78, ac_t0_sub_prim_mul_shade_mul_env}, // Boomerang circle, zelda // (t0-0)*shade+0, (1-cmb)*t0+cmb {0x0f390046, ac_t0_mul_shade}, // THPS3 // (t0-0)*shade+0, (1-0)*t0+cmb {0x0f39007e, ac_t0_mul_shade}, // ??? // (t0-0)*shade+0, (env-0)*t1+cmb {0x0f3900bd, ac_t0_mul_shade}, // Forest temple doorway, zelda // (t0-0)*shade+0, (t1-0)*primlod+cmb {0x0f3901ba, ac_t0_mul_shade}, // skis, Spacestation Silicon Valley. Added by Gonetz // (t0-0)*shade+0, (0-0)*0+t0 {0x0f3903ff, ac_t0}, // paper mario. Added by Gonetz // (t0-0)*shade+0, (cmb-t0)*prim+0 {0x0f390ec8, ac_t0_mul_prim_mul_shade}, // House windows, zelda intro //z (t0-0)*shade+0, (cmb-0)*prim+0 {0x0f390ef8, ac_t0_mul_prim_mul_shade}, // Characters, mace // (t0-0)*shade+0, (cmb-0)*shade+0 {0x0f390f38, ac_t0_mul_shade}, // Shadows, mario //z (t0-0)*shade+0 {0x0f390f39, ac_t0_mul_shade}, // Clear screen intro, banjo kazooie // (t0-0)*shade+0, (cmb-0)*env+0 {0x0f390f78, ac_t0_mul_env_mul_shade}, // ridge racer, unimp log. Added by Gonetz // (t0-0)*shade+0, (cmb-0)*primlod+0 **INC**? {0x0f390fb8, ac_t0_mul_shade}, // Reflecting combined attack at kotake & koume's, zelda // (t1-0)*shade+0, (cmb-0)*prim+0 {0x0f3a0ef8, ac_t1_mul_prim_mul_shade}, // aerofighter's assault [Ogy] // (t1-0)*shade+0 {0x0f3a0f3a, ac_t1_mul_shade}, //beetle adventure racing. Added by Gonetz //(t1-0)*shade+0, (cmb-0)*env+0 {0x0f3a0f78, ac_t1_mul_env_mul_shade}, // building shadow, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz // (prim-0)*shade+0, (cmb-cmb)*lodf+cmb {0x0f3b0000, ac_prim_mul_shade}, //chip in Spacestation Silicon Valley intro. Added by Gonetz // (prim-0)*shade+0, (env-cmb)*t1+cmb {0x0f3b0085, ac_env_sub_primshade_mul_t1_add_primshade}, // N64 logo, tetrisphere. Added by Gonetz // (prim-0)*shade+0, (prim-0)*shade+0 {0x0f3b0f3b, ac_prim_mul_shade}, // rays, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz // (shade-0)*shade+0, (cmb-0)*prim+0 {0x0f3c0ef8, ac_prim_mul_shade}, // light, dracula resurrection, castlevania 2. Added by Gonetz // (env-0)*shade+0 {0x0f3d0f3d, ac_env_mul_shade}, // zelda 2 [Ogy]. Added by Gonetz // (1-0)*shade+0 {0x0f3e0f3e, ac_shade}, // surf pokemon attack, Pokemon Stadium 2 [gokuss4]. Added by Gonetz // (1-t0)*env+0, (1-cmb)*shade+0 ** INC ** {0x0f4e0f06, ac_t0_mul_shade}, // GE, boxes // (1-shade)*env+0, (cmb-0)*shade+0 ** INC ** {0x0f660f38, ac_one_sub_shade_mul_env}, //beetle adventure racing. Added by Gonetz //(t0-0)*env+0, (1-t0)*prim+cmb //{0x0f7900ce, ac_t0_mul_env}, //this one looks better //{0x0f7900ce, ac_env_sub_prim_mul_t0_add_prim}, {0x0f7900ce, ac_one_sub_t1_add_t0_mul_env}, //Zelda, logo ? Added by Gonetz //(t0-0)*env+0, (t1-0)*primlod+0 **INC** changed to mul_env for gannon's organ disappearing [Dave2001] {0x0f7901ba, ac__t0_inter_t1_using_primlod__mul_env}, // V8-2 menu // (t0-0)*env+0, (0-0)*0+prim {0x0f7907ff, ac_prim}, // Skeleton guy's eyes, zelda // (t0-0)*env+0, (cmb-0)*prim+0 {0x0f790ef8, ac_t0_mul_prim_mul_env}, // Dust from rock spell, quest64 // (t0-0)*env+0, (cmb-0)*shade+0 {0x0f790f38, ac_t0_mul_env_mul_shade}, // eyes of poe, zelda // (t0-0)*env+0, (cmb-0)*env+0 {0x0f790f78, ac_t0_mul_env}, // Text, mario //z (t0-0)*env+0 {0x0f790f79, ac_t0_mul_env}, // Shadows, pokemon stadeom 2 // (t0-0)*env+0, (cmb-0)*primlod+0 {0x0f790fb8, ac_t0_mul_env_mul_primlod}, //gauge, PGA // (t1-0)*env+0, (cmb-0)*t1+0 ** INC ** {0x0f7a0eb8, ac_t1_mul_env}, //text and shadows, Rayman2. Added by Gonetz // (t1-0)*env+0, (cmb-0)*shade+0 {0x0f7a0f38, ac_t1_mul_env_mul_shade}, // shadows, tom and jerry. Added by Gonetz // (t1-0)*env+0 {0x0f7a0f7a, ac_t1_mul_env}, // Bomberman64-2 intro. Added by Gonetz // (prim-0)*env+0 {0x0f7b0f7b, ac_prim_mul_env}, // Text box, mario //z (shade-0)*env+0 {0x0f7c0f7c, ac_env_mul_shade}, // Ogre battle 64 // (env-0)*env+0 {0x0f7d0f7d, ac_env}, //Goldeneye, [Jeremy]. Added by Gonetz // (1-0)*env+0, (cmb-0)*shade+0 {0x0f7e0f38, ac_env_mul_shade}, // Status items, megaman // (1-0)*env+0 {0x0f7e0f7e, ac_env}, // gun fire, Beast_Wars_Transmetal [Raziel64] // (0-0)*env+0 {0x0f7f0f7f, ac_zero}, // Pokemon attack, Pokemon stadium (J). Added by Gonetz // (t1-t0)*primlod+0, (cmb-0)*env+prim ** INC ** {0x0f8a0778, ac__t1_sub_t0_mul_primlod__mul_env_add_prim}, // Shadow Ball, Pokemon Stadium 2 [gokuss4]. Added by Gonetz // (t1-t0)*primlod+0, (t1-cmb)*prim+0 ** INC ** {0x0f8a0ec2, ac_t0_mul_prim}, // Walls of well through lens of truth, zelda // (prim-t0)*primlod+0 {0x0f8b0f8b, ac_prim_sub_t0}, // N64 logo, ridge racer. Added by Gonetz // (1-prim)*primlod+0 **INC** {0x0f9e0f9e, ac_zero}, // Vines that covers a door in the third room of woodfall temple, zelda 2 [Ogy]. Added by Gonetz // (t0-0)*primlod+0, (cmb-0)*prim+0 {0x0fb90ef8, ac_t0_mul_primlod_mul_prim}, // zelda 2. Added by Gonetz // (t0-0)*primlod+0 {0x0fb90fb9, ac_t0_mul_primlod}, // NFL Blitz logo. Added by Gonetz // (t1-0)*primlod+0 {0x0fba0fba, ac_t1_mul_primlod}, //causes issues // fallen stars at star summit, Paper Mario. Added by Gonetz // (shade-0)*primlod+0 {0x0fbc0fbc, ac_primlod_mul_shade}, // expansion pack, Jeremy McGrath Supercross 2000. Added by Gonetz // (1-0)*primlod+0 {0x0fbe0fbe, ac_primlod}, // intro, Aidyn Chronicles. Added by Gonetz // (0-0)*primlod+0, (prim-env)*t0+prim **INC** {0x0fbf066b, ac_t0_mul_prim}, // sky, Rayman2. Added by Gonetz // (0-shade)*0+0 {0x0fe70fe7, ac_zero}, // flame, PokemonStadium1 [Raziel64] // (t0-0)*0+0 {0x0ff90ff9, ac_zero}, //BAR // (0-0)*0+0, (0-0)*0+TEXEL1 {0x0fff05ff, ac_t0}, // Screen clear, banjo kazooie // (0-0)*0+0 {0x0fff0fff, ac_zero}, // { #ACEND } }; // CountCombine - count the # of entries in the combine lists void CountCombine(void) { int i, index, a, b, size; size = sizeof(color_cmb_list) / sizeof(COMBINER); i = 0; index = 0; do { a = color_cmb_list[index].key >> 24; for (; i<=a; i++) cc_lookup[i] = index; while (index < size) { b = color_cmb_list[index].key >> 24; if (b != a) break; index ++; } } while (index < size); for (; i<257; i++) cc_lookup[i] = index; size = sizeof(alpha_cmb_list) / sizeof(COMBINER); i=0, index=0; do { a = (alpha_cmb_list[index].key >> 20) & 0xFF; for (; i<=a; i++) ac_lookup[i] = index; while (index < size) { b = (alpha_cmb_list[index].key >> 20) & 0xFF; if (b != a) break; index ++; } } while (index < size); for (; i<257; i++) ac_lookup[i] = index; //color_cmb_list_count = sizeof(color_cmb_list) >> 3; // #bytes/4/2 //alpha_cmb_list_count = sizeof(alpha_cmb_list) >> 3; } //**************************************************************** // Main Combine //**************************************************************** void Combine(void) { uint32_t found, cmb_mode_a, cmb_mode_c; uint32_t actual_combine, current_combine, color_combine, alpha_combine; int left, right, current, last; #if 0 FRDP (" | |- color combine: %08lx, #1: (%s-%s)*%s+%s, #2: (%s-%s)*%s+%s\n", ((rdp.cycle1 & 0xFFFF) << 16) | (rdp.cycle2 & 0xFFFF), Mode0[rdp.cycle1&0xF], Mode1[(rdp.cycle1>>4)&0xF], Mode2[(rdp.cycle1>>8)&0x1F], Mode3[(rdp.cycle1>>13)&7], Mode0[rdp.cycle2&0xF], Mode1[(rdp.cycle2>>4)&0xF], Mode2[(rdp.cycle2>>8)&0x1F], Mode3[(rdp.cycle2>>13)&7]); FRDP (" | |- alpha combine: %08lx, #1: (%s-%s)*%s+%s, #2: (%s-%s)*%s+%s\n", (rdp.cycle1 & 0x0FFF0000) | ((rdp.cycle2 & 0x0FFF0000) >> 16), Alpha0[(rdp.cycle1>>16)&7], Alpha1[(rdp.cycle1>>19)&7], Alpha2[(rdp.cycle1>>22)&7], Alpha3[(rdp.cycle1>>25)&7], Alpha0[(rdp.cycle2>>16)&7], Alpha1[(rdp.cycle2>>19)&7], Alpha2[(rdp.cycle2>>22)&7], Alpha3[(rdp.cycle2>>25)&7]); #endif if (!(rdp.othermode_h & RDP_TEX_LOD_ENABLE) || rdp.cur_tile == rdp.mipmap_level) lod_frac = g_gdp.primitive_lod_frac; else if (settings.lodmode == 0) lod_frac = 0; else lod_frac = 10; rdp.noise = NOISE_MODE_NONE; found = true; rdp.col[0] = rdp.col[1] = rdp.col[2] = rdp.col[3] = rdp.coladd[0] = rdp.coladd[1] = rdp.coladd[2] = rdp.coladd[3] = 1.0f; rdp.cmb_flags = rdp.cmb_flags_2 = 0; cmb.tex = 0; cmb.tmu0_func = cmb.tmu1_func = cmb.tmu0_a_func = cmb.tmu1_a_func = GR_COMBINE_FUNCTION_ZERO; cmb.tmu0_fac = cmb.tmu1_fac = cmb.tmu0_a_fac = cmb.tmu1_a_fac = GR_COMBINE_FACTOR_NONE; cmb.tmu0_invert = cmb.tmu0_a_invert = cmb.tmu1_invert = cmb.tmu1_a_invert = FXFALSE; cmb.dc0_detailmax = cmb.dc1_detailmax = 0; cmb.mod_0 = cmb.mod_1 = 0; // remove all modifications cmb.modcolor_0 = cmb.modcolor1_0 = cmb.modcolor2_0 = cmb.modcolor_1 = cmb.modcolor1_1 = cmb.modcolor2_1 = cmb.modfactor_0 = cmb.modfactor_1 = 0; cmb.ccolor = cmb.tex_ccolor = 0; if (cmb.cmb_ext_use || cmb.tex_cmb_ext_use) { cmb.cmb_ext_use = 0; cmb.tex_cmb_ext_use = 0; } cmb_mode_c = (rdp.cycle1 << 16) | (rdp.cycle2 & 0xFFFF); cmb_mode_a = (rdp.cycle1 & 0x0FFF0000) | ((rdp.cycle2 >> 16) & 0x00000FFF); cmb.abf1 = GR_BLEND_SRC_ALPHA; cmb.abf2 = GR_BLEND_ONE_MINUS_SRC_ALPHA; // Fast, ordered search current = 0x7FFFFFFF; actual_combine = cmb_mode_c; color_combine = actual_combine; if ((rdp.cycle2 & 0xFFFF) == 0x1FFF) actual_combine = (rdp.cycle1 << 16) | (rdp.cycle1 & 0xFFFF); left = cc_lookup[actual_combine>>24]; right = cc_lookup[(actual_combine>>24)+1]; while (1) { last = current; current = left + ((right-left) >> 1); if (current == last) break; // can't be found! current_combine = color_cmb_list[current].key; if (current_combine < actual_combine) left = current; else if (current_combine > actual_combine) right = current; else break; // found it! } // Check if we didn't find it if (actual_combine != current_combine) { #ifdef UNIMP_LOG if (log_cb) log_cb(RETRO_LOG_INFO, "COLOR combine not found: %08x, #1: (%s-%s)*%s+%s, #2: (%s-%s)*%s+%s\n", actual_combine, Mode0[rdp.cycle1&0xF], Mode1[(rdp.cycle1>>4)&0xF], Mode2[(rdp.cycle1>>8)&0x1F], Mode3[(rdp.cycle1>>13)&7], Mode0[rdp.cycle2&0xF], Mode1[(rdp.cycle2>>4)&0xF], Mode2[(rdp.cycle2>>8)&0x1F], Mode3[(rdp.cycle2>>13)&7]); #endif found = false; // use t0 as default cc_t0(); } else color_cmb_list[current].func(); LRDP(" | |- Color done\n"); // Now again for alpha current = 0x7FFFFFFF; actual_combine = cmb_mode_a; alpha_combine = actual_combine; if ((rdp.cycle2 & 0x0FFF0000) == 0x01FF0000) actual_combine = (rdp.cycle1 & 0x0FFF0000) | ((rdp.cycle1 >> 16) & 0x00000FFF); if ((rdp.cycle1 & 0x0FFF0000) == 0x0FFF0000) actual_combine = (rdp.cycle2 & 0x0FFF0000) | ((rdp.cycle2 >> 16) & 0x00000FFF); left = ac_lookup[(actual_combine>>20)&0xFF]; right = ac_lookup[((actual_combine>>20)&0xFF)+1]; while (1) { last = current; current = left + ((right-left) >> 1); if (current == last) break; // can't be found! current_combine = alpha_cmb_list[current].key; if (current_combine < actual_combine) left = current; else if (current_combine > actual_combine) right = current; else break; // found it! } // Check if we didn't find it if (actual_combine != current_combine || !found) { #ifdef UNIMP_LOG if (actual_combine != current_combine) { if (log_cb) log_cb(RETRO_LOG_INFO, "ALPHA combine not found: %08x, #1: (%s-%s)*%s+%s, #2: (%s-%s)*%s+%s\n", actual_combine, Alpha0[(rdp.cycle1>>16)&7], Alpha1[(rdp.cycle1>>19)&7], Alpha2[(rdp.cycle1>>22)&7], Alpha3[(rdp.cycle1>>25)&7], Alpha0[(rdp.cycle2>>16)&7], Alpha1[(rdp.cycle2>>19)&7], Alpha2[(rdp.cycle2>>22)&7], Alpha3[(rdp.cycle2>>25)&7]); } #endif if (settings.unk_as_red) { BrightRed(); } else { // use full alpha as default ac_t0(); } //tex |= 3; } else alpha_cmb_list[current].func(); if (color_combine == 0x69351fff) //text, PD, need to change texture alpha { A_USE_T1(); } else if ((color_combine == 0x3fff1fff) && (alpha_combine == 0x03ff03ff) && (rdp.last_tile > rdp.cur_tile))//Dr. Mario { cc_t0(); ac_t1(); } else if (color_combine == 0x613522f0 && (settings.hacks&hack_PMario)) //Paper Mario fortune teller spheres { ac_t0(); } LRDP(" | |- Alpha done\n"); CombineBlender(); //* // Update textures? // if (tex == 2 && rdp.texrecting && (cmb.tmu1_func != GR_COMBINE_FUNCTION_ZERO) && (rdp.last_tile_size == 0)) if (cmb.tex == 2 && rdp.texrecting && (rdp.cur_tile == rdp.last_tile_size)) { cmb.tex = 0; USE_T0(); A_USE_T0(); } //*/ rdp.tex = cmb.tex; { grChromakeyMode(GR_CHROMAKEY_DISABLE); } cmb.shade_mod_hash = (rdp.cmb_flags + rdp.cmb_flags_2) * (g_gdp.prim_color.total + g_gdp.env_color.total + g_gdp.k5); LRDP(" | + Combine end\n"); } void CombineBlender(void) { uint32_t blendmode = rdp.othermode_l >> 16; // Check force-blending if ((rdp.othermode_l & RDP_FORCE_BLEND) && (((rdp.othermode_h & RDP_CYCLE_TYPE) >> 20) < G_CYC_COPY)) { switch (blendmode) { case 0x0382: /* Mace objects */ case 0x0091: /* Mace special blend mode */ case 0x0c08: /* 1080 Snowboarding - sky */ case 0x0f0a: /* Mario Kart 64 - player select * clr_in * 0 + clr_in * 1 * - or just clr_in, no matter what alpha */ case 0x0302: /* Donkey Kong 64 blue prints */ case 0xA500: /* Bomberman 2 special blend mode */ case 0xcb02: /* Sin and Punishment */ case BLEND_FOG_ASHADE: /* Battlezone * clr_in * a + clr_in * (1-a) */ case 0x07C2: /* Conker BFD */ case 0x00c0: /* Conker BFD */ case 0xc302: /* ISS64 */ case 0xC702: /* Donald Duck */ A_BLEND (GR_BLEND_ONE, GR_BLEND_ZERO); break; //Space Invaders case 0x0448: case 0x055a: A_BLEND (GR_BLEND_ONE, GR_BLEND_ONE); break; case 0xc712: /* Pokemon Stadium? */ case 0xaf50: /* LOT in Zelda: Majora's Mask */ case 0x0FA5: /* LOT in Zelda: Majora's Mask */ case 0x0f5a: /* Seems to be doing just blend color - maybe combiner can be used for this? */ case 0x5055: /* Used in Paper Mario intro, I'm not sure if this is right... */ /* clr_in * 0 + clr_mem * 1 */ A_BLEND (GR_BLEND_ZERO, GR_BLEND_ONE); break; case 0x5f50: //clr_mem * 0 + clr_mem * (1-a) A_BLEND (GR_BLEND_ZERO, GR_BLEND_ONE_MINUS_SRC_ALPHA); break; case 0xf550: //clr_fog * a_fog + clr_mem * (1-a) case 0x0D18: //clr_in * a_fog + clr_mem * (1-a) A_BLEND (GR_BLEND_SRC_ALPHA, GR_BLEND_ONE_MINUS_SRC_ALPHA); { uint32_t temp = g_gdp.prim_color.total; g_gdp.prim_color.total = g_gdp.fog_color.total; g_gdp.prim_color.r = (g_gdp.prim_color.total & 0xFF000000) >> 24; g_gdp.prim_color.g = (g_gdp.prim_color.total & 0x00FF0000) >> 16; g_gdp.prim_color.b = (g_gdp.prim_color.total & 0x0000FF00) >> 8; g_gdp.prim_color.a = (g_gdp.prim_color.total & 0x000000FF); cc_prim(); ac_prim(); g_gdp.prim_color.total = temp; g_gdp.prim_color.r = (g_gdp.prim_color.total & 0xFF000000) >> 24; g_gdp.prim_color.g = (g_gdp.prim_color.total & 0x00FF0000) >> 16; g_gdp.prim_color.b = (g_gdp.prim_color.total & 0x0000FF00) >> 8; g_gdp.prim_color.a = (g_gdp.prim_color.total & 0x000000FF); } break; case 0x0150: //spiderman A_BLEND (GR_BLEND_SRC_ALPHA, GR_BLEND_ONE_MINUS_SRC_ALPHA); if (((rdp.othermode_h & RDP_CYCLE_TYPE) >> 20) == G_CYC_2CYCLE && rdp.cycle2 != 0x01ff1fff) { uint32_t temp = g_gdp.prim_color.total; g_gdp.prim_color.total = g_gdp.fog_color.total; g_gdp.prim_color.r = (g_gdp.prim_color.total & 0xFF000000) >> 24; g_gdp.prim_color.g = (g_gdp.prim_color.total & 0x00FF0000) >> 16; g_gdp.prim_color.b = (g_gdp.prim_color.total & 0x0000FF00) >> 8; g_gdp.prim_color.a = (g_gdp.prim_color.total & 0x000000FF); ac_prim(); g_gdp.prim_color.total = temp; g_gdp.prim_color.r = (g_gdp.prim_color.total & 0xFF000000) >> 24; g_gdp.prim_color.g = (g_gdp.prim_color.total & 0x00FF0000) >> 16; g_gdp.prim_color.b = (g_gdp.prim_color.total & 0x0000FF00) >> 8; g_gdp.prim_color.a = (g_gdp.prim_color.total & 0x000000FF); } break; case 0xc912: //40 winks, clr_in * a_fog + clr_mem * 1 { uint32_t temp = g_gdp.prim_color.total; g_gdp.prim_color.total = g_gdp.fog_color.total; g_gdp.prim_color.r = (g_gdp.prim_color.total & 0xFF000000) >> 24; g_gdp.prim_color.g = (g_gdp.prim_color.total & 0x00FF0000) >> 16; g_gdp.prim_color.b = (g_gdp.prim_color.total & 0x0000FF00) >> 8; g_gdp.prim_color.a = (g_gdp.prim_color.total & 0x000000FF); ac_prim(); g_gdp.prim_color.total = temp; g_gdp.prim_color.r = (g_gdp.prim_color.total & 0xFF000000) >> 24; g_gdp.prim_color.g = (g_gdp.prim_color.total & 0x00FF0000) >> 16; g_gdp.prim_color.b = (g_gdp.prim_color.total & 0x0000FF00) >> 8; g_gdp.prim_color.a = (g_gdp.prim_color.total & 0x000000FF); } A_BLEND (GR_BLEND_SRC_ALPHA, GR_BLEND_ONE); break; case 0x0040: // Fzero case 0xC810: // Blends fog case 0xC811: // Blends fog case 0x0C18: // Standard interpolated blend case 0x0C19: // Used for antialiasing case 0x0050: // Standard interpolated blend case 0x0051: // Standard interpolated blend case 0x0055: // Used for antialiasing A_BLEND (GR_BLEND_SRC_ALPHA, GR_BLEND_ONE_MINUS_SRC_ALPHA); break; case 0x5000: /* V8 explosions */ A_BLEND (GR_BLEND_ONE_MINUS_SRC_ALPHA, GR_BLEND_SRC_ALPHA); break; default: A_BLEND (GR_BLEND_SRC_ALPHA, GR_BLEND_ONE_MINUS_SRC_ALPHA); } } else if (blendmode == BLEND_XLU) // Mia Soccer Lights A_BLEND (GR_BLEND_SRC_ALPHA, GR_BLEND_ONE_MINUS_SRC_ALPHA); else if ((settings.hacks&hack_Pilotwings) && (rdp.othermode_l & RDP_COLOR_ON_CVG)) //RDP_COLOR_ON_CVG without RDP_FORCE_BLEND A_BLEND (GR_BLEND_ZERO, GR_BLEND_ONE); #if 0 else if ((settings.hacks & hack_Blastcorps)) { A_BLEND (GR_BLEND_ZERO, GR_BLEND_ONE); } #endif else A_BLEND (GR_BLEND_ONE, GR_BLEND_ZERO); // RDP_ALPHA_CVG_SELECT means full alpha // The reason it wasn't working before was because I wasn't handling rdp:setothermode if ((rdp.othermode_l & RDP_ALPHA_CVG_SELECT) && ((rdp.othermode_l & 0x7000) != 0x7000)) { switch (blendmode) { case 0x4055: /* Mario Golf */ case 0x5055: /* Paper Mario intro clr_mem * a_in + clr_mem * a_mem */ A_BLEND (GR_BLEND_ZERO, GR_BLEND_ONE); break; default: A_BLEND (GR_BLEND_ONE, GR_BLEND_ZERO); break; } } if (settings.hacks&hack_ISS64) { if (rdp.othermode_l == 0xff5a6379) { A_BLEND (GR_BLEND_ZERO, GR_BLEND_SRC_ALPHA); } else if (rdp.othermode_l == 0x00504dd9) //players shadows. CVG_DST_WRAP { A_BLEND (GR_BLEND_ZERO, GR_BLEND_ONE); } } else if (settings.hacks&hack_TGR) { if (rdp.othermode_l == 0x0f0a0235) { A_BLEND (GR_BLEND_SRC_ALPHA, GR_BLEND_ONE_MINUS_SRC_ALPHA); } } //*/ } void InitCombine(void) { LOG ("InitCombine() "); memset(&cmb, 0, sizeof(cmb)); LOG ("initialized."); cmb.dc0_lodbias = cmb.dc1_lodbias = 31; cmb.dc0_detailscale = cmb.dc1_detailscale = 7; cmb.lodbias0 = cmb.lodbias1 = 1.0f; } void ColorCombinerToExtension(void) { uint32_t ext_local, ext_local_a, ext_other, ext_other_a; switch (cmb.c_loc) { case GR_COMBINE_LOCAL_ITERATED: ext_local = GR_CMBX_ITRGB; ext_local_a = GR_CMBX_ITALPHA; break; case GR_COMBINE_LOCAL_CONSTANT: ext_local = GR_CMBX_CONSTANT_COLOR; ext_local_a = GR_CMBX_CONSTANT_ALPHA; break; }; switch (cmb.c_oth) { case GR_COMBINE_OTHER_ITERATED: ext_other = GR_CMBX_ITRGB; ext_other_a = GR_CMBX_ITALPHA; break; case GR_COMBINE_OTHER_TEXTURE: ext_other = GR_CMBX_TEXTURE_RGB; ext_other_a = GR_CMBX_TEXTURE_ALPHA; break; case GR_COMBINE_OTHER_CONSTANT: ext_other = GR_CMBX_CONSTANT_COLOR; ext_other_a = GR_CMBX_CONSTANT_ALPHA; break; }; switch (cmb.c_fac) { case GR_COMBINE_FACTOR_ZERO: cmb.c_ext_c = GR_CMBX_ZERO; cmb.c_ext_c_invert = 0; break; case GR_COMBINE_FACTOR_ONE: cmb.c_ext_c = GR_CMBX_ZERO; cmb.c_ext_c_invert = 1; break; case GR_COMBINE_FACTOR_LOCAL: cmb.c_ext_c = ext_local; cmb.c_ext_c_invert = 0; break; case GR_COMBINE_FACTOR_LOCAL_ALPHA: cmb.c_ext_c = ext_local_a; cmb.c_ext_c_invert = 0; break; case GR_COMBINE_FACTOR_OTHER_ALPHA: cmb.c_ext_c = ext_other_a; cmb.c_ext_c_invert = 0; break; case GR_COMBINE_FACTOR_TEXTURE_RGB: cmb.c_ext_c = GR_CMBX_TEXTURE_RGB; cmb.c_ext_c_invert = 0; break; case GR_COMBINE_FACTOR_TEXTURE_ALPHA: cmb.c_ext_c = GR_CMBX_TEXTURE_ALPHA; cmb.c_ext_c_invert = 0; break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL: cmb.c_ext_c = ext_local; cmb.c_ext_c_invert = 1; break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA: cmb.c_ext_c = ext_local_a; cmb.c_ext_c_invert = 1; break; case GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA: cmb.c_ext_c = ext_other_a; cmb.c_ext_c_invert = 1; break; case GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA: cmb.c_ext_c = GR_CMBX_TEXTURE_ALPHA; cmb.c_ext_c_invert = 1; break; } switch (cmb.c_fnc) { case GR_COMBINE_FUNCTION_ZERO: cmb.c_ext_a = GR_CMBX_ZERO; cmb.c_ext_a_mode = GR_FUNC_MODE_X; cmb.c_ext_b = GR_CMBX_ZERO; cmb.c_ext_b_mode = GR_FUNC_MODE_X; cmb.c_ext_c = GR_CMBX_ZERO; cmb.c_ext_c_invert = 0; cmb.c_ext_d = GR_CMBX_ZERO; cmb.c_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_LOCAL: cmb.c_ext_a = ext_local; cmb.c_ext_a_mode = GR_FUNC_MODE_X; cmb.c_ext_b = GR_CMBX_ZERO; cmb.c_ext_b_mode = GR_FUNC_MODE_X; cmb.c_ext_c = GR_CMBX_ZERO; cmb.c_ext_c_invert = 1; cmb.c_ext_d = GR_CMBX_ZERO; cmb.c_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_LOCAL_ALPHA: cmb.c_ext_a = ext_local_a; cmb.c_ext_a_mode = GR_FUNC_MODE_X; cmb.c_ext_b = GR_CMBX_ZERO; cmb.c_ext_b_mode = GR_FUNC_MODE_X; cmb.c_ext_c = GR_CMBX_ZERO; cmb.c_ext_c_invert = 1; cmb.c_ext_d = GR_CMBX_ZERO; cmb.c_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_SCALE_OTHER: cmb.c_ext_a = ext_other; cmb.c_ext_a_mode = GR_FUNC_MODE_X; cmb.c_ext_b = GR_CMBX_ZERO; cmb.c_ext_b_mode = GR_FUNC_MODE_ZERO; cmb.c_ext_d = GR_CMBX_ZERO; cmb.c_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL: cmb.c_ext_a = ext_other; cmb.c_ext_a_mode = GR_FUNC_MODE_X; cmb.c_ext_b = ext_local; cmb.c_ext_b_mode = GR_FUNC_MODE_ZERO; cmb.c_ext_d = GR_CMBX_B; cmb.c_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA: cmb.c_ext_a = ext_other; cmb.c_ext_a_mode = GR_FUNC_MODE_X; cmb.c_ext_b = ext_local_a; cmb.c_ext_b_mode = GR_FUNC_MODE_ZERO; cmb.c_ext_d = GR_CMBX_B; cmb.c_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL: cmb.c_ext_a = ext_other; cmb.c_ext_a_mode = GR_FUNC_MODE_X; cmb.c_ext_b = ext_local; cmb.c_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; cmb.c_ext_d = GR_CMBX_ZERO; cmb.c_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL: cmb.c_ext_a = ext_other; cmb.c_ext_a_mode = GR_FUNC_MODE_X; cmb.c_ext_b = ext_local; cmb.c_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; cmb.c_ext_d = GR_CMBX_B; cmb.c_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA: cmb.c_ext_a = ext_other; cmb.c_ext_a_mode = GR_FUNC_MODE_X; cmb.c_ext_b = ext_local; cmb.c_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; cmb.c_ext_d = GR_CMBX_ALOCAL; cmb.c_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL: cmb.c_ext_a = GR_CMBX_ZERO; cmb.c_ext_a_mode = GR_FUNC_MODE_ZERO; cmb.c_ext_b = ext_local; cmb.c_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; cmb.c_ext_d = GR_CMBX_B; cmb.c_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA: cmb.c_ext_a = GR_CMBX_ZERO; cmb.c_ext_a_mode = GR_FUNC_MODE_ZERO; cmb.c_ext_b = ext_local; cmb.c_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; cmb.c_ext_d = GR_CMBX_ALOCAL; cmb.c_ext_d_invert = 0; break; } } void AlphaCombinerToExtension(void) { uint32_t ext_local, ext_other; switch (cmb.a_loc) { case GR_COMBINE_LOCAL_ITERATED: ext_local = GR_CMBX_ITALPHA; break; case GR_COMBINE_LOCAL_CONSTANT: ext_local = GR_CMBX_CONSTANT_ALPHA; break; default: ext_local = GR_CMBX_ZERO; } switch (cmb.a_oth) { case GR_COMBINE_OTHER_ITERATED: ext_other = GR_CMBX_ITALPHA; break; case GR_COMBINE_OTHER_TEXTURE: ext_other = GR_CMBX_TEXTURE_ALPHA; break; case GR_COMBINE_OTHER_CONSTANT: ext_other = GR_CMBX_CONSTANT_ALPHA; break; default: ext_other = GR_CMBX_ZERO; } switch (cmb.a_fac) { case GR_COMBINE_FACTOR_ZERO: cmb.a_ext_c = GR_CMBX_ZERO; cmb.a_ext_c_invert = 0; break; case GR_COMBINE_FACTOR_ONE: cmb.a_ext_c = GR_CMBX_ZERO; cmb.a_ext_c_invert = 1; break; case GR_COMBINE_FACTOR_LOCAL: case GR_COMBINE_FACTOR_LOCAL_ALPHA: cmb.a_ext_c = ext_local; cmb.a_ext_c_invert = 0; break; case GR_COMBINE_FACTOR_OTHER_ALPHA: cmb.a_ext_c = ext_other; cmb.a_ext_c_invert = 0; break; case GR_COMBINE_FACTOR_TEXTURE_ALPHA: cmb.a_ext_c = GR_CMBX_TEXTURE_ALPHA; cmb.a_ext_c_invert = 0; break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL: case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA: cmb.a_ext_c = ext_local; cmb.a_ext_c_invert = 1; break; case GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA: cmb.a_ext_c = ext_other; cmb.a_ext_c_invert = 1; break; case GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA: cmb.a_ext_c = GR_CMBX_TEXTURE_ALPHA; cmb.a_ext_c_invert = 1; break; default: cmb.a_ext_c = GR_CMBX_ZERO; cmb.a_ext_c_invert = 0; } switch (cmb.a_fnc) { case GR_COMBINE_FUNCTION_ZERO: cmb.a_ext_a = GR_CMBX_ZERO; cmb.a_ext_a_mode = GR_FUNC_MODE_X; cmb.a_ext_b = GR_CMBX_ZERO; cmb.a_ext_b_mode = GR_FUNC_MODE_X; cmb.a_ext_c = GR_CMBX_ZERO; cmb.a_ext_c_invert = 0; cmb.a_ext_d = GR_CMBX_ZERO; cmb.a_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_LOCAL: case GR_COMBINE_FUNCTION_LOCAL_ALPHA: cmb.a_ext_a = GR_CMBX_ZERO; cmb.a_ext_a_mode = GR_FUNC_MODE_ZERO; cmb.a_ext_b = ext_local; cmb.a_ext_b_mode = GR_FUNC_MODE_X; cmb.a_ext_c = GR_CMBX_ZERO; cmb.a_ext_c_invert = 1; cmb.a_ext_d = GR_CMBX_ZERO; cmb.a_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_SCALE_OTHER: cmb.a_ext_a = ext_other; cmb.a_ext_a_mode = GR_FUNC_MODE_X; cmb.a_ext_b = GR_CMBX_ZERO; cmb.a_ext_b_mode = GR_FUNC_MODE_ZERO; cmb.a_ext_d = GR_CMBX_ZERO; cmb.a_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL: case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA: cmb.a_ext_a = ext_other; cmb.a_ext_a_mode = GR_FUNC_MODE_X; cmb.a_ext_b = ext_local; cmb.a_ext_b_mode = GR_FUNC_MODE_ZERO; cmb.a_ext_d = GR_CMBX_B; cmb.a_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL: cmb.a_ext_a = ext_other; cmb.a_ext_a_mode = GR_FUNC_MODE_X; cmb.a_ext_b = ext_local; cmb.a_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; cmb.a_ext_d = GR_CMBX_ZERO; cmb.a_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL: case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA: cmb.a_ext_a = ext_other; cmb.a_ext_a_mode = GR_FUNC_MODE_X; cmb.a_ext_b = ext_local; cmb.a_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; cmb.a_ext_d = GR_CMBX_B; cmb.a_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL: case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA: cmb.a_ext_a = GR_CMBX_ZERO; cmb.a_ext_a_mode = GR_FUNC_MODE_ZERO; cmb.a_ext_b = ext_local; cmb.a_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; cmb.a_ext_d = GR_CMBX_B; cmb.a_ext_d_invert = 0; break; } } void TexColorCombinerToExtension (int32_t tmu) { uint32_t tc_ext_a, tc_ext_a_mode, tc_ext_b, tc_ext_b_mode, tc_ext_c, tc_ext_d; int tc_ext_c_invert, tc_ext_d_invert; uint32_t tmu_func, tmu_fac; if (tmu == GR_TMU0) { tmu_func = cmb.tmu0_func; tmu_fac = cmb.tmu0_fac; } else { tmu_func = cmb.tmu1_func; tmu_fac = cmb.tmu1_fac; } switch (tmu_fac) { case GR_COMBINE_FACTOR_ZERO: tc_ext_c = GR_CMBX_ZERO; tc_ext_c_invert = 0; break; case GR_COMBINE_FACTOR_LOCAL: tc_ext_c = GR_CMBX_LOCAL_TEXTURE_RGB; tc_ext_c_invert = 0; break; case GR_COMBINE_FACTOR_LOCAL_ALPHA: tc_ext_c = GR_CMBX_LOCAL_TEXTURE_ALPHA; tc_ext_c_invert = 0; break; case GR_COMBINE_FACTOR_OTHER_ALPHA: tc_ext_c = GR_CMBX_OTHER_TEXTURE_ALPHA; tc_ext_c_invert = 0; break; case GR_COMBINE_FACTOR_DETAIL_FACTOR: tc_ext_c = GR_CMBX_DETAIL_FACTOR; tc_ext_c_invert = 0; break; case GR_COMBINE_FACTOR_ONE: tc_ext_c = GR_CMBX_ZERO; tc_ext_c_invert = 1; break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL: tc_ext_c = GR_CMBX_LOCAL_TEXTURE_RGB; tc_ext_c_invert = 1; break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA: tc_ext_c = GR_CMBX_LOCAL_TEXTURE_ALPHA; tc_ext_c_invert = 1; break; case GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA: tc_ext_c = GR_CMBX_OTHER_TEXTURE_ALPHA; tc_ext_c_invert = 1; break; case GR_COMBINE_FACTOR_ONE_MINUS_DETAIL_FACTOR: tc_ext_c = GR_CMBX_DETAIL_FACTOR; tc_ext_c_invert = 1; break; } switch (tmu_func) { case GR_COMBINE_FUNCTION_ZERO: tc_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB; tc_ext_a_mode = GR_FUNC_MODE_ZERO; tc_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; tc_ext_b_mode = GR_FUNC_MODE_ZERO; tc_ext_c = GR_CMBX_ZERO; tc_ext_c_invert = 0; tc_ext_d = GR_CMBX_ZERO; tc_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_LOCAL: tc_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB; tc_ext_a_mode = GR_FUNC_MODE_X; tc_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; tc_ext_b_mode = GR_FUNC_MODE_ZERO; tc_ext_c = GR_CMBX_ZERO; tc_ext_c_invert = 1; tc_ext_d = GR_CMBX_ZERO; tc_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_LOCAL_ALPHA: tc_ext_a = GR_CMBX_LOCAL_TEXTURE_ALPHA; tc_ext_a_mode = GR_FUNC_MODE_X; tc_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; tc_ext_b_mode = GR_FUNC_MODE_ZERO; tc_ext_c = GR_CMBX_ZERO; tc_ext_c_invert = 1; tc_ext_d = GR_CMBX_ZERO; tc_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_SCALE_OTHER: tc_ext_a = GR_CMBX_OTHER_TEXTURE_RGB; tc_ext_a_mode = GR_FUNC_MODE_X; tc_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; tc_ext_b_mode = GR_FUNC_MODE_ZERO; tc_ext_d = GR_CMBX_ZERO; tc_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL: tc_ext_a = GR_CMBX_OTHER_TEXTURE_RGB; tc_ext_a_mode = GR_FUNC_MODE_X; tc_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; tc_ext_b_mode = GR_FUNC_MODE_ZERO; tc_ext_d = GR_CMBX_B; tc_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA: tc_ext_a = GR_CMBX_OTHER_TEXTURE_RGB; tc_ext_a_mode = GR_FUNC_MODE_X; tc_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA; tc_ext_b_mode = GR_FUNC_MODE_ZERO; tc_ext_d = GR_CMBX_B; tc_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL: tc_ext_a = GR_CMBX_OTHER_TEXTURE_RGB; tc_ext_a_mode = GR_FUNC_MODE_X; tc_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; tc_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; tc_ext_d = GR_CMBX_ZERO; tc_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL: tc_ext_a = GR_CMBX_OTHER_TEXTURE_RGB; tc_ext_a_mode = GR_FUNC_MODE_X; tc_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; tc_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; tc_ext_d = GR_CMBX_B; tc_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA: tc_ext_a = GR_CMBX_OTHER_TEXTURE_RGB; tc_ext_a_mode = GR_FUNC_MODE_X; tc_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; tc_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; tc_ext_d = GR_CMBX_LOCAL_TEXTURE_ALPHA; tc_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL: tc_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB; tc_ext_a_mode = GR_FUNC_MODE_ZERO; tc_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; tc_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; tc_ext_d = GR_CMBX_B; tc_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA: tc_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB; tc_ext_a_mode = GR_FUNC_MODE_ZERO; tc_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; tc_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; tc_ext_d = GR_CMBX_LOCAL_TEXTURE_ALPHA; tc_ext_d_invert = 0; break; } if (tmu == GR_TMU0) { cmb.t0c_ext_a = tc_ext_a; cmb.t0c_ext_a_mode = tc_ext_a_mode; cmb.t0c_ext_b = tc_ext_b; cmb.t0c_ext_b_mode = tc_ext_b_mode; cmb.t0c_ext_c = tc_ext_c; cmb.t0c_ext_c_invert = tc_ext_c_invert; cmb.t0c_ext_d = tc_ext_d; cmb.t0c_ext_d_invert = tc_ext_d_invert; } else { cmb.t1c_ext_a = tc_ext_a; cmb.t1c_ext_a_mode = tc_ext_a_mode; cmb.t1c_ext_b = tc_ext_b; cmb.t1c_ext_b_mode = tc_ext_b_mode; cmb.t1c_ext_c = tc_ext_c; cmb.t1c_ext_c_invert = tc_ext_c_invert; cmb.t1c_ext_d = tc_ext_d; cmb.t1c_ext_d_invert = tc_ext_d_invert; } } void TexAlphaCombinerToExtension (int32_t tmu) { uint32_t ta_ext_a, ta_ext_a_mode, ta_ext_b, ta_ext_b_mode, ta_ext_c, ta_ext_d; int ta_ext_c_invert, ta_ext_d_invert; uint32_t tmu_a_func, tmu_a_fac; if (tmu == GR_TMU0) { tmu_a_func = cmb.tmu0_a_func; tmu_a_fac = cmb.tmu0_a_fac; } else { tmu_a_func = cmb.tmu1_a_func; tmu_a_fac = cmb.tmu1_a_fac; } switch (tmu_a_fac) { case GR_COMBINE_FACTOR_ZERO: ta_ext_c = GR_CMBX_ZERO; ta_ext_c_invert = 0; break; case GR_COMBINE_FACTOR_LOCAL: case GR_COMBINE_FACTOR_LOCAL_ALPHA: ta_ext_c = GR_CMBX_LOCAL_TEXTURE_ALPHA; ta_ext_c_invert = 0; break; case GR_COMBINE_FACTOR_OTHER_ALPHA: ta_ext_c = GR_CMBX_OTHER_TEXTURE_ALPHA; ta_ext_c_invert = 0; break; case GR_COMBINE_FACTOR_DETAIL_FACTOR: ta_ext_c = GR_CMBX_DETAIL_FACTOR; ta_ext_c_invert = 0; break; case GR_COMBINE_FACTOR_ONE: ta_ext_c = GR_CMBX_ZERO; ta_ext_c_invert = 1; break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL: case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA: ta_ext_c = GR_CMBX_LOCAL_TEXTURE_ALPHA; ta_ext_c_invert = 1; break; case GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA: ta_ext_c = GR_CMBX_OTHER_TEXTURE_ALPHA; ta_ext_c_invert = 1; break; case GR_COMBINE_FACTOR_ONE_MINUS_DETAIL_FACTOR: ta_ext_c = GR_CMBX_DETAIL_FACTOR; ta_ext_c_invert = 1; break; } switch (tmu_a_func) { case GR_COMBINE_FUNCTION_ZERO: ta_ext_a = GR_CMBX_LOCAL_TEXTURE_ALPHA; ta_ext_a_mode = GR_FUNC_MODE_ZERO; ta_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA; ta_ext_b_mode = GR_FUNC_MODE_ZERO; ta_ext_c = GR_CMBX_ZERO; ta_ext_c_invert = 0; ta_ext_d = GR_CMBX_ZERO; ta_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_LOCAL: case GR_COMBINE_FUNCTION_LOCAL_ALPHA: ta_ext_a = GR_CMBX_LOCAL_TEXTURE_ALPHA; ta_ext_a_mode = GR_FUNC_MODE_X; ta_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA; ta_ext_b_mode = GR_FUNC_MODE_ZERO; ta_ext_c = GR_CMBX_ZERO; ta_ext_c_invert = 1; ta_ext_d = GR_CMBX_ZERO; ta_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_SCALE_OTHER: ta_ext_a = GR_CMBX_OTHER_TEXTURE_ALPHA; ta_ext_a_mode = GR_FUNC_MODE_X; ta_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA; ta_ext_b_mode = GR_FUNC_MODE_ZERO; ta_ext_d = GR_CMBX_ZERO; ta_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL: case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA: ta_ext_a = GR_CMBX_OTHER_TEXTURE_ALPHA; ta_ext_a_mode = GR_FUNC_MODE_X; ta_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA; ta_ext_b_mode = GR_FUNC_MODE_ZERO; ta_ext_d = GR_CMBX_B; ta_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL: ta_ext_a = GR_CMBX_OTHER_TEXTURE_ALPHA; ta_ext_a_mode = GR_FUNC_MODE_X; ta_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA; ta_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; ta_ext_d = GR_CMBX_ZERO; ta_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL: case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA: ta_ext_a = GR_CMBX_OTHER_TEXTURE_ALPHA; ta_ext_a_mode = GR_FUNC_MODE_X; ta_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA; ta_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; ta_ext_d = GR_CMBX_B; ta_ext_d_invert = 0; break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL: case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA: ta_ext_a = GR_CMBX_LOCAL_TEXTURE_ALPHA; ta_ext_a_mode = GR_FUNC_MODE_ZERO; ta_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA; ta_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; ta_ext_d = GR_CMBX_B; ta_ext_d_invert = 0; break; } if (tmu == GR_TMU0) { cmb.t0a_ext_a = ta_ext_a; cmb.t0a_ext_a_mode = ta_ext_a_mode; cmb.t0a_ext_b = ta_ext_b; cmb.t0a_ext_b_mode = ta_ext_b_mode; cmb.t0a_ext_c = ta_ext_c; cmb.t0a_ext_c_invert = ta_ext_c_invert; cmb.t0a_ext_d = ta_ext_d; cmb.t0a_ext_d_invert = ta_ext_d_invert; } else { cmb.t1a_ext_a = ta_ext_a; cmb.t1a_ext_a_mode = ta_ext_a_mode; cmb.t1a_ext_b = ta_ext_b; cmb.t1a_ext_b_mode = ta_ext_b_mode; cmb.t1a_ext_c = ta_ext_c; cmb.t1a_ext_c_invert = ta_ext_c_invert; cmb.t1a_ext_d = ta_ext_d; cmb.t1a_ext_d_invert = ta_ext_d_invert; } } mupen64plus-core/src/debugger/dbg_decoder.h000664 001750 001750 00000004403 12655644434 022015 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - dbg_decoder.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2010 Marshall B. Rogers * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef __DECODER_H__ #define __DECODER_H__ #include "dbg_types.h" #if defined(WIN32) typedef unsigned int uint32_t; typedef unsigned char bool; #define false 0 #define true 1 #else #include #include #endif /* Disassembler lookup handler */ typedef char * (*r4k_lookup_func)(uint32_t, void *); /* Disassembler state */ typedef struct r4k_dis_t { r4k_lookup_func lookup_sym; void * lookup_sym_d; r4k_lookup_func lookup_rel_hi16; void * lookup_rel_hi16_d; r4k_lookup_func lookup_rel_lo16; void * lookup_rel_lo16_d; /* Private */ char * dest; int length; } R4kDis; extern void r4300_decode_op ( uint32_t, char *, char *, uint32_t ); #endif /* __DECODER_H__ */ mupen64plus-core/tools/build_modules_src.sh000755 001750 001750 00000004624 12655644434 022250 0ustar00sergiosergio000000 000000 #!/bin/sh #/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # * Mupen64plus - build_modules_src.sh * # * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * # * Copyright (C) 2009-2013 Richard Goedeken * # * * # * This program is free software; you can redistribute it and/or modify * # * it under the terms of the GNU General Public License as published by * # * the Free Software Foundation; either version 2 of the License, or * # * (at your option) any later version. * # * * # * This program is distributed in the hope that it will be useful, * # * but WITHOUT ANY WARRANTY; without even the implied warranty of * # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * # * GNU General Public License for more details. * # * * # * You should have received a copy of the GNU General Public License * # * along with this program; if not, write to the * # * Free Software Foundation, Inc., * # * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ # terminate the script if any commands return a non-zero error code set -e if [ $# -lt 2 ]; then echo "Usage: build_modules_src.sh " exit 1 fi modules='mupen64plus-core mupen64plus-rom mupen64plus-ui-console mupen64plus-audio-sdl mupen64plus-input-sdl mupen64plus-rsp-hle mupen64plus-video-rice mupen64plus-video-glide64mk2' for modname in ${modules}; do echo "************************************ Downloading and packaging module source code: ${modname}" rm -rf "tmp" EXCLUDE="--exclude .hgtags --exclude .hg_archival.txt --exclude .hgignore" TARTAG="" OUTPUTDIR="${modname}-$2" hg clone --noupdate "http://bitbucket.org/richard42/$modname" "tmp" cd tmp hg archive --no-decode --type tar --prefix "${OUTPUTDIR}/" ${EXCLUDE} -r $1 "../${OUTPUTDIR}${TARTAG}.tar" cd .. gzip -n -f "${OUTPUTDIR}${TARTAG}.tar" rm -rf "tmp" done gles2rice/src/arm_features.h000664 001750 001750 00000002176 12655644434 017221 0ustar00sergiosergio000000 000000 #ifndef __ARM_FEATURES_H__ #define __ARM_FEATURES_H__ #if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \ || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \ || defined(__ARM_ARCH_7EM__) #define HAVE_ARMV7 #define HAVE_ARMV6 #define HAVE_ARMV5 #elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \ || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \ || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) #define HAVE_ARMV6 #define HAVE_ARMV5 #elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5E__) \ || defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__) #define HAVE_ARMV5 #endif /* no need for HAVE_NEON - GCC defines __ARM_NEON__ consistently */ /* global function/external symbol */ #ifndef __MACH__ #define ESYM(name) name #define FUNCTION(name) \ .globl name; \ .type name, %function; \ name #define EXTRA_UNSAVED_REGS #else #define ESYM(name) _##name #define FUNCTION(name) \ .globl ESYM(name); \ name: \ ESYM(name) // r7 is preserved, but add it for EABI alignment.. #define EXTRA_UNSAVED_REGS r7, r9, #endif #endif /* __ARM_FEATURES_H__ */ glide2gl/src/Glide64/Glide64_UCode.c000664 001750 001750 00000021743 12655644434 020025 0ustar00sergiosergio000000 000000 #include #include "Glide64_UCode.h" #include "rdp.h" #include "api/libretro.h" extern uint8_t microcode[4096]; extern uint32_t uc_crc; extern int old_ucode; extern SETTINGS settings; extern retro_log_printf_t log_cb; void microcheck(void) { uint32_t i; uc_crc = 0; // Check first 3k of ucode, because the last 1k sometimes contains trash for (i = 0; i < 3072 >> 2; i++) uc_crc += ((uint32_t*)microcode)[i]; FRDP_E ("crc: %08lx\n", uc_crc); if (log_cb) log_cb(RETRO_LOG_INFO, "Glide64 ucode = 0x%04x\n", uc_crc); old_ucode = settings.ucode; if ( uc_crc == 0x006bd77f || uc_crc == 0x07200895 || uc_crc == UCODE_GOLDENEYE_007 || uc_crc == UCODE_DUKE_NUKEM_64 || uc_crc == UCODE_ROBOTECH_CRYSTAL_DREAMS_PROTO || uc_crc == UCODE_NBA_SHOWTIME || uc_crc == 0xbc03e969 || uc_crc == 0xd5604971 || uc_crc == UCODE_MORITA_SHOUGI_64 || uc_crc == 0xd67c2f8b || uc_crc == UCODE_KILLER_INSTINCT_GOLD || uc_crc == UCODE_MISCHIEF_MAKERS || uc_crc == UCODE_MORTAL_KOMBAT_TRILOGY || uc_crc == 0x5182f610 || uc_crc == UCODE_BLAST_CORPS || uc_crc == UCODE_PILOTWINGS_64 || uc_crc == UCODE_CRUISN_USA || uc_crc == UCODE_SUPER_MARIO_64 || uc_crc == UCODE_TETRISPHERE || uc_crc == 0x4165e1fd || uc_crc == UCODE_EIKU_NO_SAINT_ANDREWS ) { settings.ucode = 0; if (log_cb) log_cb(RETRO_LOG_INFO, "Microcode 0 - RSP SW 2.0X (Super Mario 64)\n"); } else if ( uc_crc == UCODE_CLAYFIGHTER_63 || uc_crc == 0x05777c62 || uc_crc == 0x057e7c62 || uc_crc == 0x1118b3e0 || uc_crc == UCODE_MINI_RACERS_CRC1 || uc_crc == 0x1de712ff || uc_crc == 0x24cd885b || uc_crc == 0x26a7879a || uc_crc == 0xfb816260 || uc_crc == 0x2c7975d6 || uc_crc == 0x2d3fe3f1 || uc_crc == UCODE_FIGHTING_FORCE_64_CRC1 || uc_crc == 0x339872a6 || uc_crc == 0x3ff1a4ca || uc_crc == 0x4340ac9b || uc_crc == 0x440cfad6 || uc_crc == 0x4fe6df78 || uc_crc == 0x5257cd2a || uc_crc == UCODE_MORTAL_KOMBAT_MYTHOLOGIES || uc_crc == 0x5414030d || uc_crc == 0x559ff7d4 || uc_crc == UCODE_YOSHIS_STORY_CRC2 || uc_crc == UCODE_IGGY_RECKIN_BALLS || uc_crc == 0x6075e9eb || uc_crc == UCODE_DEZAEMON3D || uc_crc == UCODE_1080_SNOWBOARDING || uc_crc == 0x66c0b10a || uc_crc == 0x6eaa1da8 || uc_crc == 0x72a4f34e || uc_crc == 0x73999a23 || uc_crc == 0x7df75834 || uc_crc == UCODE_DOOM_64 || uc_crc == UCODE_TUROK_1 || uc_crc == 0x82f48073 || uc_crc == UCODE_MINI_RACERS_CRC2 || uc_crc == 0x841ce10f || uc_crc == 0x863e1ca7 || uc_crc == UCODE_MARIO_KART_64 || uc_crc == 0x8d5735b2 || uc_crc == 0x8d5735b3 || uc_crc == 0x97d1b58a || uc_crc == UCODE_QUAKE_64 || uc_crc == UCODE_WETRIX || uc_crc == UCODE_STAR_FOX_64 || uc_crc == UCODE_FIGHTING_FORCE_64_CRC2 || uc_crc == 0xb4577b9c || uc_crc == 0xbe78677c || uc_crc == 0xbed8b069 || uc_crc == 0xc3704e41 || uc_crc == UCODE_EXTREME_G || uc_crc == 0xc99a4c6c || uc_crc == 0xcee7920f || uc_crc == 0xd1663234 || uc_crc == 0xd2a9f59c || uc_crc == 0xd41db5f7 || uc_crc == 0xd57049a5 || uc_crc == UCODE_TAMIYA_RACING_64_PROTO || uc_crc == UCODE_WIPEOUT_64 || uc_crc == 0xe9231df2 || uc_crc == 0xec040469 || uc_crc == UCODE_DUAL_HEROES || uc_crc == UCODE_HEXEN_64 || uc_crc == UCODE_CHAMELEON_TWIST || uc_crc == UCODE_BANJO_KAZOOIE || uc_crc == UCODE_MACE_THE_DARK_AGE || uc_crc == 0xef54ee35 ) { settings.ucode = 1; if (log_cb) log_cb(RETRO_LOG_INFO, "Microcode 1 - F3DEX 1.XX (Star Fox 64)\n"); } else if ( uc_crc == 0x03044b84 || uc_crc == 0x030f4b84 || uc_crc == 0x0ff79527 || uc_crc == UCODE_COMMAND_AND_CONQUER || uc_crc == UCODE_KNIFE_EDGE || uc_crc == UCODE_EXTREME_G_2 || uc_crc == UCODE_DONKEY_KONG_64 || uc_crc == UCODE_TONIC_TROUBLE || uc_crc == UCODE_PAPER_MARIO || uc_crc == UCODE_ANIMAL_CROSSING || uc_crc == UCODE_ZELDA_MAJORAS_MASK || uc_crc == UCODE_ZELDA_OOT || uc_crc == 0x6124a508 || uc_crc == 0x630a61fb || uc_crc == UCODE_CASTLEVANIA_64 || uc_crc == UCODE_CASTLEVANIA_64 || uc_crc == UCODE_KING_HILL_64 || uc_crc == 0x679e1205 || uc_crc == 0x6d8f8f8a || uc_crc == 0x753be4a5 || uc_crc == 0xda13ab96 || uc_crc == 0xe65cb4ad || uc_crc == 0xe1290fa2 || uc_crc == UCODE_HEY_YOU_PIKACHU || uc_crc == UCODE_CRUISN_EXOTICA || uc_crc == UCODE_STARCRAFT_64 || uc_crc == 0x2b291027 || uc_crc == UCODE_POKEMON_SNAP || uc_crc == 0x2f7dd1d5 || uc_crc == UCODE_CRUISN_EXOTICA || uc_crc == UCODE_GANBARE_GOEMON_2 || uc_crc == 0x93d11ffb || uc_crc == 0x93d1ff7b || uc_crc == UCODE_FZERO_X || uc_crc == 0x955117fb || uc_crc == UCODE_BIOHAZARD_2 || uc_crc == 0xa2d0f88e || uc_crc == 0xaa86cb1d || uc_crc == 0xaae4a5b9 || uc_crc == 0xad0a6292 || uc_crc == 0xad0a6312 || uc_crc == UCODE_NBA_SHOWTIME || uc_crc == 0xba65ea1e || uc_crc == UCODE_KIRBY_64_CRYSTAL_SHARDS || uc_crc == UCODE_SUPER_SMASH_BROS || uc_crc == UCODE_MARIO_TENNIS || uc_crc == UCODE_MEGA_MAN_64 || uc_crc == UCODE_RIDGE_RACER_64 || uc_crc == UCODE_40WINKS || uc_crc == 0xcb8c9b6c || uc_crc == UCODE_ARMORINES_PROJECT ) { settings.ucode = 2; if (log_cb) log_cb(RETRO_LOG_INFO, "Microcode 2 - F3DEX 2.XX (The Legend of Zelda: Ocarina of Time)\n"); } else if ( uc_crc == UCODE_WAVERACE_64 ) { settings.ucode = 3; if (log_cb) log_cb(RETRO_LOG_INFO, "Microcode 3 - F3DEX ? (WaveRace)\n"); } else if ( uc_crc == UCODE_STAR_WARS_SHADOW_OF_THE_EMPIRE ) { settings.ucode = 4; if (log_cb) log_cb(RETRO_LOG_INFO, "Microcode 4 - RSP SW 2.0D EXT (Star Wars: Shadows of the Empire)\n"); } else if ( uc_crc == UCODE_JET_FORCE_GEMINI || uc_crc == UCODE_MICKEYS_SPEEDWAY_USA || uc_crc == UCODE_DIDDY_KONG_RACING || uc_crc == 0x63be08b3 ) { settings.ucode = 5; if (log_cb) log_cb(RETRO_LOG_INFO, "Microcode 5 - RSP SW 2.0 (Diddy Kong Racing)\n"); } else if ( uc_crc == 0x1ea9e30f || uc_crc == 0x74af0a74 || uc_crc == 0x794c3e28 || uc_crc == UCODE_BANGAIOH || uc_crc == 0x2b5a89c2 || uc_crc == UCODE_YOSHIS_STORY_CRC1 || uc_crc == 0xd20dedbf ) { settings.ucode = 6; if (log_cb) log_cb(RETRO_LOG_INFO, "Microcode 6 - S2DEX 1.XX (Yoshi's Story - SimCity 2000)\n"); } else if ( uc_crc == UCODE_PERFECT_DARK ) { settings.ucode = 7; if (log_cb) log_cb(RETRO_LOG_INFO, "Microcode 7 - RSP SW PD (Perfect Dark)\n"); } else if ( uc_crc == UCODE_CONKERS_BAD_FUR_DAY ) { settings.ucode = 8; if (log_cb) log_cb(RETRO_LOG_INFO, "Microcode 8 - F3DEXBG 2.08 (Conker's Bad Fur Day)\n"); } else if ( uc_crc == 0x0bf36d36 ) { settings.ucode = 9; if (log_cb) log_cb(RETRO_LOG_INFO, "Microcode 9 - Star Wars: Battle for Naboo\n"); } else if ( uc_crc == 0x1f120bbb || uc_crc == 0xf9893f70 || uc_crc == UCODE_LAST_LEGION_UX ) { settings.ucode = 21; if (log_cb) log_cb(RETRO_LOG_INFO, "Microcode 21 - ???.\n"); } else if ( uc_crc == 0x0d7bbffb || uc_crc == 0x0ff795bf || uc_crc == UCODE_STAR_WARS_ROGUE_SQUADRON || uc_crc == 0x844b55b5 || uc_crc == 0x8ec3e124 || uc_crc == 0xd5c4dc96 ) { settings.ucode = -1; if (log_cb) log_cb(RETRO_LOG_INFO, "Microcode -1 - Unknown Microcode.\n"); } if (log_cb) log_cb(RETRO_LOG_INFO, "microcheck: old ucode: %d, new ucode: %d\n", old_ucode, settings.ucode); #if 0 //FIXME/TODO - check if this is/was necessary at all - persp_supported would be set to false here but rdp.Persp_en would be forcibly set to 1 if (uc_crc == 0x8d5735b2 || uc_crc == 0xb1821ed3 || uc_crc == 0x1118b3e0) //F3DLP.Rej ucode. perspective texture correction is not implemented { } #endif } mupen64plus-core/src/debugger/dbg_decoder.c000664 001750 001750 00000063650 12655644434 022021 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus -- dbg_decoder.c * * Copyright (c) 2010 Marshall B. Rogers * * http://64.vg/ * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * This is a heavily modified reentrant version of the MIPS disassembler found * in the NetBSD operating system. I chose to use this as a base due to the * small, compact, and easily manageable code. * * Original copyright/license information is contained below. */ /* $NetBSD: db_disasm.c,v 1.21 2009/12/14 00:46:06 matt Exp $ */ /*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Ralph Campbell. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. * * from: @(#)kadb.c 8.1 (Berkeley) 6/10/93 */ #include #include #include #include #include #ifndef MIPS32 #define MIPS32 #endif #include "dbg_decoder.h" #include "dbg_decoder_local.h" #include "osal/preproc.h" /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Data types ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ typedef uint32_t db_addr_t; /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Local variables ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ static const char * const r4k_str_op_name[64] = { /* 0 */ "spec", "bcond","j", "jal", "beq", "bne", "blez", "bgtz", /* 8 */ "addi", "addiu","slti", "sltiu","andi", "ori", "xori", "lui", /*16 */ "cop0", "cop1", "cop2", "cop3", "beql", "bnel", "blezl","bgtzl", /*24 */ "daddi","daddiu","ldl", "ldr", "op34", "op35", "op36", "op37", /*32 */ "lb", "lh", "lwl", "lw", "lbu", "lhu", "lwr", "lwu", /*40 */ "sb", "sh", "swl", "sw", "sdl", "sdr", "swr", "cache", /*48 */ "ll", "lwc1", "lwc2", "lwc3", "lld", "ldc1", "ldc2", "ld", /*56 */ "sc", "swc1", "swc2", "swc3", "scd", "sdc1", "sdc2", "sd" }; static const char * const r4k_str_spec_name[64] = { /* 0 */ "sll", "spec01","srl", "sra", "sllv", "spec05","srlv","srav", /* 8 */ "jr", "jalr", "spec12","spec13","syscall","break","spec16","sync", /*16 */ "mfhi", "mthi", "mflo", "mtlo", "dsllv","spec25","dsrlv","dsrav", /*24 */ "mult", "multu","div", "divu", "dmult","dmultu","ddiv","ddivu", /*32 */ "add", "addu", "sub", "subu", "and", "or", "xor", "nor", /*40 */ "spec50","spec51","slt","sltu", "dadd","daddu","dsub","dsubu", /*48 */ "tge","tgeu","tlt","tltu","teq","spec65","tne","spec67", /*56 */ "dsll","spec71","dsrl","dsra","dsll32","spec75","dsrl32","dsra32" }; static const char * const r4k_str_spec2_name[4] = /* QED RM4650, R5000, etc. */ { /* 0 */ "mad", "madu", "mul", "spec3" }; static const char * const r4k_str_bcond_name[32] = { /* 0 */ "bltz", "bgez", "bltzl", "bgezl", "?", "?", "?", "?", /* 8 */ "tgei", "tgeiu", "tlti", "tltiu", "teqi", "?", "tnei", "?", /*16 */ "bltzal", "bgezal", "bltzall", "bgezall", "?", "?", "?", "?", /*24 */ "?", "?", "?", "?", "?", "?", "?", "?", }; static const char * const r4k_str_cop1_name[64] = { /* 0 */ "add", "sub", "mul", "div", "sqrt","abs", "mov", "neg", /* 8 */ "fop08", "trunc.l","fop0a","fop0b","fop0c","trunc.w","fop0e","fop0f", /*16 */ "fop10", "fop11","fop12","fop13","fop14","fop15","fop16","fop17", /*24 */ "fop18", "fop19","fop1a","fop1b","fop1c","fop1d","fop1e","fop1f", /*32 */ "cvt.s", "cvt.d","fop22","fop23","cvt.w","cvt.l","fop26","fop27", /*40 */ "fop28", "fop29","fop2a","fop2b","fop2c","fop2d","fop2e","fop2f", /*48 */ "c.f", "c.un","c.eq","c.ueq","c.olt","c.ult", "c.ole", "c.ule", /*56 */ "c.sf", "c.ngle","c.seq","c.ngl","c.lt","c.nge", "c.le", "c.ngt" }; static const char * const r4k_str_fmt_name[16] = { "s", "d", "e", "fmt3", "w", "l", "fmt6", "fmt7", "fmt8", "fmt9", "fmta", "fmtb", "fmtc", "fmtd", "fmte", "fmtf" }; static const char * const r4k_str_reg_name[32] = { "$zero", "$at", "v0", "v1", "a0", "a1", "a2", "a3", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "t8", "t9", "k0", "k1", "$gp", "$sp", "s8", "$ra" }; static const char * const r4k_str_c0_opname[64] = { "c0op00","tlbr", "tlbwi", "c0op03","c0op04","c0op05","tlbwr", "c0op07", "tlbp", "c0op11","c0op12","c0op13","c0op14","c0op15","c0op16","c0op17", "rfe", "c0op21","c0op22","c0op23","c0op24","c0op25","c0op26","c0op27", "eret", "c0op31","c0op32","c0op33","c0op34","c0op35","c0op36","c0op37", "c0op40","c0op41","c0op42","c0op43","c0op44","c0op45","c0op46","c0op47", "c0op50","c0op51","c0op52","c0op53","c0op54","c0op55","c0op56","c0op57", "c0op60","c0op61","c0op62","c0op63","c0op64","c0op65","c0op66","c0op67", "c0op70","c0op71","c0op72","c0op73","c0op74","c0op75","c0op77","c0op77", }; static const char * const r4k_str_c0_reg[32] = { "C0_INX", "C0_RAND", "C0_ENTRYLO0", "C0_ENTRYLO1", "C0_CONTEXT", "C0_PAGEMASK", "C0_WIRED", "cp0r7", "C0_BADVADDR", "C0_COUNT", "C0_ENTRYHI", "C0_COMPARE", "C0_SR", "C0_CAUSE", "C0_EPC", "C0_PRID", "C0_CONFIG", "C0_LLADDR", "C0_WATCHLO", "C0_WATCHHI", "xcontext", "cp0r21", "cp0r22", "debug", "depc", "perfcnt", "C0_ECC", "C0_CACHE_ERR", "C0_TAGLO", "C0_TAGHI", "C0_ERROR_EPC", "desave" }; /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Local functions - lookup ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* Look up a symbol */ static char * lookup_sym ( struct r4k_dis_t * state, uint32_t address ) { if( state->lookup_sym ) return state->lookup_sym( address, state->lookup_sym_d ); return NULL; } /* Look up an upper 16-bits relocation */ static char * lookup_rel_hi16 ( struct r4k_dis_t * state, uint32_t address ) { if( state->lookup_rel_hi16 ) return state->lookup_rel_hi16( address, state->lookup_rel_hi16_d ); return NULL; } /* Look up a lower 16-bits relocation */ static char * lookup_rel_lo16 ( struct r4k_dis_t * state, uint32_t address ) { if( state->lookup_rel_lo16 ) return state->lookup_rel_lo16( address, state->lookup_rel_lo16_d ); return NULL; } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Local functions - disassembler ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* Print text into the destination buffer */ static int db_printf ( struct r4k_dis_t * state, char * fmt, ... ) { int l; va_list ap; char buffer[1024]; /* Prepare user provided */ va_start( ap, fmt ); l = vsnprintf( buffer, sizeof(buffer), fmt, ap ); va_end( ap ); /* Add it to our string */ state->dest += sprintf( state->dest, "%s", buffer ); state->length += l; return l; } /* Print an address to a string. If there's a symbol, the name will be printed */ static int print_addr ( struct r4k_dis_t * state, uint32_t address ) { int len; char * sym; /* Try to lookup symbol */ if( (sym = lookup_sym(state, address)) ) { len = db_printf( state, "%s", sym ); } else { len = db_printf( state, "0x%08X", address ); } return len; } /* Disassemble an instruction */ static db_addr_t db_disasm_insn ( struct r4k_dis_t * state, int insn, db_addr_t loc, bool altfmt ) { char * rel; InstFmt i; i.word = insn; switch (i.JType.op) { case OP_SPECIAL: if (i.word == 0) { db_printf(state, "nop"); break; } /* XXX * "addu" is a "move" only in 32-bit mode. What's the correct * answer - never decode addu/daddu as "move"? */ if (i.RType.func == OP_ADDU && i.RType.rt == 0) { db_printf(state, "%-16s%s,%s", "move", r4k_str_reg_name[i.RType.rd], r4k_str_reg_name[i.RType.rs]); break; } db_printf(state, "%-16s", r4k_str_spec_name[i.RType.func]); switch (i.RType.func) { case OP_SLL: case OP_SRL: case OP_SRA: case OP_DSLL: case OP_DSRL: case OP_DSRA: case OP_DSLL32: case OP_DSRL32: case OP_DSRA32: db_printf(state, "%s,%s,%d", r4k_str_reg_name[i.RType.rd], r4k_str_reg_name[i.RType.rt], i.RType.shamt); break; case OP_SLLV: case OP_SRLV: case OP_SRAV: case OP_DSLLV: case OP_DSRLV: case OP_DSRAV: db_printf(state, "%s,%s,%s", r4k_str_reg_name[i.RType.rd], r4k_str_reg_name[i.RType.rt], r4k_str_reg_name[i.RType.rs]); break; case OP_MFHI: case OP_MFLO: db_printf(state, "%s", r4k_str_reg_name[i.RType.rd]); break; case OP_JR: case OP_JALR: db_printf(state, "%s", r4k_str_reg_name[i.RType.rs]); break; case OP_MTLO: case OP_MTHI: db_printf(state, "%s", r4k_str_reg_name[i.RType.rs]); break; case OP_MULT: case OP_MULTU: case OP_DMULT: case OP_DMULTU: db_printf(state, "%s,%s", r4k_str_reg_name[i.RType.rs], r4k_str_reg_name[i.RType.rt]); break; case OP_DIV: case OP_DIVU: case OP_DDIV: case OP_DDIVU: db_printf(state, "$zero,%s,%s", r4k_str_reg_name[i.RType.rs], r4k_str_reg_name[i.RType.rt]); break; case OP_SYSCALL: case OP_SYNC: break; case OP_BREAK: db_printf(state, "%d", (i.RType.rs << 5) | i.RType.rt); break; default: db_printf(state, "%s,%s,%s", r4k_str_reg_name[i.RType.rd], r4k_str_reg_name[i.RType.rs], r4k_str_reg_name[i.RType.rt]); } break; case OP_SPECIAL2: if (i.RType.func == OP_MUL) db_printf(state, "%s\t%s,%s,%s", r4k_str_spec2_name[i.RType.func & 0x3], r4k_str_reg_name[i.RType.rd], r4k_str_reg_name[i.RType.rs], r4k_str_reg_name[i.RType.rt]); else db_printf(state, "%s\t%s,%s", r4k_str_spec2_name[i.RType.func & 0x3], r4k_str_reg_name[i.RType.rs], r4k_str_reg_name[i.RType.rt]); break; case OP_BCOND: db_printf(state, "%-16s%s,", r4k_str_bcond_name[i.IType.rt], r4k_str_reg_name[i.IType.rs]); goto pr_displ; case OP_BLEZ: case OP_BLEZL: case OP_BGTZ: case OP_BGTZL: db_printf(state, "%-16s%s,", r4k_str_op_name[i.IType.op], r4k_str_reg_name[i.IType.rs]); goto pr_displ; case OP_BEQ: case OP_BEQL: if (i.IType.rs == 0 && i.IType.rt == 0) { db_printf(state, "%-16s", "b"); goto pr_displ; } /* FALLTHROUGH */ case OP_BNE: case OP_BNEL: db_printf(state, "%-16s%s,%s,", r4k_str_op_name[i.IType.op], r4k_str_reg_name[i.IType.rs], r4k_str_reg_name[i.IType.rt]); pr_displ: print_addr( state, loc + 4 + ((short)i.IType.imm << 2) ); break; case OP_COP0: switch (i.RType.rs) { case OP_BCx: case OP_BCy: db_printf(state, "bc0%c\t", "ft"[i.RType.rt & COPz_BC_TF_MASK]); goto pr_displ; case OP_MT: db_printf(state, "%-16s%s,%s", "mtc0", r4k_str_reg_name[i.RType.rt], r4k_str_c0_reg[i.RType.rd]); break; case OP_DMT: db_printf(state, "%-16s%s,%s", "dmtc0", r4k_str_reg_name[i.RType.rt], r4k_str_c0_reg[i.RType.rd]); break; case OP_MF: db_printf(state, "%-16s%s,%s", "mfc0", r4k_str_reg_name[i.RType.rt], r4k_str_c0_reg[i.RType.rd]); break; case OP_DMF: db_printf(state, "%-16s%s,%s","dmfc0", r4k_str_reg_name[i.RType.rt], r4k_str_c0_reg[i.RType.rd]); break; default: db_printf(state, "%s", r4k_str_c0_opname[i.FRType.func]); } break; case OP_COP1: switch (i.RType.rs) { case OP_BCx: case OP_BCy: db_printf(state, "bc1%c%s\t\t", "ft"[i.RType.rt & COPz_BC_TF_MASK], (insn >> 16 & 0x1F) == 2 || (insn >> 16 & 0x1F) == 3 ? "l" : ""); goto pr_displ; case OP_MT: db_printf(state, "mtc1\t\t%s,$f%d", r4k_str_reg_name[i.RType.rt], i.RType.rd); break; case OP_MF: db_printf(state, "mfc1\t\t%s,$f%d", r4k_str_reg_name[i.RType.rt], i.RType.rd); break; case OP_CT: db_printf(state, "ctc1\t\t%s,$f%d", r4k_str_reg_name[i.RType.rt], i.RType.rd); break; case OP_CF: db_printf(state, "cfc1\t\t%s,$f%d", r4k_str_reg_name[i.RType.rt], i.RType.rd); break; case OP_DMT: db_printf(state, "dmtc1\t\t%s,$f%d", r4k_str_reg_name[i.RType.rt], i.RType.rd); break; case OP_DMF: db_printf(state, "dmfc1\t\t%s,$f%d", r4k_str_reg_name[i.RType.rt], i.RType.rd); break; case OP_MTH: db_printf(state, "mthc1\t\t%s,$f%d", r4k_str_reg_name[i.RType.rt], i.RType.rd); break; case OP_MFH: db_printf(state, "mfhc1\t\t%s,$f%d", r4k_str_reg_name[i.RType.rt], i.RType.rd); break; default: if( i.FRType.func == 0x21 || i.FRType.func == 0x20 || i.FRType.func == 0x24 || i.FRType.func == 0x25 || i.FRType.func == 7 || i.FRType.func == 6 || i.FRType.func == 0xd || i.FRType.func == 4 || i.FRType.func == 5 || i.FRType.func == 9 ) {/*NEG.fmt fd, fs*/ db_printf(state, "%s.%s\t\t$f%d,$f%d", r4k_str_cop1_name[i.FRType.func], r4k_str_fmt_name[i.FRType.fmt], i.FRType.fd, i.FRType.fs); } else if( i.FRType.func != 1 && i.FRType.func != 2 && (insn & 0x3F) && !(insn >> 6 & 0x1F) ) /* C */ { db_printf(state, "%s.%s\t\t$f%d,$f%d", r4k_str_cop1_name[i.FRType.func], r4k_str_fmt_name[i.FRType.fmt], i.FRType.fs, i.FRType.ft); } else { db_printf(state, "%s.%s\t\t$f%d,$f%d,$f%d", r4k_str_cop1_name[i.FRType.func], r4k_str_fmt_name[i.FRType.fmt], i.FRType.fd, i.FRType.fs, i.FRType.ft); } } break; case OP_J: case OP_JAL: db_printf(state, "%-16s", r4k_str_op_name[i.JType.op]); print_addr(state, (loc & 0xF0000000) | (i.JType.target << 2)); break; case OP_LDC1: case OP_LWC1: case OP_SWC1: case OP_SDC1: db_printf(state, "%-16s$f%d,", r4k_str_op_name[i.IType.op], i.IType.rt); goto loadstore; case OP_LB: case OP_LH: case OP_LW: case OP_LWL: case OP_LWR: case OP_LD: case OP_LBU: case OP_LHU: case OP_LWU: case OP_SB: case OP_SH: case OP_SW: case OP_SWL: case OP_SWR: case OP_SD: db_printf(state, "%-16s%s,", r4k_str_op_name[i.IType.op], r4k_str_reg_name[i.IType.rt]); loadstore: /* Part of a relocation? */ if( (rel = lookup_rel_lo16(state, loc)) ) { /* Yes. */ db_printf(state, "%%lo(%s)(%s)", rel, r4k_str_reg_name[i.IType.rs] ); break; } db_printf(state, "%d(%s)", (short)i.IType.imm, r4k_str_reg_name[i.IType.rs]); break; case OP_ORI: case OP_XORI: if( i.IType.op == OP_ORI ) { /* Part of a relocation? */ if( (rel = lookup_rel_lo16(state, loc)) ) { /* Yes. */ db_printf(state, "%-16s%s,%s,%%lo(%s)", r4k_str_op_name[i.IType.op], r4k_str_reg_name[i.IType.rt], r4k_str_reg_name[i.IType.rs], rel ); break; } else { db_printf(state, "%-16s%s,%s,0x%x", r4k_str_op_name[i.IType.op], r4k_str_reg_name[i.IType.rt], r4k_str_reg_name[i.IType.rs], i.IType.imm); break; } } else if (i.IType.rs == 0) { db_printf(state, "%-16s%s,0x%x", "li", r4k_str_reg_name[i.IType.rt], i.IType.imm); break; } /* FALLTHROUGH */ case OP_ANDI: db_printf(state, "%-16s%s,%s,0x%x", r4k_str_op_name[i.IType.op], r4k_str_reg_name[i.IType.rt], r4k_str_reg_name[i.IType.rs], i.IType.imm); break; case OP_LUI: { /* Part of a relocation? */ if( (rel = lookup_rel_hi16(state, loc)) ) { /* Yes. */ db_printf(state, "%-16s%s,%%hi(%s)", r4k_str_op_name[i.IType.op], r4k_str_reg_name[i.IType.rt], rel ); } else { db_printf(state, "%-16s%s,0x%x", r4k_str_op_name[i.IType.op], r4k_str_reg_name[i.IType.rt], i.IType.imm); } } break; case OP_CACHE: db_printf(state, "%-16s0x%x,0x%x(%s)", r4k_str_op_name[i.IType.op], i.IType.rt, i.IType.imm, r4k_str_reg_name[i.IType.rs]); break; case OP_ADDI: case OP_DADDI: case OP_ADDIU: case OP_DADDIU: { /* Part of a relocation? */ if( (rel = lookup_rel_lo16(state, loc)) ) { /* Yes. */ db_printf(state, "%-16s%s,%s,%%lo(%s)", r4k_str_op_name[i.IType.op], r4k_str_reg_name[i.IType.rt], r4k_str_reg_name[i.IType.rs], rel ); break; } if (i.IType.rs == 0) { db_printf(state, "%-16s%s,%d", "li", r4k_str_reg_name[i.IType.rt], (short)i.IType.imm); break; } /* FALLTHROUGH */ default: db_printf(state, "%-16s%s,%s,%d", r4k_str_op_name[i.IType.op], r4k_str_reg_name[i.IType.rt], r4k_str_reg_name[i.IType.rs], (short)i.IType.imm); } } /*db_printf(state, "\n");*/ return (loc + 4); } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Global functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* Disassemble an instruction with state */ static int r4k_disassemble ( struct r4k_dis_t * state, uint32_t instruction, uint32_t location, char * dest ) { state->dest = dest; db_disasm_insn( state, instruction, location, 0 ); return state->length; } /* Disassemble an instruction but split the opcode/operands into two char *'s */ static int r4k_disassemble_split ( struct r4k_dis_t * state, uint32_t instruction, uint32_t location, char ** opcode, char ** operands ) { int v, i; char buff[128], * dupd; v = r4k_disassemble( state, instruction, location, buff ); dupd = strdup( buff ); *opcode = &dupd[0]; for( i = 0; buff[i] && buff[i] != ' '; i++ ); dupd[i] = '\0'; for( ; buff[i] && buff[i] == ' '; i++ ); *operands = &dupd[i]; return v; } /* Disassemble an instruction with a blank state but split op/operands */ static int r4k_disassemble_split_quick ( uint32_t instruction, uint32_t location, char ** opcode, char ** operands ) { struct r4k_dis_t state; /* Init state */ memset( &state, 0, sizeof(state) ); /* Perform */ return r4k_disassemble_split( &state, instruction, location, opcode, operands ); } //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=[ DECODE_OP ]=-=-=-=-=-=-=-=-=-=-=-=-=-=-=[// void r4300_decode_op ( uint32_t instr, char * opcode, char * arguments, uint32_t counter ) { char * _op, * _args; _op = NULL; _args = NULL; r4k_disassemble_split_quick( instr, counter, &_op, &_args ); strcpy( opcode, _op ); strcpy( arguments, _args ); free( _op ); } libretro/000700 001750 001750 00000000000 12656647145 013530 5ustar00sergiosergio000000 000000 glide2gl/src/Glide64/DepthBufferRender.h000664 001750 001750 00000004512 12655644434 021106 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** // // Software rendering to N64 depth buffer // Created by Gonetz, Dec 2004 // //**************************************************************** #ifndef DEPTH_BUFFER_RENDER_H #define DEPTH_BUFFER_RENDER_H struct vertexi { int x,y; // Screen position in 16:16 bit fixed point int z; // z value in 16:16 bit fixed point }; extern uint16_t * zLUT; void ZLUT_init(void); void ZLUT_release(void); void Rasterize(struct vertexi * vtx, int vertices, int dzdx); #endif //DEPTH_BUFFER_RENDER_H gles2n64/src/3DMathNeon.c000664 001750 001750 00000013122 12655644434 016115 0ustar00sergiosergio000000 000000 #if defined(__ARCH_ARM) || defined(__ARM_EABI__) || defined(HAVE_NEON) #include "3DMath.h" static void MultMatrix_neon( float m0[4][4], float m1[4][4], float dest[4][4]) { __asm( "vld1.32 {d0, d1}, [%1]! \n\t" //q0 = m1 "vld1.32 {d2, d3}, [%1]! \n\t" //q1 = m1+4 "vld1.32 {d4, d5}, [%1]! \n\t" //q2 = m1+8 "vld1.32 {d6, d7}, [%1] \n\t" //q3 = m1+12 "vld1.32 {d16, d17}, [%0]! \n\t" //q8 = m0 "vld1.32 {d18, d19}, [%0]! \n\t" //q9 = m0+4 "vld1.32 {d20, d21}, [%0]! \n\t" //q10 = m0+8 "vld1.32 {d22, d23}, [%0] \n\t" //q11 = m0+12 "vmul.f32 q12, q8, d0[0] \n\t" //q12 = q8 * d0[0] "vmul.f32 q13, q8, d2[0] \n\t" //q13 = q8 * d2[0] "vmul.f32 q14, q8, d4[0] \n\t" //q14 = q8 * d4[0] "vmul.f32 q15, q8, d6[0] \n\t" //q15 = q8 * d6[0] "vmla.f32 q12, q9, d0[1] \n\t" //q12 = q9 * d0[1] "vmla.f32 q13, q9, d2[1] \n\t" //q13 = q9 * d2[1] "vmla.f32 q14, q9, d4[1] \n\t" //q14 = q9 * d4[1] "vmla.f32 q15, q9, d6[1] \n\t" //q15 = q9 * d6[1] "vmla.f32 q12, q10, d1[0] \n\t" //q12 = q10 * d0[0] "vmla.f32 q13, q10, d3[0] \n\t" //q13 = q10 * d2[0] "vmla.f32 q14, q10, d5[0] \n\t" //q14 = q10 * d4[0] "vmla.f32 q15, q10, d7[0] \n\t" //q15 = q10 * d6[0] "vmla.f32 q12, q11, d1[1] \n\t" //q12 = q11 * d0[1] "vmla.f32 q13, q11, d3[1] \n\t" //q13 = q11 * d2[1] "vmla.f32 q14, q11, d5[1] \n\t" //q14 = q11 * d4[1] "vmla.f32 q15, q11, d7[1] \n\t" //q15 = q11 * d6[1] "vst1.32 {d24, d25}, [%2]! \n\t" //d = q12 "vst1.32 {d26, d27}, [%2]! \n\t" //d+4 = q13 "vst1.32 {d28, d29}, [%2]! \n\t" //d+8 = q14 "vst1.32 {d30, d31}, [%2] \n\t" //d+12 = q15 :"+r"(m0), "+r"(m1), "+r"(dest): : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", "memory" ); } static void TransformVectorNormalize_neon(float vec[3], float mtx[4][4]) { __asm( "vld1.32 {d0}, [%1] \n\t" //Q0 = v "flds s2, [%1, #8] \n\t" //Q0 = v "vld1.32 {d18, d19}, [%0]! \n\t" //Q1 = m "vld1.32 {d20, d21}, [%0]! \n\t" //Q2 = m+4 "vld1.32 {d22, d23}, [%0] \n\t" //Q3 = m+8 "vmul.f32 q2, q9, d0[0] \n\t" //q2 = q9*Q0[0] "vmla.f32 q2, q10, d0[1] \n\t" //Q5 += Q1*Q0[1] "vmla.f32 q2, q11, d1[0] \n\t" //Q5 += Q2*Q0[2] "vmul.f32 d0, d4, d4 \n\t" //d0 = d0*d0 "vpadd.f32 d0, d0, d0 \n\t" //d0 = d[0] + d[1] "vmla.f32 d0, d5, d5 \n\t" //d0 = d0 + d1*d1 "vmov.f32 d1, d0 \n\t" //d1 = d0 "vrsqrte.f32 d0, d0 \n\t" //d0 = ~ 1.0 / sqrt(d0) "vmul.f32 d2, d0, d1 \n\t" //d2 = d0 * d1 "vrsqrts.f32 d3, d2, d0 \n\t" //d3 = (3 - d0 * d2) / 2 "vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d3 "vmul.f32 d2, d0, d1 \n\t" //d2 = d0 * d1 "vrsqrts.f32 d3, d2, d0 \n\t" //d3 = (3 - d0 * d3) / 2 "vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d4 "vmul.f32 q2, q2, d0[0] \n\t" //d0= d2*d4 "vst1.32 {d4}, [%1] \n\t" //Q4 = m+12 "fsts s10, [%1, #8] \n\t" //Q4 = m+12 : "+r"(mtx): "r"(vec) : "d0","d1","d2","d3","d18","d19","d20","d21","d22", "d23", "memory" ); } static void Normalize_neon(float v[3]) { __asm( "vld1.32 {d4}, [%0]! \n\t" //d4={x,y} "flds s10, [%0] \n\t" //d5[0] = z "sub %0, %0, #8 \n\t" //d5[0] = z "vmul.f32 d0, d4, d4 \n\t" //d0= d4*d4 "vpadd.f32 d0, d0, d0 \n\t" //d0 = d[0] + d[1] "vmla.f32 d0, d5, d5 \n\t" //d0 = d0 + d5*d5 "vmov.f32 d1, d0 \n\t" //d1 = d0 "vrsqrte.f32 d0, d0 \n\t" //d0 = ~ 1.0 / sqrt(d0) "vmul.f32 d2, d0, d1 \n\t" //d2 = d0 * d1 "vrsqrts.f32 d3, d2, d0 \n\t" //d3 = (3 - d0 * d2) / 2 "vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d3 "vmul.f32 d2, d0, d1 \n\t" //d2 = d0 * d1 "vrsqrts.f32 d3, d2, d0 \n\t" //d3 = (3 - d0 * d3) / 2 "vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d4 "vmul.f32 q2, q2, d0[0] \n\t" //d0= d2*d4 "vst1.32 {d4}, [%0]! \n\t" //d2={x0,y0}, d3={z0, w0} "fsts s10, [%0] \n\t" //d2={x0,y0}, d3={z0, w0} :"+r"(v) : : "d0", "d1", "d2", "d3", "d4", "d5", "memory" ); } static float DotProduct_neon( float v0[3], float v1[3] ) { float dot; __asm( "vld1.32 {d8}, [%1]! \n\t" //d8={x0,y0} "vld1.32 {d10}, [%2]! \n\t" //d10={x1,y1} "flds s18, [%1, #0] \n\t" //d9[0]={z0} "flds s22, [%2, #0] \n\t" //d11[0]={z1} "vmul.f32 d12, d8, d10 \n\t" //d0= d2*d4 "vpadd.f32 d12, d12, d12 \n\t" //d0 = d[0] + d[1] "vmla.f32 d12, d9, d11 \n\t" //d0 = d0 + d3*d5 "fmrs %0, s24 \n\t" //r0 = s0 : "=r"(dot), "+r"(v0), "+r"(v1): : "d8", "d9", "d10", "d11", "d12" ); return dot; } void MathInitNeon(void) { MultMatrix = MultMatrix_neon; TransformVectorNormalize = TransformVectorNormalize_neon; Normalize = Normalize_neon; DotProduct = DotProduct_neon; } #endif mupen64plus-core/src/plugin/get_time_using_C_localtime.h000664 001750 001750 00000003273 12655644434 024607 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - get_time_using_C_localtime.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_PLUGIN_GET_TIME_USING_C_LOCALTIME_H #define M64P_PLUGIN_GET_TIME_USING_C_LOCALTIME_H struct tm; const struct tm* get_time_using_C_localtime(void* user_data); #endif mupen64plus-rsp-hle/src/hle_external.h000664 001750 001750 00000004052 12655644434 021104 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-rsp-hle - hle_external.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef HLE_EXTERNAL_H #define HLE_EXTERNAL_H /* users of the hle core are expected to define these functions */ void HleVerboseMessage(void* user_defined, const char *message, ...); void HleErrorMessage(void* user_defined, const char *message, ...); void HleWarnMessage(void* user_defined, const char *message, ...); void HleCheckInterrupts(void* user_defined); void HleProcessDlistList(void* user_defined); void HleProcessAlistList(void* user_defined); void HleProcessRdpList(void* user_defined); void HleShowCFB(void* user_defined); #endif glide2gl/src/Glide64/DepthBufferRender.c000664 001750 001750 00000021656 12655644434 021111 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** // // Software rendering into N64 depth buffer // Idea and N64 depth value format by Orkin // Polygon rasterization algorithm is taken from FATMAP2 engine by Mats Byggmastar, mri@penti.sit.fi // // Created by Gonetz, Dec 2004 // //**************************************************************** #include "Gfx_1.3.h" #include "rdp.h" #include "DepthBufferRender.h" uint16_t *zLUT; #define ZLUT_SIZE 0x40000 void ZLUT_init(void) { int i; if (zLUT) return; zLUT = (uint16_t*)malloc(ZLUT_SIZE * sizeof(uint16_t)); for(i = 0; i< ZLUT_SIZE; i++) { uint32_t exponent, testbit, mantissa; exponent = 0; testbit = 1 << 17; while((i & testbit) && (exponent < 7)) { exponent++; testbit = 1 << (17 - exponent); } mantissa = (i >> (6 - (6 < exponent ? 6 : exponent))) & 0x7ff; zLUT[i] = (uint16_t)(((exponent << 11) | mantissa) << 2); } } void ZLUT_release(void) { if (zLUT) free(zLUT); zLUT = 0; } static struct vertexi *max_vtx; // Max y vertex (ending vertex) static struct vertexi *start_vtx, *end_vtx; // First and last vertex in array static struct vertexi *right_vtx, *left_vtx; // Current right and left vertex static int right_height, left_height; static int right_x, right_dxdy, left_x, left_dxdy; static int left_z, left_dzdy; // (x * y) >> 16 #define imul16(x, y) ((((long long)x) * ((long long)y)) >> 16) // (x * y) >> 14 #define imul14(x, y) ((((long long)x) * ((long long)y)) >> 14) static INLINE int idiv16(int x, int y) { const int64_t m = (int64_t)(x); const int64_t n = (int64_t)(y); int64_t result = (m << 16) / n; return (int)(result); } static INLINE int iceil(int x) { return ((x + 0xffff) >> 16); } static void RightSection(void) { int prestep; // Walk backwards trough the vertex array struct vertexi *v1 = (struct vertexi*)right_vtx; struct vertexi *v2 = end_vtx; // Wrap to end of array if(right_vtx > start_vtx) v2 = right_vtx-1; right_vtx = v2; // v1 = top vertex // v2 = bottom vertex // Calculate number of scanlines in this section right_height = iceil(v2->y) - iceil(v1->y); if(right_height <= 0) return; // Guard against possible div overflows if(right_height > 1) { // OK, no worries, we have a section that is at least // one pixel high. Calculate slope as usual. int height = v2->y - v1->y; right_dxdy = idiv16(v2->x - v1->x, height); } else { // Height is less or equal to one pixel. // Calculate slope = width * 1/height // using 18:14 bit precision to avoid overflows. int inv_height = (0x10000 << 14) / (v2->y - v1->y); right_dxdy = imul14(v2->x - v1->x, inv_height); } // Prestep initial values prestep = (iceil(v1->y) << 16) - v1->y; right_x = v1->x + imul16(prestep, right_dxdy); } static void LeftSection(void) { int prestep; // Walk forward through the vertex array struct vertexi *v1 = (struct vertexi*)left_vtx; struct vertexi *v2 = start_vtx; // Wrap to start of array if(left_vtx < end_vtx) v2 = left_vtx+1; left_vtx = v2; // v1 = top vertex // v2 = bottom vertex // Calculate number of scanlines in this section left_height = iceil(v2->y) - iceil(v1->y); if(left_height <= 0) return; // Guard against possible div overflows if(left_height > 1) { // OK, no worries, we have a section that is at least // one pixel high. Calculate slope as usual. int height = v2->y - v1->y; left_dxdy = idiv16(v2->x - v1->x, height); left_dzdy = idiv16(v2->z - v1->z, height); } else { // Height is less or equal to one pixel. // Calculate slope = width * 1/height // using 18:14 bit precision to avoid overflows. int inv_height = (0x10000 << 14) / (v2->y - v1->y); left_dxdy = imul14(v2->x - v1->x, inv_height); left_dzdy = imul14(v2->z - v1->z, inv_height); } // Prestep initial values prestep = (iceil(v1->y) << 16) - v1->y; left_x = v1->x + imul16(prestep, left_dxdy); left_z = v1->z + imul16(prestep, left_dzdy); } void Rasterize(struct vertexi * vtx, int vertices, int dzdx) { int n, min_y, max_y, y1, shift; uint16_t *destptr; struct vertexi *min_vtx; start_vtx = vtx; // First vertex in array // Search trough the vtx array to find min y, max y // and the location of these structures. min_vtx = (struct vertexi*)vtx; max_vtx = vtx; min_y = vtx->y; max_y = vtx->y; vtx++; for (n = 1; n < vertices; n++) { if(vtx->y < min_y) { min_y = vtx->y; min_vtx = vtx; } else if(vtx->y > max_y) { max_y = vtx->y; max_vtx = vtx; } vtx++; } // OK, now we know where in the array we should start and // where to end while scanning the edges of the polygon left_vtx = min_vtx; // Left side starting vertex right_vtx = min_vtx; // Right side starting vertex end_vtx = vtx-1; // Last vertex in array // Search for the first usable right section do { if(right_vtx == max_vtx) return; RightSection(); } while(right_height <= 0); // Search for the first usable left section do { if(left_vtx == max_vtx) return; LeftSection(); } while(left_height <= 0); destptr = (uint16_t*)(gfx_info.RDRAM + g_gdp.zb_address); y1 = iceil(min_y); if (y1 >= g_gdp.__clip.yl) return; for(;;) { int width; int x1 = iceil(left_x); if (x1 < g_gdp.__clip.xh) x1 = g_gdp.__clip.xh; width = iceil(right_x) - x1; if (x1+width >= g_gdp.__clip.xl) width = g_gdp.__clip.xl - x1 - 1; if(width > 0 && y1 >= g_gdp.__clip.yh) { unsigned x; // Prestep initial z int prestep = (x1 << 16) - left_x; int z = left_z + imul16(prestep, dzdx); shift = x1 + y1 * rdp.zi_width; //draw to depth buffer for (x = 0; x < width; x++) { int idx; uint16_t encodedZ; int trueZ = z / 8192; if (trueZ < 0) trueZ = 0; else if (trueZ > 0x3FFFF) trueZ = 0x3FFFF; encodedZ = zLUT[trueZ]; idx = (shift+x)^1; if(encodedZ < destptr[idx]) destptr[idx] = encodedZ; z += dzdx; } } y1++; if (y1 >= g_gdp.__clip.yl) return; // Scan the right side if(--right_height <= 0) // End of this section? { do { if(right_vtx == max_vtx) return; RightSection(); } while(right_height <= 0); } else right_x += right_dxdy; // Scan the left side if(--left_height <= 0) // End of this section ? { do { if(left_vtx == max_vtx) return; LeftSection(); } while(left_height <= 0); } else { left_x += left_dxdy; left_z += left_dzdy; } } } mupen64plus-core/src/rdp_common/gdp.h000664 001750 001750 00000031314 12655644434 020720 0ustar00sergiosergio000000 000000 #ifndef _RDP_GDP_H #define _RDP_GDP_H #include #ifndef DP_INTERRUPT #define DP_INTERRUPT 0x20 #endif /* Useful macros for decoding GBI command's parameters */ #ifndef _SHIFTL #define _SHIFTL( v, s, w ) (((uint32_t)v & ((0x01 << w) - 1)) << s) #endif #ifndef _SHIFTR #define _SHIFTR( v, s, w ) (((uint32_t)v >> s) & ((0x01 << w) - 1)) #endif #ifndef SRA #define SRA(exp, sa) ((signed)(exp) >> (sa)) #endif #ifndef SIGN #define SIGN(i, b) SRA((i) << (32 - (b)), (32 - (b))) #endif #ifndef GET_LOW #define GET_LOW(x) (((x) & 0x003E) << 2) #endif #ifndef GET_MED #define GET_MED(x) (((x) & 0x07C0) >> 3) #endif #ifndef GET_HI #define GET_HI(x) (((x) >> 8) & 0x00F8) #endif /* Update flags */ #define UPDATE_ZBUF_ENABLED 0x00000001 #define UPDATE_TEXTURE 0x00000002 /* Same thing */ #define UPDATE_COMBINE 0x00000002 /* Same thing */ #define UPDATE_CULL_MODE 0x00000004 #define UPDATE_LIGHTS 0x00000010 #define UPDATE_BIASLEVEL 0x00000020 #define UPDATE_ALPHA_COMPARE 0x00000040 #define UPDATE_VIEWPORT 0x00000080 #define UPDATE_MULT_MAT 0x00000100 #define UPDATE_SCISSOR 0x00000200 #define UPDATE_FOG_ENABLED 0x00010000 #ifdef __cplusplus extern "C" { #endif typedef struct { uint32_t total; uint32_t z; uint16_t dz; int32_t r, g, b, a, l; } gdp_color; typedef struct { int32_t xl, yl, xh, yh; } gdp_rectangle; typedef struct { int32_t clampdiffs, clampdifft; int32_t clampens, clampent; int32_t masksclamped, masktclamped; int32_t notlutswitch, tlutswitch; } gdp_faketile; typedef struct { int32_t format; /* Controls the output format of the rasterized image: 000 - RGBA 001 - YUV 010 - Color Index 011 - Intensity Alpha 011 - Intensity */ int32_t size; /* Size of an individual pixel in terms of bits: 00 - 4 bits 01 - 8 bits (Color Index) 10 - 16 bits (RGBA) 11 - 32 bits (RGBA) */ int32_t line; /* size of one row (x axis) in 64 bit words */ int32_t tmem; /* location in texture memory (in 64 bit words, max 512 (4MB)) */ int32_t palette; /* palette # to use */ int32_t ct; /* clamp_t - Enable clamping in the T direction when texturing primitives. */ int32_t mt; /* mirror_t - Enable mirroring in the T direction when texturing primitives.*/ int32_t cs; /* clamp_s - Enable clamping in the S direction when texturing primitives.*/ int32_t ms; /* mirror_s - Enable mirroring in the T direction when texturing primitives.*/ int32_t mask_t; /* mask to wrap around (y axis) */ int32_t shift_t; /* level of detail shifting in the t direction (scaling) */ int32_t mask_s; /* mask to wrap around (x axis) */ int32_t shift_s; /* level of detail shift in the s direction (scaling) */ int32_t sl; /* lr_s - Lower right s coordinate (10.5 fixed point format) */ int32_t tl; /* lr_t - Lower right t coordinate (10.5 fixed point format) */ int32_t sh; /* ul_s - Upper left s coordinate (10.5 fixed point format) */ int32_t th; /* ul_t - Upper left t coordinate (10.5 fixed point format) */ gdp_faketile f; } gdp_tile; typedef struct { int32_t sub_a_rgb0; /* c_a0 */ int32_t sub_b_rgb0; /* c_b0 */ int32_t mul_rgb0; /* c_c0 */ int32_t add_rgb0; /* c_d0 */ int32_t sub_a_a0; /* c_Aa0 */ int32_t sub_b_a0; /* c_Ab0 */ int32_t mul_a0; /* c_Ac0 */ int32_t add_a0; /* c_Ad0 */ int32_t sub_a_rgb1; /* c_a1 */ int32_t sub_b_rgb1; /* c_b1 */ int32_t mul_rgb1; /* c_c1 */ int32_t add_rgb1; /* c_d1 */ int32_t sub_a_a1; /* c_Aa1 */ int32_t sub_b_a1; /* c_Ab1 */ int32_t mul_a1; /* c_Ac1 */ int32_t add_a1; /* c_Ad1 */ } gdp_combine_modes; typedef struct { int stalederivs; int dolod; int partialreject_1cycle; int partialreject_2cycle; int special_bsel0; int special_bsel1; int rgb_alpha_dither; } GDP_MODEDERIVS; typedef struct { #if 0 int atomic_primitive_enable; /* Force primitive to be written to the framebuffer before processing next primitive. */ #endif int cycle_type; /* Pipeline rasterization mode: 00 - 1 Cycle 01 - 2 Cycle 10 - Copy 11 - Fill */ int persp_tex_en; /* Enable perspective correction on textures. */ int detail_tex_en; /* Enable detail texture. */ int sharpen_tex_en; /* Enable sharpen texture. */ int tex_lod_en; /* Enable texture level of detail (mipmapping). */ int en_tlut; /* Enable texture lookup table. This is useful when textures are color mapped but the desired output to the frame buffer is RGB. */ int tlut_type; /* Type of texels (texture color values) in TLUT table: 0 - 16 bit RGBA (0bRRRRRGGGGGBBBBBA) 1 - 16 bit IA (0xIIAA) */ int sample_type; /* Type of texture sampling: 0 - 1x1 (point sample) 1 - 2x2 */ int mid_texel; /* Enable 2x2 half-texel sampling for texture filter. */ int bi_lerp0; /* Enables bilinear interpolation for cycle 0 when 1 Cycle or 2 Cycle mode is enabled. */ int bi_lerp1; /* Enables bilinear interpolation for cycle 1 when 1 Cycle or 2 Cycle mode is enabled. */ int convert_one; /* Color convert the texel outputted by the texture filter on cycle 0. */ int key_en; /* Enable chroma keying. */ int rgb_dither_sel; /* Type of dithering is done to RGB values in 1 Cycle or 2 Cycle modes: 00 - Magic square matrix 01 - Bayer matrix 10 - Noise 11 - No dither */ int alpha_dither_sel; /* Type of dithering done to alpha values in 1 Cycle or 2 Cycle modes: 00 - Pattern 01 - ~Pattern 10 - Noise 11 - No dither */ int blend_m1a_0; /* Multiply blend 1a input in cycle 0. */ int blend_m1a_1; /* Multiply blend 1a input in cycle 1. */ int blend_m1b_0; /* Multiply blend 1b input in cycle 0. */ int blend_m1b_1; /* Multiply blend 1b input in cycle 1. */ int blend_m2a_0; /* Multiply blend 2a input in cycle 0. */ int blend_m2a_1; /* Multiply blend 2a input in cycle 1. */ int blend_m2b_0; /* Multiply blend 2b input in cycle 0. */ int blend_m2b_1; /* Multiply blend 2b input in cycle 1. */ int force_blend; /* Enable force blend. */ int alpha_cvg_select; /* Enable use of coverage bits in alpha calculation. */ int cvg_times_alpha; /* Enable multiplying coverage bits by alpha value for final pixel alpha: 0 - Alpha = CVG 1 - Alpha = CVG * A */ int z_mode; /* Mode select for Z buffer: 00 - Opaque 01 - Interpenetrating 10 - Transparent 11 - Decal */ int cvg_dest; /* Mode select for handling coverage values: 00 - Clamp 01 - Wrap 10 - Force to full coverage 11 - Don't write back */ int color_on_cvg; /* Only update color on coverage overflow. Useful for transparent surfaces. */ int image_read_en; /* Enable coverage read/modify/write access to frame buffer. */ int z_update_en; /* Enable writing new Z value if color write is enabled. */ int z_compare_en; /* Enable conditional color write based on depth comparison. */ int antialias_en; /* Enable anti-aliasing based on coverage bits if force blend is not enabled. */ int z_source_sel; /* Select the source of the Z value: 0 - Pixel Z 1 - Primitive Z */ int dither_alpha_en; /* Select source for alpha compare: 0 - Random noise 1 - Blend alpha */ int alpha_compare_en; /* Enable conditional color write based on alpha compare. */ GDP_MODEDERIVS f; } gdp_other_modes; struct gdp_global { uint32_t flags; int32_t ti_format; /* format: ARGB, IA, ... */ int32_t ti_size; /* size: 4, 8, 16, or 32-bit */ int32_t ti_width; /* used in rdp_settextureimage */ uint32_t ti_address; /* address in RDRAM to load the texture from */ int32_t primitive_lod_min; int32_t primitive_lod_frac; int32_t lod_frac; gdp_color texel0_color; gdp_color texel1_color; gdp_color combined_color; gdp_color prim_color; gdp_color fill_color; gdp_color blend_color; gdp_color fog_color; gdp_color env_color; gdp_color key_width; gdp_color key_scale; gdp_color key_center; int32_t k0, k1, k2, k3, k4, k5; gdp_tile tile[8]; gdp_combine_modes combine; gdp_other_modes other_modes; gdp_rectangle __clip; int scfield; int sckeepodd; uint8_t tmem[0x1000]; uint32_t zb_address; int32_t fb_format; int32_t fb_size; int32_t fb_width; uint32_t fb_address; }; static INLINE void gdp_calculate_clamp_diffs(struct gdp_global *g_gdp, uint32_t i) { g_gdp->tile[i].f.clampdiffs = ((g_gdp->tile[i].sh >> 2) - (g_gdp->tile[i].sl >> 2)) & 0x3ff; g_gdp->tile[i].f.clampdifft = ((g_gdp->tile[i].th >> 2) - (g_gdp->tile[i].tl >> 2)) & 0x3ff; } void gdp_set_prim_color(uint32_t w0, uint32_t w1); void gdp_set_prim_depth(uint32_t w0, uint32_t w1); void gdp_set_env_color(uint32_t w0, uint32_t w1); void gdp_set_fill_color(uint32_t w0, uint32_t w1); void gdp_set_fog_color(uint32_t w0, uint32_t w1); void gdp_set_blend_color(uint32_t w0, uint32_t w1); void gdp_set_convert(uint32_t w0, uint32_t w1); void gdp_set_key_r(uint32_t w0, uint32_t w1); void gdp_set_key_gb(uint32_t w0, uint32_t w1); int32_t gdp_set_tile(uint32_t w0, uint32_t w1); int32_t gdp_set_tile_size_wrap(uint32_t w0, uint32_t w1); void gdp_set_tile_size(uint32_t w0, uint32_t w1); void gdp_set_combine(uint32_t w0, uint32_t w1); void gdp_set_texture_image(uint32_t w0, uint32_t w1); void gdp_set_scissor(uint32_t w0, uint32_t w1); void gdp_set_other_modes(uint32_t w0, uint32_t w1); void gdp_full_sync(uint32_t w0, uint32_t w1); void gdp_pipe_sync(uint32_t w0, uint32_t w1); void gdp_tile_sync(uint32_t w0, uint32_t w1); void gdp_load_sync(uint32_t w0, uint32_t w1); void gdp_no_op(uint32_t w0, uint32_t w1); void gdp_invalid(uint32_t w0, uint32_t w1); void gdp_set_mask_image(uint32_t w0, uint32_t w1); void gdp_set_color_image(uint32_t w0, uint32_t w1); extern struct gdp_global g_gdp; #ifdef __cplusplus } #endif #endif mupen64plus-core/src/plugin/get_time_using_C_localtime.c000664 001750 001750 00000003334 12655644434 024600 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - get_time_using_C_localtime.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "get_time_using_C_localtime.h" #include const struct tm* get_time_using_C_localtime(void* user_data) { time_t current_time; time(¤t_time); return localtime(¤t_time); } mupen64plus-core/LICENSES000664 001750 001750 00000003647 12655644434 016211 0ustar00sergiosergio000000 000000 Mupen64Plus-Core LICENSES ------------------------- Mupen64Plus-Core is licensed under the GNU General Public License version 2. Please see the included doc/gpl-license file for the terms and conditions of the GNU General Public License. The authors of Mupen64Plus are: * Richard Goedeken (Richard42) * John Chadwick (NMN) * James Hood (Ebenblues) * Scott Gorman (okaygo) * Scott Knauert (Tillin9) * Jesse Dean (DarkJezter) * Louai Al-Khanji (slougi) * Bob Forder (orbitaldecay) * Jason Espinosa (hasone) * HyperHacker * and others. The Mupen64Plus API documentation (located in doc/emuwiki-api-doc/*) is Copyright(C) 2009-2011 by Richard Goedeken and is licensed under the GNU General Public License version 2. Mupen64Plus is based on GPL-licensed source code from Mupen64 v0.5, originally written by: * Hacktarux * Dave2001 * Zilmar * Gregor Anich (Blight) * Juha Luotio (JttL) * and others. The OGLFT library used for the On-Screen Display is based on GPL/LGPL-licensed code Copyright 2002 lignum Computing. Please see the included doc/lgpl-license file for the terms and conditions of the GNU Lesser General Public License. More information about this library is available at the following websites: - http://oglft.sourceforge.net/index.html - http://directory.fsf.org/project/OGLFT/ Additionally, mupen includes a number of components licensed under other OSI approved licenses: The BSD license: * minizip by Gilles Vollant and others, ftp://ftp.info-zip.org/pub/infozip/license.html * src/memory/n64_cic_nus_6105.c/.h, by X-Scale The zlib/libpng license: * Adler-32 by Mark Adler * libpng by Glenn Randers-Pehrson, Peter Deutsch, and Guy Eric Schalnat * MD5 hasing code by Peter Deutsch The Bitstream license: * The TrueType font (data/font.ttf) is licensed by the Bitstream license. Please see the included doc/font-license file for the terms and conditions of the Bitstream license. mupen64plus-core/src/dd/dd_disk.h000664 001750 001750 00000004477 12655644434 020013 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - dd_disk.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2015 LuigiBlood * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef __DDDISK_H__ #define __DDDISK_H__ #include #include "api/m64p_types.h" #define SECTORS_PER_BLOCK 85 #define BLOCKS_PER_TRACK 2 extern int dd_bm_mode_read; //BM MODE 0 = WRITE, MODE 1 = READ extern int CUR_BLOCK; //Current Block extern int dd_sector55; struct dd_disk { uint8_t* disk; size_t disk_size; }; void connect_dd_disk(struct dd_disk* dd_disk, uint8_t* disk, size_t disk_size); /* Disk Loading and Saving functions */ m64p_error open_dd_disk(const unsigned char* diskimage, unsigned int size); m64p_error close_dd_disk(void); extern unsigned char* g_dd_disk; extern int g_dd_disk_size; /* Disk Read / Write functions */ void dd_set_zone_and_track_offset(void *data); void dd_update_bm(void *data); void dd_write_sector(void *data); void dd_read_sector(void *data); #endif mupen64plus-core/src/rdp_common/gdp.c000664 001750 001750 00000040462 12655644434 020717 0ustar00sergiosergio000000 000000 #include "gdp.h" #include "../plugin/plugin.h" struct gdp_global g_gdp; void gdp_set_texture_image(uint32_t w0, uint32_t w1) { g_gdp.ti_format = (w0 & 0x00E00000) >> (53 - 32); g_gdp.ti_size = (w0 & 0x00180000) >> (51 - 32); g_gdp.ti_width = (w0 & 0x000003FF) >> (32 - 32); g_gdp.ti_address = (w1 & 0x03FFFFFF) >> ( 0 - 0); /* g_gdp.ti_address &= 0x00FFFFFF; // physical memory limit, enforced later */ ++g_gdp.ti_width; g_gdp.flags |= UPDATE_TEXTURE; } void gdp_set_prim_color(uint32_t w0, uint32_t w1) { g_gdp.prim_color.total = w1; g_gdp.prim_color.r = (w1 & 0xFF000000) >> 24; g_gdp.prim_color.g = (w1 & 0x00FF0000) >> 16; g_gdp.prim_color.b = (w1 & 0x0000FF00) >> 8; g_gdp.prim_color.a = (w1 & 0x000000FF) >> 0; /* Level of Detail fraction for primitive, used primarily * in multi-tile operations for rectangle primitives. */ g_gdp.primitive_lod_frac = (w0 & 0x000000FF) >> (32-32); /* Minimum clamp for LOD fraction when in detail or sharpen * texture modes, fixed point 0.5. */ g_gdp.primitive_lod_min = (w0 & 0x00001F00) >> (40-32); g_gdp.flags |= UPDATE_COMBINE; } void gdp_set_env_color(uint32_t w0, uint32_t w1) { g_gdp.env_color.total = w1; g_gdp.env_color.r = (w1 & 0xFF000000) >> 24; g_gdp.env_color.g = (w1 & 0x00FF0000) >> 16; g_gdp.env_color.b = (w1 & 0x0000FF00) >> 8; g_gdp.env_color.a = (w1 & 0x000000FF) >> 0; g_gdp.flags |= UPDATE_COMBINE; } void gdp_set_prim_depth(uint32_t w0, uint32_t w1) { g_gdp.prim_color.z = (w1 & 0xFFFF0000) >> 16; g_gdp.prim_color.dz = (w1 & 0x0000FFFF) >> 0; } void gdp_set_fog_color(uint32_t w0, uint32_t w1) { g_gdp.fog_color.total = w1; g_gdp.fog_color.r = (w1 & 0xFF000000) >> 24; g_gdp.fog_color.g = (w1 & 0x00FF0000) >> 16; g_gdp.fog_color.b = (w1 & 0x0000FF00) >> 8; g_gdp.fog_color.a = (w1 & 0x000000FF) >> 0; g_gdp.flags |= UPDATE_COMBINE; } void gdp_set_blend_color(uint32_t w0, uint32_t w1) { g_gdp.blend_color.total = w1; g_gdp.blend_color.r = (w1 & 0xFF000000) >> 24; g_gdp.blend_color.g = (w1 & 0x00FF0000) >> 16; g_gdp.blend_color.b = (w1 & 0x0000FF00) >> 8; g_gdp.blend_color.a = (w1 & 0x000000FF) >> 0; g_gdp.flags |= UPDATE_COMBINE; } void gdp_set_fill_color(uint32_t w0, uint32_t w1) { g_gdp.fill_color.total = w1; g_gdp.fill_color.r = (w1 & 0xFF000000) >> 24; g_gdp.fill_color.g = (w1 & 0x00FF0000) >> 16; g_gdp.fill_color.b = (w1 & 0x0000FF00) >> 8; g_gdp.fill_color.a = (w1 & 0x000000FF) >> 0; g_gdp.fill_color.z = _SHIFTR( w1, 2, 14 ); g_gdp.fill_color.dz = _SHIFTR( w1, 0, 2 ); g_gdp.flags |= UPDATE_ALPHA_COMPARE | UPDATE_COMBINE; } /* This command updates the coefficients for converting YUV * pixels to RGB. */ void gdp_set_convert(uint32_t w0, uint32_t w1) { const uint64_t fifo_word = ((uint64_t)w0 << 32) | ((uint64_t)w1 << 0); /* K0 term of YUV-RGB conversion matrix. */ g_gdp.k0 = (fifo_word >> 45) & 0x1FF; /* K1 term of YUV-RGB conversion matrix. */ g_gdp.k1 = (fifo_word >> 36) & 0x1FF; /* K2 term of YUV-RGB conversion matrix. */ g_gdp.k2 = (fifo_word >> 27) & 0x1FF; /* K3 term of YUV-RGB conversion matrix. */ g_gdp.k3 = (fifo_word >> 18) & 0x1FF; /* K4 term of YUV-RGB conversion matrix. */ g_gdp.k4 = (fifo_word >> 9) & 0x1FF; /* K5 term of YUV-RGB conversion matrix. */ g_gdp.k5 = (fifo_word >> 0) & 0x1FF; /* * All the graphics plugins emulating the RDP need to process k0, k1, k2, k3 * as 9-bit sign-extended integers. Especially with angrylion's plugin, we * can save on constantly sign-extending k0-k3 at the ninth bit by doing it * right now, as only in this function do those values ever get updated. */ g_gdp.k0 = SIGN(g_gdp.k0, 9); g_gdp.k1 = SIGN(g_gdp.k1, 9); g_gdp.k2 = SIGN(g_gdp.k2, 9); g_gdp.k3 = SIGN(g_gdp.k3, 9); } void gdp_set_key_gb(uint32_t w0, uint32_t w1) { g_gdp.key_scale.total = (g_gdp.key_scale.total & 0xFF0000FF) | (((w1 >> 16) & 0xFF) << 16) | (((w1 & 0xFF)) << 8); g_gdp.key_center.total = (g_gdp.key_center.total & 0xFF0000FF) | (((w1 >> 24) & 0xFF) << 16) | (((w1 >> 8) & 0xFF) << 8); g_gdp.key_width.g = (w0 & 0x00FFF000) >> 12; g_gdp.key_width.b = (w0 & 0x00000FFF) >> 0; g_gdp.key_center.g = (w1 & 0xFF000000) >> 24; g_gdp.key_scale.g = (w1 & 0x00FF0000) >> 16; g_gdp.key_center.b = (w1 & 0x0000FF00) >> 8; g_gdp.key_scale.b = (w1 & 0x000000FF) >> 0; } /* This command sets the coefficients used for Red keying. */ void gdp_set_key_r(uint32_t w0, uint32_t w1) { g_gdp.key_scale.total = (g_gdp.key_scale.total & 0x00FFFFFF) | ((w1 & 0xFF) << 24); g_gdp.key_center.total = (g_gdp.key_center.total & 0x00FFFFFF) | (((w1 >> 8) & 0xFF) << 24); /* Defines color or intensity at which key is active, 0-255. */ g_gdp.key_center.r = (w1 & 0x0000FF00) >> 8; /* (Size of half the key window including the soft edge) * scale. If width > 1.0, * then keying is disabled for that channel. */ g_gdp.key_width.r = (w1 & 0x0FFF0000) >> 16; /* (1.0 / (size of soft edge). For hard ege keying, set scale to 255. */ g_gdp.key_scale.r = (w1 & 0x000000FF) >> 0; } int32_t gdp_set_tile(uint32_t w0, uint32_t w1) { int32_t tilenum = (w1 & 0x07000000) >> 24; /* Image data format, 0 = RGBA, 1 = YUV, 2 = Color Index, 3 = IA, 4 = I */ g_gdp.tile[tilenum].format = (w0 & 0x00E00000) >> (53 - 32); /* Size of pixel/texel color element, 0 = 4b, 1 = 8b, 2 = 16b, 3 = 32b, 4 = Other */ g_gdp.tile[tilenum].size = (w0 & 0x00180000) >> (51 - 32); /* Size of tile line in 64bit words, max of 4KB. */ g_gdp.tile[tilenum].line = (w0 & 0x0003FE00) >> (41 - 32); /* Starting TMEM address for this tile in words (64bits), 4KB range. */ g_gdp.tile[tilenum].tmem = (w0 & 0x000001FF) >> (32 - 32); /* Palette number for 4b Color Indexed texels. This number is * used as the MS 4b of an 8b index. */ g_gdp.tile[tilenum].palette = (w1 & 0x00F00000) >> (20 - 0); /* Clamp enable for T direction. */ g_gdp.tile[tilenum].ct = (w1 & 0x00080000) >> (19 - 0); /* Mirror enable for T direction. */ g_gdp.tile[tilenum].mt = (w1 & 0x00040000) >> (18 - 0); /* Mask for wrapping/mirroring in T direction. If this field * is zero then clamp, otherwise pass (mask) LSBs of T address. */ g_gdp.tile[tilenum].mask_t = (w1 & 0x0003C000) >> (14 - 0); /* Level of Detail shift for T addresses. */ g_gdp.tile[tilenum].shift_t = (w1 & 0x00003C00) >> (10 - 0); /* Clamp enable bit for S direction. */ g_gdp.tile[tilenum].cs = (w1 & 0x00000200) >> ( 9 - 0); /* Mirror enable bit for S direction. */ g_gdp.tile[tilenum].ms = (w1 & 0x00000100) >> ( 8 - 0); /* Mask for wrapping/mirroring in S direction. If this field is * zero then clamp, otherwise pass (mask) LSBs of S address. */ g_gdp.tile[tilenum].mask_s = (w1 & 0x000000F0) >> ( 4 - 0); /* Level of Detail shift for S addresses. */ g_gdp.tile[tilenum].shift_s = (w1 & 0x0000000F) >> ( 0 - 0); g_gdp.flags |= UPDATE_TEXTURE; return tilenum; } int32_t gdp_set_tile_size_wrap(uint32_t w0, uint32_t w1) { int32_t tilenum = (w1 & 0x07000000) >> (24 - 0); /* Low S coordinate of tile in image. */ g_gdp.tile[tilenum].sl = (w0 & 0x00FFF000) >> (44 - 32); /* Low T coordinate of tile in image. */ g_gdp.tile[tilenum].tl = (w0 & 0x00000FFF) >> (32 - 32); /* High S coordinate of tile in image. */ g_gdp.tile[tilenum].sh = (w1 & 0x00FFF000) >> (12 - 0); /* High T coordinate of tile in image. */ g_gdp.tile[tilenum].th = (w1 & 0x00000FFF) >> ( 0 - 0); gdp_calculate_clamp_diffs(&g_gdp, tilenum); g_gdp.flags |= UPDATE_TEXTURE; return tilenum; } void gdp_set_tile_size(uint32_t w0, uint32_t w1) { gdp_set_tile_size_wrap(w0, w1); } /* The Color Combiner implements the * following equation on each color: * (A - B) * C + D * * RGB and Alpha channels have separate * mux selects. In addition, there are separate * mux selects for cycle 0 and cycle 1. */ void gdp_set_combine(uint32_t w0, uint32_t w1) { /* subtract A input, RGB components, cycle 0. */ g_gdp.combine.sub_a_rgb0 = (w0 & 0x00F00000) >> 20; /* multiply input, RGB components, cycle 0. */ g_gdp.combine.mul_rgb0 = (w0 & 0x000F8000) >> 15; /* subtract A input, alpha component, cycle 0. */ g_gdp.combine.sub_a_a0 = (w0 & 0x00007000) >> 12; /* multiply input, alpha component, cycle 0. */ g_gdp.combine.mul_a0 = (w0 & 0x00000E00) >> 9; /* subtract A input, RGB components, cycle 1. */ g_gdp.combine.sub_a_rgb1 = (w0 & 0x000001E0) >> 5; /* multiply input, RGB components, cycle 1. */ g_gdp.combine.mul_rgb1 = (w0 & 0x0000001F) >> 0; /* subtract B input, RGB components, cycle 0. */ g_gdp.combine.sub_b_rgb0 = (w1 & 0xF0000000) >> 28; /* subtract B input, RGB components, cycle 1. */ g_gdp.combine.sub_b_rgb1 = (w1 & 0x0F000000) >> 24; /* subtract A input, alpha component, cycle 1. */ g_gdp.combine.sub_a_a1 = (w1 & 0x00E00000) >> 21; g_gdp.combine.mul_a1 = (w1 & 0x001C0000) >> 18; g_gdp.combine.add_rgb0 = (w1 & 0x00038000) >> 15; g_gdp.combine.sub_b_a0 = (w1 & 0x00007000) >> 12; g_gdp.combine.add_a0 = (w1 & 0x00000E00) >> 9; g_gdp.combine.add_rgb1 = (w1 & 0x000001C0) >> 6; g_gdp.combine.sub_b_a1 = (w1 & 0x00000038) >> 3; g_gdp.combine.add_a1 = (w1 & 0x00000007) >> 0; g_gdp.flags |= UPDATE_COMBINE; } void gdp_set_other_modes(uint32_t w0, uint32_t w1) { /* K: atomic_prim = (w0 & 0x0080000000000000) >> 55; */ /* j: reserved for future use -- (w0 & 0x0040000000000000) >> 54 */ /* Display pipeline cycle control mode: 0 = 1 cycle, 1 = 2 cycle, * 2 = Copy, 3 = Fill */ g_gdp.other_modes.cycle_type = (w0 & 0x00300000) >> (52 - 32); /* Enable perspective correction on texture. */ g_gdp.other_modes.persp_tex_en = !!(w0 & 0x00080000); /* 51 */ /* Enable detail texture. */ g_gdp.other_modes.detail_tex_en = !!(w0 & 0x00040000); /* 50 */ /* Enable sharpened texture. */ g_gdp.other_modes.sharpen_tex_en = !!(w0 & 0x00020000); /* 49 */ /* Enable texture Level of Detail (LOD). */ g_gdp.other_modes.tex_lod_en = !!(w0 & 0x00010000); /* 48 */ /* Enable lookup of texel values from TLUT. Meaningful if texture * type is index, tile is in low TMEM, TLUT is in high TMEM, and * color image is RGB. */ g_gdp.other_modes.en_tlut = !!(w0 & 0x00008000); /* 47 */ /* Type of texels in table, 0 = 16b RGBA (5/5/5/1), I = IA (8/8) */ g_gdp.other_modes.tlut_type = !!(w0 & 0x00004000); /* 46 */ /* Determines how textures are sampled: 0 = 1x1 (Point Sample), 1 = 2x2. * Note that copy (point sample 4 horizontally adjacent texels) mode * is indicated by cycle_type. */ g_gdp.other_modes.sample_type = !!(w0 & 0x00002000); /* 45 */ /* Indicates Texture Filter should do a 2x2x half texel interpolation, * primarily used for MPEG motion compensation processing. */ g_gdp.other_modes.mid_texel = !!(w0 & 0x00001000); /* 44 */ /* color convert operation in Texture Filter. Used in cycle 0. */ g_gdp.other_modes.bi_lerp0 = !!(w0 & 0x00000800); /* 43 */ /* Color convert operation in Texture Filter. Used in cycle 1. */ g_gdp.other_modes.bi_lerp1 = !!(w0 & 0x00000400); /* 42 */ /* Color convert texel that was the output of the texture filter * on cycle0, used to qualify bi_lerp_1. */ g_gdp.other_modes.convert_one = !!(w0 & 0x00000200); /* 41 */ /* Enable chroma keying. */ g_gdp.other_modes.key_en = !!(w0 & 0x00000100); /* 40 */ /* 0 = magic square matrix (preferred if filtered) * 1 = "standard" bayer matrix (preferred if not filtered) * 2 = noise (as before) * 3 = no dither. */ g_gdp.other_modes.rgb_dither_sel = (w0 & 0x000000C0) >> (38 - 32); /* 0 = pattern * 1 = ~pattern * 2 = noise * 3 = noi dither */ g_gdp.other_modes.alpha_dither_sel = (w0 & 0x00000030) >> (36 - 32); /* reserved for future, def:15 -- (w1 & 0x0000000F00000000) >> 32 */ g_gdp.other_modes.blend_m1a_0 = (w1 & 0xC0000000) >> (30 - 0); g_gdp.other_modes.blend_m1a_1 = (w1 & 0x30000000) >> (28 - 0); g_gdp.other_modes.blend_m1b_0 = (w1 & 0x0C000000) >> (26 - 0); g_gdp.other_modes.blend_m1b_1 = (w1 & 0x03000000) >> (24 - 0); g_gdp.other_modes.blend_m2a_0 = (w1 & 0x00C00000) >> (22 - 0); g_gdp.other_modes.blend_m2a_1 = (w1 & 0x00300000) >> (20 - 0); g_gdp.other_modes.blend_m2b_0 = (w1 & 0x000C0000) >> (18 - 0); g_gdp.other_modes.blend_m2b_1 = (w1 & 0x00030000) >> (16 - 0); /* N: reserved for future use -- (w1 & 0x0000000000008000) >> 15 */ /* Force blend enable */ g_gdp.other_modes.force_blend = !!(w1 & 0x00004000); /* 14 */ /* Use cvg (or cvg * alpha) for pixel alpha. */ g_gdp.other_modes.alpha_cvg_select = !!(w1 & 0x00002000); /* 13 */ /* Use cvg times alpha for pixel alpha and coverage. */ g_gdp.other_modes.cvg_times_alpha = !!(w1 & 0x00001000); /* 12 */ /* 0 : opaque, 1 : interpenetrating, 2 : transparent, 3 : decal */ g_gdp.other_modes.z_mode = (w1 & 0x00000C00) >> (10 - 0); /* 0 : clamp (normal), 1 : wrap (was assume full cvg), * 2 : zap (force to full cvg), 3: save (don't overwrite memory cvg). */ g_gdp.other_modes.cvg_dest = (w1 & 0x00000300) >> ( 8 - 0); /* Only update color on coverage overflow (transparent surfaces). */ g_gdp.other_modes.color_on_cvg = !!(w1 & 0x00000080); /* 7 */ /* Enable color/cvg read/modify/write memory access. */ g_gdp.other_modes.image_read_en = !!(w1 & 0x00000040); /* 6 */ /* Enable writing of Z if color write enabled. */ g_gdp.other_modes.z_update_en = !!(w1 & 0x00000020); /* 5 */ /* Conditional color write enable on depth comparison. */ g_gdp.other_modes.z_compare_en = !!(w1 & 0x00000010); /* 4 */ /* If not force blend, allow blend enable - use cvg bits */ g_gdp.other_modes.antialias_en = !!(w1 & 0x00000008); /* 3 */ /* Choose between Primitive Z and pixel Z. */ g_gdp.other_modes.z_source_sel = !!(w1 & 0x00000004); /* 2 */ /* Use random noise in alpha compare, otherwise use blend alpha * in alpha compare. */ g_gdp.other_modes.dither_alpha_en = !!(w1 & 0x00000002); /* 1 */ /* Conditional color write on alpha compare. */ g_gdp.other_modes.alpha_compare_en = !!(w1 & 0x00000001); /* 0 */ } void gdp_set_scissor(uint32_t w0, uint32_t w1) { g_gdp.__clip.xh = (w0 & 0x00FFF000) >> (44 - 32); g_gdp.__clip.yh = (w0 & 0x00000FFF) >> (32 - 32); g_gdp.scfield = (w1 & 0x02000000) >> (25 - 0); g_gdp.sckeepodd = (w1 & 0x01000000) >> (24 - 0); g_gdp.__clip.xl = (w1 & 0x00FFF000) >> (12 - 0); g_gdp.__clip.yl = (w1 & 0x00000FFF) >> ( 0 - 0); g_gdp.flags |= UPDATE_SCISSOR; } /* This command stalls the RDP until the last DRAM buffer is read * or written from any preceding primitive. It is typically only needed * if the memory data is to be reused, like switching display buffers, * or writing a color_image to be used as a texture_image, or for * consistent read/write access to an RDP write/read image from the CPU. */ void gdp_full_sync(uint32_t w0, uint32_t w1) { *gfx_info.MI_INTR_REG |= DP_INTERRUPT; gfx_info.CheckInterrupts(); } void gdp_pipe_sync(uint32_t w0, uint32_t w1) { } void gdp_tile_sync(uint32_t w0, uint32_t w1) { } void gdp_load_sync(uint32_t w0, uint32_t w1) { } void gdp_no_op(uint32_t w0, uint32_t w1) { } void gdp_set_mask_image(uint32_t w0, uint32_t w1) { g_gdp.zb_address = w1 & 0x03FFFFFF; /* g_gdp.zb_address &= 0x00FFFFFF; */ } static char invalid_command[] = "00\nDP reserved command."; void gdp_invalid(uint32_t w0, uint32_t w1) { const unsigned int command = (w0 & 0x3F000000) >> 24; invalid_command[0] = '0' | command >> 3; invalid_command[1] = '0' | command & 07; //DisplayError(invalid_command); } void gdp_set_color_image(uint32_t w0, uint32_t w1) { g_gdp.fb_format = (w0 & 0x00E00000) >> (53 - 32); g_gdp.fb_size = (w0 & 0x00180000) >> (51 - 32); g_gdp.fb_width = (w0 & 0x000003FF) >> (32 - 32); g_gdp.fb_address = (w1 & 0x03FFFFFF) >> ( 0 - 0); ++g_gdp.fb_width; /* g_gdp.fb_address &= 0x00FFFFFF; */ } mupen64plus-core/src/ri/000700 001750 001750 00000000000 12656647145 016237 5ustar00sergiosergio000000 000000 gles2rice/data/RiceVideoLinux.ini000664 001750 001750 00000054554 12655644434 020116 0ustar00sergiosergio000000 000000 {e2f35d53f1899760-4a} Name=Wave Race 64 SE FastTextureCRC=2 FrameBufferEmulation=4 {b09d00f82318296b-4a} Name=CITY TOUR GP IncTexRectEdge {542540b304c04073-45} Name=Cruis'n USA {faf1b9fb8986f86b-45} Name=LT DUCK DODGERS {231f2836cf569700-45} Name=KEN GRIFFEY SLUGFEST {5b05a00a65df3776-50} Name=DAFFY DUCK STARRING {ec939031ef09c20f-45} Name=OFFROAD {378f8f658dd21318-44} Name=RTL WLS2000 {a2eca9b98ee4aa17-45} Name=Rush 2049 {54ddbcae4a83ff15-50} Name=Taz Express {e07359beb8edb089-45} Name=TOP GEAR RALLY 2 {aaccfabcefd814b8-45} Name=BASSMASTERS2000 {696b64f4951075c5-4a} Name=BattlePhoenix64 FastLoadTile {cec4d4558ac75377-45} Name=BATTLEZONE ForceScreenClear=2 {45f48871680a4184-4a} Name=DDR DISNEY D MUSEUM FastLoadTile {181a33df44e0d45f-45} Name=NASCAR 2000 PrimaryDepthHack {437f1c551c834991-4a} Name=TOUKON ROAD2 {4707dec0d372dfa2-4a} Name=PUZZLEBOBBLE64 {421886079fbc2ea1-45} Name=EXCITEBIKE64 FastTextureCRC=1 RenderToTexture=3 {9803f7728ba95665-45} Name=STAR WARS EP1 RACER ZHack {afe66a73c7e91741-4a} Name=MICKEY USA FastTextureCRC=1 AlternativeTxtSizeMethod=1 FrameBufferEmulation=3 RenderToTexture=3 {955f5df3693dfe8a-45} Name=CASTLEVANIA FrameBufferEmulation=1 {9aaae9c2aa705d47-45} Name=BANJO TOOIE {0693bfa4d1df0cbf-45} Name=Banjo-Kazooie FrameBufferEmulation=8 RenderToTexture=4 ScreenUpdateSetting=4 {ff2b5a632623028b-45} Name=SUPER MARIO 64 AlternativeTxtSizeMethod=1 {b655503e52da922e-45} Name=Mario Kart 64 FastTextureCRC=1 FrameBufferEmulation=3 RenderToTexture=3 {ec4ba2664fd9ad2e-45} Name=Rogue Squadron FrameBufferEmulation=2 {3863c01c26893887-45} Name=CASTLEVANIA2 {5cb6f92ad7a2e285-45} Name=MULTI RACING ForceScreenClear=2 {9c33b2d5edcabcca-50} Name=BUCK BUMBLE {9b98023de281a3d4-45} Name=Battle for Naboo {15cc9daf883d721a-45} Name=Indiana Jones {452fefaef1307ef9-45} Name=FIGHTER DESTINY2 {c33022a6884483f0-45} Name=Dual heroes USA {fc06d8d3a8a23ab4-50} Name=MTM64 {71d10ea66ed0853d-45} Name=SPIDERMAN {9deaf4dbc0823e33-45} Name=SNOWBOARD KIDS {b71170ec2bd71676-45} Name=THE LEGEND OF ZELDA FrameBufferEmulation=3 RenderToTexture=3 {b49f03462c823703-45} Name=Kirby64 {0aff1ce6710d1cce-50} Name=NEWTETRIS IncTexRectEdge {1c9651c8faaafc78-45} Name=Pilot Wings64 {3afc8a4ff22d91f7-50} Name=South Park Rally {7ebc10dd51b300f9-50} Name=V8: SECOND OFFENSE FrameBufferEmulation=3 RenderToTexture=3 {a819f4edcc0419bf-45} Name=Beetle Adventure Rac Texture1Hack {fc9ddf9889c10666-45} Name=HARVESTMOON64 {73f0868a4be545cd-45} Name=Bust A Move 2 FastLoadTile TexRectScaleHack {2ecf221e13c8aa42-45} Name=BRUNSWICKBOWLING {21cbbcfc6b3c9072-45} Name=Mystical Ninja FastLoadTile FrameBufferEmulation=1 {80205766e148e328-4a} Name=SUPERROBOTSPIRITS {4f5aa9e623ead2ba-45} Name=AIDYN_CHRONICLES {0b15d45cf1c20c47-45} Name=Extreme G 2 PrimaryDepthHack {0be1d56046eded8b-50} Name=Rayman 2 FastTextureCRC=1 {1c635453f0dea203-45} Name=ZELDA MAJORA'S MASK FrameBufferEmulation=3 RenderToTexture=3 {67cf7503aa3fa956-4a} Name=OgreBattle64 FrameBufferEmulation=3 RenderToTexture=3 {3ae5ee653c737ded-45} Name=PAPER MARIO FrameBufferEmulation=3 RenderToTexture=3 ScreenUpdateSetting=4 {7e260025cec37e2a-45} Name=RIDGE RACER 64 {4fcf0150bdb30cf3-45} Name=MarioTennis AccurateTextureMapping=1 FastTextureCRC=1 AlternativeTxtSizeMethod=1 FrameBufferEmulation=4 RenderToTexture=4 {5c52381956966e58-45} Name=MS. PAC-MAN MM {d0b4b8cd2d353288-45} Name=JET FORCE GEMINI FrameBufferEmulation=1 {db0e7e142cb1c536-4a} Name=EVANGELION AccurateTextureMapping=1 FastTextureCRC=1 {cc60f4ddc034a63c-45} Name=Perfect Dark {85e05e0c3edd67a1-45} Name=ROCKETROBOTONWHEELS FastTextureCRC=1 {8438e2bfafea48ef-45} Name=Silicon Valley AlternativeTxtSizeMethod=1 RenderToTexture=3 {0c28d5b12abca74b-4a} Name=SIM CITY 2000 {325e9b7280d928b7-45} Name=GAUNTLET LEGENDS FrameBufferEmulation=1 {0d4302e49dfcfcd2-45} Name=Diddy Kong Racing {22c04e2085d119b1-45} Name=TONY HAWK PRO SKATER {b2bb524c6b0fabce-45} Name=ARMYMENAIRCOMBAT IncTexRectEdge {b6ce09347a51c8ce-45} Name=SMASH BROTHERS {50acc7302d070477-45} Name=CONKER BFD FrameBufferEmulation=3 RenderToTexture=4 {a5b118aaeb6adb07-45} Name=Resident Evil II ForceScreenClear=1 {d150bcdca31afd09-45} Name=GOLDENEYE ZHack FrameBufferEmulation=1 ScreenUpdateSetting=4 {e8d83723ec7c8e6b-45} Name=YOSHI STORY FrameBufferEmulation=3 RenderToTexture=3 {78d90eb3f9c90330-45} Name=F-ZERO X {3603165ab0377bbc-50} Name=BOMBERMAN64E {0390a59064980831-45} Name=WRESTLEMANIA 2000 {6d208ebd1c5ec398-4a} Name=DOUBUTSUNOMORI {96fa0e65a7f9dd30-50} Name=WAVE RACE 64 VIWidth=320 VIHeight=240 {72e270fcaae7ff08-50} Name=Silicon Valley {bbe8e07eaa11e449-50} Name=Rogue Squadron {38a59bd089541a1c-50} Name=Top Gear Overdrive {f4791f15e5c8ed8e-50} Name=VIGILANTE 8 {7b5bf45be8ee6b59-50} Name=WWF: Attitude {485f9493302e0f5c-50} Name=SMASH BROTHERS {36f03ca0d2c5c1bc-50} Name=SUPER MARIO 64 FastTextureCRC=1 {8616b80c815ad85f-45} Name=Madden NFL 2000 {a475a233594450b8-50} Name=WWF War Zone RenderToTexture=3 {a526899f09b48705-50} Name=TONY HAWK SKATEBOARD {84ea4ed8b4f1b245-50} Name=SHADOWGATE64 {bfe514d6c1bc6da7-50} Name=TARZAN {4a831839290cb515-45} Name=RAZOR FREESTYLE {4d675728da3743cc-45} Name=NIGHTMARE CREATURES {9940307f7652cf52-4a} Name=LASTLEGION UX {782706acb8fcaddf-50} Name=WORLD DRIVER CHAMP FullTMEM=1 {f336411da9ee63af-45} Name=ZELDA MASTER QUEST {614b2f496a14e504-45} Name=WAVE RACE 64 {b1cc3f73f9924844-50} Name=Banjo-Kazooie {e74bc5a2b2cb1967-50} Name=CASTLEVANIA2 FastTextureCRC=1 {b609608a50e1ac94-45} Name=JET FORCE GEMINI AccurateTextureMapping=1 FastTextureCRC=1 RenderToTexture=3 {b3d9f590f0dc0e9d-45} Name=POKEMON STADIUM FrameBufferEmulation=3 RenderToTexture=3 {a059e913b0ca930e-45} Name=WORMS ARMAGEDDON {d7d81095d20d1035-45} Name=Stunt Racer 64 FullTMEM=1 {bfea58ec69717cad-45} Name=DONKEY KONG 64 EmulateClear=2 {40064b4efbbc491b-45} Name=WWF No Mercy {d68cbe33126918ec-45} Name=WCW MAYHEM {bd193e2c5eee1351-45} Name=WCWvs.NWO:World Tour FrameBufferEmulation=4 ScreenUpdateSetting=4 {b960be713cfbdb1d-45} Name=WCWvs.NWO:World Tour FrameBufferEmulation=1 ScreenUpdateSetting=4 {ab96e5dee77a3baf-45} Name=WCW / nWo REVENGE ScreenUpdateSetting=4 {253ffd588daa2ed9-50} Name=1080 SNOWBOARDING {47cfa352fc3bc14e-50} Name=NFL QBC '99 {497df9d35b132469-50} Name=YOSHI STORY FrameBufferEmulation=3 RenderToTexture=3 {af29ab1928cd1bc7-50} Name=PAPER MARIO {7d1d6172d2bd1999-58} Name=HSV ADVENTURE RACING Texture1Hack {ad84d7df036642ae-50} Name=ALL STAR TENNIS '99 {b4fb88b01d4b1e44-50} Name=BASS HUNTER 64 {d3dd3f71efa0d672-20} Name=Bike Race by NaN ForceScreenClear=2 {16d3794d331b50e8-45} Name=BEAST WARS US {d0483cfb9ff6288d-50} Name=CHARLIE BLAST'S {e89d2b491cc8ccc6-50} Name=EARTHWORM JIM 3D {3421cfdc7835d69d-50} Name=Centre Court Tennis UseCIWidthAndRatio=1 {9531740f95dba6d8-50} Name=DAIKATANA {b3c83ccca405c40e-50} Name=F1 WORLD GRAND PRIX {9d127b27ff7938dd-50} Name=Holy Magic Century {98da8b41580f8a24-50} Name=MISCHIEF MAKERS {f10bfd20871dcff5-50} Name=RAT ATTACK {7bc5212d8cc5e48f-50} Name=WORMS N64 {9bbfc5f3e2330f16-45} Name=Rayman 2 FastTextureCRC=1 {118a08497e959464-45} Name=Turok 2: Seeds of Ev AccurateTextureMapping=1 {4e2d0ff0f4aa0f34-45} Name=CARMAGEDDON64 FastTextureCRC=1 {ababd40d1ea9a2b5-45} Name=D K DISPLAY {32d9b51f1b48a93b-45} Name=Armorines Project S. {b46e28958fd56ab7-45} Name=Command&Conquer {9addd0dea72582e7-50} Name=MICKEY USA PAL {75d474fcab78029a-45} Name=PPG CHEMICAL X {b5707f1afdb9b700-45} Name=THPS3 {6a0571ea474821e4-45} Name=VIGILANTE 8 FullTMEM=2 RenderToTexture=3 {e7dda46ae7f4e2e3-45} Name=BATTLETANX {47e2a4753d960860-45} Name=BATTLETANXGA {ca243cf0cc7b23c5-45} Name=CLAYFIGHTER 63 {cbc7ef32203feac3-45} Name=Fighting Force {1a103ea89db637e9-45} Name=Doom64 {ff016e8e48f9b4cc-45} Name=Glover AccurateTextureMapping=1 {3f14532151632d99-45} Name=NEWTETRIS VIWidth=400 VIHeight=300 {a35ecf42df34139a-50} Name=STARCRAFT 64 NormalAlphaBlender=2 UseCIWidthAndRatio=1 RenderToTexture=3 {ac47477a23ecee44-44} Name=PUZZLE LEAGUE N64 VIWidth=320 VIHeight=240 FrameBufferEmulation=4 RenderToTexture=3 {fd04dc82f4822dcf-45} Name=A Bug's Life {f628fef7c3acf2c3-45} Name=WAR GODS {3f22456b565c0ef0-45} Name=W.G. 3DHOCKEY {59389d5a10e7aa97-45} Name=W.G 3D Hockey 98 {329dc9bb80aa7d11-45} Name=TWISTED EDGE {3e7450a1cd2225cf-45} Name=Toy Story 2 FrameBufferEmulation=2 {3d9b2662e8b111fe-45} Name=TOP GEAR RALLY ScreenUpdateSetting=2 {beda1f3cbae0a402-45} Name=TETRISPHERE IncTexRectEdge {5bf3e8a2d987dcc9-45} Name=SUPERMAN {c8615eab9675faa2-45} Name=PENNY RACERS {669464dcd9f02f57-4a} Name=ONEGAI MONSTER {1a5ac4d45eb225f4-45} Name=NITRO64 {eeb0255fdbc12762-45} Name=NBA LIVE 2000 {ada552424ebf6fae-45} Name=GOEMONS GREAT ADV {c59b41e6e31d0169-45} Name=OgreBattle64 {e5522da955b6261d-45} Name=FLYING DRAGON FastLoadTile {d6fd4644088278e3-45} Name=BOMBERMAN HERO {b42f2fff9a1461d1-45} Name=Cruis'n USA {5c7e4d2622468718-45} Name=Shadow of the Empire DisableObjBG=1 ScreenUpdateSetting=4 {63cff584dc7eee08-45} Name=KNIFE EDGE {9fd8224237b6e0af-45} Name=Bust A Move '99 FastLoadTile {a43c70efc99a4a4d-4a} Name=TOUKON ROAD {b3c83ccca405c40e-45} Name=F1 WORLD GRAND PRIX {8e8fc9c7de5d1442-45} Name=HOT WHEELS TURBO {36cee20de6291dd4-4a} Name=HYBRID HEAVEN JP {374cff6dfd63b7b1-4a} Name=̧н?64 {180e1599a5e66612-45} Name=THPS2 {7ff0da0488e6180d-45} Name=DUKE NUKEM ZERO HOUR {7a6882ae8d383f9a-45} Name=F1 POLE POSITION 64 {6e86c107decc7557-50} Name=F1 WORLD GRAND PRIX2 {5858a99e18b672af-45} Name=MarioParty2 {d929387cce47826e-45} Name=MarioParty3 FastTextureCRC=1 TexRectScaleHack {9207384145e067a1-45} Name=POLARISSNOCROSS TexRectScaleHack DisableAlphaBlender=1 {31e0d6ed13601368-45} Name=RUSH 2 {0d7ddff78f0152ed-00} Name=Shufflepuck 64 {ac3363d79d21b60c-4a} Name=Bass Rush {fab428e3e1284a00-50} Name=Bust A Move 3 DX {20186b2a66f4bc6a-45} Name=S.F. RUSH IncTexRectEdge {4d7a545e9507e690-45} Name=All-Star Baseball '0 {30a61376f396d63e-45} Name=FIFA 99 FastTextureCRC=1 {996e30b6b2d23eb6-4a} Name=ÄÞ×´ÓÝ2 ˶ØÉ¼ÝÃÞ {049805d8119b7392-4a} Name=ÄÞ×´ÓÝ3 ÉËÞÀÉÏÁSOS! {4cca08f927434636-45} Name=Killer Instinct Gold ForceScreenClear=1 {ac0443c321c0792d-45} Name=MK_MYTHOLOGIES {b9019507ab3202ab-4a} Name=CUSTOMROBOV2 {582ba5a441987523-45} Name=DARK RIFT EmulateClear=1 {c18944202bcf8612-45} Name=BATMAN BEYOND RETURN {b4737e23376b3bd6-45} Name=BOMBERMAN64U2 AccurateTextureMapping=1 FastTextureCRC=1 {bf2ff236f2128931-4a} Name=64ÊÅÌÀ?~ÃݼÉÔ¸¿¸~ {ec7c7fc26f80e085-50} Name=MYSTICAL NINJA2 SG {33ddbf4e849d4c66-45} Name=Tigger's Honey Hunt {dd5a6f39a7ec9366-45} Name=WCW BACKSTAGE {8c1168f44ee42ee3-4a} Name=Ultraman Battle JAPA {aff7a346d091750f-45} Name=CruisnExotica ForceScreenClear=1 FrameBufferEmulation=2 {e1a49e51e88475eb-4a} Name=KING HILL 64 {f002cc8e81de8b7f-45} Name=Top Gear Hyper Bike {54edd74d7d28f974-45} Name=Shadow of the Empire FrameBufferEmulation=3 ScreenUpdateSetting=3 {6c7450f00b827b24-45} Name=ROAD RASH 64 AccurateTextureMapping=1 {6a6d63bdba541f5d-45} Name=World Cup 98 {9516943beb5e0af9-50} Name=TWINE UseCIWidthAndRatio=1 {95351208def11005-45} Name=BIOFREAKS {abd8f7d146043b29-45} Name=Asteroids Hyper 64 {0588f752b7ca8f8b-45} Name=Fighter's Destiny {a2dc9ac4621b50f1-45} Name=GT64 IncTexRectEdge {ea406a09100abe8a-45} Name=LEGORacers FrameBufferEmulation=2 {87b4694e90e218fe-45} Name=NBA HANGTIME FastLoadTile FullTMEM=1 {47b512cae44efa71-45} Name=POKEMON SNAP FastTextureCRC=1 RenderToTexture=3 {1a1d75c2ff9bc1f8-50} Name=SNOWBOARD KIDS2 {f85c032635912b80-45} Name=Mission Impossible {f18b591b459ba2ec-45} Name=AERO FIGHTERS ASSAUL {20d568510dcd5fca-4a} Name=Banjo-Kazooie {eeea74f73eb1d8f0-4a} Name=F3 ̳ײɼÚÝ2 AccurateTextureMapping=1 FastTextureCRC=1 {6d8d76286c9779b3-45} Name=Monaco Grand Prix {821157036dd02f89-45} Name=POKEMON STADIUM 2 FrameBufferEmulation=3 {b8a5ed9403e97386-45} Name=Starshot {127edc3ec91c6ce2-45} Name=Gex 3 Deep Cover Gec {98ae2b8dbf2537d7-45} Name=NAGANO OLYMPICS {6b7e8094e462cc60-4a} Name=PUYO PUYO SUN 64 {f34791760ec13320-45} Name=SCARS VIWidth=320 VIHeight=240 FullTMEM=1 {2d16e69f37407ee9-4a} Name=TROUBLE MAKERS {8ad56680c1cadec3-45} Name=Waialae Country Club {20f9b837efb38ba5-45} Name=Twintris {9dae5305c1e0d8ea-45} Name=XENAWARRIORPRINCESS {f179a589ef977e66-45} Name=Turok 3: Shadow of O {3d8ea87371c5c53a-45} Name=RALLY CHALLENGE RenderToTexture=3 {9cf75b9fa008fed2-45} Name=Quake ForceScreenClear=1 {a7233ec41a68b140-45} Name=All Star Baseball 99 {d025c427c1992d8c-50} Name=AIR BOARDER 64 {941a95b6af49c863-4a} Name=DRACULA MOKUSHIROKU {2907d2674c7796f6-4a} Name=SMASH BROTHERS {c73b072011013b5e-45} Name=ITF 2000 {4fd5ea30f60b6231-45} Name=NFL BLITZ SPECIAL ED {80cd41d712b9a9ac-45} Name=Top Gear Overdrive {2b0996e84e4d24dc-45} Name=WHEEL OF FORTUNE {3e46beae4b4671cc-45} Name=AEROGAUGE {ec620158f18b10e3-58} Name=CARMAGEDDON64 {d245a2fd473d4aa7-45} Name=extremeg {74d7fe891be2afca-45} Name=GEX: ENTER THE GECKO {6064256986f5a3b9-45} Name=JEOPARDY! {bcb516e6888b65c9-45} Name=Iggy's Reckin' Balls {32272d1318910ec7-45} Name=Wipeout 64 {14979eef7d2c3bc0-45} Name=Tonic Trouble {163ed509b968b23a-45} Name=PIAZZA STRIKEZONE {f4d47d41e22f481b-45} Name=MORTAL KOMBAT 4 {4f47294f7a70cb30-4a} Name=KAKUTOU DENSHOU {6910969c8d48eaf5-4a} Name=64 OHZUMOU FastLoadTile {1462a21e0f9090e7-50} Name=Turok: Rage Wars {f6290781c1cf3fe0-45} Name=NBA JAM 99 {cab7f1645537a271-50} Name=CASTLEVANIA {5991f1c35abcd265-45} Name=FIFA Soccer 64 {dce23ae1e85cb64f-4a} Name=Eltail {514423656f34d3eb-4a} Name=Blastdozer {e48c53cdf9fc8a61-45} Name=Chameleon Twist2 ScreenUpdateSetting=4 {56ab73a29adb33da-45} Name=DUKE NUKEM {657e647c05d34819-45} Name=Blast Corps {e167f6a51fbd1fda-4a} Name=DERBYSTALLION 64 {92f738eb46a20e19-45} Name=Madden NFL 2001 ScreenUpdateSetting=4 {d4a34b66b7808a67-45} Name=MarioGolf64 FrameBufferEmulation=4 RenderToTexture=4 {83c871d5cf3f2d82-50} Name=BLUES BROTHERS 2000 {134d9d76fe3f23da-45} Name=DR.MARIO 64 FastTextureCRC=2 TexRectScaleHack FrameBufferEmulation=7 RenderToTexture=3 {f815d0a743aa8922-45} Name=STARFOX64 {a284e5de8711160f-45} Name=DESTRUCT DERBY {7e652928771862a0-45} Name=MarioParty FastTextureCRC=1 ScreenUpdateSetting=4 {c8fe8d30f6b52ece-45} Name=WORLD DRIVER CHAMP {d94dbbc80b435fcc-45} Name=Quest 64 {4fb5a8ce03d5217f-45} Name=Wetrix AccurateTextureMapping=1 FastTextureCRC=1 {436b4bfea7291d08-45} Name=TRIPLE PLAY 2000 {77eb3c7f0a038189-45} Name=HERCULES {b7a4ff08b653f401-45} Name=Big Mountain 2000 {d66abc75c92b5578-4a} Name=·×¯Ä¶²¹Â 64ÀÝòÀÞ {65973ce4bec1b105-4a} Name=Wonder Project J2 {78957423fd58dc80-45} Name=NASCAR 99 PrimaryDepthHack {b6730fb234fc7529-45} Name=ARMYMEN SARGE 2 {1cfb9046446dd54c-45} Name=GOLDEN NUGGET 64 {8074f13d5aed3d19-50} Name=Donald Duck Quack At FastTextureCRC=1 {cdb8580bd291b2b7-50} Name=Body Harvest ScreenUpdateSetting=2 {4dd12fd7c432ed1f-45} Name=Bottom of the 9th VIWidth=320 VIHeight=240 {c2b1f7bf8e14bfae-4a} Name=ÄÞ×´ÓÝ Ð¯Âɾ²Ú²¾· {405127a8e856b0b9-4a} Name=ÄÞ×´ÓÝ3 ÉËÞÀÉÏÁSOS! {26f7fc68bc8c6549-50} Name=G.A.S.P!!Fighters'NE {978d9fab66a7ea95-00} Name=Kings of Porn Vol 01 {4c5eb3e4c95cc41a-45} Name=MGAH VOL1 {2f96deac7ff8cbb2-50} Name=NBA PRO 98 {a55f70280e6909b5-50} Name=Monaco GP Racing 2 {420c2a397de790b7-45} Name=RAINBOW SIX {5d0ef1d379a52e05-45} Name=hey you, pikachu {d44a7da4f981fa8b-45} Name=Manic Miner 64 {231b1c14259ef43e-00} Name=(C) DATEL D&D NU10:0 {0cf10110c1d8513d-45} Name=Mia Hamm Soccer 64 {bbdd9849bcaeb7f7-45} Name=NUCLEARSTRIKE64 {25d625395ec7838c-50} Name=MADDEN NFL 99 {bf882810ca884843-45} Name=HYBRID HEAVEN USA {7a4636e49b8fde82-45} Name=INDY RACING 2000 {d04eabe3d20d0483-45} Name=NFL QBC 2000 {6960bfac62e1beea-45} Name=CHOPPER_ATTACK {707ae874d4ae9362-50} Name=ROADSTERS TROPHY {c463275fe52a4162-45} Name=I S S 64 ScreenUpdateSetting=3 {43f1a8bd622dafb1-45} Name=QUAKE II ForceScreenClear=2 {127341ec5fde31eb-4a} Name=THE MASK OF MUJURA DisableObjBG=1 {c26661e3e5a21386-58} Name=MO WORLD LEAGUE SOCC {5a211daa9abecb91-45} Name=SUPER BOWLING {e2a2bb4bb2bbf38b-00} Name=Puzzle Master 64 {9e5abd88bfdf1fe8-50} Name=NFL QBC 2000 {48a90cc04bd3608e-45} Name=South Park: Chef's L TexRectScaleHack FullTMEM=1 AlternativeTxtSizeMethod=1 {4b45d50895ccaaff-4a} Name=TETRIS64 {5a53206462800250-45} Name=Chameleon Twist {493336f51bd2f9db-45} Name=DeadlyArts {c7c4eb0c32e99c0c-4a} Name=WILD CHOPPERS {57062c866d89fd8d-45} Name=Army Men Sarge {a18efce89183739f-45} Name=CyberTiger {010c339eba14038c-45} Name=Forsaken {36fecce375bc8f39-45} Name=YOSHI STORY {1d5bce9c83e25163-00} Name= {e98889b5e84bfcb1-50} Name=Hydro Thunder {6e84e4bab0fe8ebb-45} Name=PAPERBOY {ec4716df47a9a2be-50} Name=MYSTICAL NINJA2 SG {532a11638fa89fa2-4a} Name=PERFECT STRIKER2 {2d56d52850aed5e4-4a} Name=ÃÞÝØ­³²×²×ÎÞ ScreenUpdateSetting=2 {fbabf721e8a78a6a-50} Name=Jeremy McGrath Super {0df1702fff87415c-45} Name=TUROK_DINOSAUR_HUNTE {efc64654bb478ee1-45} Name=All-Star Baseball 20 {e8603e5e95d4b54a-4a} Name=»²·®³ÊÌÞ¼®³· {cd0d702fc9c56c17-50} Name=TUROK_DINOSAUR_HUNTE {db4d6b0b82e67196-45} Name=ROADSTERS TROPHY {aea23b699f4ef1b7-45} Name=THE LEGEND OF ZELDA {3890053c8221bfc8-45} Name=V-RALLY {5b8b6b91a4850b78-45} Name=SMASH BROTHERS {89638313763c5b26-45} Name=MADDEN 64 {a93af3830dd401a9-45} Name=MortalKombatTrilogy {29b4b7ea572cc9ba-45} Name=READY 2 RUMBLE {5e6c6384fa4a9e94-4a} Name=TETRIS64 {c45db2418667721b-45} Name=Lamborghini 64 {5007706bfe21d629-45} Name=MACE {865877637b0eb85f-4a} Name=POKEMON STADIUM 2 FrameBufferEmulation=3 RenderToTexture=3 {d0f2f9989cf0d903-50} Name=Virtual Pool 64 ScreenUpdateSetting=3 {f311e83524277999-4a} Name=½½?À²¾ÝÊß½ÞÙÀÞÏ TexRectScaleHack {2dac77289a13dcc3-44} Name=Racing Simulation 2 FastLoadTile {d8526891efeadb73-45} Name=NBA Courtside 2 {3754838eb44857cd-45} Name=I.S.S.2000 {f336411da9ee63af-50} Name=THE LEGEND OF ZELDA FrameBufferEmulation=7 {0000000000000000-00} Name= {decd1acbf21d29cf-45} Name=FIFA: RTWC 98 ScreenUpdateSetting=2 {6930669c804af280-50} Name=MarioParty {79c712671d78723b-50} Name=IT&F SUMMERGAMES {f49e624b9b1db299-50} Name=quarterback_club_98 {8725c27e23e31aef-45} Name=OLYMPIC HOCKEY {f0ed310ed54972c3-50} Name=FIFA: RTWC 98 {51a69801849d21fc-50} Name=FIFA 99 {dbe5388cd7277cb3-50} Name=ECW Hardcore Revolut {2ce9cbf412ed92b3-50} Name=STARFOX64 {796690e4053f249f-50} Name=MAGICAL TETRIS {7e9598edacdc4282-45} Name=WIN BACK {ba8bb7de9dbdf652-45} Name=MADDEN NFL 99 {604167c53c455f0f-50} Name=MarioParty3 TexRectScaleHack {d057e9625d5ac17f-50} Name=MarioGolf64 FrameBufferEmulation=3 RenderToTexture=3 {396d17c9d17947ea-50} Name=BANJO TOOIE {185bf98d7b49daec-45} Name=NBA IN THE ZONE 2000 {9c9094082dd8d4da-45} Name=Knockout Kings 2000 UseCIWidthAndRatio=1 RenderToTexture=3 {fb4e4f2bfe11c543-50} Name=TOM AND JERRY {dadf3a4daefc9875-50} Name=RUGRATSTREASUREHUNT {02c608eea6d5c26b-50} Name=PGA European Tour Go {94ad4c21243b1abe-45} Name=CHOPPER_ATTACK {4716b67578bfda7a-45} Name=MAGICAL TETRIS {350c85f11279e0ac-45} Name=MICROMACHINES64TURBO {e183c35a87e312d7-45} Name=monopoly {168bc185af2296df-4a} Name=64 µµ½ÞÓ³ 2 {fbb1ab739360ca9c-45} Name=PENNY RACERS {e4f99fc27dfe4b26-45} Name=RAMPAGE {99d7e0fc546c3165-45} Name=KNIFE EDGE {0ca3d88317c15285-00} Name=YOSHI BOOT EMU {8d3bda777c0d2b16-4a} Name=²ÃÞÖ³½¹Éϰ¼Þ¬Ý¼Þ­¸ {986c006081a30526-4a} Name=VIOLENCEKILLER {cd0c011cfab7d322-4a} Name=½Þ°Ù ϼޭ³Â¶²ÃÞݾ {222ee09cb0f16e20-4a} Name=SUPER SPEED RACE 64 {dccda73ba0524e46-4a} Name=MARIO STORY {1e82cccc838ae896-4a} Name=ϰ¼Þ¬Ýγ۳·CLASSIC {20b93bd8166440cc-4a} Name=ǼÂÞØ64 {3b4b5574b5bcaef4-4a} Name=PACHINKO365NICHI {ad5b4934269d2e50-4a} Name=PAWAFURU PUROYAKYU4 {da4329d2c0772bac-4a} Name=PAWAFURU PUROYAKYU5 {b7205eb7fdfdfeb3-4a} Name=PAWAFURU PUROYAKYU6 {547fd2f3f9ac11c1-50} Name=Premier Manager 64 {3b5966d6075ca2d7-4a} Name=RockMan Dash {ff04fc84e93c25b1-4a} Name=½ÉÎÞ·¯½Þ ScreenUpdateSetting=4 {c1a7caff37858568-4a} Name=STARFOX64 {87a91f0fa6afc1bf-45} Name=Re-Volt {5db998df78098458-4a} Name=BANGAIOH IncTexRectEdge {8824ae7e5aa3409d-4a} Name=BioHazard II {c4085c048b79fd4a-4a} Name=ÊÞ°Á¬Ù ÌßÛÚ½ØÝ¸Þ 64 FrameBufferEmulation=2 ScreenUpdateSetting=3 {9c167989a0f689f1-4a} Name=DEZAEMON3D {819b9b3911ad33d5-4a} Name=´¸½ÄذÑG2 PrimaryDepthHack {66e8703ee8ba3844-4a} Name=HEIWA ÊßÁݺ ܰÙÄÞ64 RenderToTexture=3 {f5d919afcc2302b7-4a} Name=G1STABLE {ac90989adf13c3f0-4a} Name=ÏØµÉÌ«ÄËß° {0f692b27777a0aad-4a} Name=Robopon64 FrameBufferEmulation=3 RenderToTexture=3 {339521e9bdaffb13-45} Name=Ready to Rumble {f480fe3f7e5fc1a7-45} Name=NBA SHOWTIME {56a48bb9af762b5b-4a} Name=ÐÝÅÃÞÀϺޯÁܰÙÄÞ FastLoadTile FullTMEM=1 {69025b840295de57-4a} Name=Top Gear Hyper Bike {e6849c48f9496e4c-4a} Name=Getter Love!! {b157ae0937562a18-4a} Name=MASTERS'98 {f127177deb836b6c-00} Name=Test Program {93b8a075b521a34c-00} Name= {321536813f64eb2a-00} Name= {e04dda1e8d69bf22-00} Name=Test Program {0ab5b39a056166bc-44} Name=HEXEN {6805ed0d5e510215-4a} Name=´²º³É¾ÝıÝÄÞØ­°½ {c851318f45f53a4f-44} Name=WWF: Attitude {8ef08d6dcfc308d0-50} Name=WWF No Mercy {dbe6647cdb24b955-50} Name=Blast Corps {ce97680354fad4e0-45} Name=SHADOWGATE64 {324b8eac2673b4e7-45} Name=ROBOTRON-64 {424a5554fb5f98e4-4a} Name=J LEAGUE LIVE 64 {d218739cc10dae24-4a} Name=BEETLE ADVENTURE JP Texture1Hack {614ab6a10b9414d0-50} Name=Beetle Adventure Rac Texture1Hack {5cc0c180f45e06ea-45} Name=MLB FEATURING K G JR FastLoadTile {be98b9cdc8a52410-50} Name=MLB FEATURING K G JR FastLoadTile AlternativeTxtSizeMethod=1 {1e93f3833d2272cb-50} Name=CRUIS'N WORLD UseCIWidthAndRatio=2 {80064660720e5f30-50} Name=Lode Runner 3D ScreenUpdateSetting=1 {140efa7505d1b3c9-44} Name=Holy Magic Century {3e269b97040047f8-50} Name=Killer Instinct Gold {2bc6673d5031d031-4a} Name=LET'S SMASH {87a9c3c94c341058-4a} Name=MARIOKART64 {b8a588e6183f4bb1-50} Name=TWISTED EDGE {30dcef8261246a80-45} Name=BLADES OF STEEL '99 {b01a15d04ba15cfe-45} Name=DAIKATANA {bae28f9e7007278b-45} Name=KILLER INSTINCT GOLD ForceScreenClear=1 {61f1ba1ff1541c2c-41} Name=1080 SNOWBOARDING FastTextureCRC=2 ScreenUpdateSetting=2 {e08b138c460e7095-45} Name=BASS HUNTER 64 {8b24b3824d243ee7-45} Name=VIRTUALCHESS {9369a7da7cf7acd8-00} Name= {4986248e52de1c2e-00} Name= {74ab4cb4299a0207-50} Name=SUPERMAN {1ed568f51eba497e-45} Name=BOMBERMAN64U {f558c10e96683efb-45} Name=Mega Man 64 {dab629518c3cef9d-45} Name=NAMCOMUSEUM64 {60a73e50960e30e1-50} Name=Cruis'n USA {9723feeb34da74ff-45} Name=SPACE INVADERS {0e4016ac1a075dcf-45} Name=CAL SPEED {e8960e1e6b82284e-45} Name=CHARLIE BLAST'S {a00b78ba34db210f-45} Name=STARFOX64 {e740d45311b01975-45} Name=Diddy Kong Racing {134c3f03a7e79e31-45} Name=TWINE {ccffc42d215affc8-50} Name=AIDYN_CHRONICLES {91e285e16d76504e-45} Name=ALL STAR TENNIS '99 {df1850253aaed657-45} Name=Lode Runner 3D {71458cfac0f9e7bb-45} Name=MICKEY USA mupen64plus-core/src/plugin/audio_libretro/000700 001750 001750 00000000000 12656647145 022126 5ustar00sergiosergio000000 000000 glide2gl/src/Glide64/ucode06.h000664 001750 001750 00000131546 12655644434 017025 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified-> Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** // STANDARD DRAWIMAGE - draws a 2d image based on the following structure static float set_sprite_combine_mode(void) { float Z; if (((rdp.othermode_h & RDP_CYCLE_TYPE) >> 20) == G_CYC_COPY) { int32_t color_source; rdp.tex = 1; rdp.allow_combine = 0; // Now actually combine ! color_source = GR_COMBINE_FUNCTION_LOCAL; cmb.tmu1_func = cmb.tmu0_func = color_source; cmb.tmu1_fac = cmb.tmu0_fac = GR_COMBINE_FACTOR_NONE; cmb.tmu1_a_func = cmb.tmu0_a_func = GR_COMBINE_FUNCTION_LOCAL; cmb.tmu1_a_fac = cmb.tmu0_a_fac = GR_COMBINE_FACTOR_NONE; cmb.tmu1_invert = cmb.tmu0_invert = FXFALSE; cmb.tmu1_a_invert = cmb.tmu0_a_invert = FXFALSE; } g_gdp.flags |= UPDATE_COMBINE; update (); rdp.allow_combine = 1; // set z buffer mode Z = 0.0f; if ((rdp.othermode_l & 0x00000030) && (((rdp.othermode_h & RDP_CYCLE_TYPE) >> 20) < 2)) { if (g_gdp.other_modes.z_source_sel == 1) Z = g_gdp.prim_color.z; FRDP ("prim_depth = %d, prim_dz = %d\n", g_gdp.prim_color.z, g_gdp.prim_color.dz); Z = ScaleZ(Z); if (rdp.othermode_l & 0x00000400) grDepthBiasLevel(g_gdp.prim_color.dz); } #if 0 else { LRDP("z compare not used, using 0\n"); } #endif grCullMode (GR_CULL_DISABLE); grFogMode (GR_FOG_DISABLE, g_gdp.fog_color.total); g_gdp.flags |= UPDATE_CULL_MODE | UPDATE_FOG_ENABLED; if (((rdp.othermode_h & RDP_CYCLE_TYPE) >> 20) == G_CYC_COPY) { grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE, FXFALSE); grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE, FXFALSE); grAlphaBlendFunction (GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_ZERO, GR_BLEND_ZERO); grAlphaTestFunction ((rdp.othermode_l & 1) ? GR_CMP_GEQUAL : GR_CMP_ALWAYS, 0x80, (rdp.othermode_l & 1) ? 1 : 0); g_gdp.flags |= UPDATE_ALPHA_COMPARE | UPDATE_COMBINE; } return Z; } typedef struct DRAWIMAGE_t { float frameX; float frameY; uint16_t frameW; uint16_t frameH; uint16_t imageX; uint16_t imageY; uint16_t imageW; uint16_t imageH; uint32_t imagePtr; uint8_t imageFmt; uint8_t imageSiz; uint16_t imagePal; uint8_t flipX; uint8_t flipY; float scaleX; float scaleY; } DRAWIMAGE; static void DrawDepthImage (const DRAWIMAGE *d) { float scale_x_src, scale_y_src, scale_x_dst, scale_y_dst; uint16_t *src, *dst; int32_t x, y, src_width, src_height, dst_width, dst_height; if (!fb_depth_render_enabled || d->imageH > d->imageW) return; scale_x_dst = rdp.scale_x; scale_y_dst = rdp.scale_y; scale_x_src = 1.0f/rdp.scale_x; scale_y_src = 1.0f/rdp.scale_y; src_width = d->imageW; src_height = d->imageH; dst_width = min((int)(src_width*scale_x_dst), (int)settings.scr_res_x); dst_height = min((int)(src_height*scale_y_dst), (int)settings.scr_res_y); src = (uint16_t*)(gfx_info.RDRAM+d->imagePtr); dst = (uint16_t*)malloc(dst_width * dst_height * sizeof(uint16_t)); for (y = 0; y < dst_height; y++) { for (x = 0; x < dst_width; x++) dst[x + y * dst_width] = src[((int)(x * scale_x_src) + (int)(y*scale_y_src) * src_width)^1]; } grLfbWriteRegion(GR_BUFFER_AUXBUFFER, 0, 0, GR_LFB_SRC_FMT_ZA16, dst_width, dst_height, FXFALSE, dst_width<<1, dst); free(dst); } static void DrawImage (DRAWIMAGE *d) { int x_size, y_size, x_shift, y_shift, line; int min_wrap_u, min_wrap_v, min_256_u, min_256_v; float nul_y, nlr_x; int nul_v, nlr_u; int cur_wrap_v, cur_v; int cb_v; // coordinate-base int tb_v; // texture-base float ful_u, ful_v, flr_u, flr_v; float ful_x, ful_y, flr_x, flr_y, mx, bx, my, by; float Z; TILE *tile; int ul_u, ul_v, lr_u, lr_v; float ul_x, ul_y, lr_x, lr_y; if (d->imageW == 0 || d->imageH == 0 || d->frameH == 0) return; // choose optimum size for the format/size switch (d->imageSiz) { case 0: y_size = 32; y_shift = 5; if (rdp.tlut_mode < 2) { y_size = 64; y_shift = 6; } x_size = 128; x_shift = 7; line = 8; break; case 1: y_size = 32; y_shift = 5; if (rdp.tlut_mode < 2) { y_size = 64; y_shift = 6; } x_size = 64; x_shift = 6; line = 8; break; case 2: x_size = 64; y_size = 32; x_shift = 6; y_shift = 5; line = 16; break; case 3: x_size = 32; y_size = 16; x_shift = 4; y_shift = 3; line = 16; break; default: FRDP("DrawImage. unknown image size: %d\n", d->imageSiz); return; } if (rdp.ci_width == 512 && !no_dlist) //RE2 { uint16_t width = (uint16_t)(*gfx_info.VI_WIDTH_REG & 0xFFF); d->frameH = d->imageH = (d->frameW * d->frameH)/width; d->frameW = d->imageW = width; if (g_gdp.zb_address == rdp.cimg) { DrawDepthImage(d); g_gdp.flags |= UPDATE_ZBUF_ENABLED | UPDATE_COMBINE | UPDATE_ALPHA_COMPARE | UPDATE_VIEWPORT; return; } } #if 0 if ((settings.hacks&hack_PPL) > 0) { if (d->imageY > d->imageH) d->imageY = (d->imageY % d->imageH); } else #endif if ((settings.hacks&hack_Starcraft) > 0) { if (d->imageH%2 == 1) d->imageH -= 1; } else { if ( (d->frameX > 0) && (d->frameW == rdp.ci_width) ) d->frameW -= (uint16_t)(2.0f*d->frameX); if ( (d->frameY > 0) && (d->frameH == rdp.ci_height) ) d->frameH -= (uint16_t)(2.0f*d->frameY); } ul_u = (int)d->imageX; ul_v = (int)d->imageY; lr_u = (int)d->imageX + (int)(d->frameW * d->scaleX); lr_v = (int)d->imageY + (int)(d->frameH * d->scaleY); ul_x = d->frameX; lr_x = d->frameX + d->frameW; ul_y = d->frameY; lr_y = d->frameY + d->frameH; if (d->flipX) { ul_x = d->frameX + d->frameW; lr_x = d->frameX; } if (d->flipY) { ul_y = d->frameY + d->frameH; lr_y = d->frameY; } min_wrap_u = ul_u / d->imageW; min_wrap_v = ul_v / d->imageH; min_256_u = ul_u >> x_shift; min_256_v = ul_v >> y_shift; // SetTextureImage () g_gdp.ti_format = d->imageFmt; // RGBA g_gdp.ti_size = d->imageSiz; // 16-bit g_gdp.ti_address = d->imagePtr; g_gdp.ti_width = (d->imageW%2)?d->imageW-1:d->imageW; rdp.timg.set_by = 0; // SetTile () g_gdp.tile[0].format = d->imageFmt; // RGBA g_gdp.tile[0].size = d->imageSiz; // 16-bit g_gdp.tile[0].line = line; g_gdp.tile[0].tmem = 0; g_gdp.tile[0].palette = (uint8_t)d->imagePal; g_gdp.tile[0].ct = 1; g_gdp.tile[0].mt = 0; g_gdp.tile[0].mask_t = 0; g_gdp.tile[0].shift_t = 0; g_gdp.tile[0].cs = 1; g_gdp.tile[0].ms = 0; g_gdp.tile[0].mask_s = 0; g_gdp.tile[0].shift_s = 0; g_gdp.tile[0].sh = 0; g_gdp.tile[0].th = 0; g_gdp.tile[0].sl = x_size-1; g_gdp.tile[0].tl = y_size-1; Z = set_sprite_combine_mode (); if (((rdp.othermode_h & RDP_CYCLE_TYPE) >> 20) == 2) rdp.allow_combine = 0; { uint32_t minx = 0; uint32_t miny = 0; uint32_t maxx, maxy; if (rdp.ci_width == 512 && !no_dlist) { maxx = settings.scr_res_x; maxy = settings.scr_res_y; } else if (d->scaleX == 1.0f && d->scaleY == 1.0f) { minx = rdp.scissor.ul_x; miny = rdp.scissor.ul_y; maxx = rdp.scissor.lr_x; maxy = rdp.scissor.lr_y; } else { minx = rdp.scissor.ul_x; miny = rdp.scissor.ul_y; maxx = min(rdp.scissor.lr_x, (uint32_t)((d->frameX+d->imageW/d->scaleX+0.5f)*rdp.scale_x)); maxy = min(rdp.scissor.lr_y, (uint32_t)((d->frameY+d->imageH/d->scaleY+0.5f)*rdp.scale_y)); } grClipWindow(minx, miny, maxx, maxy); g_gdp.flags |= UPDATE_SCISSOR; } // Texture () rdp.cur_tile = 0; mx = (float)(lr_x - ul_x) / (float)(lr_u - ul_u); bx = ul_x - mx * ul_u; my = (float)(lr_y - ul_y) / (float)(lr_v - ul_v); by = ul_y - my * ul_v; nul_v = ul_v; nul_y = ul_y; // #162 cur_wrap_v = min_wrap_v + 1; cur_v = min_256_v + 1; cb_v = ((cur_v-1)<= d->imageH) cb_v -= d->imageH; tb_v = cb_v; rdp.bg_image_height = d->imageH; while (1) { int nul_u, cb_u, tb_u; float nul_x, nlr_y; int cur_wrap_u = min_wrap_u + 1; int cur_u = min_256_u + 1; // calculate intersection with this point int nlr_v = min (min (cur_wrap_v*d->imageH, (cur_v<= d->imageW) cb_u -= d->imageW; tb_u = cb_u; while (1) { // calculate intersection with this point nlr_u = min (min (cur_wrap_u * d->imageW, (cur_u<c_scl_x; ful_v *= rdp.cur_cache[0]->c_scl_y; flr_u *= rdp.cur_cache[0]->c_scl_x; flr_v *= rdp.cur_cache[0]->c_scl_y; ful_x = nul_x * rdp.scale_x + rdp.offset_x; flr_x = nlr_x * rdp.scale_x + rdp.offset_x; ful_y = nul_y * rdp.scale_y + rdp.offset_y; flr_y = nlr_y * rdp.scale_y + rdp.offset_y; /* Make the vertices */ if ((flr_x <= rdp.scissor.lr_x) || (ful_x < rdp.scissor.lr_x)) { VERTEX v[4]; v[0].x = ful_x; v[0].y = ful_y; v[0].z = Z; v[0].q = 1.0f; v[0].u[0] = ful_u; v[0].v[0] = ful_v; v[1].x = flr_x; v[1].y = ful_y; v[1].z = Z; v[1].q = 1.0f; v[1].u[0] = flr_u; v[1].v[0] = ful_v; v[2].x = ful_x; v[2].y = flr_y; v[2].z = Z; v[2].q = 1.0f; v[2].u[0] = ful_u; v[2].v[0] = flr_v; v[3].x = flr_x; v[3].y = flr_y; v[3].z = Z; v[3].q = 1.0f; v[3].u[0] = flr_u; v[3].v[0] = flr_v; apply_shading(v); ConvertCoordsConvert (v, 4); grDrawVertexArrayContiguous (GR_TRIANGLE_STRIP, 4, v); } // increment whatever caused this split tb_u += x_size - (x_size-(nlr_u-cb_u)); cb_u = nlr_u; if (nlr_u == cur_wrap_u * d->imageW) { cur_wrap_u ++; tb_u = 0; } if (nlr_u == (cur_u<imageH) { cur_wrap_v ++; tb_v = 0; } if (nlr_v == (cur_v<> 1; d->imageX = (((uint16_t *)gfx_info.RDRAM)[(addr+0)^1] >> 5); // 0 d->imageW = (((uint16_t *)gfx_info.RDRAM)[(addr+1)^1] >> 2); // 1 d->frameX = ((int16_t*)gfx_info.RDRAM)[(addr+2)^1] / 4.0f; // 2 d->frameW = ((uint16_t *)gfx_info.RDRAM)[(addr+3)^1] >> 2; // 3 d->imageY = (((uint16_t *)gfx_info.RDRAM)[(addr+4)^1] >> 5); // 4 d->imageH = (((uint16_t *)gfx_info.RDRAM)[(addr+5)^1] >> 2); // 5 d->frameY = ((int16_t*)gfx_info.RDRAM)[(addr+6)^1] / 4.0f; // 6 d->frameH = ((uint16_t *)gfx_info.RDRAM)[(addr+7)^1] >> 2; // 7 d->imagePtr = RSP_SegmentToPhysical(((uint32_t*)gfx_info.RDRAM)[(addr+8)>>1]); // 8,9 d->imageFmt = ((uint8_t *)gfx_info.RDRAM)[(((addr+11)<<1)+0)^3]; // 11 d->imageSiz = ((uint8_t *)gfx_info.RDRAM)[(((addr+11)<<1)+1)^3]; // | d->imagePal = ((uint16_t *)gfx_info.RDRAM)[(addr+12)^1]; // 12 imageFlip = ((uint16_t *)gfx_info.RDRAM)[(addr+13)^1]; // 13; d->flipX = (uint8_t)imageFlip & G_BG_FLAG_FLIPS; if (bReadScale) { d->scaleX = ((int16_t*)gfx_info.RDRAM)[(addr+14)^1] / 1024.0f; // 14 d->scaleY = ((int16_t*)gfx_info.RDRAM)[(addr+15)^1] / 1024.0f; // 15 } else d->scaleX = d->scaleY = 1.0f; d->flipY = 0; imageYorig= ((int *)gfx_info.RDRAM)[(addr+16)>>1] >> 5; rdp.last_bg = d->imagePtr; #if 0 FRDP ("imagePtr: %08lx\n", d->imagePtr); FRDP ("frameX: %f, frameW: %d, frameY: %f, frameH: %d\n", d->frameX, d->frameW, d->frameY, d->frameH); FRDP ("imageX: %d, imageW: %d, imageY: %d, imageH: %d\n", d->imageX, d->imageW, d->imageY, d->imageH); FRDP ("imageYorig: %d, scaleX: %f, scaleY: %f\n", imageYorig, d->scaleX, d->scaleY); FRDP ("imageFmt: %d, imageSiz: %d, imagePal: %d, imageFlip: %d\n", d->imageFmt, d->imageSiz, d->imagePal, d->flipX); #endif } static void uc6_bg (bool bg_1cyc) { DRAWIMAGE d; //static const char *strFuncNames[] = {"uc6:bg_1cyc", "uc6:bg_copy"}; //const char *strFuncName = bg_1cyc ? strFuncNames[0] : strFuncNames[1]; if (rdp.skip_drawing) return; uc6_read_background_data(&d, bg_1cyc); if (settings.ucode == ucode_F3DEX2/* || (settings.hacks&hack_PPL)*/) { if ( (d.imagePtr != rdp.cimg) && (d.imagePtr != rdp.ocimg) && d.imagePtr) //can't draw from framebuffer DrawImage(&d); #if 0 else { FRDP("%s skipped\n", strFuncName); } #endif } else DrawImage(&d); } static void uc6_bg_1cyc(uint32_t w0, uint32_t w1) { uc6_bg(true); } static void uc6_bg_copy(uint32_t w0, uint32_t w1) { uc6_bg(false); } static void draw_split_triangle(VERTEX **vtx) { int index,i,j, min_256,max_256, cur_256; float percent; vtx[0]->not_zclipped = vtx[1]->not_zclipped = vtx[2]->not_zclipped = 1; min_256 = min((int)vtx[0]->u[0],(int)vtx[1]->u[0]); // bah, don't put two mins on one line min_256 = min(min_256,(int)vtx[2]->u[0]) >> 8; // or it will be calculated twice max_256 = max((int)vtx[0]->u[0],(int)vtx[1]->u[0]); // not like it makes much difference max_256 = max(max_256,(int)vtx[2]->u[0]) >> 8; // anyway :P for (cur_256=min_256; cur_256<=max_256; cur_256++) { int left_256 = cur_256 << 8; int right_256 = (cur_256+1) << 8; // Set vertex buffers rdp.vtxbuf = rdp.vtx1; // copy from v to rdp.vtx1 rdp.vtxbuf2 = rdp.vtx2; rdp.vtx_buffer = 0; rdp.n_global = 3; index = 0; // ** Left plane ** for (i=0; i<3; i++) { VERTEX *v2 = NULL; VERTEX *v1 = (VERTEX*)vtx[i]; j = i+1; if (j == 3) j = 0; v2 = (VERTEX*)vtx[j]; if (v1->u[0] >= left_256) { if (v2->u[0] >= left_256) // Both are in, save the last one { rdp.vtxbuf[index] = *v2; rdp.vtxbuf[index].u[0] -= left_256; rdp.vtxbuf[index++].v[0] += rdp.cur_cache[0]->c_scl_y * (cur_256 * rdp.cur_cache[0]->splitheight); } else // First is in, second is out, save intersection { percent = (left_256 - v1->u[0]) / (v2->u[0] - v1->u[0]); rdp.vtxbuf[index].x = v1->x + (v2->x - v1->x) * percent; rdp.vtxbuf[index].y = v1->y + (v2->y - v1->y) * percent; rdp.vtxbuf[index].z = 1; rdp.vtxbuf[index].q = 1; rdp.vtxbuf[index].u[0] = 0.5f; rdp.vtxbuf[index].v[0] = v1->v[0] + (v2->v[0] - v1->v[0]) * percent + rdp.cur_cache[0]->c_scl_y * cur_256 * rdp.cur_cache[0]->splitheight; rdp.vtxbuf[index].b = (uint8_t)(v1->b + (v2->b - v1->b) * percent); rdp.vtxbuf[index].g = (uint8_t)(v1->g + (v2->g - v1->g) * percent); rdp.vtxbuf[index].r = (uint8_t)(v1->r + (v2->r - v1->r) * percent); rdp.vtxbuf[index++].a = (uint8_t)(v1->a + (v2->a - v1->a) * percent); } } else { if (v2->u[0] >= left_256) // First is out, second is in, save intersection & in point { percent = (left_256 - v2->u[0]) / (v1->u[0] - v2->u[0]); rdp.vtxbuf[index].x = v2->x + (v1->x - v2->x) * percent; rdp.vtxbuf[index].y = v2->y + (v1->y - v2->y) * percent; rdp.vtxbuf[index].z = 1; rdp.vtxbuf[index].q = 1; rdp.vtxbuf[index].u[0] = 0.5f; rdp.vtxbuf[index].v[0] = v2->v[0] + (v1->v[0] - v2->v[0]) * percent + rdp.cur_cache[0]->c_scl_y * cur_256 * rdp.cur_cache[0]->splitheight; rdp.vtxbuf[index].b = (uint8_t)(v2->b + (v1->b - v2->b) * percent); rdp.vtxbuf[index].g = (uint8_t)(v2->g + (v1->g - v2->g) * percent); rdp.vtxbuf[index].r = (uint8_t)(v2->r + (v1->r - v2->r) * percent); rdp.vtxbuf[index++].a = (uint8_t)(v2->a + (v1->a - v2->a) * percent); // Save the in point rdp.vtxbuf[index] = *v2; rdp.vtxbuf[index].u[0] -= left_256; rdp.vtxbuf[index++].v[0] += rdp.cur_cache[0]->c_scl_y * (cur_256 * rdp.cur_cache[0]->splitheight); } } } rdp.n_global = index; rdp.vtxbuf = rdp.vtx2; // now vtx1 holds the value, & vtx2 is the destination rdp.vtxbuf2 = rdp.vtx1; rdp.vtx_buffer ^= 1; index = 0; for (i=0; iu[0] <= 256.0f) { if (v2->u[0] <= 256.0f) // Both are in, save the last one { rdp.vtxbuf[index++] = *v2; } else // First is in, second is out, save intersection { percent = (right_256 - v1->u[0]) / (v2->u[0] - v1->u[0]); rdp.vtxbuf[index].x = v1->x + (v2->x - v1->x) * percent; rdp.vtxbuf[index].y = v1->y + (v2->y - v1->y) * percent; rdp.vtxbuf[index].z = 1; rdp.vtxbuf[index].q = 1; rdp.vtxbuf[index].u[0] = 255.5f; rdp.vtxbuf[index].v[0] = v1->v[0] + (v2->v[0] - v1->v[0]) * percent; rdp.vtxbuf[index].b = (uint8_t)(v1->b + (v2->b - v1->b) * percent); rdp.vtxbuf[index].g = (uint8_t)(v1->g + (v2->g - v1->g) * percent); rdp.vtxbuf[index].r = (uint8_t)(v1->r + (v2->r - v1->r) * percent); rdp.vtxbuf[index++].a = (uint8_t)(v1->a + (v2->a - v1->a) * percent); } } else { if (v2->u[0] <= 256.0f) // First is out, second is in, save intersection & in point { percent = (right_256 - v2->u[0]) / (v1->u[0] - v2->u[0]); rdp.vtxbuf[index].x = v2->x + (v1->x - v2->x) * percent; rdp.vtxbuf[index].y = v2->y + (v1->y - v2->y) * percent; rdp.vtxbuf[index].z = 1; rdp.vtxbuf[index].q = 1; rdp.vtxbuf[index].u[0] = 255.5f; rdp.vtxbuf[index].v[0] = v2->v[0] + (v1->v[0] - v2->v[0]) * percent; rdp.vtxbuf[index].b = (uint8_t)(v2->b + (v1->b - v2->b) * percent); rdp.vtxbuf[index].g = (uint8_t)(v2->g + (v1->g - v2->g) * percent); rdp.vtxbuf[index].r = (uint8_t)(v2->r + (v1->r - v2->r) * percent); rdp.vtxbuf[index++].a = (uint8_t)(v2->a + (v1->a - v2->a) * percent); // Save the in point rdp.vtxbuf[index++] = *v2; } } } rdp.n_global = index; do_triangle_stuff_2 (0, 1, 1); } } static void uc6_draw_polygons (VERTEX v[4]) { apply_shading(v); { rdp.vtxbuf = rdp.vtx1; // copy from v to rdp.vtx1 rdp.vtxbuf2 = rdp.vtx2; rdp.vtx_buffer = 0; rdp.n_global = 3; memcpy (rdp.vtxbuf, v, sizeof(VERTEX)*3); do_triangle_stuff_2 (0, 1, 1); rdp.vtxbuf = rdp.vtx1; // copy from v to rdp.vtx1 rdp.vtxbuf2 = rdp.vtx2; rdp.vtx_buffer = 0; rdp.n_global = 3; memcpy (rdp.vtxbuf, v+1, sizeof(VERTEX)*3); do_triangle_stuff_2 (0, 1, 1); } g_gdp.flags |= UPDATE_ZBUF_ENABLED | UPDATE_VIEWPORT; if (settings.fog && (rdp.flags & FOG_ENABLED)) grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT, g_gdp.fog_color.total); } static void uc6_read_object_data (DRAWOBJECT *d) { uint32_t addr = RSP_SegmentToPhysical(rdp.cmd1) >> 1; d->objX = ((int16_t*)gfx_info.RDRAM)[(addr+0)^1] / 4.0f; // 0 d->scaleW = ((uint16_t *)gfx_info.RDRAM)[(addr+1)^1] / 1024.0f; // 1 d->imageW = ((int16_t*)gfx_info.RDRAM)[(addr+2)^1] >> 5; // 2, 3 is padding d->objY = ((int16_t*)gfx_info.RDRAM)[(addr+4)^1] / 4.0f; // 4 d->scaleH = ((uint16_t *)gfx_info.RDRAM)[(addr+5)^1] / 1024.0f; // 5 d->imageH = ((int16_t*)gfx_info.RDRAM)[(addr+6)^1] >> 5; // 6, 7 is padding d->imageStride = ((uint16_t *)gfx_info.RDRAM)[(addr+8)^1]; // 8 d->imageAdrs = ((uint16_t *)gfx_info.RDRAM)[(addr+9)^1]; // 9 d->imageFmt = ((uint8_t *)gfx_info.RDRAM)[(((addr+10)<<1)+0)^3]; // 10 d->imageSiz = ((uint8_t *)gfx_info.RDRAM)[(((addr+10)<<1)+1)^3]; // | d->imagePal = ((uint8_t *)gfx_info.RDRAM)[(((addr+10)<<1)+2)^3]; // 11 d->imageFlags = ((uint8_t *)gfx_info.RDRAM)[(((addr+10)<<1)+3)^3]; // | if (d->imageW < 0) d->imageW = (int16_t)g_gdp.__clip.xl - (int16_t)d->objX - d->imageW; if (d->imageH < 0) d->imageH = (int16_t)g_gdp.__clip.yl - (int16_t)d->objY - d->imageH; } static void uc6_init_tile(const DRAWOBJECT *d) { // SetTile () g_gdp.tile[0].format = d->imageFmt; // RGBA g_gdp.tile[0].size = d->imageSiz; // 16-bit g_gdp.tile[0].line = d->imageStride; g_gdp.tile[0].tmem = d->imageAdrs; g_gdp.tile[0].palette = d->imagePal; g_gdp.tile[0].ct = 1; g_gdp.tile[0].mt = 0; g_gdp.tile[0].mask_t = 0; g_gdp.tile[0].shift_t = 0; g_gdp.tile[0].cs = 1; g_gdp.tile[0].ms = 0; g_gdp.tile[0].mask_s = 0; g_gdp.tile[0].shift_s = 0; // SetTileSize () g_gdp.tile[0].sh = 0; g_gdp.tile[0].th = 0; g_gdp.tile[0].sl = (d->imageW>0)?d->imageW-1:0; g_gdp.tile[0].tl = (d->imageH>0)?d->imageH-1:0; } static void uc6_obj_rectangle(uint32_t w0, uint32_t w1) { int i; float Z, ul_x, lr_x, ul_y, lr_y, ul_u, ul_v, lr_u, lr_v; VERTEX v[4]; DRAWOBJECT d; uc6_read_object_data(&d); if (d.imageAdrs > 4096) { FRDP("tmem: %08lx is out of bounds! return\n", d.imageAdrs); return; } if (!rdp.s2dex_tex_loaded) { LRDP("Texture was not loaded! return\n"); return; } uc6_init_tile(&d); Z = set_sprite_combine_mode(); ul_x = d.objX; lr_x = d.objX + d.imageW / d.scaleW; ul_y = d.objY; lr_y = d.objY + d.imageH / d.scaleH; lr_u = 255.0f*rdp.cur_cache[0]->scale_x; lr_v = 255.0f*rdp.cur_cache[0]->scale_y; ul_u = 0.5f; ul_v = 0.5f; if (d.imageFlags & G_BG_FLAG_FLIPS) /* flipS */ { ul_u = lr_u; lr_u = 0.5f; } if (d.imageFlags & G_BG_FLAG_FLIPT) //flipT { ul_v = lr_v; lr_v = 0.5f; } /* Make the vertices */ v[0].x = ul_x; v[0].y = ul_y; v[0].z = Z; v[0].q = 1.0f; v[0].u[0] = ul_u; v[0].v[0] = ul_v; v[1].x = lr_x; v[1].y = ul_y; v[1].z = Z; v[1].q = 1.0f; v[1].u[0] = lr_u; v[1].v[0] = ul_v; v[2].x = ul_x; v[2].y = lr_y; v[2].z = Z; v[2].q = 1.0f; v[2].u[0] = ul_u; v[2].v[0] = lr_v; v[3].x = lr_x; v[3].y = lr_y; v[3].z = Z; v[3].q = 1.0f; v[3].u[0] = lr_u; v[3].v[0] = lr_v; for (i = 0; i < 4; i++) { v[i].x = (v[i].x * rdp.scale_x) + rdp.offset_x; v[i].y = (v[i].y * rdp.scale_y) + rdp.offset_y; } uc6_draw_polygons (v); } static void uc6_obj_sprite(uint32_t w0, uint32_t w1) { DRAWOBJECT d; VERTEX v[4]; int i; float Z, ul_x, lr_x, ul_y, lr_y, ul_u, lr_u, ul_v, lr_v; uc6_read_object_data(&d); uc6_init_tile(&d); Z = set_sprite_combine_mode (); ul_x = d.objX; lr_x = d.objX + d.imageW/d.scaleW; ul_y = d.objY; lr_y = d.objY + d.imageH/d.scaleH; #if 0 if (rdp.cur_cache[0]->splits > 1) { lr_u = (float)(d.imageW-1); lr_v = (float)(d.imageH-1); } else #endif { lr_u = 255.0f*rdp.cur_cache[0]->scale_x; lr_v = 255.0f*rdp.cur_cache[0]->scale_y; } if (d.imageFlags&0x01) //flipS { ul_u = lr_u; lr_u = 0.5f; } else ul_u = 0.5f; if (d.imageFlags&0x10) //flipT { ul_v = lr_v; lr_v = 0.5f; } else ul_v = 0.5f; /* Make the vertices */ // FRDP("scale_x: %f, scale_y: %f\n", rdp.cur_cache[0]->scale_x, rdp.cur_cache[0]->scale_y); v[0].x = ul_x; v[0].y = ul_y; v[0].z = Z; v[0].q = 1.0f; v[0].u[0] = ul_u; v[0].v[0] = ul_v; v[1].x = lr_x; v[1].y = ul_y; v[1].z = Z; v[1].q = 1.0f; v[1].u[0] = lr_u; v[1].v[0] = ul_v; v[2].x = ul_x; v[2].y = lr_y; v[2].z = Z; v[2].q = 1.0f; v[2].u[0] = ul_u; v[2].v[0] = lr_v; v[3].x = lr_x; v[3].y = lr_y; v[3].z = Z; v[3].q = 1.0f; v[3].u[0] = lr_u; v[3].v[0] = lr_v; for (i = 0; i < 4; i++) { float x = v[i].x; float y = v[i].y; v[i].x = ((x * mat_2d.A + y * mat_2d.B + mat_2d.X) * rdp.scale_x) + rdp.offset_x; v[i].y = ((x * mat_2d.C + y * mat_2d.D + mat_2d.Y) * rdp.scale_y) + rdp.offset_y; } uc6_draw_polygons (v); } static void uc6_obj_movemem(uint32_t w0, uint32_t w1) { int index = w0 & 0xFFFF; uint32_t addr = RSP_SegmentToPhysical(w1) >> 1; if (index == 0) { // movemem matrix mat_2d.A = ((int*)gfx_info.RDRAM)[(addr+0)>>1] / 65536.0f; mat_2d.B = ((int*)gfx_info.RDRAM)[(addr+2)>>1] / 65536.0f; mat_2d.C = ((int*)gfx_info.RDRAM)[(addr+4)>>1] / 65536.0f; mat_2d.D = ((int*)gfx_info.RDRAM)[(addr+6)>>1] / 65536.0f; mat_2d.X = ((short*)gfx_info.RDRAM)[(addr+8)^1] / 4.0f; mat_2d.Y = ((short*)gfx_info.RDRAM)[(addr+9)^1] / 4.0f; mat_2d.BaseScaleX = ((uint16_t*)gfx_info.RDRAM)[(addr+10)^1] / 1024.0f; mat_2d.BaseScaleY = ((uint16_t*)gfx_info.RDRAM)[(addr+11)^1] / 1024.0f; //FRDP ("mat_2d\nA: %f, B: %f, c: %f, D: %f\nX: %f, Y: %f\nBaseScaleX: %f, BaseScaleY: %f\n", mat_2d.A, mat_2d.B, mat_2d.C, mat_2d.D, mat_2d.X, mat_2d.Y, mat_2d.BaseScaleX, mat_2d.BaseScaleY); } else if (index == 2) { // movemem submatrix mat_2d.X = ((short*)gfx_info.RDRAM)[(addr+0)^1] / 4.0f; mat_2d.Y = ((short*)gfx_info.RDRAM)[(addr+1)^1] / 4.0f; mat_2d.BaseScaleX = ((uint16_t*)gfx_info.RDRAM)[(addr+2)^1] / 1024.0f; mat_2d.BaseScaleY = ((uint16_t*)gfx_info.RDRAM)[(addr+3)^1] / 1024.0f; //FRDP ("submatrix\nX: %f, Y: %f\nBaseScaleX: %f, BaseScaleY: %f\n", mat_2d.X, mat_2d.Y, mat_2d.BaseScaleX, mat_2d.BaseScaleY); } } static void uc6_select_dl(uint32_t w0, uint32_t w1) { } static void uc6_obj_rendermode(uint32_t w0, uint32_t w1) { } static uint16_t uc6_yuv_to_rgba(uint8_t y, uint8_t u, uint8_t v) { float r, g, b; uint16_t c; r = y + (1.370705f * (v-128)); g = y - (0.698001f * (v-128)) - (0.337633f * (u-128)); b = y + (1.732446f * (u-128)); r *= 0.125f; g *= 0.125f; b *= 0.125f; //clipping the result if (r > 32) r = 32; if (g > 32) g = 32; if (b > 32) b = 32; if (r < 0) r = 0; if (g < 0) g = 0; if (b < 0) b = 0; c = (uint16_t)(((uint16_t)(r) << 11) | ((uint16_t)(g) << 6) | ((uint16_t)(b) << 1) | 1); return c; } static void uc6_DrawYUVImageToFrameBuffer(uint16_t ul_x, uint16_t ul_y, uint16_t lr_x, uint16_t lr_y) { uint16_t h, w, *dst; uint32_t ci_width, ci_height, width, height, *mb; ci_width = rdp.ci_width; ci_height = rdp.ci_lower_bound; FRDP ("uc6:DrawYUVImageToFrameBuffer ul_x%d, ul_y%d, lr_x%d, lr_y%d\n", ul_x, ul_y, lr_x, lr_y); if (ul_x >= ci_width) return; if (ul_y >= ci_height) return; width = 16; height = 16; if (lr_x > ci_width) width = ci_width - ul_x; if (lr_y > ci_height) height = ci_height - ul_y; mb = (uint32_t*)(gfx_info.RDRAM+g_gdp.ti_address); //pointer to the first macro block dst = (uint16_t*)(gfx_info.RDRAM+rdp.cimg); dst += ul_x + ul_y * ci_width; //yuv macro block contains 16x16 texture. we need to put it in the proper place inside cimg for (h = 0; h < 16; h++) { for (w = 0; w < 16; w+=2) { uint32_t t = *(mb++); //each uint32_t contains 2 pixels if ((h < height) && (w < width)) //clipping. texture image may be larger than color image { uint8_t y0, v, y1, u; y0 = (uint8_t)t&0xFF; v = (uint8_t)(t>>8)&0xFF; y1 = (uint8_t)(t>>16)&0xFF; u = (uint8_t)(t>>24)&0xFF; *(dst++) = uc6_yuv_to_rgba(y0, u, v); *(dst++) = uc6_yuv_to_rgba(y1, u, v); } } dst += rdp.ci_width - 16; } } static void uc6_obj_rectangle_r(uint32_t w0, uint32_t w1) { int i; float Z, ul_x, lr_x, ul_y, lr_y, ul_u, ul_v, lr_u, lr_v; VERTEX v[4]; DRAWOBJECT d; uc6_read_object_data(&d); if (d.imageFmt == 1 && (settings.hacks&hack_Ogre64)) //Ogre Battle needs to copy YUV texture to frame buffer { ul_x = d.objX/mat_2d.BaseScaleX + mat_2d.X; lr_x = (d.objX + d.imageW / d.scaleW) / mat_2d.BaseScaleX + mat_2d.X; ul_y = d.objY / mat_2d.BaseScaleY + mat_2d.Y; lr_y = (d.objY + d.imageH / d.scaleH) / mat_2d.BaseScaleY + mat_2d.Y; uc6_DrawYUVImageToFrameBuffer((uint16_t)ul_x, (uint16_t)ul_y, (uint16_t)lr_x, (uint16_t)lr_y); return; } uc6_init_tile(&d); Z = set_sprite_combine_mode(); ul_x = d.objX / mat_2d.BaseScaleX; lr_x = (d.objX + d.imageW / d.scaleW) / mat_2d.BaseScaleX; ul_y = d.objY / mat_2d.BaseScaleY; lr_y = (d.objY + d.imageH / d.scaleH) / mat_2d.BaseScaleY; lr_u = 255.0f * rdp.cur_cache[0]->scale_x; lr_v = 255.0f * rdp.cur_cache[0]->scale_y; if (d.imageFlags & G_BG_FLAG_FLIPS) //flipS { ul_u = lr_u; lr_u = 0.5f; } else ul_u = 0.5f; if (d.imageFlags & G_BG_FLAG_FLIPT) //flipT { ul_v = lr_v; lr_v = 0.5f; } else ul_v = 0.5f; /* Make the vertices */ v[0].x = ul_x; v[0].y = ul_y; v[0].z = Z; v[0].q = 1.0f; v[0].u[0] = ul_u; v[0].v[0] = ul_v; v[1].x = lr_x; v[1].y = ul_y; v[1].z = Z; v[1].q = 1.0f; v[1].u[0] = lr_u; v[1].v[0] = ul_v; v[2].x = ul_x; v[2].y = lr_y; v[2].z = Z; v[2].q = 1.0f; v[2].u[0] = ul_u; v[2].v[0] = lr_v; v[3].x = lr_x; v[3].y = lr_y; v[3].z = Z; v[3].q = 1.0f; v[3].u[0] = lr_u; v[3].v[0] = lr_v; for (i = 0; i < 4; i++) { v[i].x = ((v[i].x + mat_2d.X) * rdp.scale_x) + rdp.offset_x; v[i].y = ((v[i].y + mat_2d.Y) * rdp.scale_y) + rdp.offset_y; } uc6_draw_polygons (v); } static void uc6_obj_loadtxtr(uint32_t w0, uint32_t w1) { uint32_t addr, type; rdp.s2dex_tex_loaded = true; g_gdp.flags |= UPDATE_TEXTURE; addr = RSP_SegmentToPhysical(w1) >> 1; type = ((uint32_t*)gfx_info.RDRAM)[(addr + 0) >> 1]; // 0, 1 if (type == 0x00000030) { // TLUT uint32_t image = RSP_SegmentToPhysical(((uint32_t*)gfx_info.RDRAM)[(addr + 2) >> 1]); // 2, 3 uint16_t phead = ((uint16_t *)gfx_info.RDRAM)[(addr + 4) ^ 1] - 256; // 4 uint16_t pnum = ((uint16_t *)gfx_info.RDRAM)[(addr + 5) ^ 1] + 1; // 5 //FRDP ("palette addr: %08lx, start: %d, num: %d\n", image, phead, pnum); load_palette (image, phead, pnum); } else if (type == 0x00001033) { // TxtrBlock uint32_t image = RSP_SegmentToPhysical(((uint32_t*)gfx_info.RDRAM)[(addr + 2) >> 1]); // 2, 3 uint16_t tmem = ((uint16_t *)gfx_info.RDRAM)[(addr + 4) ^ 1]; // 4 uint16_t tsize = ((uint16_t *)gfx_info.RDRAM)[(addr + 5) ^ 1]; // 5 uint16_t tline = ((uint16_t *)gfx_info.RDRAM)[(addr + 6) ^ 1]; // 6 //FRDP ("addr: %08lx, tmem: %08lx, size: %d\n", image, tmem, tsize); g_gdp.ti_address = image; g_gdp.ti_width = 1; g_gdp.ti_size = G_IM_SIZ_8b; g_gdp.tile[7].tmem = tmem; g_gdp.tile[7].size = 1; rdp.cmd0 = 0; rdp.cmd1 = 0x07000000 | (tsize << 14) | tline; rdp_loadblock(rdp.cmd0, rdp.cmd1); } else if (type == 0x00fc1034) { int line; uint32_t image = RSP_SegmentToPhysical(((uint32_t*)gfx_info.RDRAM)[(addr + 2) >> 1]); // 2, 3 uint16_t tmem = ((uint16_t *)gfx_info.RDRAM)[(addr + 4) ^ 1]; // 4 uint16_t twidth = ((uint16_t *)gfx_info.RDRAM)[(addr + 5) ^ 1]; // 5 uint16_t theight = ((uint16_t *)gfx_info.RDRAM)[(addr + 6) ^ 1]; // 6 #if 0 FRDP ("tile addr: %08lx, tmem: %08lx, twidth: %d, theight: %d\n", image, tmem, twidth, theight); #endif line = (twidth + 1) >> 2; g_gdp.ti_address = image; g_gdp.ti_width = line << 3; g_gdp.ti_size = G_IM_SIZ_8b; g_gdp.tile[7].tmem = tmem; g_gdp.tile[7].line = line; g_gdp.tile[7].size = 1; rdp.cmd0 = 0; rdp.cmd1 = 0x07000000 | (twidth << 14) | (theight << 2); rdp_loadtile(rdp.cmd0, rdp.cmd1); } #if 0 else { FRDP ("UNKNOWN (0x%08lx)\n", type); FRDP_E ("uc6:obj_loadtxtr UNKNOWN (0x%08lx)\n", type); } #endif } static void uc6_obj_ldtx_sprite(uint32_t w0, uint32_t w1) { uint32_t addr = w1; uc6_obj_loadtxtr(rdp.cmd0, rdp.cmd1); rdp.cmd1 = addr + 24; uc6_obj_sprite(rdp.cmd0, rdp.cmd1); } static void uc6_obj_ldtx_rect(uint32_t w0, uint32_t w1) { uint32_t addr = w1; uc6_obj_loadtxtr(rdp.cmd0, rdp.cmd1); rdp.cmd1 = addr + 24; uc6_obj_rectangle(rdp.cmd0, rdp.cmd1); } static void uc6_ldtx_rect_r(uint32_t w0, uint32_t w1) { uint32_t addr = w1; uc6_obj_loadtxtr(rdp.cmd0, rdp.cmd1); rdp.cmd1 = addr + 24; uc6_obj_rectangle_r(rdp.cmd0, rdp.cmd1); } static void uc6_loaducode(uint32_t w0, uint32_t w1) { // copy the microcode data uint32_t addr = RSP_SegmentToPhysical(w1); uint32_t size = (w0 & 0xFFFF) + 1; memcpy (microcode, gfx_info.RDRAM+addr, size); microcheck (); } static void uc6_sprite2d(uint32_t w0, uint32_t w1) { uint16_t stride; uint32_t addr, tlut; int i; DRAWIMAGE d; uint32_t a = rdp.pc[rdp.pc_i] & BMASK; uint32_t cmd0 = ((uint32_t*)gfx_info.RDRAM)[a>>2]; //check next command if ( (cmd0>>24) != 0xBE ) return; addr = RSP_SegmentToPhysical(w1) >> 1; d.imagePtr = RSP_SegmentToPhysical(((uint32_t*)gfx_info.RDRAM)[(addr+0)>>1]); // 0,1 stride = (((uint16_t *)gfx_info.RDRAM)[(addr+4)^1]); // 4 d.imageW = (((uint16_t *)gfx_info.RDRAM)[(addr+5)^1]); // 5 d.imageH = (((uint16_t *)gfx_info.RDRAM)[(addr+6)^1]); // 6 d.imageFmt = ((uint8_t *)gfx_info.RDRAM)[(((addr+7)<<1)+0)^3]; // 7 d.imageSiz = ((uint8_t *)gfx_info.RDRAM)[(((addr+7)<<1)+1)^3]; // | d.imagePal = 0; d.imageX = (((uint16_t *)gfx_info.RDRAM)[(addr+8)^1]); // 8 d.imageY = (((uint16_t *)gfx_info.RDRAM)[(addr+9)^1]); // 9 tlut = ((uint32_t*)gfx_info.RDRAM)[(addr + 2) >> 1]; // 2, 3 //low-level implementation of sprite2d apparently calls setothermode command to set tlut mode //However, description of sprite2d microcode just says that //TlutPointer should be Null when CI images will not be used. //HLE implementation sets rdp.tlut_mode=2 if TlutPointer is not null, and rdp.tlut_mode=0 otherwise //Alas, it is not sufficient, since WCW Nitro uses non-Null TlutPointer for rgba textures. //So, additional check added. rdp.tlut_mode = 0; if (tlut) { load_palette (RSP_SegmentToPhysical(tlut), 0, 256); if (d.imageFmt > 0) rdp.tlut_mode = 2; else rdp.tlut_mode = 0; } if (d.imageW == 0) return;// d.imageW = stride; cmd0 = ((uint32_t*)gfx_info.RDRAM)[a>>2]; //check next command while (1) { uint32_t texsize, maxTexSize; if ( (cmd0>>24) == 0xBE ) { uint32_t cmd1 = ((uint32_t*)gfx_info.RDRAM)[(a>>2)+1]; rdp.pc[rdp.pc_i] = (a+8) & BMASK; d.scaleX = ((cmd1>>16)&0xFFFF)/1024.0f; d.scaleY = (cmd1&0xFFFF)/1024.0f; //the code below causes wrong background height in super robot spirit, so it is disabled. //need to find, for which game this hack was made //if( (cmd1&0xFFFF) < 0x100 ) // d.scaleY = d.scaleX; d.flipX = (uint8_t)((cmd0>>8)&0xFF); d.flipY = (uint8_t)(cmd0&0xFF); a = rdp.pc[rdp.pc_i] & BMASK; rdp.pc[rdp.pc_i] = (a+8) & BMASK; cmd0 = ((uint32_t*)gfx_info.RDRAM)[a>>2]; //check next command } if ( (cmd0>>24) == 0xBD ) { uint32_t cmd1 = ((uint32_t*)gfx_info.RDRAM)[(a>>2)+1]; d.frameX = ((int16_t)((cmd1>>16)&0xFFFF)) / 4.0f; d.frameY = ((int16_t)(cmd1&0xFFFF)) / 4.0f; d.frameW = (uint16_t) (d.imageW / d.scaleX); d.frameH = (uint16_t) (d.imageH / d.scaleY); if (settings.hacks&hack_WCWnitro) { int scaleY = (int)d.scaleY; d.imageH /= scaleY; d.imageY /= scaleY; stride *= scaleY; d.scaleY = 1.0f; } #if 0 FRDP ("imagePtr: %08lx\n", d.imagePtr); FRDP ("frameX: %f, frameW: %d, frameY: %f, frameH: %d\n", d.frameX, d.frameW, d.frameY, d.frameH); FRDP ("imageX: %d, imageW: %d, imageY: %d, imageH: %d\n", d.imageX, d.imageW, d.imageY, d.imageH); FRDP ("imageFmt: %d, imageSiz: %d, imagePal: %d, imageStride: %d\n", d.imageFmt, d.imageSiz, d.imagePal, stride); FRDP ("scaleX: %f, scaleY: %f\n", d.scaleX, d.scaleY); #endif } else return; texsize = (d.imageW * d.imageH) << d.imageSiz >> 1; maxTexSize = rdp.tlut_mode < 2 ? 4096 : 2048; if (texsize > maxTexSize) { if (d.scaleX != 1) d.scaleX *= (float)stride/(float)d.imageW; d.imageW = stride; d.imageH += d.imageY; DrawImage(&d); } else { float Z, ul_x, ul_y, lr_x, lr_y, lr_u, lr_v; TILE *tile; VERTEX v[4]; uint16_t line = d.imageW; if (line & 7) line += 8; // round up line >>= 3; if (d.imageSiz == 0) { if (line%2) line++; line >>= 1; } else { line <<= (d.imageSiz-1); } if (line == 0) line = 1; g_gdp.ti_address = d.imagePtr; g_gdp.ti_width = stride; g_gdp.tile[7].tmem = 0; g_gdp.tile[7].line = line;//(d.imageW>>3); g_gdp.tile[7].size = d.imageSiz; rdp.cmd0 = (d.imageX << 14) | (d.imageY << 2); rdp.cmd1 = 0x07000000 | ((d.imageX+d.imageW-1) << 14) | ((d.imageY+d.imageH-1) << 2); rdp_loadtile(rdp.cmd0, rdp.cmd1); // SetTile () g_gdp.tile[0].format = d.imageFmt; g_gdp.tile[0].size = d.imageSiz; g_gdp.tile[0].line = line;//(d.imageW>>3); g_gdp.tile[0].tmem = 0; g_gdp.tile[0].palette = 0; g_gdp.tile[0].ct = 1; g_gdp.tile[0].mt = 0; g_gdp.tile[0].mask_t = 0; g_gdp.tile[0].shift_t = 0; g_gdp.tile[0].cs = 1; g_gdp.tile[0].ms = 0; g_gdp.tile[0].mask_s = 0; g_gdp.tile[0].shift_s = 0; // SetTileSize () g_gdp.tile[0].sh = d.imageX; g_gdp.tile[0].th = d.imageY; g_gdp.tile[0].sl = d.imageX+d.imageW-1; g_gdp.tile[0].tl = d.imageY+d.imageH-1; Z = set_sprite_combine_mode (); if (d.flipX) { ul_x = d.frameX + d.frameW; lr_x = d.frameX; } else { ul_x = d.frameX; lr_x = d.frameX + d.frameW; } if (d.flipY) { ul_y = d.frameY + d.frameH; lr_y = d.frameY; } else { ul_y = d.frameY; lr_y = d.frameY + d.frameH; } #if 0 if (rdp.cur_cache[0]->splits > 1) { lr_u = (float)(d.imageW-1); lr_v = (float)(d.imageH-1); } else #endif { lr_u = 255.0f*rdp.cur_cache[0]->scale_x; lr_v = 255.0f*rdp.cur_cache[0]->scale_y; } /* Make the vertices */ v[0].x = ul_x; v[0].y = ul_y; v[0].z = Z; v[0].q = 1.0f; v[0].u[0] = 0.5f; v[0].v[0] = 0.5f; v[1].x = lr_x; v[1].y = ul_y; v[1].z = Z; v[1].q = 1.0f; v[1].u[0] = lr_u; v[1].v[0] = 0.5f; v[2].x = ul_x; v[2].y = lr_y; v[2].z = Z; v[2].q = 1.0f; v[2].u[0] = 0.5f; v[2].v[0] = lr_v; v[3].x = lr_x; v[3].y = lr_y; v[3].z = Z; v[3].q = 1.0f; v[3].u[0] = lr_u; v[3].v[0] = lr_v; for (i=0; i<4; i++) { v[i].x = (v[i].x * rdp.scale_x) + rdp.offset_x; v[i].y = (v[i].y * rdp.scale_y) + rdp.offset_y; } apply_shading(v); #if 0 // Set vertex buffers if (rdp.cur_cache[0]->splits > 1) { VERTEX *vptr[3]; for (i = 0; i < 3; i++) vptr[i] = &v[i]; draw_split_triangle(vptr); for (i = 0; i < 3; i++) vptr[i] = &v[i+1]; draw_split_triangle(vptr); } else #endif { rdp.vtxbuf = rdp.vtx1; // copy from v to rdp.vtx1 rdp.vtxbuf2 = rdp.vtx2; rdp.vtx_buffer = 0; rdp.n_global = 3; memcpy (rdp.vtxbuf, v, sizeof(VERTEX)*3); do_triangle_stuff_2 (0, 1, 1); rdp.vtxbuf = rdp.vtx1; // copy from v to rdp.vtx1 rdp.vtxbuf2 = rdp.vtx2; rdp.vtx_buffer = 0; rdp.n_global = 3; memcpy (rdp.vtxbuf, v+1, sizeof(VERTEX)*3); do_triangle_stuff_2 (0, 1, 1); } g_gdp.flags |= UPDATE_ZBUF_ENABLED | UPDATE_VIEWPORT; if (settings.fog && (rdp.flags & FOG_ENABLED)) grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT, g_gdp.fog_color.total); } a = rdp.pc[rdp.pc_i] & BMASK; cmd0 = ((uint32_t*)gfx_info.RDRAM)[a>>2]; //check next command if (( (cmd0>>24) == 0xBD ) || ( (cmd0>>24) == 0xBE )) rdp.pc[rdp.pc_i] = (a+8) & BMASK; else return; } } mupen64plus-core/src/dd/dd_disk.c000664 001750 001750 00000020115 12655644434 017771 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - dd_disk.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2015 LuigiBlood * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include "dd_controller.h" #include "dd_disk.h" #include "pi/pi_controller.h" #include "api/callbacks.h" #include "api/config.h" #include "api/m64p_config.h" #include "api/m64p_types.h" #include "main/main.h" #include "main/rom.h" #include "main/util.h" #include "r4300/r4300_core.h" /* Global loaded disk memory space. */ unsigned char* g_dd_disk = NULL; /* Global loaded disk size. */ int g_dd_disk_size = 0; int dd_bm_mode_read; //BM MODE 0 = WRITE, MODE 1 = READ int CUR_BLOCK; //Current Block int dd_sector55; int dd_zone; //Current Zone int dd_track_offset; //Offset to Track const unsigned int ddZoneSecSize[16] = { 232, 216, 208, 192, 176, 160, 144, 128, 216, 208, 192, 176, 160, 144, 128, 112 }; const unsigned int ddZoneTrackSize[16] = { 158, 158, 149, 149, 149, 149, 149, 114, 158, 158, 149, 149, 149, 149, 149, 114 }; const unsigned int ddStartOffset[16] = { 0x0, 0x5F15E0, 0xB79D00, 0x10801A0, 0x1523720, 0x1963D80, 0x1D414C0, 0x20BBCE0, 0x23196E0, 0x28A1E00, 0x2DF5DC0, 0x3299340, 0x36D99A0, 0x3AB70E0, 0x3E31900, 0x4149200 }; void connect_dd_disk(struct dd_disk* dd_disk, uint8_t* disk, size_t disk_size) { dd_disk->disk = disk; dd_disk->disk_size = disk_size; } m64p_error open_dd_disk(const unsigned char* diskimage, unsigned int size) { /* allocate new buffer for ROM and copy into this buffer */ g_dd_disk_size = size; g_dd_disk = (unsigned char *)malloc(size); if (g_dd_disk == NULL) return M64ERR_NO_MEMORY; memcpy(g_dd_disk, diskimage, size); DebugMessage(M64MSG_STATUS, "64DD Disk loaded!"); return M64ERR_SUCCESS; } m64p_error close_dd_disk(void) { if (g_dd_disk == NULL) return M64ERR_INVALID_STATE; free(g_dd_disk); g_dd_disk = NULL; DebugMessage(M64MSG_STATUS, "64DD Disk closed."); return M64ERR_SUCCESS; } void dd_set_zone_and_track_offset(void *opaque) { int tr_off; struct dd_controller *dd = (struct dd_controller *) opaque; int head = ((dd->regs[ASIC_CUR_TK] & 0x10000000U) >> 25); //Head * 8 int track = ((dd->regs[ASIC_CUR_TK] & 0x0FFF0000U) >> 16); if (track >= 0x425) { dd_zone = 7 + head; tr_off = track - 0x425; } else if (track >= 0x390) { dd_zone = 6 + head; tr_off = track - 0x390; } else if (track >= 0x2FB) { dd_zone = 5 + head; tr_off = track - 0x2FB; } else if (track >= 0x266) { dd_zone = 4 + head; tr_off = track - 0x266; } else if (track >= 0x1D1) { dd_zone = 3 + head; tr_off = track - 0x1D1; } else if (track >= 0x13C) { dd_zone = 2 + head; tr_off = track - 0x13C; } else if (track >= 0x9E) { dd_zone = 1 + head; tr_off = track - 0x9E; } else { dd_zone = 0 + head; tr_off = track; } dd_track_offset = ddStartOffset[dd_zone] + tr_off*ddZoneSecSize[dd_zone] * SECTORS_PER_BLOCK*BLOCKS_PER_TRACK; } void dd_update_bm(void *opaque) { struct dd_controller *dd = (struct dd_controller *) opaque; if (!(dd->regs[ASIC_BM_STATUS_CTL] & 0x80000000)) return; else { int Cur_Sector = dd->regs[ASIC_CUR_SECTOR] >> 16; if (Cur_Sector >= 0x5A) { CUR_BLOCK = 1; Cur_Sector -= 0x5A; } if (!dd_bm_mode_read) //WRITE MODE { //printf("--DD_UPDATE_BM WRITE Block %d Sector %X\n", ((dd->regs[ASIC_CUR_TK] & 0x0FFF0000U) >> 15) + CUR_BLOCK, Cur_Sector); if (Cur_Sector == 0) { Cur_Sector++; dd->regs[ASIC_CMD_STATUS] |= 0x40000000; } else if (Cur_Sector < SECTORS_PER_BLOCK) { dd_write_sector(dd); Cur_Sector++; dd->regs[ASIC_CMD_STATUS] |= 0x40000000; } else if (Cur_Sector < SECTORS_PER_BLOCK + 1) { if (dd->regs[ASIC_BM_STATUS_CTL] & 0x01000000) { dd_write_sector(dd); //next block Cur_Sector = 1; CUR_BLOCK = 1 - CUR_BLOCK; dd->regs[ASIC_BM_STATUS_CTL] &= ~0x01000000; dd->regs[ASIC_CMD_STATUS] |= 0x40000000; } else { dd_write_sector(dd); Cur_Sector++; dd->regs[ASIC_BM_STATUS_CTL] &= ~0x80000000; } } } else //READ MODE { int Cur_Track = (dd->regs[ASIC_CUR_TK] & 0x0FFF0000U) >> 16; printf("--DD_UPDATE_BM READ Block %d Sector %X\n", ((dd->regs[ASIC_CUR_TK] & 0x0FFF0000U) >> 15) + CUR_BLOCK, Cur_Sector); dd->regs[ASIC_CMD_STATUS] &= ~(0x40000000 | 0x10000000); if (!dd_sector55 && Cur_Sector == 0x59) { dd_sector55 = 1; Cur_Sector--; } if (Cur_Track == 6 && CUR_BLOCK == 0) { dd->regs[ASIC_CMD_STATUS] &= ~0x40000000; dd->regs[ASIC_BM_STATUS_CTL] |= 0x02000000; } else if (Cur_Sector < SECTORS_PER_BLOCK) //user sector { dd_read_sector(dd); Cur_Sector++; dd->regs[ASIC_CMD_STATUS] |= 0x40000000; } else if (Cur_Sector < SECTORS_PER_BLOCK + 4) //C2 { Cur_Sector++; if (Cur_Sector == SECTORS_PER_BLOCK + 4) { //dd_read_C2(opaque); dd->regs[ASIC_CMD_STATUS] |= 0x10000000; } } else if (Cur_Sector == SECTORS_PER_BLOCK + 4) //Gap { if (dd->regs[ASIC_BM_STATUS_CTL] & 0x01000000) { CUR_BLOCK = 1 - CUR_BLOCK; Cur_Sector = 0; dd->regs[ASIC_BM_STATUS_CTL] &= ~0x01000000; } else dd->regs[ASIC_BM_STATUS_CTL] &= ~0x80000000; } } dd->regs[ASIC_CUR_SECTOR] = (Cur_Sector + (0x5A * CUR_BLOCK)) << 16; if ((dd->regs[ASIC_CMD_STATUS] & 0x04000000) == 0) { dd->regs[ASIC_CMD_STATUS] |= 0x04000000; cp0_update_count(); add_interupt_event(CART_INT, 1000); } } } void dd_write_sector(void *opaque) { unsigned i; int Cur_Sector, offset; struct dd_controller *dd = (struct dd_controller *) opaque; /* WRITE SECTOR */ Cur_Sector = dd->regs[ASIC_CUR_SECTOR] >> 16; if (Cur_Sector >= 0x5A) Cur_Sector -= 0x5A; offset = dd_track_offset; offset += CUR_BLOCK * SECTORS_PER_BLOCK * ddZoneSecSize[dd_zone]; offset += (Cur_Sector - 1) * ddZoneSecSize[dd_zone]; for (i = 0; i <= (int)(dd->regs[ASIC_HOST_SECBYTE] >> 16); i++) dd->disk.disk[offset + i] = dd->sec_buf[i]; } void dd_read_sector(void *opaque) { unsigned i; int offset, Cur_Sector; struct dd_controller *dd = (struct dd_controller *) opaque; /*READ SECTOR */ Cur_Sector = dd->regs[ASIC_CUR_SECTOR] >> 16; if (Cur_Sector >= 0x5A) Cur_Sector -= 0x5A; offset = dd_track_offset; offset += CUR_BLOCK * SECTORS_PER_BLOCK * ddZoneSecSize[dd_zone]; offset += Cur_Sector * ddZoneSecSize[dd_zone]; #if 0 printf("--DD_UPDATE_BM READ Block %d Sector %X -- Offset: 0x%08X\n", ((dd->regs[ASIC_CUR_TK] & 0x0FFF0000U) >> 15) + CUR_BLOCK, Cur_Sector, offset); #endif for (i = 0; i <= (int)(dd->regs[ASIC_HOST_SECBYTE] >> 16); i++) dd->sec_buf[i] = dd->disk.disk[offset + i]; } libretro/msvc/msvc-2010/msvc-2010.vcxproj.filters000664 001750 001750 00000077421 12655644434 022470 0ustar00sergiosergio000000 000000  {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms {08d74e8f-2a39-4efc-a018-65d09dd080e0} {1a0773bc-aafe-4c69-a662-06bfbff51772} {a7cdfbab-ff50-40c0-a177-b4650f46a8b9} {a46407d8-1f51-4026-81bd-a2d2d2bb044c} {59454037-914e-46d3-926b-eb44a633db95} {1b901a4f-6cd0-428a-b754-62e2627ff26b} {414825e7-a398-4574-b277-856daee0d840} {01adbf61-50e6-4d05-a36c-70004e1b8ed6} {259de9c9-1d36-4929-a270-8648bda52582} {c5857766-5cbb-4440-877f-ab87a7321bea} {a0fdbf97-4901-458a-9dee-abadca6b58ef} {178fcce8-709b-4a8f-962a-2da8b76f7c9d} {0a6c2a05-6e47-40cf-9c1a-79c5f75e937c} {93e9ecbf-9833-4d05-b93d-1e9011be0a30} {42b40386-eb46-4921-bfd4-172300e51fc1} {29ffaa41-ab03-45ef-b1b5-e4a5e2509f96} {4e37543d-dd07-4a8c-be81-a0077b49622f} {8ccebd5b-1c04-4e0f-9aba-ef8ac7c92835} {91a5e14e-8d8f-45d2-aa1a-bf02225f7c78} {33bfeb66-7c5e-4b3b-a3f2-2bc6c460e0d7} {6fce91a3-24d0-441b-ac7d-3d6bfe2e9c45} {2f954036-39e2-416b-8ad8-57de5c20979c} {043b04b0-a1d8-4553-a42f-beee591167ff} {f36ec05b-e8c8-485f-92f6-7b3159b4fee2} {be734aec-bdb7-47ea-a241-31d3444ec246} {d5c262d1-6d32-40ec-bda4-08e71ed16a83} {d3d9ee3e-fedf-420e-85cb-60e6e88cdeaa} {0ed3c36d-5d7c-4c7e-b0af-d4fd41697658} {ccc16655-7b53-4b76-b6d2-d7b0028deab5} {411087e2-871a-4e56-ac73-2fb545941488} {df287fcb-b034-4181-a275-fbdff2645b32} {8f9f1514-ae74-4a7e-953a-1ea03cef66f6} {9c507cb5-ae0d-432d-a25b-77aa00bc014c} {9d83b714-4362-4144-8b9d-133a52ee3f48} Source Files\libretro Source Files\libretro Source Files\libretro Source Files\libretro\libco Source Files\mupen64plus-hle-rsp\src Source Files\mupen64plus-hle-rsp\src Source Files\mupen64plus-hle-rsp\src Source Files\mupen64plus-hle-rsp\src Source Files\mupen64plus-hle-rsp\src Source Files\mupen64plus-hle-rsp\src Source Files\mupen64plus-hle-rsp\src Source Files\mupen64plus-hle-rsp\src Source Files\mupen64plus-hle-rsp\src Source Files\mupen64plus-hle-rsp\src Source Files\mupen64plus-hle-rsp\src Source Files\mupen64plus-hle-rsp\src Source Files\mupen64plus-rsp-cxd4\src Source Files\mupen64plus-core\src\api Source Files\mupen64plus-core\src\api Source Files\mupen64plus-core\src\api Source Files\mupen64plus-core\src\api Source Files\mupen64plus-core\src\main Source Files\mupen64plus-core\src\main Source Files\mupen64plus-core\src\main Source Files\mupen64plus-core\src\main Source Files\mupen64plus-core\src\main Source Files\mupen64plus-core\src\main Source Files\mupen64plus-core\src\main Source Files\mupen64plus-core\src\plugin Source Files\glide2gl\src\Glide64 Source Files\glide2gl\src\Glide64 Source Files\glide2gl\src\Glide64 Source Files\glide2gl\src\Glide64 Source Files\glide2gl\src\Glide64 Source Files\glide2gl\src\Glide64 Source Files\glide2gl\src\Glide64 Source Files\glide2gl\src\Glide64 Source Files\glide2gl\src\Glitch64 Source Files\glide2gl\src\Glitch64 Source Files\glide2gl\src\Glitch64 Source Files\gles2n64\src Source Files\gles2n64\src Source Files\gles2n64\src Source Files\gles2n64\src Source Files\gles2n64\src Source Files\gles2n64\src Source Files\gles2n64\src Source Files\gles2n64\src Source Files\gles2n64\src Source Files\gles2n64\src Source Files\gles2n64\src Source Files\gles2n64\src Source Files\gles2n64\src Source Files\gles2n64\src Source Files\gles2n64\src Source Files\gles2n64\src Source Files\gles2n64\src Source Files\gles2n64\src Source Files\gles2n64\src Source Files\gles2n64\src Source Files\gles2n64\src Source Files\gles2n64\src Source Files\gles2n64\src Source Files\gles2n64\src Source Files\gles2rice\src Source Files\gles2rice\src Source Files\gles2rice\src Source Files\gles2rice\src Source Files\gles2rice\src Source Files\gles2rice\src Source Files\gles2rice\src Source Files\gles2rice\src Source Files\gles2rice\src Source Files\gles2rice\src Source Files\gles2rice\src Source Files\gles2rice\src Source Files\gles2rice\src Source Files\gles2rice\src Source Files\gles2rice\src Source Files\gles2rice\src Source Files\gles2rice\src Source Files\gles2rice\src Source Files\gles2rice\src Source Files\gles2rice\src Source Files\gles2rice\src Source Files\gles2rice\src Source Files\gles2rice\src Source Files\gles2rice\src Source Files\gles2rice\src Source Files\gles2rice\src Source Files\gles2rice\src Source Files\mupen64plus-core\src\r4300 Source Files\mupen64plus-core\src\r4300 Source Files\mupen64plus-core\src\r4300 Source Files\mupen64plus-core\src\r4300 Source Files\mupen64plus-core\src\r4300 Source Files\mupen64plus-core\src\r4300 Source Files\mupen64plus-core\src\r4300 Source Files\mupen64plus-core\src\r4300\x86_64 Source Files\mupen64plus-core\src\r4300\x86_64 Source Files\mupen64plus-core\src\r4300\x86_64 Source Files\mupen64plus-core\src\r4300\x86_64 Source Files\mupen64plus-core\src\r4300\x86_64 Source Files\mupen64plus-core\src\r4300\x86_64 Source Files\mupen64plus-core\src\r4300\x86_64 Source Files\mupen64plus-core\src\r4300\x86_64 Source Files\mupen64plus-core\src\r4300\x86_64 Source Files\mupen64plus-core\src\r4300\x86_64 Source Files\mupen64plus-core\src\r4300\x86_64 Source Files\mupen64plus-core\src\r4300\x86_64 Source Files\mupen64plus-core\src\r4300\x86_64 Source Files\mupen64plus-core\src\r4300\x86_64 Source Files\rzlib Source Files\rzlib Source Files\rzlib Source Files\rzlib Source Files\rzlib Source Files\rzlib Source Files\rzlib Source Files\rzlib Source Files\rzlib Source Files\rzlib Source Files\rzlib Source Files\rzlib Source Files\rzlib Source Files\rzlib Source Files\rzlib Source Files\rzlib Source Files\gles2n64\src Source Files\gles2rice\src Source Files\libretro\glsym Source Files\libretro\glsym Source Files\mupen64plus-core\src\r4300 Source Files\mupen64plus-core\src\r4300 Source Files\mupen64plus-core\src\r4300 Source Files\mupen64plus-core\src\r4300 Source Files\gles2n64\src Source Files\glide2gl\src\Glitch64 Source Files\mupen64plus-core\src\memory Source Files\libretro Source Files\glide2gl\src\Glide64 Source Files\glide2gl\src\Glide64 Source Files\gles2n64\src Source Files\mupen64plus-video-angrylion Source Files\mupen64plus-video-angrylion Source Files\mupen64plus-video-angrylion Source Files\mupen64plus-video-angrylion Source Files\gles2rice\src Source Files\mupen64plus-core\src\plugin Source Files\mupen64plus-core\src\plugin Source Files\mupen64plus-core\src\plugin Source Files\mupen64plus-core\src\plugin\audio_libretro Source Files\mupen64plus-core\src\plugin\audio_libretro Source Files\mupen64plus-core\src\plugin\audio_libretro Source Files\mupen64plus-core\src\plugin\audio_libretro\drivers_resampler Source Files\mupen64plus-core\src\plugin\audio_libretro\drivers_resampler Source Files\mupen64plus-core\src\plugin\audio_libretro\drivers_resampler Source Files\mupen64plus-core\src\api Source Files\mupen64plus-core\src\api Source Files\mupen64plus-core\src\ai Source Files\mupen64plus-core\src\pi Source Files\mupen64plus-core\src\pi Source Files\mupen64plus-core\src\pi Source Files\mupen64plus-core\src\pi Source Files\mupen64plus-core\src\r4300 Source Files\mupen64plus-core\src\rdp Source Files\mupen64plus-core\src\rdp Source Files\mupen64plus-core\src\ri Source Files\mupen64plus-core\src\ri Source Files\mupen64plus-core\src\rsp Source Files\mupen64plus-core\src\si Source Files\mupen64plus-core\src\si Source Files\mupen64plus-core\src\si Source Files\mupen64plus-core\src\si Source Files\mupen64plus-core\src\si Source Files\mupen64plus-core\src\si Source Files\mupen64plus-core\src\si Source Files\mupen64plus-core\src\si Source Files\mupen64plus-core\src\si Source Files\mupen64plus-core\src\vi Source Files\mupen64plus-core\src\r4300 Source Files\mupen64plus-core\src\r4300 mupen64plus-core/src/000700 001750 001750 00000000000 12656647145 015625 5ustar00sergiosergio000000 000000 mupen64plus-rsp-cxd4/README.md000664 001750 001750 00000023072 12655644434 017046 0ustar00sergiosergio000000 000000 # Vector Technology as Implemented for Use with a RISC and SIMD Technology Signal Processor A vector processor uses long registers addressable by segment-precision, where each segment is _n_ bits wide. The power of a vector processor is that many complex matrix operations, whose algorithms take many scalar CPU instructions and clock cycles to emulate on a regular, personal computer processor, can often times formulate and transfer the correct result in less than a single clock cycle. The impossibility to replicate this precise behavior has paved the way for vendor businesses to protect their systems against hardware emulation since the introduction of display devices rendering three-dimensional graphics. The Nintendo 64 was the first video game system to employ this convenience to their advantage. *** ## Project Reality's Signal Processor In the engineering make-up of the Nintendo 64 (original codename: Project Reality) is a modified MIPS family revision 4000 co-processor called the "Reality Coprocessor" (RCP). More importantly, the signal processor in this component is responsible for all vector memory operations and transactions, which are almost all impossible to emulate with full accuracy on a scalar, personal computer processor. The vector technology implemented into this design is that accepted from Silicon Graphics, Inc. ### RSP Vector Operation Matrices Here, the entire MIPS R4000 instruction set was modified for very fast, exception-free processing flow, and operation definitions for each instruction do not fall within the scope of this section. Presented instead are layouts of the new instructions added to the scalar unit (those under `LWC2` and `SWC2`, even though they do interface with the vector unit) and the vector unit (essentially, any instruction under `COP2` whose mnemonic starts with a 'V'). Information of how pre-existing MIPS R4000 instructions were modified or which ones were removed is the adventure of the MIPS programmer to research. V*_vd_, _vs_, _vt_[_element_] `/* exceptions: scalar divide reads */`
COP2elementvs1vs2vtfunc
0100101-------------------??????
The major types of VU computational instructions are _multiply,_ _add,_ _select,_ _logical,_ and _divide._ Multiply instructions are the most frequent and classifiable as follows: * If `a == 0`, then round the product loaded to the accumulator (`VMUL*` and `VMUD*`). * If `a == 1`, then the product is added to an accumulator element (`VMAC*` and `VMAD*`). * If `(format & 0b100) == 0`, then the operation is single-precision (`VMUL*` and `VMAC*`). * If `(format & 0b100) != 0`, then the operation is double-precision (`VMUD*` and `VMAD*`).
op-codeType
0 0 a x x xmultiply
0 1 x x x xadd
1 0 0 x x xselect
1 0 1 x x xlogical
1 1 0 x x xdivide
* `00 (VMULF)` Vector Multiply Signed Fractions * `01 (VMULU)` Vector Multiply Unsigned Fractions * `02 reserved` `VRNDP` was intended for MPEG DCT rounding but omitted. * `03 reserved` `VMULQ` was intended for MPEG inverse quantization but omitted. * `04 (VMUDL)` Vector Multiply Low Partial Products * `05 (VMUDM)` Vector Multiply Mid Partial Products * `06 (VMUDN)` Vector Multiply Mid Partial Products * `07 (VMUDH)` Vector Multiply High Partial Products * `10 (VMACF)` Vector Multiply-Accumulate Signed Fractions * `11 (VMACU)` Vector Multiply-Accumulate Unsigned Fractions * `12 reserved` `VRNDN` was intended for MPEG DCT rounding but omitted. * `13 (VMACQ)` Vector Accumulator Oddification * `14 (VMADL)` Vector Multiply-Accumulate Low Partial Products * `15 (VMADM)` Vector Multiply-Accumulate Mid Partial Products * `16 (VMADN)` Vector Multiply-Accumulate Mid Partial Products * `17 (VMADH)` Vector Multiply-Accumulate High Partial Products * `20 (VADD)` Vector Add Short Elements * `21 (VSUB)` Vector Subtract Short Elements * `22 reserved` * `23 (VABS)` Vector Absolute Value of Short Elements * `24 (VADDC)` Vector Add Short Elements with Carry * `25 (VSUBC)` Vector Subtract Short Elements with Carry * `26 reserved` * `27 reserved` * `30 reserved` * `31 reserved` * `32 reserved` * `33 reserved` * `34 reserved` * `35 (VSAR)` Vector Accumulator Read * `36 reserved` * `37 reserved` * `40 (VLT)` Vector Select Less Than * `41 (VEQ)` Vector Select Equal * `42 (VNE)` Vector Select Not Equal * `43 (VGE)` Vector Select Greater Than or Equal * `44 (VCL)` Vector Select Clip Test Low * `45 (VCH)` Vector Select Clip Test High * `46 (VCR)` Vector Select Clip Test Low (single-precision) * `47 (VMRG)` Vector Select Merge * `50 (VAND)` Vector AND Short Elements * `51 (VNAND)` Vector NAND Short Elements * `52 (VOR)` Vector OR Short Elements * `53 (VNOR)` Vector NOR Short Elements * `54 (VXOR)` Vector XOR Short Elements * `55 (VNXOR)` Vector NXOR Short Elements * `56 reserved` * `57 reserved` * `60 (VRCP)` Vector Element Scalar Reciprocal (single-precision) * `61 (VRCPL)` Vector Element Scalar Reciprocal Low * `62 (VRCPH)` Vector Element Scalar Reciprocal High * `63 (VMOV)` Vector Element Scalar Move * `64 (VRSQ)` Vector Element Scalar SQRT Reciprocal (single-precision) * `65 (VRSQL)` Vector Element Scalar SQRT Reciprocal Low * `66 (VRSQH)` Vector Element Scalar SQRT Reciprocal High * `67 (VNOP)` Vector Null Instruction * `70 reserved` * `71 reserved` * `72 reserved` * `73 reserved` * `74 reserved` * `75 reserved` * `76 reserved` * `77 reserved` ### RSP Vector Load Transfers The VR-DMEM transaction instruction cycles are still processed by the scalar unit, not the vector unit. In the modern implementations accepted by most vector unit communications systems today, the transfer instructions are classifiable under five groups:
  1. BV, SV, LV, DV
  2. PV, UV, XV, ZV
  3. HV, FV, AV
  4. QV, RV
  5. TV, WV
Not all of those instructions were implemented as of the time of the Nintendo 64's RCP, however. Additionally, their ordering in the opcode matrix was a little skewed to what is seen below. At this time, it is better to use only three categories of instructions: * _normal_: Anything under Group I or Group IV is normal type. Only the element must be aligned; `addr & 1` may resolve true. * _packed_: Anything under Group II or Group III. Useful for working with specially mapped data, such as pixels. * _transposed_: `LTV`, *LTWV,* `STV`, and `SWV` can be found in heaps of 16 instructions, all dedicated to matrix transposition through eight diagonals of halfword elements. LWC2_vt_[_element_], _offset_(_base_)
LWC2basevtrdelementoffset
110010----------?????-----------
* `00 (LBV)` Load Byte to Vector Unit * `01 (LSV)` Load Shortword to Vector Unit * `02 (LLV)` Load Longword to Vector Unit * `03 (LDV)` Load Doubleword to Vector Unit * `04 (LQV)` Load Quadword to Vector Unit * `05 (LRV)` Load Rest to Vector Unit * `06 (LPV)` Load Packed Signed to Vector Unit * `07 (LUV)` Load Packed Unsigned to Vector Unit * `10 (LHV)` Load Alternate Bytes to Vector Unit * `11 (LFV)` Load Alternate Fourths to Vector Unit * `12 reserved` *LTWV* * `13 (LTV)` Load Transposed to Vector Unit * `14 reserved` * `15 reserved` * `16 reserved` * `17 reserved`
SWC2basevtrdelementoffset
111010----------?????-----------
* `00 (SBV)` Store Byte from Vector Unit * `01 (SSV)` Store Shortword from Vector Unit * `02 (SLV)` Store Longword from Vector Unit * `03 (SDV)` Store Doubleword from Vector Unit * `04 (SQV)` Store Quadword from Vector Unit * `05 (SRV)` Store Rest from Vector Unit * `06 (SPV)` Store Packed Signed from Vector Unit * `07 (SUV)` Store Packed Unsigned from Vector Unit * `10 (SHV)` Store Alternate Bytes from Vector Unit * `11 (SFV)` Store Alternate Fourths from Vector Unit * `12 (SWV)` Store Transposed Wrapped from Vector Unit * `13 (STV)` Store Transposed from Vector Unit * `14 reserved` * `15 reserved` * `16 reserved` * `17 reserved` If, by any chance, the opcode specifier is greater than 17 [oct], it was probably meant to execute the extended counterparts to the above loads and stores, which were questionably obsolete and remain reserved. ## Informational References for Vector Processor Architecture _Instruction Methods for Performing Data Formatting While Moving Data Between Memory and a Vector Register File_ United States patent no. 5,812,147 Timothy J. Van Hook *Silicon Graphics, Inc.* _Method and System for Efficient Matrix Multiplication in a SIMD Processor Architecture_ United States patent no. 7,873,812 Tibet Mimar _Efficient Handling of Vector High-Level Language Constructs in a SIMD Processor_ United States patent no. 7,793,084 Tibet Mimar _Flexible Vector Modes of Operation for SIMD Processor_ patent pending? Tibet Mimar _Programming a Vector Processor and Parallel Programming of an Asymmetric Dual Multiprocessor Comprised of a Vector Processor and a RISC Processor_ United States patent no. 6,016,395 Moataz Ali Mohamed *Samsung Electronics Co., Ltd.* _Execution Unit for Processing a Data Stream Independently and in Parallel_ United States patent no. 6,401,194 Le Trong Nguyen *Samsung Electronics Co., Ltd.* libretro/msvc/stdbool.h000664 001750 001750 00000002040 12655644434 016324 0ustar00sergiosergio000000 000000 /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. * * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with RetroArch. * If not, see . */ #ifndef __RARCH_BOOLEAN_H #define __RARCH_BOOLEAN_H #ifndef __cplusplus #if defined(_MSC_VER) && !defined(SN_TARGET_PS3) /* Hack applied for MSVC when compiling in C89 mode as it isn't C99 compliant. */ #define bool unsigned char #define true 1 #define false 0 #else #include #endif #endif #endif mupen64plus-core/src/plugin/000700 001750 001750 00000000000 12656647145 017123 5ustar00sergiosergio000000 000000 mupen64plus-video-gliden64/src/OpenGL.h000664 001750 001750 00000017215 12655644434 020731 0ustar00sergiosergio000000 000000 #ifndef OPENGL_H #define OPENGL_H #include #ifdef OS_WINDOWS #include #else #include "winlnxdefs.h" #endif #include "../../libretro/SDL_opengl.h" #ifdef GLES2 #include #define GL_DRAW_FRAMEBUFFER GL_FRAMEBUFFER #define GL_READ_FRAMEBUFFER GL_FRAMEBUFFER #define GLESX #elif defined(GLES3) #include #define GLESX #define GL_UNIFORMBLOCK_SUPPORT #elif defined(GLES3_1) #include #define GLESX #define GL_IMAGE_TEXTURES_SUPPORT #define GL_MULTISAMPLING_SUPPORT #define GL_UNIFORMBLOCK_SUPPORT #else #if defined(OS_MAC_OS_X) #define GL_GLEXT_PROTOTYPES #include #include #include #elif defined(OS_LINUX) #define GL_GLEXT_PROTOTYPES #include #include #define GL_IMAGE_TEXTURES_SUPPORT #define GL_MULTISAMPLING_SUPPORT #define GL_UNIFORMBLOCK_SUPPORT #elif defined(OS_WINDOWS) #include #include "glext.h" #include "windows/GLFunctions.h" #define GL_IMAGE_TEXTURES_SUPPORT #define GL_MULTISAMPLING_SUPPORT #define GL_UNIFORMBLOCK_SUPPORT #endif // OS_MAC_OS_X #endif // GLES2 #ifdef GLESX #define GET_PROGRAM_BINARY_EXTENSION "GL_OES_get_program_binary" #else #define GET_PROGRAM_BINARY_EXTENSION "GL_ARB_get_program_binary" #endif #ifdef USE_SDL #include #endif // USE_SDL #ifndef GL_EXT_texture_filter_anisotropic #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF #endif #include "glState.h" #include "gSP.h" #define INDEXMAP_SIZE 80U #define VERTBUFF_SIZE 256U #define ELEMBUFF_SIZE 1024U class OGLRender { public: void addTriangle(int _v0, int _v1, int _v2); void drawTriangles(); void drawLLETriangle(u32 _numVtx); void drawDMATriangles(u32 _numVtx); void drawLine(int _v0, int _v1, float _width); void drawRect(int _ulx, int _uly, int _lrx, int _lry, float * _pColor); struct TexturedRectParams { float ulx, uly, lrx, lry; float uls, ult, lrs, lrt; bool flip; TexturedRectParams(float _ulx, float _uly, float _lrx, float _lry, float _uls, float _ult, float _lrs, float _lrt, bool _flip) : ulx(_ulx), uly(_uly), lrx(_lrx), lry(_lry), uls(_uls), ult(_ult), lrs(_lrs), lrt(_lrt), flip(_flip) {} }; void drawTexturedRect(const TexturedRectParams & _params); void drawText(const char *_pText, float x, float y); void clearDepthBuffer(u32 _uly, u32 _lry); void clearColorBuffer( float * _pColor ); int getTrianglesCount() const {return triangles.num;} bool isClipped(s32 _v0, s32 _v1, s32 _v2) const { return (triangles.vertices[_v0].clip & triangles.vertices[_v1].clip & triangles.vertices[_v2].clip) != 0; } bool isImageTexturesSupported() const {return m_bImageTexture;} SPVertex & getVertex(u32 _v) {return triangles.vertices[_v];} void setDMAVerticesSize(u32 _size) { if (triangles.dmaVertices.size() < _size) triangles.dmaVertices.resize(_size); } SPVertex * getDMAVerticesData() { return triangles.dmaVertices.data(); } void updateScissor(FrameBuffer * _pBuffer) const; enum RENDER_STATE { rsNone = 0, rsTriangle = 1, rsRect = 2, rsTexRect = 3, rsLine = 4 }; RENDER_STATE getRenderState() const {return m_renderState;} enum OGL_RENDERER { glrOther, glrAdreno }; OGL_RENDERER getRenderer() const { return m_oglRenderer; } void dropRenderState() {m_renderState = rsNone;} private: OGLRender() : m_oglRenderer(glrOther), m_bImageTexture(false), m_bFlatColors(false) {} OGLRender(const OGLRender &); friend class OGLVideo; void _initExtensions(); void _initStates(); void _initData(); void _destroyData(); void _setSpecialTexrect() const; void _setColorArray() const; void _setTexCoordArrays() const; void _setBlendMode() const; void _updateCullFace() const; void _updateViewport() const; void _updateDepthUpdate() const; void _updateStates(RENDER_STATE _renderState) const; void _prepareDrawTriangle(bool _dma); bool _canDraw() const; struct { SPVertex vertices[VERTBUFF_SIZE]; std::vector dmaVertices; GLubyte elements[ELEMBUFF_SIZE]; int num; u32 indexmap[INDEXMAP_SIZE]; u32 indexmapinv[VERTBUFF_SIZE]; u32 indexmap_prev; u32 indexmap_nomap; } triangles; struct GLVertex { float x, y, z, w; float s0, t0, s1, t1; }; RENDER_STATE m_renderState; OGL_RENDERER m_oglRenderer; GLVertex m_rect[4]; bool m_bImageTexture; bool m_bFlatColors; }; class OGLVideo { public: void start(); void stop(); void restart(); void swapBuffers(); void saveScreenshot(); bool changeWindow(); bool resizeWindow(); void setWindowSize(u32 _width, u32 _height); void setCaptureScreen(const char * const _strDirectory); void setToggleFullscreen() {m_bToggleFullscreen = true;} void readScreen(void **_pDest, long *_pWidth, long *_pHeight ); void readScreen2(void * _dest, int * _width, int * _height, int _front); void updateScale(); f32 getScaleX() const {return m_scaleX;} f32 getScaleY() const {return m_scaleY;} f32 getAdjustScale() const {return m_adjustScale;} u32 getBuffersSwapCount() const {return m_buffersSwapCount;} u32 getWidth() const { return m_width; } u32 getHeight() const {return m_height;} u32 getScreenWidth() const {return m_screenWidth;} u32 getScreenHeight() const {return m_screenHeight;} u32 getHeightOffset() const {return m_heightOffset;} bool isFullscreen() const {return m_bFullscreen;} bool isAdjustScreen() const {return m_bAdjustScreen;} bool isResizeWindow() const {return m_bResizeWindow;} OGLRender & getRender() {return m_render;} static OGLVideo & get(); static bool isExtensionSupported(const char * extension); protected: OGLVideo() : m_bCaptureScreen(false), m_bToggleFullscreen(false), m_bResizeWindow(false), m_bFullscreen(false), m_bAdjustScreen(false), m_width(0), m_height(0), m_heightOffset(0), m_screenWidth(0), m_screenHeight(0), m_resizeWidth(0), m_resizeHeight(0), m_scaleX(0), m_scaleY(0), m_adjustScale(0) {} void _setBufferSize(); bool m_bCaptureScreen; bool m_bToggleFullscreen; bool m_bResizeWindow; bool m_bFullscreen; bool m_bAdjustScreen; u32 m_buffersSwapCount; u32 m_width, m_height, m_heightOffset; u32 m_screenWidth, m_screenHeight; u32 m_resizeWidth, m_resizeHeight; f32 m_scaleX, m_scaleY; f32 m_adjustScale; wchar_t m_strScreenDirectory[PLUGIN_PATH_SIZE]; private: OGLRender m_render; virtual bool _start() = 0; virtual void _stop() = 0; virtual void _swapBuffers() = 0; virtual void _saveScreenshot() = 0; virtual void _changeWindow() = 0; virtual bool _resizeWindow() = 0; }; struct FBOTextureFormats { GLint colorInternalFormat; GLenum colorFormat; GLenum colorType; u32 colorFormatBytes; GLint monochromeInternalFormat; GLenum monochromeFormat; GLenum monochromeType; u32 monochromeFormatBytes; GLint depthInternalFormat; GLenum depthFormat; GLenum depthType; u32 depthFormatBytes; GLint depthImageInternalFormat; GLenum depthImageFormat; GLenum depthImageType; u32 depthImageFormatBytes; GLint lutInternalFormat; GLenum lutFormat; GLenum lutType; u32 lutFormatBytes; void init(); }; extern FBOTextureFormats fboFormats; inline OGLVideo & video() { return OGLVideo::get(); } class TextureFilterHandler { public: TextureFilterHandler() : m_inited(0), m_options(0) {} // It's not safe to call shutdown() in destructor, because texture filter has its own static objects, which can be destroyed first. ~TextureFilterHandler() { m_inited = m_options = 0; } void init(); void shutdown(); bool isInited() const { return m_inited != 0; } bool optionsChanged() const { return _getConfigOptions() != m_options; } private: u32 _getConfigOptions() const; u32 m_inited; u32 m_options; }; extern TextureFilterHandler TFH; void initGLFunctions(); bool checkFBO(); bool isGLError(); void displayLoadProgress(const wchar_t *format, ...); #endif mupen64plus-core/src/r4300/new_dynarec/assem_x86.h000664 001750 001750 00000001133 12655644434 022670 0ustar00sergiosergio000000 000000 #ifndef M64P_R4300_ASSEM_X86_H #define M64P_R4300_ASSEM_X86_H #define HOST_REGS 8 #define HOST_CCREG 6 #define HOST_BTREG 5 #define EXCLUDE_REG 4 //#define IMM_PREFETCH 1 #define HOST_IMM_ADDR32 1 #define INVERTED_CARRY 1 #define DESTRUCTIVE_WRITEBACK 1 #define DESTRUCTIVE_SHIFT 1 #define USE_MINI_HT 1 extern void *base_addr; // Code generator target address #define TARGET_SIZE_2 25 // 2^25 = 32 megabytes #define JUMP_TABLE_SIZE 0 // Not needed for 32-bit x86 /* x86 calling convention: caller-save: %eax %ecx %edx callee-save: %ebp %ebx %esi %edi */ #endif /* M64P_R4300_ASSEM_X86_H */ mupen64plus-core/src/pi/sram.h000664 001750 001750 00000003631 12655644434 017364 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - sram.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_PI_SRAM_H #define M64P_PI_SRAM_H #include struct pi_controller; enum { SRAM_SIZE = 0x8000 }; struct sram { /* external sram storage */ void* user_data; void (*save)(void*); uint8_t* data; }; void sram_save(struct sram* sram); void format_sram(uint8_t* sram); void dma_write_sram(struct pi_controller* pi); void dma_read_sram(struct pi_controller* pi); #endif mupen64plus-core/src/r4300/hacktarux_dynarec/gregimm.c000664 001750 001750 00000037777 12655644434 023725 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - gregimm.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2007 Richard Goedeken (Richard42) * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include "assemble.h" #include "interpret.h" #include "r4300/cached_interp.h" #include "r4300/recomph.h" #include "r4300/recomp.h" #include "r4300/r4300.h" #include "r4300/ops.h" #include "r4300/macros.h" #include "memory/memory.h" static void genbltz_test(void) { int rs_64bit = is64((unsigned int *)dst->f.i.rs); if (rs_64bit == 0) { #ifdef __x86_64__ int rs = allocate_register_32((unsigned int *)dst->f.i.rs); #else int rs = allocate_register((unsigned int *)dst->f.i.rs); #endif cmp_reg32_imm32(rs, 0); #ifdef __x86_64__ setl_m8rel((unsigned char *) &branch_taken); #else jge_rj(12); mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10 #endif } else if (rs_64bit == -1) { #ifdef __x86_64__ cmp_m32rel_imm32(((unsigned int *)dst->f.i.rs)+1, 0); setl_m8rel((unsigned char *) &branch_taken); #else cmp_m32_imm32(((unsigned int *)dst->f.i.rs)+1, 0); jge_rj(12); mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10 #endif } else { #ifdef __x86_64__ int rs = allocate_register_64((uint64_t*)dst->f.i.rs); cmp_reg64_imm8(rs, 0); setl_m8rel((unsigned char *) &branch_taken); #else int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs); cmp_reg32_imm32(rs2, 0); jge_rj(12); mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10 #endif } } void genbltz(void) { #ifdef INTERPRET_BLTZ gencallinterp((native_type)cached_interpreter_table.BLTZ, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BLTZ, 1); return; } genbltz_test(); gendelayslot(); gentest(); #endif } void genbltz_out(void) { #ifdef INTERPRET_BLTZ_OUT gencallinterp((native_type)cached_interpreter_table.BLTZ_OUT, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BLTZ_OUT, 1); return; } genbltz_test(); gendelayslot(); gentest_out(); #endif } void genbltz_idle(void) { #ifdef INTERPRET_BLTZ_IDLE gencallinterp((native_type)cached_interpreter_table.BLTZ_IDLE, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BLTZ_IDLE, 1); return; } genbltz_test(); gentest_idle(); genbltz(); #endif } static void genbgez_test(void) { int rs_64bit = is64((unsigned int *)dst->f.i.rs); if (rs_64bit == 0) { #ifdef __x86_64__ int rs = allocate_register_32((unsigned int *)dst->f.i.rs); cmp_reg32_imm32(rs, 0); setge_m8rel((unsigned char *) &branch_taken); #else int rs = allocate_register((unsigned int*)dst->f.i.rs); cmp_reg32_imm32(rs, 0); jl_rj(12); mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10 #endif } else if (rs_64bit == -1) { #ifdef __x86_64__ cmp_m32rel_imm32(((unsigned int *)dst->f.i.rs)+1, 0); setge_m8rel((unsigned char *) &branch_taken); #else cmp_m32_imm32(((unsigned int *)dst->f.i.rs)+1, 0); jl_rj(12); mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10 #endif } else { #ifdef __x86_64__ int rs = allocate_register_64((uint64_t*)dst->f.i.rs); cmp_reg64_imm8(rs, 0); setge_m8rel((unsigned char *) &branch_taken); #else int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs); cmp_reg32_imm32(rs2, 0); jl_rj(12); mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10 #endif } } void genbgez(void) { #ifdef INTERPRET_BGEZ gencallinterp((native_type)cached_interpreter_table.BGEZ, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BGEZ, 1); return; } genbgez_test(); gendelayslot(); gentest(); #endif } void genbgez_out(void) { #ifdef INTERPRET_BGEZ_OUT gencallinterp((native_type)cached_interpreter_table.BGEZ_OUT, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BGEZ_OUT, 1); return; } genbgez_test(); gendelayslot(); gentest_out(); #endif } void genbgez_idle(void) { #ifdef INTERPRET_BGEZ_IDLE gencallinterp((native_type)cached_interpreter_table.BGEZ_IDLE, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BGEZ_IDLE, 1); return; } genbgez_test(); gentest_idle(); genbgez(); #endif } void genbltzl(void) { #ifdef INTERPRET_BLTZL gencallinterp((native_type)cached_interpreter_table.BLTZL, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BLTZL, 1); return; } genbltz_test(); free_all_registers(); gentestl(); #endif } void genbltzl_out(void) { #ifdef INTERPRET_BLTZL_OUT gencallinterp((native_type)cached_interpreter_table.BLTZL_OUT, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BLTZL_OUT, 1); return; } genbltz_test(); free_all_registers(); gentestl_out(); #endif } void genbltzl_idle(void) { #ifdef INTERPRET_BLTZL_IDLE gencallinterp((native_type)cached_interpreter_table.BLTZL_IDLE, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BLTZL_IDLE, 1); return; } genbltz_test(); gentest_idle(); genbltzl(); #endif } void genbgezl(void) { #ifdef INTERPRET_BGEZL gencallinterp((native_type)cached_interpreter_table.BGEZL, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BGEZL, 1); return; } genbgez_test(); free_all_registers(); gentestl(); #endif } void genbgezl_out(void) { #ifdef INTERPRET_BGEZL_OUT gencallinterp((native_type)cached_interpreter_table.BGEZL_OUT, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BGEZL_OUT, 1); return; } genbgez_test(); free_all_registers(); gentestl_out(); #endif } void genbgezl_idle(void) { #ifdef INTERPRET_BGEZL_IDLE gencallinterp((native_type)cached_interpreter_table.BGEZL_IDLE, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BGEZL_IDLE, 1); return; } genbgez_test(); gentest_idle(); genbgezl(); #endif } static void genbranchlink(void) { int r31_64bit = is64((unsigned int*)®[31]); if (r31_64bit == 0) { #ifdef __x86_64__ int r31 = allocate_register_32_w((unsigned int *)®[31]); mov_reg32_imm32(r31, dst->addr+8); #else int r31 = allocate_register_w((unsigned int *)®[31]); mov_reg32_imm32(r31, dst->addr+8); #endif } else if (r31_64bit == -1) { #ifdef __x86_64__ mov_m32rel_imm32((unsigned int *)®[31], dst->addr + 8); if (dst->addr & 0x80000000) mov_m32rel_imm32(((unsigned int *)®[31])+1, 0xFFFFFFFF); else mov_m32rel_imm32(((unsigned int *)®[31])+1, 0); #else mov_m32_imm32((unsigned int *)®[31], dst->addr + 8); if (dst->addr & 0x80000000) mov_m32_imm32(((unsigned int *)®[31])+1, 0xFFFFFFFF); else mov_m32_imm32(((unsigned int *)®[31])+1, 0); #endif } else { #ifdef __x86_64__ int r31 = allocate_register_64_w((uint64_t*)®[31]); mov_reg32_imm32(r31, dst->addr+8); movsxd_reg64_reg32(r31, r31); #else int r311 = allocate_64_register1_w((unsigned int *)®[31]); int r312 = allocate_64_register2_w((unsigned int *)®[31]); mov_reg32_imm32(r311, dst->addr+8); if (dst->addr & 0x80000000) mov_reg32_imm32(r312, 0xFFFFFFFF); else mov_reg32_imm32(r312, 0); #endif } } void genbltzal(void) { #ifdef INTERPRET_BLTZAL gencallinterp((native_type)cached_interpreter_table.BLTZAL, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BLTZAL, 1); return; } genbltz_test(); genbranchlink(); gendelayslot(); gentest(); #endif } void genbltzal_out(void) { #ifdef INTERPRET_BLTZAL_OUT gencallinterp((native_type)cached_interpreter_table.BLTZAL_OUT, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BLTZAL_OUT, 1); return; } genbltz_test(); genbranchlink(); gendelayslot(); gentest_out(); #endif } void genbltzal_idle(void) { #ifdef INTERPRET_BLTZAL_IDLE gencallinterp((native_type)cached_interpreter_table.BLTZAL_IDLE, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BLTZAL_IDLE, 1); return; } genbltz_test(); genbranchlink(); gentest_idle(); genbltzal(); #endif } void genbgezal(void) { #ifdef INTERPRET_BGEZAL gencallinterp((native_type)cached_interpreter_table.BGEZAL, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BGEZAL, 1); return; } genbgez_test(); genbranchlink(); gendelayslot(); gentest(); #endif } void genbgezal_out(void) { #ifdef INTERPRET_BGEZAL_OUT gencallinterp((native_type)cached_interpreter_table.BGEZAL_OUT, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BGEZAL_OUT, 1); return; } genbgez_test(); genbranchlink(); gendelayslot(); gentest_out(); #endif } void genbgezal_idle(void) { #ifdef INTERPRET_BGEZAL_IDLE gencallinterp((native_type)cached_interpreter_table.BGEZAL_IDLE, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BGEZAL_IDLE, 1); return; } genbgez_test(); genbranchlink(); gentest_idle(); genbgezal(); #endif } void genbltzall(void) { #ifdef INTERPRET_BLTZALL gencallinterp((native_type)cached_interpreter_table.BLTZALL, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BLTZALL, 1); return; } genbltz_test(); genbranchlink(); free_all_registers(); gentestl(); #endif } void genbltzall_out(void) { #ifdef INTERPRET_BLTZALL_OUT gencallinterp((native_type)cached_interpreter_table.BLTZALL_OUT, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BLTZALL_OUT, 1); return; } genbltz_test(); genbranchlink(); free_all_registers(); gentestl_out(); #endif } void genbltzall_idle(void) { #ifdef INTERPRET_BLTZALL_IDLE gencallinterp((native_type)cached_interpreter_table.BLTZALL_IDLE, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BLTZALL_IDLE, 1); return; } genbltz_test(); genbranchlink(); gentest_idle(); genbltzall(); #endif } void genbgezall(void) { #ifdef INTERPRET_BGEZALL gencallinterp((native_type)cached_interpreter_table.BGEZALL, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BGEZALL, 1); return; } genbgez_test(); genbranchlink(); free_all_registers(); gentestl(); #endif } void genbgezall_out(void) { #ifdef INTERPRET_BGEZALL_OUT gencallinterp((native_type)cached_interpreter_table.BGEZALL_OUT, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BGEZALL_OUT, 1); return; } genbgez_test(); genbranchlink(); free_all_registers(); gentestl_out(); #endif } void genbgezall_idle(void) { #ifdef INTERPRET_BGEZALL_IDLE gencallinterp((native_type)cached_interpreter_table.BGEZALL_IDLE, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BGEZALL_IDLE, 1); return; } genbgez_test(); genbranchlink(); gentest_idle(); genbgezall(); #endif } libretro-common/glsym/glsym_gl.c000664 001750 001750 00000261545 12655644434 020160 0ustar00sergiosergio000000 000000 /* Copyright (C) 2010-2015 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this libretro SDK code part (glsym). * --------------------------------------------------------------------------------------- * * Permission is hereby granted, free of charge, * to any person obtaining a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include #define SYM(x) { "gl" #x, &(gl##x) } const struct rglgen_sym_map rglgen_symbol_map[] = { SYM(DrawRangeElements), SYM(TexImage3D), SYM(TexSubImage3D), SYM(CopyTexSubImage3D), SYM(ActiveTexture), SYM(SampleCoverage), SYM(CompressedTexImage3D), SYM(CompressedTexImage2D), SYM(CompressedTexImage1D), SYM(CompressedTexSubImage3D), SYM(CompressedTexSubImage2D), SYM(CompressedTexSubImage1D), SYM(GetCompressedTexImage), SYM(ClientActiveTexture), SYM(MultiTexCoord1d), SYM(MultiTexCoord1dv), SYM(MultiTexCoord1f), SYM(MultiTexCoord1fv), SYM(MultiTexCoord1i), SYM(MultiTexCoord1iv), SYM(MultiTexCoord1s), SYM(MultiTexCoord1sv), SYM(MultiTexCoord2d), SYM(MultiTexCoord2dv), SYM(MultiTexCoord2f), SYM(MultiTexCoord2fv), SYM(MultiTexCoord2i), SYM(MultiTexCoord2iv), SYM(MultiTexCoord2s), SYM(MultiTexCoord2sv), SYM(MultiTexCoord3d), SYM(MultiTexCoord3dv), SYM(MultiTexCoord3f), SYM(MultiTexCoord3fv), SYM(MultiTexCoord3i), SYM(MultiTexCoord3iv), SYM(MultiTexCoord3s), SYM(MultiTexCoord3sv), SYM(MultiTexCoord4d), SYM(MultiTexCoord4dv), SYM(MultiTexCoord4f), SYM(MultiTexCoord4fv), SYM(MultiTexCoord4i), SYM(MultiTexCoord4iv), SYM(MultiTexCoord4s), SYM(MultiTexCoord4sv), SYM(LoadTransposeMatrixf), SYM(LoadTransposeMatrixd), SYM(MultTransposeMatrixf), SYM(MultTransposeMatrixd), SYM(BlendFuncSeparate), SYM(MultiDrawArrays), SYM(MultiDrawElements), SYM(PointParameterf), SYM(PointParameterfv), SYM(PointParameteri), SYM(PointParameteriv), SYM(FogCoordf), SYM(FogCoordfv), SYM(FogCoordd), SYM(FogCoorddv), SYM(FogCoordPointer), SYM(SecondaryColor3b), SYM(SecondaryColor3bv), SYM(SecondaryColor3d), SYM(SecondaryColor3dv), SYM(SecondaryColor3f), SYM(SecondaryColor3fv), SYM(SecondaryColor3i), SYM(SecondaryColor3iv), SYM(SecondaryColor3s), SYM(SecondaryColor3sv), SYM(SecondaryColor3ub), SYM(SecondaryColor3ubv), SYM(SecondaryColor3ui), SYM(SecondaryColor3uiv), SYM(SecondaryColor3us), SYM(SecondaryColor3usv), SYM(SecondaryColorPointer), SYM(WindowPos2d), SYM(WindowPos2dv), SYM(WindowPos2f), SYM(WindowPos2fv), SYM(WindowPos2i), SYM(WindowPos2iv), SYM(WindowPos2s), SYM(WindowPos2sv), SYM(WindowPos3d), SYM(WindowPos3dv), SYM(WindowPos3f), SYM(WindowPos3fv), SYM(WindowPos3i), SYM(WindowPos3iv), SYM(WindowPos3s), SYM(WindowPos3sv), SYM(BlendColor), SYM(BlendEquation), SYM(GenQueries), SYM(DeleteQueries), SYM(IsQuery), SYM(BeginQuery), SYM(EndQuery), SYM(GetQueryiv), SYM(GetQueryObjectiv), SYM(GetQueryObjectuiv), SYM(BindBuffer), SYM(DeleteBuffers), SYM(GenBuffers), SYM(IsBuffer), SYM(BufferData), SYM(BufferSubData), SYM(GetBufferSubData), SYM(MapBuffer), SYM(UnmapBuffer), SYM(GetBufferParameteriv), SYM(GetBufferPointerv), SYM(BlendEquationSeparate), SYM(DrawBuffers), SYM(StencilOpSeparate), SYM(StencilFuncSeparate), SYM(StencilMaskSeparate), SYM(AttachShader), SYM(BindAttribLocation), SYM(CompileShader), SYM(CreateProgram), SYM(CreateShader), SYM(DeleteProgram), SYM(DeleteShader), SYM(DetachShader), SYM(DisableVertexAttribArray), SYM(EnableVertexAttribArray), SYM(GetActiveAttrib), SYM(GetActiveUniform), SYM(GetAttachedShaders), SYM(GetAttribLocation), SYM(GetProgramiv), SYM(GetProgramInfoLog), SYM(GetShaderiv), SYM(GetShaderInfoLog), SYM(GetShaderSource), SYM(GetUniformLocation), SYM(GetUniformfv), SYM(GetUniformiv), SYM(GetVertexAttribdv), SYM(GetVertexAttribfv), SYM(GetVertexAttribiv), SYM(GetVertexAttribPointerv), SYM(IsProgram), SYM(IsShader), SYM(LinkProgram), SYM(ShaderSource), SYM(UseProgram), SYM(Uniform1f), SYM(Uniform2f), SYM(Uniform3f), SYM(Uniform4f), SYM(Uniform1i), SYM(Uniform2i), SYM(Uniform3i), SYM(Uniform4i), SYM(Uniform1fv), SYM(Uniform2fv), SYM(Uniform3fv), SYM(Uniform4fv), SYM(Uniform1iv), SYM(Uniform2iv), SYM(Uniform3iv), SYM(Uniform4iv), SYM(UniformMatrix2fv), SYM(UniformMatrix3fv), SYM(UniformMatrix4fv), SYM(ValidateProgram), SYM(VertexAttrib1d), SYM(VertexAttrib1dv), SYM(VertexAttrib1f), SYM(VertexAttrib1fv), SYM(VertexAttrib1s), SYM(VertexAttrib1sv), SYM(VertexAttrib2d), SYM(VertexAttrib2dv), SYM(VertexAttrib2f), SYM(VertexAttrib2fv), SYM(VertexAttrib2s), SYM(VertexAttrib2sv), SYM(VertexAttrib3d), SYM(VertexAttrib3dv), SYM(VertexAttrib3f), SYM(VertexAttrib3fv), SYM(VertexAttrib3s), SYM(VertexAttrib3sv), SYM(VertexAttrib4Nbv), SYM(VertexAttrib4Niv), SYM(VertexAttrib4Nsv), SYM(VertexAttrib4Nub), SYM(VertexAttrib4Nubv), SYM(VertexAttrib4Nuiv), SYM(VertexAttrib4Nusv), SYM(VertexAttrib4bv), SYM(VertexAttrib4d), SYM(VertexAttrib4dv), SYM(VertexAttrib4f), SYM(VertexAttrib4fv), SYM(VertexAttrib4iv), SYM(VertexAttrib4s), SYM(VertexAttrib4sv), SYM(VertexAttrib4ubv), SYM(VertexAttrib4uiv), SYM(VertexAttrib4usv), SYM(VertexAttribPointer), SYM(UniformMatrix2x3fv), SYM(UniformMatrix3x2fv), SYM(UniformMatrix2x4fv), SYM(UniformMatrix4x2fv), SYM(UniformMatrix3x4fv), SYM(UniformMatrix4x3fv), SYM(ColorMaski), SYM(GetBooleani_v), SYM(GetIntegeri_v), SYM(Enablei), SYM(Disablei), SYM(IsEnabledi), SYM(BeginTransformFeedback), SYM(EndTransformFeedback), SYM(BindBufferRange), SYM(BindBufferBase), SYM(TransformFeedbackVaryings), SYM(GetTransformFeedbackVarying), SYM(ClampColor), SYM(BeginConditionalRender), SYM(EndConditionalRender), SYM(VertexAttribIPointer), SYM(GetVertexAttribIiv), SYM(GetVertexAttribIuiv), SYM(VertexAttribI1i), SYM(VertexAttribI2i), SYM(VertexAttribI3i), SYM(VertexAttribI4i), SYM(VertexAttribI1ui), SYM(VertexAttribI2ui), SYM(VertexAttribI3ui), SYM(VertexAttribI4ui), SYM(VertexAttribI1iv), SYM(VertexAttribI2iv), SYM(VertexAttribI3iv), SYM(VertexAttribI4iv), SYM(VertexAttribI1uiv), SYM(VertexAttribI2uiv), SYM(VertexAttribI3uiv), SYM(VertexAttribI4uiv), SYM(VertexAttribI4bv), SYM(VertexAttribI4sv), SYM(VertexAttribI4ubv), SYM(VertexAttribI4usv), SYM(GetUniformuiv), SYM(BindFragDataLocation), SYM(GetFragDataLocation), SYM(Uniform1ui), SYM(Uniform2ui), SYM(Uniform3ui), SYM(Uniform4ui), SYM(Uniform1uiv), SYM(Uniform2uiv), SYM(Uniform3uiv), SYM(Uniform4uiv), SYM(TexParameterIiv), SYM(TexParameterIuiv), SYM(GetTexParameterIiv), SYM(GetTexParameterIuiv), SYM(ClearBufferiv), SYM(ClearBufferuiv), SYM(ClearBufferfv), SYM(ClearBufferfi), SYM(GetStringi), SYM(IsRenderbuffer), SYM(BindRenderbuffer), SYM(DeleteRenderbuffers), SYM(GenRenderbuffers), SYM(RenderbufferStorage), SYM(GetRenderbufferParameteriv), SYM(IsFramebuffer), SYM(BindFramebuffer), SYM(DeleteFramebuffers), SYM(GenFramebuffers), SYM(CheckFramebufferStatus), SYM(FramebufferTexture1D), SYM(FramebufferTexture2D), SYM(FramebufferTexture3D), SYM(FramebufferRenderbuffer), SYM(GetFramebufferAttachmentParameteriv), SYM(GenerateMipmap), SYM(BlitFramebuffer), SYM(RenderbufferStorageMultisample), SYM(FramebufferTextureLayer), SYM(MapBufferRange), SYM(FlushMappedBufferRange), SYM(BindVertexArray), SYM(DeleteVertexArrays), SYM(GenVertexArrays), SYM(IsVertexArray), SYM(DrawArraysInstanced), SYM(DrawElementsInstanced), SYM(TexBuffer), SYM(PrimitiveRestartIndex), SYM(CopyBufferSubData), SYM(GetUniformIndices), SYM(GetActiveUniformsiv), SYM(GetActiveUniformName), SYM(GetUniformBlockIndex), SYM(GetActiveUniformBlockiv), SYM(GetActiveUniformBlockName), SYM(UniformBlockBinding), SYM(DrawElementsBaseVertex), SYM(DrawRangeElementsBaseVertex), SYM(DrawElementsInstancedBaseVertex), SYM(MultiDrawElementsBaseVertex), SYM(ProvokingVertex), SYM(FenceSync), SYM(IsSync), SYM(DeleteSync), SYM(ClientWaitSync), SYM(WaitSync), SYM(GetInteger64v), SYM(GetSynciv), SYM(GetInteger64i_v), SYM(GetBufferParameteri64v), SYM(FramebufferTexture), SYM(TexImage2DMultisample), SYM(TexImage3DMultisample), SYM(GetMultisamplefv), SYM(SampleMaski), SYM(BindFragDataLocationIndexed), SYM(GetFragDataIndex), SYM(GenSamplers), SYM(DeleteSamplers), SYM(IsSampler), SYM(BindSampler), SYM(SamplerParameteri), SYM(SamplerParameteriv), SYM(SamplerParameterf), SYM(SamplerParameterfv), SYM(SamplerParameterIiv), SYM(SamplerParameterIuiv), SYM(GetSamplerParameteriv), SYM(GetSamplerParameterIiv), SYM(GetSamplerParameterfv), SYM(GetSamplerParameterIuiv), SYM(QueryCounter), SYM(GetQueryObjecti64v), SYM(GetQueryObjectui64v), SYM(VertexAttribDivisor), SYM(VertexAttribP1ui), SYM(VertexAttribP1uiv), SYM(VertexAttribP2ui), SYM(VertexAttribP2uiv), SYM(VertexAttribP3ui), SYM(VertexAttribP3uiv), SYM(VertexAttribP4ui), SYM(VertexAttribP4uiv), SYM(VertexP2ui), SYM(VertexP2uiv), SYM(VertexP3ui), SYM(VertexP3uiv), SYM(VertexP4ui), SYM(VertexP4uiv), SYM(TexCoordP1ui), SYM(TexCoordP1uiv), SYM(TexCoordP2ui), SYM(TexCoordP2uiv), SYM(TexCoordP3ui), SYM(TexCoordP3uiv), SYM(TexCoordP4ui), SYM(TexCoordP4uiv), SYM(MultiTexCoordP1ui), SYM(MultiTexCoordP1uiv), SYM(MultiTexCoordP2ui), SYM(MultiTexCoordP2uiv), SYM(MultiTexCoordP3ui), SYM(MultiTexCoordP3uiv), SYM(MultiTexCoordP4ui), SYM(MultiTexCoordP4uiv), SYM(NormalP3ui), SYM(NormalP3uiv), SYM(ColorP3ui), SYM(ColorP3uiv), SYM(ColorP4ui), SYM(ColorP4uiv), SYM(SecondaryColorP3ui), SYM(SecondaryColorP3uiv), SYM(MinSampleShading), SYM(BlendEquationi), SYM(BlendEquationSeparatei), SYM(BlendFunci), SYM(BlendFuncSeparatei), SYM(DrawArraysIndirect), SYM(DrawElementsIndirect), SYM(Uniform1d), SYM(Uniform2d), SYM(Uniform3d), SYM(Uniform4d), SYM(Uniform1dv), SYM(Uniform2dv), SYM(Uniform3dv), SYM(Uniform4dv), SYM(UniformMatrix2dv), SYM(UniformMatrix3dv), SYM(UniformMatrix4dv), SYM(UniformMatrix2x3dv), SYM(UniformMatrix2x4dv), SYM(UniformMatrix3x2dv), SYM(UniformMatrix3x4dv), SYM(UniformMatrix4x2dv), SYM(UniformMatrix4x3dv), SYM(GetUniformdv), SYM(GetSubroutineUniformLocation), SYM(GetSubroutineIndex), SYM(GetActiveSubroutineUniformiv), SYM(GetActiveSubroutineUniformName), SYM(GetActiveSubroutineName), SYM(UniformSubroutinesuiv), SYM(GetUniformSubroutineuiv), SYM(GetProgramStageiv), SYM(PatchParameteri), SYM(PatchParameterfv), SYM(BindTransformFeedback), SYM(DeleteTransformFeedbacks), SYM(GenTransformFeedbacks), SYM(IsTransformFeedback), SYM(PauseTransformFeedback), SYM(ResumeTransformFeedback), SYM(DrawTransformFeedback), SYM(DrawTransformFeedbackStream), SYM(BeginQueryIndexed), SYM(EndQueryIndexed), SYM(GetQueryIndexediv), SYM(ReleaseShaderCompiler), SYM(ShaderBinary), SYM(GetShaderPrecisionFormat), SYM(DepthRangef), SYM(ClearDepthf), SYM(GetProgramBinary), SYM(ProgramBinary), SYM(ProgramParameteri), SYM(UseProgramStages), SYM(ActiveShaderProgram), SYM(CreateShaderProgramv), SYM(BindProgramPipeline), SYM(DeleteProgramPipelines), SYM(GenProgramPipelines), SYM(IsProgramPipeline), SYM(GetProgramPipelineiv), SYM(ProgramUniform1i), SYM(ProgramUniform1iv), SYM(ProgramUniform1f), SYM(ProgramUniform1fv), SYM(ProgramUniform1d), SYM(ProgramUniform1dv), SYM(ProgramUniform1ui), SYM(ProgramUniform1uiv), SYM(ProgramUniform2i), SYM(ProgramUniform2iv), SYM(ProgramUniform2f), SYM(ProgramUniform2fv), SYM(ProgramUniform2d), SYM(ProgramUniform2dv), SYM(ProgramUniform2ui), SYM(ProgramUniform2uiv), SYM(ProgramUniform3i), SYM(ProgramUniform3iv), SYM(ProgramUniform3f), SYM(ProgramUniform3fv), SYM(ProgramUniform3d), SYM(ProgramUniform3dv), SYM(ProgramUniform3ui), SYM(ProgramUniform3uiv), SYM(ProgramUniform4i), SYM(ProgramUniform4iv), SYM(ProgramUniform4f), SYM(ProgramUniform4fv), SYM(ProgramUniform4d), SYM(ProgramUniform4dv), SYM(ProgramUniform4ui), SYM(ProgramUniform4uiv), SYM(ProgramUniformMatrix2fv), SYM(ProgramUniformMatrix3fv), SYM(ProgramUniformMatrix4fv), SYM(ProgramUniformMatrix2dv), SYM(ProgramUniformMatrix3dv), SYM(ProgramUniformMatrix4dv), SYM(ProgramUniformMatrix2x3fv), SYM(ProgramUniformMatrix3x2fv), SYM(ProgramUniformMatrix2x4fv), SYM(ProgramUniformMatrix4x2fv), SYM(ProgramUniformMatrix3x4fv), SYM(ProgramUniformMatrix4x3fv), SYM(ProgramUniformMatrix2x3dv), SYM(ProgramUniformMatrix3x2dv), SYM(ProgramUniformMatrix2x4dv), SYM(ProgramUniformMatrix4x2dv), SYM(ProgramUniformMatrix3x4dv), SYM(ProgramUniformMatrix4x3dv), SYM(ValidateProgramPipeline), SYM(GetProgramPipelineInfoLog), SYM(VertexAttribL1d), SYM(VertexAttribL2d), SYM(VertexAttribL3d), SYM(VertexAttribL4d), SYM(VertexAttribL1dv), SYM(VertexAttribL2dv), SYM(VertexAttribL3dv), SYM(VertexAttribL4dv), SYM(VertexAttribLPointer), SYM(GetVertexAttribLdv), SYM(ViewportArrayv), SYM(ViewportIndexedf), SYM(ViewportIndexedfv), SYM(ScissorArrayv), SYM(ScissorIndexed), SYM(ScissorIndexedv), SYM(DepthRangeArrayv), SYM(DepthRangeIndexed), SYM(GetFloati_v), SYM(GetDoublei_v), SYM(DrawArraysInstancedBaseInstance), SYM(DrawElementsInstancedBaseInstance), SYM(DrawElementsInstancedBaseVertexBaseInstance), SYM(GetInternalformativ), SYM(GetActiveAtomicCounterBufferiv), SYM(BindImageTexture), SYM(MemoryBarrier), SYM(TexStorage1D), SYM(TexStorage2D), SYM(TexStorage3D), SYM(DrawTransformFeedbackInstanced), SYM(DrawTransformFeedbackStreamInstanced), SYM(ClearBufferData), SYM(ClearBufferSubData), SYM(DispatchCompute), SYM(DispatchComputeIndirect), SYM(CopyImageSubData), SYM(FramebufferParameteri), SYM(GetFramebufferParameteriv), SYM(GetInternalformati64v), SYM(InvalidateTexSubImage), SYM(InvalidateTexImage), SYM(InvalidateBufferSubData), SYM(InvalidateBufferData), SYM(InvalidateFramebuffer), SYM(InvalidateSubFramebuffer), SYM(MultiDrawArraysIndirect), SYM(MultiDrawElementsIndirect), SYM(GetProgramInterfaceiv), SYM(GetProgramResourceIndex), SYM(GetProgramResourceName), SYM(GetProgramResourceiv), SYM(GetProgramResourceLocation), SYM(GetProgramResourceLocationIndex), SYM(ShaderStorageBlockBinding), SYM(TexBufferRange), SYM(TexStorage2DMultisample), SYM(TexStorage3DMultisample), SYM(TextureView), SYM(BindVertexBuffer), SYM(VertexAttribFormat), SYM(VertexAttribIFormat), SYM(VertexAttribLFormat), SYM(VertexAttribBinding), SYM(VertexBindingDivisor), SYM(DebugMessageControl), SYM(DebugMessageInsert), SYM(DebugMessageCallback), SYM(GetDebugMessageLog), SYM(PushDebugGroup), SYM(PopDebugGroup), SYM(ObjectLabel), SYM(GetObjectLabel), SYM(ObjectPtrLabel), SYM(GetObjectPtrLabel), SYM(BufferStorage), SYM(ClearTexImage), SYM(ClearTexSubImage), SYM(BindBuffersBase), SYM(BindBuffersRange), SYM(BindTextures), SYM(BindSamplers), SYM(BindImageTextures), SYM(BindVertexBuffers), SYM(GetTextureHandleARB), SYM(GetTextureSamplerHandleARB), SYM(MakeTextureHandleResidentARB), SYM(MakeTextureHandleNonResidentARB), SYM(GetImageHandleARB), SYM(MakeImageHandleResidentARB), SYM(MakeImageHandleNonResidentARB), SYM(UniformHandleui64ARB), SYM(UniformHandleui64vARB), SYM(ProgramUniformHandleui64ARB), SYM(ProgramUniformHandleui64vARB), SYM(IsTextureHandleResidentARB), SYM(IsImageHandleResidentARB), SYM(VertexAttribL1ui64ARB), SYM(VertexAttribL1ui64vARB), SYM(GetVertexAttribLui64vARB), SYM(CreateSyncFromCLeventARB), SYM(ClampColorARB), SYM(DispatchComputeGroupSizeARB), SYM(DebugMessageControlARB), SYM(DebugMessageInsertARB), SYM(DebugMessageCallbackARB), SYM(GetDebugMessageLogARB), SYM(DrawBuffersARB), SYM(BlendEquationiARB), SYM(BlendEquationSeparateiARB), SYM(BlendFunciARB), SYM(BlendFuncSeparateiARB), SYM(DrawArraysInstancedARB), SYM(DrawElementsInstancedARB), SYM(ProgramStringARB), SYM(BindProgramARB), SYM(DeleteProgramsARB), SYM(GenProgramsARB), SYM(ProgramEnvParameter4dARB), SYM(ProgramEnvParameter4dvARB), SYM(ProgramEnvParameter4fARB), SYM(ProgramEnvParameter4fvARB), SYM(ProgramLocalParameter4dARB), SYM(ProgramLocalParameter4dvARB), SYM(ProgramLocalParameter4fARB), SYM(ProgramLocalParameter4fvARB), SYM(GetProgramEnvParameterdvARB), SYM(GetProgramEnvParameterfvARB), SYM(GetProgramLocalParameterdvARB), SYM(GetProgramLocalParameterfvARB), SYM(GetProgramivARB), SYM(GetProgramStringARB), SYM(IsProgramARB), SYM(ProgramParameteriARB), SYM(FramebufferTextureARB), SYM(FramebufferTextureLayerARB), SYM(FramebufferTextureFaceARB), SYM(ColorTable), SYM(ColorTableParameterfv), SYM(ColorTableParameteriv), SYM(CopyColorTable), SYM(GetColorTable), SYM(GetColorTableParameterfv), SYM(GetColorTableParameteriv), SYM(ColorSubTable), SYM(CopyColorSubTable), SYM(ConvolutionFilter1D), SYM(ConvolutionFilter2D), SYM(ConvolutionParameterf), SYM(ConvolutionParameterfv), SYM(ConvolutionParameteri), SYM(ConvolutionParameteriv), SYM(CopyConvolutionFilter1D), SYM(CopyConvolutionFilter2D), SYM(GetConvolutionFilter), SYM(GetConvolutionParameterfv), SYM(GetConvolutionParameteriv), SYM(GetSeparableFilter), SYM(SeparableFilter2D), SYM(GetHistogram), SYM(GetHistogramParameterfv), SYM(GetHistogramParameteriv), SYM(GetMinmax), SYM(GetMinmaxParameterfv), SYM(GetMinmaxParameteriv), SYM(Histogram), SYM(Minmax), SYM(ResetHistogram), SYM(ResetMinmax), SYM(MultiDrawArraysIndirectCountARB), SYM(MultiDrawElementsIndirectCountARB), SYM(VertexAttribDivisorARB), SYM(CurrentPaletteMatrixARB), SYM(MatrixIndexubvARB), SYM(MatrixIndexusvARB), SYM(MatrixIndexuivARB), SYM(MatrixIndexPointerARB), SYM(SampleCoverageARB), SYM(ActiveTextureARB), SYM(ClientActiveTextureARB), SYM(MultiTexCoord1dARB), SYM(MultiTexCoord1dvARB), SYM(MultiTexCoord1fARB), SYM(MultiTexCoord1fvARB), SYM(MultiTexCoord1iARB), SYM(MultiTexCoord1ivARB), SYM(MultiTexCoord1sARB), SYM(MultiTexCoord1svARB), SYM(MultiTexCoord2dARB), SYM(MultiTexCoord2dvARB), SYM(MultiTexCoord2fARB), SYM(MultiTexCoord2fvARB), SYM(MultiTexCoord2iARB), SYM(MultiTexCoord2ivARB), SYM(MultiTexCoord2sARB), SYM(MultiTexCoord2svARB), SYM(MultiTexCoord3dARB), SYM(MultiTexCoord3dvARB), SYM(MultiTexCoord3fARB), SYM(MultiTexCoord3fvARB), SYM(MultiTexCoord3iARB), SYM(MultiTexCoord3ivARB), SYM(MultiTexCoord3sARB), SYM(MultiTexCoord3svARB), SYM(MultiTexCoord4dARB), SYM(MultiTexCoord4dvARB), SYM(MultiTexCoord4fARB), SYM(MultiTexCoord4fvARB), SYM(MultiTexCoord4iARB), SYM(MultiTexCoord4ivARB), SYM(MultiTexCoord4sARB), SYM(MultiTexCoord4svARB), SYM(GenQueriesARB), SYM(DeleteQueriesARB), SYM(IsQueryARB), SYM(BeginQueryARB), SYM(EndQueryARB), SYM(GetQueryivARB), SYM(GetQueryObjectivARB), SYM(GetQueryObjectuivARB), SYM(PointParameterfARB), SYM(PointParameterfvARB), SYM(GetGraphicsResetStatusARB), SYM(GetnTexImageARB), SYM(ReadnPixelsARB), SYM(GetnCompressedTexImageARB), SYM(GetnUniformfvARB), SYM(GetnUniformivARB), SYM(GetnUniformuivARB), SYM(GetnUniformdvARB), SYM(GetnMapdvARB), SYM(GetnMapfvARB), SYM(GetnMapivARB), SYM(GetnPixelMapfvARB), SYM(GetnPixelMapuivARB), SYM(GetnPixelMapusvARB), SYM(GetnPolygonStippleARB), SYM(GetnColorTableARB), SYM(GetnConvolutionFilterARB), SYM(GetnSeparableFilterARB), SYM(GetnHistogramARB), SYM(GetnMinmaxARB), SYM(MinSampleShadingARB), SYM(DeleteObjectARB), SYM(GetHandleARB), SYM(DetachObjectARB), SYM(CreateShaderObjectARB), SYM(ShaderSourceARB), SYM(CompileShaderARB), SYM(CreateProgramObjectARB), SYM(AttachObjectARB), SYM(LinkProgramARB), SYM(UseProgramObjectARB), SYM(ValidateProgramARB), SYM(Uniform1fARB), SYM(Uniform2fARB), SYM(Uniform3fARB), SYM(Uniform4fARB), SYM(Uniform1iARB), SYM(Uniform2iARB), SYM(Uniform3iARB), SYM(Uniform4iARB), SYM(Uniform1fvARB), SYM(Uniform2fvARB), SYM(Uniform3fvARB), SYM(Uniform4fvARB), SYM(Uniform1ivARB), SYM(Uniform2ivARB), SYM(Uniform3ivARB), SYM(Uniform4ivARB), SYM(UniformMatrix2fvARB), SYM(UniformMatrix3fvARB), SYM(UniformMatrix4fvARB), SYM(GetObjectParameterfvARB), SYM(GetObjectParameterivARB), SYM(GetInfoLogARB), SYM(GetAttachedObjectsARB), SYM(GetUniformLocationARB), SYM(GetActiveUniformARB), SYM(GetUniformfvARB), SYM(GetUniformivARB), SYM(GetShaderSourceARB), SYM(NamedStringARB), SYM(DeleteNamedStringARB), SYM(CompileShaderIncludeARB), SYM(IsNamedStringARB), SYM(GetNamedStringARB), SYM(GetNamedStringivARB), SYM(TexPageCommitmentARB), SYM(TexBufferARB), SYM(CompressedTexImage3DARB), SYM(CompressedTexImage2DARB), SYM(CompressedTexImage1DARB), SYM(CompressedTexSubImage3DARB), SYM(CompressedTexSubImage2DARB), SYM(CompressedTexSubImage1DARB), SYM(GetCompressedTexImageARB), SYM(LoadTransposeMatrixfARB), SYM(LoadTransposeMatrixdARB), SYM(MultTransposeMatrixfARB), SYM(MultTransposeMatrixdARB), SYM(WeightbvARB), SYM(WeightsvARB), SYM(WeightivARB), SYM(WeightfvARB), SYM(WeightdvARB), SYM(WeightubvARB), SYM(WeightusvARB), SYM(WeightuivARB), SYM(WeightPointerARB), SYM(VertexBlendARB), SYM(BindBufferARB), SYM(DeleteBuffersARB), SYM(GenBuffersARB), SYM(IsBufferARB), SYM(BufferDataARB), SYM(BufferSubDataARB), SYM(GetBufferSubDataARB), SYM(MapBufferARB), SYM(UnmapBufferARB), SYM(GetBufferParameterivARB), SYM(GetBufferPointervARB), SYM(VertexAttrib1dARB), SYM(VertexAttrib1dvARB), SYM(VertexAttrib1fARB), SYM(VertexAttrib1fvARB), SYM(VertexAttrib1sARB), SYM(VertexAttrib1svARB), SYM(VertexAttrib2dARB), SYM(VertexAttrib2dvARB), SYM(VertexAttrib2fARB), SYM(VertexAttrib2fvARB), SYM(VertexAttrib2sARB), SYM(VertexAttrib2svARB), SYM(VertexAttrib3dARB), SYM(VertexAttrib3dvARB), SYM(VertexAttrib3fARB), SYM(VertexAttrib3fvARB), SYM(VertexAttrib3sARB), SYM(VertexAttrib3svARB), SYM(VertexAttrib4NbvARB), SYM(VertexAttrib4NivARB), SYM(VertexAttrib4NsvARB), SYM(VertexAttrib4NubARB), SYM(VertexAttrib4NubvARB), SYM(VertexAttrib4NuivARB), SYM(VertexAttrib4NusvARB), SYM(VertexAttrib4bvARB), SYM(VertexAttrib4dARB), SYM(VertexAttrib4dvARB), SYM(VertexAttrib4fARB), SYM(VertexAttrib4fvARB), SYM(VertexAttrib4ivARB), SYM(VertexAttrib4sARB), SYM(VertexAttrib4svARB), SYM(VertexAttrib4ubvARB), SYM(VertexAttrib4uivARB), SYM(VertexAttrib4usvARB), SYM(VertexAttribPointerARB), SYM(EnableVertexAttribArrayARB), SYM(DisableVertexAttribArrayARB), SYM(GetVertexAttribdvARB), SYM(GetVertexAttribfvARB), SYM(GetVertexAttribivARB), SYM(GetVertexAttribPointervARB), SYM(BindAttribLocationARB), SYM(GetActiveAttribARB), SYM(GetAttribLocationARB), SYM(WindowPos2dARB), SYM(WindowPos2dvARB), SYM(WindowPos2fARB), SYM(WindowPos2fvARB), SYM(WindowPos2iARB), SYM(WindowPos2ivARB), SYM(WindowPos2sARB), SYM(WindowPos2svARB), SYM(WindowPos3dARB), SYM(WindowPos3dvARB), SYM(WindowPos3fARB), SYM(WindowPos3fvARB), SYM(WindowPos3iARB), SYM(WindowPos3ivARB), SYM(WindowPos3sARB), SYM(WindowPos3svARB), SYM(MultiTexCoord1bOES), SYM(MultiTexCoord1bvOES), SYM(MultiTexCoord2bOES), SYM(MultiTexCoord2bvOES), SYM(MultiTexCoord3bOES), SYM(MultiTexCoord3bvOES), SYM(MultiTexCoord4bOES), SYM(MultiTexCoord4bvOES), SYM(TexCoord1bOES), SYM(TexCoord1bvOES), SYM(TexCoord2bOES), SYM(TexCoord2bvOES), SYM(TexCoord3bOES), SYM(TexCoord3bvOES), SYM(TexCoord4bOES), SYM(TexCoord4bvOES), SYM(Vertex2bOES), SYM(Vertex2bvOES), SYM(Vertex3bOES), SYM(Vertex3bvOES), SYM(Vertex4bOES), SYM(Vertex4bvOES), SYM(AlphaFuncxOES), SYM(ClearColorxOES), SYM(ClearDepthxOES), SYM(ClipPlanexOES), SYM(Color4xOES), SYM(DepthRangexOES), SYM(FogxOES), SYM(FogxvOES), SYM(FrustumxOES), SYM(GetClipPlanexOES), SYM(GetFixedvOES), SYM(GetTexEnvxvOES), SYM(GetTexParameterxvOES), SYM(LightModelxOES), SYM(LightModelxvOES), SYM(LightxOES), SYM(LightxvOES), SYM(LineWidthxOES), SYM(LoadMatrixxOES), SYM(MaterialxOES), SYM(MaterialxvOES), SYM(MultMatrixxOES), SYM(MultiTexCoord4xOES), SYM(Normal3xOES), SYM(OrthoxOES), SYM(PointParameterxvOES), SYM(PointSizexOES), SYM(PolygonOffsetxOES), SYM(RotatexOES), SYM(SampleCoverageOES), SYM(ScalexOES), SYM(TexEnvxOES), SYM(TexEnvxvOES), SYM(TexParameterxOES), SYM(TexParameterxvOES), SYM(TranslatexOES), SYM(AccumxOES), SYM(BitmapxOES), SYM(BlendColorxOES), SYM(ClearAccumxOES), SYM(Color3xOES), SYM(Color3xvOES), SYM(Color4xvOES), SYM(ConvolutionParameterxOES), SYM(ConvolutionParameterxvOES), SYM(EvalCoord1xOES), SYM(EvalCoord1xvOES), SYM(EvalCoord2xOES), SYM(EvalCoord2xvOES), SYM(FeedbackBufferxOES), SYM(GetConvolutionParameterxvOES), SYM(GetHistogramParameterxvOES), SYM(GetLightxOES), SYM(GetMapxvOES), SYM(GetMaterialxOES), SYM(GetPixelMapxv), SYM(GetTexGenxvOES), SYM(GetTexLevelParameterxvOES), SYM(IndexxOES), SYM(IndexxvOES), SYM(LoadTransposeMatrixxOES), SYM(Map1xOES), SYM(Map2xOES), SYM(MapGrid1xOES), SYM(MapGrid2xOES), SYM(MultTransposeMatrixxOES), SYM(MultiTexCoord1xOES), SYM(MultiTexCoord1xvOES), SYM(MultiTexCoord2xOES), SYM(MultiTexCoord2xvOES), SYM(MultiTexCoord3xOES), SYM(MultiTexCoord3xvOES), SYM(MultiTexCoord4xvOES), SYM(Normal3xvOES), SYM(PassThroughxOES), SYM(PixelMapx), SYM(PixelStorex), SYM(PixelTransferxOES), SYM(PixelZoomxOES), SYM(PrioritizeTexturesxOES), SYM(RasterPos2xOES), SYM(RasterPos2xvOES), SYM(RasterPos3xOES), SYM(RasterPos3xvOES), SYM(RasterPos4xOES), SYM(RasterPos4xvOES), SYM(RectxOES), SYM(RectxvOES), SYM(TexCoord1xOES), SYM(TexCoord1xvOES), SYM(TexCoord2xOES), SYM(TexCoord2xvOES), SYM(TexCoord3xOES), SYM(TexCoord3xvOES), SYM(TexCoord4xOES), SYM(TexCoord4xvOES), SYM(TexGenxOES), SYM(TexGenxvOES), SYM(Vertex2xOES), SYM(Vertex2xvOES), SYM(Vertex3xOES), SYM(Vertex3xvOES), SYM(Vertex4xOES), SYM(Vertex4xvOES), SYM(QueryMatrixxOES), SYM(ClearDepthfOES), SYM(ClipPlanefOES), SYM(DepthRangefOES), SYM(FrustumfOES), SYM(GetClipPlanefOES), SYM(OrthofOES), SYM(ImageTransformParameteriHP), SYM(ImageTransformParameterfHP), SYM(ImageTransformParameterivHP), SYM(ImageTransformParameterfvHP), SYM(GetImageTransformParameterivHP), SYM(GetImageTransformParameterfvHP), { NULL, NULL }, }; RGLSYMGLDRAWRANGEELEMENTSPROC __rglgen_glDrawRangeElements; RGLSYMGLTEXIMAGE3DPROC __rglgen_glTexImage3D; RGLSYMGLTEXSUBIMAGE3DPROC __rglgen_glTexSubImage3D; RGLSYMGLCOPYTEXSUBIMAGE3DPROC __rglgen_glCopyTexSubImage3D; RGLSYMGLACTIVETEXTUREPROC __rglgen_glActiveTexture; RGLSYMGLSAMPLECOVERAGEPROC __rglgen_glSampleCoverage; RGLSYMGLCOMPRESSEDTEXIMAGE3DPROC __rglgen_glCompressedTexImage3D; RGLSYMGLCOMPRESSEDTEXIMAGE2DPROC __rglgen_glCompressedTexImage2D; RGLSYMGLCOMPRESSEDTEXIMAGE1DPROC __rglgen_glCompressedTexImage1D; RGLSYMGLCOMPRESSEDTEXSUBIMAGE3DPROC __rglgen_glCompressedTexSubImage3D; RGLSYMGLCOMPRESSEDTEXSUBIMAGE2DPROC __rglgen_glCompressedTexSubImage2D; RGLSYMGLCOMPRESSEDTEXSUBIMAGE1DPROC __rglgen_glCompressedTexSubImage1D; RGLSYMGLGETCOMPRESSEDTEXIMAGEPROC __rglgen_glGetCompressedTexImage; RGLSYMGLCLIENTACTIVETEXTUREPROC __rglgen_glClientActiveTexture; RGLSYMGLMULTITEXCOORD1DPROC __rglgen_glMultiTexCoord1d; RGLSYMGLMULTITEXCOORD1DVPROC __rglgen_glMultiTexCoord1dv; RGLSYMGLMULTITEXCOORD1FPROC __rglgen_glMultiTexCoord1f; RGLSYMGLMULTITEXCOORD1FVPROC __rglgen_glMultiTexCoord1fv; RGLSYMGLMULTITEXCOORD1IPROC __rglgen_glMultiTexCoord1i; RGLSYMGLMULTITEXCOORD1IVPROC __rglgen_glMultiTexCoord1iv; RGLSYMGLMULTITEXCOORD1SPROC __rglgen_glMultiTexCoord1s; RGLSYMGLMULTITEXCOORD1SVPROC __rglgen_glMultiTexCoord1sv; RGLSYMGLMULTITEXCOORD2DPROC __rglgen_glMultiTexCoord2d; RGLSYMGLMULTITEXCOORD2DVPROC __rglgen_glMultiTexCoord2dv; RGLSYMGLMULTITEXCOORD2FPROC __rglgen_glMultiTexCoord2f; RGLSYMGLMULTITEXCOORD2FVPROC __rglgen_glMultiTexCoord2fv; RGLSYMGLMULTITEXCOORD2IPROC __rglgen_glMultiTexCoord2i; RGLSYMGLMULTITEXCOORD2IVPROC __rglgen_glMultiTexCoord2iv; RGLSYMGLMULTITEXCOORD2SPROC __rglgen_glMultiTexCoord2s; RGLSYMGLMULTITEXCOORD2SVPROC __rglgen_glMultiTexCoord2sv; RGLSYMGLMULTITEXCOORD3DPROC __rglgen_glMultiTexCoord3d; RGLSYMGLMULTITEXCOORD3DVPROC __rglgen_glMultiTexCoord3dv; RGLSYMGLMULTITEXCOORD3FPROC __rglgen_glMultiTexCoord3f; RGLSYMGLMULTITEXCOORD3FVPROC __rglgen_glMultiTexCoord3fv; RGLSYMGLMULTITEXCOORD3IPROC __rglgen_glMultiTexCoord3i; RGLSYMGLMULTITEXCOORD3IVPROC __rglgen_glMultiTexCoord3iv; RGLSYMGLMULTITEXCOORD3SPROC __rglgen_glMultiTexCoord3s; RGLSYMGLMULTITEXCOORD3SVPROC __rglgen_glMultiTexCoord3sv; RGLSYMGLMULTITEXCOORD4DPROC __rglgen_glMultiTexCoord4d; RGLSYMGLMULTITEXCOORD4DVPROC __rglgen_glMultiTexCoord4dv; RGLSYMGLMULTITEXCOORD4FPROC __rglgen_glMultiTexCoord4f; RGLSYMGLMULTITEXCOORD4FVPROC __rglgen_glMultiTexCoord4fv; RGLSYMGLMULTITEXCOORD4IPROC __rglgen_glMultiTexCoord4i; RGLSYMGLMULTITEXCOORD4IVPROC __rglgen_glMultiTexCoord4iv; RGLSYMGLMULTITEXCOORD4SPROC __rglgen_glMultiTexCoord4s; RGLSYMGLMULTITEXCOORD4SVPROC __rglgen_glMultiTexCoord4sv; RGLSYMGLLOADTRANSPOSEMATRIXFPROC __rglgen_glLoadTransposeMatrixf; RGLSYMGLLOADTRANSPOSEMATRIXDPROC __rglgen_glLoadTransposeMatrixd; RGLSYMGLMULTTRANSPOSEMATRIXFPROC __rglgen_glMultTransposeMatrixf; RGLSYMGLMULTTRANSPOSEMATRIXDPROC __rglgen_glMultTransposeMatrixd; RGLSYMGLBLENDFUNCSEPARATEPROC __rglgen_glBlendFuncSeparate; RGLSYMGLMULTIDRAWARRAYSPROC __rglgen_glMultiDrawArrays; RGLSYMGLMULTIDRAWELEMENTSPROC __rglgen_glMultiDrawElements; RGLSYMGLPOINTPARAMETERFPROC __rglgen_glPointParameterf; RGLSYMGLPOINTPARAMETERFVPROC __rglgen_glPointParameterfv; RGLSYMGLPOINTPARAMETERIPROC __rglgen_glPointParameteri; RGLSYMGLPOINTPARAMETERIVPROC __rglgen_glPointParameteriv; RGLSYMGLFOGCOORDFPROC __rglgen_glFogCoordf; RGLSYMGLFOGCOORDFVPROC __rglgen_glFogCoordfv; RGLSYMGLFOGCOORDDPROC __rglgen_glFogCoordd; RGLSYMGLFOGCOORDDVPROC __rglgen_glFogCoorddv; RGLSYMGLFOGCOORDPOINTERPROC __rglgen_glFogCoordPointer; RGLSYMGLSECONDARYCOLOR3BPROC __rglgen_glSecondaryColor3b; RGLSYMGLSECONDARYCOLOR3BVPROC __rglgen_glSecondaryColor3bv; RGLSYMGLSECONDARYCOLOR3DPROC __rglgen_glSecondaryColor3d; RGLSYMGLSECONDARYCOLOR3DVPROC __rglgen_glSecondaryColor3dv; RGLSYMGLSECONDARYCOLOR3FPROC __rglgen_glSecondaryColor3f; RGLSYMGLSECONDARYCOLOR3FVPROC __rglgen_glSecondaryColor3fv; RGLSYMGLSECONDARYCOLOR3IPROC __rglgen_glSecondaryColor3i; RGLSYMGLSECONDARYCOLOR3IVPROC __rglgen_glSecondaryColor3iv; RGLSYMGLSECONDARYCOLOR3SPROC __rglgen_glSecondaryColor3s; RGLSYMGLSECONDARYCOLOR3SVPROC __rglgen_glSecondaryColor3sv; RGLSYMGLSECONDARYCOLOR3UBPROC __rglgen_glSecondaryColor3ub; RGLSYMGLSECONDARYCOLOR3UBVPROC __rglgen_glSecondaryColor3ubv; RGLSYMGLSECONDARYCOLOR3UIPROC __rglgen_glSecondaryColor3ui; RGLSYMGLSECONDARYCOLOR3UIVPROC __rglgen_glSecondaryColor3uiv; RGLSYMGLSECONDARYCOLOR3USPROC __rglgen_glSecondaryColor3us; RGLSYMGLSECONDARYCOLOR3USVPROC __rglgen_glSecondaryColor3usv; RGLSYMGLSECONDARYCOLORPOINTERPROC __rglgen_glSecondaryColorPointer; RGLSYMGLWINDOWPOS2DPROC __rglgen_glWindowPos2d; RGLSYMGLWINDOWPOS2DVPROC __rglgen_glWindowPos2dv; RGLSYMGLWINDOWPOS2FPROC __rglgen_glWindowPos2f; RGLSYMGLWINDOWPOS2FVPROC __rglgen_glWindowPos2fv; RGLSYMGLWINDOWPOS2IPROC __rglgen_glWindowPos2i; RGLSYMGLWINDOWPOS2IVPROC __rglgen_glWindowPos2iv; RGLSYMGLWINDOWPOS2SPROC __rglgen_glWindowPos2s; RGLSYMGLWINDOWPOS2SVPROC __rglgen_glWindowPos2sv; RGLSYMGLWINDOWPOS3DPROC __rglgen_glWindowPos3d; RGLSYMGLWINDOWPOS3DVPROC __rglgen_glWindowPos3dv; RGLSYMGLWINDOWPOS3FPROC __rglgen_glWindowPos3f; RGLSYMGLWINDOWPOS3FVPROC __rglgen_glWindowPos3fv; RGLSYMGLWINDOWPOS3IPROC __rglgen_glWindowPos3i; RGLSYMGLWINDOWPOS3IVPROC __rglgen_glWindowPos3iv; RGLSYMGLWINDOWPOS3SPROC __rglgen_glWindowPos3s; RGLSYMGLWINDOWPOS3SVPROC __rglgen_glWindowPos3sv; RGLSYMGLBLENDCOLORPROC __rglgen_glBlendColor; RGLSYMGLBLENDEQUATIONPROC __rglgen_glBlendEquation; RGLSYMGLGENQUERIESPROC __rglgen_glGenQueries; RGLSYMGLDELETEQUERIESPROC __rglgen_glDeleteQueries; RGLSYMGLISQUERYPROC __rglgen_glIsQuery; RGLSYMGLBEGINQUERYPROC __rglgen_glBeginQuery; RGLSYMGLENDQUERYPROC __rglgen_glEndQuery; RGLSYMGLGETQUERYIVPROC __rglgen_glGetQueryiv; RGLSYMGLGETQUERYOBJECTIVPROC __rglgen_glGetQueryObjectiv; RGLSYMGLGETQUERYOBJECTUIVPROC __rglgen_glGetQueryObjectuiv; RGLSYMGLBINDBUFFERPROC __rglgen_glBindBuffer; RGLSYMGLDELETEBUFFERSPROC __rglgen_glDeleteBuffers; RGLSYMGLGENBUFFERSPROC __rglgen_glGenBuffers; RGLSYMGLISBUFFERPROC __rglgen_glIsBuffer; RGLSYMGLBUFFERDATAPROC __rglgen_glBufferData; RGLSYMGLBUFFERSUBDATAPROC __rglgen_glBufferSubData; RGLSYMGLGETBUFFERSUBDATAPROC __rglgen_glGetBufferSubData; RGLSYMGLMAPBUFFERPROC __rglgen_glMapBuffer; RGLSYMGLUNMAPBUFFERPROC __rglgen_glUnmapBuffer; RGLSYMGLGETBUFFERPARAMETERIVPROC __rglgen_glGetBufferParameteriv; RGLSYMGLGETBUFFERPOINTERVPROC __rglgen_glGetBufferPointerv; RGLSYMGLBLENDEQUATIONSEPARATEPROC __rglgen_glBlendEquationSeparate; RGLSYMGLDRAWBUFFERSPROC __rglgen_glDrawBuffers; RGLSYMGLSTENCILOPSEPARATEPROC __rglgen_glStencilOpSeparate; RGLSYMGLSTENCILFUNCSEPARATEPROC __rglgen_glStencilFuncSeparate; RGLSYMGLSTENCILMASKSEPARATEPROC __rglgen_glStencilMaskSeparate; RGLSYMGLATTACHSHADERPROC __rglgen_glAttachShader; RGLSYMGLBINDATTRIBLOCATIONPROC __rglgen_glBindAttribLocation; RGLSYMGLCOMPILESHADERPROC __rglgen_glCompileShader; RGLSYMGLCREATEPROGRAMPROC __rglgen_glCreateProgram; RGLSYMGLCREATESHADERPROC __rglgen_glCreateShader; RGLSYMGLDELETEPROGRAMPROC __rglgen_glDeleteProgram; RGLSYMGLDELETESHADERPROC __rglgen_glDeleteShader; RGLSYMGLDETACHSHADERPROC __rglgen_glDetachShader; RGLSYMGLDISABLEVERTEXATTRIBARRAYPROC __rglgen_glDisableVertexAttribArray; RGLSYMGLENABLEVERTEXATTRIBARRAYPROC __rglgen_glEnableVertexAttribArray; RGLSYMGLGETACTIVEATTRIBPROC __rglgen_glGetActiveAttrib; RGLSYMGLGETACTIVEUNIFORMPROC __rglgen_glGetActiveUniform; RGLSYMGLGETATTACHEDSHADERSPROC __rglgen_glGetAttachedShaders; RGLSYMGLGETATTRIBLOCATIONPROC __rglgen_glGetAttribLocation; RGLSYMGLGETPROGRAMIVPROC __rglgen_glGetProgramiv; RGLSYMGLGETPROGRAMINFOLOGPROC __rglgen_glGetProgramInfoLog; RGLSYMGLGETSHADERIVPROC __rglgen_glGetShaderiv; RGLSYMGLGETSHADERINFOLOGPROC __rglgen_glGetShaderInfoLog; RGLSYMGLGETSHADERSOURCEPROC __rglgen_glGetShaderSource; RGLSYMGLGETUNIFORMLOCATIONPROC __rglgen_glGetUniformLocation; RGLSYMGLGETUNIFORMFVPROC __rglgen_glGetUniformfv; RGLSYMGLGETUNIFORMIVPROC __rglgen_glGetUniformiv; RGLSYMGLGETVERTEXATTRIBDVPROC __rglgen_glGetVertexAttribdv; RGLSYMGLGETVERTEXATTRIBFVPROC __rglgen_glGetVertexAttribfv; RGLSYMGLGETVERTEXATTRIBIVPROC __rglgen_glGetVertexAttribiv; RGLSYMGLGETVERTEXATTRIBPOINTERVPROC __rglgen_glGetVertexAttribPointerv; RGLSYMGLISPROGRAMPROC __rglgen_glIsProgram; RGLSYMGLISSHADERPROC __rglgen_glIsShader; RGLSYMGLLINKPROGRAMPROC __rglgen_glLinkProgram; RGLSYMGLSHADERSOURCEPROC __rglgen_glShaderSource; RGLSYMGLUSEPROGRAMPROC __rglgen_glUseProgram; RGLSYMGLUNIFORM1FPROC __rglgen_glUniform1f; RGLSYMGLUNIFORM2FPROC __rglgen_glUniform2f; RGLSYMGLUNIFORM3FPROC __rglgen_glUniform3f; RGLSYMGLUNIFORM4FPROC __rglgen_glUniform4f; RGLSYMGLUNIFORM1IPROC __rglgen_glUniform1i; RGLSYMGLUNIFORM2IPROC __rglgen_glUniform2i; RGLSYMGLUNIFORM3IPROC __rglgen_glUniform3i; RGLSYMGLUNIFORM4IPROC __rglgen_glUniform4i; RGLSYMGLUNIFORM1FVPROC __rglgen_glUniform1fv; RGLSYMGLUNIFORM2FVPROC __rglgen_glUniform2fv; RGLSYMGLUNIFORM3FVPROC __rglgen_glUniform3fv; RGLSYMGLUNIFORM4FVPROC __rglgen_glUniform4fv; RGLSYMGLUNIFORM1IVPROC __rglgen_glUniform1iv; RGLSYMGLUNIFORM2IVPROC __rglgen_glUniform2iv; RGLSYMGLUNIFORM3IVPROC __rglgen_glUniform3iv; RGLSYMGLUNIFORM4IVPROC __rglgen_glUniform4iv; RGLSYMGLUNIFORMMATRIX2FVPROC __rglgen_glUniformMatrix2fv; RGLSYMGLUNIFORMMATRIX3FVPROC __rglgen_glUniformMatrix3fv; RGLSYMGLUNIFORMMATRIX4FVPROC __rglgen_glUniformMatrix4fv; RGLSYMGLVALIDATEPROGRAMPROC __rglgen_glValidateProgram; RGLSYMGLVERTEXATTRIB1DPROC __rglgen_glVertexAttrib1d; RGLSYMGLVERTEXATTRIB1DVPROC __rglgen_glVertexAttrib1dv; RGLSYMGLVERTEXATTRIB1FPROC __rglgen_glVertexAttrib1f; RGLSYMGLVERTEXATTRIB1FVPROC __rglgen_glVertexAttrib1fv; RGLSYMGLVERTEXATTRIB1SPROC __rglgen_glVertexAttrib1s; RGLSYMGLVERTEXATTRIB1SVPROC __rglgen_glVertexAttrib1sv; RGLSYMGLVERTEXATTRIB2DPROC __rglgen_glVertexAttrib2d; RGLSYMGLVERTEXATTRIB2DVPROC __rglgen_glVertexAttrib2dv; RGLSYMGLVERTEXATTRIB2FPROC __rglgen_glVertexAttrib2f; RGLSYMGLVERTEXATTRIB2FVPROC __rglgen_glVertexAttrib2fv; RGLSYMGLVERTEXATTRIB2SPROC __rglgen_glVertexAttrib2s; RGLSYMGLVERTEXATTRIB2SVPROC __rglgen_glVertexAttrib2sv; RGLSYMGLVERTEXATTRIB3DPROC __rglgen_glVertexAttrib3d; RGLSYMGLVERTEXATTRIB3DVPROC __rglgen_glVertexAttrib3dv; RGLSYMGLVERTEXATTRIB3FPROC __rglgen_glVertexAttrib3f; RGLSYMGLVERTEXATTRIB3FVPROC __rglgen_glVertexAttrib3fv; RGLSYMGLVERTEXATTRIB3SPROC __rglgen_glVertexAttrib3s; RGLSYMGLVERTEXATTRIB3SVPROC __rglgen_glVertexAttrib3sv; RGLSYMGLVERTEXATTRIB4NBVPROC __rglgen_glVertexAttrib4Nbv; RGLSYMGLVERTEXATTRIB4NIVPROC __rglgen_glVertexAttrib4Niv; RGLSYMGLVERTEXATTRIB4NSVPROC __rglgen_glVertexAttrib4Nsv; RGLSYMGLVERTEXATTRIB4NUBPROC __rglgen_glVertexAttrib4Nub; RGLSYMGLVERTEXATTRIB4NUBVPROC __rglgen_glVertexAttrib4Nubv; RGLSYMGLVERTEXATTRIB4NUIVPROC __rglgen_glVertexAttrib4Nuiv; RGLSYMGLVERTEXATTRIB4NUSVPROC __rglgen_glVertexAttrib4Nusv; RGLSYMGLVERTEXATTRIB4BVPROC __rglgen_glVertexAttrib4bv; RGLSYMGLVERTEXATTRIB4DPROC __rglgen_glVertexAttrib4d; RGLSYMGLVERTEXATTRIB4DVPROC __rglgen_glVertexAttrib4dv; RGLSYMGLVERTEXATTRIB4FPROC __rglgen_glVertexAttrib4f; RGLSYMGLVERTEXATTRIB4FVPROC __rglgen_glVertexAttrib4fv; RGLSYMGLVERTEXATTRIB4IVPROC __rglgen_glVertexAttrib4iv; RGLSYMGLVERTEXATTRIB4SPROC __rglgen_glVertexAttrib4s; RGLSYMGLVERTEXATTRIB4SVPROC __rglgen_glVertexAttrib4sv; RGLSYMGLVERTEXATTRIB4UBVPROC __rglgen_glVertexAttrib4ubv; RGLSYMGLVERTEXATTRIB4UIVPROC __rglgen_glVertexAttrib4uiv; RGLSYMGLVERTEXATTRIB4USVPROC __rglgen_glVertexAttrib4usv; RGLSYMGLVERTEXATTRIBPOINTERPROC __rglgen_glVertexAttribPointer; RGLSYMGLUNIFORMMATRIX2X3FVPROC __rglgen_glUniformMatrix2x3fv; RGLSYMGLUNIFORMMATRIX3X2FVPROC __rglgen_glUniformMatrix3x2fv; RGLSYMGLUNIFORMMATRIX2X4FVPROC __rglgen_glUniformMatrix2x4fv; RGLSYMGLUNIFORMMATRIX4X2FVPROC __rglgen_glUniformMatrix4x2fv; RGLSYMGLUNIFORMMATRIX3X4FVPROC __rglgen_glUniformMatrix3x4fv; RGLSYMGLUNIFORMMATRIX4X3FVPROC __rglgen_glUniformMatrix4x3fv; RGLSYMGLCOLORMASKIPROC __rglgen_glColorMaski; RGLSYMGLGETBOOLEANI_VPROC __rglgen_glGetBooleani_v; RGLSYMGLGETINTEGERI_VPROC __rglgen_glGetIntegeri_v; RGLSYMGLENABLEIPROC __rglgen_glEnablei; RGLSYMGLDISABLEIPROC __rglgen_glDisablei; RGLSYMGLISENABLEDIPROC __rglgen_glIsEnabledi; RGLSYMGLBEGINTRANSFORMFEEDBACKPROC __rglgen_glBeginTransformFeedback; RGLSYMGLENDTRANSFORMFEEDBACKPROC __rglgen_glEndTransformFeedback; RGLSYMGLBINDBUFFERRANGEPROC __rglgen_glBindBufferRange; RGLSYMGLBINDBUFFERBASEPROC __rglgen_glBindBufferBase; RGLSYMGLTRANSFORMFEEDBACKVARYINGSPROC __rglgen_glTransformFeedbackVaryings; RGLSYMGLGETTRANSFORMFEEDBACKVARYINGPROC __rglgen_glGetTransformFeedbackVarying; RGLSYMGLCLAMPCOLORPROC __rglgen_glClampColor; RGLSYMGLBEGINCONDITIONALRENDERPROC __rglgen_glBeginConditionalRender; RGLSYMGLENDCONDITIONALRENDERPROC __rglgen_glEndConditionalRender; RGLSYMGLVERTEXATTRIBIPOINTERPROC __rglgen_glVertexAttribIPointer; RGLSYMGLGETVERTEXATTRIBIIVPROC __rglgen_glGetVertexAttribIiv; RGLSYMGLGETVERTEXATTRIBIUIVPROC __rglgen_glGetVertexAttribIuiv; RGLSYMGLVERTEXATTRIBI1IPROC __rglgen_glVertexAttribI1i; RGLSYMGLVERTEXATTRIBI2IPROC __rglgen_glVertexAttribI2i; RGLSYMGLVERTEXATTRIBI3IPROC __rglgen_glVertexAttribI3i; RGLSYMGLVERTEXATTRIBI4IPROC __rglgen_glVertexAttribI4i; RGLSYMGLVERTEXATTRIBI1UIPROC __rglgen_glVertexAttribI1ui; RGLSYMGLVERTEXATTRIBI2UIPROC __rglgen_glVertexAttribI2ui; RGLSYMGLVERTEXATTRIBI3UIPROC __rglgen_glVertexAttribI3ui; RGLSYMGLVERTEXATTRIBI4UIPROC __rglgen_glVertexAttribI4ui; RGLSYMGLVERTEXATTRIBI1IVPROC __rglgen_glVertexAttribI1iv; RGLSYMGLVERTEXATTRIBI2IVPROC __rglgen_glVertexAttribI2iv; RGLSYMGLVERTEXATTRIBI3IVPROC __rglgen_glVertexAttribI3iv; RGLSYMGLVERTEXATTRIBI4IVPROC __rglgen_glVertexAttribI4iv; RGLSYMGLVERTEXATTRIBI1UIVPROC __rglgen_glVertexAttribI1uiv; RGLSYMGLVERTEXATTRIBI2UIVPROC __rglgen_glVertexAttribI2uiv; RGLSYMGLVERTEXATTRIBI3UIVPROC __rglgen_glVertexAttribI3uiv; RGLSYMGLVERTEXATTRIBI4UIVPROC __rglgen_glVertexAttribI4uiv; RGLSYMGLVERTEXATTRIBI4BVPROC __rglgen_glVertexAttribI4bv; RGLSYMGLVERTEXATTRIBI4SVPROC __rglgen_glVertexAttribI4sv; RGLSYMGLVERTEXATTRIBI4UBVPROC __rglgen_glVertexAttribI4ubv; RGLSYMGLVERTEXATTRIBI4USVPROC __rglgen_glVertexAttribI4usv; RGLSYMGLGETUNIFORMUIVPROC __rglgen_glGetUniformuiv; RGLSYMGLBINDFRAGDATALOCATIONPROC __rglgen_glBindFragDataLocation; RGLSYMGLGETFRAGDATALOCATIONPROC __rglgen_glGetFragDataLocation; RGLSYMGLUNIFORM1UIPROC __rglgen_glUniform1ui; RGLSYMGLUNIFORM2UIPROC __rglgen_glUniform2ui; RGLSYMGLUNIFORM3UIPROC __rglgen_glUniform3ui; RGLSYMGLUNIFORM4UIPROC __rglgen_glUniform4ui; RGLSYMGLUNIFORM1UIVPROC __rglgen_glUniform1uiv; RGLSYMGLUNIFORM2UIVPROC __rglgen_glUniform2uiv; RGLSYMGLUNIFORM3UIVPROC __rglgen_glUniform3uiv; RGLSYMGLUNIFORM4UIVPROC __rglgen_glUniform4uiv; RGLSYMGLTEXPARAMETERIIVPROC __rglgen_glTexParameterIiv; RGLSYMGLTEXPARAMETERIUIVPROC __rglgen_glTexParameterIuiv; RGLSYMGLGETTEXPARAMETERIIVPROC __rglgen_glGetTexParameterIiv; RGLSYMGLGETTEXPARAMETERIUIVPROC __rglgen_glGetTexParameterIuiv; RGLSYMGLCLEARBUFFERIVPROC __rglgen_glClearBufferiv; RGLSYMGLCLEARBUFFERUIVPROC __rglgen_glClearBufferuiv; RGLSYMGLCLEARBUFFERFVPROC __rglgen_glClearBufferfv; RGLSYMGLCLEARBUFFERFIPROC __rglgen_glClearBufferfi; RGLSYMGLGETSTRINGIPROC __rglgen_glGetStringi; RGLSYMGLISRENDERBUFFERPROC __rglgen_glIsRenderbuffer; RGLSYMGLBINDRENDERBUFFERPROC __rglgen_glBindRenderbuffer; RGLSYMGLDELETERENDERBUFFERSPROC __rglgen_glDeleteRenderbuffers; RGLSYMGLGENRENDERBUFFERSPROC __rglgen_glGenRenderbuffers; RGLSYMGLRENDERBUFFERSTORAGEPROC __rglgen_glRenderbufferStorage; RGLSYMGLGETRENDERBUFFERPARAMETERIVPROC __rglgen_glGetRenderbufferParameteriv; RGLSYMGLISFRAMEBUFFERPROC __rglgen_glIsFramebuffer; RGLSYMGLBINDFRAMEBUFFERPROC __rglgen_glBindFramebuffer; RGLSYMGLDELETEFRAMEBUFFERSPROC __rglgen_glDeleteFramebuffers; RGLSYMGLGENFRAMEBUFFERSPROC __rglgen_glGenFramebuffers; RGLSYMGLCHECKFRAMEBUFFERSTATUSPROC __rglgen_glCheckFramebufferStatus; RGLSYMGLFRAMEBUFFERTEXTURE1DPROC __rglgen_glFramebufferTexture1D; RGLSYMGLFRAMEBUFFERTEXTURE2DPROC __rglgen_glFramebufferTexture2D; RGLSYMGLFRAMEBUFFERTEXTURE3DPROC __rglgen_glFramebufferTexture3D; RGLSYMGLFRAMEBUFFERRENDERBUFFERPROC __rglgen_glFramebufferRenderbuffer; RGLSYMGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC __rglgen_glGetFramebufferAttachmentParameteriv; RGLSYMGLGENERATEMIPMAPPROC __rglgen_glGenerateMipmap; RGLSYMGLBLITFRAMEBUFFERPROC __rglgen_glBlitFramebuffer; RGLSYMGLRENDERBUFFERSTORAGEMULTISAMPLEPROC __rglgen_glRenderbufferStorageMultisample; RGLSYMGLFRAMEBUFFERTEXTURELAYERPROC __rglgen_glFramebufferTextureLayer; RGLSYMGLMAPBUFFERRANGEPROC __rglgen_glMapBufferRange; RGLSYMGLFLUSHMAPPEDBUFFERRANGEPROC __rglgen_glFlushMappedBufferRange; RGLSYMGLBINDVERTEXARRAYPROC __rglgen_glBindVertexArray; RGLSYMGLDELETEVERTEXARRAYSPROC __rglgen_glDeleteVertexArrays; RGLSYMGLGENVERTEXARRAYSPROC __rglgen_glGenVertexArrays; RGLSYMGLISVERTEXARRAYPROC __rglgen_glIsVertexArray; RGLSYMGLDRAWARRAYSINSTANCEDPROC __rglgen_glDrawArraysInstanced; RGLSYMGLDRAWELEMENTSINSTANCEDPROC __rglgen_glDrawElementsInstanced; RGLSYMGLTEXBUFFERPROC __rglgen_glTexBuffer; RGLSYMGLPRIMITIVERESTARTINDEXPROC __rglgen_glPrimitiveRestartIndex; RGLSYMGLCOPYBUFFERSUBDATAPROC __rglgen_glCopyBufferSubData; RGLSYMGLGETUNIFORMINDICESPROC __rglgen_glGetUniformIndices; RGLSYMGLGETACTIVEUNIFORMSIVPROC __rglgen_glGetActiveUniformsiv; RGLSYMGLGETACTIVEUNIFORMNAMEPROC __rglgen_glGetActiveUniformName; RGLSYMGLGETUNIFORMBLOCKINDEXPROC __rglgen_glGetUniformBlockIndex; RGLSYMGLGETACTIVEUNIFORMBLOCKIVPROC __rglgen_glGetActiveUniformBlockiv; RGLSYMGLGETACTIVEUNIFORMBLOCKNAMEPROC __rglgen_glGetActiveUniformBlockName; RGLSYMGLUNIFORMBLOCKBINDINGPROC __rglgen_glUniformBlockBinding; RGLSYMGLDRAWELEMENTSBASEVERTEXPROC __rglgen_glDrawElementsBaseVertex; RGLSYMGLDRAWRANGEELEMENTSBASEVERTEXPROC __rglgen_glDrawRangeElementsBaseVertex; RGLSYMGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC __rglgen_glDrawElementsInstancedBaseVertex; RGLSYMGLMULTIDRAWELEMENTSBASEVERTEXPROC __rglgen_glMultiDrawElementsBaseVertex; RGLSYMGLPROVOKINGVERTEXPROC __rglgen_glProvokingVertex; RGLSYMGLFENCESYNCPROC __rglgen_glFenceSync; RGLSYMGLISSYNCPROC __rglgen_glIsSync; RGLSYMGLDELETESYNCPROC __rglgen_glDeleteSync; RGLSYMGLCLIENTWAITSYNCPROC __rglgen_glClientWaitSync; RGLSYMGLWAITSYNCPROC __rglgen_glWaitSync; RGLSYMGLGETINTEGER64VPROC __rglgen_glGetInteger64v; RGLSYMGLGETSYNCIVPROC __rglgen_glGetSynciv; RGLSYMGLGETINTEGER64I_VPROC __rglgen_glGetInteger64i_v; RGLSYMGLGETBUFFERPARAMETERI64VPROC __rglgen_glGetBufferParameteri64v; RGLSYMGLFRAMEBUFFERTEXTUREPROC __rglgen_glFramebufferTexture; RGLSYMGLTEXIMAGE2DMULTISAMPLEPROC __rglgen_glTexImage2DMultisample; RGLSYMGLTEXIMAGE3DMULTISAMPLEPROC __rglgen_glTexImage3DMultisample; RGLSYMGLGETMULTISAMPLEFVPROC __rglgen_glGetMultisamplefv; RGLSYMGLSAMPLEMASKIPROC __rglgen_glSampleMaski; RGLSYMGLBINDFRAGDATALOCATIONINDEXEDPROC __rglgen_glBindFragDataLocationIndexed; RGLSYMGLGETFRAGDATAINDEXPROC __rglgen_glGetFragDataIndex; RGLSYMGLGENSAMPLERSPROC __rglgen_glGenSamplers; RGLSYMGLDELETESAMPLERSPROC __rglgen_glDeleteSamplers; RGLSYMGLISSAMPLERPROC __rglgen_glIsSampler; RGLSYMGLBINDSAMPLERPROC __rglgen_glBindSampler; RGLSYMGLSAMPLERPARAMETERIPROC __rglgen_glSamplerParameteri; RGLSYMGLSAMPLERPARAMETERIVPROC __rglgen_glSamplerParameteriv; RGLSYMGLSAMPLERPARAMETERFPROC __rglgen_glSamplerParameterf; RGLSYMGLSAMPLERPARAMETERFVPROC __rglgen_glSamplerParameterfv; RGLSYMGLSAMPLERPARAMETERIIVPROC __rglgen_glSamplerParameterIiv; RGLSYMGLSAMPLERPARAMETERIUIVPROC __rglgen_glSamplerParameterIuiv; RGLSYMGLGETSAMPLERPARAMETERIVPROC __rglgen_glGetSamplerParameteriv; RGLSYMGLGETSAMPLERPARAMETERIIVPROC __rglgen_glGetSamplerParameterIiv; RGLSYMGLGETSAMPLERPARAMETERFVPROC __rglgen_glGetSamplerParameterfv; RGLSYMGLGETSAMPLERPARAMETERIUIVPROC __rglgen_glGetSamplerParameterIuiv; RGLSYMGLQUERYCOUNTERPROC __rglgen_glQueryCounter; RGLSYMGLGETQUERYOBJECTI64VPROC __rglgen_glGetQueryObjecti64v; RGLSYMGLGETQUERYOBJECTUI64VPROC __rglgen_glGetQueryObjectui64v; RGLSYMGLVERTEXATTRIBDIVISORPROC __rglgen_glVertexAttribDivisor; RGLSYMGLVERTEXATTRIBP1UIPROC __rglgen_glVertexAttribP1ui; RGLSYMGLVERTEXATTRIBP1UIVPROC __rglgen_glVertexAttribP1uiv; RGLSYMGLVERTEXATTRIBP2UIPROC __rglgen_glVertexAttribP2ui; RGLSYMGLVERTEXATTRIBP2UIVPROC __rglgen_glVertexAttribP2uiv; RGLSYMGLVERTEXATTRIBP3UIPROC __rglgen_glVertexAttribP3ui; RGLSYMGLVERTEXATTRIBP3UIVPROC __rglgen_glVertexAttribP3uiv; RGLSYMGLVERTEXATTRIBP4UIPROC __rglgen_glVertexAttribP4ui; RGLSYMGLVERTEXATTRIBP4UIVPROC __rglgen_glVertexAttribP4uiv; RGLSYMGLVERTEXP2UIPROC __rglgen_glVertexP2ui; RGLSYMGLVERTEXP2UIVPROC __rglgen_glVertexP2uiv; RGLSYMGLVERTEXP3UIPROC __rglgen_glVertexP3ui; RGLSYMGLVERTEXP3UIVPROC __rglgen_glVertexP3uiv; RGLSYMGLVERTEXP4UIPROC __rglgen_glVertexP4ui; RGLSYMGLVERTEXP4UIVPROC __rglgen_glVertexP4uiv; RGLSYMGLTEXCOORDP1UIPROC __rglgen_glTexCoordP1ui; RGLSYMGLTEXCOORDP1UIVPROC __rglgen_glTexCoordP1uiv; RGLSYMGLTEXCOORDP2UIPROC __rglgen_glTexCoordP2ui; RGLSYMGLTEXCOORDP2UIVPROC __rglgen_glTexCoordP2uiv; RGLSYMGLTEXCOORDP3UIPROC __rglgen_glTexCoordP3ui; RGLSYMGLTEXCOORDP3UIVPROC __rglgen_glTexCoordP3uiv; RGLSYMGLTEXCOORDP4UIPROC __rglgen_glTexCoordP4ui; RGLSYMGLTEXCOORDP4UIVPROC __rglgen_glTexCoordP4uiv; RGLSYMGLMULTITEXCOORDP1UIPROC __rglgen_glMultiTexCoordP1ui; RGLSYMGLMULTITEXCOORDP1UIVPROC __rglgen_glMultiTexCoordP1uiv; RGLSYMGLMULTITEXCOORDP2UIPROC __rglgen_glMultiTexCoordP2ui; RGLSYMGLMULTITEXCOORDP2UIVPROC __rglgen_glMultiTexCoordP2uiv; RGLSYMGLMULTITEXCOORDP3UIPROC __rglgen_glMultiTexCoordP3ui; RGLSYMGLMULTITEXCOORDP3UIVPROC __rglgen_glMultiTexCoordP3uiv; RGLSYMGLMULTITEXCOORDP4UIPROC __rglgen_glMultiTexCoordP4ui; RGLSYMGLMULTITEXCOORDP4UIVPROC __rglgen_glMultiTexCoordP4uiv; RGLSYMGLNORMALP3UIPROC __rglgen_glNormalP3ui; RGLSYMGLNORMALP3UIVPROC __rglgen_glNormalP3uiv; RGLSYMGLCOLORP3UIPROC __rglgen_glColorP3ui; RGLSYMGLCOLORP3UIVPROC __rglgen_glColorP3uiv; RGLSYMGLCOLORP4UIPROC __rglgen_glColorP4ui; RGLSYMGLCOLORP4UIVPROC __rglgen_glColorP4uiv; RGLSYMGLSECONDARYCOLORP3UIPROC __rglgen_glSecondaryColorP3ui; RGLSYMGLSECONDARYCOLORP3UIVPROC __rglgen_glSecondaryColorP3uiv; RGLSYMGLMINSAMPLESHADINGPROC __rglgen_glMinSampleShading; RGLSYMGLBLENDEQUATIONIPROC __rglgen_glBlendEquationi; RGLSYMGLBLENDEQUATIONSEPARATEIPROC __rglgen_glBlendEquationSeparatei; RGLSYMGLBLENDFUNCIPROC __rglgen_glBlendFunci; RGLSYMGLBLENDFUNCSEPARATEIPROC __rglgen_glBlendFuncSeparatei; RGLSYMGLDRAWARRAYSINDIRECTPROC __rglgen_glDrawArraysIndirect; RGLSYMGLDRAWELEMENTSINDIRECTPROC __rglgen_glDrawElementsIndirect; RGLSYMGLUNIFORM1DPROC __rglgen_glUniform1d; RGLSYMGLUNIFORM2DPROC __rglgen_glUniform2d; RGLSYMGLUNIFORM3DPROC __rglgen_glUniform3d; RGLSYMGLUNIFORM4DPROC __rglgen_glUniform4d; RGLSYMGLUNIFORM1DVPROC __rglgen_glUniform1dv; RGLSYMGLUNIFORM2DVPROC __rglgen_glUniform2dv; RGLSYMGLUNIFORM3DVPROC __rglgen_glUniform3dv; RGLSYMGLUNIFORM4DVPROC __rglgen_glUniform4dv; RGLSYMGLUNIFORMMATRIX2DVPROC __rglgen_glUniformMatrix2dv; RGLSYMGLUNIFORMMATRIX3DVPROC __rglgen_glUniformMatrix3dv; RGLSYMGLUNIFORMMATRIX4DVPROC __rglgen_glUniformMatrix4dv; RGLSYMGLUNIFORMMATRIX2X3DVPROC __rglgen_glUniformMatrix2x3dv; RGLSYMGLUNIFORMMATRIX2X4DVPROC __rglgen_glUniformMatrix2x4dv; RGLSYMGLUNIFORMMATRIX3X2DVPROC __rglgen_glUniformMatrix3x2dv; RGLSYMGLUNIFORMMATRIX3X4DVPROC __rglgen_glUniformMatrix3x4dv; RGLSYMGLUNIFORMMATRIX4X2DVPROC __rglgen_glUniformMatrix4x2dv; RGLSYMGLUNIFORMMATRIX4X3DVPROC __rglgen_glUniformMatrix4x3dv; RGLSYMGLGETUNIFORMDVPROC __rglgen_glGetUniformdv; RGLSYMGLGETSUBROUTINEUNIFORMLOCATIONPROC __rglgen_glGetSubroutineUniformLocation; RGLSYMGLGETSUBROUTINEINDEXPROC __rglgen_glGetSubroutineIndex; RGLSYMGLGETACTIVESUBROUTINEUNIFORMIVPROC __rglgen_glGetActiveSubroutineUniformiv; RGLSYMGLGETACTIVESUBROUTINEUNIFORMNAMEPROC __rglgen_glGetActiveSubroutineUniformName; RGLSYMGLGETACTIVESUBROUTINENAMEPROC __rglgen_glGetActiveSubroutineName; RGLSYMGLUNIFORMSUBROUTINESUIVPROC __rglgen_glUniformSubroutinesuiv; RGLSYMGLGETUNIFORMSUBROUTINEUIVPROC __rglgen_glGetUniformSubroutineuiv; RGLSYMGLGETPROGRAMSTAGEIVPROC __rglgen_glGetProgramStageiv; RGLSYMGLPATCHPARAMETERIPROC __rglgen_glPatchParameteri; RGLSYMGLPATCHPARAMETERFVPROC __rglgen_glPatchParameterfv; RGLSYMGLBINDTRANSFORMFEEDBACKPROC __rglgen_glBindTransformFeedback; RGLSYMGLDELETETRANSFORMFEEDBACKSPROC __rglgen_glDeleteTransformFeedbacks; RGLSYMGLGENTRANSFORMFEEDBACKSPROC __rglgen_glGenTransformFeedbacks; RGLSYMGLISTRANSFORMFEEDBACKPROC __rglgen_glIsTransformFeedback; RGLSYMGLPAUSETRANSFORMFEEDBACKPROC __rglgen_glPauseTransformFeedback; RGLSYMGLRESUMETRANSFORMFEEDBACKPROC __rglgen_glResumeTransformFeedback; RGLSYMGLDRAWTRANSFORMFEEDBACKPROC __rglgen_glDrawTransformFeedback; RGLSYMGLDRAWTRANSFORMFEEDBACKSTREAMPROC __rglgen_glDrawTransformFeedbackStream; RGLSYMGLBEGINQUERYINDEXEDPROC __rglgen_glBeginQueryIndexed; RGLSYMGLENDQUERYINDEXEDPROC __rglgen_glEndQueryIndexed; RGLSYMGLGETQUERYINDEXEDIVPROC __rglgen_glGetQueryIndexediv; RGLSYMGLRELEASESHADERCOMPILERPROC __rglgen_glReleaseShaderCompiler; RGLSYMGLSHADERBINARYPROC __rglgen_glShaderBinary; RGLSYMGLGETSHADERPRECISIONFORMATPROC __rglgen_glGetShaderPrecisionFormat; RGLSYMGLDEPTHRANGEFPROC __rglgen_glDepthRangef; RGLSYMGLCLEARDEPTHFPROC __rglgen_glClearDepthf; RGLSYMGLGETPROGRAMBINARYPROC __rglgen_glGetProgramBinary; RGLSYMGLPROGRAMBINARYPROC __rglgen_glProgramBinary; RGLSYMGLPROGRAMPARAMETERIPROC __rglgen_glProgramParameteri; RGLSYMGLUSEPROGRAMSTAGESPROC __rglgen_glUseProgramStages; RGLSYMGLACTIVESHADERPROGRAMPROC __rglgen_glActiveShaderProgram; RGLSYMGLCREATESHADERPROGRAMVPROC __rglgen_glCreateShaderProgramv; RGLSYMGLBINDPROGRAMPIPELINEPROC __rglgen_glBindProgramPipeline; RGLSYMGLDELETEPROGRAMPIPELINESPROC __rglgen_glDeleteProgramPipelines; RGLSYMGLGENPROGRAMPIPELINESPROC __rglgen_glGenProgramPipelines; RGLSYMGLISPROGRAMPIPELINEPROC __rglgen_glIsProgramPipeline; RGLSYMGLGETPROGRAMPIPELINEIVPROC __rglgen_glGetProgramPipelineiv; RGLSYMGLPROGRAMUNIFORM1IPROC __rglgen_glProgramUniform1i; RGLSYMGLPROGRAMUNIFORM1IVPROC __rglgen_glProgramUniform1iv; RGLSYMGLPROGRAMUNIFORM1FPROC __rglgen_glProgramUniform1f; RGLSYMGLPROGRAMUNIFORM1FVPROC __rglgen_glProgramUniform1fv; RGLSYMGLPROGRAMUNIFORM1DPROC __rglgen_glProgramUniform1d; RGLSYMGLPROGRAMUNIFORM1DVPROC __rglgen_glProgramUniform1dv; RGLSYMGLPROGRAMUNIFORM1UIPROC __rglgen_glProgramUniform1ui; RGLSYMGLPROGRAMUNIFORM1UIVPROC __rglgen_glProgramUniform1uiv; RGLSYMGLPROGRAMUNIFORM2IPROC __rglgen_glProgramUniform2i; RGLSYMGLPROGRAMUNIFORM2IVPROC __rglgen_glProgramUniform2iv; RGLSYMGLPROGRAMUNIFORM2FPROC __rglgen_glProgramUniform2f; RGLSYMGLPROGRAMUNIFORM2FVPROC __rglgen_glProgramUniform2fv; RGLSYMGLPROGRAMUNIFORM2DPROC __rglgen_glProgramUniform2d; RGLSYMGLPROGRAMUNIFORM2DVPROC __rglgen_glProgramUniform2dv; RGLSYMGLPROGRAMUNIFORM2UIPROC __rglgen_glProgramUniform2ui; RGLSYMGLPROGRAMUNIFORM2UIVPROC __rglgen_glProgramUniform2uiv; RGLSYMGLPROGRAMUNIFORM3IPROC __rglgen_glProgramUniform3i; RGLSYMGLPROGRAMUNIFORM3IVPROC __rglgen_glProgramUniform3iv; RGLSYMGLPROGRAMUNIFORM3FPROC __rglgen_glProgramUniform3f; RGLSYMGLPROGRAMUNIFORM3FVPROC __rglgen_glProgramUniform3fv; RGLSYMGLPROGRAMUNIFORM3DPROC __rglgen_glProgramUniform3d; RGLSYMGLPROGRAMUNIFORM3DVPROC __rglgen_glProgramUniform3dv; RGLSYMGLPROGRAMUNIFORM3UIPROC __rglgen_glProgramUniform3ui; RGLSYMGLPROGRAMUNIFORM3UIVPROC __rglgen_glProgramUniform3uiv; RGLSYMGLPROGRAMUNIFORM4IPROC __rglgen_glProgramUniform4i; RGLSYMGLPROGRAMUNIFORM4IVPROC __rglgen_glProgramUniform4iv; RGLSYMGLPROGRAMUNIFORM4FPROC __rglgen_glProgramUniform4f; RGLSYMGLPROGRAMUNIFORM4FVPROC __rglgen_glProgramUniform4fv; RGLSYMGLPROGRAMUNIFORM4DPROC __rglgen_glProgramUniform4d; RGLSYMGLPROGRAMUNIFORM4DVPROC __rglgen_glProgramUniform4dv; RGLSYMGLPROGRAMUNIFORM4UIPROC __rglgen_glProgramUniform4ui; RGLSYMGLPROGRAMUNIFORM4UIVPROC __rglgen_glProgramUniform4uiv; RGLSYMGLPROGRAMUNIFORMMATRIX2FVPROC __rglgen_glProgramUniformMatrix2fv; RGLSYMGLPROGRAMUNIFORMMATRIX3FVPROC __rglgen_glProgramUniformMatrix3fv; RGLSYMGLPROGRAMUNIFORMMATRIX4FVPROC __rglgen_glProgramUniformMatrix4fv; RGLSYMGLPROGRAMUNIFORMMATRIX2DVPROC __rglgen_glProgramUniformMatrix2dv; RGLSYMGLPROGRAMUNIFORMMATRIX3DVPROC __rglgen_glProgramUniformMatrix3dv; RGLSYMGLPROGRAMUNIFORMMATRIX4DVPROC __rglgen_glProgramUniformMatrix4dv; RGLSYMGLPROGRAMUNIFORMMATRIX2X3FVPROC __rglgen_glProgramUniformMatrix2x3fv; RGLSYMGLPROGRAMUNIFORMMATRIX3X2FVPROC __rglgen_glProgramUniformMatrix3x2fv; RGLSYMGLPROGRAMUNIFORMMATRIX2X4FVPROC __rglgen_glProgramUniformMatrix2x4fv; RGLSYMGLPROGRAMUNIFORMMATRIX4X2FVPROC __rglgen_glProgramUniformMatrix4x2fv; RGLSYMGLPROGRAMUNIFORMMATRIX3X4FVPROC __rglgen_glProgramUniformMatrix3x4fv; RGLSYMGLPROGRAMUNIFORMMATRIX4X3FVPROC __rglgen_glProgramUniformMatrix4x3fv; RGLSYMGLPROGRAMUNIFORMMATRIX2X3DVPROC __rglgen_glProgramUniformMatrix2x3dv; RGLSYMGLPROGRAMUNIFORMMATRIX3X2DVPROC __rglgen_glProgramUniformMatrix3x2dv; RGLSYMGLPROGRAMUNIFORMMATRIX2X4DVPROC __rglgen_glProgramUniformMatrix2x4dv; RGLSYMGLPROGRAMUNIFORMMATRIX4X2DVPROC __rglgen_glProgramUniformMatrix4x2dv; RGLSYMGLPROGRAMUNIFORMMATRIX3X4DVPROC __rglgen_glProgramUniformMatrix3x4dv; RGLSYMGLPROGRAMUNIFORMMATRIX4X3DVPROC __rglgen_glProgramUniformMatrix4x3dv; RGLSYMGLVALIDATEPROGRAMPIPELINEPROC __rglgen_glValidateProgramPipeline; RGLSYMGLGETPROGRAMPIPELINEINFOLOGPROC __rglgen_glGetProgramPipelineInfoLog; RGLSYMGLVERTEXATTRIBL1DPROC __rglgen_glVertexAttribL1d; RGLSYMGLVERTEXATTRIBL2DPROC __rglgen_glVertexAttribL2d; RGLSYMGLVERTEXATTRIBL3DPROC __rglgen_glVertexAttribL3d; RGLSYMGLVERTEXATTRIBL4DPROC __rglgen_glVertexAttribL4d; RGLSYMGLVERTEXATTRIBL1DVPROC __rglgen_glVertexAttribL1dv; RGLSYMGLVERTEXATTRIBL2DVPROC __rglgen_glVertexAttribL2dv; RGLSYMGLVERTEXATTRIBL3DVPROC __rglgen_glVertexAttribL3dv; RGLSYMGLVERTEXATTRIBL4DVPROC __rglgen_glVertexAttribL4dv; RGLSYMGLVERTEXATTRIBLPOINTERPROC __rglgen_glVertexAttribLPointer; RGLSYMGLGETVERTEXATTRIBLDVPROC __rglgen_glGetVertexAttribLdv; RGLSYMGLVIEWPORTARRAYVPROC __rglgen_glViewportArrayv; RGLSYMGLVIEWPORTINDEXEDFPROC __rglgen_glViewportIndexedf; RGLSYMGLVIEWPORTINDEXEDFVPROC __rglgen_glViewportIndexedfv; RGLSYMGLSCISSORARRAYVPROC __rglgen_glScissorArrayv; RGLSYMGLSCISSORINDEXEDPROC __rglgen_glScissorIndexed; RGLSYMGLSCISSORINDEXEDVPROC __rglgen_glScissorIndexedv; RGLSYMGLDEPTHRANGEARRAYVPROC __rglgen_glDepthRangeArrayv; RGLSYMGLDEPTHRANGEINDEXEDPROC __rglgen_glDepthRangeIndexed; RGLSYMGLGETFLOATI_VPROC __rglgen_glGetFloati_v; RGLSYMGLGETDOUBLEI_VPROC __rglgen_glGetDoublei_v; RGLSYMGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC __rglgen_glDrawArraysInstancedBaseInstance; RGLSYMGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC __rglgen_glDrawElementsInstancedBaseInstance; RGLSYMGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC __rglgen_glDrawElementsInstancedBaseVertexBaseInstance; RGLSYMGLGETINTERNALFORMATIVPROC __rglgen_glGetInternalformativ; RGLSYMGLGETACTIVEATOMICCOUNTERBUFFERIVPROC __rglgen_glGetActiveAtomicCounterBufferiv; RGLSYMGLBINDIMAGETEXTUREPROC __rglgen_glBindImageTexture; RGLSYMGLMEMORYBARRIERPROC __rglgen_glMemoryBarrier; RGLSYMGLTEXSTORAGE1DPROC __rglgen_glTexStorage1D; RGLSYMGLTEXSTORAGE2DPROC __rglgen_glTexStorage2D; RGLSYMGLTEXSTORAGE3DPROC __rglgen_glTexStorage3D; RGLSYMGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC __rglgen_glDrawTransformFeedbackInstanced; RGLSYMGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC __rglgen_glDrawTransformFeedbackStreamInstanced; RGLSYMGLCLEARBUFFERDATAPROC __rglgen_glClearBufferData; RGLSYMGLCLEARBUFFERSUBDATAPROC __rglgen_glClearBufferSubData; RGLSYMGLDISPATCHCOMPUTEPROC __rglgen_glDispatchCompute; RGLSYMGLDISPATCHCOMPUTEINDIRECTPROC __rglgen_glDispatchComputeIndirect; RGLSYMGLCOPYIMAGESUBDATAPROC __rglgen_glCopyImageSubData; RGLSYMGLFRAMEBUFFERPARAMETERIPROC __rglgen_glFramebufferParameteri; RGLSYMGLGETFRAMEBUFFERPARAMETERIVPROC __rglgen_glGetFramebufferParameteriv; RGLSYMGLGETINTERNALFORMATI64VPROC __rglgen_glGetInternalformati64v; RGLSYMGLINVALIDATETEXSUBIMAGEPROC __rglgen_glInvalidateTexSubImage; RGLSYMGLINVALIDATETEXIMAGEPROC __rglgen_glInvalidateTexImage; RGLSYMGLINVALIDATEBUFFERSUBDATAPROC __rglgen_glInvalidateBufferSubData; RGLSYMGLINVALIDATEBUFFERDATAPROC __rglgen_glInvalidateBufferData; RGLSYMGLINVALIDATEFRAMEBUFFERPROC __rglgen_glInvalidateFramebuffer; RGLSYMGLINVALIDATESUBFRAMEBUFFERPROC __rglgen_glInvalidateSubFramebuffer; RGLSYMGLMULTIDRAWARRAYSINDIRECTPROC __rglgen_glMultiDrawArraysIndirect; RGLSYMGLMULTIDRAWELEMENTSINDIRECTPROC __rglgen_glMultiDrawElementsIndirect; RGLSYMGLGETPROGRAMINTERFACEIVPROC __rglgen_glGetProgramInterfaceiv; RGLSYMGLGETPROGRAMRESOURCEINDEXPROC __rglgen_glGetProgramResourceIndex; RGLSYMGLGETPROGRAMRESOURCENAMEPROC __rglgen_glGetProgramResourceName; RGLSYMGLGETPROGRAMRESOURCEIVPROC __rglgen_glGetProgramResourceiv; RGLSYMGLGETPROGRAMRESOURCELOCATIONPROC __rglgen_glGetProgramResourceLocation; RGLSYMGLGETPROGRAMRESOURCELOCATIONINDEXPROC __rglgen_glGetProgramResourceLocationIndex; RGLSYMGLSHADERSTORAGEBLOCKBINDINGPROC __rglgen_glShaderStorageBlockBinding; RGLSYMGLTEXBUFFERRANGEPROC __rglgen_glTexBufferRange; RGLSYMGLTEXSTORAGE2DMULTISAMPLEPROC __rglgen_glTexStorage2DMultisample; RGLSYMGLTEXSTORAGE3DMULTISAMPLEPROC __rglgen_glTexStorage3DMultisample; RGLSYMGLTEXTUREVIEWPROC __rglgen_glTextureView; RGLSYMGLBINDVERTEXBUFFERPROC __rglgen_glBindVertexBuffer; RGLSYMGLVERTEXATTRIBFORMATPROC __rglgen_glVertexAttribFormat; RGLSYMGLVERTEXATTRIBIFORMATPROC __rglgen_glVertexAttribIFormat; RGLSYMGLVERTEXATTRIBLFORMATPROC __rglgen_glVertexAttribLFormat; RGLSYMGLVERTEXATTRIBBINDINGPROC __rglgen_glVertexAttribBinding; RGLSYMGLVERTEXBINDINGDIVISORPROC __rglgen_glVertexBindingDivisor; RGLSYMGLDEBUGMESSAGECONTROLPROC __rglgen_glDebugMessageControl; RGLSYMGLDEBUGMESSAGEINSERTPROC __rglgen_glDebugMessageInsert; RGLSYMGLDEBUGMESSAGECALLBACKPROC __rglgen_glDebugMessageCallback; RGLSYMGLGETDEBUGMESSAGELOGPROC __rglgen_glGetDebugMessageLog; RGLSYMGLPUSHDEBUGGROUPPROC __rglgen_glPushDebugGroup; RGLSYMGLPOPDEBUGGROUPPROC __rglgen_glPopDebugGroup; RGLSYMGLOBJECTLABELPROC __rglgen_glObjectLabel; RGLSYMGLGETOBJECTLABELPROC __rglgen_glGetObjectLabel; RGLSYMGLOBJECTPTRLABELPROC __rglgen_glObjectPtrLabel; RGLSYMGLGETOBJECTPTRLABELPROC __rglgen_glGetObjectPtrLabel; RGLSYMGLBUFFERSTORAGEPROC __rglgen_glBufferStorage; RGLSYMGLCLEARTEXIMAGEPROC __rglgen_glClearTexImage; RGLSYMGLCLEARTEXSUBIMAGEPROC __rglgen_glClearTexSubImage; RGLSYMGLBINDBUFFERSBASEPROC __rglgen_glBindBuffersBase; RGLSYMGLBINDBUFFERSRANGEPROC __rglgen_glBindBuffersRange; RGLSYMGLBINDTEXTURESPROC __rglgen_glBindTextures; RGLSYMGLBINDSAMPLERSPROC __rglgen_glBindSamplers; RGLSYMGLBINDIMAGETEXTURESPROC __rglgen_glBindImageTextures; RGLSYMGLBINDVERTEXBUFFERSPROC __rglgen_glBindVertexBuffers; RGLSYMGLGETTEXTUREHANDLEARBPROC __rglgen_glGetTextureHandleARB; RGLSYMGLGETTEXTURESAMPLERHANDLEARBPROC __rglgen_glGetTextureSamplerHandleARB; RGLSYMGLMAKETEXTUREHANDLERESIDENTARBPROC __rglgen_glMakeTextureHandleResidentARB; RGLSYMGLMAKETEXTUREHANDLENONRESIDENTARBPROC __rglgen_glMakeTextureHandleNonResidentARB; RGLSYMGLGETIMAGEHANDLEARBPROC __rglgen_glGetImageHandleARB; RGLSYMGLMAKEIMAGEHANDLERESIDENTARBPROC __rglgen_glMakeImageHandleResidentARB; RGLSYMGLMAKEIMAGEHANDLENONRESIDENTARBPROC __rglgen_glMakeImageHandleNonResidentARB; RGLSYMGLUNIFORMHANDLEUI64ARBPROC __rglgen_glUniformHandleui64ARB; RGLSYMGLUNIFORMHANDLEUI64VARBPROC __rglgen_glUniformHandleui64vARB; RGLSYMGLPROGRAMUNIFORMHANDLEUI64ARBPROC __rglgen_glProgramUniformHandleui64ARB; RGLSYMGLPROGRAMUNIFORMHANDLEUI64VARBPROC __rglgen_glProgramUniformHandleui64vARB; RGLSYMGLISTEXTUREHANDLERESIDENTARBPROC __rglgen_glIsTextureHandleResidentARB; RGLSYMGLISIMAGEHANDLERESIDENTARBPROC __rglgen_glIsImageHandleResidentARB; RGLSYMGLVERTEXATTRIBL1UI64ARBPROC __rglgen_glVertexAttribL1ui64ARB; RGLSYMGLVERTEXATTRIBL1UI64VARBPROC __rglgen_glVertexAttribL1ui64vARB; RGLSYMGLGETVERTEXATTRIBLUI64VARBPROC __rglgen_glGetVertexAttribLui64vARB; RGLSYMGLCREATESYNCFROMCLEVENTARBPROC __rglgen_glCreateSyncFromCLeventARB; RGLSYMGLCLAMPCOLORARBPROC __rglgen_glClampColorARB; RGLSYMGLDISPATCHCOMPUTEGROUPSIZEARBPROC __rglgen_glDispatchComputeGroupSizeARB; RGLSYMGLDEBUGMESSAGECONTROLARBPROC __rglgen_glDebugMessageControlARB; RGLSYMGLDEBUGMESSAGEINSERTARBPROC __rglgen_glDebugMessageInsertARB; RGLSYMGLDEBUGMESSAGECALLBACKARBPROC __rglgen_glDebugMessageCallbackARB; RGLSYMGLGETDEBUGMESSAGELOGARBPROC __rglgen_glGetDebugMessageLogARB; RGLSYMGLDRAWBUFFERSARBPROC __rglgen_glDrawBuffersARB; RGLSYMGLBLENDEQUATIONIARBPROC __rglgen_glBlendEquationiARB; RGLSYMGLBLENDEQUATIONSEPARATEIARBPROC __rglgen_glBlendEquationSeparateiARB; RGLSYMGLBLENDFUNCIARBPROC __rglgen_glBlendFunciARB; RGLSYMGLBLENDFUNCSEPARATEIARBPROC __rglgen_glBlendFuncSeparateiARB; RGLSYMGLDRAWARRAYSINSTANCEDARBPROC __rglgen_glDrawArraysInstancedARB; RGLSYMGLDRAWELEMENTSINSTANCEDARBPROC __rglgen_glDrawElementsInstancedARB; RGLSYMGLPROGRAMSTRINGARBPROC __rglgen_glProgramStringARB; RGLSYMGLBINDPROGRAMARBPROC __rglgen_glBindProgramARB; RGLSYMGLDELETEPROGRAMSARBPROC __rglgen_glDeleteProgramsARB; RGLSYMGLGENPROGRAMSARBPROC __rglgen_glGenProgramsARB; RGLSYMGLPROGRAMENVPARAMETER4DARBPROC __rglgen_glProgramEnvParameter4dARB; RGLSYMGLPROGRAMENVPARAMETER4DVARBPROC __rglgen_glProgramEnvParameter4dvARB; RGLSYMGLPROGRAMENVPARAMETER4FARBPROC __rglgen_glProgramEnvParameter4fARB; RGLSYMGLPROGRAMENVPARAMETER4FVARBPROC __rglgen_glProgramEnvParameter4fvARB; RGLSYMGLPROGRAMLOCALPARAMETER4DARBPROC __rglgen_glProgramLocalParameter4dARB; RGLSYMGLPROGRAMLOCALPARAMETER4DVARBPROC __rglgen_glProgramLocalParameter4dvARB; RGLSYMGLPROGRAMLOCALPARAMETER4FARBPROC __rglgen_glProgramLocalParameter4fARB; RGLSYMGLPROGRAMLOCALPARAMETER4FVARBPROC __rglgen_glProgramLocalParameter4fvARB; RGLSYMGLGETPROGRAMENVPARAMETERDVARBPROC __rglgen_glGetProgramEnvParameterdvARB; RGLSYMGLGETPROGRAMENVPARAMETERFVARBPROC __rglgen_glGetProgramEnvParameterfvARB; RGLSYMGLGETPROGRAMLOCALPARAMETERDVARBPROC __rglgen_glGetProgramLocalParameterdvARB; RGLSYMGLGETPROGRAMLOCALPARAMETERFVARBPROC __rglgen_glGetProgramLocalParameterfvARB; RGLSYMGLGETPROGRAMIVARBPROC __rglgen_glGetProgramivARB; RGLSYMGLGETPROGRAMSTRINGARBPROC __rglgen_glGetProgramStringARB; RGLSYMGLISPROGRAMARBPROC __rglgen_glIsProgramARB; RGLSYMGLPROGRAMPARAMETERIARBPROC __rglgen_glProgramParameteriARB; RGLSYMGLFRAMEBUFFERTEXTUREARBPROC __rglgen_glFramebufferTextureARB; RGLSYMGLFRAMEBUFFERTEXTURELAYERARBPROC __rglgen_glFramebufferTextureLayerARB; RGLSYMGLFRAMEBUFFERTEXTUREFACEARBPROC __rglgen_glFramebufferTextureFaceARB; RGLSYMGLCOLORTABLEPROC __rglgen_glColorTable; RGLSYMGLCOLORTABLEPARAMETERFVPROC __rglgen_glColorTableParameterfv; RGLSYMGLCOLORTABLEPARAMETERIVPROC __rglgen_glColorTableParameteriv; RGLSYMGLCOPYCOLORTABLEPROC __rglgen_glCopyColorTable; RGLSYMGLGETCOLORTABLEPROC __rglgen_glGetColorTable; RGLSYMGLGETCOLORTABLEPARAMETERFVPROC __rglgen_glGetColorTableParameterfv; RGLSYMGLGETCOLORTABLEPARAMETERIVPROC __rglgen_glGetColorTableParameteriv; RGLSYMGLCOLORSUBTABLEPROC __rglgen_glColorSubTable; RGLSYMGLCOPYCOLORSUBTABLEPROC __rglgen_glCopyColorSubTable; RGLSYMGLCONVOLUTIONFILTER1DPROC __rglgen_glConvolutionFilter1D; RGLSYMGLCONVOLUTIONFILTER2DPROC __rglgen_glConvolutionFilter2D; RGLSYMGLCONVOLUTIONPARAMETERFPROC __rglgen_glConvolutionParameterf; RGLSYMGLCONVOLUTIONPARAMETERFVPROC __rglgen_glConvolutionParameterfv; RGLSYMGLCONVOLUTIONPARAMETERIPROC __rglgen_glConvolutionParameteri; RGLSYMGLCONVOLUTIONPARAMETERIVPROC __rglgen_glConvolutionParameteriv; RGLSYMGLCOPYCONVOLUTIONFILTER1DPROC __rglgen_glCopyConvolutionFilter1D; RGLSYMGLCOPYCONVOLUTIONFILTER2DPROC __rglgen_glCopyConvolutionFilter2D; RGLSYMGLGETCONVOLUTIONFILTERPROC __rglgen_glGetConvolutionFilter; RGLSYMGLGETCONVOLUTIONPARAMETERFVPROC __rglgen_glGetConvolutionParameterfv; RGLSYMGLGETCONVOLUTIONPARAMETERIVPROC __rglgen_glGetConvolutionParameteriv; RGLSYMGLGETSEPARABLEFILTERPROC __rglgen_glGetSeparableFilter; RGLSYMGLSEPARABLEFILTER2DPROC __rglgen_glSeparableFilter2D; RGLSYMGLGETHISTOGRAMPROC __rglgen_glGetHistogram; RGLSYMGLGETHISTOGRAMPARAMETERFVPROC __rglgen_glGetHistogramParameterfv; RGLSYMGLGETHISTOGRAMPARAMETERIVPROC __rglgen_glGetHistogramParameteriv; RGLSYMGLGETMINMAXPROC __rglgen_glGetMinmax; RGLSYMGLGETMINMAXPARAMETERFVPROC __rglgen_glGetMinmaxParameterfv; RGLSYMGLGETMINMAXPARAMETERIVPROC __rglgen_glGetMinmaxParameteriv; RGLSYMGLHISTOGRAMPROC __rglgen_glHistogram; RGLSYMGLMINMAXPROC __rglgen_glMinmax; RGLSYMGLRESETHISTOGRAMPROC __rglgen_glResetHistogram; RGLSYMGLRESETMINMAXPROC __rglgen_glResetMinmax; RGLSYMGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC __rglgen_glMultiDrawArraysIndirectCountARB; RGLSYMGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC __rglgen_glMultiDrawElementsIndirectCountARB; RGLSYMGLVERTEXATTRIBDIVISORARBPROC __rglgen_glVertexAttribDivisorARB; RGLSYMGLCURRENTPALETTEMATRIXARBPROC __rglgen_glCurrentPaletteMatrixARB; RGLSYMGLMATRIXINDEXUBVARBPROC __rglgen_glMatrixIndexubvARB; RGLSYMGLMATRIXINDEXUSVARBPROC __rglgen_glMatrixIndexusvARB; RGLSYMGLMATRIXINDEXUIVARBPROC __rglgen_glMatrixIndexuivARB; RGLSYMGLMATRIXINDEXPOINTERARBPROC __rglgen_glMatrixIndexPointerARB; RGLSYMGLSAMPLECOVERAGEARBPROC __rglgen_glSampleCoverageARB; RGLSYMGLACTIVETEXTUREARBPROC __rglgen_glActiveTextureARB; RGLSYMGLCLIENTACTIVETEXTUREARBPROC __rglgen_glClientActiveTextureARB; RGLSYMGLMULTITEXCOORD1DARBPROC __rglgen_glMultiTexCoord1dARB; RGLSYMGLMULTITEXCOORD1DVARBPROC __rglgen_glMultiTexCoord1dvARB; RGLSYMGLMULTITEXCOORD1FARBPROC __rglgen_glMultiTexCoord1fARB; RGLSYMGLMULTITEXCOORD1FVARBPROC __rglgen_glMultiTexCoord1fvARB; RGLSYMGLMULTITEXCOORD1IARBPROC __rglgen_glMultiTexCoord1iARB; RGLSYMGLMULTITEXCOORD1IVARBPROC __rglgen_glMultiTexCoord1ivARB; RGLSYMGLMULTITEXCOORD1SARBPROC __rglgen_glMultiTexCoord1sARB; RGLSYMGLMULTITEXCOORD1SVARBPROC __rglgen_glMultiTexCoord1svARB; RGLSYMGLMULTITEXCOORD2DARBPROC __rglgen_glMultiTexCoord2dARB; RGLSYMGLMULTITEXCOORD2DVARBPROC __rglgen_glMultiTexCoord2dvARB; RGLSYMGLMULTITEXCOORD2FARBPROC __rglgen_glMultiTexCoord2fARB; RGLSYMGLMULTITEXCOORD2FVARBPROC __rglgen_glMultiTexCoord2fvARB; RGLSYMGLMULTITEXCOORD2IARBPROC __rglgen_glMultiTexCoord2iARB; RGLSYMGLMULTITEXCOORD2IVARBPROC __rglgen_glMultiTexCoord2ivARB; RGLSYMGLMULTITEXCOORD2SARBPROC __rglgen_glMultiTexCoord2sARB; RGLSYMGLMULTITEXCOORD2SVARBPROC __rglgen_glMultiTexCoord2svARB; RGLSYMGLMULTITEXCOORD3DARBPROC __rglgen_glMultiTexCoord3dARB; RGLSYMGLMULTITEXCOORD3DVARBPROC __rglgen_glMultiTexCoord3dvARB; RGLSYMGLMULTITEXCOORD3FARBPROC __rglgen_glMultiTexCoord3fARB; RGLSYMGLMULTITEXCOORD3FVARBPROC __rglgen_glMultiTexCoord3fvARB; RGLSYMGLMULTITEXCOORD3IARBPROC __rglgen_glMultiTexCoord3iARB; RGLSYMGLMULTITEXCOORD3IVARBPROC __rglgen_glMultiTexCoord3ivARB; RGLSYMGLMULTITEXCOORD3SARBPROC __rglgen_glMultiTexCoord3sARB; RGLSYMGLMULTITEXCOORD3SVARBPROC __rglgen_glMultiTexCoord3svARB; RGLSYMGLMULTITEXCOORD4DARBPROC __rglgen_glMultiTexCoord4dARB; RGLSYMGLMULTITEXCOORD4DVARBPROC __rglgen_glMultiTexCoord4dvARB; RGLSYMGLMULTITEXCOORD4FARBPROC __rglgen_glMultiTexCoord4fARB; RGLSYMGLMULTITEXCOORD4FVARBPROC __rglgen_glMultiTexCoord4fvARB; RGLSYMGLMULTITEXCOORD4IARBPROC __rglgen_glMultiTexCoord4iARB; RGLSYMGLMULTITEXCOORD4IVARBPROC __rglgen_glMultiTexCoord4ivARB; RGLSYMGLMULTITEXCOORD4SARBPROC __rglgen_glMultiTexCoord4sARB; RGLSYMGLMULTITEXCOORD4SVARBPROC __rglgen_glMultiTexCoord4svARB; RGLSYMGLGENQUERIESARBPROC __rglgen_glGenQueriesARB; RGLSYMGLDELETEQUERIESARBPROC __rglgen_glDeleteQueriesARB; RGLSYMGLISQUERYARBPROC __rglgen_glIsQueryARB; RGLSYMGLBEGINQUERYARBPROC __rglgen_glBeginQueryARB; RGLSYMGLENDQUERYARBPROC __rglgen_glEndQueryARB; RGLSYMGLGETQUERYIVARBPROC __rglgen_glGetQueryivARB; RGLSYMGLGETQUERYOBJECTIVARBPROC __rglgen_glGetQueryObjectivARB; RGLSYMGLGETQUERYOBJECTUIVARBPROC __rglgen_glGetQueryObjectuivARB; RGLSYMGLPOINTPARAMETERFARBPROC __rglgen_glPointParameterfARB; RGLSYMGLPOINTPARAMETERFVARBPROC __rglgen_glPointParameterfvARB; RGLSYMGLGETGRAPHICSRESETSTATUSARBPROC __rglgen_glGetGraphicsResetStatusARB; RGLSYMGLGETNTEXIMAGEARBPROC __rglgen_glGetnTexImageARB; RGLSYMGLREADNPIXELSARBPROC __rglgen_glReadnPixelsARB; RGLSYMGLGETNCOMPRESSEDTEXIMAGEARBPROC __rglgen_glGetnCompressedTexImageARB; RGLSYMGLGETNUNIFORMFVARBPROC __rglgen_glGetnUniformfvARB; RGLSYMGLGETNUNIFORMIVARBPROC __rglgen_glGetnUniformivARB; RGLSYMGLGETNUNIFORMUIVARBPROC __rglgen_glGetnUniformuivARB; RGLSYMGLGETNUNIFORMDVARBPROC __rglgen_glGetnUniformdvARB; RGLSYMGLGETNMAPDVARBPROC __rglgen_glGetnMapdvARB; RGLSYMGLGETNMAPFVARBPROC __rglgen_glGetnMapfvARB; RGLSYMGLGETNMAPIVARBPROC __rglgen_glGetnMapivARB; RGLSYMGLGETNPIXELMAPFVARBPROC __rglgen_glGetnPixelMapfvARB; RGLSYMGLGETNPIXELMAPUIVARBPROC __rglgen_glGetnPixelMapuivARB; RGLSYMGLGETNPIXELMAPUSVARBPROC __rglgen_glGetnPixelMapusvARB; RGLSYMGLGETNPOLYGONSTIPPLEARBPROC __rglgen_glGetnPolygonStippleARB; RGLSYMGLGETNCOLORTABLEARBPROC __rglgen_glGetnColorTableARB; RGLSYMGLGETNCONVOLUTIONFILTERARBPROC __rglgen_glGetnConvolutionFilterARB; RGLSYMGLGETNSEPARABLEFILTERARBPROC __rglgen_glGetnSeparableFilterARB; RGLSYMGLGETNHISTOGRAMARBPROC __rglgen_glGetnHistogramARB; RGLSYMGLGETNMINMAXARBPROC __rglgen_glGetnMinmaxARB; RGLSYMGLMINSAMPLESHADINGARBPROC __rglgen_glMinSampleShadingARB; RGLSYMGLDELETEOBJECTARBPROC __rglgen_glDeleteObjectARB; RGLSYMGLGETHANDLEARBPROC __rglgen_glGetHandleARB; RGLSYMGLDETACHOBJECTARBPROC __rglgen_glDetachObjectARB; RGLSYMGLCREATESHADEROBJECTARBPROC __rglgen_glCreateShaderObjectARB; RGLSYMGLSHADERSOURCEARBPROC __rglgen_glShaderSourceARB; RGLSYMGLCOMPILESHADERARBPROC __rglgen_glCompileShaderARB; RGLSYMGLCREATEPROGRAMOBJECTARBPROC __rglgen_glCreateProgramObjectARB; RGLSYMGLATTACHOBJECTARBPROC __rglgen_glAttachObjectARB; RGLSYMGLLINKPROGRAMARBPROC __rglgen_glLinkProgramARB; RGLSYMGLUSEPROGRAMOBJECTARBPROC __rglgen_glUseProgramObjectARB; RGLSYMGLVALIDATEPROGRAMARBPROC __rglgen_glValidateProgramARB; RGLSYMGLUNIFORM1FARBPROC __rglgen_glUniform1fARB; RGLSYMGLUNIFORM2FARBPROC __rglgen_glUniform2fARB; RGLSYMGLUNIFORM3FARBPROC __rglgen_glUniform3fARB; RGLSYMGLUNIFORM4FARBPROC __rglgen_glUniform4fARB; RGLSYMGLUNIFORM1IARBPROC __rglgen_glUniform1iARB; RGLSYMGLUNIFORM2IARBPROC __rglgen_glUniform2iARB; RGLSYMGLUNIFORM3IARBPROC __rglgen_glUniform3iARB; RGLSYMGLUNIFORM4IARBPROC __rglgen_glUniform4iARB; RGLSYMGLUNIFORM1FVARBPROC __rglgen_glUniform1fvARB; RGLSYMGLUNIFORM2FVARBPROC __rglgen_glUniform2fvARB; RGLSYMGLUNIFORM3FVARBPROC __rglgen_glUniform3fvARB; RGLSYMGLUNIFORM4FVARBPROC __rglgen_glUniform4fvARB; RGLSYMGLUNIFORM1IVARBPROC __rglgen_glUniform1ivARB; RGLSYMGLUNIFORM2IVARBPROC __rglgen_glUniform2ivARB; RGLSYMGLUNIFORM3IVARBPROC __rglgen_glUniform3ivARB; RGLSYMGLUNIFORM4IVARBPROC __rglgen_glUniform4ivARB; RGLSYMGLUNIFORMMATRIX2FVARBPROC __rglgen_glUniformMatrix2fvARB; RGLSYMGLUNIFORMMATRIX3FVARBPROC __rglgen_glUniformMatrix3fvARB; RGLSYMGLUNIFORMMATRIX4FVARBPROC __rglgen_glUniformMatrix4fvARB; RGLSYMGLGETOBJECTPARAMETERFVARBPROC __rglgen_glGetObjectParameterfvARB; RGLSYMGLGETOBJECTPARAMETERIVARBPROC __rglgen_glGetObjectParameterivARB; RGLSYMGLGETINFOLOGARBPROC __rglgen_glGetInfoLogARB; RGLSYMGLGETATTACHEDOBJECTSARBPROC __rglgen_glGetAttachedObjectsARB; RGLSYMGLGETUNIFORMLOCATIONARBPROC __rglgen_glGetUniformLocationARB; RGLSYMGLGETACTIVEUNIFORMARBPROC __rglgen_glGetActiveUniformARB; RGLSYMGLGETUNIFORMFVARBPROC __rglgen_glGetUniformfvARB; RGLSYMGLGETUNIFORMIVARBPROC __rglgen_glGetUniformivARB; RGLSYMGLGETSHADERSOURCEARBPROC __rglgen_glGetShaderSourceARB; RGLSYMGLNAMEDSTRINGARBPROC __rglgen_glNamedStringARB; RGLSYMGLDELETENAMEDSTRINGARBPROC __rglgen_glDeleteNamedStringARB; RGLSYMGLCOMPILESHADERINCLUDEARBPROC __rglgen_glCompileShaderIncludeARB; RGLSYMGLISNAMEDSTRINGARBPROC __rglgen_glIsNamedStringARB; RGLSYMGLGETNAMEDSTRINGARBPROC __rglgen_glGetNamedStringARB; RGLSYMGLGETNAMEDSTRINGIVARBPROC __rglgen_glGetNamedStringivARB; RGLSYMGLTEXPAGECOMMITMENTARBPROC __rglgen_glTexPageCommitmentARB; RGLSYMGLTEXBUFFERARBPROC __rglgen_glTexBufferARB; RGLSYMGLCOMPRESSEDTEXIMAGE3DARBPROC __rglgen_glCompressedTexImage3DARB; RGLSYMGLCOMPRESSEDTEXIMAGE2DARBPROC __rglgen_glCompressedTexImage2DARB; RGLSYMGLCOMPRESSEDTEXIMAGE1DARBPROC __rglgen_glCompressedTexImage1DARB; RGLSYMGLCOMPRESSEDTEXSUBIMAGE3DARBPROC __rglgen_glCompressedTexSubImage3DARB; RGLSYMGLCOMPRESSEDTEXSUBIMAGE2DARBPROC __rglgen_glCompressedTexSubImage2DARB; RGLSYMGLCOMPRESSEDTEXSUBIMAGE1DARBPROC __rglgen_glCompressedTexSubImage1DARB; RGLSYMGLGETCOMPRESSEDTEXIMAGEARBPROC __rglgen_glGetCompressedTexImageARB; RGLSYMGLLOADTRANSPOSEMATRIXFARBPROC __rglgen_glLoadTransposeMatrixfARB; RGLSYMGLLOADTRANSPOSEMATRIXDARBPROC __rglgen_glLoadTransposeMatrixdARB; RGLSYMGLMULTTRANSPOSEMATRIXFARBPROC __rglgen_glMultTransposeMatrixfARB; RGLSYMGLMULTTRANSPOSEMATRIXDARBPROC __rglgen_glMultTransposeMatrixdARB; RGLSYMGLWEIGHTBVARBPROC __rglgen_glWeightbvARB; RGLSYMGLWEIGHTSVARBPROC __rglgen_glWeightsvARB; RGLSYMGLWEIGHTIVARBPROC __rglgen_glWeightivARB; RGLSYMGLWEIGHTFVARBPROC __rglgen_glWeightfvARB; RGLSYMGLWEIGHTDVARBPROC __rglgen_glWeightdvARB; RGLSYMGLWEIGHTUBVARBPROC __rglgen_glWeightubvARB; RGLSYMGLWEIGHTUSVARBPROC __rglgen_glWeightusvARB; RGLSYMGLWEIGHTUIVARBPROC __rglgen_glWeightuivARB; RGLSYMGLWEIGHTPOINTERARBPROC __rglgen_glWeightPointerARB; RGLSYMGLVERTEXBLENDARBPROC __rglgen_glVertexBlendARB; RGLSYMGLBINDBUFFERARBPROC __rglgen_glBindBufferARB; RGLSYMGLDELETEBUFFERSARBPROC __rglgen_glDeleteBuffersARB; RGLSYMGLGENBUFFERSARBPROC __rglgen_glGenBuffersARB; RGLSYMGLISBUFFERARBPROC __rglgen_glIsBufferARB; RGLSYMGLBUFFERDATAARBPROC __rglgen_glBufferDataARB; RGLSYMGLBUFFERSUBDATAARBPROC __rglgen_glBufferSubDataARB; RGLSYMGLGETBUFFERSUBDATAARBPROC __rglgen_glGetBufferSubDataARB; RGLSYMGLMAPBUFFERARBPROC __rglgen_glMapBufferARB; RGLSYMGLUNMAPBUFFERARBPROC __rglgen_glUnmapBufferARB; RGLSYMGLGETBUFFERPARAMETERIVARBPROC __rglgen_glGetBufferParameterivARB; RGLSYMGLGETBUFFERPOINTERVARBPROC __rglgen_glGetBufferPointervARB; RGLSYMGLVERTEXATTRIB1DARBPROC __rglgen_glVertexAttrib1dARB; RGLSYMGLVERTEXATTRIB1DVARBPROC __rglgen_glVertexAttrib1dvARB; RGLSYMGLVERTEXATTRIB1FARBPROC __rglgen_glVertexAttrib1fARB; RGLSYMGLVERTEXATTRIB1FVARBPROC __rglgen_glVertexAttrib1fvARB; RGLSYMGLVERTEXATTRIB1SARBPROC __rglgen_glVertexAttrib1sARB; RGLSYMGLVERTEXATTRIB1SVARBPROC __rglgen_glVertexAttrib1svARB; RGLSYMGLVERTEXATTRIB2DARBPROC __rglgen_glVertexAttrib2dARB; RGLSYMGLVERTEXATTRIB2DVARBPROC __rglgen_glVertexAttrib2dvARB; RGLSYMGLVERTEXATTRIB2FARBPROC __rglgen_glVertexAttrib2fARB; RGLSYMGLVERTEXATTRIB2FVARBPROC __rglgen_glVertexAttrib2fvARB; RGLSYMGLVERTEXATTRIB2SARBPROC __rglgen_glVertexAttrib2sARB; RGLSYMGLVERTEXATTRIB2SVARBPROC __rglgen_glVertexAttrib2svARB; RGLSYMGLVERTEXATTRIB3DARBPROC __rglgen_glVertexAttrib3dARB; RGLSYMGLVERTEXATTRIB3DVARBPROC __rglgen_glVertexAttrib3dvARB; RGLSYMGLVERTEXATTRIB3FARBPROC __rglgen_glVertexAttrib3fARB; RGLSYMGLVERTEXATTRIB3FVARBPROC __rglgen_glVertexAttrib3fvARB; RGLSYMGLVERTEXATTRIB3SARBPROC __rglgen_glVertexAttrib3sARB; RGLSYMGLVERTEXATTRIB3SVARBPROC __rglgen_glVertexAttrib3svARB; RGLSYMGLVERTEXATTRIB4NBVARBPROC __rglgen_glVertexAttrib4NbvARB; RGLSYMGLVERTEXATTRIB4NIVARBPROC __rglgen_glVertexAttrib4NivARB; RGLSYMGLVERTEXATTRIB4NSVARBPROC __rglgen_glVertexAttrib4NsvARB; RGLSYMGLVERTEXATTRIB4NUBARBPROC __rglgen_glVertexAttrib4NubARB; RGLSYMGLVERTEXATTRIB4NUBVARBPROC __rglgen_glVertexAttrib4NubvARB; RGLSYMGLVERTEXATTRIB4NUIVARBPROC __rglgen_glVertexAttrib4NuivARB; RGLSYMGLVERTEXATTRIB4NUSVARBPROC __rglgen_glVertexAttrib4NusvARB; RGLSYMGLVERTEXATTRIB4BVARBPROC __rglgen_glVertexAttrib4bvARB; RGLSYMGLVERTEXATTRIB4DARBPROC __rglgen_glVertexAttrib4dARB; RGLSYMGLVERTEXATTRIB4DVARBPROC __rglgen_glVertexAttrib4dvARB; RGLSYMGLVERTEXATTRIB4FARBPROC __rglgen_glVertexAttrib4fARB; RGLSYMGLVERTEXATTRIB4FVARBPROC __rglgen_glVertexAttrib4fvARB; RGLSYMGLVERTEXATTRIB4IVARBPROC __rglgen_glVertexAttrib4ivARB; RGLSYMGLVERTEXATTRIB4SARBPROC __rglgen_glVertexAttrib4sARB; RGLSYMGLVERTEXATTRIB4SVARBPROC __rglgen_glVertexAttrib4svARB; RGLSYMGLVERTEXATTRIB4UBVARBPROC __rglgen_glVertexAttrib4ubvARB; RGLSYMGLVERTEXATTRIB4UIVARBPROC __rglgen_glVertexAttrib4uivARB; RGLSYMGLVERTEXATTRIB4USVARBPROC __rglgen_glVertexAttrib4usvARB; RGLSYMGLVERTEXATTRIBPOINTERARBPROC __rglgen_glVertexAttribPointerARB; RGLSYMGLENABLEVERTEXATTRIBARRAYARBPROC __rglgen_glEnableVertexAttribArrayARB; RGLSYMGLDISABLEVERTEXATTRIBARRAYARBPROC __rglgen_glDisableVertexAttribArrayARB; RGLSYMGLGETVERTEXATTRIBDVARBPROC __rglgen_glGetVertexAttribdvARB; RGLSYMGLGETVERTEXATTRIBFVARBPROC __rglgen_glGetVertexAttribfvARB; RGLSYMGLGETVERTEXATTRIBIVARBPROC __rglgen_glGetVertexAttribivARB; RGLSYMGLGETVERTEXATTRIBPOINTERVARBPROC __rglgen_glGetVertexAttribPointervARB; RGLSYMGLBINDATTRIBLOCATIONARBPROC __rglgen_glBindAttribLocationARB; RGLSYMGLGETACTIVEATTRIBARBPROC __rglgen_glGetActiveAttribARB; RGLSYMGLGETATTRIBLOCATIONARBPROC __rglgen_glGetAttribLocationARB; RGLSYMGLWINDOWPOS2DARBPROC __rglgen_glWindowPos2dARB; RGLSYMGLWINDOWPOS2DVARBPROC __rglgen_glWindowPos2dvARB; RGLSYMGLWINDOWPOS2FARBPROC __rglgen_glWindowPos2fARB; RGLSYMGLWINDOWPOS2FVARBPROC __rglgen_glWindowPos2fvARB; RGLSYMGLWINDOWPOS2IARBPROC __rglgen_glWindowPos2iARB; RGLSYMGLWINDOWPOS2IVARBPROC __rglgen_glWindowPos2ivARB; RGLSYMGLWINDOWPOS2SARBPROC __rglgen_glWindowPos2sARB; RGLSYMGLWINDOWPOS2SVARBPROC __rglgen_glWindowPos2svARB; RGLSYMGLWINDOWPOS3DARBPROC __rglgen_glWindowPos3dARB; RGLSYMGLWINDOWPOS3DVARBPROC __rglgen_glWindowPos3dvARB; RGLSYMGLWINDOWPOS3FARBPROC __rglgen_glWindowPos3fARB; RGLSYMGLWINDOWPOS3FVARBPROC __rglgen_glWindowPos3fvARB; RGLSYMGLWINDOWPOS3IARBPROC __rglgen_glWindowPos3iARB; RGLSYMGLWINDOWPOS3IVARBPROC __rglgen_glWindowPos3ivARB; RGLSYMGLWINDOWPOS3SARBPROC __rglgen_glWindowPos3sARB; RGLSYMGLWINDOWPOS3SVARBPROC __rglgen_glWindowPos3svARB; RGLSYMGLMULTITEXCOORD1BOESPROC __rglgen_glMultiTexCoord1bOES; RGLSYMGLMULTITEXCOORD1BVOESPROC __rglgen_glMultiTexCoord1bvOES; RGLSYMGLMULTITEXCOORD2BOESPROC __rglgen_glMultiTexCoord2bOES; RGLSYMGLMULTITEXCOORD2BVOESPROC __rglgen_glMultiTexCoord2bvOES; RGLSYMGLMULTITEXCOORD3BOESPROC __rglgen_glMultiTexCoord3bOES; RGLSYMGLMULTITEXCOORD3BVOESPROC __rglgen_glMultiTexCoord3bvOES; RGLSYMGLMULTITEXCOORD4BOESPROC __rglgen_glMultiTexCoord4bOES; RGLSYMGLMULTITEXCOORD4BVOESPROC __rglgen_glMultiTexCoord4bvOES; RGLSYMGLTEXCOORD1BOESPROC __rglgen_glTexCoord1bOES; RGLSYMGLTEXCOORD1BVOESPROC __rglgen_glTexCoord1bvOES; RGLSYMGLTEXCOORD2BOESPROC __rglgen_glTexCoord2bOES; RGLSYMGLTEXCOORD2BVOESPROC __rglgen_glTexCoord2bvOES; RGLSYMGLTEXCOORD3BOESPROC __rglgen_glTexCoord3bOES; RGLSYMGLTEXCOORD3BVOESPROC __rglgen_glTexCoord3bvOES; RGLSYMGLTEXCOORD4BOESPROC __rglgen_glTexCoord4bOES; RGLSYMGLTEXCOORD4BVOESPROC __rglgen_glTexCoord4bvOES; RGLSYMGLVERTEX2BOESPROC __rglgen_glVertex2bOES; RGLSYMGLVERTEX2BVOESPROC __rglgen_glVertex2bvOES; RGLSYMGLVERTEX3BOESPROC __rglgen_glVertex3bOES; RGLSYMGLVERTEX3BVOESPROC __rglgen_glVertex3bvOES; RGLSYMGLVERTEX4BOESPROC __rglgen_glVertex4bOES; RGLSYMGLVERTEX4BVOESPROC __rglgen_glVertex4bvOES; RGLSYMGLALPHAFUNCXOESPROC __rglgen_glAlphaFuncxOES; RGLSYMGLCLEARCOLORXOESPROC __rglgen_glClearColorxOES; RGLSYMGLCLEARDEPTHXOESPROC __rglgen_glClearDepthxOES; RGLSYMGLCLIPPLANEXOESPROC __rglgen_glClipPlanexOES; RGLSYMGLCOLOR4XOESPROC __rglgen_glColor4xOES; RGLSYMGLDEPTHRANGEXOESPROC __rglgen_glDepthRangexOES; RGLSYMGLFOGXOESPROC __rglgen_glFogxOES; RGLSYMGLFOGXVOESPROC __rglgen_glFogxvOES; RGLSYMGLFRUSTUMXOESPROC __rglgen_glFrustumxOES; RGLSYMGLGETCLIPPLANEXOESPROC __rglgen_glGetClipPlanexOES; RGLSYMGLGETFIXEDVOESPROC __rglgen_glGetFixedvOES; RGLSYMGLGETTEXENVXVOESPROC __rglgen_glGetTexEnvxvOES; RGLSYMGLGETTEXPARAMETERXVOESPROC __rglgen_glGetTexParameterxvOES; RGLSYMGLLIGHTMODELXOESPROC __rglgen_glLightModelxOES; RGLSYMGLLIGHTMODELXVOESPROC __rglgen_glLightModelxvOES; RGLSYMGLLIGHTXOESPROC __rglgen_glLightxOES; RGLSYMGLLIGHTXVOESPROC __rglgen_glLightxvOES; RGLSYMGLLINEWIDTHXOESPROC __rglgen_glLineWidthxOES; RGLSYMGLLOADMATRIXXOESPROC __rglgen_glLoadMatrixxOES; RGLSYMGLMATERIALXOESPROC __rglgen_glMaterialxOES; RGLSYMGLMATERIALXVOESPROC __rglgen_glMaterialxvOES; RGLSYMGLMULTMATRIXXOESPROC __rglgen_glMultMatrixxOES; RGLSYMGLMULTITEXCOORD4XOESPROC __rglgen_glMultiTexCoord4xOES; RGLSYMGLNORMAL3XOESPROC __rglgen_glNormal3xOES; RGLSYMGLORTHOXOESPROC __rglgen_glOrthoxOES; RGLSYMGLPOINTPARAMETERXVOESPROC __rglgen_glPointParameterxvOES; RGLSYMGLPOINTSIZEXOESPROC __rglgen_glPointSizexOES; RGLSYMGLPOLYGONOFFSETXOESPROC __rglgen_glPolygonOffsetxOES; RGLSYMGLROTATEXOESPROC __rglgen_glRotatexOES; RGLSYMGLSAMPLECOVERAGEOESPROC __rglgen_glSampleCoverageOES; RGLSYMGLSCALEXOESPROC __rglgen_glScalexOES; RGLSYMGLTEXENVXOESPROC __rglgen_glTexEnvxOES; RGLSYMGLTEXENVXVOESPROC __rglgen_glTexEnvxvOES; RGLSYMGLTEXPARAMETERXOESPROC __rglgen_glTexParameterxOES; RGLSYMGLTEXPARAMETERXVOESPROC __rglgen_glTexParameterxvOES; RGLSYMGLTRANSLATEXOESPROC __rglgen_glTranslatexOES; RGLSYMGLACCUMXOESPROC __rglgen_glAccumxOES; RGLSYMGLBITMAPXOESPROC __rglgen_glBitmapxOES; RGLSYMGLBLENDCOLORXOESPROC __rglgen_glBlendColorxOES; RGLSYMGLCLEARACCUMXOESPROC __rglgen_glClearAccumxOES; RGLSYMGLCOLOR3XOESPROC __rglgen_glColor3xOES; RGLSYMGLCOLOR3XVOESPROC __rglgen_glColor3xvOES; RGLSYMGLCOLOR4XVOESPROC __rglgen_glColor4xvOES; RGLSYMGLCONVOLUTIONPARAMETERXOESPROC __rglgen_glConvolutionParameterxOES; RGLSYMGLCONVOLUTIONPARAMETERXVOESPROC __rglgen_glConvolutionParameterxvOES; RGLSYMGLEVALCOORD1XOESPROC __rglgen_glEvalCoord1xOES; RGLSYMGLEVALCOORD1XVOESPROC __rglgen_glEvalCoord1xvOES; RGLSYMGLEVALCOORD2XOESPROC __rglgen_glEvalCoord2xOES; RGLSYMGLEVALCOORD2XVOESPROC __rglgen_glEvalCoord2xvOES; RGLSYMGLFEEDBACKBUFFERXOESPROC __rglgen_glFeedbackBufferxOES; RGLSYMGLGETCONVOLUTIONPARAMETERXVOESPROC __rglgen_glGetConvolutionParameterxvOES; RGLSYMGLGETHISTOGRAMPARAMETERXVOESPROC __rglgen_glGetHistogramParameterxvOES; RGLSYMGLGETLIGHTXOESPROC __rglgen_glGetLightxOES; RGLSYMGLGETMAPXVOESPROC __rglgen_glGetMapxvOES; RGLSYMGLGETMATERIALXOESPROC __rglgen_glGetMaterialxOES; RGLSYMGLGETPIXELMAPXVPROC __rglgen_glGetPixelMapxv; RGLSYMGLGETTEXGENXVOESPROC __rglgen_glGetTexGenxvOES; RGLSYMGLGETTEXLEVELPARAMETERXVOESPROC __rglgen_glGetTexLevelParameterxvOES; RGLSYMGLINDEXXOESPROC __rglgen_glIndexxOES; RGLSYMGLINDEXXVOESPROC __rglgen_glIndexxvOES; RGLSYMGLLOADTRANSPOSEMATRIXXOESPROC __rglgen_glLoadTransposeMatrixxOES; RGLSYMGLMAP1XOESPROC __rglgen_glMap1xOES; RGLSYMGLMAP2XOESPROC __rglgen_glMap2xOES; RGLSYMGLMAPGRID1XOESPROC __rglgen_glMapGrid1xOES; RGLSYMGLMAPGRID2XOESPROC __rglgen_glMapGrid2xOES; RGLSYMGLMULTTRANSPOSEMATRIXXOESPROC __rglgen_glMultTransposeMatrixxOES; RGLSYMGLMULTITEXCOORD1XOESPROC __rglgen_glMultiTexCoord1xOES; RGLSYMGLMULTITEXCOORD1XVOESPROC __rglgen_glMultiTexCoord1xvOES; RGLSYMGLMULTITEXCOORD2XOESPROC __rglgen_glMultiTexCoord2xOES; RGLSYMGLMULTITEXCOORD2XVOESPROC __rglgen_glMultiTexCoord2xvOES; RGLSYMGLMULTITEXCOORD3XOESPROC __rglgen_glMultiTexCoord3xOES; RGLSYMGLMULTITEXCOORD3XVOESPROC __rglgen_glMultiTexCoord3xvOES; RGLSYMGLMULTITEXCOORD4XVOESPROC __rglgen_glMultiTexCoord4xvOES; RGLSYMGLNORMAL3XVOESPROC __rglgen_glNormal3xvOES; RGLSYMGLPASSTHROUGHXOESPROC __rglgen_glPassThroughxOES; RGLSYMGLPIXELMAPXPROC __rglgen_glPixelMapx; RGLSYMGLPIXELSTOREXPROC __rglgen_glPixelStorex; RGLSYMGLPIXELTRANSFERXOESPROC __rglgen_glPixelTransferxOES; RGLSYMGLPIXELZOOMXOESPROC __rglgen_glPixelZoomxOES; RGLSYMGLPRIORITIZETEXTURESXOESPROC __rglgen_glPrioritizeTexturesxOES; RGLSYMGLRASTERPOS2XOESPROC __rglgen_glRasterPos2xOES; RGLSYMGLRASTERPOS2XVOESPROC __rglgen_glRasterPos2xvOES; RGLSYMGLRASTERPOS3XOESPROC __rglgen_glRasterPos3xOES; RGLSYMGLRASTERPOS3XVOESPROC __rglgen_glRasterPos3xvOES; RGLSYMGLRASTERPOS4XOESPROC __rglgen_glRasterPos4xOES; RGLSYMGLRASTERPOS4XVOESPROC __rglgen_glRasterPos4xvOES; RGLSYMGLRECTXOESPROC __rglgen_glRectxOES; RGLSYMGLRECTXVOESPROC __rglgen_glRectxvOES; RGLSYMGLTEXCOORD1XOESPROC __rglgen_glTexCoord1xOES; RGLSYMGLTEXCOORD1XVOESPROC __rglgen_glTexCoord1xvOES; RGLSYMGLTEXCOORD2XOESPROC __rglgen_glTexCoord2xOES; RGLSYMGLTEXCOORD2XVOESPROC __rglgen_glTexCoord2xvOES; RGLSYMGLTEXCOORD3XOESPROC __rglgen_glTexCoord3xOES; RGLSYMGLTEXCOORD3XVOESPROC __rglgen_glTexCoord3xvOES; RGLSYMGLTEXCOORD4XOESPROC __rglgen_glTexCoord4xOES; RGLSYMGLTEXCOORD4XVOESPROC __rglgen_glTexCoord4xvOES; RGLSYMGLTEXGENXOESPROC __rglgen_glTexGenxOES; RGLSYMGLTEXGENXVOESPROC __rglgen_glTexGenxvOES; RGLSYMGLVERTEX2XOESPROC __rglgen_glVertex2xOES; RGLSYMGLVERTEX2XVOESPROC __rglgen_glVertex2xvOES; RGLSYMGLVERTEX3XOESPROC __rglgen_glVertex3xOES; RGLSYMGLVERTEX3XVOESPROC __rglgen_glVertex3xvOES; RGLSYMGLVERTEX4XOESPROC __rglgen_glVertex4xOES; RGLSYMGLVERTEX4XVOESPROC __rglgen_glVertex4xvOES; RGLSYMGLQUERYMATRIXXOESPROC __rglgen_glQueryMatrixxOES; RGLSYMGLCLEARDEPTHFOESPROC __rglgen_glClearDepthfOES; RGLSYMGLCLIPPLANEFOESPROC __rglgen_glClipPlanefOES; RGLSYMGLDEPTHRANGEFOESPROC __rglgen_glDepthRangefOES; RGLSYMGLFRUSTUMFOESPROC __rglgen_glFrustumfOES; RGLSYMGLGETCLIPPLANEFOESPROC __rglgen_glGetClipPlanefOES; RGLSYMGLORTHOFOESPROC __rglgen_glOrthofOES; RGLSYMGLIMAGETRANSFORMPARAMETERIHPPROC __rglgen_glImageTransformParameteriHP; RGLSYMGLIMAGETRANSFORMPARAMETERFHPPROC __rglgen_glImageTransformParameterfHP; RGLSYMGLIMAGETRANSFORMPARAMETERIVHPPROC __rglgen_glImageTransformParameterivHP; RGLSYMGLIMAGETRANSFORMPARAMETERFVHPPROC __rglgen_glImageTransformParameterfvHP; RGLSYMGLGETIMAGETRANSFORMPARAMETERIVHPPROC __rglgen_glGetImageTransformParameterivHP; RGLSYMGLGETIMAGETRANSFORMPARAMETERFVHPPROC __rglgen_glGetImageTransformParameterfvHP; mupen64plus-core/src/r4300/new_dynarec/assem_x86.c000664 001750 001750 00000357671 12655644434 022710 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - assem_x86.c * * Copyright (C) 2009-2011 Ari64 * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "main/main.h" int cycle_count; int last_count; int pcaddr; int pending_exception; int branch_target; uint64_t readmem_dword; static precomp_instr fake_pc; u_int memory_map[1048576]; static u_int mini_ht[32][2] __attribute__((aligned(8))); u_char restore_candidate[512] __attribute__((aligned(4))); void do_interrupt(); void jump_vaddr_eax(); void jump_vaddr_ecx(); void jump_vaddr_edx(); void jump_vaddr_ebx(); void jump_vaddr_ebp(); void jump_vaddr_edi(); static const u_int jump_vaddr_reg[8] = { (int)jump_vaddr_eax, (int)jump_vaddr_ecx, (int)jump_vaddr_edx, (int)jump_vaddr_ebx, 0, (int)jump_vaddr_ebp, 0, (int)jump_vaddr_edi }; void invalidate_block_eax(); void invalidate_block_ecx(); void invalidate_block_edx(); void invalidate_block_ebx(); void invalidate_block_ebp(); void invalidate_block_esi(); void invalidate_block_edi(); static const u_int invalidate_block_reg[8] = { (int)invalidate_block_eax, (int)invalidate_block_ecx, (int)invalidate_block_edx, (int)invalidate_block_ebx, 0, (int)invalidate_block_ebp, (int)invalidate_block_esi, (int)invalidate_block_edi }; static const u_short rounding_modes[4] = { 0x33F, // round 0xF3F, // trunc 0xB3F, // ceil 0x73F};// floor #include "../fpu.h" // We need these for cmovcc instructions on x86 static const u_int const_zero=0; static const u_int const_one=1; /* Linker */ static void set_jump_target(intptr_t addr, int target) { u_char *ptr=(u_char *)addr; if(*ptr==0x0f) { assert(ptr[1]>=0x80&&ptr[1]<=0x8f); u_int *ptr2=(u_int *)(ptr+2); *ptr2=target-(int)ptr2-4; } else if(*ptr==0xe8||*ptr==0xe9) { u_int *ptr2=(u_int *)(ptr+1); *ptr2=target-(int)ptr2-4; } else { assert(*ptr==0xc7); /* mov immediate (store address) */ u_int *ptr2=(u_int *)(ptr+6); *ptr2=target; } } static void *kill_pointer(void *stub) { int *i_ptr=*((int **)(stub+6)); *i_ptr=(int)stub-(int)i_ptr-4; return i_ptr; } static int get_pointer(void *stub) { int *i_ptr=*((int **)(stub+6)); return *i_ptr+(int)i_ptr+4; } // Find the "clean" entry point from a "dirty" entry point // by skipping past the call to verify_code static u_int get_clean_addr(int addr) { u_char *ptr=(u_char *)addr; assert(ptr[20]==0xE8); // call instruction assert(ptr[25]==0x83); // pop (add esp,4) instruction if(ptr[28]==0xE9) return *(u_int *)(ptr+29)+addr+33; // follow jmp else return(addr+28); } static int verify_dirty(void *addr) { u_char *ptr=(u_char *)addr; assert(ptr[5]==0xB8); u_int source=*(u_int *)(ptr+6); u_int copy=*(u_int *)(ptr+11); u_int len=*(u_int *)(ptr+16); assert(ptr[20]==0xE8); // call instruction u_int verifier=*(u_int *)(ptr+21)+(u_int)ptr+25; if(verifier==(u_int)verify_code_vm||verifier==(u_int)verify_code_ds) { unsigned int page=source>>12; unsigned int map_value=memory_map[page]; if(map_value>=0x80000000) return 0; while(page<((source+len-1)>>12)) { if((memory_map[++page]<<2)!=(map_value<<2)) return 0; } source = source+(map_value<<2); } //DebugMessage(M64MSG_VERBOSE, "verify_dirty: %x %x %x",source,copy,len); return !memcmp((void *)source,(void *)copy,len); } // This doesn't necessarily find all clean entry points, just // guarantees that it's not dirty static int isclean(int addr) { u_char *ptr=(u_char *)addr; if(ptr[5]!=0xB8) return 1; // mov imm,%eax if(ptr[10]!=0xBB) return 1; // mov imm,%ebx if(ptr[15]!=0xB9) return 1; // mov imm,%ecx if(ptr[20]!=0xE8) return 1; // call instruction if(ptr[25]!=0x83) return 1; // pop (add esp,4) instruction return 0; } static void get_bounds(int addr,u_int *start,u_int *end) { u_char *ptr=(u_char *)addr; assert(ptr[5]==0xB8); u_int source=*(u_int *)(ptr+6); //u_int copy=*(u_int *)(ptr+11); u_int len=*(u_int *)(ptr+16); assert(ptr[20]==0xE8); // call instruction u_int verifier=*(u_int *)(ptr+21)+(u_int)ptr+25; if(verifier==(u_int)verify_code_vm||verifier==(u_int)verify_code_ds) { if(memory_map[source>>12]>=0x80000000) source = 0; else source = source+(memory_map[source>>12]<<2); } if(start) *start=source; if(end) *end=source+len; } /* Register allocation */ // Note: registers are allocated clean (unmodified state) // if you intend to modify the register, you must call dirty_reg(). static void alloc_reg(struct regstat *cur,int i,signed char reg) { int r,hr; int preferred_reg = (reg&3)+(reg>28)*4-(reg==32)+2*(reg==36)-(reg==40); // Don't allocate unused registers if((cur->u>>reg)&1) return; // see if it's already allocated for(hr=0;hrregmap[hr]==reg) return; } // Keep the same mapping if the register was already allocated in a loop preferred_reg = loop_reg(i,reg,preferred_reg); // Try to allocate the preferred register if(cur->regmap[preferred_reg]==-1) { cur->regmap[preferred_reg]=reg; cur->dirty&=~(1<isconst&=~(1<regmap[preferred_reg]; if(r<64&&((cur->u>>r)&1)) { cur->regmap[preferred_reg]=reg; cur->dirty&=~(1<isconst&=~(1<=64&&((cur->uu>>(r&63))&1)) { cur->regmap[preferred_reg]=reg; cur->dirty&=~(1<isconst&=~(1<regmap[hr]==-1) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<regmap[hr]; if(r>=0) { if(r<64) { if((cur->u>>r)&1) if(i==0||(unneeded_reg[i-1]>>r)&1) {cur->regmap[hr]=-1;break;} } else { if((cur->uu>>(r&63))&1) if(i==0||(unneeded_reg_upper[i-1]>>(r&63))&1) {cur->regmap[hr]=-1;break;} } } } // Try to allocate any available register, but prefer // registers that have not been used recently. if(i>0) { for(hr=0;hrregmap[hr]==-1) { if(regs[i-1].regmap[hr]!=rs1[i-1]&®s[i-1].regmap[hr]!=rs2[i-1]&®s[i-1].regmap[hr]!=rt1[i-1]&®s[i-1].regmap[hr]!=rt2[i-1]) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<regmap[hr]==-1) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<regmap[0]&63],hsn[cur->regmap[1]&63],hsn[cur->regmap[2]&63],hsn[cur->regmap[3]&63],hsn[cur->regmap[5]&63],hsn[cur->regmap[6]&63],hsn[cur->regmap[7]&63]); if(i>0) { // Don't evict the cycle count at entry points, otherwise the entry // stub will have to write it. if(bt[i]&&hsn[CCREG]>2) hsn[CCREG]=2; if(i>1&&hsn[CCREG]>2&&(itype[i-2]==RJUMP||itype[i-2]==UJUMP||itype[i-2]==CJUMP||itype[i-2]==SJUMP||itype[i-2]==FJUMP)) hsn[CCREG]=2; for(j=10;j>=3;j--) { // Alloc preferred register if available if(hsn[r=cur->regmap[preferred_reg]&63]==j) { for(hr=0;hrregmap[hr]&63)==r) { cur->regmap[hr]=-1; cur->dirty&=~(1<isconst&=~(1<regmap[preferred_reg]=reg; return; } for(r=1;r<=MAXREG;r++) { if(hsn[r]==j&&r!=rs1[i-1]&&r!=rs2[i-1]&&r!=rt1[i-1]&&r!=rt2[i-1]) { for(hr=0;hrregmap[hr]==r+64) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<regmap[hr]==r) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<=0;j--) { for(r=1;r<=MAXREG;r++) { if(hsn[r]==j) { for(hr=0;hrregmap[hr]==r+64) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<regmap[hr]==r) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<uu>>reg)&1) return; // see if the upper half is already allocated for(hr=0;hrregmap[hr]==reg+64) return; } // Keep the same mapping if the register was already allocated in a loop preferred_reg = loop_reg(i,reg,preferred_reg); // Try to allocate the preferred register if(cur->regmap[preferred_reg]==-1) { cur->regmap[preferred_reg]=reg|64; cur->dirty&=~(1<isconst&=~(1<regmap[preferred_reg]; if(r<64&&((cur->u>>r)&1)) { cur->regmap[preferred_reg]=reg|64; cur->dirty&=~(1<isconst&=~(1<=64&&((cur->uu>>(r&63))&1)) { cur->regmap[preferred_reg]=reg|64; cur->dirty&=~(1<isconst&=~(1<regmap[hr]==-1) { cur->regmap[hr]=reg|64; cur->dirty&=~(1<isconst&=~(1<=0;hr--) { r=cur->regmap[hr]; if(r>=0) { if(r<64) { if((cur->u>>r)&1) {cur->regmap[hr]=-1;break;} } else { if((cur->uu>>(r&63))&1) {cur->regmap[hr]=-1;break;} } } } // Try to allocate any available register, but prefer // registers that have not been used recently. if(i>0) { for(hr=0;hrregmap[hr]==-1) { if(regs[i-1].regmap[hr]!=rs1[i-1]&®s[i-1].regmap[hr]!=rs2[i-1]&®s[i-1].regmap[hr]!=rt1[i-1]&®s[i-1].regmap[hr]!=rt2[i-1]) { cur->regmap[hr]=reg|64; cur->dirty&=~(1<isconst&=~(1<regmap[hr]==-1) { cur->regmap[hr]=reg|64; cur->dirty&=~(1<isconst&=~(1<regmap[0],cur->regmap[1],cur->regmap[2],cur->regmap[3],cur->regmap[5],cur->regmap[6],cur->regmap[7]); //DebugMessage(M64MSG_VERBOSE, "hsn(%x): %d %d %d %d %d %d %d",start+i*4,hsn[cur->regmap[0]&63],hsn[cur->regmap[1]&63],hsn[cur->regmap[2]&63],hsn[cur->regmap[3]&63],hsn[cur->regmap[5]&63],hsn[cur->regmap[6]&63],hsn[cur->regmap[7]&63]); if(i>0) { // Don't evict the cycle count at entry points, otherwise the entry // stub will have to write it. if(bt[i]&&hsn[CCREG]>2) hsn[CCREG]=2; if(i>1&&hsn[CCREG]>2&&(itype[i-2]==RJUMP||itype[i-2]==UJUMP||itype[i-2]==CJUMP||itype[i-2]==SJUMP||itype[i-2]==FJUMP)) hsn[CCREG]=2; for(j=10;j>=3;j--) { // Alloc preferred register if available if(hsn[r=cur->regmap[preferred_reg]&63]==j) { for(hr=0;hrregmap[hr]&63)==r) { cur->regmap[hr]=-1; cur->dirty&=~(1<isconst&=~(1<regmap[preferred_reg]=reg|64; return; } for(r=1;r<=MAXREG;r++) { if(hsn[r]==j&&r!=rs1[i-1]&&r!=rs2[i-1]&&r!=rt1[i-1]&&r!=rt2[i-1]) { for(hr=0;hrregmap[hr]==r+64) { cur->regmap[hr]=reg|64; cur->dirty&=~(1<isconst&=~(1<regmap[hr]==r) { cur->regmap[hr]=reg|64; cur->dirty&=~(1<isconst&=~(1<=0;j--) { for(r=1;r<=MAXREG;r++) { if(hsn[r]==j) { for(hr=0;hrregmap[hr]==r+64) { cur->regmap[hr]=reg|64; cur->dirty&=~(1<isconst&=~(1<regmap[hr]==r) { cur->regmap[hr]=reg|64; cur->dirty&=~(1<isconst&=~(1<regmap[hr]==reg) return; } // Try to allocate any available register, starting with EDI, ESI, EBP... // We prefer EDI, ESI, EBP since the others are used for byte/halfword stores for(hr=HOST_REGS-1;hr>=0;hr--) { if(hr!=EXCLUDE_REG&&cur->regmap[hr]==-1) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<=0;hr--) { r=cur->regmap[hr]; if(r>=0) { if(r<64) { if((cur->u>>r)&1) { if(i==0||((unneeded_reg[i-1]>>r)&1)) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<uu>>(r&63))&1) { if(i==0||((unneeded_reg_upper[i-1]>>(r&63))&1)) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<regmap[0]&63],hsn[cur->regmap[1]&63],hsn[cur->regmap[2]&63],hsn[cur->regmap[3]&63],hsn[cur->regmap[5]&63],hsn[cur->regmap[6]&63],hsn[cur->regmap[7]&63]); if(i>0) { // Don't evict the cycle count at entry points, otherwise the entry // stub will have to write it. if(bt[i]&&hsn[CCREG]>2) hsn[CCREG]=2; if(i>1&&hsn[CCREG]>2&&(itype[i-2]==RJUMP||itype[i-2]==UJUMP||itype[i-2]==CJUMP||itype[i-2]==SJUMP||itype[i-2]==FJUMP)) hsn[CCREG]=2; for(j=10;j>=3;j--) { for(r=1;r<=MAXREG;r++) { if(hsn[r]==j&&r!=rs1[i-1]&&r!=rs2[i-1]&&r!=rt1[i-1]&&r!=rt2[i-1]) { for(hr=0;hr2) { if(cur->regmap[hr]==r+64) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<2) { if(cur->regmap[hr]==r) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<=0;j--) { for(r=1;r<=MAXREG;r++) { if(hsn[r]==j) { for(hr=0;hrregmap[hr]==r+64) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<regmap[hr]==r) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<regmap[n]==reg) { dirty=(cur->dirty>>n)&1; cur->regmap[n]=-1; } } cur->regmap[hr]=reg; cur->dirty&=~(1<dirty|=dirty<isconst&=~(1<u&=~(1LL<u&=~(1LL<is32|=1LL<is32|=1LL<is32&=~(1LL<is32&=~(1LL<is32|=1LL<is32|=1LL<>4); if((r&63)==HIREG) addr=(int)&hi+((r&64)>>4); if((r&63)==LOREG) addr=(int)&lo+((r&64)>>4); if(r==CCREG) addr=(int)&cycle_count; if(r==CSREG) addr=(int)&g_cp0_regs[CP0_STATUS_REG]; if(r==FSREG) addr=(int)&FCR31; assem_debug("mov %x+%d,%%%s",addr,r,regname[hr]); output_byte(0x8B); output_modrm(0,5,hr); output_w32(addr); } } static void emit_storereg(int r, int hr) { int addr=((int)reg)+((r&63)<<3)+((r&64)>>4); if((r&63)==HIREG) addr=(int)&hi+((r&64)>>4); if((r&63)==LOREG) addr=(int)&lo+((r&64)>>4); if(r==CCREG) addr=(int)&cycle_count; if(r==FSREG) addr=(int)&FCR31; assem_debug("mov %%%s,%x+%d",regname[hr],addr,r); output_byte(0x89); output_modrm(0,5,hr); output_w32(addr); } static void emit_test(int rs, int rt) { assem_debug("test %%%s,%%%s",regname[rs],regname[rt]); output_byte(0x85); output_modrm(3,rs,rt); } static void emit_testimm(int rs,int imm) { assem_debug("test $0x%x,%%%s",imm,regname[rs]); if(imm<128&&imm>=-128&&rs<4) { output_byte(0xF6); output_modrm(3,rs,0); output_byte(imm); } else { output_byte(0xF7); output_modrm(3,rs,0); output_w32(imm); } } static void emit_not(int rs,int rt) { if(rs!=rt) emit_mov(rs,rt); assem_debug("not %%%s",regname[rt]); output_byte(0xF7); output_modrm(3,rt,2); } static void emit_and(u_int rs1,u_int rs2,u_int rt) { assert(rs1<8); assert(rs2<8); assert(rt<8); if(rs1==rt) { assem_debug("and %%%s,%%%s",regname[rs2],regname[rt]); output_byte(0x21); output_modrm(3,rs1,rs2); } else if(rs2==rt) { assem_debug("and %%%s,%%%s",regname[rs1],regname[rt]); output_byte(0x21); output_modrm(3,rs2,rs1); } else { emit_mov(rs1,rt); emit_and(rt,rs2,rt); } } static void emit_or(u_int rs1,u_int rs2,u_int rt) { assert(rs1<8); assert(rs2<8); assert(rt<8); if(rs1==rt) { assem_debug("or %%%s,%%%s",regname[rs2],regname[rt]); output_byte(0x09); output_modrm(3,rs1,rs2); } else if(rs2==rt) { assem_debug("or %%%s,%%%s",regname[rs1],regname[rt]); output_byte(0x09); output_modrm(3,rs2,rs1); } else { emit_mov(rs1,rt); emit_or(rt,rs2,rt); } } static void emit_or_and_set_flags(int rs1,int rs2,int rt) { emit_or(rs1,rs2,rt); } static void emit_xor(u_int rs1,u_int rs2,u_int rt) { assert(rs1<8); assert(rs2<8); assert(rt<8); if(rs1==rt) { assem_debug("xor %%%s,%%%s",regname[rs2],regname[rt]); output_byte(0x31); output_modrm(3,rs1,rs2); } else if(rs2==rt) { assem_debug("xor %%%s,%%%s",regname[rs1],regname[rt]); output_byte(0x31); output_modrm(3,rs2,rs1); } else { emit_mov(rs1,rt); emit_xor(rt,rs2,rt); } } static void emit_movimm(int imm,u_int rt) { assem_debug("mov $%d,%%%s",imm,regname[rt]); assert(rt<8); output_byte(0xB8+rt); output_w32(imm); } static void emit_addimm(int rs,int imm,int rt) { if(rs==rt) { if(imm!=0) { assem_debug("add $%d,%%%s",imm,regname[rt]); if(imm<128&&imm>=-128) { output_byte(0x83); output_modrm(3,rt,0); output_byte(imm); } else { output_byte(0x81); output_modrm(3,rt,0); output_w32(imm); } } } else { if(imm!=0) { assem_debug("lea %d(%%%s),%%%s",imm,regname[rs],regname[rt]); output_byte(0x8D); if(imm<128&&imm>=-128) { output_modrm(1,rs,rt); output_byte(imm); }else{ output_modrm(2,rs,rt); output_w32(imm); } }else{ emit_mov(rs,rt); } } } static void emit_addimm_and_set_flags(int imm,int rt) { assem_debug("add $%d,%%%s",imm,regname[rt]); if(imm<128&&imm>=-128) { output_byte(0x83); output_modrm(3,rt,0); output_byte(imm); } else { output_byte(0x81); output_modrm(3,rt,0); output_w32(imm); } } static void emit_addimm_no_flags(int imm,int rt) { if(imm!=0) { assem_debug("lea %d(%%%s),%%%s",imm,regname[rt],regname[rt]); output_byte(0x8D); if(imm<128&&imm>=-128) { output_modrm(1,rt,rt); output_byte(imm); }else{ output_modrm(2,rt,rt); output_w32(imm); } } } static void emit_adcimm(int imm,u_int rt) { assem_debug("adc $%d,%%%s",imm,regname[rt]); assert(rt<8); if(imm<128&&imm>=-128) { output_byte(0x83); output_modrm(3,rt,2); output_byte(imm); } else { output_byte(0x81); output_modrm(3,rt,2); output_w32(imm); } } static void emit_sbc(int rs1,int rs2,int rt) { if(rs1==rt) { assem_debug("sbb %%%s,%%%s",regname[rs2],regname[rs1]); output_byte(0x19); output_modrm(3,rs1,rs2); } else if(rs2==rt) { emit_neg(rs2,rs2); emit_adc(rs2,rs1,rs2); } else { emit_mov(rs1,rt); emit_sbc(rt,rs2,rt); } } static void emit_sbbimm(int imm,u_int rt) { assem_debug("sbb $%d,%%%s",imm,regname[rt]); assert(rt<8); if(imm<128&&imm>=-128) { output_byte(0x83); output_modrm(3,rt,3); output_byte(imm); } else { output_byte(0x81); output_modrm(3,rt,3); output_w32(imm); } } static void emit_addimm64_32(int rsh,int rsl,int imm,int rth,int rtl) { if(rsh==rth&&rsl==rtl) { assem_debug("add $%d,%%%s",imm,regname[rtl]); if(imm<128&&imm>=-128) { output_byte(0x83); output_modrm(3,rtl,0); output_byte(imm); } else { output_byte(0x81); output_modrm(3,rtl,0); output_w32(imm); } assem_debug("adc $%d,%%%s",imm>>31,regname[rth]); output_byte(0x83); output_modrm(3,rth,2); output_byte(imm>>31); } else { emit_mov(rsh,rth); emit_mov(rsl,rtl); emit_addimm64_32(rth,rtl,imm,rth,rtl); } } static void emit_sbb(int rs1,int rs2) { assem_debug("sbb %%%s,%%%s",regname[rs1],regname[rs2]); output_byte(0x19); output_modrm(3,rs2,rs1); } static void emit_andimm(int rs,int imm,int rt) { if(imm==0) { emit_zeroreg(rt); } else if(rs==rt) { assem_debug("and $%d,%%%s",imm,regname[rt]); if(imm<128&&imm>=-128) { output_byte(0x83); output_modrm(3,rt,4); output_byte(imm); } else { output_byte(0x81); output_modrm(3,rt,4); output_w32(imm); } } else { emit_mov(rs,rt); emit_andimm(rt,imm,rt); } } static void emit_orimm(int rs,int imm,int rt) { if(rs==rt) { if(imm!=0) { assem_debug("or $%d,%%%s",imm,regname[rt]); if(imm<128&&imm>=-128) { output_byte(0x83); output_modrm(3,rt,1); output_byte(imm); } else { output_byte(0x81); output_modrm(3,rt,1); output_w32(imm); } } } else { emit_mov(rs,rt); emit_orimm(rt,imm,rt); } } static void emit_xorimm(int rs,int imm,int rt) { if(rs==rt) { if(imm!=0) { assem_debug("xor $%d,%%%s",imm,regname[rt]); if(imm<128&&imm>=-128) { output_byte(0x83); output_modrm(3,rt,6); output_byte(imm); } else { output_byte(0x81); output_modrm(3,rt,6); output_w32(imm); } } } else { emit_mov(rs,rt); emit_xorimm(rt,imm,rt); } } static void emit_shlimm(int rs,u_int imm,int rt) { if(rs==rt) { assem_debug("shl %%%s,%d",regname[rt],imm); assert(imm>0); if(imm==1) output_byte(0xD1); else output_byte(0xC1); output_modrm(3,rt,4); if(imm>1) output_byte(imm); } else { emit_mov(rs,rt); emit_shlimm(rt,imm,rt); } } static void emit_shrimm(int rs,u_int imm,int rt) { if(rs==rt) { assem_debug("shr %%%s,%d",regname[rt],imm); assert(imm>0); if(imm==1) output_byte(0xD1); else output_byte(0xC1); output_modrm(3,rt,5); if(imm>1) output_byte(imm); } else { emit_mov(rs,rt); emit_shrimm(rt,imm,rt); } } static void emit_sarimm(int rs,u_int imm,int rt) { if(rs==rt) { assem_debug("sar %%%s,%d",regname[rt],imm); assert(imm>0); if(imm==1) output_byte(0xD1); else output_byte(0xC1); output_modrm(3,rt,7); if(imm>1) output_byte(imm); } else { emit_mov(rs,rt); emit_sarimm(rt,imm,rt); } } static void emit_rorimm(int rs,u_int imm,int rt) { if(rs==rt) { assem_debug("ror %%%s,%d",regname[rt],imm); assert(imm>0); if(imm==1) output_byte(0xD1); else output_byte(0xC1); output_modrm(3,rt,1); if(imm>1) output_byte(imm); } else { emit_mov(rs,rt); emit_rorimm(rt,imm,rt); } } static void emit_shldimm(int rs,int rs2,u_int imm,int rt) { if(rs==rt) { assem_debug("shld %%%s,%%%s,%d",regname[rt],regname[rs2],imm); assert(imm>0); output_byte(0x0F); output_byte(0xA4); output_modrm(3,rt,rs2); output_byte(imm); } else { emit_mov(rs,rt); emit_shldimm(rt,rs2,imm,rt); } } static void emit_shrdimm(int rs,int rs2,u_int imm,int rt) { if(rs==rt) { assem_debug("shrd %%%s,%%%s,%d",regname[rt],regname[rs2],imm); assert(imm>0); output_byte(0x0F); output_byte(0xAC); output_modrm(3,rt,rs2); output_byte(imm); } else { emit_mov(rs,rt); emit_shrdimm(rt,rs2,imm,rt); } } static void emit_shlcl(int r) { assem_debug("shl %%%s,%%cl",regname[r]); output_byte(0xD3); output_modrm(3,r,4); } static void emit_shrcl(int r) { assem_debug("shr %%%s,%%cl",regname[r]); output_byte(0xD3); output_modrm(3,r,5); } static void emit_sarcl(int r) { assem_debug("sar %%%s,%%cl",regname[r]); output_byte(0xD3); output_modrm(3,r,7); } static void emit_shldcl(int r1,int r2) { assem_debug("shld %%%s,%%%s,%%cl",regname[r1],regname[r2]); output_byte(0x0F); output_byte(0xA5); output_modrm(3,r1,r2); } static void emit_shrdcl(int r1,int r2) { assem_debug("shrd %%%s,%%%s,%%cl",regname[r1],regname[r2]); output_byte(0x0F); output_byte(0xAD); output_modrm(3,r1,r2); } static void emit_cmpimm(int rs,int imm) { assem_debug("cmp $%d,%%%s",imm,regname[rs]); if(imm<128&&imm>=-128) { output_byte(0x83); output_modrm(3,rs,7); output_byte(imm); } else { output_byte(0x81); output_modrm(3,rs,7); output_w32(imm); } } static void emit_cmovne(const u_int *addr,int rt) { assem_debug("cmovne %x,%%%s",(int)addr,regname[rt]); if(addr==&const_zero) assem_debug(" [zero]"); else if(addr==&const_one) assem_debug(" [one]"); else assem_debug(""); output_byte(0x0F); output_byte(0x45); output_modrm(0,5,rt); output_w32((int)addr); } static void emit_cmovl(const u_int *addr,int rt) { assem_debug("cmovl %x,%%%s",(int)addr,regname[rt]); if(addr==&const_zero) assem_debug(" [zero]"); else if(addr==&const_one) assem_debug(" [one]"); else assem_debug(""); output_byte(0x0F); output_byte(0x4C); output_modrm(0,5,rt); output_w32((int)addr); } static void emit_cmovs(const u_int *addr,int rt) { assem_debug("cmovs %x,%%%s",(int)addr,regname[rt]); if(addr==&const_zero) assem_debug(" [zero]"); else if(addr==&const_one) assem_debug(" [one]"); else assem_debug(""); output_byte(0x0F); output_byte(0x48); output_modrm(0,5,rt); output_w32((int)addr); } static void emit_cmovne_reg(int rs,int rt) { assem_debug("cmovne %%%s,%%%s",regname[rs],regname[rt]); output_byte(0x0F); output_byte(0x45); output_modrm(3,rs,rt); } static void emit_cmovl_reg(int rs,int rt) { assem_debug("cmovl %%%s,%%%s",regname[rs],regname[rt]); output_byte(0x0F); output_byte(0x4C); output_modrm(3,rs,rt); } static void emit_cmovs_reg(int rs,int rt) { assem_debug("cmovs %%%s,%%%s",regname[rs],regname[rt]); output_byte(0x0F); output_byte(0x48); output_modrm(3,rs,rt); } static void emit_cmovnc_reg(int rs,int rt) { assem_debug("cmovae %%%s,%%%s",regname[rs],regname[rt]); output_byte(0x0F); output_byte(0x43); output_modrm(3,rs,rt); } static void emit_cmova_reg(int rs,int rt) { assem_debug("cmova %%%s,%%%s",regname[rs],regname[rt]); output_byte(0x0F); output_byte(0x47); output_modrm(3,rs,rt); } static void emit_cmovp_reg(int rs,int rt) { assem_debug("cmovp %%%s,%%%s",regname[rs],regname[rt]); output_byte(0x0F); output_byte(0x4A); output_modrm(3,rs,rt); } static void emit_cmovnp_reg(int rs,int rt) { assem_debug("cmovnp %%%s,%%%s",regname[rs],regname[rt]); output_byte(0x0F); output_byte(0x4B); output_modrm(3,rs,rt); } static void emit_setl(int rt) { assem_debug("setl %%%s",regname[rt]); output_byte(0x0F); output_byte(0x9C); output_modrm(3,rt,2); } static void emit_movzbl_reg(int rs, int rt) { assem_debug("movzbl %%%s,%%%s",regname[rs]+1,regname[rt]); output_byte(0x0F); output_byte(0xB6); output_modrm(3,rs,rt); } static void emit_slti32(int rs,int imm,int rt) { if(rs!=rt) emit_zeroreg(rt); emit_cmpimm(rs,imm); if(rt<4) { emit_setl(rt); if(rs==rt) emit_movzbl_reg(rt,rt); } else { if(rs==rt) emit_movimm(0,rt); emit_cmovl(&const_one,rt); } } static void emit_sltiu32(int rs,int imm,int rt) { if(rs!=rt) emit_zeroreg(rt); emit_cmpimm(rs,imm); if(rs==rt) emit_movimm(0,rt); emit_adcimm(0,rt); } static void emit_slti64_32(int rsh,int rsl,int imm,int rt) { assert(rsh!=rt); emit_slti32(rsl,imm,rt); if(imm>=0) { emit_test(rsh,rsh); emit_cmovne(&const_zero,rt); emit_cmovs(&const_one,rt); } else { emit_cmpimm(rsh,-1); emit_cmovne(&const_zero,rt); emit_cmovl(&const_one,rt); } } static void emit_sltiu64_32(int rsh,int rsl,int imm,int rt) { assert(rsh!=rt); emit_sltiu32(rsl,imm,rt); if(imm>=0) { emit_test(rsh,rsh); emit_cmovne(&const_zero,rt); } else { emit_cmpimm(rsh,-1); emit_cmovne(&const_one,rt); } } static void emit_cmp(int rs,int rt) { assem_debug("cmp %%%s,%%%s",regname[rt],regname[rs]); output_byte(0x39); output_modrm(3,rs,rt); } static void emit_set_gz32(int rs, int rt) { //assem_debug("set_gz32"); emit_cmpimm(rs,1); emit_movimm(1,rt); emit_cmovl(&const_zero,rt); } static void emit_set_nz32(int rs, int rt) { //assem_debug("set_nz32"); emit_cmpimm(rs,1); emit_movimm(1,rt); emit_sbbimm(0,rt); } static void emit_set_gz64_32(int rsh, int rsl, int rt) { //assem_debug("set_gz64"); emit_set_gz32(rsl,rt); emit_test(rsh,rsh); emit_cmovne(&const_one,rt); emit_cmovs(&const_zero,rt); } static void emit_set_nz64_32(int rsh, int rsl, int rt) { //assem_debug("set_nz64"); emit_or_and_set_flags(rsh,rsl,rt); emit_cmovne(&const_one,rt); } static void emit_set_if_less32(int rs1, int rs2, int rt) { //assem_debug("set if less (%%%s,%%%s),%%%s",regname[rs1],regname[rs2],regname[rt]); if(rs1!=rt&&rs2!=rt) emit_zeroreg(rt); emit_cmp(rs1,rs2); if(rs1==rt||rs2==rt) emit_movimm(0,rt); emit_cmovl(&const_one,rt); } static void emit_set_if_carry32(int rs1, int rs2, int rt) { //assem_debug("set if carry (%%%s,%%%s),%%%s",regname[rs1],regname[rs2],regname[rt]); if(rs1!=rt&&rs2!=rt) emit_zeroreg(rt); emit_cmp(rs1,rs2); if(rs1==rt||rs2==rt) emit_movimm(0,rt); emit_adcimm(0,rt); } static void emit_set_if_less64_32(int u1, int l1, int u2, int l2, int rt) { //assem_debug("set if less64 (%%%s,%%%s,%%%s,%%%s),%%%s",regname[u1],regname[l1],regname[u2],regname[l2],regname[rt]); assert(u1!=rt); assert(u2!=rt); emit_cmp(l1,l2); emit_mov(u1,rt); emit_sbb(u2,rt); emit_movimm(0,rt); emit_cmovl(&const_one,rt); } static void emit_set_if_carry64_32(int u1, int l1, int u2, int l2, int rt) { //assem_debug("set if carry64 (%%%s,%%%s,%%%s,%%%s),%%%s",regname[u1],regname[l1],regname[u2],regname[l2],regname[rt]); assert(u1!=rt); assert(u2!=rt); emit_cmp(l1,l2); emit_mov(u1,rt); emit_sbb(u2,rt); emit_movimm(0,rt); emit_adcimm(0,rt); } static void emit_call(int a) { assem_debug("call %x (%x+%x)",a,(int)out+5,a-(int)out-5); output_byte(0xe8); output_w32(a-(int)out-4); } static void emit_jmp(int a) { assem_debug("jmp %x (%x+%x)",a,(int)out+5,a-(int)out-5); output_byte(0xe9); output_w32(a-(int)out-4); } static void emit_jne(int a) { assem_debug("jne %x",a); output_byte(0x0f); output_byte(0x85); output_w32(a-(int)out-4); } static void emit_jeq(int a) { assem_debug("jeq %x",a); output_byte(0x0f); output_byte(0x84); output_w32(a-(int)out-4); } static void emit_js(int a) { assem_debug("js %x",a); output_byte(0x0f); output_byte(0x88); output_w32(a-(int)out-4); } static void emit_jns(int a) { assem_debug("jns %x",a); output_byte(0x0f); output_byte(0x89); output_w32(a-(int)out-4); } static void emit_jl(int a) { assem_debug("jl %x",a); output_byte(0x0f); output_byte(0x8c); output_w32(a-(int)out-4); } static void emit_jge(int a) { assem_debug("jge %x",a); output_byte(0x0f); output_byte(0x8d); output_w32(a-(int)out-4); } static void emit_jno(int a) { assem_debug("jno %x",a); output_byte(0x0f); output_byte(0x81); output_w32(a-(int)out-4); } static void emit_jc(int a) { assem_debug("jc %x",a); output_byte(0x0f); output_byte(0x82); output_w32(a-(int)out-4); } static void emit_jae(int a) { assem_debug("jae %x",a); output_byte(0x0f); output_byte(0x83); output_w32(a-(int)out-4); } static void emit_jb(int a) { assem_debug("jb %x",a); output_byte(0x0f); output_byte(0x82); output_w32(a-(int)out-4); } static void emit_pushimm(int imm) { assem_debug("push $%x",imm); output_byte(0x68); output_w32(imm); } static void emit_pushmem(int addr) { assem_debug("push *%x",addr); output_byte(0xFF); output_modrm(0,5,6); output_w32(addr); } static void emit_pusha() { assem_debug("pusha"); output_byte(0x60); } static void emit_popa() { assem_debug("popa"); output_byte(0x61); } static void emit_pushreg(u_int r) { assem_debug("push %%%s",regname[r]); assert(r<8); output_byte(0x50+r); } static void emit_popreg(u_int r) { assem_debug("pop %%%s",regname[r]); assert(r<8); output_byte(0x58+r); } static void emit_callreg(u_int r) { assem_debug("call *%%%s",regname[r]); assert(r<8); output_byte(0xFF); output_modrm(3,r,2); } /*static void emit_jmpreg(u_int r) { assem_debug("jmp *%%%s",regname[r]); assert(r<8); output_byte(0xFF); output_modrm(3,r,4); }*/ static void emit_jmpmem_indexed(u_int addr,u_int r) { assem_debug("jmp *%x(%%%s)",addr,regname[r]); assert(r<8); output_byte(0xFF); output_modrm(2,r,4); output_w32(addr); } static void emit_readword(int addr, int rt) { assem_debug("mov %x,%%%s",addr,regname[rt]); output_byte(0x8B); output_modrm(0,5,rt); output_w32(addr); } static void emit_readword_indexed(int addr, int rs, int rt) { assem_debug("mov %x+%%%s,%%%s",addr,regname[rs],regname[rt]); output_byte(0x8B); if(addr<128&&addr>=-128) { output_modrm(1,rs,rt); if(rs==ESP) output_sib(0,4,4); output_byte(addr); } else { output_modrm(2,rs,rt); if(rs==ESP) output_sib(0,4,4); output_w32(addr); } } static void emit_readword_tlb(int addr, int map, int rt) { if(map<0) emit_readword(addr+(int)g_rdram-0x80000000, rt); else { assem_debug("mov (%x,%%%s,4),%%%s",addr,regname[map],regname[rt]); output_byte(0x8B); output_modrm(0,4,rt); output_sib(2,map,5); output_w32(addr); } } static void emit_readword_indexed_tlb(int addr, int rs, int map, int rt) { if(map<0) emit_readword_indexed(addr+(int)g_rdram-0x80000000, rs, rt); else { assem_debug("mov %x(%%%s,%%%s,4),%%%s",addr,regname[rs],regname[map],regname[rt]); assert(rs!=ESP); output_byte(0x8B); if(addr==0&&rs!=EBP) { output_modrm(0,4,rt); output_sib(2,map,rs); } else if(addr<128&&addr>=-128) { output_modrm(1,4,rt); output_sib(2,map,rs); output_byte(addr); } else { output_modrm(2,4,rt); output_sib(2,map,rs); output_w32(addr); } } } static void emit_movmem_indexedx4(int addr, int rs, int rt) { assem_debug("mov (%x,%%%s,4),%%%s",addr,regname[rs],regname[rt]); output_byte(0x8B); output_modrm(0,4,rt); output_sib(2,rs,5); output_w32(addr); } static void emit_readdword_tlb(int addr, int map, int rh, int rl) { if(map<0) { if(rh>=0) emit_readword(addr+(int)g_rdram-0x80000000, rh); emit_readword(addr+(int)g_rdram-0x7FFFFFFC, rl); } else { if(rh>=0) emit_movmem_indexedx4(addr, map, rh); emit_movmem_indexedx4(addr+4, map, rl); } } static void emit_readdword_indexed_tlb(int addr, int rs, int map, int rh, int rl) { assert(rh!=rs); if(rh>=0) emit_readword_indexed_tlb(addr, rs, map, rh); emit_readword_indexed_tlb(addr+4, rs, map, rl); } static void emit_movsbl(int addr, int rt) { assem_debug("movsbl %x,%%%s",addr,regname[rt]); output_byte(0x0F); output_byte(0xBE); output_modrm(0,5,rt); output_w32(addr); } static void emit_movsbl_indexed(int addr, int rs, int rt) { assem_debug("movsbl %x+%%%s,%%%s",addr,regname[rs],regname[rt]); output_byte(0x0F); output_byte(0xBE); output_modrm(2,rs,rt); output_w32(addr); } static void emit_movsbl_tlb(int addr, int map, int rt) { if(map<0) emit_movsbl(addr+(int)g_rdram-0x80000000, rt); else { assem_debug("movsbl (%x,%%%s,4),%%%s",addr,regname[map],regname[rt]); output_byte(0x0F); output_byte(0xBE); output_modrm(0,4,rt); output_sib(2,map,5); output_w32(addr); } } static void emit_movsbl_indexed_tlb(int addr, int rs, int map, int rt) { if(map<0) emit_movsbl_indexed(addr+(int)g_rdram-0x80000000, rs, rt); else { assem_debug("movsbl %x(%%%s,%%%s,4),%%%s",addr,regname[rs],regname[map],regname[rt]); assert(rs!=ESP); output_byte(0x0F); output_byte(0xBE); if(addr==0&&rs!=EBP) { output_modrm(0,4,rt); output_sib(2,map,rs); } else if(addr<128&&addr>=-128) { output_modrm(1,4,rt); output_sib(2,map,rs); output_byte(addr); } else { output_modrm(2,4,rt); output_sib(2,map,rs); output_w32(addr); } } } static void emit_movswl(int addr, int rt) { assem_debug("movswl %x,%%%s",addr,regname[rt]); output_byte(0x0F); output_byte(0xBF); output_modrm(0,5,rt); output_w32(addr); } static void emit_movswl_indexed(int addr, int rs, int rt) { assem_debug("movswl %x+%%%s,%%%s",addr,regname[rs],regname[rt]); output_byte(0x0F); output_byte(0xBF); output_modrm(2,rs,rt); output_w32(addr); } static void emit_movswl_tlb(int addr, int map, int rt) { if(map<0) emit_movswl(addr+(int)g_rdram-0x80000000, rt); else { assem_debug("movswl (%x,%%%s,4),%%%s",addr,regname[map],regname[rt]); output_byte(0x0F); output_byte(0xBF); output_modrm(0,4,rt); output_sib(2,map,5); output_w32(addr); } } static void emit_movzbl(int addr, int rt) { assem_debug("movzbl %x,%%%s",addr,regname[rt]); output_byte(0x0F); output_byte(0xB6); output_modrm(0,5,rt); output_w32(addr); } static void emit_movzbl_indexed(int addr, int rs, int rt) { assem_debug("movzbl %x+%%%s,%%%s",addr,regname[rs],regname[rt]); output_byte(0x0F); output_byte(0xB6); output_modrm(2,rs,rt); output_w32(addr); } static void emit_movzbl_tlb(int addr, int map, int rt) { if(map<0) emit_movzbl(addr+(int)g_rdram-0x80000000, rt); else { assem_debug("movzbl (%x,%%%s,4),%%%s",addr,regname[map],regname[rt]); output_byte(0x0F); output_byte(0xB6); output_modrm(0,4,rt); output_sib(2,map,5); output_w32(addr); } } static void emit_movzbl_indexed_tlb(int addr, int rs, int map, int rt) { if(map<0) emit_movzbl_indexed(addr+(int)g_rdram-0x80000000, rs, rt); else { assem_debug("movzbl %x(%%%s,%%%s,4),%%%s",addr,regname[rs],regname[map],regname[rt]); assert(rs!=ESP); output_byte(0x0F); output_byte(0xB6); if(addr==0&&rs!=EBP) { output_modrm(0,4,rt); output_sib(2,map,rs); } else if(addr<128&&addr>=-128) { output_modrm(1,4,rt); output_sib(2,map,rs); output_byte(addr); } else { output_modrm(2,4,rt); output_sib(2,map,rs); output_w32(addr); } } } static void emit_movzwl(int addr, int rt) { assem_debug("movzwl %x,%%%s",addr,regname[rt]); output_byte(0x0F); output_byte(0xB7); output_modrm(0,5,rt); output_w32(addr); } static void emit_movzwl_indexed(int addr, int rs, int rt) { assem_debug("movzwl %x+%%%s,%%%s",addr,regname[rs],regname[rt]); output_byte(0x0F); output_byte(0xB7); output_modrm(2,rs,rt); output_w32(addr); } static void emit_movzwl_tlb(int addr, int map, int rt) { if(map<0) emit_movzwl(addr+(int)g_rdram-0x80000000, rt); else { assem_debug("movzwl (%x,%%%s,4),%%%s",addr,regname[map],regname[rt]); output_byte(0x0F); output_byte(0xB7); output_modrm(0,4,rt); output_sib(2,map,5); output_w32(addr); } } /* static void emit_movzwl_reg(int rs, int rt) { assem_debug("movzwl %%%s,%%%s",regname[rs]+1,regname[rt]); output_byte(0x0F); output_byte(0xB7); output_modrm(3,rs,rt); }*/ static void emit_xchg(int rs, int rt) { assem_debug("xchg %%%s,%%%s",regname[rs],regname[rt]); if(rs==EAX) { output_byte(0x90+rt); } else { output_byte(0x87); output_modrm(3,rs,rt); } } static void emit_writeword(int rt, int addr) { assem_debug("movl %%%s,%x",regname[rt],addr); output_byte(0x89); output_modrm(0,5,rt); output_w32(addr); } static void emit_writeword_indexed(int rt, int addr, int rs) { assem_debug("mov %%%s,%x+%%%s",regname[rt],addr,regname[rs]); output_byte(0x89); if(addr<128&&addr>=-128) { output_modrm(1,rs,rt); if(rs==ESP) output_sib(0,4,4); output_byte(addr); } else { output_modrm(2,rs,rt); if(rs==ESP) output_sib(0,4,4); output_w32(addr); } } static void emit_writeword_indexed_tlb(int rt, int addr, int rs, int map, int temp) { if(map<0) emit_writeword_indexed(rt, addr+(int)g_rdram-0x80000000, rs); else { assem_debug("mov %%%s,%x(%%%s,%%%s,1)",regname[rt],addr,regname[rs],regname[map]); assert(rs!=ESP); output_byte(0x89); if(addr==0&&rs!=EBP) { output_modrm(0,4,rt); output_sib(0,map,rs); } else if(addr<128&&addr>=-128) { output_modrm(1,4,rt); output_sib(0,map,rs); output_byte(addr); } else { output_modrm(2,4,rt); output_sib(0,map,rs); output_w32(addr); } } } static void emit_writedword_indexed_tlb(int rh, int rl, int addr, int rs, int map, int temp) { assert(rh>=0); emit_writeword_indexed_tlb(rh, addr, rs, map, temp); emit_writeword_indexed_tlb(rl, addr+4, rs, map, temp); } static void emit_writehword(int rt, int addr) { assem_debug("movw %%%s,%x",regname[rt]+1,addr); output_byte(0x66); output_byte(0x89); output_modrm(0,5,rt); output_w32(addr); } static void emit_writehword_indexed(int rt, int addr, int rs) { assem_debug("movw %%%s,%x+%%%s",regname[rt]+1,addr,regname[rs]); output_byte(0x66); output_byte(0x89); if(addr<128&&addr>=-128) { output_modrm(1,rs,rt); output_byte(addr); } else { output_modrm(2,rs,rt); output_w32(addr); } } static void emit_writebyte(int rt, int addr) { if(rt<4) { assem_debug("movb %%%cl,%x",regname[rt][1],addr); output_byte(0x88); output_modrm(0,5,rt); output_w32(addr); } else { emit_xchg(EAX,rt); emit_writebyte(EAX,addr); emit_xchg(EAX,rt); } } static void emit_writebyte_indexed(int rt, int addr, int rs) { if(rt<4) { assem_debug("movb %%%cl,%x+%%%s",regname[rt][1],addr,regname[rs]); output_byte(0x88); if(addr<128&&addr>=-128) { output_modrm(1,rs,rt); output_byte(addr); } else { output_modrm(2,rs,rt); output_w32(addr); } } else { emit_xchg(EAX,rt); emit_writebyte_indexed(EAX,addr,rs==EAX?rt:rs); emit_xchg(EAX,rt); } } static void emit_writebyte_indexed_tlb(int rt, int addr, int rs, int map, int temp) { if(map<0) emit_writebyte_indexed(rt, addr+(int)g_rdram-0x80000000, rs); else if(rt<4) { assem_debug("movb %%%cl,%x(%%%s,%%%s,1)",regname[rt][1],addr,regname[rs],regname[map]); assert(rs!=ESP); output_byte(0x88); if(addr==0&&rs!=EBP) { output_modrm(0,4,rt); output_sib(0,map,rs); } else if(addr<128&&addr>=-128) { output_modrm(1,4,rt); output_sib(0,map,rs); output_byte(addr); } else { output_modrm(2,4,rt); output_sib(0,map,rs); output_w32(addr); } } else { emit_xchg(EAX,rt); emit_writebyte_indexed_tlb(EAX,addr,rs==EAX?rt:rs,map==EAX?rt:map,temp); emit_xchg(EAX,rt); } } static void emit_writeword_imm(int imm, int addr) { assem_debug("movl $%x,%x",imm,addr); output_byte(0xC7); output_modrm(0,5,0); output_w32(addr); output_w32(imm); } static void emit_writeword_imm_esp(int imm, int addr) { assem_debug("mov $%x,%x(%%esp)",imm,addr); assert(addr>=-128&&addr<128); output_byte(0xC7); output_modrm(1,4,0); output_sib(0,4,4); output_byte(addr); output_w32(imm); } static void emit_writebyte_imm(int imm, int addr) { assem_debug("movb $%x,%x",imm,addr); assert(imm>=-128&&imm<128); output_byte(0xC6); output_modrm(0,5,0); output_w32(addr); output_byte(imm); } static void emit_mul(int rs) { assem_debug("mul %%%s",regname[rs]); output_byte(0xF7); output_modrm(3,rs,4); } static void emit_imul(int rs) { assem_debug("imul %%%s",regname[rs]); output_byte(0xF7); output_modrm(3,rs,5); } static void emit_div(int rs) { assem_debug("div %%%s",regname[rs]); output_byte(0xF7); output_modrm(3,rs,6); } static void emit_idiv(int rs) { assem_debug("idiv %%%s",regname[rs]); output_byte(0xF7); output_modrm(3,rs,7); } static void emit_cdq() { assem_debug("cdq"); output_byte(0x99); } // Load 2 immediates optimizing for small code size static void emit_mov2imm_compact(int imm1,u_int rt1,int imm2,u_int rt2) { emit_movimm(imm1,rt1); if(imm2-imm1<128&&imm2-imm1>=-128) emit_addimm(rt1,imm2-imm1,rt2); else emit_movimm(imm2,rt2); } // special case for checking pending_exception static void emit_cmpmem_imm_byte(int addr,int imm) { assert(imm<128&&imm>=-127); assem_debug("cmpb $%d,%x",imm,addr); output_byte(0x80); output_modrm(0,5,7); output_w32(addr); output_byte(imm); } // special case for checking invalid_code static void emit_cmpmem_indexedsr12_imm(int addr,int r,int imm) { assert(imm<128&&imm>=-127); assert(r>=0&&r<8); emit_shrimm(r,12,r); assem_debug("cmp $%d,%x+%%%s",imm,addr,regname[r]); output_byte(0x80); output_modrm(2,r,7); output_w32(addr); output_byte(imm); } // special case for checking hash_table static void emit_cmpmem_indexed(int addr,int rs,int rt) { assert(rs>=0&&rs<8); assert(rt>=0&&rt<8); assem_debug("cmp %x+%%%s,%%%s",addr,regname[rs],regname[rt]); output_byte(0x39); output_modrm(2,rs,rt); output_w32(addr); } // Used to preload hash table entries #ifdef IMM_PREFETCH static void emit_prefetch(void *addr) { assem_debug("prefetch %x",(int)addr); output_byte(0x0F); output_byte(0x18); output_modrm(0,5,1); output_w32((int)addr); } #endif /*void emit_submem(int r,int addr) { assert(r>=0&&r<8); assem_debug("sub %x,%%%s",addr,regname[r]); output_byte(0x2B); output_modrm(0,5,r); output_w32((int)addr); } static void emit_subfrommem(int addr,int r) { assert(r>=0&&r<8); assem_debug("sub %%%s,%x",regname[r],addr); output_byte(0x29); output_modrm(0,5,r); output_w32((int)addr); }*/ static void emit_readptr(intptr_t addr, int rt) { emit_readword(addr, rt); } static void emit_flds(int r) { assem_debug("flds (%%%s)",regname[r]); output_byte(0xd9); if(r!=EBP) output_modrm(0,r,0); else {output_modrm(1,EBP,0);output_byte(0);} } static void emit_fldl(int r) { assem_debug("fldl (%%%s)",regname[r]); output_byte(0xdd); if(r!=EBP) output_modrm(0,r,0); else {output_modrm(1,EBP,0);output_byte(0);} } static void emit_fucomip(u_int r) { assem_debug("fucomip %d",r); assert(r<8); output_byte(0xdf); output_byte(0xe8+r); } static void emit_fchs() { assem_debug("fchs"); output_byte(0xd9); output_byte(0xe0); } static void emit_fabs() { assem_debug("fabs"); output_byte(0xd9); output_byte(0xe1); } static void emit_fsqrt() { assem_debug("fsqrt"); output_byte(0xd9); output_byte(0xfa); } static void emit_fadds(int r) { assem_debug("fadds (%%%s)",regname[r]); output_byte(0xd8); if(r!=EBP) output_modrm(0,r,0); else {output_modrm(1,EBP,0);output_byte(0);} } static void emit_faddl(int r) { assem_debug("faddl (%%%s)",regname[r]); output_byte(0xdc); if(r!=EBP) output_modrm(0,r,0); else {output_modrm(1,EBP,0);output_byte(0);} } static void emit_fadd(int r) { assem_debug("fadd st%d",r); output_byte(0xd8); output_byte(0xc0+r); } static void emit_fsubs(int r) { assem_debug("fsubs (%%%s)",regname[r]); output_byte(0xd8); if(r!=EBP) output_modrm(0,r,4); else {output_modrm(1,EBP,4);output_byte(0);} } static void emit_fsubl(int r) { assem_debug("fsubl (%%%s)",regname[r]); output_byte(0xdc); if(r!=EBP) output_modrm(0,r,4); else {output_modrm(1,EBP,4);output_byte(0);} } static void emit_fsub(int r) { assem_debug("fsub st%d",r); output_byte(0xd8); output_byte(0xe0+r); } static void emit_fmuls(int r) { assem_debug("fmuls (%%%s)",regname[r]); output_byte(0xd8); if(r!=EBP) output_modrm(0,r,1); else {output_modrm(1,EBP,1);output_byte(0);} } static void emit_fmull(int r) { assem_debug("fmull (%%%s)",regname[r]); output_byte(0xdc); if(r!=EBP) output_modrm(0,r,1); else {output_modrm(1,EBP,1);output_byte(0);} } static void emit_fmul(int r) { assem_debug("fmul st%d",r); output_byte(0xd8); output_byte(0xc8+r); } static void emit_fdivs(int r) { assem_debug("fdivs (%%%s)",regname[r]); output_byte(0xd8); if(r!=EBP) output_modrm(0,r,6); else {output_modrm(1,EBP,6);output_byte(0);} } static void emit_fdivl(int r) { assem_debug("fdivl (%%%s)",regname[r]); output_byte(0xdc); if(r!=EBP) output_modrm(0,r,6); else {output_modrm(1,EBP,6);output_byte(0);} } static void emit_fdiv(int r) { assem_debug("fdiv st%d",r); output_byte(0xd8); output_byte(0xf0+r); } static void emit_fpop() { // fstp st(0) assem_debug("fpop"); output_byte(0xdd); output_byte(0xd8); } static void emit_fildl(int r) { assem_debug("fildl (%%%s)",regname[r]); output_byte(0xdb); if(r!=EBP) output_modrm(0,r,0); else {output_modrm(1,EBP,0);output_byte(0);} } static void emit_fildll(int r) { assem_debug("fildll (%%%s)",regname[r]); output_byte(0xdf); if(r!=EBP) output_modrm(0,r,5); else {output_modrm(1,EBP,5);output_byte(0);} } static void emit_fistpl(int r) { assem_debug("fistpl (%%%s)",regname[r]); output_byte(0xdb); if(r!=EBP) output_modrm(0,r,3); else {output_modrm(1,EBP,3);output_byte(0);} } static void emit_fistpll(int r) { assem_debug("fistpll (%%%s)",regname[r]); output_byte(0xdf); if(r!=EBP) output_modrm(0,r,7); else {output_modrm(1,EBP,7);output_byte(0);} } static void emit_fstps(int r) { assem_debug("fstps (%%%s)",regname[r]); output_byte(0xd9); if(r!=EBP) output_modrm(0,r,3); else {output_modrm(1,EBP,3);output_byte(0);} } static void emit_fstpl(int r) { assem_debug("fstpl (%%%s)",regname[r]); output_byte(0xdd); if(r!=EBP) output_modrm(0,r,3); else {output_modrm(1,EBP,3);output_byte(0);} } static void emit_fnstcw_stack() { assem_debug("fnstcw (%%esp)"); output_byte(0xd9); output_modrm(0,4,7); output_sib(0,4,4); } static void emit_fldcw_stack() { assem_debug("fldcw (%%esp)"); output_byte(0xd9); output_modrm(0,4,5); output_sib(0,4,4); } static void emit_fldcw_indexed(int addr,int r) { assem_debug("fldcw %x(%%%s,2)",addr,regname[r]); output_byte(0xd9); output_modrm(0,4,5); output_sib(1,r,5); output_w32(addr); } static void emit_fldcw(int addr) { assem_debug("fldcw %x",addr); output_byte(0xd9); output_modrm(0,5,5); output_w32(addr); } #ifdef __SSE__ static void emit_movss_load(u_int addr,u_int ssereg) { assem_debug("movss (%%%s),xmm%d",regname[addr],ssereg); assert(ssereg<8); output_byte(0xf3); output_byte(0x0f); output_byte(0x10); if(addr!=EBP) output_modrm(0,addr,ssereg); else {output_modrm(1,EBP,ssereg);output_byte(0);} } static void emit_movsd_load(u_int addr,u_int ssereg) { assem_debug("movsd (%%%s),xmm%d",regname[addr],ssereg); assert(ssereg<8); output_byte(0xf2); output_byte(0x0f); output_byte(0x10); if(addr!=EBP) output_modrm(0,addr,ssereg); else {output_modrm(1,EBP,ssereg);output_byte(0);} } static void emit_movd_store(u_int ssereg,u_int addr) { assem_debug("movd xmm%d,(%%%s)",ssereg,regname[addr]); assert(ssereg<8); output_byte(0x66); output_byte(0x0f); output_byte(0x7e); if(addr!=EBP) output_modrm(0,addr,ssereg); else {output_modrm(1,EBP,ssereg);output_byte(0);} } static void emit_cvttps2dq(u_int ssereg1,u_int ssereg2) { assem_debug("cvttps2dq xmm%d,xmm%d",ssereg1,ssereg2); assert(ssereg1<8); assert(ssereg2<8); output_byte(0xf3); output_byte(0x0f); output_byte(0x5b); output_modrm(3,ssereg1,ssereg2); } static void emit_cvttpd2dq(u_int ssereg1,u_int ssereg2) { assem_debug("cvttpd2dq xmm%d,xmm%d",ssereg1,ssereg2); assert(ssereg1<8); assert(ssereg2<8); output_byte(0x66); output_byte(0x0f); output_byte(0xe6); output_modrm(3,ssereg1,ssereg2); } #endif /* Stubs/epilogue */ static void emit_extjump2(int addr, int target, int linker) { u_char *ptr=(u_char *)addr; if(*ptr==0x0f) { assert(ptr[1]>=0x80&&ptr[1]<=0x8f); addr+=2; } else { assert(*ptr==0xe8||*ptr==0xe9); addr++; } emit_movimm(target,EAX); emit_movimm(addr,EBX); //assert(addr>=0x7000000&&addr<0x7FFFFFF); //assert((target>=0x80000000&&target<0x80800000)||(target>0xA4000000&&target<0xA4001000)); //DEBUG > #ifdef DEBUG_CYCLE_COUNT emit_readword((int)&last_count,ECX); emit_add(HOST_CCREG,ECX,HOST_CCREG); emit_readword((int)&next_interupt,ECX); emit_writeword(HOST_CCREG,(int)&g_cp0_regs[CP0_COUNT_REG]); emit_sub(HOST_CCREG,ECX,HOST_CCREG); emit_writeword(ECX,(int)&last_count); #endif //DEBUG < emit_jmp(linker); } static void emit_extjump(int addr, int target) { emit_extjump2(addr, target, (int)dyna_linker); } static void emit_extjump_ds(int addr, int target) { emit_extjump2(addr, target, (int)dyna_linker_ds); } static void do_readstub(int n) { assem_debug("do_readstub %x",start+stubs[n][3]*4); set_jump_target(stubs[n][1],(int)out); int type=stubs[n][0]; int i=stubs[n][3]; int rs=stubs[n][4]; struct regstat *i_regs=(struct regstat *)stubs[n][5]; signed char *i_regmap=i_regs->regmap; int addr=get_reg(i_regmap,AGEN1+(i&1)); int rth,rt; int ds; if(itype[i]==C1LS||itype[i]==LOADLR) { rth=get_reg(i_regmap,FTEMP|64); rt=get_reg(i_regmap,FTEMP); }else{ rth=get_reg(i_regmap,rt1[i]|64); rt=get_reg(i_regmap,rt1[i]); } assert(rs>=0); if(addr<0) addr=rt; if(addr<0&&itype[i]!=C1LS&&itype[i]!=LOADLR) addr=get_reg(i_regmap,-1); assert(addr>=0); int ftable=0; if(type==LOADB_STUB||type==LOADBU_STUB) ftable=(int)readmemb; if(type==LOADH_STUB||type==LOADHU_STUB) ftable=(int)readmemh; if(type==LOADW_STUB) ftable=(int)readmem; if(type==LOADD_STUB) ftable=(int)readmemd; emit_writeword(rs,(int)&address); emit_shrimm(rs,16,addr); emit_movmem_indexedx4(ftable,addr,addr); emit_pusha(); ds=i_regs!=®s[i]; int real_rs=(itype[i]==LOADLR)?-1:get_reg(i_regmap,rs1[i]); if(!ds) load_all_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty&~(1<regmap_entry,i_regs->was32,i_regs->wasdirty&~(1<>rs1[i])&1)<<1)+ds,32); emit_add(cc,temp,cc); emit_writeword(cc,(int)&g_cp0_regs[CP0_COUNT_REG]); emit_callreg(addr); // We really shouldn't need to update the count here, // but not doing so causes random crashes... emit_readword((int)&g_cp0_regs[CP0_COUNT_REG],HOST_CCREG); emit_readword((int)&next_interupt,ECX); emit_addimm(HOST_CCREG,-CLOCK_DIVIDER*(stubs[n][6]+1),HOST_CCREG); emit_sub(HOST_CCREG,ECX,HOST_CCREG); emit_writeword(ECX,(int)&last_count); emit_storereg(CCREG,HOST_CCREG); emit_popa(); if((cc=get_reg(i_regmap,CCREG))>=0) { emit_loadreg(CCREG,cc); } if(rt>=0) { if(type==LOADB_STUB) emit_movsbl((int)&readmem_dword,rt); if(type==LOADBU_STUB) emit_movzbl((int)&readmem_dword,rt); if(type==LOADH_STUB) emit_movswl((int)&readmem_dword,rt); if(type==LOADHU_STUB) emit_movzwl((int)&readmem_dword,rt); if(type==LOADW_STUB) emit_readword((int)&readmem_dword,rt); if(type==LOADD_STUB) { emit_readword((int)&readmem_dword,rt); if(rth>=0) emit_readword(((int)&readmem_dword)+4,rth); } } emit_jmp(stubs[n][2]); // return address } static void inline_readstub(int type, int i, u_int addr, signed char regmap[], int target, int adj, u_int reglist) { assem_debug("inline_readstub"); int rs=get_reg(regmap,target); int rth=get_reg(regmap,target|64); int rt=get_reg(regmap,target); if(rs<0) rs=get_reg(regmap,-1); assert(rs>=0); int ftable=0; if(type==LOADB_STUB||type==LOADBU_STUB) ftable=(int)readmemb; if(type==LOADH_STUB||type==LOADHU_STUB) ftable=(int)readmemh; if(type==LOADW_STUB) ftable=(int)readmem; if(type==LOADD_STUB) ftable=(int)readmemd; #ifdef HOST_IMM_ADDR32 emit_writeword_imm(addr,(int)&address); #else emit_writeword(rs,(int)&address); #endif emit_pusha(); if((signed int)addr>=(signed int)0xC0000000) { // Theoretically we can have a pagefault here, if the TLB has never // been enabled and the address is outside the range 80000000..BFFFFFFF // Write out the registers so the pagefault can be handled. This is // a very rare case and likely represents a bug. int ds=regmap!=regs[i].regmap; if(!ds) load_all_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty,i); if(!ds) wb_dirtys(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty); else wb_dirtys(branch_regs[i-1].regmap_entry,branch_regs[i-1].was32,branch_regs[i-1].wasdirty); } int cc=get_reg(regmap,CCREG); int temp; if(cc<0) { if(rs==HOST_CCREG) { cc=0;temp=1; assert(cc!=HOST_CCREG); assert(temp!=HOST_CCREG); emit_loadreg(CCREG,cc); } else { cc=HOST_CCREG; emit_loadreg(CCREG,cc); temp=!rs; } } else { temp=!rs; } emit_readword((int)&last_count,temp); emit_addimm(cc,CLOCK_DIVIDER*(adj+1),cc); emit_add(cc,temp,cc); emit_writeword(cc,(int)&g_cp0_regs[CP0_COUNT_REG]); if((signed int)addr>=(signed int)0xC0000000) { // Pagefault address int ds=regmap!=regs[i].regmap; emit_writeword_imm_esp(start+i*4+(((regs[i].was32>>rs1[i])&1)<<1)+ds,32); } emit_call(((u_int *)ftable)[addr>>16]); // We really shouldn't need to update the count here, // but not doing so causes random crashes... emit_readword((int)&g_cp0_regs[CP0_COUNT_REG],HOST_CCREG); emit_readword((int)&next_interupt,ECX); emit_addimm(HOST_CCREG,-CLOCK_DIVIDER*(adj+1),HOST_CCREG); emit_sub(HOST_CCREG,ECX,HOST_CCREG); emit_writeword(ECX,(int)&last_count); emit_storereg(CCREG,HOST_CCREG); emit_popa(); if((cc=get_reg(regmap,CCREG))>=0) { emit_loadreg(CCREG,cc); } if(rt>=0) { if(type==LOADB_STUB) emit_movsbl((int)&readmem_dword,rt); if(type==LOADBU_STUB) emit_movzbl((int)&readmem_dword,rt); if(type==LOADH_STUB) emit_movswl((int)&readmem_dword,rt); if(type==LOADHU_STUB) emit_movzwl((int)&readmem_dword,rt); if(type==LOADW_STUB) emit_readword((int)&readmem_dword,rt); if(type==LOADD_STUB) { emit_readword((int)&readmem_dword,rt); if(rth>=0) emit_readword(((int)&readmem_dword)+4,rth); } } } static void do_writestub(int n) { assem_debug("do_writestub %x",start+stubs[n][3]*4); set_jump_target(stubs[n][1],(int)out); int type=stubs[n][0]; int i=stubs[n][3]; int rs=stubs[n][4]; struct regstat *i_regs=(struct regstat *)stubs[n][5]; signed char *i_regmap=i_regs->regmap; int addr=get_reg(i_regmap,AGEN1+(i&1)); int rth,rt,r; int ds; if(itype[i]==C1LS) { rth=get_reg(i_regmap,FTEMP|64); rt=get_reg(i_regmap,r=FTEMP); }else{ rth=get_reg(i_regmap,rs2[i]|64); rt=get_reg(i_regmap,r=rs2[i]); } assert(rs>=0); assert(rt>=0); if(addr<0) addr=get_reg(i_regmap,-1); assert(addr>=0); int ftable=0; if(type==STOREB_STUB) ftable=(int)writememb; if(type==STOREH_STUB) ftable=(int)writememh; if(type==STOREW_STUB) ftable=(int)writemem; if(type==STORED_STUB) ftable=(int)writememd; emit_writeword(rs,(int)&address); emit_shrimm(rs,16,addr); emit_movmem_indexedx4(ftable,addr,addr); if(type==STOREB_STUB) emit_writebyte(rt,(int)&cpu_byte); if(type==STOREH_STUB) emit_writehword(rt,(int)&hword); if(type==STOREW_STUB) emit_writeword(rt,(int)&word); if(type==STORED_STUB) { emit_writeword(rt,(int)&dword); emit_writeword(r?rth:rt,(int)&dword+4); } emit_pusha(); ds=i_regs!=®s[i]; int real_rs=get_reg(i_regmap,rs1[i]); if(!ds) load_all_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty&~(1<regmap_entry,i_regs->was32,i_regs->wasdirty&~(1<>rs1[i])&1)<<1)+ds,32); emit_add(cc,temp,cc); emit_writeword(cc,(int)&g_cp0_regs[CP0_COUNT_REG]); emit_callreg(addr); emit_readword((int)&g_cp0_regs[CP0_COUNT_REG],HOST_CCREG); emit_readword((int)&next_interupt,ECX); emit_addimm(HOST_CCREG,-CLOCK_DIVIDER*(stubs[n][6]+1),HOST_CCREG); emit_sub(HOST_CCREG,ECX,HOST_CCREG); emit_writeword(ECX,(int)&last_count); emit_storereg(CCREG,HOST_CCREG); emit_popa(); if((cc=get_reg(i_regmap,CCREG))>=0) { emit_loadreg(CCREG,cc); } emit_jmp(stubs[n][2]); // return address } static void inline_writestub(int type, int i, u_int addr, signed char regmap[], int target, int adj, u_int reglist) { assem_debug("inline_writestub"); int rs=get_reg(regmap,-1); int rth=get_reg(regmap,target|64); int rt=get_reg(regmap,target); assert(rs>=0); assert(rt>=0); int ftable=0; if(type==STOREB_STUB) ftable=(int)writememb; if(type==STOREH_STUB) ftable=(int)writememh; if(type==STOREW_STUB) ftable=(int)writemem; if(type==STORED_STUB) ftable=(int)writememd; emit_writeword(rs,(int)&address); if(type==STOREB_STUB) emit_writebyte(rt,(int)&cpu_byte); if(type==STOREH_STUB) emit_writehword(rt,(int)&hword); if(type==STOREW_STUB) emit_writeword(rt,(int)&word); if(type==STORED_STUB) { emit_writeword(rt,(int)&dword); emit_writeword(target?rth:rt,(int)&dword+4); } emit_pusha(); if((signed int)addr>=(signed int)0xC0000000) { // Theoretically we can have a pagefault here, if the TLB has never // been enabled and the address is outside the range 80000000..BFFFFFFF // Write out the registers so the pagefault can be handled. This is // a very rare case and likely represents a bug. int ds=regmap!=regs[i].regmap; if(!ds) load_all_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty,i); if(!ds) wb_dirtys(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty); else wb_dirtys(branch_regs[i-1].regmap_entry,branch_regs[i-1].was32,branch_regs[i-1].wasdirty); } int cc=get_reg(regmap,CCREG); int temp; if(cc<0) { if(rs==HOST_CCREG) { cc=0;temp=1; assert(cc!=HOST_CCREG); assert(temp!=HOST_CCREG); emit_loadreg(CCREG,cc); } else { cc=HOST_CCREG; emit_loadreg(CCREG,cc); temp=!rs; } } else { temp=!rs; } emit_readword((int)&last_count,temp); emit_addimm(cc,CLOCK_DIVIDER*(adj+1),cc); emit_add(cc,temp,cc); emit_writeword(cc,(int)&g_cp0_regs[CP0_COUNT_REG]); if((signed int)addr>=(signed int)0xC0000000) { // Pagefault address int ds=regmap!=regs[i].regmap; emit_writeword_imm_esp(start+i*4+(((regs[i].was32>>rs1[i])&1)<<1)+ds,32); } emit_call(((u_int *)ftable)[addr>>16]); emit_readword((int)&g_cp0_regs[CP0_COUNT_REG],HOST_CCREG); emit_readword((int)&next_interupt,ECX); emit_addimm(HOST_CCREG,-CLOCK_DIVIDER*(adj+1),HOST_CCREG); emit_sub(HOST_CCREG,ECX,HOST_CCREG); emit_writeword(ECX,(int)&last_count); emit_storereg(CCREG,HOST_CCREG); emit_popa(); if((cc=get_reg(regmap,CCREG))>=0) { emit_loadreg(CCREG,cc); } } static void do_unalignedwritestub(int n) { set_jump_target(stubs[n][1],(int)out); output_byte(0xCC); emit_jmp(stubs[n][2]); // return address } static void do_invstub(int n) { set_jump_target(stubs[n][1],(int)out); emit_call(invalidate_block_reg[stubs[n][4]]); emit_jmp(stubs[n][2]); // return address } static int do_dirty_stub(int i) { assem_debug("do_dirty_stub %x",start+i*4); emit_pushimm(start+i*4); emit_movimm((int)start<(int)0xC0000000?(int)source:(int)start,EAX); emit_movimm((int)copy,EBX); emit_movimm(slen*4,ECX); emit_call((int)start<(int)0xC0000000?(int)&verify_code:(int)&verify_code_vm); emit_addimm(ESP,4,ESP); int entry=(int)out; load_regs_entry(i); if(entry==(int)out) entry=instr_addr[i]; emit_jmp(instr_addr[i]); return entry; } static void do_dirty_stub_ds() { emit_pushimm(start+1); emit_movimm((int)start<(int)0xC0000000?(int)source:(int)start,EAX); emit_movimm((int)copy,EBX); emit_movimm(slen*4,ECX); emit_call((int)&verify_code_ds); emit_addimm(ESP,4,ESP); } static void do_cop1stub(int n) { assem_debug("do_cop1stub %x",start+stubs[n][3]*4); set_jump_target(stubs[n][1],(int)out); int i=stubs[n][3]; struct regstat *i_regs=(struct regstat *)stubs[n][5]; int ds=stubs[n][6]; if(!ds) { load_all_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty,i); //if(i_regs!=®s[i]) DebugMessage(M64MSG_VERBOSE, "oops: regs[i]=%x i_regs=%x",(int)®s[i],(int)i_regs); } //else {DebugMessage(M64MSG_VERBOSE, "fp exception in delay slot");} wb_dirtys(i_regs->regmap_entry,i_regs->was32,i_regs->wasdirty); if(regs[i].regmap_entry[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG); emit_movimm(start+(i-ds)*4,EAX); // Get PC emit_addimm(HOST_CCREG,CLOCK_DIVIDER*ccadj[i],HOST_CCREG); // CHECK: is this right? There should probably be an extra cycle... emit_jmp(ds?(int)fp_exception_ds:(int)fp_exception); } /* TLB */ static int do_tlb_r(int s,int ar,int map,int cache,int x,int a,int shift,int c,u_int addr) { if(c) { if((signed int)addr>=(signed int)0xC0000000) { emit_readword((int)(memory_map+(addr>>12)),map); } else return -1; // No mapping } else { if(s!=map) emit_mov(s,map); emit_shrimm(map,12,map); // Schedule this while we wait on the load //if(x) emit_xorimm(addr,x,addr); if(shift>=0) emit_lea8(s,shift); if(~a) emit_andimm(s,a,ar); emit_movmem_indexedx4((int)memory_map,map,map); } return map; } static int do_tlb_r_branch(int map, int c, u_int addr, intptr_t *jaddr) { if(!c||(signed int)addr>=(signed int)0xC0000000) { emit_test(map,map); *jaddr=(intptr_t)out; emit_js(0); } return map; } static void gen_tlb_addr_r(int ar, int map) { if(map>=0) { emit_leairrx4(0,ar,map,ar); } } static int do_tlb_w(int s,int ar,int map,int cache,int x,int c,u_int addr) { if(c) { if(addr<0x80800000||addr>=0xC0000000) { emit_readword((int)(memory_map+(addr>>12)),map); } else return -1; // No mapping } else { if(s!=map) emit_mov(s,map); //if(s!=ar) emit_mov(s,ar); emit_shrimm(map,12,map); // Schedule this while we wait on the load //if(x) emit_xorimm(s,x,addr); emit_movmem_indexedx4((int)memory_map,map,map); } emit_shlimm(map,2,map); return map; } static void do_tlb_w_branch(int map, int c, u_int addr, intptr_t *jaddr) { if(!c||addr<0x80800000||addr>=0xC0000000) { *jaddr=(intptr_t)out; emit_jc(0); } } static void gen_tlb_addr_w(int ar, int map) { if(map>=0) { emit_leairrx1(0,ar,map,ar); } } // We don't need this for x86 static void generate_map_const(u_int addr,int reg) { // void *mapaddr=memory_map+(addr>>12); } /* Special assem */ static void shift_assemble_x86(int i,struct regstat *i_regs) { if(rt1[i]) { if(opcode2[i]<=0x07) // SLLV/SRLV/SRAV { char s,t,shift; t=get_reg(i_regs->regmap,rt1[i]); s=get_reg(i_regs->regmap,rs1[i]); shift=get_reg(i_regs->regmap,rs2[i]); if(t>=0){ if(rs1[i]==0) { emit_zeroreg(t); } else if(rs2[i]==0) { assert(s>=0); if(s!=t) emit_mov(s,t); } else { char temp=get_reg(i_regs->regmap,-1); assert(s>=0); if(t==ECX&&s!=ECX) { if(shift!=ECX) emit_mov(shift,ECX); if(rt1[i]==rs2[i]) {shift=temp;} if(s!=shift) emit_mov(s,shift); } else { if(rt1[i]==rs2[i]) {emit_mov(shift,temp);shift=temp;} if(s!=t) emit_mov(s,t); if(shift!=ECX) { if(i_regs->regmap[ECX]<0) emit_mov(shift,ECX); else emit_xchg(shift,ECX); } } if(opcode2[i]==4) // SLLV { emit_shlcl(t==ECX?shift:t); } if(opcode2[i]==6) // SRLV { emit_shrcl(t==ECX?shift:t); } if(opcode2[i]==7) // SRAV { emit_sarcl(t==ECX?shift:t); } if(shift!=ECX&&i_regs->regmap[ECX]>=0) emit_xchg(shift,ECX); } } } else { // DSLLV/DSRLV/DSRAV char sh,sl,th,tl,shift; th=get_reg(i_regs->regmap,rt1[i]|64); tl=get_reg(i_regs->regmap,rt1[i]); sh=get_reg(i_regs->regmap,rs1[i]|64); sl=get_reg(i_regs->regmap,rs1[i]); shift=get_reg(i_regs->regmap,rs2[i]); if(tl>=0){ if(rs1[i]==0) { emit_zeroreg(tl); if(th>=0) emit_zeroreg(th); } else if(rs2[i]==0) { assert(sl>=0); if(sl!=tl) emit_mov(sl,tl); if(th>=0&&sh!=th) emit_mov(sh,th); } else { // FIXME: What if shift==tl ? assert(shift!=tl); int temp=get_reg(i_regs->regmap,-1); int real_th=th; if(th<0&&opcode2[i]!=0x14) {th=temp;} // DSLLV doesn't need a temporary register assert(sl>=0); assert(sh>=0); if(tl==ECX&&sl!=ECX) { if(shift!=ECX) emit_mov(shift,ECX); if(sl!=shift) emit_mov(sl,shift); if(th>=0 && sh!=th) emit_mov(sh,th); } else if(th==ECX&&sh!=ECX) { if(shift!=ECX) emit_mov(shift,ECX); if(sh!=shift) emit_mov(sh,shift); if(sl!=tl) emit_mov(sl,tl); } else { if(sl!=tl) emit_mov(sl,tl); if(th>=0 && sh!=th) emit_mov(sh,th); if(shift!=ECX) { if(i_regs->regmap[ECX]<0) emit_mov(shift,ECX); else emit_xchg(shift,ECX); } } if(opcode2[i]==0x14) // DSLLV { if(th>=0) emit_shldcl(th==ECX?shift:th,tl==ECX?shift:tl); emit_shlcl(tl==ECX?shift:tl); emit_testimm(ECX,32); if(th>=0) emit_cmovne_reg(tl==ECX?shift:tl,th==ECX?shift:th); emit_cmovne(&const_zero,tl==ECX?shift:tl); } if(opcode2[i]==0x16) // DSRLV { assert(th>=0); emit_shrdcl(tl==ECX?shift:tl,th==ECX?shift:th); emit_shrcl(th==ECX?shift:th); emit_testimm(ECX,32); emit_cmovne_reg(th==ECX?shift:th,tl==ECX?shift:tl); if(real_th>=0) emit_cmovne(&const_zero,th==ECX?shift:th); } if(opcode2[i]==0x17) // DSRAV { assert(th>=0); emit_shrdcl(tl==ECX?shift:tl,th==ECX?shift:th); if(real_th>=0) { assert(temp>=0); emit_mov(th==ECX?shift:th,temp==ECX?shift:temp); } emit_sarcl(th==ECX?shift:th); if(real_th>=0) emit_sarimm(temp==ECX?shift:temp,31,temp==ECX?shift:temp); emit_testimm(ECX,32); emit_cmovne_reg(th==ECX?shift:th,tl==ECX?shift:tl); if(real_th>=0) emit_cmovne_reg(temp==ECX?shift:temp,th==ECX?shift:th); } if(shift!=ECX&&(i_regs->regmap[ECX]>=0||temp==ECX)) emit_xchg(shift,ECX); } } } } } #define shift_assemble shift_assemble_x86 static void loadlr_assemble_x86(int i,struct regstat *i_regs) { int s,th,tl,temp,temp2,addr,map=-1; int offset; intptr_t jaddr=0; int memtarget,c=0; u_int hr,reglist=0; th=get_reg(i_regs->regmap,rt1[i]|64); tl=get_reg(i_regs->regmap,rt1[i]); s=get_reg(i_regs->regmap,rs1[i]); temp=get_reg(i_regs->regmap,-1); temp2=get_reg(i_regs->regmap,FTEMP); addr=get_reg(i_regs->regmap,AGEN1+(i&1)); assert(addr<0); offset=imm[i]; for(hr=0;hrregmap[hr]>=0) reglist|=1<=0) { c=(i_regs->wasconst>>s)&1; memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80800000; if(using_tlb&&((signed int)(constmap[i][s]+offset))>=(signed int)0xC0000000) memtarget=1; } if(!using_tlb) { if(!c) { emit_lea8(addr,temp); if (opcode[i]==0x22||opcode[i]==0x26) { emit_andimm(addr,0xFFFFFFFC,temp2); // LWL/LWR }else{ emit_andimm(addr,0xFFFFFFF8,temp2); // LDL/LDR } emit_cmpimm(addr,0x800000); jaddr=(intptr_t)out; emit_jno(0); } else { if (opcode[i]==0x22||opcode[i]==0x26) { emit_movimm(((constmap[i][s]+offset)<<3)&24,temp); // LWL/LWR }else{ emit_movimm(((constmap[i][s]+offset)<<3)&56,temp); // LDL/LDR } } }else{ // using tlb int a; if(c) { a=-1; }else if (opcode[i]==0x22||opcode[i]==0x26) { a=0xFFFFFFFC; // LWL/LWR }else{ a=0xFFFFFFF8; // LDL/LDR } map=get_reg(i_regs->regmap,TLREG); assert(map>=0); reglist&=~(1<regmap,FTEMP,ccadj[i],reglist); if(rt1[i]) { assert(tl>=0); emit_andimm(temp,24,temp); if (opcode[i]==0x26) emit_xorimm(temp,24,temp); // LWR if(temp==ECX) { int temp3=EDX; if(temp3==temp2) temp3++; emit_pushreg(temp3); emit_movimm(-1,temp3); if (opcode[i]==0x26) { emit_shrcl(temp3); emit_shrcl(temp2); }else{ emit_shlcl(temp3); emit_shlcl(temp2); } emit_mov(temp3,ECX); emit_not(ECX,ECX); emit_popreg(temp3); } else { int temp3=EBP; if(temp3==temp) temp3++; if(temp3==temp2) temp3++; if(temp3==temp) temp3++; emit_xchg(ECX,temp); emit_pushreg(temp3); emit_movimm(-1,temp3); if (opcode[i]==0x26) { emit_shrcl(temp3); emit_shrcl(temp2==ECX?temp:temp2); }else{ emit_shlcl(temp3); emit_shlcl(temp2==ECX?temp:temp2); } emit_not(temp3,temp3); emit_mov(temp,ECX); emit_mov(temp3,temp); emit_popreg(temp3); } emit_and(temp,tl,tl); emit_or(temp2,tl,tl); //emit_storereg(rt1[i],tl); // DEBUG /*emit_pusha(); //save_regs(0x100f); emit_readword((int)&last_count,ECX); if(get_reg(i_regs->regmap,CCREG)<0) emit_loadreg(CCREG,HOST_CCREG); emit_add(HOST_CCREG,ECX,HOST_CCREG); emit_addimm(HOST_CCREG,2*ccadj[i],HOST_CCREG); emit_writeword(HOST_CCREG,(int)&g_cp0_regs[CP0_COUNT_REG]); emit_call((int)memdebug); emit_popa(); //restore_regs(0x100f);*/ } } if (opcode[i]==0x1A||opcode[i]==0x1B) { // LDL/LDR if(s>=0) if((i_regs->wasdirty>>s)&1) emit_storereg(rs1[i],s); if(get_reg(i_regs->regmap,rs1[i]|64)>=0) if((i_regs->wasdirty>>get_reg(i_regs->regmap,rs1[i]|64))&1) emit_storereg(rs1[i]|64,get_reg(i_regs->regmap,rs1[i]|64)); int temp2h=get_reg(i_regs->regmap,FTEMP|64); if(!c||memtarget) { //if(th>=0) emit_readword_indexed((int)g_rdram-0x80000000,temp2,temp2h); //emit_readword_indexed((int)g_rdram-0x7FFFFFFC,temp2,temp2); emit_readdword_indexed_tlb(0,temp2,map,temp2h,temp2); if(jaddr) add_stub(LOADD_STUB,jaddr,(int)out,i,temp2,(int)i_regs,ccadj[i],reglist); } else inline_readstub(LOADD_STUB,i,(constmap[i][s]+offset)&0xFFFFFFF8,i_regs->regmap,FTEMP,ccadj[i],reglist); if(rt1[i]) { assert(th>=0); assert(tl>=0); emit_andimm(temp,56,temp); emit_pushreg(temp); emit_pushreg(temp2h); emit_pushreg(temp2); emit_pushreg(th); emit_pushreg(tl); if(opcode[i]==0x1A) emit_call((int)ldl_merge); if(opcode[i]==0x1B) emit_call((int)ldr_merge); emit_addimm(ESP,20,ESP); if(tl!=EDX) { if(tl!=EAX) emit_mov(EAX,tl); if(th!=EDX) emit_mov(EDX,th); } else if(th!=EAX) { if(th!=EDX) emit_mov(EDX,th); if(tl!=EAX) emit_mov(EAX,tl); } else { emit_xchg(EAX,EDX); } if(s>=0) emit_loadreg(rs1[i],s); if(get_reg(i_regs->regmap,rs1[i]|64)>=0) emit_loadreg(rs1[i]|64,get_reg(i_regs->regmap,rs1[i]|64)); } } } #define loadlr_assemble loadlr_assemble_x86 static void cop0_assemble(int i,struct regstat *i_regs) { if(opcode2[i]==0) // MFC0 { if(rt1[i]) { signed char t=get_reg(i_regs->regmap,rt1[i]); char copr=(source[i]>>11)&0x1f; if(t>=0) { emit_writeword_imm((int)&fake_pc,(int)&PC); emit_writebyte_imm((source[i]>>11)&0x1f,(int)&(fake_pc.f.r.nrd)); if(copr==9) { emit_readword((int)&last_count,ECX); emit_loadreg(CCREG,HOST_CCREG); // TODO: do proper reg alloc emit_add(HOST_CCREG,ECX,HOST_CCREG); emit_addimm(HOST_CCREG,CLOCK_DIVIDER*ccadj[i],HOST_CCREG); emit_writeword(HOST_CCREG,(int)&g_cp0_regs[CP0_COUNT_REG]); } emit_call((int)cached_interpreter_table.MFC0); emit_readword((int)&readmem_dword,t); } } } else if(opcode2[i]==4) // MTC0 { signed char s=get_reg(i_regs->regmap,rs1[i]); char copr=(source[i]>>11)&0x1f; assert(s>=0); emit_writeword(s,(int)&readmem_dword); emit_pusha(); emit_writeword_imm((int)&fake_pc,(int)&PC); emit_writebyte_imm((source[i]>>11)&0x1f,(int)&(fake_pc.f.r.nrd)); if(copr==9||copr==11||copr==12) { if(copr==12&&!is_delayslot) { wb_register(rs1[i],i_regs->regmap,i_regs->dirty,i_regs->is32); } emit_readword((int)&last_count,ECX); emit_loadreg(CCREG,HOST_CCREG); // TODO: do proper reg alloc emit_add(HOST_CCREG,ECX,HOST_CCREG); emit_addimm(HOST_CCREG,CLOCK_DIVIDER*ccadj[i],HOST_CCREG); emit_writeword(HOST_CCREG,(int)&g_cp0_regs[CP0_COUNT_REG]); } // What a mess. The status register (12) can enable interrupts, // so needs a special case to handle a pending interrupt. // The interrupt must be taken immediately, because a subsequent // instruction might disable interrupts again. if(copr==12&&!is_delayslot) { emit_writeword_imm(start+i*4+4,(int)&pcaddr); emit_writebyte_imm(0,(int)&pending_exception); } //else if(copr==12&&is_delayslot) emit_call((int)MTC0_R12); //else emit_call((int)cached_interpreter_table.MTC0); if(copr==9||copr==11||copr==12) { emit_readword((int)&g_cp0_regs[CP0_COUNT_REG],HOST_CCREG); emit_readword((int)&next_interupt,ECX); emit_addimm(HOST_CCREG,-CLOCK_DIVIDER*ccadj[i],HOST_CCREG); emit_sub(HOST_CCREG,ECX,HOST_CCREG); emit_writeword(ECX,(int)&last_count); emit_storereg(CCREG,HOST_CCREG); } emit_popa(); if(copr==12) { assert(!is_delayslot); //if(is_delayslot) output_byte(0xcc); emit_cmpmem_imm_byte((int)&pending_exception,0); emit_jne((int)&do_interrupt); } cop1_usable=0; } else { assert(opcode2[i]==0x10); if((source[i]&0x3f)==0x01) // TLBR emit_call((int)cached_interpreter_table.TLBR); if((source[i]&0x3f)==0x02) // TLBWI emit_call((int)TLBWI_new); if((source[i]&0x3f)==0x06) { // TLBWR // The TLB entry written by TLBWR is dependent on the count, // so update the cycle count emit_readword((int)&last_count,ECX); if(i_regs->regmap[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG); emit_add(HOST_CCREG,ECX,HOST_CCREG); emit_addimm(HOST_CCREG,CLOCK_DIVIDER*ccadj[i],HOST_CCREG); emit_writeword(HOST_CCREG,(int)&g_cp0_regs[CP0_COUNT_REG]); emit_call((int)TLBWR_new); } if((source[i]&0x3f)==0x08) // TLBP emit_call((int)cached_interpreter_table.TLBP); if((source[i]&0x3f)==0x18) // ERET { int count=ccadj[i]; if(i_regs->regmap[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG); emit_addimm_and_set_flags(CLOCK_DIVIDER*count,HOST_CCREG); // TODO: Should there be an extra cycle here? emit_jmp((int)jump_eret); } } } static void cop1_assemble(int i,struct regstat *i_regs) { // Check cop1 unusable if(!cop1_usable) { signed char rs=get_reg(i_regs->regmap,CSREG); assert(rs>=0); emit_testimm(rs,0x20000000); intptr_t jaddr=(intptr_t)out; emit_jeq(0); add_stub(FP_STUB,jaddr,(int)out,i,rs,(int)i_regs,is_delayslot,0); cop1_usable=1; } if (opcode2[i]==0) { // MFC1 signed char tl=get_reg(i_regs->regmap,rt1[i]); if(tl>=0) { emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],tl); emit_readword_indexed(0,tl,tl); } } else if (opcode2[i]==1) { // DMFC1 signed char tl=get_reg(i_regs->regmap,rt1[i]); signed char th=get_reg(i_regs->regmap,rt1[i]|64); if(tl>=0) { emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],tl); if(th>=0) emit_readword_indexed(4,tl,th); emit_readword_indexed(0,tl,tl); } } else if (opcode2[i]==4) { // MTC1 signed char sl=get_reg(i_regs->regmap,rs1[i]); signed char temp=get_reg(i_regs->regmap,-1); emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],temp); emit_writeword_indexed(sl,0,temp); } else if (opcode2[i]==5) { // DMTC1 signed char sl=get_reg(i_regs->regmap,rs1[i]); signed char sh=rs1[i]>0?get_reg(i_regs->regmap,rs1[i]|64):sl; signed char temp=get_reg(i_regs->regmap,-1); emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],temp); emit_writeword_indexed(sh,4,temp); emit_writeword_indexed(sl,0,temp); } else if (opcode2[i]==2) // CFC1 { signed char tl=get_reg(i_regs->regmap,rt1[i]); if(tl>=0) { u_int copr=(source[i]>>11)&0x1f; if(copr==0) emit_readword((int)&FCR0,tl); if(copr==31) emit_readword((int)&FCR31,tl); } } else if (opcode2[i]==6) // CTC1 { signed char sl=get_reg(i_regs->regmap,rs1[i]); u_int copr=(source[i]>>11)&0x1f; assert(sl>=0); if(copr==31) { emit_writeword(sl,(int)&FCR31); // Set the rounding mode char temp=get_reg(i_regs->regmap,-1); emit_movimm(3,temp); emit_and(sl,temp,temp); emit_fldcw_indexed((int)&rounding_modes,temp); } } } static void fconv_assemble_x86(int i,struct regstat *i_regs) { signed char temp=get_reg(i_regs->regmap,-1); assert(temp>=0); // Check cop1 unusable if(!cop1_usable) { signed char rs=get_reg(i_regs->regmap,CSREG); assert(rs>=0); emit_testimm(rs,0x20000000); intptr_t jaddr=(intptr_t)out; emit_jeq(0); add_stub(FP_STUB,jaddr,(int)out,i,rs,(int)i_regs,is_delayslot,0); cop1_usable=1; } #ifdef __SSE__ if(opcode2[i]==0x10&&(source[i]&0x3f)==0x0d) { // trunc_w_s emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],temp); emit_movss_load(temp,0); emit_cvttps2dq(0,0); // float->int, truncate if(((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f)) emit_readword((int)®_cop1_simple[(source[i]>>6)&0x1f],temp); emit_movd_store(0,temp); return; } if(opcode2[i]==0x11&&(source[i]&0x3f)==0x0d) { // trunc_w_d emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],temp); emit_movsd_load(temp,0); emit_cvttpd2dq(0,0); // double->int, truncate emit_readword((int)®_cop1_simple[(source[i]>>6)&0x1f],temp); emit_movd_store(0,temp); return; } #endif if(opcode2[i]==0x14&&(source[i]&0x3f)==0x20) { // cvt_s_w emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],temp); emit_fildl(temp); if(((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f)) emit_readword((int)®_cop1_simple[(source[i]>>6)&0x1f],temp); emit_fstps(temp); return; } if(opcode2[i]==0x14&&(source[i]&0x3f)==0x21) { // cvt_d_w emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],temp); emit_fildl(temp); emit_readword((int)®_cop1_double[(source[i]>>6)&0x1f],temp); emit_fstpl(temp); return; } if(opcode2[i]==0x15&&(source[i]&0x3f)==0x20) { // cvt_s_l emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],temp); emit_fildll(temp); emit_readword((int)®_cop1_simple[(source[i]>>6)&0x1f],temp); emit_fstps(temp); return; } if(opcode2[i]==0x15&&(source[i]&0x3f)==0x21) { // cvt_d_l emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],temp); emit_fildll(temp); if(((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f)) emit_readword((int)®_cop1_double[(source[i]>>6)&0x1f],temp); emit_fstpl(temp); return; } if(opcode2[i]==0x10&&(source[i]&0x3f)==0x21) { // cvt_d_s emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],temp); emit_flds(temp); emit_readword((int)®_cop1_double[(source[i]>>6)&0x1f],temp); emit_fstpl(temp); return; } if(opcode2[i]==0x11&&(source[i]&0x3f)==0x20) { // cvt_s_d emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],temp); emit_fldl(temp); emit_readword((int)®_cop1_simple[(source[i]>>6)&0x1f],temp); emit_fstps(temp); return; } if(opcode2[i]==0x10) { // cvt_*_s emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],temp); emit_flds(temp); } if(opcode2[i]==0x11) { // cvt_*_d emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],temp); emit_fldl(temp); } if((source[i]&0x3f)<0x10) { emit_fnstcw_stack(); if((source[i]&3)==0) emit_fldcw((int)&rounding_modes[0]); //DebugMessage(M64MSG_VERBOSE, "round"); if((source[i]&3)==1) emit_fldcw((int)&rounding_modes[1]); //DebugMessage(M64MSG_VERBOSE, "trunc"); if((source[i]&3)==2) emit_fldcw((int)&rounding_modes[2]); //DebugMessage(M64MSG_VERBOSE, "ceil"); if((source[i]&3)==3) emit_fldcw((int)&rounding_modes[3]); //DebugMessage(M64MSG_VERBOSE, "floor"); } if((source[i]&0x3f)==0x24||(source[i]&0x3c)==0x0c) { // cvt_w_* if(opcode2[i]!=0x10||((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f)) emit_readword((int)®_cop1_simple[(source[i]>>6)&0x1f],temp); emit_fistpl(temp); } if((source[i]&0x3f)==0x25||(source[i]&0x3c)==0x08) { // cvt_l_* if(opcode2[i]!=0x11||((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f)) emit_readword((int)®_cop1_double[(source[i]>>6)&0x1f],temp); emit_fistpll(temp); } if((source[i]&0x3f)<0x10) { emit_fldcw_stack(); } return; // C emulation code for debugging emit_pusha(); if(opcode2[i]==0x14&&(source[i]&0x3f)==0x20) { emit_pushmem((int)®_cop1_simple[(source[i]>> 6)&0x1f]); emit_pushmem((int)®_cop1_simple[(source[i]>>11)&0x1f]); emit_call((int)cvt_s_w); } if(opcode2[i]==0x14&&(source[i]&0x3f)==0x21) { emit_pushmem((int)®_cop1_double[(source[i]>> 6)&0x1f]); emit_pushmem((int)®_cop1_simple[(source[i]>>11)&0x1f]); emit_call((int)cvt_d_w); } if(opcode2[i]==0x15&&(source[i]&0x3f)==0x20) { emit_pushmem((int)®_cop1_simple[(source[i]>> 6)&0x1f]); emit_pushmem((int)®_cop1_double[(source[i]>>11)&0x1f]); emit_call((int)cvt_s_l); } if(opcode2[i]==0x15&&(source[i]&0x3f)==0x21) { emit_pushmem((int)®_cop1_double[(source[i]>> 6)&0x1f]); emit_pushmem((int)®_cop1_double[(source[i]>>11)&0x1f]); emit_call((int)cvt_d_l); } if(opcode2[i]==0x10&&(source[i]&0x3f)==0x21) { emit_pushmem((int)®_cop1_double[(source[i]>> 6)&0x1f]); emit_pushmem((int)®_cop1_simple[(source[i]>>11)&0x1f]); emit_call((int)cvt_d_s); } if(opcode2[i]==0x10&&(source[i]&0x3f)==0x24) { emit_pushmem((int)®_cop1_simple[(source[i]>> 6)&0x1f]); emit_pushmem((int)®_cop1_simple[(source[i]>>11)&0x1f]); emit_call((int)cvt_w_s); } if(opcode2[i]==0x10&&(source[i]&0x3f)==0x25) { emit_pushmem((int)®_cop1_double[(source[i]>> 6)&0x1f]); emit_pushmem((int)®_cop1_simple[(source[i]>>11)&0x1f]); emit_call((int)cvt_l_s); } if(opcode2[i]==0x11&&(source[i]&0x3f)==0x20) { emit_pushmem((int)®_cop1_simple[(source[i]>> 6)&0x1f]); emit_pushmem((int)®_cop1_double[(source[i]>>11)&0x1f]); emit_call((int)cvt_s_d); } if(opcode2[i]==0x11&&(source[i]&0x3f)==0x24) { emit_pushmem((int)®_cop1_simple[(source[i]>> 6)&0x1f]); emit_pushmem((int)®_cop1_double[(source[i]>>11)&0x1f]); emit_call((int)cvt_w_d); } if(opcode2[i]==0x11&&(source[i]&0x3f)==0x25) { emit_pushmem((int)®_cop1_double[(source[i]>> 6)&0x1f]); emit_pushmem((int)®_cop1_double[(source[i]>>11)&0x1f]); emit_call((int)cvt_l_d); } if(opcode2[i]==0x10&&(source[i]&0x3f)==0x08) { emit_pushmem((int)®_cop1_double[(source[i]>> 6)&0x1f]); emit_pushmem((int)®_cop1_simple[(source[i]>>11)&0x1f]); emit_call((int)round_l_s); } if(opcode2[i]==0x10&&(source[i]&0x3f)==0x09) { emit_pushmem((int)®_cop1_double[(source[i]>> 6)&0x1f]); emit_pushmem((int)®_cop1_simple[(source[i]>>11)&0x1f]); emit_call((int)trunc_l_s); } if(opcode2[i]==0x10&&(source[i]&0x3f)==0x0a) { emit_pushmem((int)®_cop1_double[(source[i]>> 6)&0x1f]); emit_pushmem((int)®_cop1_simple[(source[i]>>11)&0x1f]); emit_call((int)ceil_l_s); } if(opcode2[i]==0x10&&(source[i]&0x3f)==0x0b) { emit_pushmem((int)®_cop1_double[(source[i]>> 6)&0x1f]); emit_pushmem((int)®_cop1_simple[(source[i]>>11)&0x1f]); emit_call((int)floor_l_s); } if(opcode2[i]==0x10&&(source[i]&0x3f)==0x0c) { emit_pushmem((int)®_cop1_simple[(source[i]>> 6)&0x1f]); emit_pushmem((int)®_cop1_simple[(source[i]>>11)&0x1f]); emit_call((int)round_w_s); } if(opcode2[i]==0x10&&(source[i]&0x3f)==0x0d) { emit_pushmem((int)®_cop1_simple[(source[i]>> 6)&0x1f]); emit_pushmem((int)®_cop1_simple[(source[i]>>11)&0x1f]); emit_call((int)trunc_w_s); } if(opcode2[i]==0x10&&(source[i]&0x3f)==0x0e) { emit_pushmem((int)®_cop1_simple[(source[i]>> 6)&0x1f]); emit_pushmem((int)®_cop1_simple[(source[i]>>11)&0x1f]); emit_call((int)ceil_w_s); } if(opcode2[i]==0x10&&(source[i]&0x3f)==0x0f) { emit_pushmem((int)®_cop1_simple[(source[i]>> 6)&0x1f]); emit_pushmem((int)®_cop1_simple[(source[i]>>11)&0x1f]); emit_call((int)floor_w_s); } if(opcode2[i]==0x11&&(source[i]&0x3f)==0x08) { emit_pushmem((int)®_cop1_double[(source[i]>> 6)&0x1f]); emit_pushmem((int)®_cop1_double[(source[i]>>11)&0x1f]); emit_call((int)round_l_d); } if(opcode2[i]==0x11&&(source[i]&0x3f)==0x09) { emit_pushmem((int)®_cop1_double[(source[i]>> 6)&0x1f]); emit_pushmem((int)®_cop1_double[(source[i]>>11)&0x1f]); emit_call((int)trunc_l_d); } if(opcode2[i]==0x11&&(source[i]&0x3f)==0x0a) { emit_pushmem((int)®_cop1_double[(source[i]>> 6)&0x1f]); emit_pushmem((int)®_cop1_double[(source[i]>>11)&0x1f]); emit_call((int)ceil_l_d); } if(opcode2[i]==0x11&&(source[i]&0x3f)==0x0b) { emit_pushmem((int)®_cop1_double[(source[i]>> 6)&0x1f]); emit_pushmem((int)®_cop1_double[(source[i]>>11)&0x1f]); emit_call((int)floor_l_d); } if(opcode2[i]==0x11&&(source[i]&0x3f)==0x0c) { emit_pushmem((int)®_cop1_simple[(source[i]>> 6)&0x1f]); emit_pushmem((int)®_cop1_double[(source[i]>>11)&0x1f]); emit_call((int)round_w_d); } if(opcode2[i]==0x11&&(source[i]&0x3f)==0x0d) { emit_pushmem((int)®_cop1_simple[(source[i]>> 6)&0x1f]); emit_pushmem((int)®_cop1_double[(source[i]>>11)&0x1f]); emit_call((int)trunc_w_d); } if(opcode2[i]==0x11&&(source[i]&0x3f)==0x0e) { emit_pushmem((int)®_cop1_simple[(source[i]>> 6)&0x1f]); emit_pushmem((int)®_cop1_double[(source[i]>>11)&0x1f]); emit_call((int)ceil_w_d); } if(opcode2[i]==0x11&&(source[i]&0x3f)==0x0f) { emit_pushmem((int)®_cop1_simple[(source[i]>> 6)&0x1f]); emit_pushmem((int)®_cop1_double[(source[i]>>11)&0x1f]); emit_call((int)floor_w_d); } emit_addimm(ESP,8,ESP); emit_popa(); //emit_loadreg(CSREG,rs); return; } #define fconv_assemble fconv_assemble_x86 static void fcomp_assemble(int i,struct regstat *i_regs) { signed char fs=get_reg(i_regs->regmap,FSREG); signed char temp=get_reg(i_regs->regmap,-1); assert(temp>=0); // Check cop1 unusable if(!cop1_usable) { signed char cs=get_reg(i_regs->regmap,CSREG); assert(cs>=0); emit_testimm(cs,0x20000000); intptr_t jaddr=(intptr_t)out; emit_jeq(0); add_stub(FP_STUB,jaddr,(int)out,i,cs,(int)i_regs,is_delayslot,0); cop1_usable=1; } if((source[i]&0x3f)==0x30) { emit_andimm(fs,~0x800000,fs); return; } if((source[i]&0x3e)==0x38) { // sf/ngle - these should throw exceptions for NaNs emit_andimm(fs,~0x800000,fs); return; } if(opcode2[i]==0x10) { emit_readword((int)®_cop1_simple[(source[i]>>16)&0x1f],temp); emit_flds(temp); emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],temp); emit_flds(temp); emit_movimm(0x800000,temp); emit_or(fs,temp,fs); emit_xor(temp,fs,temp); emit_fucomip(1); emit_fpop(); if((source[i]&0x3f)==0x31) emit_cmovnp_reg(temp,fs); // c_un_s if((source[i]&0x3f)==0x32) {emit_cmovne_reg(temp,fs);emit_cmovp_reg(temp,fs);} // c_eq_s if((source[i]&0x3f)==0x33) emit_cmovne_reg(temp,fs); // c_ueq_s if((source[i]&0x3f)==0x34) {emit_cmovnc_reg(temp,fs);emit_cmovp_reg(temp,fs);} // c_olt_s if((source[i]&0x3f)==0x35) emit_cmovnc_reg(temp,fs); // c_ult_s if((source[i]&0x3f)==0x36) {emit_cmova_reg(temp,fs);emit_cmovp_reg(temp,fs);} // c_ole_s if((source[i]&0x3f)==0x37) emit_cmova_reg(temp,fs); // c_ule_s if((source[i]&0x3f)==0x3a) emit_cmovne_reg(temp,fs); // c_seq_s if((source[i]&0x3f)==0x3b) emit_cmovne_reg(temp,fs); // c_ngl_s if((source[i]&0x3f)==0x3c) emit_cmovnc_reg(temp,fs); // c_lt_s if((source[i]&0x3f)==0x3d) emit_cmovnc_reg(temp,fs); // c_nge_s if((source[i]&0x3f)==0x3e) emit_cmova_reg(temp,fs); // c_le_s if((source[i]&0x3f)==0x3f) emit_cmova_reg(temp,fs); // c_ngt_s return; } if(opcode2[i]==0x11) { emit_readword((int)®_cop1_double[(source[i]>>16)&0x1f],temp); emit_fldl(temp); emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],temp); emit_fldl(temp); emit_movimm(0x800000,temp); emit_or(fs,temp,fs); emit_xor(temp,fs,temp); emit_fucomip(1); emit_fpop(); if((source[i]&0x3f)==0x31) emit_cmovnp_reg(temp,fs); // c_un_d if((source[i]&0x3f)==0x32) {emit_cmovne_reg(temp,fs);emit_cmovp_reg(temp,fs);} // c_eq_d if((source[i]&0x3f)==0x33) emit_cmovne_reg(temp,fs); // c_ueq_d if((source[i]&0x3f)==0x34) {emit_cmovnc_reg(temp,fs);emit_cmovp_reg(temp,fs);} // c_olt_d if((source[i]&0x3f)==0x35) emit_cmovnc_reg(temp,fs); // c_ult_d if((source[i]&0x3f)==0x36) {emit_cmova_reg(temp,fs);emit_cmovp_reg(temp,fs);} // c_ole_d if((source[i]&0x3f)==0x37) emit_cmova_reg(temp,fs); // c_ule_d if((source[i]&0x3f)==0x3a) emit_cmovne_reg(temp,fs); // c_seq_d if((source[i]&0x3f)==0x3b) emit_cmovne_reg(temp,fs); // c_ngl_d if((source[i]&0x3f)==0x3c) emit_cmovnc_reg(temp,fs); // c_lt_d if((source[i]&0x3f)==0x3d) emit_cmovnc_reg(temp,fs); // c_nge_d if((source[i]&0x3f)==0x3e) emit_cmova_reg(temp,fs); // c_le_d if((source[i]&0x3f)==0x3f) emit_cmova_reg(temp,fs); // c_ngt_d return; } emit_pusha(); if(opcode2[i]==0x10) { emit_pushmem((int)®_cop1_simple[(source[i]>>16)&0x1f]); emit_pushmem((int)®_cop1_simple[(source[i]>>11)&0x1f]); if((source[i]&0x3f)==0x30) emit_call((int)c_f_s); if((source[i]&0x3f)==0x31) emit_call((int)c_un_s); if((source[i]&0x3f)==0x32) emit_call((int)c_eq_s); if((source[i]&0x3f)==0x33) emit_call((int)c_ueq_s); if((source[i]&0x3f)==0x34) emit_call((int)c_olt_s); if((source[i]&0x3f)==0x35) emit_call((int)c_ult_s); if((source[i]&0x3f)==0x36) emit_call((int)c_ole_s); if((source[i]&0x3f)==0x37) emit_call((int)c_ule_s); if((source[i]&0x3f)==0x38) emit_call((int)c_sf_s); if((source[i]&0x3f)==0x39) emit_call((int)c_ngle_s); if((source[i]&0x3f)==0x3a) emit_call((int)c_seq_s); if((source[i]&0x3f)==0x3b) emit_call((int)c_ngl_s); if((source[i]&0x3f)==0x3c) emit_call((int)c_lt_s); if((source[i]&0x3f)==0x3d) emit_call((int)c_nge_s); if((source[i]&0x3f)==0x3e) emit_call((int)c_le_s); if((source[i]&0x3f)==0x3f) emit_call((int)c_ngt_s); } if(opcode2[i]==0x11) { emit_pushmem((int)®_cop1_double[(source[i]>>16)&0x1f]); emit_pushmem((int)®_cop1_double[(source[i]>>11)&0x1f]); if((source[i]&0x3f)==0x30) emit_call((int)c_f_d); if((source[i]&0x3f)==0x31) emit_call((int)c_un_d); if((source[i]&0x3f)==0x32) emit_call((int)c_eq_d); if((source[i]&0x3f)==0x33) emit_call((int)c_ueq_d); if((source[i]&0x3f)==0x34) emit_call((int)c_olt_d); if((source[i]&0x3f)==0x35) emit_call((int)c_ult_d); if((source[i]&0x3f)==0x36) emit_call((int)c_ole_d); if((source[i]&0x3f)==0x37) emit_call((int)c_ule_d); if((source[i]&0x3f)==0x38) emit_call((int)c_sf_d); if((source[i]&0x3f)==0x39) emit_call((int)c_ngle_d); if((source[i]&0x3f)==0x3a) emit_call((int)c_seq_d); if((source[i]&0x3f)==0x3b) emit_call((int)c_ngl_d); if((source[i]&0x3f)==0x3c) emit_call((int)c_lt_d); if((source[i]&0x3f)==0x3d) emit_call((int)c_nge_d); if((source[i]&0x3f)==0x3e) emit_call((int)c_le_d); if((source[i]&0x3f)==0x3f) emit_call((int)c_ngt_d); } emit_addimm(ESP,8,ESP); emit_popa(); emit_loadreg(FSREG,fs); return; } static void float_assemble(int i,struct regstat *i_regs) { signed char temp=get_reg(i_regs->regmap,-1); assert(temp>=0); // Check cop1 unusable if(!cop1_usable) { signed char cs=get_reg(i_regs->regmap,CSREG); assert(cs>=0); emit_testimm(cs,0x20000000); intptr_t jaddr=(intptr_t)out; emit_jeq(0); add_stub(FP_STUB,jaddr,(int)out,i,cs,(int)i_regs,is_delayslot,0); cop1_usable=1; } if((source[i]&0x3f)==6) // mov { if(((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f)) { if(opcode2[i]==0x10) { emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],temp); emit_flds(temp); emit_readword((int)®_cop1_simple[(source[i]>>6)&0x1f],temp); emit_fstps(temp); } if(opcode2[i]==0x11) { emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],temp); emit_fldl(temp); emit_readword((int)®_cop1_double[(source[i]>>6)&0x1f],temp); emit_fstpl(temp); } } return; } if((source[i]&0x3f)>3) { if(opcode2[i]==0x10) { emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],temp); emit_flds(temp); if(((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f)) { emit_readword((int)®_cop1_simple[(source[i]>>6)&0x1f],temp); } } if(opcode2[i]==0x11) { emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],temp); emit_fldl(temp); if(((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f)) { emit_readword((int)®_cop1_double[(source[i]>>6)&0x1f],temp); } } if((source[i]&0x3f)==4) // sqrt emit_fsqrt(); if((source[i]&0x3f)==5) // abs emit_fabs(); if((source[i]&0x3f)==7) // neg emit_fchs(); if(opcode2[i]==0x10) { emit_fstps(temp); } if(opcode2[i]==0x11) { emit_fstpl(temp); } return; } if((source[i]&0x3f)<4) { if(opcode2[i]==0x10) { emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],temp); emit_flds(temp); } if(opcode2[i]==0x11) { emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],temp); emit_fldl(temp); } if(((source[i]>>11)&0x1f)!=((source[i]>>16)&0x1f)) { if(opcode2[i]==0x10) { emit_readword((int)®_cop1_simple[(source[i]>>16)&0x1f],temp); if((source[i]&0x3f)==0) emit_fadds(temp); if((source[i]&0x3f)==1) emit_fsubs(temp); if((source[i]&0x3f)==2) emit_fmuls(temp); if((source[i]&0x3f)==3) emit_fdivs(temp); } else if(opcode2[i]==0x11) { emit_readword((int)®_cop1_double[(source[i]>>16)&0x1f],temp); if((source[i]&0x3f)==0) emit_faddl(temp); if((source[i]&0x3f)==1) emit_fsubl(temp); if((source[i]&0x3f)==2) emit_fmull(temp); if((source[i]&0x3f)==3) emit_fdivl(temp); } } else { if((source[i]&0x3f)==0) emit_fadd(0); if((source[i]&0x3f)==1) emit_fsub(0); if((source[i]&0x3f)==2) emit_fmul(0); if((source[i]&0x3f)==3) emit_fdiv(0); } if(opcode2[i]==0x10) { if(((source[i]>>16)&0x1f)!=((source[i]>>6)&0x1f)) { emit_readword((int)®_cop1_simple[(source[i]>>6)&0x1f],temp); } emit_fstps(temp); } if(opcode2[i]==0x11) { if(((source[i]>>16)&0x1f)!=((source[i]>>6)&0x1f)) { emit_readword((int)®_cop1_double[(source[i]>>6)&0x1f],temp); } emit_fstpl(temp); } return; } if(opcode2[i]==0x10) { // Single precision emit_pusha(); emit_pushmem((int)®_cop1_simple[(source[i]>> 6)&0x1f]); if((source[i]&0x3f)<4) emit_pushmem((int)®_cop1_simple[(source[i]>>16)&0x1f]); emit_pushmem((int)®_cop1_simple[(source[i]>>11)&0x1f]); switch(source[i]&0x3f) { case 0x00: emit_call((int)add_s);break; case 0x01: emit_call((int)sub_s);break; case 0x02: emit_call((int)mul_s);break; case 0x03: emit_call((int)div_s);break; case 0x04: emit_call((int)sqrt_s);break; case 0x05: emit_call((int)abs_s);break; case 0x06: emit_call((int)mov_s);break; case 0x07: emit_call((int)neg_s);break; } emit_addimm(ESP,(source[i]&0x3f)<4?12:8,ESP); emit_popa(); } if(opcode2[i]==0x11) { // Double precision emit_pusha(); emit_pushmem((int)®_cop1_double[(source[i]>> 6)&0x1f]); if((source[i]&0x3f)<4) emit_pushmem((int)®_cop1_double[(source[i]>>16)&0x1f]); emit_pushmem((int)®_cop1_double[(source[i]>>11)&0x1f]); switch(source[i]&0x3f) { case 0x00: emit_call((int)add_d);break; case 0x01: emit_call((int)sub_d);break; case 0x02: emit_call((int)mul_d);break; case 0x03: emit_call((int)div_d);break; case 0x04: emit_call((int)sqrt_d);break; case 0x05: emit_call((int)abs_d);break; case 0x06: emit_call((int)mov_d);break; case 0x07: emit_call((int)neg_d);break; } emit_addimm(ESP,(source[i]&0x3f)<4?12:8,ESP); emit_popa(); } } static void multdiv_assemble_x86(int i,struct regstat *i_regs) { // case 0x18: MULT // case 0x19: MULTU // case 0x1A: DIV // case 0x1B: DIVU // case 0x1C: DMULT // case 0x1D: DMULTU // case 0x1E: DDIV // case 0x1F: DDIVU if(rs1[i]&&rs2[i]) { if((opcode2[i]&4)==0) // 32-bit { if(opcode2[i]==0x18) // MULT { char m1=get_reg(i_regs->regmap,rs1[i]); char m2=get_reg(i_regs->regmap,rs2[i]); assert(m1>=0); assert(m2>=0); emit_mov(m1,EAX); emit_imul(m2); } if(opcode2[i]==0x19) // MULTU { char m1=get_reg(i_regs->regmap,rs1[i]); char m2=get_reg(i_regs->regmap,rs2[i]); assert(m1>=0); assert(m2>=0); emit_mov(m1,EAX); emit_mul(m2); } if(opcode2[i]==0x1A) // DIV { char d1=get_reg(i_regs->regmap,rs1[i]); char d2=get_reg(i_regs->regmap,rs2[i]); assert(d1>=0); assert(d2>=0); emit_mov(d1,EAX); emit_cdq(); emit_test(d2,d2); emit_jeq((int)out+8); emit_idiv(d2); } if(opcode2[i]==0x1B) // DIVU { char d1=get_reg(i_regs->regmap,rs1[i]); char d2=get_reg(i_regs->regmap,rs2[i]); assert(d1>=0); assert(d2>=0); emit_mov(d1,EAX); emit_zeroreg(EDX); emit_test(d2,d2); emit_jeq((int)out+8); emit_div(d2); } } else // 64-bit { if(opcode2[i]==0x1C) // DMULT { char m1h=get_reg(i_regs->regmap,rs1[i]|64); char m1l=get_reg(i_regs->regmap,rs1[i]); char m2h=get_reg(i_regs->regmap,rs2[i]|64); char m2l=get_reg(i_regs->regmap,rs2[i]); assert(m1h>=0); assert(m2h>=0); assert(m1l>=0); assert(m2l>=0); emit_pushreg(m2h); emit_pushreg(m2l); emit_pushreg(m1h); emit_pushreg(m1l); emit_call((int)&mult64); emit_popreg(m1l); emit_popreg(m1h); emit_popreg(m2l); emit_popreg(m2h); char hih=get_reg(i_regs->regmap,HIREG|64); char hil=get_reg(i_regs->regmap,HIREG); if(hih>=0) emit_loadreg(HIREG|64,hih); if(hil>=0) emit_loadreg(HIREG,hil); char loh=get_reg(i_regs->regmap,LOREG|64); char lol=get_reg(i_regs->regmap,LOREG); if(loh>=0) emit_loadreg(LOREG|64,loh); if(lol>=0) emit_loadreg(LOREG,lol); } if(opcode2[i]==0x1D) // DMULTU { char m1h=get_reg(i_regs->regmap,rs1[i]|64); char m1l=get_reg(i_regs->regmap,rs1[i]); char m2h=get_reg(i_regs->regmap,rs2[i]|64); char m2l=get_reg(i_regs->regmap,rs2[i]); // DEBUG emit_pushreg(m2h); emit_pushreg(m2l); emit_pushreg(m1h); emit_pushreg(m1l); emit_call((int)&multu64); emit_popreg(m1l); emit_popreg(m1h); emit_popreg(m2l); emit_popreg(m2h); char hih=get_reg(i_regs->regmap,HIREG|64); char hil=get_reg(i_regs->regmap,HIREG); if(hih>=0) emit_loadreg(HIREG|64,hih); // DEBUG if(hil>=0) emit_loadreg(HIREG,hil); // DEBUG // Shouldn't be necessary //char loh=get_reg(i_regs->regmap,LOREG|64); //char lol=get_reg(i_regs->regmap,LOREG); //if(loh>=0) emit_loadreg(LOREG|64,loh); //if(lol>=0) emit_loadreg(LOREG,lol); } if(opcode2[i]==0x1E) // DDIV { char d1h=get_reg(i_regs->regmap,rs1[i]|64); char d1l=get_reg(i_regs->regmap,rs1[i]); char d2h=get_reg(i_regs->regmap,rs2[i]|64); char d2l=get_reg(i_regs->regmap,rs2[i]); assert(d1h>=0); assert(d2h>=0); assert(d1l>=0); assert(d2l>=0); //emit_pushreg(d2h); //emit_pushreg(d2l); //emit_pushreg(d1h); //emit_pushreg(d1l); emit_addimm(ESP,-16,ESP); emit_writeword_indexed(d2h,12,ESP); emit_writeword_indexed(d2l,8,ESP); emit_writeword_indexed(d1h,4,ESP); emit_writeword_indexed(d1l,0,ESP); emit_call((int)&div64); //emit_popreg(d1l); //emit_popreg(d1h); //emit_popreg(d2l); //emit_popreg(d2h); emit_readword_indexed(0,ESP,d1l); emit_readword_indexed(4,ESP,d1h); emit_readword_indexed(8,ESP,d2l); emit_readword_indexed(12,ESP,d2h); emit_addimm(ESP,16,ESP); char hih=get_reg(i_regs->regmap,HIREG|64); char hil=get_reg(i_regs->regmap,HIREG); char loh=get_reg(i_regs->regmap,LOREG|64); char lol=get_reg(i_regs->regmap,LOREG); if(hih>=0) emit_loadreg(HIREG|64,hih); if(hil>=0) emit_loadreg(HIREG,hil); if(loh>=0) emit_loadreg(LOREG|64,loh); if(lol>=0) emit_loadreg(LOREG,lol); } if(opcode2[i]==0x1F) // DDIVU { char d1h=get_reg(i_regs->regmap,rs1[i]|64); char d1l=get_reg(i_regs->regmap,rs1[i]); char d2h=get_reg(i_regs->regmap,rs2[i]|64); char d2l=get_reg(i_regs->regmap,rs2[i]); assert(d1h>=0); assert(d2h>=0); assert(d1l>=0); assert(d2l>=0); //emit_pushreg(d2h); //emit_pushreg(d2l); //emit_pushreg(d1h); //emit_pushreg(d1l); emit_addimm(ESP,-16,ESP); emit_writeword_indexed(d2h,12,ESP); emit_writeword_indexed(d2l,8,ESP); emit_writeword_indexed(d1h,4,ESP); emit_writeword_indexed(d1l,0,ESP); emit_call((int)&divu64); //emit_popreg(d1l); //emit_popreg(d1h); //emit_popreg(d2l); //emit_popreg(d2h); emit_readword_indexed(0,ESP,d1l); emit_readword_indexed(4,ESP,d1h); emit_readword_indexed(8,ESP,d2l); emit_readword_indexed(12,ESP,d2h); emit_addimm(ESP,16,ESP); char hih=get_reg(i_regs->regmap,HIREG|64); char hil=get_reg(i_regs->regmap,HIREG); char loh=get_reg(i_regs->regmap,LOREG|64); char lol=get_reg(i_regs->regmap,LOREG); if(hih>=0) emit_loadreg(HIREG|64,hih); if(hil>=0) emit_loadreg(HIREG,hil); if(loh>=0) emit_loadreg(LOREG|64,loh); if(lol>=0) emit_loadreg(LOREG,lol); } } } else { // Multiply by zero is zero. // MIPS does not have a divide by zero exception. // The result is undefined, we return zero. char hr=get_reg(i_regs->regmap,HIREG); char lr=get_reg(i_regs->regmap,LOREG); if(hr>=0) emit_zeroreg(hr); if(lr>=0) emit_zeroreg(lr); } } #define multdiv_assemble multdiv_assemble_x86 static void do_preload_rhash(int r) { emit_movimm(0xf8,r); } static void do_preload_rhtbl(int r) { // Don't need this for x86 } static void do_rhash(int rs,int rh) { emit_and(rs,rh,rh); } static void do_miniht_load(int ht,int rh) { // Don't need this for x86. The load and compare can be combined into // a single instruction (below) } static void do_miniht_jump(int rs,int rh,int ht) { emit_cmpmem_indexed((int)mini_ht,rh,rs); emit_jne(jump_vaddr_reg[rs]); emit_jmpmem_indexed((int)mini_ht+4,rh); } static void do_miniht_insert(int return_address,int rt,int temp) { emit_movimm(return_address,rt); // PC into link register //emit_writeword_imm(return_address,(int)&mini_ht[(return_address&0xFF)>>8][0]); emit_writeword(rt,(int)&mini_ht[(return_address&0xFF)>>3][0]); add_to_linker((int)out,return_address,1); emit_writeword_imm(0,(int)&mini_ht[(return_address&0xFF)>>3][1]); } // We don't need this for x86 static void literal_pool(int n) {} static void literal_pool_jumpover(int n) {} // CPU-architecture-specific initialization, not needed for x86 static void arch_init() {} libretro/msvc/GL/000700 001750 001750 00000000000 12656647145 015002 5ustar00sergiosergio000000 000000 mupen64plus-core/src/pi/sram.c000664 001750 001750 00000005224 12655644434 017357 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - sram.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "sram.h" #include "pi_controller.h" #include "memory/memory.h" #include "ri/ri_controller.h" #include #include #include void sram_save(struct sram* sram) { sram->save(sram->user_data); } void format_sram(uint8_t* sram) { memset(sram, 0, SRAM_SIZE); } void dma_write_sram(struct pi_controller* pi) { size_t i; size_t length = (pi->regs[PI_RD_LEN_REG] & 0xffffff) + 1; uint8_t* sram = pi->sram.data; uint8_t* dram = (uint8_t*)pi->ri->rdram.dram; uint32_t cart_addr = pi->regs[PI_CART_ADDR_REG] - 0x08000000; uint32_t dram_addr = pi->regs[PI_DRAM_ADDR_REG]; for(i = 0; i < length; ++i) sram[(cart_addr+i)^S8] = dram[(dram_addr+i)^S8]; sram_save(&pi->sram); } void dma_read_sram(struct pi_controller* pi) { size_t i; size_t length = (pi->regs[PI_WR_LEN_REG] & 0xffffff) + 1; uint8_t* sram = pi->sram.data; uint8_t* dram = (uint8_t*)pi->ri->rdram.dram; uint32_t cart_addr = (pi->regs[PI_CART_ADDR_REG] - 0x08000000) & 0xffff; uint32_t dram_addr = pi->regs[PI_DRAM_ADDR_REG]; for(i = 0; i < length; ++i) dram[(dram_addr+i)^S8] = sram[(cart_addr+i)^S8]; } mupen64plus-video-gliden64/src/GLideNHQ/bldno.cpp000664 001750 001750 00000001141 12655644434 022560 0ustar00sergiosergio000000 000000 #include #include #include int main (void) { struct tm locTime; time_t sysTime; char *build; time(&sysTime); locTime = *localtime(&sysTime); if ((build = getenv("BUILD_NUMBER")) != NULL) { printf("#define BUILD_NUMBER %s\n", build); printf("#define BUILD_NUMBER_STR \"%s\"\n", build); } else { unsigned short magic; magic = (locTime.tm_yday << 7) | (locTime.tm_hour << 2) | (locTime.tm_min / 15); printf("#define BUILD_NUMBER %d\n", magic); printf("#define BUILD_NUMBER_STR \"%d\"\n", magic); } return 0; } mupen64plus-video-gliden64/src/F3DEX.h000664 001750 001750 00000002713 12655644434 020413 0ustar00sergiosergio000000 000000 #ifndef F3DEX_H #define F3DEX_H #define F3DEX_MTX_STACKSIZE 18 #define F3DEX_MTX_MODELVIEW 0x00 #define F3DEX_MTX_PROJECTION 0x01 #define F3DEX_MTX_MUL 0x00 #define F3DEX_MTX_LOAD 0x02 #define F3DEX_MTX_NOPUSH 0x00 #define F3DEX_MTX_PUSH 0x04 #define F3DEX_TEXTURE_ENABLE 0x00000002 #define F3DEX_SHADING_SMOOTH 0x00000200 #define F3DEX_CULL_FRONT 0x00001000 #define F3DEX_CULL_BACK 0x00002000 #define F3DEX_CULL_BOTH 0x00003000 #define F3DEX_CLIPPING 0x00800000 #define F3DEX_MV_VIEWPORT 0x80 #define F3DEX_MWO_aLIGHT_1 0x00 #define F3DEX_MWO_bLIGHT_1 0x04 #define F3DEX_MWO_aLIGHT_2 0x20 #define F3DEX_MWO_bLIGHT_2 0x24 #define F3DEX_MWO_aLIGHT_3 0x40 #define F3DEX_MWO_bLIGHT_3 0x44 #define F3DEX_MWO_aLIGHT_4 0x60 #define F3DEX_MWO_bLIGHT_4 0x64 #define F3DEX_MWO_aLIGHT_5 0x80 #define F3DEX_MWO_bLIGHT_5 0x84 #define F3DEX_MWO_aLIGHT_6 0xa0 #define F3DEX_MWO_bLIGHT_6 0xa4 #define F3DEX_MWO_aLIGHT_7 0xc0 #define F3DEX_MWO_bLIGHT_7 0xc4 #define F3DEX_MWO_aLIGHT_8 0xe0 #define F3DEX_MWO_bLIGHT_8 0xe4 // F3DEX commands #define F3DEX_MODIFYVTX 0xB2 #define F3DEX_TRI2 0xB1 #define F3DEX_BRANCH_Z 0xB0 #define F3DEX_LOAD_UCODE 0xAF // 0xCF void F3DEX_Vtx( u32 w0, u32 w1 ); void F3DEX_Tri1( u32 w0, u32 w1 ); void F3DEX_CullDL( u32 w0, u32 w1 ); void F3DEX_ModifyVtx( u32 w0, u32 w1 ); void F3DEX_Tri2( u32 w0, u32 w1 ); void F3DEX_Branch_Z( u32 w0, u32 w1 ); void F3DEX_Load_uCode( u32 w0, u32 w1 ); void F3DEX_Init(); #endif glide2gl/src/Glide64/Util.h000664 001750 001750 00000005630 12655644434 016467 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** #ifndef Util_H #define Util_H #include "../../../mupen64plus-core/src/main/util.h" #define NOT_TMU0 0x00 #define NOT_TMU1 0x01 #define NOT_TMU2 0x02 void do_triangle_stuff(uint16_t linew, int old_interpolate); void do_triangle_stuff_2(uint16_t linew, uint8_t no_clip, int old_interpolate); void apply_shade_mods(VERTEX *v); void update(void); void update_scissor(bool set_scissor); float ScaleZ(float z); // rotate left #define __ROL__(value, count, nbits) ((value << (count % (nbits))) | (value >> ((nbits) - (count % (nbits))))) static INLINE uint32_t rol32(uint32_t value, uint32_t amount) { return (value << amount) | (value >> (-(int32_t)amount & 31)); } static INLINE uint32_t ror32(uint32_t value, uint32_t amount) { return (value << (-(int32_t)amount & 31)) | (value >> amount); } static INLINE uint16_t rol16(uint16_t value, uint16_t amount) { return (value << amount) | (value >> (-(int16_t)amount & 15)); } static INLINE uint16_t ror16(uint16_t value, uint16_t amount) { return (value << (-(int16_t)amount & 15)) | (value >> amount); } #endif // ifndef Util_H gles2rice/src/OGLCombiner.cpp000664 001750 001750 00000016500 12655644434 017173 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - OGLCombiner.cpp * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2003 Rice1964 * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "osal_opengl.h" #include "OGLCombiner.h" #include "OGLDebug.h" #include "OGLRender.h" #include "OGLGraphicsContext.h" #include "OGLDecodedMux.h" #include "OGLTexture.h" //======================================================================== uint32_t DirectX_OGL_BlendFuncMaps [] = { GL_SRC_ALPHA, //Nothing GL_ZERO, //BLEND_ZERO = 1, GL_ONE, //BLEND_ONE = 2, GL_SRC_COLOR, //BLEND_SRCCOLOR = 3, GL_ONE_MINUS_SRC_COLOR, //BLEND_INVSRCCOLOR = 4, GL_SRC_ALPHA, //BLEND_SRCALPHA = 5, GL_ONE_MINUS_SRC_ALPHA, //BLEND_INVSRCALPHA = 6, GL_DST_ALPHA, //BLEND_DESTALPHA = 7, GL_ONE_MINUS_DST_ALPHA, //BLEND_INVDESTALPHA = 8, GL_DST_COLOR, //BLEND_DESTCOLOR = 9, GL_ONE_MINUS_DST_COLOR, //BLEND_INVDESTCOLOR = 10, GL_SRC_ALPHA_SATURATE, //BLEND_SRCALPHASAT = 11, GL_SRC_ALPHA_SATURATE, //BLEND_BOTHSRCALPHA = 12, GL_SRC_ALPHA_SATURATE, //BLEND_BOTHINVSRCALPHA = 13, }; //======================================================================== COGLColorCombiner::COGLColorCombiner(CRender *pRender) : CColorCombiner(pRender), m_pOGLRender((OGLRender*)pRender), m_bSupportAdd(false), m_bSupportSubtract(false) { m_pDecodedMux = new COGLDecodedMux; m_pDecodedMux->m_maxConstants = 0; m_pDecodedMux->m_maxTextures = 1; } COGLColorCombiner::~COGLColorCombiner() { delete m_pDecodedMux; m_pDecodedMux = NULL; } bool COGLColorCombiner::Initialize(void) { m_bSupportAdd = false; m_bSupportSubtract = false; m_supportedStages = 1; COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext); if( pcontext->IsExtensionSupported(OSAL_GL_ARB_TEXTURE_ENV_ADD) || pcontext->IsExtensionSupported("GL_EXT_texture_env_add") ) { m_bSupportAdd = true; } if( pcontext->IsExtensionSupported("GL_EXT_blend_subtract") ) { m_bSupportSubtract = true; } return true; } void COGLColorCombiner::DisableCombiner(void) { m_pOGLRender->DisableMultiTexture(); glEnable(GL_BLEND); OPENGL_CHECK_ERRORS; glBlendFunc(GL_ONE, GL_ZERO); OPENGL_CHECK_ERRORS; if( m_bTexelsEnable ) { COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture; if( pTexture ) { m_pOGLRender->EnableTexUnit(0, true); m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); OPENGL_CHECK_ERRORS; m_pOGLRender->SetAllTexelRepeatFlag(); } #ifdef DEBUGGER else { DebuggerAppendMsg("Check me, texture is NULL but it is enabled"); } #endif } else { glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); OPENGL_CHECK_ERRORS; m_pOGLRender->EnableTexUnit(0, false); } } void COGLColorCombiner::InitCombinerCycleCopy(void) { m_pOGLRender->DisableMultiTexture(); m_pOGLRender->EnableTexUnit(0, true); COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture; if( pTexture ) { m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0); m_pOGLRender->SetTexelRepeatFlags(gRSP.curTile); } #ifdef DEBUGGER else { DebuggerAppendMsg("Check me, texture is NULL"); } #endif glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); OPENGL_CHECK_ERRORS; } void COGLColorCombiner::InitCombinerCycleFill(void) { m_pOGLRender->DisableMultiTexture(); m_pOGLRender->EnableTexUnit(0, false); } void COGLColorCombiner::InitCombinerCycle12(void) { m_pOGLRender->DisableMultiTexture(); if (!m_bTexelsEnable) { glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); OPENGL_CHECK_ERRORS; m_pOGLRender->EnableTexUnit(0, false); return; } } void COGLBlender::NormalAlphaBlender(void) { glEnable(GL_BLEND); OPENGL_CHECK_ERRORS; glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); OPENGL_CHECK_ERRORS; } void COGLBlender::DisableAlphaBlender(void) { glEnable(GL_BLEND); OPENGL_CHECK_ERRORS; glBlendFunc(GL_ONE, GL_ZERO); OPENGL_CHECK_ERRORS; } void COGLBlender::BlendFunc(uint32_t srcFunc, uint32_t desFunc) { glBlendFunc(DirectX_OGL_BlendFuncMaps[srcFunc], DirectX_OGL_BlendFuncMaps[desFunc]); OPENGL_CHECK_ERRORS; } void COGLBlender::Enable() { glEnable(GL_BLEND); OPENGL_CHECK_ERRORS; } void COGLBlender::Disable() { glDisable(GL_BLEND); OPENGL_CHECK_ERRORS; } void COGLColorCombiner::InitCombinerBlenderForSimpleTextureDraw(uint32_t tile) { m_pOGLRender->DisableMultiTexture(); if( g_textures[tile].m_pCTexture ) { m_pOGLRender->EnableTexUnit(0, true); glBindTexture(GL_TEXTURE_2D, ((COGLTexture*)(g_textures[tile].m_pCTexture))->m_dwTextureName); OPENGL_CHECK_ERRORS; } m_pOGLRender->SetAllTexelRepeatFlag(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); OPENGL_CHECK_ERRORS; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); OPENGL_CHECK_ERRORS; glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // Linear Filtering OPENGL_CHECK_ERRORS; glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // Linear Filtering OPENGL_CHECK_ERRORS; glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); OPENGL_CHECK_ERRORS; m_pOGLRender->SetAlphaTestEnable(FALSE); } #ifdef DEBUGGER extern const char *translatedCombTypes[]; void COGLColorCombiner::DisplaySimpleMuxString(void) { TRACE0("\nSimplified Mux\n"); m_pDecodedMux->DisplaySimpliedMuxString("Used"); } #endif mupen64plus-core/tools/install_binary_bundle.sh000755 001750 001750 00000006531 12655644434 023114 0ustar00sergiosergio000000 000000 #!/bin/sh # # mupen64plus binary bundle install script # # Copyright 2007-2013 The Mupen64Plus Development Team # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # set -e export PATH=/bin:/usr/bin GINSTALLFLAG=-D if `which ginstall >/dev/null 2>&1`; then INSTALL=ginstall elif install --help >/dev/null 2>&1; then INSTALL=install elif [ -e "`which install 2>/dev/null`" ]; then printf "warning: GNU install not found, assuming BSD install\n" >&2 INSTALL=install GINSTALLFLAG= else printf "error: install tool not found\n" >&2 exit 1 fi INSTALL_STRIP_FLAG="${INSTALL_STRIP_FLAG:=-s}" usage() { printf "usage: $(basename $0) [PREFIX] [SHAREDIR] [BINDIR] [LIBDIR] [PLUGINDIR] [MANDIR] \tPREFIX - installation directories prefix (default: /usr/local) \tSHAREDIR - path to Mupen64Plus shared data files (default: \$PREFIX/share/mupen64plus) \tBINDIR - path to Mupen64Plus binary program files (default: \$PREFIX/bin) \tLIBDIR - path to Mupen64Plus core library (default: \$PREFIX/lib) \tPLUGINDIR - path to Mupen64Plus plugin libraries (default: \$PREFIX/lib/mupen64plus) \tMANDIR - path to manual files (default: \$PREFIX/share/man) " } if [ $# -gt 6 ]; then usage exit 1 fi PREFIX="${1:-/usr/local}" SHAREDIR="${2:-${PREFIX}/share/mupen64plus}" BINDIR="${3:-${PREFIX}/bin}" LIBDIR="${4:-${PREFIX}/lib}" PLUGINDIR="${5:-${PREFIX}/lib/mupen64plus}" MANDIR="${6:-${PREFIX}/share/man}" printf "Installing Mupen64Plus Binary Bundle to ${PREFIX}\n" # Mupen64Plus-Core $INSTALL -d -v "${LIBDIR}" $INSTALL -m 0644 "${INSTALL_STRIP_FLAG}" libmupen64plus.so.2.* "${LIBDIR}" /sbin/ldconfig $INSTALL -d -v "${SHAREDIR}" $INSTALL -m 0644 font.ttf "${SHAREDIR}" $INSTALL -m 0644 mupen64plus.cht "${SHAREDIR}" $INSTALL -m 0644 mupen64plus.ini "${SHAREDIR}" $INSTALL -d -v "${SHAREDIR}/doc" $INSTALL -m 0644 doc/* "${SHAREDIR}/doc" # Mupen64Plus-ROM $INSTALL -m 0644 m64p_test_rom.v64 "${SHAREDIR}" # Mupen64Plus-UI-Console $INSTALL -d -v "${BINDIR}" $INSTALL $GINSTALLFLAG -m 0755 mupen64plus "${BINDIR}" $INSTALL -d -v "${MANDIR}/man6" $INSTALL -m 0644 man6/mupen64plus.6 "${MANDIR}/man6" # Plugins $INSTALL -d -v "${PLUGINDIR}" $INSTALL -m 0644 "${INSTALL_STRIP_FLAG}" mupen64plus-audio-sdl.so "${PLUGINDIR}" $INSTALL -m 0644 "${INSTALL_STRIP_FLAG}" mupen64plus-input-sdl.so "${PLUGINDIR}" $INSTALL -m 0644 "${INSTALL_STRIP_FLAG}" mupen64plus-rsp-hle.so "${PLUGINDIR}" $INSTALL -m 0644 "${INSTALL_STRIP_FLAG}" mupen64plus-video-rice.so "${PLUGINDIR}" $INSTALL -m 0644 "${INSTALL_STRIP_FLAG}" mupen64plus-video-glide64mk2.so "${PLUGINDIR}" $INSTALL -m 0644 RiceVideoLinux.ini "${SHAREDIR}" $INSTALL -m 0644 InputAutoCfg.ini "${SHAREDIR}" $INSTALL -m 0644 Glide64mk2.ini "${SHAREDIR}" printf "Installation successful.\n" mupen64plus-core/src/main/rom_luts.c000664 001750 001750 00000072104 12655644434 020576 0ustar00sergiosergio000000 000000 /* This file was generated by gen_romdb.py */ /* Games that use 16Kbit EEPROM */ static const uint64_t lut_ee16k[] = { 0x975B7845A2505C18ULL, /* 77a Special Edition by Count0 (PD) */ 0x514B6900B4B19881ULL, /* Banjo to Kazooie no Daibouken 2 (J) [!] */ 0x155B7CDFF0DA7325ULL, /* Banjo-Tooie (A) [!] */ 0xC9176D39EA4779D1ULL, /* Banjo-Tooie (E) (M4) [!] */ 0xC2E9AA9A475D70AAULL, /* Banjo-Tooie (U) [!] */ 0x373F58899A6CA80AULL, /* Conker's Bad Fur Day (E) [!] */ 0x30C7AC507704072DULL, /* Conker's Bad Fur Day (U) [!] */ 0x83F3931ECB72223DULL, /* Cruis'n World (E) [!] */ 0xDFE61153D76118E6ULL, /* Cruis'n World (U) [!] */ 0x11936D8C6F2C4B43ULL, /* Donkey Kong 64 (E) [!] */ 0x053C89A7A5064302ULL, /* Donkey Kong 64 (J) [!] */ 0x0DD4ABABB5A2A91EULL, /* Donkey Kong 64 (U) (Kiosk Demo) [!] */ 0xEC58EABFAD7C7169ULL, /* Donkey Kong 64 (U) [!] */ 0xB6306E99B63ED2B2ULL, /* Doraemon 2 - Nobita to Hikari no Shinden (J) [!] */ 0xA8275140B9B056E8ULL, /* Doraemon 3 - Nobita no Machi SOS! (J) [!] */ 0x202A8EE483F88B89ULL, /* Excitebike 64 (E) [!] */ 0x861C3519F6091CE5ULL, /* Excitebike 64 (J) [!] */ 0xAF754F7B1DD17381ULL, /* Excitebike 64 (U) (Kiosk Demo) [!] */ 0x07861842A12EBC9FULL, /* Excitebike 64 (U) [!] */ 0x1739EFBAD0B43A68ULL, /* Kobe Bryant in NBA Courtside (E) [!] */ 0x616B84948A509210ULL, /* Kobe Bryant's NBA Courtside (U) [!] */ 0xA197CB527520DE0EULL, /* Madden Football 64 (E) [!] */ 0x13836389265B3C76ULL, /* Madden Football 64 (U) [!] */ 0xC56741600F5F453CULL, /* Mario Party 3 (E) (M4) [!] */ 0x0B0AB4CD7B158937ULL, /* Mario Party 3 (J) [!] */ 0x7C3829D96E8247CEULL, /* Mario Party 3 (U) [!] */ 0x839F3AD5406D15FAULL, /* Mario Tennis (E) [!] */ 0x5001CF4FF30CB3BDULL, /* Mario Tennis (U) [!] */ 0x3A6C42B51ACADA1BULL, /* Mario Tennis 64 (J) [!] */ 0x147E0EDB36C5B12CULL, /* Neon Genesis Evangelion (J) [!] */ 0xF468118CE32EE44EULL, /* PD Ultraman Battle Collection 64 (J) [!] */ 0xE4B08007A602FF33ULL, /* Perfect Dark (E) (M5) [!] */ 0x96747EB4104BB243ULL, /* Perfect Dark (J) [!] */ 0xDDF460CC3CA634C0ULL, /* Perfect Dark (U) (V1.0) [!] */ 0x41F2B98FB458B466ULL, /* Perfect Dark (U) (V1.1) [!] */ 0xFEE970104E94A9A0ULL, /* RR64 - Ridge Racer 64 (E) [!] */ 0x2500267E2A7EC3CEULL, /* RR64 - Ridge Racer 64 (U) [!] */ 0x53ED2DC406258002ULL, /* Star Wars Episode I - Racer (E) (M3) [!] */ 0x61F5B152046122ABULL, /* Star Wars Episode I - Racer (J) [!] */ 0x72F703986556A98BULL, /* Star Wars Episode I - Racer (U) [!] */ 0x2DCFCA608354B147ULL, /* Yoshi Story (J) [!] */ 0xD3F97D496924135BULL, /* Yoshi's Story (E) (M3) [!] */ 0x2337D8E86B8E7CECULL /* Yoshi's Story (U) (M2) [!] */ }; /* Games that use 4Kbit EEPROM */ static const uint64_t lut_ee4k[] = { 0xB98BA4565B2B76AFULL, /* 64 de Hakken!! Tamagotchi Minna de Tamagotchi World (J) [!] */ 0x36F22FBF318912F2ULL, /* 64 Hanafuda - Tenshi no Yakusoku (J) [!] */ 0x7A6081FCFF8F7A78ULL, /* 64 Trump Collection - Alice no Wakuwaku Trump World (J) [!] */ 0x62F6BE95F102D6D6ULL, /* AeroFighters Assault (E) (M3) [!] */ 0x1B598BF1ECA29B45ULL, /* AeroFighters Assault (U) [!] */ 0x8CC182A6C2D0CAB0ULL, /* AI Shougi 3 (J) [!] */ 0xDFD784ADAE426603ULL, /* All Star Tennis '99 (E) (M5) [!] */ 0xE185E2914E50766DULL, /* All Star Tennis '99 (U) [!] */ 0xE340A49C74318D41ULL, /* Baku Bomberman (J) [!] */ 0xE73C7C4FAF93B838ULL, /* Baku Bomberman 2 (J) [!] */ 0x5168D520CA5FCD0DULL, /* Banjo to Kazooie no Daibouken (J) [!] */ 0x733FCCB1444892F9ULL, /* Banjo-Kazooie (E) (M3) [!] */ 0xA4BF9306BF0CDFD1ULL, /* Banjo-Kazooie (U) (V1.0) [!] */ 0xB088FBB4441E4B1DULL, /* Bass Hunter 64 (E) [!] */ 0x08FFA4B701F453B6ULL, /* Big Mountain 2000 (U) [!] */ 0x7C64E6DB55B924DBULL, /* Blast Corps (E) (M2) [!] */ 0x7C647C25D9D901E6ULL, /* Blast Corps (U) (V1.0) [!] */ 0x7C647E651948D305ULL, /* Blast Corps (U) (V1.1) [!] */ 0x65234451EBD3346FULL, /* Blast Dozer (J) [!] */ 0x0B58B8CDB7B291D2ULL, /* Body Harvest (E) (M3) [!] */ 0x5326696FFE9A99C3ULL, /* Body Harvest (U) [!] */ 0x5A160336BC7B37B0ULL, /* Bomberman 64 (E) [!] */ 0xF568D51E7E49BA1EULL, /* Bomberman 64 (U) [!] */ 0x237E73B4D63B6B37ULL, /* Bomberman 64 - The Second Attack! (U) [!] */ 0xD85C4E2988E276AFULL, /* Bomberman Hero (E) [!] */ 0x4446FDD6E3788208ULL, /* Bomberman Hero (U) [!] */ 0x67FF12CC76BF0212ULL, /* Bomberman Hero - Mirian Oujo wo Sukue! (J) [!] */ 0xB9AF8CC6DEC9F19FULL, /* Chameleon Twist (E) [!] */ 0xA4F2F521F0EB168EULL, /* Chameleon Twist (J) [!] */ 0x6420535A50028062ULL, /* Chameleon Twist (U) [!] */ 0x2E3593393FA5EDA6ULL, /* Chopper Attack (E) [!] */ 0x214CAD94BE1A3B24ULL, /* Chopper Attack (U) [!] */ 0x2BCCF9C4403D9F6FULL, /* Choro Q 64 (J) [!] */ 0xA794152861F1199DULL, /* Chou Snobow Kids (J) [!] */ 0xF8009DB06B291823ULL, /* City-Tour GP - Zennihon GT Senshuken (J) [!] */ 0x46A3F7AF0F7591D0ULL, /* Cruis'n Exotica (U) [!] */ 0x503EA760E1300E96ULL, /* Cruis'n USA (E) [!] */ 0xFF2F2FB4D161149AULL, /* Cruis'n USA (U) (V1.0) [!] */ 0x5306CF45CBC49250ULL, /* Cruis'n USA (U) (V1.1) [!] */ 0xB34025547340C004ULL, /* Cruis'n USA (U) (V1.2) [!] */ 0xFD73F7759724755AULL, /* Diddy Kong Racing (E) (M3) (V1.0) [!] */ 0x596E145BF7D9879FULL, /* Diddy Kong Racing (E) (M3) (V1.1) [!] */ 0xF389A35A17785562ULL, /* Diddy Kong Racing (J) [f1] (Z64) */ 0x7435C9BB39763CF4ULL, /* Diddy Kong Racing (J) */ 0x53D440E77519B011ULL, /* Diddy Kong Racing (U) (M2) (V1.0) [!] */ 0xE402430DD2FCFC9DULL, /* Diddy Kong Racing (U) (M2) (V1.1) [!] */ 0xC16C421BA21580F7ULL, /* Disney's Donald Duck - Goin' Quackers (U) [!] */ 0x3DF17480193DED5AULL, /* Donald Duck - Quack Attack (E) (M5) [!] */ 0xD52FE29D8EA6A759ULL, /* Donchan Puzzle Hanabi de Doon! (J) [ALECK64] */ 0x492B9DE8C6CCC81CULL, /* Earthworm Jim 3D (E) (M6) [!] */ 0xDF5741919EB5123DULL, /* Earthworm Jim 3D (U) [!] */ 0x6D9D1FE484D10BEAULL, /* Eleven Beat - World Tournament (J) [ALECK64] */ 0xCC3CC8B30EC405A4ULL, /* F-1 World Grand Prix (E) [!] */ 0xB70BAEE53A5005A8ULL, /* F-1 World Grand Prix (F) [!] */ 0x3844263466B3F060ULL, /* F-1 World Grand Prix (G) [!] */ 0x64BF47C4F4BD22BAULL, /* F-1 World Grand Prix (J) [!] */ 0x36F1C74BF2029939ULL, /* Fighter's Destiny (E) [!] */ 0x0C41F9C201717A0DULL, /* Fighter's Destiny (F) [!] */ 0xFE94E570E4873A9CULL, /* Fighter's Destiny (G) [!] */ 0x52F788058B8FCAB7ULL, /* Fighter's Destiny (U) [!] */ 0x49E46C2D7B1A110CULL, /* Fighting Cup (J) [!] */ 0xF523730199E3EE93ULL, /* Glover (E) (M3) [!] */ 0x8E6E01FFCCB4F948ULL, /* Glover (U) [!] */ 0x0414CA612E57B8AAULL, /* GoldenEye 007 (E) [!] */ 0xA24F4CF1A82327BAULL, /* GoldenEye 007 (J) [!] */ 0xB57D4EB4345E09E5ULL, /* Guru - Kuru Kuru Fever (J) [ALECK64] */ 0xEE4A0E338FD588C9ULL, /* GT 64 - Championship Edition (E) (M3) [!] */ 0xC49ADCA2F1501B62ULL, /* GT 64 - Championship Edition (U) [!] */ 0xD3F10E5D052EA579ULL, /* Hey You, Pikachu! (U) [!] */ 0xC1D702BD6D416547ULL, /* Hoshi no Kirby 64 (J) (V1.0) [!] */ 0xCA1BB86F41CCA5C5ULL, /* Hoshi no Kirby 64 (J) (V1.1) [!] */ 0x0C581C7A3D6E20E4ULL, /* Hoshi no Kirby 64 (J) (V1.2) [!] */ 0xBCB1F89F060752A2ULL, /* Hoshi no Kirby 64 (J) (V1.3) [!] */ 0x8C138BE095700E46ULL, /* In-Fisherman Bass Hunter 64 (U) [!] */ 0xAF9DCC151A723D88ULL, /* Indiana Jones and the Infernal Machine (U) [!] */ 0x3A6F8C6B2897BAEBULL, /* Indiana Jones and the Infernal Machine (E) */ 0xE436467A82DE8F9BULL, /* Indy Racing 2000 (U) [!] */ 0x979B263EF8470004ULL, /* Killer Instinct Gold (E) [!] */ 0x9E8FE2BA8B270770ULL, /* Killer Instinct Gold (U) (V1.0) [!] */ 0x9E8FCDFA49F5652BULL, /* Killer Instinct Gold (U) (V1.1) [!] */ 0xF908CA4C36464327ULL, /* Killer Instinct Gold (U) (V1.2) [!] */ 0x0D93BA11683868A6ULL, /* Kirby 64 - The Crystal Shards (E) [!] */ 0x46039FB40337822CULL, /* Kirby 64 - The Crystal Shards (U) [!] */ 0x60460680305F0E72ULL, /* Lode Runner 3-D (E) (M5) [!] */ 0x964ADD0BB29213DBULL, /* Lode Runner 3-D (J) [!] */ 0x255018DF57D6AE3AULL, /* Lode Runner 3-D (U) [!] */ 0x2483F22B136E025EULL, /* Lylat Wars (A) (M3) [!] */ 0xF4CBE92CB392ED12ULL, /* Lylat Wars (E) (M3) [!] */ 0xD5356BAC97AE69D2ULL, /* Magical Tetris Challenge Featuring Mickey (J) [ALECK64] */ 0xC3B6DE9D65D2DE76ULL, /* Mario Kart 64 (E) (V1.0) [!] */ 0x2577C7D4D18FAAAEULL, /* Mario Kart 64 (E) (V1.1) [!] */ 0x6BFF4758E5FF5D5EULL, /* Mario Kart 64 (J) (V1.0) [!] */ 0xC9C3A9875810344CULL, /* Mario Kart 64 (J) (V1.1) [!] */ 0x3E5055B62E92DA52ULL, /* Mario Kart 64 (U) [!] */ 0x9C66306980F24A80ULL, /* Mario Party (E) (M3) [!] */ 0xADA815BE6028622FULL, /* Mario Party (J) [!] */ 0x2829657EA0621877ULL, /* Mario Party (U) [!] */ 0x82380387DFC744D9ULL, /* Mario Party 2 (E) (M5) [!] */ 0xED567D0F38B08915ULL, /* Mario Party 2 (J) [!] */ 0x9EA95858AF72B618ULL, /* Mario Party 2 (U) [!] */ 0x736AE6AF4117E9C7ULL, /* Mickey no Racing Challenge USA (J) [!] */ 0xDED0DD9AE78225A7ULL, /* Mickey's Speedway USA (E) (M5) [!] */ 0xFA8C4571BBE7F9C0ULL, /* Mickey's Speedway USA (U) [!] */ 0x418BDA98248A0F58ULL, /* Mischief Makers (E) [!] */ 0x0B93051B603D81F9ULL, /* Mischief Makers (U) [!] */ 0x2256ECDA71AB1B9CULL, /* Mission Impossible (E) [!] */ 0x20095B34343D9E87ULL, /* Mission Impossible (F) [!] */ 0x93EB3F7E81675E44ULL, /* Mission Impossible (G) [!] */ 0xEBA949DC39BAECBDULL, /* Mission Impossible (I) [!] */ 0x5F6A04E2D4FA070DULL, /* Mission Impossible (S) [!] */ 0x26035CF8802B9135ULL, /* Mission Impossible (U) [!] */ 0x5AC383E1D712E387ULL, /* Monopoly (U) [!] */ 0xB8F0BD034479189EULL, /* MRC - Multi Racing Championship (E) (M3) [!] */ 0xA6B6B41315D113CCULL, /* MRC - Multi Racing Championship (J) [!] */ 0x2AF9B65C85E2A2D7ULL, /* MRC - Multi Racing Championship (U) [!] */ 0xC83CEB83FDC56219ULL, /* Penny Racers (E) [!] */ 0x73ABB1FB9CCA6093ULL, /* Penny Racers (U) [!] */ 0xEE08C6026BC2D5A6ULL, /* PGA European Tour (E) (M5) [!] */ 0xB54CE881BCCB6126ULL, /* PGA European Tour (U) [!] */ 0x3F245305FC0B74AAULL, /* Pikachu Genki Dechu (J) [!] */ 0x1AA05AD546F52D80ULL, /* Pilotwings 64 (E) (M3) [!] */ 0x09CC4801E42EE491ULL, /* Pilotwings 64 (J) [!] */ 0xC851961C78FCAAFAULL, /* Pilotwings 64 (U) [!] */ 0x9FD375F845F32DC8ULL, /* Rocket - Robot on Wheels (E) (M3) [!] */ 0x0C5EE085A167DD3EULL, /* Rocket - Robot on Wheels (U) [!] */ 0x2EF4D519C64A0C5EULL, /* Snow Speeder (J) [!] */ 0xC2751D1AF8C19BFFULL, /* Snowboard Kids 2 (E) [!] */ 0x222123514046594BULL, /* Sonic Wings Assault (J) [!] */ 0xFC70E27208FFE7AAULL, /* Space Station Silicon Valley (E) (M7) [!] */ 0xBFE23884EF48EAAFULL, /* Space Station Silicon Valley (J) [!] */ 0xFFCAA7C168858537ULL, /* Star Fox 64 (J) [!] */ 0xA7D015F82289AA43ULL, /* Star Fox 64 (U) (V1.0) [!] */ 0xBA780BA00F21DB34ULL, /* Star Fox 64 (U) (V1.1) [!] */ 0xB703EB2328AAE53AULL, /* Star Soldier - Vanishing Earth (J) [!] */ 0x315C74663A453265ULL, /* Star Soldier - Vanishing Earth (J) [!] [ALECK64] */ 0xDDD93C85DAE381E8ULL, /* Star Soldier - Vanishing Earth (U) [!] */ 0x7EE0E8BB49E411AAULL, /* Star Wars - Rogue Squadron (E) (M3) (V1.0) [!] */ 0x219191C133183C61ULL, /* Star Wars - Rogue Squadron (E) (M3) (V1.1) [!] */ 0x66A24BEC2EADD94FULL, /* Star Wars - Rogue Squadron (U) (M3) [!] */ 0x4D486681AB7D9245ULL, /* Star Wars - Shadows of the Empire (E) [!] */ 0x264D7E5C18874622ULL, /* Star Wars - Shadows of the Empire (U) (V1.0) [!] */ 0x4147B09163251060ULL, /* Star Wars - Shadows of the Empire (U) (V1.1) [!] */ 0x4DD7ED5474F9287DULL, /* Star Wars - Shadows of the Empire (U) (V1.2) [!] */ 0x827E4890958468DCULL, /* Star Wars - Shutsugeki! Rogue Chuutai (J) [!] */ 0xEAE6ACE2020B4384ULL, /* Star Wars Episode I - Battle for Naboo (E) [!] */ 0x3D02989BD4A381E2ULL, /* Star Wars Episode I - Battle for Naboo (U) [!] */ 0xD89E0E55B17AA99AULL, /* Starshot - Space Circus Fever (E) (M3) [!] */ 0x94EDA5B88673E903ULL, /* Starshot - Space Circus Fever (U) (M3) [!] */ 0xA03CF036BCC1C5D2ULL, /* Super Mario 64 (E) (M3) [!] */ 0x4EAA3D0E74757C24ULL, /* Super Mario 64 (J) [!] */ 0x635A2BFF8B022326ULL, /* Super Mario 64 (U) [!] */ 0xD6FBA4A86326AA2CULL, /* Super Mario 64 - Shindou Edition (J) [!] */ 0x0FE684A98BB77AC4ULL, /* Tetrisphere (E) [!] */ 0x3C1FDABE02A4E0BAULL, /* Tetrisphere (U) [!] */ 0x2B4F4EFB43C511FEULL, /* Tom and Jerry in Fists of Furry (E) (M6) [!] */ 0x63E7391CE6CCEA33ULL, /* Tom and Jerry in Fists of Furry (U) [!] */ 0xD09BA5381C1A5489ULL, /* Top Gear Overdrive (E) [!] */ 0x0578F24F9175BF17ULL, /* Top Gear Overdrive (J) [!] */ 0xD741CD80ACA9B912ULL, /* Top Gear Overdrive (U) [!] */ 0x90AF8D2CE1AC1B37ULL, /* Tower & Shaft (J) [ALECK64] */ 0x636E6B19E57DDC5FULL, /* V-Rally Edition 99 (E) (M3) [!] */ 0x4D0224A51BEB5794ULL, /* V-Rally Edition 99 (J) [!] */ 0x3C059038C8BF2182ULL, /* V-Rally Edition 99 (U) [!] */ 0x2F57C9F7F1E29CA6ULL, /* Vivid Dolls (J) [ALECK64] */ 0x93053075261E0F43ULL, /* Waialae Country Club - True Golf Classics (E) (M4) (V1.0) [!] */ 0x0C5057AD046E126EULL, /* Waialae Country Club - True Golf Classics (E) (M4) (V1.1) [!] */ 0x8066D58AC3DECAC1ULL, /* Waialae Country Club - True Golf Classics (U) (V1.0) [!] */ 0x650EFA9630DDF9A7ULL, /* Wave Race 64 (E) (M2) [!] */ 0x5C9191D6B30AC306ULL, /* Wave Race 64 (J) [!] */ 0x7DE11F5374872F9DULL, /* Wave Race 64 (U) (V1.0) [!] */ 0x492F4B6104E5146AULL, /* Wave Race 64 (U) (V1.1) [!] */ 0x535DF3E2609789F1ULL, /* Wave Race 64 - Shindou Edition (J) (V1.2) [!] */ 0x0CEBC4C70C9CE932ULL, /* Wild Choppers (J) [!] */ 0x2D21C57B8FE4C58CULL, /* Worms - Armageddon (E) (M6) [!] */ 0x13E959A00E93CAB0ULL, /* Worms - Armageddon (U) (M3) [!] */ 0x9FE6162DE97E4037ULL /* Yuke Yuke!! Trouble Makers (J) [!] */ }; /* Games that use Flash RAM */ static const uint64_t lut_flashram[] = { 0xAE5B9465C54D6576ULL, /* Command & Conquer (E) (M2) [!] */ 0xB5025BADD32675FDULL, /* Command & Conquer (G) [!] */ 0x95286EB4B76AD58FULL, /* Command & Conquer (U) [!] */ 0x68D7A1DE0079834AULL, /* Jet Force Gemini (E) (M4) [!] */ 0x8A6009B694ACE150ULL, /* Jet Force Gemini (U) [!] */ 0x36281F23009756CFULL, /* Ken Griffey Jr.'s Slugfest (U) [!] */ 0xE97955C6BC338D38ULL, /* Legend of Zelda, The - Majora's Mask (E) (M4) (V1.0) [!] */ 0x0A5D8F8398C5371AULL, /* Legend of Zelda, The - Majora's Mask (E) (M4) (V1.1) */ 0x5354631C03A2DEF0ULL, /* Legend of Zelda, The - Majora's Mask (U) [!] */ 0xB443EB084DB31193ULL, /* Legend of Zelda, The - Majora's Mask (U) (GC) */ 0x3BA7CDDC464E52A0ULL, /* Mario Story (J) [!] */ 0x0EC158F5FB3E6896ULL, /* Mega Man 64 (U) [!] */ 0x916852D873DBEAEFULL, /* NBA Courtside 2 - Featuring Kobe Bryant (U) [!] */ 0x19AB29AFC71BCD28ULL, /* Paper Mario (E) (M4) [!] */ 0x65EEE53AED7D733CULL, /* Paper Mario (U) [!] */ 0xEC0F690D32A7438CULL, /* Pocket Monsters Snap (J) [!] */ 0x637758865FB80E7BULL, /* Pocket Monsters Stadium 2 (J) [!] */ 0xEE4FD7C29CF1D938ULL, /* Pocket Monsters Stadium Kin Gin (J) [!] */ 0x4A1CD153D830AEF8ULL, /* Pokemon Puzzle League (E) [!] */ 0x3EB2E6F3062F9EFEULL, /* Pokemon Puzzle League (F) [!] */ 0x7A4747AC44EEEC23ULL, /* Pokemon Puzzle League (G) [!] */ 0x19C553A7A70F4B52ULL, /* Pokemon Puzzle League (U) [!] */ 0x7BB18D4083138559ULL, /* Pokemon Snap (A) [!] */ 0x4FF5976FACF559D8ULL, /* Pokemon Snap (E) [!] */ 0xBA6C293A9FAFA338ULL, /* Pokemon Snap (F) [!] */ 0x5753720D2A8A884DULL, /* Pokemon Snap (G) [!] */ 0xC0C8504661051B05ULL, /* Pokemon Snap (I) [!] */ 0x817D286AEF417416ULL, /* Pokemon Snap (S) [!] */ 0xCA12B54771FA4EE4ULL, /* Pokemon Snap (U) [!] */ 0x8407727557315B9CULL, /* Pokemon Stadium (E) (V1.0) [!] */ 0x91C9E05DAD3AAFB9ULL, /* Pokemon Stadium (E) (V1.1) [!] */ 0xA23553A342BF2D39ULL, /* Pokemon Stadium (F) [!] */ 0x42011E1BE3552DB5ULL, /* Pokemon Stadium (G) [!] */ 0xA53FA82DDAE2C15DULL, /* Pokemon Stadium (I) [!] */ 0xB6E549CEDC8134C0ULL, /* Pokemon Stadium (S) [!] */ 0x90F5D9B39D0EDCF0ULL, /* Pokemon Stadium (U) (V1.0) [!] */ 0x1A122D43C17DAF0FULL, /* Pokemon Stadium (U) (V1.1) [!] */ 0x2952369CB6E4C3A8ULL, /* Pokemon Stadium 2 (E) [!] */ 0xAC5AA5C7A9B0CDC3ULL, /* Pokemon Stadium 2 (F) [!] */ 0x439B7E7EC1A1495DULL, /* Pokemon Stadium 2 (G) [!] */ 0xEFCEAF0022094848ULL, /* Pokemon Stadium 2 (I) [!] */ 0xD0A1FC5B2FB8074BULL, /* Pokemon Stadium 2 (S) [!] */ 0x03571182892FD06DULL, /* Pokemon Stadium 2 (U) [!] */ 0xD666593BD7A25C07ULL, /* Rockman Dash (J) [!] */ 0xF163A242F2449B3BULL, /* Star Twins (J) [!] */ 0xBC9B2CC34ED04DA5ULL, /* StarCraft 64 (Beta) */ 0x42CF5EA39A1334DFULL, /* StarCraft 64 (E) [!] */ 0x0684FBFB5D3EA8A5ULL, /* StarCraft 64 (U) [!] */ 0xE0C4F72F769E1506ULL, /* Tigger's Honey Hunt (E) (M7) [!] */ 0x4EBFDD33664C9D84ULL, /* Tigger's Honey Hunt (U) [!] */ 0x6D8DF08ED008C3CFULL, /* WWF No Mercy (E) (V1.0) [!] */ 0x8CDB94C2CB46C6F0ULL, /* WWF No Mercy (E) (V1.1) [!] */ 0x4E4B06401B49BCFBULL, /* WWF No Mercy (U) (V1.0) [!] */ 0xF7F52DB82195E636ULL, /* Zelda no Densetsu - Toki no Ocarina - Zelda Collection Version (J) (GC) [!] */ 0xF611F4BAC584135CULL, /* Zelda no Densetsu - Toki no Ocarina GC (J) (GC) [!] */ 0xF43B45BA2F0E9B6FULL /* Zelda no Densetsu - Toki no Ocarina GC URA (J) (GC) [!] */ }; /* (Delay SI) */ static const uint64_t lut_delaysi[][2] = { { 0x514B6900B4B19881ULL, 0 }, /* Banjo to Kazooie no Daibouken 2 (J) [!] */ { 0xC2E9AA9A475D70AAULL, 0 }, /* Banjo-Tooie (U) [!] */ { 0xC9176D39EA4779D1ULL, 0 }, /* Banjo-Tooie (E) (M4) [!] */ { 0x155B7CDFF0DA7325ULL, 0 }, /* Banjo-Tooie (A) [!] */ { 0x9F8B96C3A01194DCULL, 0 }, /* Yakouchuu II - Satsujin Kouro (J) */ }; /* Cycles per emulated instruction (aka CountPerOp) */ static const uint64_t lut_cpop[][2] = { { 0xB98BA4565B2B76AFULL, 1 }, /* 64 de Hakken!! Tamagotchi Minna de Tamagotchi World (J) [!] */ { 0x9C961069F5EA488DULL, 1 }, /* 64 Oozumou (J) [!] */ { 0x27C425D08C2D99C1ULL, 1 }, /* Airboarder 64 (E) [!] */ { 0x6C45B60CDCE50E30ULL, 1 }, /* Airboarder 64 (J) [!] */ { 0xB088FBB4441E4B1DULL, 1 }, /* Bass Hunter 64 (E) [!] */ { 0xD76333AC0CB6219DULL, 1 }, /* Bass Rush - ECOGEAR PowerWorm Championship (J) [!] */ { 0xBCFACCAAB814D8EFULL, 1 }, /* Bassmasters 2000 (U) [!] */ { 0x6AA4DDE7E3E2F4E7ULL, 3 }, /* BattleTanx (U) [!] */ { 0x75A4E2476008963DULL, 3 }, /* BattleTanx - Global Assault (U) [!] */ { 0xA1B64A61D014940BULL, 3 }, /* Beetle Adventure Racing! (E) (M3) [!] */ { 0x7EAE24889D40A35AULL, 1 }, /* Biohazard 2 (J) [!] */ { 0x0B58B8CDB7B291D2ULL, 1 }, /* Body Harvest (E) (M3) [!] */ { 0x5326696FFE9A99C3ULL, 1 }, /* Body Harvest (U) [!] */ { 0x8F12C09645DC17E1ULL, 1 }, /* Bug's Life, A (E) [!] */ { 0x2B38AEC06350B810ULL, 1 }, /* Bug's Life, A (F) [!] */ { 0xDFF227D90D4D8169ULL, 1 }, /* Bug's Life, A (G) [!] */ { 0xF63B89CE4582D57DULL, 1 }, /* Bug's Life, A (I) [!] */ { 0x82DC04FDCF2D82F4ULL, 1 }, /* Bug's Life, A (U) [!] */ { 0xAC16400ECF5D071AULL, 1 }, /* California Speed (U) [!] */ { 0x580162ECE3108BF1ULL, 1 }, /* Carmageddon 64 (E) (M4) (Eng-Spa-Fre-Ger) [!] */ { 0xE48E01F5E6E51F9BULL, 1 }, /* Carmageddon 64 (E) (M4) (Eng-Spa-Fre-Ita) [!] */ { 0xF00F2D4E340FAAF4ULL, 1 }, /* Carmageddon 64 (U) [!] */ { 0xFB3C48D08D28F69FULL, 1 }, /* Charlie Blast's Territory (E) [!] */ { 0x1E0E96E84E28826BULL, 1 }, /* Charlie Blast's Territory (U) [!] */ { 0xF8009DB06B291823ULL, 1 }, /* City-Tour GP - Zennihon GT Senshuken (J) [!] */ { 0x630AA37D896BD7DBULL, 1 }, /* Destruction Derby 64 (E) (M3) [!] */ { 0xDEE584A20F161187ULL, 1 }, /* Destruction Derby 64 (U) [!] */ { 0xC16C421BA21580F7ULL, 3 }, /* Disney's Donald Duck - Goin' Quackers (U) [!] */ { 0xD614E5BFA76DBCC1ULL, 1 }, /* Disney's Tarzan (E) [!] */ { 0x001A3BD0AFB3DE1AULL, 1 }, /* Disney's Tarzan (F) [!] */ { 0x4C2613234F295E1AULL, 1 }, /* Disney's Tarzan (G) [!] */ { 0xCBFE69C7F2C0AB2AULL, 1 }, /* Disney's Tarzan (U) [!] */ { 0x3DF17480193DED5AULL, 3 }, /* Donald Duck - Quack Attack (E) (M5) [!] */ { 0xD52FE29D8EA6A759ULL, 1 }, /* Donchan Puzzle Hanabi de Doon! (J) [ALECK64] */ { 0x11936D8C6F2C4B43ULL, 1 }, /* Donkey Kong 64 (E) [!] */ { 0x053C89A7A5064302ULL, 1 }, /* Donkey Kong 64 (J) [!] */ { 0x0DD4ABABB5A2A91EULL, 1 }, /* Donkey Kong 64 (U) (Kiosk Demo) [!] */ { 0xEC58EABFAD7C7169ULL, 1 }, /* Donkey Kong 64 (U) [!] */ { 0xFBB9F1FA6BF88689ULL, 1 }, /* Duck Dodgers Starring Daffy Duck (U) (M3) [!] */ { 0xDC36626A3F3770CBULL, 1 }, /* Duke Nukem - ZER0 H0UR (E) [!] */ { 0x32CA974BB2C29C50ULL, 1 }, /* Duke Nukem - ZER0 H0UR (F) [!] */ { 0x04DAF07F0D18E688ULL, 1 }, /* Duke Nukem - ZER0 H0UR (U) [!] */ { 0x6D9D1FE484D10BEAULL, 1 }, /* Eleven Beat - World Tournament (J) [ALECK64] */ { 0x202A8EE483F88B89ULL, 1 }, /* Excitebike 64 (E) [!] */ { 0x07861842A12EBC9FULL, 1 }, /* Excitebike 64 (U) [!] */ { 0x66CF0FFEAD697F9CULL, 1 }, /* Fighting Force 64 (E) [!] */ { 0x32EFC7CBC3EA3F20ULL, 1 }, /* Fighting Force 64 (U) [!] */ { 0x22E9623FB60E52ADULL, 1 }, /* Flying Dragon (E) [!] */ { 0xA92D52E51D26B655ULL, 1 }, /* Flying Dragon (U) [!] */ { 0xF774EAEEF0D8B13EULL, 1 }, /* Fushigi no Dungeon - Fuurai no Shiren 2 - Oni Shuurai! Shiren Jou! (J) [!] */ { 0xEE4A0E338FD588C9ULL, 1 }, /* GT 64 - Championship Edition (E) (M3) [!] */ { 0xC49ADCA2F1501B62ULL, 1 }, /* GT 64 - Championship Edition (U) [!] */ { 0xB57D4EB4345E09E5ULL, 1 }, /* Guru - Kuru Kuru Fever (J) [ALECK64] */ { 0x95A80114E0B72A7FULL, 1 }, /* Hamster Monogatari 64 (J) [!] */ { 0x775AFA9C0EB52EF6ULL, 1 }, /* Hard Coded Demo by Silo and Fractal (PD) [a1] */ { 0x98DF9DFC6606C189ULL, 1 }, /* Harvest Moon 64 (U) [!] */ { 0xAE90DBEB79B89123ULL, 1 }, /* Hercules - The Legendary Journeys (E) (M6) [!] */ { 0x7F3CEB778981030AULL, 1 }, /* Hercules - The Legendary Journeys (U) [!] */ { 0x95B2B30B2B6415C1ULL, 1 }, /* Hexen (E) [!] */ { 0x5C1B5FBD7E961634ULL, 1 }, /* Hexen (F) [!] */ { 0x9AB3B50ABC666105ULL, 1 }, /* Hexen (G) [!] */ { 0x66751A5754A29D6EULL, 1 }, /* Hexen (J) [!] */ { 0x35FF8F1A6E79E3BEULL, 1 }, /* Hiryuu no Ken Twin (J) [!] */ { 0x72611D7D9919BDD2ULL, 3 }, /* HSV Adventure Racing (A) [b1] */ { 0xB58988E9B1FC4BE8ULL, 1 }, /* Hydro Thunder (E) [!] */ { 0x29A045CEABA9060EULL, 1 }, /* Hydro Thunder (F) [!] */ { 0xC8DC65EB3D8C8904ULL, 1 }, /* Hydro Thunder (U) [!] */ #ifndef GLES { 0x979B263EF8470004ULL, 1 }, /* Killer Instinct Gold (E) [!] */ { 0x9E8FE2BA8B270770ULL, 1 }, /* Killer Instinct Gold (U) (V1.0) [!] */ { 0xCB06B744633194DBULL, 1 }, /* Killer Instinct Gold (U) (V1.0) [b1][t1] */ { 0x06CB44B73163DB94ULL, 1 }, /* Killer Instinct Gold (U) (V1.0) [b2] */ { 0x9E8FE2BA8B270770ULL, 1 }, /* Killer Instinct Gold (U) (V1.0) [o1] */ { 0x06CB44B73163DB94ULL, 1 }, /* Killer Instinct Gold (U) (V1.0) [t1] */ { 0xCB06B744633194DBULL, 1 }, /* Killer Instinct Gold (U) (V1.0) [t2] */ { 0x9E8FCDFA49F5652BULL, 1 }, /* Killer Instinct Gold (U) (V1.1) [!] */ { 0xF908CA4C36464327ULL, 1 }, /* Killer Instinct Gold (U) (V1.2) [!] */ { 0x06CB44B73163DB94ULL, 1 }, /* Killer Instinct Gold (U) (V1.2) [b1] */ { 0xF908CA4C36464327ULL, 1 }, /* Killer Instinct Gold (U) (V1.2) [o1] */ #endif { 0x8C138BE095700E46ULL, 1 }, /* In-Fisherman Bass Hunter 64 (U) [!] */ { 0xE2D37CF0F57E4EAEULL, 1 }, /* International Superstar Soccer 64 (E) [!] */ { 0x5F2763C462412AE5ULL, 1 }, /* International Superstar Soccer 64 (U) [!] */ { 0x6EDD4766A93E9BA8ULL, 3 }, /* Jikkyou Powerful Pro Yakyuu - Basic Han 2001 (J) [!] */ { 0xE0A79F8C32CC97FAULL, 1 }, /* Jikkyou World Soccer 3 (J) [!] */ { 0xF478D8B39716DD6DULL, 3 }, /* LEGO Racers (E) (M10) [!] */ { 0x096A40EA8ABE0A10ULL, 3 }, /* LEGO Racers (U) (M10) [b1] */ { 0xFBB9F1FA6BF88689ULL, 1 }, /* Lt. Duck Dodgers (Prototype) */ { 0x0CB816865FD85A81ULL, 1 }, /* Madden NFL 2000 (U) [!] */ { 0xEB38F792190EA246ULL, 1 }, /* Madden NFL 2001 (U) [!] */ { 0xD7134F8DC11A00B5ULL, 1 }, /* Madden NFL 2002 (U) [!] */ { 0x3925D6258C83C75EULL, 1 }, /* Madden NFL 99 (E) [!] */ { 0xDEB78BBA52F6BD9DULL, 1 }, /* Madden NFL 99 (U) [!] */ { 0xD5356BAC97AE69D2ULL, 1 }, /* Magical Tetris Challenge Featuring Mickey (J) [ALECK64] */ { 0x9C66306980F24A80ULL, 1 }, /* Mario Party (E) (M3) [!] */ { 0xADA815BE6028622FULL, 1 }, /* Mario Party (J) [!] */ { 0x2829657EA0621877ULL, 1 }, /* Mario Party (U) [!] */ { 0x82380387DFC744D9ULL, 1 }, /* Mario Party 2 (E) (M5) [!] */ { 0xED567D0F38B08915ULL, 1 }, /* Mario Party 2 (J) [!] */ { 0x9EA95858AF72B618ULL, 1 }, /* Mario Party 2 (U) [!] */ { 0xC56741600F5F453CULL, 1 }, /* Mario Party 3 (E) (M4) [!] */ { 0x0B0AB4CD7B158937ULL, 1 }, /* Mario Party 3 (J) [!] */ { 0x7C3829D96E8247CEULL, 1 }, /* Mario Party 3 (U) [!] */ { 0x3BA7CDDC464E52A0ULL, 1 }, /* Mario Story (J) [!] */ { 0x5AC383E1D712E387ULL, 1 }, /* Monopoly (U) [!] */ { 0xD3D806FCB43AA2A8ULL, 3 }, /* Monster Truck Madness 64 (E) (M5) [!] */ { 0xB19AD9997E585118ULL, 3 }, /* Monster Truck Madness 64 (U) [!] */ { 0x7F9345D3841ECADEULL, 1 }, /* Mystical Ninja 2 Starring Goemon (E) (M3) [!] */ { 0xA292524F3D6C2A49ULL, 1 }, /* NBA In the Zone '99 (U) [!] */ { 0x3FFE80F4A7C15F7EULL, 1 }, /* NBA Showtime - NBA on NBC (U) [!] */ { 0x2857674DCC4337DAULL, 1 }, /* Nightmare Creatures (U) [!] */ { 0xCD3C3CDF317793FAULL, 1 }, /* Nintama Rantarou 64 Game Gallery (J) [!] */ { 0x8A97A197272DF6C1ULL, 1 }, /* Nuclear Strike 64 (E) (M2) [!] */ { 0x8F50B845D729D22FULL, 1 }, /* Nuclear Strike 64 (G) [!] */ { 0x4998DDBBF7B7AEBCULL, 1 }, /* Nuclear Strike 64 (U) [!] */ { 0xD83BB920CC406416ULL, 1 }, /* Nushi Tsuri 64 (J) [!] */ { 0x19AB29AFC71BCD28ULL, 1 }, /* Paper Mario (E) (M4) [!] */ { 0x65EEE53AED7D733CULL, 1 }, /* Paper Mario (U) [!] */ { 0x1AA05AD546F52D80ULL, 3 }, /* Pilotwings 64 (E) (M3) [!] */ { 0x09CC4801E42EE491ULL, 3 }, /* Pilotwings 64 (J) [!] */ { 0xC851961C78FCAAFAULL, 3 }, /* Pilotwings 64 (U) [!] */ { 0x9BA10C4E0408ABD3ULL, 1 }, /* Pro Mahjong Kiwame 64 (J) [!] */ { 0x1BDCB30FA132D876ULL, 1 }, /* Pro Mahjong Tsuwamono 64 - Jansou Battle ni Chousen (J) [!] */ { 0x7433D9D72C4322D0ULL, 1 }, /* Quake II (E) [!] */ { 0xBDA8F143B1AF2D62ULL, 1 }, /* Quake II (U) [!] */ { 0x3918834A15B50C29ULL, 1 }, /* Razor Freestyle Scooter (U) [!] */ { 0xE921953313FBAFBDULL, 1 }, /* Ready 2 Rumble Boxing - Round 2 (U) [!] */ { 0x9B500E8EE90550B3ULL, 1 }, /* Resident Evil 2 (E) (M2) [!] */ { 0x2F493DD02E64DFD9ULL, 1 }, /* Resident Evil 2 (U) [!] */ { 0xAA18B1A507DB6AEBULL, 1 }, /* Resident Evil 2 (U) (V1.1) [!] */ { 0x02D8366A6CABEF9CULL, 3 }, /* Road Rash 64 (E) [!] */ { 0xF050746C247B820BULL, 3 }, /* Road Rash 64 (U) [!] */ { 0x0B6B4DDB9671E682ULL, 1 }, /* Roadsters Trophy (U) (M3) [!] */ { 0xB7CF2136FA0AA715ULL, 1 }, /* Rush 2 - Extreme Racing USA (E) (M6) [!] */ { 0xEDD6E03168136013ULL, 1 }, /* Rush 2 - Extreme Racing USA (U) [!] */ { 0x51D29418D5B46AE3ULL, 1 }, /* San Francisco Rush 2049 (E) (M6) [!] */ { 0xB9A9ECA217AAE48EULL, 1 }, /* San Francisco Rush 2049 (U) [!] */ { 0x315C74663A453265ULL, 1 }, /* Star Soldier - Vanishing Earth (J) [!] [ALECK64] */ { 0x60C437E5A2251EE3ULL, 1 }, /* Shadow Man (E) (M3) [!] */ { 0xEA06F8C307C2DEEDULL, 1 }, /* Shadow Man (F) [!] */ { 0x84D5FD75BBFD3CDFULL, 1 }, /* Shadow Man (G) [!] */ { 0x3A4760B52D74D410ULL, 1 }, /* Shadow Man (U) [!] */ { 0xD137A2CA62B65053ULL, 1 }, /* Shigesato Itoi's No. 1 Bass Fishing! Definitive Edition (J) [!] */ { 0xA3A044B56DB1BF5EULL, 1 }, /* Spacer by Memir (POM '99) (PD) */ { 0xE0C4F72F769E1506ULL, 1 }, /* Tigger's Honey Hunt (E) (M7) [!] */ { 0x4EBFDD33664C9D84ULL, 1 }, /* Tigger's Honey Hunt (U) [!] */ { 0x90AF8D2CE1AC1B37ULL, 1 }, /* Tower & Shaft (J) [ALECK64] */ { 0xCCEB385826952D97ULL, 1 }, /* Toy Story 2 (E) [!] */ { 0xCB93DB977F5C63D5ULL, 1 }, /* Toy Story 2 (F) [!] */ { 0x782A9075E552631DULL, 1 }, /* Toy Story 2 (G) [!] */ { 0xA150743ECF2522CDULL, 1 }, /* Toy Story 2 (U) [!] */ { 0xFE4B6B43081D29A7ULL, 1 }, /* Triple Play 2000 (U) [!] */ { 0x28D5562DE4D5AE50ULL, 1 }, /* Uchhannanchan no Hono no Challenger - Denryu IraIra Bou (J) [!] */ { 0x151F79F48EEDC8E5ULL, 1 }, /* Vigilante 8 (E) [!] */ { 0xE2BC82A2591CD694ULL, 1 }, /* Vigilante 8 (F) [!] */ { 0x6EDA5178D396FEC1ULL, 1 }, /* Vigilante 8 (G) [!] */ { 0xEA71056AE4214847ULL, 1 }, /* Vigilante 8 (U) [!] */ { 0xDD10BC7EF900B351ULL, 1 }, /* Vigilante 8 - 2nd Offence (E) [!] */ { 0xF5C5866D052713D9ULL, 1 }, /* Vigilante 8 - 2nd Offense (U) [!] */ { 0x98F9F2D003D9F09CULL, 1 }, /* Virtual Pool 64 (E) [!] */ { 0x4E4A7643A37439D7ULL, 1 }, /* Virtual Pool 64 (U) [!] */ { 0x2F57C9F7F1E29CA6ULL, 1 }, /* Vivid Dolls (J) [ALECK64] */ { 0xD715CC70271CF5D6ULL, 1 }, /* War Gods (E) [!] */ { 0xF7FE28F6C3F2ACC3ULL, 1 }, /* War Gods (U) [!] */ { 0x535DF3E2609789F1ULL, 3 }, /* Wave Race 64 - Shindou Edition (J) (V1.2) [!] */ { 0xD4C45A1AF425B25EULL, 3 }, /* WCW Nitro (U) [!] */ { 0x68E8A8750CE7A486ULL, 1 }, /* WCW-nWo Revenge (E) [!] */ { 0xDEE596ABAF3B7AE7ULL, 1 }, /* WCW-nWo Revenge (U) [!] */ { 0xCEA8B54F7F21D503ULL, 3 }, /* Wetrix (E) (M6) [!] */ { 0xDCB6EAFAC6BBCFA3ULL, 3 }, /* Wetrix (J) [!] */ { 0x54310E7D6B5430D8ULL, 1 }, /* Wipeout 64 (E) [!] */ { 0x132D2732C70E9118ULL, 1 }, /* Wipeout 64 (U) [!] */ { 0x9F8B96C3A01194DCULL, 1 }, /* Yakouchuu II - Satsujin Kouro (J) */ }; mupen64plus-core/src/rsp/rsp_core.h000664 001750 001750 00000006136 12655644434 020435 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - rsp_core.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_RSP_RSP_CORE_H #define M64P_RSP_RSP_CORE_H #include #ifndef RSP_MEM_ADDR #define RSP_MEM_ADDR(a) ((a & 0x1fff) >> 2) #endif #ifndef RSP_REG #define RSP_REG(a) ((a & 0xffff) >> 2) #endif #ifndef RSP_REG2 #define RSP_REG2(a) ((a & 0xffff) >> 2) #endif struct r4300_core; struct rdp_core; struct ri_controller; enum { SP_MEM_SIZE = 0x2000 }; enum sp_registers { SP_MEM_ADDR_REG, SP_DRAM_ADDR_REG, SP_RD_LEN_REG, SP_WR_LEN_REG, SP_STATUS_REG, SP_DMA_FULL_REG, SP_DMA_BUSY_REG, SP_SEMAPHORE_REG, SP_REGS_COUNT }; enum sp_registers2 { SP_PC_REG, SP_IBIST_REG, SP_REGS2_COUNT }; struct rsp_core { uint32_t mem[SP_MEM_SIZE/4]; uint32_t regs[SP_REGS_COUNT]; uint32_t regs2[SP_REGS2_COUNT]; struct r4300_core* r4300; struct rdp_core* dp; struct ri_controller* ri; }; void connect_rsp(struct rsp_core* sp, struct r4300_core* r4300, struct rdp_core* dp, struct ri_controller* ri); void init_rsp(struct rsp_core* sp); int read_rsp_mem(void* opaque, uint32_t address, uint32_t* value); int write_rsp_mem(void* opaque, uint32_t address, uint32_t value, uint32_t mask); int read_rsp_regs(void* opaque, uint32_t address, uint32_t* value); int write_rsp_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask); int read_rsp_regs2(void* opaque, uint32_t address, uint32_t* value); int write_rsp_regs2(void* opaque, uint32_t address, uint32_t value, uint32_t mask); void do_SP_Task(struct rsp_core* sp); void rsp_interrupt_event(struct rsp_core* sp); #endif mupen64plus-core/src/rsp/rsp_core.c000664 001750 001750 00000024644 12655644434 020434 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - rsp_core.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "rsp_core.h" #include "main/main.h" #include "main/profile.h" #include "memory/memory.h" #include "plugin/plugin.h" #include "r4300/r4300_core.h" #include "../rdp/rdp_core.h" #include "../ri/ri_controller.h" #include #include static void dma_sp_write(struct rsp_core* sp, unsigned length, unsigned count, unsigned skip) { unsigned int i,j; unsigned int memaddr = sp->regs[SP_MEM_ADDR_REG] & 0xfff; unsigned int dramaddr = sp->regs[SP_DRAM_ADDR_REG] & 0xffffff; unsigned char *spmem = (unsigned char*)sp->mem + (sp->regs[SP_MEM_ADDR_REG] & 0x1000); unsigned char *dram = (unsigned char*)sp->ri->rdram.dram; for(j = 0; j < count; j++) { for(i = 0; i < length; i++) { spmem[memaddr^S8] = dram[dramaddr^S8]; memaddr++; dramaddr++; } dramaddr+=skip; } } static void dma_sp_read(struct rsp_core* sp, unsigned length, unsigned count, unsigned skip) { unsigned int i,j; unsigned int memaddr = sp->regs[SP_MEM_ADDR_REG] & 0xfff; unsigned int dramaddr = sp->regs[SP_DRAM_ADDR_REG] & 0xffffff; unsigned char *spmem = (unsigned char*)sp->mem + (sp->regs[SP_MEM_ADDR_REG] & 0x1000); unsigned char *dram = (unsigned char*)sp->ri->rdram.dram; for(j = 0; j < count; j++) { for(i = 0; i < length; i++) { dram[dramaddr^S8] = spmem[memaddr^S8]; memaddr++; dramaddr++; } dramaddr+=skip; } } static void update_sp_status(struct rsp_core* sp, uint32_t w) { /* clear / set halt */ if (w & 0x1) sp->regs[SP_STATUS_REG] &= ~0x1; if (w & 0x2) sp->regs[SP_STATUS_REG] |= 0x1; /* clear broke */ if (w & 0x4) sp->regs[SP_STATUS_REG] &= ~0x2; /* clear SP interrupt */ if (w & 0x8) clear_rcp_interrupt(sp->r4300, MI_INTR_SP); /* set SP interrupt */ if (w & 0x10) signal_rcp_interrupt(sp->r4300, MI_INTR_SP); /* clear / set single step */ if (w & 0x20) sp->regs[SP_STATUS_REG] &= ~0x20; if (w & 0x40) sp->regs[SP_STATUS_REG] |= 0x20; /* clear / set interrupt on break */ if (w & 0x80) sp->regs[SP_STATUS_REG] &= ~0x40; if (w & 0x100) sp->regs[SP_STATUS_REG] |= 0x40; /* clear / set signal 0 */ if (w & 0x200) sp->regs[SP_STATUS_REG] &= ~0x80; if (w & 0x400) sp->regs[SP_STATUS_REG] |= 0x80; /* clear / set signal 1 */ if (w & 0x800) sp->regs[SP_STATUS_REG] &= ~0x100; if (w & 0x1000) sp->regs[SP_STATUS_REG] |= 0x100; /* clear / set signal 2 */ if (w & 0x2000) sp->regs[SP_STATUS_REG] &= ~0x200; if (w & 0x4000) sp->regs[SP_STATUS_REG] |= 0x200; /* clear / set signal 3 */ if (w & 0x8000) sp->regs[SP_STATUS_REG] &= ~0x400; if (w & 0x10000) sp->regs[SP_STATUS_REG] |= 0x400; /* clear / set signal 4 */ if (w & 0x20000) sp->regs[SP_STATUS_REG] &= ~0x800; if (w & 0x40000) sp->regs[SP_STATUS_REG] |= 0x800; /* clear / set signal 5 */ if (w & 0x80000) sp->regs[SP_STATUS_REG] &= ~0x1000; if (w & 0x100000) sp->regs[SP_STATUS_REG] |= 0x1000; /* clear / set signal 6 */ if (w & 0x200000) sp->regs[SP_STATUS_REG] &= ~0x2000; if (w & 0x400000) sp->regs[SP_STATUS_REG] |= 0x2000; /* clear / set signal 7 */ if (w & 0x800000) sp->regs[SP_STATUS_REG] &= ~0x4000; if (w & 0x1000000) sp->regs[SP_STATUS_REG] |= 0x4000; //if (get_event(SP_INT)) return; if (!(w & 0x1) && !(w & 0x4)) return; if (!(sp->regs[SP_STATUS_REG] & 0x3)) // !halt && !broke do_SP_Task(sp); } void connect_rsp(struct rsp_core* sp, struct r4300_core* r4300, struct rdp_core* dp, struct ri_controller* ri) { sp->r4300 = r4300; sp->dp = dp; sp->ri = ri; } void init_rsp(struct rsp_core* sp) { memset(sp->mem, 0, SP_MEM_SIZE); memset(sp->regs, 0, SP_REGS_COUNT*sizeof(uint32_t)); memset(sp->regs2, 0, SP_REGS2_COUNT*sizeof(uint32_t)); sp->regs[SP_STATUS_REG] = 1; } int read_rsp_mem(void* opaque, uint32_t address, uint32_t* value) { struct rsp_core* sp = (struct rsp_core*)opaque; uint32_t addr = RSP_MEM_ADDR(address); *value = sp->mem[addr]; return 0; } int write_rsp_mem(void* opaque, uint32_t address, uint32_t value, uint32_t mask) { struct rsp_core* sp = (struct rsp_core*)opaque; uint32_t addr = RSP_MEM_ADDR(address); sp->mem[addr] = MASKED_WRITE(&sp->mem[addr], value, mask); return 0; } int read_rsp_regs(void* opaque, uint32_t address, uint32_t* value) { struct rsp_core* sp = (struct rsp_core*)opaque; uint32_t reg = RSP_REG(address); *value = sp->regs[reg]; if (reg == SP_SEMAPHORE_REG) sp->regs[SP_SEMAPHORE_REG] = 1; return 0; } int write_rsp_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask) { unsigned l, length, count, skip; struct rsp_core* sp = (struct rsp_core*)opaque; uint32_t reg = RSP_REG(address); switch(reg) { case SP_STATUS_REG: update_sp_status(sp, value & mask); case SP_DMA_FULL_REG: case SP_DMA_BUSY_REG: return 0; } sp->regs[reg] = MASKED_WRITE(&sp->regs[reg], value, mask); switch(reg) { case SP_RD_LEN_REG: l = sp->regs[SP_RD_LEN_REG]; length = ((l & 0xfff) | 7) + 1; count = ((l >> 12) & 0xff) + 1; skip = ((l >> 20) & 0xfff); dma_sp_write(sp, length, count, skip); break; case SP_WR_LEN_REG: l = sp->regs[SP_WR_LEN_REG]; length = ((l & 0xfff)) + 1; count = ((l >> 12) & 0xff) + 1; skip = ((l >> 20) & 0xfff); dma_sp_read(sp, length, count, skip); break; case SP_SEMAPHORE_REG: sp->regs[SP_SEMAPHORE_REG] = 0; break; } return 0; } int read_rsp_regs2(void* opaque, uint32_t address, uint32_t* value) { struct rsp_core* sp = (struct rsp_core*)opaque; uint32_t reg = RSP_REG2(address); *value = sp->regs2[reg]; return 0; } int write_rsp_regs2(void* opaque, uint32_t address, uint32_t value, uint32_t mask) { struct rsp_core* sp = (struct rsp_core*)opaque; uint32_t reg = RSP_REG2(address); sp->regs2[reg] = MASKED_WRITE(&sp->regs2[reg], value, mask); return 0; } void do_SP_Task(struct rsp_core* sp) { uint32_t save_pc = sp->regs2[SP_PC_REG] & ~0xfff; unsigned task = sp->mem[0xfc0/4]; if (((sp->regs[SP_STATUS_REG] & 0x00000001) == 0x00000000) && (sp->regs[SP_STATUS_REG] & 0x00000002) == 0x00000000) { if (task == 1) { /* Display list */ if (sp->dp->dpc_regs[DPC_STATUS_REG] & 0x2) // DP frozen (DK64, BC) { // don't do the task now // the task will be done when DP is unfreezed (see update_dpc_status) return; } unprotect_framebuffers(sp->dp); new_frame(); cp0_update_count(); if (sp->r4300->mi.regs[MI_INTR_REG] & MI_INTR_SP) add_interupt_event(SP_INT, 1000); sp->r4300->mi.regs[MI_INTR_REG] &= ~(MI_INTR_SP); sp->regs[SP_STATUS_REG] &= ~0x300; /* task done && yielded */ protect_framebuffers(sp->dp); } else if (task == 2) { /* Audio List */ cp0_update_count(); if (sp->r4300->mi.regs[MI_INTR_REG] & MI_INTR_SP) add_interupt_event(SP_INT, 4000/*500*/); sp->r4300->mi.regs[MI_INTR_REG] &= ~MI_INTR_SP; sp->regs[SP_STATUS_REG] &= ~0x300; /* task done && yielded */ } else { /* Unknown list */ cp0_update_count(); if (sp->r4300->mi.regs[MI_INTR_REG] & MI_INTR_SP) add_interupt_event(SP_INT, 0/*100*/); sp->r4300->mi.regs[MI_INTR_REG] &= ~MI_INTR_SP; sp->regs[SP_STATUS_REG] &= ~0x200; /* task done (SP_STATUS_SIG2) */ } } sp->regs2[SP_PC_REG] &= 0xfff; rsp.doRspCycles(0xffffffff); sp->regs2[SP_PC_REG] |= save_pc; if (task == 1 && (sp->r4300->mi.regs[MI_INTR_REG] & MI_INTR_DP)) { add_interupt_event(DP_INT, 1000); sp->r4300->mi.regs[MI_INTR_REG] &= ~(MI_INTR_DP); } if (((sp->regs[SP_STATUS_REG] & 0x00000001) == 0x00000000) && (sp->regs[SP_STATUS_REG] & 0x00000002) == 0x00000000) { /* needed for games like "Stunt Racer 64" with CPU-RSP timer sync fails */ /* printf( "To do: early RSP exit and task resume (SP_STATUS_REG = %08X)\n", sp->regs[SP_STATUS_REG] ); */ add_interupt_event(SP_INT, 0x200); sp->regs[SP_STATUS_REG] &= ~0x00000003; /* Clear BROKE and HALT. */ } else { sp->regs[SP_STATUS_REG] |= 0x00000003; /* Set BROKE and HALT. */ } } void rsp_interrupt_event(struct rsp_core* sp) { sp->regs[SP_STATUS_REG] |= 0x203; if ((sp->regs[SP_STATUS_REG] & 0x40) != 0) raise_rcp_interrupt(sp->r4300, MI_INTR_SP); } gles2rice/src/DecodedMux.cpp000664 001750 001750 00000142263 12655644434 017122 0ustar00sergiosergio000000 000000 /* Copyright (C) 2002 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include "Combiner.h" #include "Config.h" #include "RenderBase.h" #ifndef min #define min(a,b) ((a) < (b) ? (a) : (b)) #endif #ifndef max #define max(a,b) ((a) > (b) ? (a) : (b)) #endif #define ALLOW_USE_TEXTURE_FOR_CONSTANTS static const uint8_t sc_Mux32[32] = { MUX_COMBINED, MUX_TEXEL0, MUX_TEXEL1, MUX_PRIM, MUX_SHADE, MUX_ENV, MUX_1, MUX_COMBINED|MUX_ALPHAREPLICATE, MUX_TEXEL0|MUX_ALPHAREPLICATE, MUX_TEXEL1|MUX_ALPHAREPLICATE, MUX_PRIM|MUX_ALPHAREPLICATE, MUX_SHADE|MUX_ALPHAREPLICATE, MUX_ENV|MUX_ALPHAREPLICATE, MUX_LODFRAC, MUX_PRIMLODFRAC, MUX_K5, // Actually k5 MUX_UNK, MUX_UNK, MUX_UNK, MUX_UNK, MUX_UNK, MUX_UNK, MUX_UNK, MUX_UNK, MUX_UNK, MUX_UNK, MUX_UNK, MUX_UNK, MUX_UNK, MUX_UNK, MUX_UNK, MUX_0 }; static const uint8_t sc_Mux16[16] = { MUX_COMBINED, MUX_TEXEL0, MUX_TEXEL1, MUX_PRIM, MUX_SHADE, MUX_ENV, MUX_1, MUX_COMBALPHA, MUX_TEXEL0|MUX_ALPHAREPLICATE, MUX_TEXEL1|MUX_ALPHAREPLICATE, MUX_PRIM|MUX_ALPHAREPLICATE, MUX_SHADE|MUX_ALPHAREPLICATE, MUX_ENV|MUX_ALPHAREPLICATE, MUX_LODFRAC, MUX_PRIMLODFRAC, MUX_0 }; static const uint8_t sc_Mux8[8] = { MUX_COMBINED, MUX_TEXEL0, MUX_TEXEL1, MUX_PRIM, MUX_SHADE, MUX_ENV, MUX_1, MUX_0 }; const char * translatedCombTypes[] = { "0", "1", "COMBINED", "TEXEL0", "TEXEL1", "PRIM", "SHADE", "ENV", "COMBALPHA", "T0_ALPHA_wrong", "T1_ALPHA_wrong", "PRIM_ALPHA_wrong", "SHADE_ALPHA_wrong", "ENV_ALPHA_wrong", "LODFRAC", "PRIMLODFRAC", "K5", "UNK", "FACTOR_PRIM_MINUS_ENV", "FACTOR_ENV_MINUS_PRIM", "FACTOR_1_MINUS_PRIM", "FACTOR_0_MINUS_PRIM", "FACTOR_1_MINUS_ENV", "FACTOR_0_MINUS_ENV", "FACTOR_1_MINUS_PRIMALPHA", "FACTOR_1_MINUS_ENVALPHA", "FACTOR_HALF", "PRIM_X_PRIMALPHA", "1_MINUS_PRIM_X_ENV_PLUS_PRIM", "ENV_X_PRIM", "PRIM_X_1_MINUS_ENV", "PRIM_X_PRIM", "ENV_X_ENV", }; const char* muxTypeStrs[] = { "CM_FMT_TYPE_NOT_USED", "CM_FMT_TYPE1_D", "CM_FMT_TYPE2_A_ADD_D", "CM_FMT_TYPE3_A_MOD_C", "CM_FMT_TYPE4_A_SUB_B", "CM_FMT_TYPE5_A_MOD_C_ADD_D", "CM_FMT_TYPE6_A_LERP_B_C", "CM_FMT_TYPE7_A_SUB_B_ADD_D", "CM_FMT_TYPE8_A_SUB_B_MOD_C", "CM_FMT_TYPE9_A_B_C_D", "CM_FMT_TYPE_NOT_CHECKED", }; void DecodedMux::Decode(uint32_t dwMux0, uint32_t dwMux1) { m_dwMux0 = dwMux0; m_dwMux1 = dwMux1; aRGB0 = uint8_t((dwMux0>>20)&0x0F); // c1 c1 // a0 bRGB0 = uint8_t((dwMux1>>28)&0x0F); // c1 c2 // b0 cRGB0 = uint8_t((dwMux0>>15)&0x1F); // c1 c3 // c0 dRGB0 = uint8_t((dwMux1>>15)&0x07); // c1 c4 // d0 aA0 = uint8_t((dwMux0>>12)&0x07); // c1 a1 // Aa0 bA0 = uint8_t((dwMux1>>12)&0x07); // c1 a2 // Ab0 cA0 = uint8_t((dwMux0>>9 )&0x07); // c1 a3 // Ac0 dA0 = uint8_t((dwMux1>>9 )&0x07); // c1 a4 // Ad0 aRGB1 = uint8_t((dwMux0>>5 )&0x0F); // c2 c1 // a1 bRGB1 = uint8_t((dwMux1>>24)&0x0F); // c2 c2 // b1 cRGB1 = uint8_t((dwMux0 )&0x1F); // c2 c3 // c1 dRGB1 = uint8_t((dwMux1>>6 )&0x07); // c2 c4 // d1 aA1 = uint8_t((dwMux1>>21)&0x07); // c2 a1 // Aa1 bA1 = uint8_t((dwMux1>>3 )&0x07); // c2 a2 // Ab1 cA1 = uint8_t((dwMux1>>18)&0x07); // c2 a3 // Ac1 dA1 = uint8_t((dwMux1 )&0x07); // c2 a4 // Ad1 //This function will translate the decode mux info further, so we can use //the decode data better. //Will translate A,B,C,D to unified presentation aRGB0 = sc_Mux16[aRGB0]; bRGB0 = sc_Mux16[bRGB0]; cRGB0 = sc_Mux32[cRGB0]; dRGB0 = sc_Mux8[dRGB0]; aA0 = sc_Mux8[aA0]; bA0 = sc_Mux8[bA0]; cA0 = sc_Mux8[cA0]; dA0 = sc_Mux8[dA0]; aRGB1 = sc_Mux16[aRGB1]; bRGB1 = sc_Mux16[bRGB1]; cRGB1 = sc_Mux32[cRGB1]; dRGB1 = sc_Mux8[dRGB1]; aA1 = sc_Mux8[aA1]; bA1 = sc_Mux8[bA1]; cA1 = sc_Mux8[cA1]; dA1 = sc_Mux8[dA1]; m_bShadeIsUsed[1] = IsUsedInAlphaChannel(MUX_SHADE, MUX_MASK); m_bShadeIsUsed[0] = IsUsedInColorChannel(MUX_SHADE, MUX_MASK); m_bTexel0IsUsed = IsUsed(MUX_TEXEL0, MUX_MASK); m_bTexel1IsUsed = IsUsed(MUX_TEXEL1, MUX_MASK); m_dwShadeColorChannelFlag = 0; m_dwShadeAlphaChannelFlag = 0; m_ColorTextureFlag[0] = 0; m_ColorTextureFlag[1] = 0; } int DecodedMux::Count(uint8_t val, int cycle, uint8_t mask) { uint8_t* pmux = m_bytes; int count=0; int start=0; int end=16; if( cycle >= 0 ) { start = cycle*4; end = start+4; } for( int i=start; i=N64Cycle1RGB ) splitType[i] = CM_FMT_TYPE_NOT_USED; } else if( (m.b == MUX_0 && m.c == MUX_1 && m.d == MUX_0 ) || ( m.c == MUX_1 && m.b==m.d ) ) { splitType[i] = CM_FMT_TYPE_D; //All Type 1 will be changed to = D m.d = m.a; m.a = m.b = m.c = MUX_0; if( m.d == MUX_COMBINED && i>=N64Cycle1RGB ) splitType[i] = CM_FMT_TYPE_NOT_USED; } else if( m.a == MUX_1 && m.b == MUX_0 && m.d == MUX_0 ) { splitType[i] = CM_FMT_TYPE_D; //All Type 1 will be changed to = D m.d = m.c; m.a = m.b = m.c = MUX_0; if( m.d == MUX_COMBINED && i>=N64Cycle1RGB ) splitType[i] = CM_FMT_TYPE_NOT_USED; } else if( m.a == MUX_1 && m.c == MUX_1 && m.d == MUX_0 && do_complement ) { splitType[i] = CM_FMT_TYPE_D; //All Type 1 will be changed to = D m.d = m.b^MUX_COMPLEMENT; m.a = m.b = m.c = MUX_0; if( m.d == MUX_COMBINED && i>=N64Cycle1RGB ) splitType[i] = CM_FMT_TYPE_NOT_USED; } if( splitType[i] == CM_FMT_TYPE_NOT_USED ) continue; if( splitType[i] == CM_FMT_TYPE_D ) { if( (i == N64Cycle0RGB || i == N64Cycle0Alpha) && splitType[i+2]!=CM_FMT_TYPE_NOT_USED ) //Cycle 1's Color or Alpha { uint8_t saveD = m.d; for( int j=0; j<4; j++ ) { if( (m_bytes[j+i*4+8]&MUX_MASK) == MUX_COMBINED ) { m_bytes[j+i*4+8] = saveD|(m_bytes[j+i*4+8]&0xC0); //Replace cycle's CMB with D from cycle 1 } } m_dWords[i] = m_dWords[i+2]; splitType[i+2]=CM_FMT_TYPE_NOT_USED; m_dWords[i+2] = 0x02000000; i=i-1; // Throw the first cycle result away, use 2nd cycle for the 1st cycle // and then redo the 1st cycle continue; } if( (i==2 || i == 3) && (m.d&MUX_MASK) == MUX_COMBINED ) { splitType[i] = CM_FMT_TYPE_NOT_USED; } continue; } //Type 2: A+D ' ADD //B=0, C=1 = A+D //A=1, B=0 = C+D splitType[i] = CM_FMT_TYPE_A_ADD_D; //All Type 2 will be changed to = A+D if( m.b == MUX_0 && m.c == MUX_1 ) { if( m.d == MUX_TEXEL0 || m.d == MUX_TEXEL1 ) swap(m.a, m.d); if( m.a == MUX_COMBINED ) swap(m.a, m.d); continue; } if( m.a == MUX_1 && m.b == MUX_0 ) { m.a = m.c; //Change format A+D m.c = MUX_1; if( m.d == MUX_TEXEL0 || m.d == MUX_TEXEL1 ) swap(m.a, m.d); continue; } //Type 3: A*C //B=0, D=0 = A*C //A=1, D=0 = (1-A)*C splitType[i] = CM_FMT_TYPE_A_MOD_C; //A*C if( m.b == MUX_0 && m.d == MUX_0 ) { if( m.c == MUX_TEXEL0 || m.c == MUX_TEXEL1 ) swap(m.a, m.c); if( m.a == MUX_COMBINED ) swap(m.a, m.c); continue; } if( m.a == MUX_1 && m.d == MUX_0 && do_complement ) { m.a = m.b^MUX_COMPLEMENT; m.b = MUX_0; if( m.c == MUX_TEXEL0 || m.c == MUX_TEXEL1 ) swap(m.a, m.c); if( m.a == MUX_COMBINED ) swap(m.a, m.c); continue; } //Type 4: A-B ' SUB //C=1, D=0 = A-B splitType[i] = CM_FMT_TYPE_A_SUB_B; //A-B if( m.c == MUX_1 && m.d == MUX_0 ) { continue; } //Type 5: A*C+D , ' MULTIPLYADD //B=0 = A*C+D //A=1 = (1-B) * C + D splitType[i] = CM_FMT_TYPE_A_MOD_C_ADD_D; if( m.b == MUX_0 ) { if( m.c == MUX_TEXEL0 || m.c == MUX_TEXEL1 ) swap(m.a, m.c); if( m.a == MUX_COMBINED ) swap(m.a, m.c); continue; } if( m.a == MUX_1 && m.b!=m.d && do_complement ) { m.a = m.b^MUX_COMPLEMENT; m.b = MUX_0; if( m.c == MUX_TEXEL0 || m.c == MUX_TEXEL1 ) swap(m.a, m.c); if( m.a == MUX_COMBINED ) swap(m.a, m.c); continue; } //Type 6: (A-B)*C+B Map to LERP, or BLENDALPHA //D==B splitType[i] = CM_FMT_TYPE_A_LERP_B_C; if( m.b == m.d ) { continue; } //Type 7: A-B+D //C=1 = A-B+D splitType[i] = CM_FMT_TYPE_A_SUB_B_ADD_D; if( m.c == MUX_1 ) { if( m.c == MUX_TEXEL0 || m.c == MUX_TEXEL1 ) swap(m.a, m.c); continue; } //Type 8: (A-B)*C splitType[i] = CM_FMT_TYPE_A_SUB_B_MOD_C; if( m.d == MUX_0 ) { continue; } if( m.c == m.d && do_complement ) // (A-B)*C+C ==> (A + B|C ) * C { m.d = MUX_0; m.b |= MUX_COMPLEMENT; continue; } if( m.a == m.d ) { splitType[i] = CM_FMT_TYPE_A_B_C_A; continue; } //Type 9: (A-B)*C+D splitType[i] = CM_FMT_TYPE_A_B_C_D; } if ((splitType[0] == CM_FMT_TYPE_D && splitType[2]!= CM_FMT_TYPE_NOT_USED ) || //Cycle 1 Color (!IsUsedInCycle(MUX_COMBINED, 1, COLOR_CHANNEL, MUX_MASK) && !IsUsedInCycle(MUX_COMBINED, 1, ALPHA_CHANNEL, MUX_MASK) && splitType[2]!= CM_FMT_TYPE_NOT_USED)) { //Replace cycle 1 color with cycle 2 color because we have already replace cycle2's cmb aRGB0 = aRGB1; bRGB0 = bRGB1; cRGB0 = cRGB1; dRGB0 = dRGB1; aRGB1 = MUX_0; bRGB1 = MUX_0; cRGB1 = MUX_0; dRGB1 = MUX_COMBINED; splitType[0] = splitType[2]; splitType[2] = CM_FMT_TYPE_NOT_USED; } if ((splitType[1] == CM_FMT_TYPE_D && splitType[3]!= CM_FMT_TYPE_NOT_USED ) || //Cycle 2 Alpha (!IsUsedInCycle(MUX_COMBINED, 1, ALPHA_CHANNEL, MUX_MASK) && !IsUsedInCycle(MUX_COMBINED|MUX_ALPHAREPLICATE, 1, COLOR_CHANNEL, MUX_MASK_WITH_ALPHA) && splitType[3]!= CM_FMT_TYPE_NOT_USED)) { //Replace cycle 1 alpha with cycle 2 alpha because we have already replace cycle2's cmb aA0 = aA1; bA0 = bA1; cA0 = cA1; dA0 = dA1; aA1 = MUX_0; bA1 = MUX_0; cA1 = MUX_0; dA1 = MUX_COMBINED; splitType[1] = splitType[3]; splitType[3] = CM_FMT_TYPE_NOT_USED; } if( splitType[0] == CM_FMT_TYPE_A_MOD_C && splitType[2] == CM_FMT_TYPE_A_ADD_D ) { m_n64Combiners[0].d = (m_n64Combiners[2].a & MUX_MASK) == MUX_COMBINED ? m_n64Combiners[2].d : m_n64Combiners[2].a; splitType[0] = CM_FMT_TYPE_A_MOD_C_ADD_D; splitType[2] = CM_FMT_TYPE_NOT_USED; m_n64Combiners[2].a = MUX_0; m_n64Combiners[2].c = MUX_0; m_n64Combiners[2].d = MUX_COMBINED; } if( splitType[1] == CM_FMT_TYPE_A_MOD_C && splitType[3] == CM_FMT_TYPE_A_ADD_D ) { m_n64Combiners[1].d = (m_n64Combiners[3].a & MUX_MASK) == MUX_COMBINED ? m_n64Combiners[3].d : m_n64Combiners[3].a; splitType[1] = CM_FMT_TYPE_A_MOD_C_ADD_D; splitType[3] = CM_FMT_TYPE_NOT_USED; m_n64Combiners[3].a = MUX_0; m_n64Combiners[3].c = MUX_0; m_n64Combiners[3].d = MUX_COMBINED; } signed cond3 = max(splitType[0], splitType[1]); signed cond2 = max(cond3, splitType[2]); mType = (CombinerFormatType)max(cond2,splitType[3]); } const char* MuxGroupStr[4] = { "Color0", "Alpha0", "Color1", "Alpha1", }; char* DecodedMux::FormatStr(uint8_t val, char *buf) { if( val == CM_IGNORE_BYTE ) { strcpy(buf," "); } else { strcpy(buf, translatedCombTypes[val&MUX_MASK]); if( val&MUX_ALPHAREPLICATE ) strcat(buf,"|A"); if( val&MUX_COMPLEMENT ) strcat(buf,"|C"); if( val&MUX_NEG ) strcat(buf,"|N"); } return buf; } void DecodedMux::Display(bool simplified, FILE *fp) { DecodedMux decodedMux; DecodedMux *mux; if (simplified) { mux = this; } else { decodedMux.Decode(m_dwMux0, m_dwMux1); mux = &decodedMux; } char buf0[30]; char buf1[30]; char buf2[30]; char buf3[30]; for (int i=0; i<2; i++) { for (int j=0; j<2; j++) { N64CombinerType &m = mux->m_n64Combiners[i+2*j]; if (fp != NULL) { fprintf(fp,"%s: (%s - %s) * %s + %s\n", MuxGroupStr[i+2*j], FormatStr(m.a,buf0), FormatStr(m.b,buf1), FormatStr(m.c,buf2), FormatStr(m.d,buf3)); } else { DebuggerAppendMsg("%s: (%s - %s) * %s + %s\n", MuxGroupStr[i+2*j], FormatStr(m.a,buf0), FormatStr(m.b,buf1), FormatStr(m.c,buf2), FormatStr(m.d,buf3)); } } } } int DecodedMux::HowManyConstFactors() { int n = 0; if (IsUsed(MUX_PRIM, MUX_MASK)) n++; if (IsUsed(MUX_ENV, MUX_MASK)) n++; if (IsUsed(MUX_LODFRAC, MUX_MASK)) n++; if (IsUsed(MUX_PRIMLODFRAC, MUX_MASK)) n++; return n; } int DecodedMux::HowManyTextures() { int n = 0; if (IsUsed(MUX_TEXEL0, MUX_MASK)) n++; if (IsUsed(MUX_TEXEL1, MUX_MASK)) n++; return n; } int DecodedMux::CountTexels(void) { int count=0; for (int i=0; i<4; i++) { N64CombinerType &m = m_n64Combiners[i]; count = max(count, ::CountTexel1Cycle(m)); if (count == 2) break; } return count; } void DecodedMux::ReplaceVal(uint8_t val1, uint8_t val2, int cycle, uint8_t mask) { int start = 0; int end = 16; if (cycle >= 0) { start = cycle*4; end = start+4; } uint8_t* pmux = m_bytes; for (int i=start; im_maxConstants; if (!IsUsedInColorChannel(MUX_SHADE, MUX_MASK) && (forceToUsed || max(splitType[0], splitType[2]) >= CM_FMT_TYPE_A_MOD_C_ADD_D)) { int countEnv = Count(MUX_ENV, N64Cycle0RGB, mask) + Count(MUX_ENV, N64Cycle1RGB, mask); int countPrim = Count(MUX_PRIM, N64Cycle0RGB, mask) + Count(MUX_PRIM, N64Cycle1RGB, mask); if (countEnv+countPrim > 0) { if (countPrim >= countEnv) { //TRACE0("Use Shade for PRIM in color channel"); ReplaceVal(MUX_PRIM, MUX_SHADE, N64Cycle0RGB, MUX_MASK); ReplaceVal(MUX_PRIM, MUX_SHADE, N64Cycle1RGB, MUX_MASK); m_dwShadeColorChannelFlag = MUX_PRIM; } else if (countEnv > 0) { //TRACE0("Use Shade for ENV in color channel"); ReplaceVal(MUX_ENV, MUX_SHADE, N64Cycle0RGB, MUX_MASK); ReplaceVal(MUX_ENV, MUX_SHADE, N64Cycle1RGB, MUX_MASK); m_dwShadeColorChannelFlag = MUX_ENV; } if (IsUsedInColorChannel(MUX_SHADE|MUX_ALPHAREPLICATE, mask)) { m_dwShadeAlphaChannelFlag = m_dwShadeColorChannelFlag; ReplaceVal((uint8_t)m_dwShadeColorChannelFlag, MUX_SHADE, N64Cycle0Alpha, MUX_MASK); ReplaceVal((uint8_t)m_dwShadeColorChannelFlag, MUX_SHADE, N64Cycle1Alpha, MUX_MASK); doAlphaChannel = false; } } } if (doAlphaChannel && !IsUsedInAlphaChannel(MUX_SHADE, MUX_MASK) && !IsUsedInColorChannel(MUX_SHADE|MUX_ALPHAREPLICATE, MUX_MASK_WITH_ALPHA)) { int countEnv = Count(MUX_ENV|MUX_ALPHAREPLICATE, N64Cycle0RGB, mask) + Count(MUX_ENV|MUX_ALPHAREPLICATE, N64Cycle1RGB, mask); int countPrim = Count(MUX_PRIM|MUX_ALPHAREPLICATE, N64Cycle0RGB, mask) + Count(MUX_PRIM|MUX_ALPHAREPLICATE, N64Cycle1RGB, mask); if (forceToUsed || max(splitType[1], splitType[3]) >= CM_FMT_TYPE_A_MOD_C_ADD_D || (max(splitType[0], splitType[2]) >= CM_FMT_TYPE_A_MOD_C_ADD_D && countEnv+countPrim > 0 )) { countEnv = Count(MUX_ENV, N64Cycle0Alpha, MUX_MASK) + Count(MUX_ENV, N64Cycle1Alpha, MUX_MASK) + Count(MUX_ENV|MUX_ALPHAREPLICATE, N64Cycle0RGB, mask) + Count(MUX_ENV|MUX_ALPHAREPLICATE, N64Cycle1RGB, mask); countPrim = Count(MUX_PRIM, N64Cycle0Alpha, MUX_MASK) + Count(MUX_PRIM, N64Cycle1Alpha, MUX_MASK) + Count(MUX_PRIM|MUX_ALPHAREPLICATE, N64Cycle0RGB, mask) + Count(MUX_PRIM|MUX_ALPHAREPLICATE, N64Cycle1RGB, mask); if (countEnv+countPrim > 0) { if (countPrim > 0 && m_dwShadeColorChannelFlag == MUX_PRIM) { //TRACE0("Use Shade for PRIM in alpha channel"); ReplaceVal(MUX_PRIM, MUX_SHADE, N64Cycle0Alpha, MUX_MASK); ReplaceVal(MUX_PRIM, MUX_SHADE, N64Cycle1Alpha, MUX_MASK); ReplaceVal(MUX_PRIM|MUX_ALPHAREPLICATE, MUX_SHADE|MUX_ALPHAREPLICATE, N64Cycle0RGB, mask); ReplaceVal(MUX_PRIM|MUX_ALPHAREPLICATE, MUX_SHADE|MUX_ALPHAREPLICATE, N64Cycle1RGB, mask); m_dwShadeAlphaChannelFlag = MUX_PRIM; } else if (countEnv>0 && m_dwShadeColorChannelFlag == MUX_ENV) { //TRACE0("Use Shade for PRIM in alpha channel"); ReplaceVal(MUX_ENV, MUX_SHADE, N64Cycle0Alpha, MUX_MASK); ReplaceVal(MUX_ENV, MUX_SHADE, N64Cycle1Alpha, MUX_MASK); ReplaceVal(MUX_ENV|MUX_ALPHAREPLICATE, MUX_SHADE|MUX_ALPHAREPLICATE, N64Cycle0RGB, mask); ReplaceVal(MUX_ENV|MUX_ALPHAREPLICATE, MUX_SHADE|MUX_ALPHAREPLICATE, N64Cycle1RGB, mask); m_dwShadeAlphaChannelFlag = MUX_ENV; } else if (countPrim >= countEnv) { //TRACE0("Use Shade for PRIM in alpha channel"); ReplaceVal(MUX_PRIM, MUX_SHADE, N64Cycle0Alpha, MUX_MASK); ReplaceVal(MUX_PRIM, MUX_SHADE, N64Cycle1Alpha, MUX_MASK); ReplaceVal(MUX_PRIM|MUX_ALPHAREPLICATE, MUX_SHADE|MUX_ALPHAREPLICATE, N64Cycle0RGB, mask); ReplaceVal(MUX_PRIM|MUX_ALPHAREPLICATE, MUX_SHADE|MUX_ALPHAREPLICATE, N64Cycle1RGB, mask); m_dwShadeAlphaChannelFlag = MUX_PRIM; } else if (countEnv > 0) { //TRACE0("Use Shade for ENV in alpha channel"); ReplaceVal(MUX_ENV, MUX_SHADE, N64Cycle0Alpha, MUX_MASK); ReplaceVal(MUX_ENV, MUX_SHADE, N64Cycle1Alpha, MUX_MASK); ReplaceVal(MUX_ENV|MUX_ALPHAREPLICATE, MUX_SHADE|MUX_ALPHAREPLICATE, N64Cycle0RGB, mask); ReplaceVal(MUX_ENV|MUX_ALPHAREPLICATE, MUX_SHADE|MUX_ALPHAREPLICATE, N64Cycle1RGB, mask); m_dwShadeAlphaChannelFlag = MUX_ENV; } } } } } void DecodedMux::UseTextureForConstant(void) { int numofconst = HowManyConstFactors(); int numOftex = HowManyTextures(); if (numofconst > m_maxConstants && numOftex < m_maxTextures) { // We can use a texture for a constant for (int i=0; i<2 && numofconst > m_maxConstants ; i++) { if (IsUsed(MUX_TEXEL0+i, MUX_MASK)) { continue; // can not use this texture } if (IsUsed(MUX_PRIM, MUX_MASK)) { ReplaceVal(MUX_PRIM, MUX_TEXEL0+i, -1, MUX_MASK); m_ColorTextureFlag[i] = MUX_PRIM; numofconst--; continue; } if (IsUsed(MUX_ENV, MUX_MASK)) { ReplaceVal(MUX_ENV, MUX_TEXEL0+i, -1, MUX_MASK); m_ColorTextureFlag[i] = MUX_ENV; numofconst--; continue; } if (IsUsed(MUX_LODFRAC, MUX_MASK)) { ReplaceVal(MUX_LODFRAC, MUX_TEXEL0+i, -1, MUX_MASK); m_ColorTextureFlag[i] = MUX_LODFRAC; numofconst--; continue; } if (IsUsed(MUX_PRIMLODFRAC, MUX_MASK)) { ReplaceVal(MUX_PRIMLODFRAC, MUX_TEXEL0+i, -1, MUX_MASK); m_ColorTextureFlag[i] = MUX_PRIMLODFRAC; numofconst--; continue; } } } } void DecodedMuxForOGL14V2::UseTextureForConstant(void) { bool envused = IsUsed(MUX_ENV, MUX_MASK); bool lodused = IsUsed(MUX_LODFRAC, MUX_MASK); int numofconst = 0; if (envused) numofconst++; if (lodused) numofconst++; int numOftex = HowManyTextures(); if (numofconst > 0 && numOftex < 2) { // We can use a texture for a constant for (int i=0; i<2 && numofconst > 0 ; i++) { if (IsUsed(MUX_TEXEL0+i, MUX_MASK)) { continue; // can not use this texture } if (envused) { ReplaceVal(MUX_ENV, MUX_TEXEL0+i, -1, MUX_MASK); m_ColorTextureFlag[i] = MUX_ENV; numofconst--; envused = false; continue; } if (IsUsed(MUX_LODFRAC, MUX_MASK)) { ReplaceVal(MUX_LODFRAC, MUX_TEXEL0+i, -1, MUX_MASK); m_ColorTextureFlag[i] = MUX_LODFRAC; numofconst--; continue; } if (IsUsed(MUX_PRIMLODFRAC, MUX_MASK)) { ReplaceVal(MUX_PRIMLODFRAC, MUX_TEXEL0+i, -1, MUX_MASK); m_ColorTextureFlag[i] = MUX_PRIMLODFRAC; numofconst--; continue; } } } } #ifdef DEBUGGER extern const char *translatedCombTypes[]; void DecodedMux::DisplayMuxString(const char *prompt) { DebuggerAppendMsg("//Mux=0x%08x%08x\t%s in %s\n", m_dwMux0, m_dwMux1, prompt, g_curRomInfo.szGameName); Display(false, NULL); TRACE0("\n"); } void DecodedMux::DisplaySimpliedMuxString(const char *prompt) { DebuggerAppendMsg("//Simplified Mux=0x%08x%08x\t%s in %s\n", m_dwMux0, m_dwMux1, prompt, g_curRomInfo.szGameName); DebuggerAppendMsg("Simplified DWORDs=%08X, %08X, %08X, %08X", m_dWords[0],m_dWords[1],m_dWords[2],m_dWords[3]); Display(true, NULL); DebuggerAppendMsg("Simplified type: %s", muxTypeStrs[mType]); if( m_dwShadeColorChannelFlag != 0 ) { if( m_dwShadeColorChannelFlag == MUX_ENV ) TRACE0("Shade = ENV in color channel") else if( m_dwShadeColorChannelFlag == MUX_PRIM ) TRACE0("Shade = PRIM in color channel") else if( m_dwShadeColorChannelFlag == MUX_LODFRAC ) TRACE0("Shade = MUX_LODFRAC in color channel") else if( m_dwShadeColorChannelFlag == MUX_PRIMLODFRAC ) TRACE0("Shade = MUX_PRIMLODFRAC in color channel") else DisplayConstantsWithShade(m_dwShadeColorChannelFlag,COLOR_CHANNEL); } if( m_dwShadeAlphaChannelFlag != 0 ) { if( m_dwShadeAlphaChannelFlag == MUX_ENV ) TRACE0("Shade = ENV in alpha channel") else if( m_dwShadeAlphaChannelFlag == MUX_PRIM ) TRACE0("Shade = PRIM in alpha channel") else if( m_dwShadeAlphaChannelFlag == MUX_LODFRAC ) TRACE0("Shade = MUX_LODFRAC in alpha channel") else if( m_dwShadeAlphaChannelFlag == MUX_PRIMLODFRAC ) TRACE0("Shade = MUX_PRIMLODFRAC in alpha channel") else DisplayConstantsWithShade(m_dwShadeAlphaChannelFlag,ALPHA_CHANNEL); } for( int i=0; i<2; i++ ) { if( m_ColorTextureFlag[i] != 0 ) { if( m_ColorTextureFlag[i] == MUX_ENV ) TRACE1("Tex %d = ENV", i) else if( m_ColorTextureFlag[i] == MUX_PRIM ) TRACE1("Tex %d = PRIM", i) else if( m_ColorTextureFlag[i] == MUX_LODFRAC ) TRACE1("Tex %d = MUX_LODFRAC", i) else if( m_ColorTextureFlag[i] == MUX_PRIMLODFRAC ) TRACE1("Tex %d = MUX_PRIMLODFRAC", i) } } TRACE0("\n"); } void DecodedMux::DisplayConstantsWithShade(uint32_t flag,CombineChannel channel) { DebuggerAppendMsg("Shade = %08X in %s channel",flag,channel==COLOR_CHANNEL?"color":"alpha"); } #else extern const char *translatedCombTypes[]; void DecodedMux::LogMuxString(const char *prompt, FILE *fp) { fprintf(fp, "//Mux=0x%08x%08x\t%s in %s\n", m_dwMux0, m_dwMux1, prompt, g_curRomInfo.szGameName); Display(false, fp); TRACE0("\n"); } void DecodedMux::LogSimpliedMuxString(const char *prompt, FILE *fp) { fprintf(fp, "//Simplified Mux=0x%08x%08x\t%s in %s\n", m_dwMux0, m_dwMux1, prompt, g_curRomInfo.szGameName); fprintf(fp, "Simplified DWORDs=%08X, %08X, %08X, %08X\n", m_dWords[0],m_dWords[1],m_dWords[2],m_dWords[3]); Display(true, fp); fprintf(fp, "Simplified type: %s", muxTypeStrs[mType]); if( m_dwShadeColorChannelFlag != 0 ) { if( m_dwShadeColorChannelFlag == MUX_ENV ) TRACE0("Shade = ENV in color channel") else if( m_dwShadeColorChannelFlag == MUX_PRIM ) TRACE0("Shade = PRIM in color channel") else if( m_dwShadeColorChannelFlag == MUX_LODFRAC ) TRACE0("Shade = MUX_LODFRAC in color channel") else if( m_dwShadeColorChannelFlag == MUX_PRIMLODFRAC ) TRACE0("Shade = MUX_PRIMLODFRAC in color channel") else LogConstantsWithShade(m_dwShadeColorChannelFlag,COLOR_CHANNEL,fp); } if( m_dwShadeAlphaChannelFlag != 0 ) { if( m_dwShadeAlphaChannelFlag == MUX_ENV ) TRACE0("Shade = ENV in alpha channel") else if( m_dwShadeAlphaChannelFlag == MUX_PRIM ) TRACE0("Shade = PRIM in alpha channel") else if( m_dwShadeAlphaChannelFlag == MUX_LODFRAC ) TRACE0("Shade = MUX_LODFRAC in alpha channel") else if( m_dwShadeAlphaChannelFlag == MUX_PRIMLODFRAC ) TRACE0("Shade = MUX_PRIMLODFRAC in alpha channel") else LogConstantsWithShade(m_dwShadeAlphaChannelFlag,ALPHA_CHANNEL,fp); } for( int i=0; i<2; i++ ) { if( m_ColorTextureFlag[i] != 0 ) { if( m_ColorTextureFlag[i] == MUX_ENV ) TRACE1("Tex %d = ENV", i) else if( m_ColorTextureFlag[i] == MUX_PRIM ) TRACE1("Tex %d = PRIM", i) else if( m_ColorTextureFlag[i] == MUX_LODFRAC ) TRACE1("Tex %d = MUX_LODFRAC", i) else if( m_ColorTextureFlag[i] == MUX_PRIMLODFRAC ) TRACE1("Tex %d = MUX_PRIMLODFRAC", i) } } TRACE0("\n"); } void DecodedMux::LogConstantsWithShade(uint32_t flag,CombineChannel channel, FILE *fp) { fprintf(fp, "Shade = %08X in %s channel",flag,channel==COLOR_CHANNEL?"color":"alpha"); } #endif void DecodedMux::To_AB_Add_CD_Format(void) // Use by TNT,Geforce { // This function should be called after calling reformat // This function will not be called by default, can be called optionally // by TNT/Geforce combiner compilers for( int i=0; i<2; i++ ) { N64CombinerType &m0 = m_n64Combiners[i]; N64CombinerType &m1 = m_n64Combiners[i+2]; switch( splitType[i] ) { case CM_FMT_TYPE_A_SUB_B_ADD_D: // = A-B+D can not map very well in 1 stage if( splitType[i+2] == CM_FMT_TYPE_NOT_USED ) { m1.a = m0.d; m1.d = MUX_COMBINED; splitType[i+2] = CM_FMT_TYPE_A_ADD_D; m0.d = MUX_0; splitType[i] = CM_FMT_TYPE_A_SUB_B; } else if( splitType[i+2] == CM_FMT_TYPE_A_MOD_C ) { if( (m1.c&MUX_MASK) == MUX_COMBINED ) swap(m1.a, m1.c); m1.b = m1.d = m1.c; m1.c = (m0.d | (m1.a & (~MUX_MASK))); splitType[i+2] = CM_FMT_TYPE_AB_ADD_CD; m0.d = MUX_0; splitType[i] = CM_FMT_TYPE_A_SUB_B; } break; case CM_FMT_TYPE_A_SUB_B_MOD_C: // = (A-B)*C can not map very well in 1 stage m0.d = m0.b; m0.b = m0.c; splitType[i] = CM_FMT_TYPE_AB_SUB_CD; break; case CM_FMT_TYPE_A_ADD_B_MOD_C: // = (A+B)*C can not map very well in 1 stage m0.d = m0.b; m0.b = m0.c; splitType[i] = CM_FMT_TYPE_AB_ADD_CD; break; case CM_FMT_TYPE_A_B_C_D: // = (A-B)*C+D case CM_FMT_TYPE_A_B_C_A: // = (A-B)*C+D if( splitType[i+2] == CM_FMT_TYPE_NOT_USED ) { m1.a = m0.d; m1.d = MUX_COMBINED; splitType[i+2] = CM_FMT_TYPE_A_ADD_D; m0.d = m0.b; m0.b = m0.c; splitType[i] = CM_FMT_TYPE_AB_SUB_CD; } else if( splitType[i+2] == CM_FMT_TYPE_A_MOD_C ) { if( (m1.c&MUX_MASK) == MUX_COMBINED ) swap(m1.a, m1.c); m1.b = m1.d = m1.c; m1.c = (m0.d | (m1.a & (~MUX_MASK))); splitType[i+2] = CM_FMT_TYPE_AB_ADD_CD; m0.d = m0.b; m0.b = m0.c; splitType[i] = CM_FMT_TYPE_AB_ADD_CD; } break; default: break; } } } void DecodedMux::To_AB_Add_C_Format(void) // Use by ATI Radeon { // This function should be called after calling reformat // This function will not be called by default, can be called optionally // by ATI combiner compilers } void DecodedMux::CheckCombineInCycle1(void) { if (IsUsedInCycle(MUX_COMBINED, 0, COLOR_CHANNEL, MUX_MASK)) { ReplaceVal(MUX_COMBINED, MUX_SHADE, 0, MUX_MASK); } if (IsUsedInCycle(MUX_COMBALPHA, 0, COLOR_CHANNEL, MUX_MASK)) { ReplaceVal(MUX_COMBALPHA, MUX_SHADE|MUX_ALPHAREPLICATE, 0, MUX_MASK); } if (IsUsedInCycle(MUX_COMBINED, 0, ALPHA_CHANNEL, MUX_MASK)) { if (cA0 == MUX_COMBINED && cRGB0 == MUX_LODFRAC && bRGB0 == dRGB0 && bA0 == dA0) { cA0 = MUX_LODFRAC; } else { ReplaceVal(MUX_COMBINED, MUX_SHADE, 1, MUX_MASK); } } if (IsUsedInCycle(MUX_COMBALPHA, 0, ALPHA_CHANNEL, MUX_MASK)) { ReplaceVal(MUX_COMBALPHA, MUX_SHADE, 1, MUX_MASK); } } void DecodedMux::SplitComplexStages() { for( int i=0; i<2; i++) // Color channel and alpha channel { if( splitType[i+2] != CM_FMT_TYPE_NOT_USED ) continue; N64CombinerType &m = m_n64Combiners[i]; N64CombinerType &m2 = m_n64Combiners[i+2]; switch( splitType[i] ) { case CM_FMT_TYPE_A_MOD_C_ADD_D: // = A*C+D can mapped to MULTIPLYADD(arg1,arg2,arg0) m2.a = m.d; m2.d = MUX_COMBINED; m2.c = MUX_1; m2.b = 0; splitType[i+2] = CM_FMT_TYPE_A_ADD_D; m.d = MUX_0; splitType[i] = CM_FMT_TYPE_A_MOD_C; break; case CM_FMT_TYPE_A_SUB_B_ADD_D: // = A-B+D can not map very well in 1 stage m2.a = m.d; m2.d = MUX_COMBINED; m2.c = MUX_1; m2.b=0; splitType[i+2] = CM_FMT_TYPE_A_ADD_D; m.d = MUX_0; splitType[i] = CM_FMT_TYPE_A_SUB_B; break; case CM_FMT_TYPE_A_SUB_B_MOD_C: // = (A-B)*C can not map very well in 1 stage m2.a = m.c; m2.c = MUX_COMBINED; m2.d = m2.b=0; splitType[i+2] = CM_FMT_TYPE_A_MOD_C; m.c = MUX_1; splitType[i] = CM_FMT_TYPE_A_SUB_B; break; case CM_FMT_TYPE_A_ADD_B_MOD_C: // = (A+B)*C can not map very well in 1 stage m2.a = m.c; m2.c = MUX_COMBINED; m2.d = m2.b = 0; splitType[i+2] = CM_FMT_TYPE_A_MOD_C; m.c = MUX_1; m.d = m.b; m.b = MUX_0; splitType[i] = CM_FMT_TYPE_A_ADD_D; break; case CM_FMT_TYPE_A_B_C_D: // = (A-B)*C+D can not map very well in 1 stage m2.a = m.d; m2.d = MUX_COMBINED; m2.c = MUX_1; m2.b = 0; splitType[i+2] = CM_FMT_TYPE_A_ADD_D; m.d = MUX_0; splitType[i] = CM_FMT_TYPE_A_SUB_B_MOD_C; break; case CM_FMT_TYPE_A_B_C_A: // = (A-B)*C+A can not map very well in 1 stage m2.a = m.d; m2.d = MUX_COMBINED; m2.c = MUX_1; m2.b = 0; splitType[i+2] = CM_FMT_TYPE_A_ADD_D; m.d = MUX_0; splitType[i] = CM_FMT_TYPE_A_SUB_B_MOD_C; break; default: break; } } //Reformat(true); //UseShadeForConstant(); } void DecodedMux::ConvertLODFracTo0() { ReplaceVal(MUX_LODFRAC, MUX_0, -1, MUX_MASK); ReplaceVal(MUX_PRIMLODFRAC, MUX_0, -1, MUX_MASK); } void DecodedMux::Hack(void) { if( options.enableHackForGames == HACK_FOR_TONYHAWK ) { if( gRSP.curTile == 1 ) { ReplaceVal(MUX_TEXEL1, MUX_TEXEL0, -1, MUX_MASK); } } else if( options.enableHackForGames == HACK_FOR_ZELDA || options.enableHackForGames == HACK_FOR_ZELDA_MM) { if( m_dwMux1 == 0xfffd9238 && m_dwMux0 == 0x00ffadff ) { ReplaceVal(MUX_TEXEL1, MUX_TEXEL0, -1, MUX_MASK); } else if( m_dwMux1 == 0xff5bfff8 && m_dwMux0 == 0x00121603 ) { // The Zelda road trace ReplaceVal(MUX_TEXEL1, MUX_0, -1, MUX_MASK); } } else if( options.enableHackForGames == HACK_FOR_MARIO_TENNIS ) { if( m_dwMux1 == 0xffebdbc0 && m_dwMux0 == 0x00ffb9ff ) { // Player shadow //m_decodedMux.dRGB0 = MUX_TEXEL0; //m_decodedMux.dRGB1 = MUX_COMBINED; cA1 = MUX_TEXEL0; } } else if( options.enableHackForGames == HACK_FOR_MARIO_GOLF ) { // Hack for Mario Golf if( m_dwMux1 == 0xf1ffca7e || m_dwMux0 == 0x00115407 ) { // The grass ReplaceVal(MUX_TEXEL0, MUX_TEXEL1, -1, MUX_MASK); } } else if( options.enableHackForGames == HACK_FOR_TOPGEARRALLY ) { //Mux=0x00317e025ffef3fa Used in TOP GEAR RALLY //Color0: (PRIM - ENV) * TEXEL1 + ENV //Color1: (COMBINED - 0) * TEXEL1 + 0 //Alpha0: (0 - 0) * 0 + TEXEL0 //Alpha1: (0 - 0) * 0 + TEXEL1 if( m_dwMux1 == 0x5ffef3fa || m_dwMux0 == 0x00317e02 ) { // The grass //ReplaceVal(MUX_TEXEL0, MUX_TEXEL1, -1, MUX_MASK); dA1 = MUX_COMBINED; //aA1 = MUX_COMBINED; //cA1 = MUX_TEXEL1; //dA1 = MUX_0; cRGB1 = MUX_TEXEL0; } } } gles2rice/src/TextureManager.cpp000664 001750 001750 00000130316 12655644434 020030 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "ConvertImage.h" #include "DeviceBuilder.h" #include "FrameBuffer.h" #include "RenderBase.h" #include "TextureManager.h" CTextureManager gTextureManager; unsigned int g_maxTextureMemUsage = (5*1024*1024); unsigned int g_amountToFree = (512*1024); bool g_bUseSetTextureMem = false; // Returns the first prime greater than or equal to nFirst inline int GetNextPrime(int nFirst) { int nCurrent = nFirst; // Just make sure it's odd if ((nCurrent % 2) == 0) nCurrent++; for (;;) { // nSqrtCurrent = nCurrent^0.5 + 1 (round up) int nSqrtCurrent = (int)sqrt((double)nCurrent) + 1; bool bIsComposite = false; // Test all odd numbers from 3..nSqrtCurrent for (int i = 3; i <= nSqrtCurrent; i+=2) { if ((nCurrent % i) == 0) { bIsComposite = true; break; } } if (!bIsComposite) { return nCurrent; } // Select next odd candidate... nCurrent += 2; } } /////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////// CTextureManager::CTextureManager() : m_pHead(NULL), m_pCacheTxtrList(NULL), m_numOfCachedTxtrList(809) { m_numOfCachedTxtrList = GetNextPrime(800); m_currentTextureMemUsage = 0; m_pYoungestTexture = NULL; m_pOldestTexture = NULL; m_pCacheTxtrList = new TxtrCacheEntry *[m_numOfCachedTxtrList]; for (uint32_t i = 0; i < m_numOfCachedTxtrList; i++) m_pCacheTxtrList[i] = NULL; memset(&m_blackTextureEntry, 0, sizeof(TxtrCacheEntry)); memset(&m_PrimColorTextureEntry, 0, sizeof(TxtrCacheEntry)); memset(&m_EnvColorTextureEntry, 0, sizeof(TxtrCacheEntry)); memset(&m_LODFracTextureEntry, 0, sizeof(TxtrCacheEntry)); memset(&m_PrimLODFracTextureEntry, 0, sizeof(TxtrCacheEntry)); } CTextureManager::~CTextureManager() { CleanUp(); delete []m_pCacheTxtrList; m_pCacheTxtrList = NULL; } // // Delete all textures. // bool CTextureManager::CleanUp() { RecycleAllTextures(); if (!g_bUseSetTextureMem) { while (m_pHead) { TxtrCacheEntry * pVictim = m_pHead; m_pHead = pVictim->pNext; delete pVictim; } } if( m_blackTextureEntry.pTexture ) delete m_blackTextureEntry.pTexture; if( m_PrimColorTextureEntry.pTexture ) delete m_PrimColorTextureEntry.pTexture; if( m_EnvColorTextureEntry.pTexture ) delete m_EnvColorTextureEntry.pTexture; if( m_LODFracTextureEntry.pTexture ) delete m_LODFracTextureEntry.pTexture; if( m_PrimLODFracTextureEntry.pTexture ) delete m_PrimLODFracTextureEntry.pTexture; memset(&m_blackTextureEntry, 0, sizeof(TxtrCacheEntry)); memset(&m_PrimColorTextureEntry, 0, sizeof(TxtrCacheEntry)); memset(&m_EnvColorTextureEntry, 0, sizeof(TxtrCacheEntry)); memset(&m_LODFracTextureEntry, 0, sizeof(TxtrCacheEntry)); memset(&m_PrimLODFracTextureEntry, 0, sizeof(TxtrCacheEntry)); return true; } bool CTextureManager::TCacheEntryIsLoaded(TxtrCacheEntry *pEntry) { for (int i = 0; i < MAX_TEXTURES; i++) { if (g_textures[i].pTextureEntry == pEntry) return true; } return false; } // Purge any textures whos last usage was over 5 seconds ago void CTextureManager::PurgeOldTextures() { if (m_pCacheTxtrList == NULL) return; if (g_bUseSetTextureMem) return; static const uint32_t dwFramesToKill = 5*30; // 5 secs at 30 fps static const uint32_t dwFramesToDelete = 30*30; // 30 secs at 30 fps for ( uint32_t i = 0; i < m_numOfCachedTxtrList; i++ ) { TxtrCacheEntry * pEntry; TxtrCacheEntry * pNext; pEntry = m_pCacheTxtrList[i]; while (pEntry) { pNext = pEntry->pNext; if ( status.gDlistCount - pEntry->FrameLastUsed > dwFramesToKill && !TCacheEntryIsLoaded(pEntry)) { RemoveTexture(pEntry); } pEntry = pNext; } } // Remove any old textures that haven't been recycled in 1 minute or so // Normally these would be reused TxtrCacheEntry* pPrev = NULL; TxtrCacheEntry* pCurr = m_pHead; TxtrCacheEntry * pNext; while (pCurr) { pNext = pCurr->pNext; if ( status.gDlistCount - pCurr->FrameLastUsed > dwFramesToDelete && !TCacheEntryIsLoaded(pCurr) ) { if (pPrev != NULL) pPrev->pNext = pCurr->pNext; else m_pHead = pCurr->pNext; delete pCurr; pCurr = pNext; } else { pPrev = pCurr; pCurr = pNext; } } } void CTextureManager::RecycleAllTextures() { if (m_pCacheTxtrList == NULL) return; uint32_t dwCount = 0; uint32_t dwTotalUses = 0; m_pYoungestTexture = NULL; m_pOldestTexture = NULL; for (uint32_t i = 0; i < m_numOfCachedTxtrList; i++) { while (m_pCacheTxtrList[i]) { TxtrCacheEntry *pTVictim = m_pCacheTxtrList[i]; m_pCacheTxtrList[i] = pTVictim->pNext; dwTotalUses += pTVictim->dwUses; dwCount++; if (g_bUseSetTextureMem) delete pTVictim; else RecycleTexture(pTVictim); } } } void CTextureManager::RecheckHiresForAllTextures() { if (m_pCacheTxtrList == NULL) return; for (uint32_t i = 0; i < m_numOfCachedTxtrList; i++) { while (m_pCacheTxtrList[i]) { TxtrCacheEntry *pTVictim = m_pCacheTxtrList[i]; m_pCacheTxtrList[i] = pTVictim->pNext; pTVictim->bExternalTxtrChecked = false; } } } // Add to the recycle list void CTextureManager::RecycleTexture(TxtrCacheEntry *pEntry) { if (g_bUseSetTextureMem) return; // Fix me, why I can not reuse the texture in OpenGL, // how can I unload texture from video card memory for OpenGL delete pEntry; } // Search for a texture of the specified dimensions to recycle TxtrCacheEntry * CTextureManager::ReviveTexture( uint32_t width, uint32_t height ) { if (g_bUseSetTextureMem) return NULL; TxtrCacheEntry* pPrev = NULL; TxtrCacheEntry* pCurr = m_pHead; while (pCurr) { if (pCurr->ti.WidthToCreate == width && pCurr->ti.HeightToCreate == height) { // Remove from list if (pPrev != NULL) pPrev->pNext = pCurr->pNext; else m_pHead = pCurr->pNext; return pCurr; } pPrev = pCurr; pCurr = pCurr->pNext; } return NULL; } uint32_t CTextureManager::Hash(uint32_t dwValue) { // Divide by four, because most textures will be on a 4 byte boundry, so bottom four // bits are null return (dwValue>>2) % m_numOfCachedTxtrList; } void CTextureManager::MakeTextureYoungest(TxtrCacheEntry *pEntry) { if (!g_bUseSetTextureMem) return; if (pEntry == m_pYoungestTexture) return; // if its the oldest, then change the oldest pointer if (pEntry == m_pOldestTexture) { m_pOldestTexture = pEntry->pNextYoungest; } // if its a not a new texture, close the gap in the age list // where pEntry use to reside if (pEntry->pNextYoungest != NULL || pEntry->pLastYoungest != NULL) { if (pEntry->pNextYoungest != NULL) { pEntry->pNextYoungest->pLastYoungest = pEntry->pLastYoungest; } if (pEntry->pLastYoungest != NULL) { pEntry->pLastYoungest->pNextYoungest = pEntry->pNextYoungest; } } // this texture is now the youngest, so place it on the end of the list if (m_pYoungestTexture != NULL) { m_pYoungestTexture->pNextYoungest = pEntry; } pEntry->pNextYoungest = NULL; pEntry->pLastYoungest = m_pYoungestTexture; m_pYoungestTexture = pEntry; // if this is the first texture in memory then its also the oldest if (m_pOldestTexture == NULL) { m_pOldestTexture = pEntry; } } void CTextureManager::AddTexture(TxtrCacheEntry *pEntry) { uint32_t dwKey = Hash(pEntry->ti.Address); if (m_pCacheTxtrList == NULL) return; //TxtrCacheEntry **p = &m_pCacheTxtrList[dwKey]; // Add to head (not tail, for speed - new textures are more likely to be accessed next) pEntry->pNext = m_pCacheTxtrList[dwKey]; m_pCacheTxtrList[dwKey] = pEntry; // Move the texture to the top of the age list MakeTextureYoungest(pEntry); } TxtrCacheEntry * CTextureManager::GetTxtrCacheEntry(TxtrInfo * pti) { TxtrCacheEntry *pEntry; if (m_pCacheTxtrList == NULL) return NULL; // See if it is already in the hash table uint32_t dwKey = Hash(pti->Address); for (pEntry = m_pCacheTxtrList[dwKey]; pEntry; pEntry = pEntry->pNext) { if ( pEntry->ti == *pti ) { MakeTextureYoungest(pEntry); return pEntry; } } return NULL; } void CTextureManager::RemoveTexture(TxtrCacheEntry * pEntry) { if (m_pCacheTxtrList == NULL) return; // See if it is already in the hash table uint32_t dwKey = Hash(pEntry->ti.Address); TxtrCacheEntry* pPrev = NULL; TxtrCacheEntry* pCurr = m_pCacheTxtrList[dwKey]; while (pCurr) { // Check that the attributes match if ( pCurr->ti == pEntry->ti ) { if (pPrev != NULL) pPrev->pNext = pCurr->pNext; else m_pCacheTxtrList[dwKey] = pCurr->pNext; if (g_bUseSetTextureMem) { // remove the texture from the age list if (pEntry->pNextYoungest != NULL) { pEntry->pNextYoungest->pLastYoungest = pEntry->pLastYoungest; } if (pEntry->pLastYoungest != NULL) { pEntry->pLastYoungest->pNextYoungest = pEntry->pNextYoungest; } // decrease the mem usage counter m_currentTextureMemUsage -= (pEntry->pTexture->m_dwWidth * pEntry->pTexture->m_dwHeight * 4); delete pEntry; } else { RecycleTexture(pEntry); } break; } pPrev = pCurr; pCurr = pCurr->pNext; } } TxtrCacheEntry * CTextureManager::CreateNewCacheEntry(uint32_t dwAddr, uint32_t dwWidth, uint32_t dwHeight) { TxtrCacheEntry * pEntry = NULL; if (g_bUseSetTextureMem) { uint32_t widthToCreate = dwWidth; uint32_t heightToCreate = dwHeight; unsigned int freeUpSize = (widthToCreate * heightToCreate * 4) + g_amountToFree; // make sure there is enough room for the new texture by deleting old textures while ((m_currentTextureMemUsage + freeUpSize) > g_maxTextureMemUsage && m_pOldestTexture != NULL) { TxtrCacheEntry *nextYoungest = m_pOldestTexture->pNextYoungest; RemoveTexture(m_pOldestTexture); m_pOldestTexture = nextYoungest; //printf("Freeing Texture\n"); } m_currentTextureMemUsage += widthToCreate * heightToCreate * 4; } else { // Find a used texture pEntry = ReviveTexture(dwWidth, dwHeight); } if (pEntry == NULL || g_bUseSetTextureMem) { // Couldn't find on - recreate! pEntry = new TxtrCacheEntry; if (pEntry == NULL) { _VIDEO_DisplayTemporaryMessage("Error to create an texture entry"); return NULL; } pEntry->pTexture = CDeviceBuilder::GetBuilder()->CreateTexture(dwWidth, dwHeight); if (pEntry->pTexture == NULL || pEntry->pTexture->GetTexture() == NULL) { _VIDEO_DisplayTemporaryMessage("Error to create an texture"); TRACE2("Warning, unable to create %d x %d texture!", dwWidth, dwHeight); } else { pEntry->pTexture->m_bScaledS = false; pEntry->pTexture->m_bScaledT = false; } } // Initialize pEntry->ti.Address = dwAddr; pEntry->pNext = NULL; pEntry->pNextYoungest = NULL; pEntry->pLastYoungest = NULL; pEntry->dwUses = 0; pEntry->dwTimeLastUsed = status.gRDPTime; pEntry->dwCRC = 0; pEntry->FrameLastUsed = status.gDlistCount; pEntry->FrameLastUpdated = 0; pEntry->lastEntry = NULL; pEntry->bExternalTxtrChecked = false; pEntry->maxCI = -1; // Add to the hash table AddTexture(pEntry); return pEntry; } // If already in table, return // Otherwise, create surfaces, and load texture into memory uint32_t dwAsmHeight; uint32_t dwAsmPitch; uint32_t dwAsmdwBytesPerLine; uint32_t dwAsmCRC; uint32_t dwAsmCRC2; uint8_t* pAsmStart; TxtrCacheEntry *g_lastTextureEntry=NULL; bool lastEntryModified = false; TxtrCacheEntry * CTextureManager::GetTexture(TxtrInfo * pgti, bool fromTMEM, bool doCRCCheck, bool AutoExtendTexture) { TxtrCacheEntry *pEntry; if( g_curRomInfo.bDisableTextureCRC ) doCRCCheck = false; gRDP.texturesAreReloaded = true; dwAsmCRC = 0; uint32_t dwPalCRC = 0; pEntry = GetTxtrCacheEntry(pgti); bool loadFromTextureBuffer=false; int txtBufIdxToLoadFrom = -1; if( (frameBufferOptions.bCheckRenderTextures&&!frameBufferOptions.bWriteBackBufToRDRAM) || (frameBufferOptions.bCheckBackBufs&&!frameBufferOptions.bWriteBackBufToRDRAM) ) { txtBufIdxToLoadFrom = g_pFrameBufferManager->CheckAddrInRenderTextures(pgti->Address, true); if( txtBufIdxToLoadFrom >= 0 ) { loadFromTextureBuffer = true; // Check if it is the same size, RenderTextureInfo &info = gRenderTextureInfos[txtBufIdxToLoadFrom]; //if( info.pRenderTexture && info.CI_Info.dwAddr == pgti->Address && info.CI_Info.dwFormat == pgti->Format if( info.pRenderTexture && info.CI_Info.dwFormat == pgti->Format && info.CI_Info.dwSize == pgti->Size ) { info.txtEntry.ti = *pgti; return &info.txtEntry; } } } if (frameBufferOptions.bCheckBackBufs && g_pFrameBufferManager->CheckAddrInBackBuffers(pgti->Address, pgti->HeightToLoad*pgti->Pitch, false) >= 0) { if( !frameBufferOptions.bWriteBackBufToRDRAM ) { // Load the texture from recent back buffer txtBufIdxToLoadFrom = g_pFrameBufferManager->CheckAddrInRenderTextures(pgti->Address, true); if( txtBufIdxToLoadFrom >= 0 ) { loadFromTextureBuffer = true; // Check if it is the same size, RenderTextureInfo &info = gRenderTextureInfos[txtBufIdxToLoadFrom]; //if( info.pRenderTexture && info.CI_Info.dwAddr == pgti->Address && info.CI_Info.dwFormat == pgti->Format if( info.pRenderTexture && info.CI_Info.dwFormat == pgti->Format && info.CI_Info.dwSize == pgti->Size ) { info.txtEntry.ti = *pgti; return &info.txtEntry; } } } } if (pEntry && pEntry->dwTimeLastUsed == status.gRDPTime && status.gDlistCount != 0 && !status.bN64FrameBufferIsUsed ) // This is not good, Palatte may changes { // We've already calculated a CRC this frame! dwAsmCRC = pEntry->dwCRC; } else { if ( doCRCCheck ) { if( loadFromTextureBuffer ) dwAsmCRC = gRenderTextureInfos[txtBufIdxToLoadFrom].crcInRDRAM; else CalculateRDRAMCRC(pgti->pPhysicalAddress, pgti->LeftToLoad, pgti->TopToLoad, pgti->WidthToLoad, pgti->HeightToLoad, pgti->Size, pgti->Pitch); } } int maxCI = 0; if ( doCRCCheck && (pgti->Format == TXT_FMT_CI || (pgti->Format == TXT_FMT_RGBA && pgti->Size <= TXT_SIZE_8b ))) { //maxCI = pgti->Size == TXT_SIZE_8b ? 255 : 15; extern unsigned char CalculateMaxCI(void *pPhysicalAddress, uint32_t left, uint32_t top, uint32_t width, uint32_t height, uint32_t size, uint32_t pitchInBytes ); if( !pEntry || pEntry->dwCRC != dwAsmCRC || pEntry->maxCI < 0 ) { maxCI = CalculateMaxCI(pgti->pPhysicalAddress, pgti->LeftToLoad, pgti->TopToLoad, pgti->WidthToLoad, pgti->HeightToLoad, pgti->Size, pgti->Pitch); } else { maxCI = pEntry->maxCI; } //Check PAL CRC uint8_t * pStart; uint32_t dwPalSize = 16; uint32_t dwOffset; if( pgti->Size == TXT_SIZE_8b ) { dwPalSize = 256; dwOffset = 0; } else { dwOffset = pgti->Palette << 4; } pStart = (uint8_t*)pgti->PalAddress+dwOffset*2; //uint32_t y; //for (y = 0; y < dwPalSize*2; y+=4) //{ // dwPalCRC = (dwPalCRC + *(uint32_t*)&pStart[y]); //} uint32_t dwAsmCRCSave = dwAsmCRC; //dwPalCRC = CalculateRDRAMCRC(pStart, 0, 0, dwPalSize, 1, TXT_SIZE_16b, dwPalSize*2); dwPalCRC = CalculateRDRAMCRC(pStart, 0, 0, maxCI+1, 1, TXT_SIZE_16b, dwPalSize*2); dwAsmCRC = dwAsmCRCSave; } if (pEntry && doCRCCheck ) { if(pEntry->dwCRC == dwAsmCRC && pEntry->dwPalCRC == dwPalCRC && (!loadFromTextureBuffer || gRenderTextureInfos[txtBufIdxToLoadFrom].updateAtFrame < pEntry->FrameLastUsed ) ) { // Tile is ok, return pEntry->dwUses++; pEntry->dwTimeLastUsed = status.gRDPTime; pEntry->FrameLastUsed = status.gDlistCount; LOG_TEXTURE(TRACE0(" Use current texture:\n")); pEntry->lastEntry = g_lastTextureEntry; g_lastTextureEntry = pEntry; lastEntryModified = false; DEBUGGER_IF_DUMP((pauseAtNext && loadFromTextureBuffer) , {DebuggerAppendMsg("Load cached texture from render_texture");} ); return pEntry; } else { //Do something } } if (pEntry == NULL) { // We need to create a new entry, and add it // to the hash table. pEntry = CreateNewCacheEntry(pgti->Address, pgti->WidthToCreate, pgti->HeightToCreate); if (pEntry == NULL) { g_lastTextureEntry = pEntry; _VIDEO_DisplayTemporaryMessage("Fail to create new texture entry"); return NULL; } } pEntry->ti = *pgti; pEntry->dwCRC = dwAsmCRC; pEntry->dwPalCRC = dwPalCRC; pEntry->bExternalTxtrChecked = false; pEntry->maxCI = maxCI; if (pEntry->pTexture != NULL) { if( pEntry->pTexture->m_dwCreatedTextureWidth < pgti->WidthToCreate ) { pEntry->ti.WidthToLoad = pEntry->pTexture->m_dwCreatedTextureWidth; pEntry->pTexture->m_bScaledS = false; pEntry->pTexture->m_bScaledT = false; } if( pEntry->pTexture->m_dwCreatedTextureHeight < pgti->HeightToCreate ) { pEntry->ti.HeightToLoad = pEntry->pTexture->m_dwCreatedTextureHeight; pEntry->pTexture->m_bScaledT = false; pEntry->pTexture->m_bScaledS = false; } TextureFmt dwType = pEntry->pTexture->GetSurfaceFormat(); SAFE_DELETE(pEntry->pEnhancedTexture); pEntry->dwEnhancementFlag = TEXTURE_NO_ENHANCEMENT; if (dwType != TEXTURE_FMT_UNKNOWN) { if( loadFromTextureBuffer ) { g_pFrameBufferManager->LoadTextureFromRenderTexture(pEntry, txtBufIdxToLoadFrom); DEBUGGER_IF_DUMP((pauseAtNext && loadFromTextureBuffer) , {DebuggerAppendMsg("Load texture from render_texture %d", txtBufIdxToLoadFrom);} ); extern void ConvertTextureRGBAtoI(TxtrCacheEntry* pEntry, bool alpha); if( g_pRenderTextureInfo->CI_Info.dwFormat == TXT_FMT_I ) { // Convert texture from RGBA to I ConvertTextureRGBAtoI(pEntry,false); } else if( g_pRenderTextureInfo->CI_Info.dwFormat == TXT_FMT_IA ) { // Convert texture from RGBA to IA ConvertTextureRGBAtoI(pEntry,true); } } else { LOG_TEXTURE(TRACE0(" Load new texture from RDRAM:\n")); if (dwType == TEXTURE_FMT_A8R8G8B8) { ConvertTexture(pEntry, fromTMEM); } else ConvertTexture_16(pEntry, fromTMEM); pEntry->FrameLastUpdated = status.gDlistCount; SAFE_DELETE(pEntry->pEnhancedTexture); pEntry->dwEnhancementFlag = TEXTURE_NO_ENHANCEMENT; } } pEntry->ti.WidthToLoad = pgti->WidthToLoad; pEntry->ti.HeightToLoad = pgti->HeightToLoad; if( AutoExtendTexture ) { ExpandTextureS(pEntry); ExpandTextureT(pEntry); } #ifdef DEBUGGER if( pauseAtNext && eventToPause == NEXT_NEW_TEXTURE ) { CRender::g_pRender->SetCurrentTexture( 0, pEntry->pTexture, pEntry->ti.WidthToCreate, pEntry->ti.HeightToCreate, pEntry); CRender::g_pRender->DrawTexture(0, TXT_RGB); debuggerPause = true; TRACE0("Pause after loading a new texture"); if( pEntry->ti.Format == TXT_FMT_YUV ) { TRACE0("This is YUV texture"); } DebuggerAppendMsg("W:%d, H:%d, RealW:%d, RealH:%d, D3DW:%d, D3DH: %d", pEntry->ti.WidthToCreate, pEntry->ti.HeightToCreate, pEntry->ti.WidthToLoad, pEntry->ti.HeightToLoad, pEntry->pTexture->m_dwCreatedTextureWidth, pEntry->pTexture->m_dwCreatedTextureHeight); DebuggerAppendMsg("ScaledS:%s, ScaledT:%s, CRC=%08X", pEntry->pTexture->m_bScaledS?"T":"F", pEntry->pTexture->m_bScaledT?"T":"F", pEntry->dwCRC); DebuggerPause(); CRender::g_pRender->SetCurrentTexture( 0, NULL, 64, 64, NULL); } #endif } pEntry->lastEntry = g_lastTextureEntry; g_lastTextureEntry = pEntry; lastEntryModified = true; return pEntry; } const char *pszImgFormat[8] = {"RGBA", "YUV", "CI", "IA", "I", "?1", "?2", "?3"}; uint8_t pnImgSize[4] = {4, 8, 16, 32}; const char *textlutname[4] = {"RGB16", "I16?", "RGBA16", "IA16"}; extern uint16_t g_wRDPTlut[]; extern ConvertFunction gConvertFunctions_FullTMEM[ 8 ][ 4 ]; extern ConvertFunction gConvertFunctions[ 8 ][ 4 ]; extern ConvertFunction gConvertTlutFunctions[ 8 ][ 4 ]; extern ConvertFunction gConvertFunctions_16[ 8 ][ 4 ]; extern ConvertFunction gConvertFunctions_16_FullTMEM[ 8 ][ 4 ]; extern ConvertFunction gConvertTlutFunctions_16[ 8 ][ 4 ]; void CTextureManager::ConvertTexture(TxtrCacheEntry * pEntry, bool fromTMEM) { static uint32_t dwCount = 0; ConvertFunction pF; if( options.bUseFullTMEM && fromTMEM && status.bAllowLoadFromTMEM ) { pF = gConvertFunctions_FullTMEM[ pEntry->ti.Format ][ pEntry->ti.Size ]; } else { if( gRDP.tiles[7].dwFormat == TXT_FMT_YUV ) { if( gRDP.otherMode.text_tlut>=2 ) pF = gConvertTlutFunctions[ TXT_FMT_YUV ][ pEntry->ti.Size ]; else pF = gConvertFunctions[ TXT_FMT_YUV ][ pEntry->ti.Size ]; } else { if( gRDP.otherMode.text_tlut>=2 ) pF = gConvertTlutFunctions[ pEntry->ti.Format ][ pEntry->ti.Size ]; else pF = gConvertFunctions[ pEntry->ti.Format ][ pEntry->ti.Size ]; } } if( pF ) { pF( pEntry->pTexture, pEntry->ti ); LOG_TEXTURE( { DebuggerAppendMsg("Decompress 32bit Texture:\n\tFormat: %s\n\tImage Size:%d\n", pszImgFormat[pEntry->ti.Format], pnImgSize[pEntry->ti.Size]); DebuggerAppendMsg("Palette Format: %s (%d)\n", textlutname[pEntry->ti.TLutFmt>>RSP_SETOTHERMODE_SHIFT_TEXTLUT], pEntry->ti.TLutFmt>>RSP_SETOTHERMODE_SHIFT_TEXTLUT); }); } else { TRACE2("ConvertTexture: Unable to decompress %s/%dbpp", pszImgFormat[pEntry->ti.Format], pnImgSize[pEntry->ti.Size]); } dwCount++; } void CTextureManager::ConvertTexture_16(TxtrCacheEntry * pEntry, bool fromTMEM) { static uint32_t dwCount = 0; ConvertFunction pF; if( options.bUseFullTMEM && fromTMEM && status.bAllowLoadFromTMEM ) { pF = gConvertFunctions_16_FullTMEM[ pEntry->ti.Format ][ pEntry->ti.Size ]; } else { if( gRDP.otherMode.text_tlut>=2 ) pF = gConvertTlutFunctions_16[ pEntry->ti.Format ][ pEntry->ti.Size ]; else pF = gConvertFunctions_16[ pEntry->ti.Format ][ pEntry->ti.Size ]; } if( pF ) { pF( pEntry->pTexture, pEntry->ti ); LOG_TEXTURE(TRACE2("Decompress 16bit Texture:\n\tFormat: %s\n\tImage Size:%d\n", pszImgFormat[pEntry->ti.Format], pnImgSize[pEntry->ti.Size])); } else { TRACE2("ConvertTexture: Unable to decompress %s/%dbpp", pszImgFormat[pEntry->ti.Format], pnImgSize[pEntry->ti.Size]); } dwCount++; } void CTextureManager::ExpandTexture(TxtrCacheEntry * pEntry, uint32_t sizeToLoad, uint32_t sizeToCreate, uint32_t sizeCreated, int arrayWidth, int flag, int mask, int mirror, int clamp, uint32_t otherSize) { if( sizeToLoad >= sizeCreated ) return; uint32_t maskWidth = (1<pTexture->GetPixelSize(); #ifdef DEBUGGER // Some checks if( sizeToLoad > sizeToCreate || sizeToCreate > sizeCreated ) TRACE0("Something is wrong, check me here in ExpandTextureS"); #endif // Doing Mirror And/Or Wrap in S direction // Image has been loaded with width=WidthToLoad, we need to enlarge the image // to width = pEntry->ti.WidthToCreate by doing mirroring or wrapping DrawInfo di; if( !(pEntry->pTexture->StartUpdate(&di)) ) { TRACE0("Can't update the texture"); return; } if( mask == 0 ) { // Clamp Clamp(di.lpSurface, sizeToLoad, sizeCreated, arrayWidth, otherSize, flag, size); pEntry->pTexture->EndUpdate(&di); return; } #ifdef DEBUGGER if( sizeToLoad > maskWidth ) { TRACE0("Something is wrong, check me here in ExpandTextureS"); pEntry->pTexture->EndUpdate(&di); return; } if( sizeToLoad == maskWidth && maskWidth == sizeToCreate && sizeToCreate != sizeCreated ) { TRACE0("Something is wrong, check me here in ExpandTextureS"); pEntry->pTexture->EndUpdate(&di); return; } #endif if( sizeToLoad == maskWidth ) { uint32_t tempwidth = clamp ? sizeToCreate : sizeCreated; if( mirror ) { Mirror(di.lpSurface, sizeToLoad, mask, tempwidth, arrayWidth, otherSize, flag, size ); } else { Wrap(di.lpSurface, sizeToLoad, mask, tempwidth, arrayWidth, otherSize, flag, size ); } if( tempwidth < sizeCreated ) { Clamp(di.lpSurface, tempwidth, sizeCreated, arrayWidth, otherSize, flag, size ); } pEntry->pTexture->EndUpdate(&di); return; } if( sizeToLoad < sizeToCreate && sizeToCreate == maskWidth && maskWidth == sizeCreated ) { // widthToLoad < widthToCreate = maskWidth Wrap(di.lpSurface, sizeToLoad, mask, sizeCreated, arrayWidth, otherSize, flag, size ); pEntry->pTexture->EndUpdate(&di); return; } if( sizeToLoad == sizeToCreate && sizeToCreate < maskWidth ) { #ifdef DEBUGGER if( maskWidth < sizeToCreate ) TRACE0("Incorrect condition, check me"); #endif Clamp(di.lpSurface, sizeToLoad, sizeCreated, arrayWidth, otherSize, flag, size ); pEntry->pTexture->EndUpdate(&di); return; } if( sizeToLoad < sizeToCreate && sizeToCreate < maskWidth ) { #ifdef DEBUGGER if( clamp ) TRACE0("Incorrect condition, check me"); if( maskWidth < sizeCreated ) TRACE0("Incorrect condition, check me"); #endif Clamp(di.lpSurface, sizeToLoad, sizeCreated, arrayWidth, otherSize, flag, size ); pEntry->pTexture->EndUpdate(&di); return; } TRACE0("Check me, should not get here"); pEntry->pTexture->EndUpdate(&di); } void CTextureManager::ExpandTextureS(TxtrCacheEntry * pEntry) { TxtrInfo &ti = pEntry->ti; uint32_t textureWidth = pEntry->pTexture->m_dwCreatedTextureWidth; ExpandTexture(pEntry, ti.WidthToLoad, ti.WidthToCreate, textureWidth, textureWidth, S_FLAG, ti.maskS, ti.mirrorS, ti.clampS, ti.HeightToLoad); } void CTextureManager::ExpandTextureT(TxtrCacheEntry * pEntry) { TxtrInfo &ti = pEntry->ti; uint32_t textureHeight = pEntry->pTexture->m_dwCreatedTextureHeight; uint32_t textureWidth = pEntry->pTexture->m_dwCreatedTextureWidth; ExpandTexture(pEntry, ti.HeightToLoad, ti.HeightToCreate, textureHeight, textureWidth, T_FLAG, ti.maskT, ti.mirrorT, ti.clampT, ti.WidthToLoad); } void CTextureManager::ClampS32(uint32_t *array, uint32_t width, uint32_t towidth, uint32_t arrayWidth, uint32_t rows) { if ((int) width <= 0 || (int) towidth < 0) return; for( uint32_t y = 0; ymaskval?y&maskval:y-height); uint32_t* linedst = array+arrayWidth*y;; for( uint32_t x=0; xmaskval?y&maskval:y-height); uint16_t* linedst = array+arrayWidth*y;; for( uint32_t x=0; xpNext) { if( size == tex ) return pEntry; else size++; } } } return NULL; } uint32_t CTextureManager::GetNumOfCachedTexture() { uint32_t size = 0; for( uint32_t i=0; ipNext) { size++; } } } TRACE1("Totally %d texture cached", size); return size; } #endif TxtrCacheEntry * CTextureManager::GetBlackTexture(void) { if( m_blackTextureEntry.pTexture == NULL ) { m_blackTextureEntry.pTexture = CDeviceBuilder::GetBuilder()->CreateTexture(4, 4); m_blackTextureEntry.ti.WidthToCreate = 4; m_blackTextureEntry.ti.HeightToCreate = 4; updateColorTexture(m_blackTextureEntry.pTexture,0x00000000); } return &m_blackTextureEntry; } TxtrCacheEntry * CTextureManager::GetPrimColorTexture(uint32_t color) { static uint32_t mcolor = 0; if( m_PrimColorTextureEntry.pTexture == NULL ) { m_PrimColorTextureEntry.pTexture = CDeviceBuilder::GetBuilder()->CreateTexture(4, 4); m_PrimColorTextureEntry.ti.WidthToCreate = 4; m_PrimColorTextureEntry.ti.HeightToCreate = 4; updateColorTexture(m_PrimColorTextureEntry.pTexture,color); gRDP.texturesAreReloaded = true; } else if( mcolor != color ) { updateColorTexture(m_PrimColorTextureEntry.pTexture,color); gRDP.texturesAreReloaded = true; } mcolor = color; return &m_PrimColorTextureEntry; } TxtrCacheEntry * CTextureManager::GetEnvColorTexture(uint32_t color) { static uint32_t mcolor = 0; if( m_EnvColorTextureEntry.pTexture == NULL ) { m_EnvColorTextureEntry.pTexture = CDeviceBuilder::GetBuilder()->CreateTexture(4, 4); m_EnvColorTextureEntry.ti.WidthToCreate = 4; m_EnvColorTextureEntry.ti.HeightToCreate = 4; gRDP.texturesAreReloaded = true; updateColorTexture(m_EnvColorTextureEntry.pTexture,color); } else if( mcolor != color ) { updateColorTexture(m_EnvColorTextureEntry.pTexture,color); gRDP.texturesAreReloaded = true; } mcolor = color; return &m_EnvColorTextureEntry; } TxtrCacheEntry * CTextureManager::GetLODFracTexture(uint8_t fac) { static uint8_t mfac = 0; if( m_LODFracTextureEntry.pTexture == NULL ) { m_LODFracTextureEntry.pTexture = CDeviceBuilder::GetBuilder()->CreateTexture(4, 4); m_LODFracTextureEntry.ti.WidthToCreate = 4; m_LODFracTextureEntry.ti.HeightToCreate = 4; uint32_t factor = fac; uint32_t color = fac; color |= factor << 8; color |= color << 16; updateColorTexture(m_LODFracTextureEntry.pTexture,color); gRDP.texturesAreReloaded = true; } else if( mfac != fac ) { uint32_t factor = fac; uint32_t color = fac; color |= factor << 8; color |= color << 16; updateColorTexture(m_LODFracTextureEntry.pTexture,color); gRDP.texturesAreReloaded = true; } mfac = fac; return &m_LODFracTextureEntry; } TxtrCacheEntry * CTextureManager::GetPrimLODFracTexture(uint8_t fac) { static uint8_t mfac = 0; if( m_PrimLODFracTextureEntry.pTexture == NULL ) { m_PrimLODFracTextureEntry.pTexture = CDeviceBuilder::GetBuilder()->CreateTexture(4, 4); m_PrimLODFracTextureEntry.ti.WidthToCreate = 4; m_PrimLODFracTextureEntry.ti.HeightToCreate = 4; uint32_t factor = fac; uint32_t color = fac; color |= factor << 8; color |= color << 16; updateColorTexture(m_PrimLODFracTextureEntry.pTexture,color); gRDP.texturesAreReloaded = true; } else if( mfac != fac ) { uint32_t factor = fac; uint32_t color = fac; color |= factor << 8; color |= color << 16; updateColorTexture(m_PrimLODFracTextureEntry.pTexture,color); gRDP.texturesAreReloaded = true; } mfac = fac; return &m_PrimLODFracTextureEntry; } TxtrCacheEntry * CTextureManager::GetConstantColorTexture(uint32_t constant) { switch( constant ) { case MUX_PRIM: return GetPrimColorTexture(gRDP.primitiveColor); break; case MUX_ENV: return GetEnvColorTexture(gRDP.envColor); break; case MUX_LODFRAC: return GetLODFracTexture((uint8_t)gRDP.LODFrac); break; default: // MUX_PRIMLODFRAC return GetPrimLODFracTexture((uint8_t)gRDP.primLODFrac); break; } } void CTextureManager::updateColorTexture(CTexture *ptexture, uint32_t color) { DrawInfo di; if( !(ptexture->StartUpdate(&di)) ) { TRACE0("Cann't update the texture"); return; } int size = ptexture->GetPixelSize(); switch( size ) { case 2: // 16 bits { uint16_t *buf = (uint16_t*)di.lpSurface; uint16_t color16= (uint16_t)((color>>4)&0xF); color16 |= ((color>>12)&0xF)<<4; color16 |= ((color>>20)&0xF)<<8; color16 |= ((color>>28)&0xF)<<12; for( int i=0; i<16; i++ ) { buf[i] = color16; } } break; case 4: // 32 bits { uint32_t *buf = (uint32_t*)di.lpSurface; for( int i=0; i<16; i++ ) { buf[i] = color; } } break; } ptexture->EndUpdate(&di); } void ConvertTextureRGBAtoI(TxtrCacheEntry* pEntry, bool alpha) { DrawInfo srcInfo; if( pEntry->pTexture->StartUpdate(&srcInfo) ) { uint32_t *buf; uint32_t val; uint32_t r,g,b,a,i; for(int nY = 0; nY < srcInfo.dwCreatedHeight; nY++) { buf = (uint32_t*)((uint8_t*)srcInfo.lpSurface+nY*srcInfo.lPitch); for(int nX = 0; nX < srcInfo.dwCreatedWidth; nX++) { val = buf[nX]; b = (val>>0)&0xFF; g = (val>>8)&0xFF; r = (val>>16)&0xFF; i = (r+g+b)/3; a = alpha?(val&0xFF000000):(i<<24); buf[nX] = (a|(i<<16)|(i<<8)|i); } } pEntry->pTexture->EndUpdate(&srcInfo); } } mupen64plus-core/src/api/vidext_libretro.c000664 001750 001750 00000012247 12655644434 021766 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-core - api/vidext.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2009 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file contains the Core video extension functions which will be exported * outside of the core library. */ #include #include #define M64P_CORE_PROTOTYPES 1 #include "m64p_types.h" #include "m64p_vidext.h" #include "vidext.h" #include "callbacks.h" #include #include extern struct retro_hw_render_callback hw_render; /* local variables */ static m64p_video_extension_functions l_ExternalVideoFuncTable = {10, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; static int l_VideoExtensionActive = 0; static int l_VideoOutputActive = 0; /* global function for use by frontend.c */ m64p_error OverrideVideoFunctions(m64p_video_extension_functions *VideoFunctionStruct) { /* check input data */ if (VideoFunctionStruct == NULL) return M64ERR_INPUT_ASSERT; if (VideoFunctionStruct->Functions < 11) return M64ERR_INPUT_INVALID; /* disable video extension if any of the function pointers are NULL */ if (VideoFunctionStruct->VidExtFuncInit == NULL || VideoFunctionStruct->VidExtFuncQuit == NULL || VideoFunctionStruct->VidExtFuncListModes == NULL || VideoFunctionStruct->VidExtFuncSetMode == NULL || VideoFunctionStruct->VidExtFuncGLGetProc == NULL || VideoFunctionStruct->VidExtFuncGLSetAttr == NULL || VideoFunctionStruct->VidExtFuncGLGetAttr == NULL || VideoFunctionStruct->VidExtFuncGLSwapBuf == NULL || VideoFunctionStruct->VidExtFuncSetCaption == NULL || VideoFunctionStruct->VidExtFuncToggleFS == NULL || VideoFunctionStruct->VidExtFuncResizeWindow == NULL) { l_ExternalVideoFuncTable.Functions = 11; memset(&l_ExternalVideoFuncTable.VidExtFuncInit, 0, 11 * sizeof(void *)); l_VideoExtensionActive = 0; return M64ERR_SUCCESS; } /* otherwise copy in the override function pointers */ memcpy(&l_ExternalVideoFuncTable, VideoFunctionStruct, sizeof(m64p_video_extension_functions)); l_VideoExtensionActive = 1; return M64ERR_SUCCESS; } int VidExt_InFullscreenMode(void) { return 1; } int VidExt_VideoRunning(void) { return l_VideoOutputActive; } EXPORT m64p_error CALL VidExt_SetCaption(const char *Title) { return M64ERR_SUCCESS; } EXPORT m64p_error CALL VidExt_ToggleFullScreen(void) { /* TODO/FIXME - should just do a context reset here. */ return M64ERR_SUCCESS; } EXPORT m64p_error CALL VidExt_GL_SetAttribute(m64p_GLattr Attr, int Value) { return M64ERR_SUCCESS; } EXPORT m64p_error CALL VidExt_Init(void) { /* TODO/FIXME - implement. */ return M64ERR_SUCCESS; } EXPORT m64p_error CALL VidExt_Quit(void) { /* TODO/FIXME - implement. */ return M64ERR_SUCCESS; } EXPORT m64p_error CALL VidExt_SetVideoMode(int Width, int Height, int BitsPerPixel, m64p_video_mode ScreenMode, m64p_video_flags Flags) { /* TODO/FIXME - implement. */ return M64ERR_SUCCESS; } EXPORT void * CALL VidExt_GL_GetProcAddress(const char* Proc) { if (hw_render.get_proc_address) return hw_render.get_proc_address; return NULL; } EXPORT m64p_error CALL VidExt_GL_SwapBuffers(void) { retro_return(true); return M64ERR_SUCCESS; } EXPORT m64p_error CALL VidExt_ListFullscreenModes(m64p_2d_size *SizeArray, int *NumSizes) { #if 0 /* TODO/FIXME - implement */ i = 0; while (i < *NumSizes && modes[i] != NULL) { SizeArray[i].uiWidth = modes[i]->w; SizeArray[i].uiHeight = modes[i]->h; i++; } *NumSizes = i; #endif return M64ERR_SUCCESS; } EXPORT m64p_error CALL VidExt_ResizeWindow(int Width, int Height) { /* TODO/FIXME - implement? */ return M64ERR_SUCCESS; } mupen64plus-video-gliden64/src/windows/Config_windows.cpp000664 001750 001750 00000001467 12655644434 024613 0ustar00sergiosergio000000 000000 #include "GLideN64_Windows.h" #include "../N64.h" #include "../Config.h" #include "../RSP.h" #include "../PluginAPI.h" #include "../OpenGL.h" #include "../GLideNUI/GLideNUI.h" Config config; void Config_DoConfig(/*HWND hParent*/) { wchar_t strIniFolderPath[PLUGIN_PATH_SIZE]; api().FindPluginPath(strIniFolderPath); ConfigOpen = true; const bool bRestart = RunConfig(strIniFolderPath); if (config.generalEmulation.enableCustomSettings != 0) LoadCustomRomSettings(strIniFolderPath, RSP.romname); if (bRestart) video().restart(); ConfigOpen = false; } void Config_LoadConfig() { wchar_t strIniFolderPath[PLUGIN_PATH_SIZE]; api().FindPluginPath(strIniFolderPath); LoadConfig(strIniFolderPath); if (config.generalEmulation.enableCustomSettings != 0) LoadCustomRomSettings(strIniFolderPath, RSP.romname); } mupen64plus-video-gliden64/projects/000700 001750 001750 00000000000 12656647145 020457 5ustar00sergiosergio000000 000000 mupen64plus-video-gliden64/src/GLideNHQ/test/Makefile.gcc000664 001750 001750 00000002762 12655644434 024142 0ustar00sergiosergio000000 000000 # This MUST be processed by GNU make # # Texture Filtering Test Linux Makefile # Version: 1.0 # # Copyright (C) 2007 Hiroshi Morii All Rights Reserved. # Email koolsmoky(at)users.sourceforge.net # Web http://www.3dfxzone.it/koolsmoky # # this is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # this is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Make; see the file COPYING. If not, write to # the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. # # # Available options: # # Environment variables: # # Targets: # all: build dynamic module # clean: remove object files # realclean: remove all generated files # # # GCC does not have SEH (structured exception handling) # .PHONY: all clean realclean CC = g++ CFLAGS += -I. -I../ CFLAGS += -fPIC -DPIC CFLAGS += -DGHQCHK=1 LD = g++ LDFLAGS += -ldl -lstdc++ RM = rm SOURCES = \ test.cpp \ ../Ext_TxFilter.cpp OBJECTS = $(SOURCES:.cpp=.o) .cpp.o: $(CC) -o $@ $(CFLAGS) -c $< all: test.exe test.exe: $(OBJECTS) $(LD) -o $@ $(LDFLAGS) $^ clean: -$(RM) *.o realclean: clean -$(RM) test.exe mupen64plus-core/src/r4300/new_dynarec/assem_arm.h000664 001750 001750 00000002171 12655644434 023025 0ustar00sergiosergio000000 000000 #ifndef M64P_R4300_ASSEM_ARM_H #define M64P_R4300_ASSEM_ARM_H #define HOST_REGS 13 #define HOST_CCREG 10 #define HOST_BTREG 8 #define EXCLUDE_REG 11 #define HOST_IMM8 1 #define HAVE_CMOV_IMM 1 #ifndef ARMv5_ONLY #define CORTEX_A8_BRANCH_PREDICTION_HACK 1 #endif #define USE_MINI_HT 1 //#define REG_PREFETCH 1 #define HAVE_CONDITIONAL_CALL 1 #define RAM_OFFSET 1 /* ARM calling convention: r0-r3, r12: caller-save r4-r11: callee-save */ #define ARG1_REG 0 #define ARG2_REG 1 #define ARG3_REG 2 #define ARG4_REG 3 /* GCC register naming convention: r10 = sl (base) r11 = fp (frame pointer) r12 = ip (scratch) r13 = sp (stack pointer) r14 = lr (link register) r15 = pc (program counter) */ #define FP 11 #define LR 14 #define HOST_TEMPREG 14 // Note: FP is set to &dynarec_local when executing generated code. // Thus the local variables are actually global and not on the stack. extern char *invc_ptr; extern char extra_memory[33554432]; #define BASE_ADDR ((int)(&extra_memory)) //#define TARGET_SIZE_2 24 // 2^24 = 16 megabytes #define TARGET_SIZE_2 25 // 2^25 = 32 megabytes #endif /* M64P_R4300_ASSEM_ARM_H */ mupen64plus-video-gliden64/src/GLideNHQ/test/CMakeLists.txt000664 001750 001750 00000001102 12655644434 024472 0ustar00sergiosergio000000 000000 cmake_minimum_required(VERSION 2.6) project( test_hq ) # Build type if( NOT CMAKE_BUILD_TYPE) set( CMAKE_BUILD_TYPE Release) endif( NOT CMAKE_BUILD_TYPE) if( CMAKE_BUILD_TYPE STREQUAL "Debug") set( CMAKE_BUILD_TYPE Debug) set( DEBUG_BUILD TRUE) add_definitions( -DDEBUG ) endif( CMAKE_BUILD_TYPE STREQUAL "Debug") add_definitions( -DGHQCHK=1 -DTXFILTER_DLL=1 ) if(WIN32) add_definitions( -DWIN32 -DOS_WINDOWS ) endif(WIN32) #SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_CPP11_COMPILE_FLAGS}" ) add_executable( test_hq test.cpp ../Ext_TxFilter.cpp ) mupen64plus-video-gliden64/src/GLideNHQ/txWidestringWrapper.cpp000664 001750 001750 00000004276 12655644434 025532 0ustar00sergiosergio000000 000000 #ifdef ANDROID #include #include #include #include "txWidestringWrapper.h" tx_wstring::tx_wstring(const wchar_t * wstr) : _wstring(wstr) { wcstombs(cbuf, wstr, BUF_SIZE); _astring.assign(cbuf); } tx_wstring::tx_wstring(const tx_wstring & other) : _wstring(other.c_str()) { wcstombs(cbuf, other.c_str(), BUF_SIZE); _astring.assign(cbuf); } void tx_wstring::assign(const wchar_t * wstr) { _wstring.assign(wstr); wcstombs(cbuf, wstr, BUF_SIZE); _astring.assign(cbuf); } void tx_wstring::assign(const tx_wstring & wstr) { _wstring.assign(wstr.c_str()); wcstombs(cbuf, wstr.c_str(), BUF_SIZE); _astring.assign(cbuf); } void tx_wstring::append(const tx_wstring & wstr) { wcstombs(cbuf, wstr.c_str(), BUF_SIZE); _astring.append(cbuf); mbstowcs(wbuf, _astring.c_str(), BUF_SIZE); _wstring.assign(wbuf); } tx_wstring & tx_wstring::operator=(const tx_wstring & other) { assign(other); return *this; } tx_wstring & tx_wstring::operator+=(const tx_wstring & other) { append(other); return *this; } tx_wstring & tx_wstring::operator+=(const wchar_t * wstr) { append(wstr); return *this; } tx_wstring tx_wstring::operator + (const tx_wstring & wstr) { tx_wstring ans(_wstring.c_str()); ans.append(wstr); return ans; } tx_wstring tx_wstring::operator+(const wchar_t * wstr) { tx_wstring ans(_wstring.c_str()); ans.append(wstr); return ans; } const wchar_t * tx_wstring::c_str() const { return _wstring.c_str(); } bool tx_wstring::empty() const { return _astring.empty(); } int tx_wstring::compare(const wchar_t * wstr) { wcstombs(cbuf, wstr, BUF_SIZE); return _astring.compare(cbuf); } dummyWString::dummyWString(const char * _str) { wchar_t buf[BUF_SIZE]; mbstowcs(buf, _str, BUF_SIZE); _wstr.assign(buf); } int tx_swprintf(wchar_t* ws, size_t len, const wchar_t* format, ...) { char cbuf[BUF_SIZE]; char fmt[BUF_SIZE]; wcstombs(fmt, format, BUF_SIZE); va_list ap; va_start(ap, format); int res = vsprintf(cbuf, fmt, ap); va_end(ap); mbstowcs(ws, cbuf, len); return res; } bool wccmp(const wchar_t* w1, const wchar_t* w2) { char cbuf1[16]; wcstombs(cbuf1, w1, 16); char cbuf2[16]; wcstombs(cbuf2, w2, 16); return cbuf1[0] == cbuf2[0]; } #endif // ANDROID mupen64plus-core/src/r4300/new_dynarec/assem_arm.c000664 001750 001750 00000424770 12655644434 023035 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - assem_arm.c * * Copyright (C) 2009-2011 Ari64 * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef __MACH__ #define CALLER_SAVE_REGS 0x100f #else #define CALLER_SAVE_REGS 0x120f #endif #include "main/main.h" #include "../cp0_private.h" extern int cycle_count; extern int last_count; extern int pcaddr; extern int pending_exception; extern int branch_target; extern int ram_offset; extern uint64_t readmem_dword; extern precomp_instr fake_pc; extern void *dynarec_local; extern uintptr_t memory_map[1048576]; extern u_int mini_ht[32][2]; extern u_int rounding_modes[4]; static u_int literals[1024][2]; void indirect_jump_indexed(); void indirect_jump(); void do_interrupt(); void jump_vaddr(); void jump_vaddr_r0(); void jump_vaddr_r1(); void jump_vaddr_r2(); void jump_vaddr_r3(); void jump_vaddr_r4(); void jump_vaddr_r5(); void jump_vaddr_r6(); void jump_vaddr_r7(); void jump_vaddr_r8(); void jump_vaddr_r9(); void jump_vaddr_r10(); void jump_vaddr_r12(); const u_int jump_vaddr_reg[16] = { (int)jump_vaddr_r0, (int)jump_vaddr_r1, (int)jump_vaddr_r2, (int)jump_vaddr_r3, (int)jump_vaddr_r4, (int)jump_vaddr_r5, (int)jump_vaddr_r6, (int)jump_vaddr_r7, (int)jump_vaddr_r8, (int)jump_vaddr_r9, (int)jump_vaddr_r10, 0, (int)jump_vaddr_r12, 0, 0, 0}; void invalidate_addr_r0(); void invalidate_addr_r1(); void invalidate_addr_r2(); void invalidate_addr_r3(); void invalidate_addr_r4(); void invalidate_addr_r5(); void invalidate_addr_r6(); void invalidate_addr_r7(); void invalidate_addr_r8(); void invalidate_addr_r9(); void invalidate_addr_r10(); void invalidate_addr_r12(); const u_int invalidate_addr_reg[16] = { (int)invalidate_addr_r0, (int)invalidate_addr_r1, (int)invalidate_addr_r2, (int)invalidate_addr_r3, (int)invalidate_addr_r4, (int)invalidate_addr_r5, (int)invalidate_addr_r6, (int)invalidate_addr_r7, (int)invalidate_addr_r8, (int)invalidate_addr_r9, (int)invalidate_addr_r10, 0, (int)invalidate_addr_r12, 0, 0, 0}; #include "../fpu.h" static u_int jump_table_symbols[] = { (int)invalidate_addr, (int)jump_vaddr, (int)dyna_linker, (int)dyna_linker_ds, (int)verify_code, (int)verify_code_vm, (int)verify_code_ds, (int)cc_interrupt, (int)fp_exception, (int)fp_exception_ds, (int)jump_syscall, (int)jump_eret, (int)indirect_jump_indexed, (int)indirect_jump, (int)do_interrupt, (int)NULL /*MFC0*/, (int)NULL /*MTC0*/, (int)NULL /*TLBR*/, (int)NULL /*TLBP*/, (int)TLBWI_new, (int)TLBWR_new, (int)jump_vaddr_r0, (int)jump_vaddr_r1, (int)jump_vaddr_r2, (int)jump_vaddr_r3, (int)jump_vaddr_r4, (int)jump_vaddr_r5, (int)jump_vaddr_r6, (int)jump_vaddr_r7, (int)jump_vaddr_r8, (int)jump_vaddr_r9, (int)jump_vaddr_r10, (int)jump_vaddr_r12, (int)invalidate_addr_r0, (int)invalidate_addr_r1, (int)invalidate_addr_r2, (int)invalidate_addr_r3, (int)invalidate_addr_r4, (int)invalidate_addr_r5, (int)invalidate_addr_r6, (int)invalidate_addr_r7, (int)invalidate_addr_r8, (int)invalidate_addr_r9, (int)invalidate_addr_r10, (int)invalidate_addr_r12, (int)mult64, (int)multu64, (int)div64, (int)divu64, (int)cvt_s_w, (int)cvt_d_w, (int)cvt_s_l, (int)cvt_d_l, (int)cvt_w_s, (int)cvt_w_d, (int)cvt_l_s, (int)cvt_l_d, (int)cvt_d_s, (int)cvt_s_d, (int)round_l_s, (int)round_w_s, (int)trunc_l_s, (int)trunc_w_s, (int)ceil_l_s, (int)ceil_w_s, (int)floor_l_s, (int)floor_w_s, (int)round_l_d, (int)round_w_d, (int)trunc_l_d, (int)trunc_w_d, (int)ceil_l_d, (int)ceil_w_d, (int)floor_l_d, (int)floor_w_d, (int)c_f_s, (int)c_un_s, (int)c_eq_s, (int)c_ueq_s, (int)c_olt_s, (int)c_ult_s, (int)c_ole_s, (int)c_ule_s, (int)c_sf_s, (int)c_ngle_s, (int)c_seq_s, (int)c_ngl_s, (int)c_lt_s, (int)c_nge_s, (int)c_le_s, (int)c_ngt_s, (int)c_f_d, (int)c_un_d, (int)c_eq_d, (int)c_ueq_d, (int)c_olt_d, (int)c_ult_d, (int)c_ole_d, (int)c_ule_d, (int)c_sf_d, (int)c_ngle_d, (int)c_seq_d, (int)c_ngl_d, (int)c_lt_d, (int)c_nge_d, (int)c_le_d, (int)c_ngt_d, (int)add_s, (int)sub_s, (int)mul_s, (int)div_s, (int)sqrt_s, (int)abs_s, (int)mov_s, (int)neg_s, (int)add_d, (int)sub_d, (int)mul_d, (int)div_d, (int)sqrt_d, (int)abs_d, (int)mov_d, (int)neg_d }; static unsigned int needs_clear_cache[1<<(TARGET_SIZE_2-17)]; #define JUMP_TABLE_SIZE (sizeof(jump_table_symbols)*2) /* Linker */ static void set_jump_target(int addr,u_int target) { u_char *ptr = (u_char *)addr; u_int *ptr2 = (u_int *)ptr; if(ptr[3]==0xe2) { assert((target-(u_int)ptr2-8)<1024); assert((addr&3)==0); assert((target&3)==0); *ptr2=(*ptr2&0xFFFFF000)|((target-(u_int)ptr2-8)>>2)|0xF00; //DebugMessage(M64MSG_VERBOSE, "target=%x addr=%x insn=%x",target,addr,*ptr2); } else if(ptr[3]==0x72) { // generated by emit_jno_unlikely if((target-(u_int)ptr2-8)<1024) { assert((addr&3)==0); assert((target&3)==0); *ptr2=(*ptr2&0xFFFFF000)|((target-(u_int)ptr2-8)>>2)|0xF00; } else if((target-(u_int)ptr2-8)<4096&&!((target-(u_int)ptr2-8)&15)) { assert((addr&3)==0); assert((target&3)==0); *ptr2=(*ptr2&0xFFFFF000)|((target-(u_int)ptr2-8)>>4)|0xE00; } else *ptr2=(0x7A000000)|(((target-(u_int)ptr2-8)<<6)>>8); } else { assert((ptr[3]&0x0e)==0xa); *ptr2=(*ptr2&0xFF000000)|(((target-(u_int)ptr2-8)<<6)>>8); } } // This optionally copies the instruction from the target of the branch into // the space before the branch. Works, but the difference in speed is // usually insignificant. #if 0 static void set_jump_target_fillslot(int addr,u_int target,int copy) { u_char *ptr=(u_char *)addr; u_int *ptr2=(u_int *)ptr; assert(!copy||ptr2[-1]==0xe28dd000); if(ptr[3]==0xe2) { assert(!copy); assert((target-(u_int)ptr2-8)<4096); *ptr2=(*ptr2&0xFFFFF000)|(target-(u_int)ptr2-8); } else { assert((ptr[3]&0x0e)==0xa); u_int target_insn=*(u_int *)target; if((target_insn&0x0e100000)==0) { // ALU, no immediate, no flags copy=0; } if((target_insn&0x0c100000)==0x04100000) { // Load copy=0; } if(target_insn&0x08000000) { copy=0; } if(copy) { ptr2[-1]=target_insn; target+=4; } *ptr2=(*ptr2&0xFF000000)|(((target-(u_int)ptr2-8)<<6)>>8); } } #endif /* Literal pool */ static void add_literal(int addr,int val) { assert(literalcount>6)+8; } // Find the "clean" entry point from a "dirty" entry point // by skipping past the call to verify_code static u_int get_clean_addr(int addr) { int *ptr=(int *)addr; #ifdef ARMv5_ONLY ptr+=4; #else ptr+=6; #endif if((*ptr&0xFF000000)!=0xeb000000) ptr++; assert((*ptr&0xFF000000)==0xeb000000); // bl instruction ptr++; if((*ptr&0xFF000000)==0xea000000) return (int)ptr+((*ptr<<8)>>6)+8; // follow jump return (u_int)ptr; } extern uint8_t isGoldeneyeRom; static int verify_dirty(void *addr) { u_int *ptr=(u_int *)addr; #ifdef ARMv5_ONLY // get from literal pool assert((*ptr&0xFFF00000)==0xe5900000); u_int offset=*ptr&0xfff; u_int *l_ptr=(void *)ptr+offset+8; u_int source=l_ptr[0]; u_int copy=l_ptr[1]; u_int len=l_ptr[2]; ptr+=4; #else // ARMv7 movw/movt assert((*ptr&0xFFF00000)==0xe3000000); u_int source=(ptr[0]&0xFFF)+((ptr[0]>>4)&0xF000)+((ptr[2]<<16)&0xFFF0000)+((ptr[2]<<12)&0xF0000000); u_int copy=(ptr[1]&0xFFF)+((ptr[1]>>4)&0xF000)+((ptr[3]<<16)&0xFFF0000)+((ptr[3]<<12)&0xF0000000); u_int len=(ptr[4]&0xFFF)+((ptr[4]>>4)&0xF000); ptr+=6; #endif if((*ptr&0xFF000000)!=0xeb000000) ptr++; assert((*ptr&0xFF000000)==0xeb000000); // bl instruction #ifndef DISABLE_TLB u_int verifier=(int)ptr+((signed int)(*ptr<<8)>>6)+8; // get target of bl if(verifier==(u_int)verify_code_vm||verifier==(u_int)verify_code_ds) { unsigned int page=source>>12; unsigned int map_value=memory_map[page]; if(map_value>=0x80000000) return 0; while(page<((source+len-1)>>12)) { if((memory_map[++page]<<2)!=(map_value<<2)) return 0; } source = source+(map_value<<2); } #ifdef IOS // Hack to workaround crash if (isGoldeneyeRom) return 1; else #endif #endif #if 0 printf("verify_dirty: %x %x %x",source,copy,len); #endif return !memcmp((void *)source,(void *)copy,len); } // This doesn't necessarily find all clean entry points, just // guarantees that it's not dirty static int isclean(int addr) { #ifdef ARMv5_ONLY intptr_t* ptr= (intptr_t*)(((uintptr_t*)addr)+4); #else intptr_t* ptr= (intptr_t*)(((uintptr_t*)addr)+6); #endif if((*ptr&0xFF000000)!=0xeb000000) ptr++; if((*ptr&0xFF000000)!=0xeb000000) return 1; // bl instruction if((int)ptr+((*ptr<<8)>>6)+8==(int)verify_code) return 0; if((int)ptr+((*ptr<<8)>>6)+8==(int)verify_code_vm) return 0; if((int)ptr+((*ptr<<8)>>6)+8==(int)verify_code_ds) return 0; return 1; } static void get_bounds(int addr,u_int *start,u_int *end) { u_int *ptr=(u_int *)addr; #ifdef ARMv5_ONLY // get from literal pool assert((*ptr&0xFFF00000)==0xe5900000); u_int offset=*ptr&0xfff; u_int *l_ptr=(void *)ptr+offset+8; u_int source=l_ptr[0]; //u_int copy=l_ptr[1]; u_int len=l_ptr[2]; ptr+=4; #else // ARMv7 movw/movt assert((*ptr&0xFFF00000)==0xe3000000); u_int source=(ptr[0]&0xFFF)+((ptr[0]>>4)&0xF000)+((ptr[2]<<16)&0xFFF0000)+((ptr[2]<<12)&0xF0000000); //u_int copy=(ptr[1]&0xFFF)+((ptr[1]>>4)&0xF000)+((ptr[3]<<16)&0xFFF0000)+((ptr[3]<<12)&0xF0000000); u_int len=(ptr[4]&0xFFF)+((ptr[4]>>4)&0xF000); ptr+=6; #endif if((*ptr&0xFF000000)!=0xeb000000) ptr++; assert((*ptr&0xFF000000)==0xeb000000); // bl instruction #ifndef DISABLE_TLB u_int verifier=(int)ptr+((signed int)(*ptr<<8)>>6)+8; // get target of bl if(verifier==(u_int)verify_code_vm||verifier==(u_int)verify_code_ds) { if(memory_map[source>>12]>=0x80000000) source = 0; else source = source+(memory_map[source>>12]<<2); } #endif *start=source; *end=source+len; } /* Register allocation */ // Note: registers are allocated clean (unmodified state) // if you intend to modify the register, you must call dirty_reg(). static void alloc_reg(struct regstat *cur,int i,signed char reg) { int r,hr; int preferred_reg = (reg&7); if(reg==CCREG) preferred_reg=HOST_CCREG; if(reg==PTEMP||reg==FTEMP) preferred_reg=12; // Don't allocate unused registers if((cur->u>>reg)&1) return; // see if it's already allocated for(hr=0;hrregmap[hr]==reg) return; } // Keep the same mapping if the register was already allocated in a loop preferred_reg = loop_reg(i,reg,preferred_reg); // Try to allocate the preferred register if(cur->regmap[preferred_reg]==-1) { cur->regmap[preferred_reg]=reg; cur->dirty&=~(1<isconst&=~(1<regmap[preferred_reg]; if(r<64&&((cur->u>>r)&1)) { cur->regmap[preferred_reg]=reg; cur->dirty&=~(1<isconst&=~(1<=64&&((cur->uu>>(r&63))&1)) { cur->regmap[preferred_reg]=reg; cur->dirty&=~(1<isconst&=~(1<regmap[hr]; if(r>=0) { if(r<64) { if((cur->u>>r)&1) {cur->regmap[hr]=-1;break;} } else { if((cur->uu>>(r&63))&1) {cur->regmap[hr]=-1;break;} } } } // Try to allocate any available register, but prefer // registers that have not been used recently. if(i>0) { for(hr=0;hrregmap[hr]==-1) { if(regs[i-1].regmap[hr]!=rs1[i-1]&®s[i-1].regmap[hr]!=rs2[i-1]&®s[i-1].regmap[hr]!=rt1[i-1]&®s[i-1].regmap[hr]!=rt2[i-1]) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<regmap[hr]==-1) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<regmap[0],cur->regmap[1],cur->regmap[2],cur->regmap[3],cur->regmap[5],cur->regmap[6],cur->regmap[7]); printf("hsn(%x): %d %d %d %d %d %d %d",start+i*4,hsn[cur->regmap[0]&63],hsn[cur->regmap[1]&63],hsn[cur->regmap[2]&63],hsn[cur->regmap[3]&63],hsn[cur->regmap[5]&63],hsn[cur->regmap[6]&63],hsn[cur->regmap[7]&63]); #endif if(i>0) { // Don't evict the cycle count at entry points, otherwise the entry // stub will have to write it. if(bt[i]&&hsn[CCREG]>2) hsn[CCREG]=2; if(i>1&&hsn[CCREG]>2&&(itype[i-2]==RJUMP||itype[i-2]==UJUMP||itype[i-2]==CJUMP||itype[i-2]==SJUMP||itype[i-2]==FJUMP)) hsn[CCREG]=2; for(j=10;j>=3;j--) { /* Allocate preferred register if available */ if(hsn[r=cur->regmap[preferred_reg]&63]==j) { for(hr=0;hrregmap[hr]&63)==r) { cur->regmap[hr]=-1; cur->dirty&=~(1<isconst&=~(1<regmap[preferred_reg]=reg; return; } for(r=1;r<=MAXREG;r++) { if(hsn[r]==j&&r!=rs1[i-1]&&r!=rs2[i-1]&&r!=rt1[i-1]&&r!=rt2[i-1]) { for(hr=0;hrregmap[hr]==r+64) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<regmap[hr]==r) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<=0;j--) { for(r=1;r<=MAXREG;r++) { if(hsn[r]==j) { for(hr=0;hrregmap[hr]==r+64) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<regmap[hr]==r) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<uu>>reg)&1) return; // see if the upper half is already allocated for(hr=0;hrregmap[hr]==reg+64) return; } // Keep the same mapping if the register was already allocated in a loop preferred_reg = loop_reg(i,reg,preferred_reg); // Try to allocate the preferred register if(cur->regmap[preferred_reg]==-1) { cur->regmap[preferred_reg]=reg|64; cur->dirty&=~(1<isconst&=~(1<regmap[preferred_reg]; if(r<64&&((cur->u>>r)&1)) { cur->regmap[preferred_reg]=reg|64; cur->dirty&=~(1<isconst&=~(1<=64&&((cur->uu>>(r&63))&1)) { cur->regmap[preferred_reg]=reg|64; cur->dirty&=~(1<isconst&=~(1<=0;hr--) { r=cur->regmap[hr]; if(r>=0) { if(r<64) { if((cur->u>>r)&1) {cur->regmap[hr]=-1;break;} } else { if((cur->uu>>(r&63))&1) {cur->regmap[hr]=-1;break;} } } } // Try to allocate any available register, but prefer // registers that have not been used recently. if(i>0) { for(hr=0;hrregmap[hr]==-1) { if(regs[i-1].regmap[hr]!=rs1[i-1]&®s[i-1].regmap[hr]!=rs2[i-1]&®s[i-1].regmap[hr]!=rt1[i-1]&®s[i-1].regmap[hr]!=rt2[i-1]) { cur->regmap[hr]=reg|64; cur->dirty&=~(1<isconst&=~(1<regmap[hr]==-1) { cur->regmap[hr]=reg|64; cur->dirty&=~(1<isconst&=~(1<regmap[0],cur->regmap[1],cur->regmap[2],cur->regmap[3],cur->regmap[5],cur->regmap[6],cur->regmap[7]); printf("hsn(%x): %d %d %d %d %d %d %d",start+i*4,hsn[cur->regmap[0]&63],hsn[cur->regmap[1]&63],hsn[cur->regmap[2]&63],hsn[cur->regmap[3]&63],hsn[cur->regmap[5]&63],hsn[cur->regmap[6]&63],hsn[cur->regmap[7]&63]); #endif if(i>0) { // Don't evict the cycle count at entry points, otherwise the entry // stub will have to write it. if(bt[i]&&hsn[CCREG]>2) hsn[CCREG]=2; if(i>1&&hsn[CCREG]>2&&(itype[i-2]==RJUMP||itype[i-2]==UJUMP||itype[i-2]==CJUMP||itype[i-2]==SJUMP||itype[i-2]==FJUMP)) hsn[CCREG]=2; for(j=10;j>=3;j--) { // Alloc preferred register if available if(hsn[r=cur->regmap[preferred_reg]&63]==j) { for(hr=0;hrregmap[hr]&63)==r) { cur->regmap[hr]=-1; cur->dirty&=~(1<isconst&=~(1<regmap[preferred_reg]=reg|64; return; } for(r=1;r<=MAXREG;r++) { if(hsn[r]==j&&r!=rs1[i-1]&&r!=rs2[i-1]&&r!=rt1[i-1]&&r!=rt2[i-1]) { for(hr=0;hrregmap[hr]==r+64) { cur->regmap[hr]=reg|64; cur->dirty&=~(1<isconst&=~(1<regmap[hr]==r) { cur->regmap[hr]=reg|64; cur->dirty&=~(1<isconst&=~(1<=0;j--) { for(r=1;r<=MAXREG;r++) { if(hsn[r]==j) { for(hr=0;hrregmap[hr]==r+64) { cur->regmap[hr]=reg|64; cur->dirty&=~(1<isconst&=~(1<regmap[hr]==r) { cur->regmap[hr]=reg|64; cur->dirty&=~(1<isconst&=~(1<regmap[hr]==reg) return; } // Try to allocate any available register for(hr=HOST_REGS-1;hr>=0;hr--) { if(hr!=EXCLUDE_REG&&cur->regmap[hr]==-1) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<=0;hr--) { r=cur->regmap[hr]; if(r>=0) { if(r<64) { if((cur->u>>r)&1) { if(i==0||((unneeded_reg[i-1]>>r)&1)) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<uu>>(r&63))&1) { if(i==0||((unneeded_reg_upper[i-1]>>(r&63))&1)) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<regmap[0]&63],hsn[cur->regmap[1]&63],hsn[cur->regmap[2]&63],hsn[cur->regmap[3]&63],hsn[cur->regmap[5]&63],hsn[cur->regmap[6]&63],hsn[cur->regmap[7]&63]); if(i>0) { // Don't evict the cycle count at entry points, otherwise the entry // stub will have to write it. if(bt[i]&&hsn[CCREG]>2) hsn[CCREG]=2; if(i>1&&hsn[CCREG]>2&&(itype[i-2]==RJUMP||itype[i-2]==UJUMP||itype[i-2]==CJUMP||itype[i-2]==SJUMP||itype[i-2]==FJUMP)) hsn[CCREG]=2; for(j=10;j>=3;j--) { for(r=1;r<=MAXREG;r++) { if(hsn[r]==j&&r!=rs1[i-1]&&r!=rs2[i-1]&&r!=rt1[i-1]&&r!=rt2[i-1]) { for(hr=0;hr2) { if(cur->regmap[hr]==r+64) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<2) { if(cur->regmap[hr]==r) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<=0;j--) { for(r=1;r<=MAXREG;r++) { if(hsn[r]==j) { for(hr=0;hrregmap[hr]==r+64) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<regmap[hr]==r) { cur->regmap[hr]=reg; cur->dirty&=~(1<isconst&=~(1<regmap[n]==reg) { dirty=(cur->dirty>>n)&1; cur->regmap[n]=-1; } } cur->regmap[hr]=reg; cur->dirty&=~(1<dirty|=dirty<isconst&=~(1<0) { if(imm<256) { *encoded=((i&30)<<7)|imm; return 1; } imm=(imm>>2)|(imm<<30);i-=2; } return 0; } static u_int genjmp(u_int addr) { if(addr<4) return 0; int offset=addr-(int)out-8; if(offset<-33554432||offset>=33554432) { int n; for (n=0;n=-33554432&&offset<33554432); return ((u_int)offset>>2)&0xffffff; } static void emit_mov(int rs,int rt) { assem_debug("mov %s,%s",regname[rt],regname[rs]); output_w32(0xe1a00000|rd_rn_rm(rt,0,rs)); } static void emit_movs(int rs,int rt) { assem_debug("movs %s,%s",regname[rt],regname[rs]); output_w32(0xe1b00000|rd_rn_rm(rt,0,rs)); } static void emit_add(int rs1,int rs2,int rt) { assem_debug("add %s,%s,%s",regname[rt],regname[rs1],regname[rs2]); output_w32(0xe0800000|rd_rn_rm(rt,rs1,rs2)); } static void emit_addne(int rs1,int rs2,int rt) { assem_debug("addne %s,%s,%s",regname[rt],regname[rs1],regname[rs2]); output_w32(0x12800000|rd_rn_rm(rt,rs1,rs2)); } static void emit_addsarimm(int rs1,int rs2,int rt,int imm) { assert(imm>0); assert(imm<32); assem_debug("add %s,%s,%s,ASR#%d",regname[rt],regname[rs1],regname[rs2],imm); output_w32(0xe0a00000|rd_rn_rm(rt,rs1,rs2)|0x40|(imm<<7)); } static void emit_adds(int rs1,int rs2,int rt) { assem_debug("adds %s,%s,%s",regname[rt],regname[rs1],regname[rs2]); output_w32(0xe0900000|rd_rn_rm(rt,rs1,rs2)); } static void emit_adc(int rs1,int rs2,int rt) { assem_debug("adc %s,%s,%s",regname[rt],regname[rs1],regname[rs2]); output_w32(0xe0a00000|rd_rn_rm(rt,rs1,rs2)); } static void emit_adcs(int rs1,int rs2,int rt) { assem_debug("adcs %s,%s,%s",regname[rt],regname[rs1],regname[rs2]); output_w32(0xe0b00000|rd_rn_rm(rt,rs1,rs2)); } static void emit_sbc(int rs1,int rs2,int rt) { assem_debug("sbc %s,%s,%s",regname[rt],regname[rs1],regname[rs2]); output_w32(0xe0c00000|rd_rn_rm(rt,rs1,rs2)); } static void emit_sbcs(int rs1,int rs2,int rt) { assem_debug("sbcs %s,%s,%s",regname[rt],regname[rs1],regname[rs2]); output_w32(0xe0d00000|rd_rn_rm(rt,rs1,rs2)); } static void emit_neg(int rs, int rt) { assem_debug("rsb %s,%s,#0",regname[rt],regname[rs]); output_w32(0xe2600000|rd_rn_rm(rt,rs,0)); } static void emit_negs(int rs, int rt) { assem_debug("rsbs %s,%s,#0",regname[rt],regname[rs]); output_w32(0xe2700000|rd_rn_rm(rt,rs,0)); } static void emit_sub(int rs1,int rs2,int rt) { assem_debug("sub %s,%s,%s",regname[rt],regname[rs1],regname[rs2]); output_w32(0xe0400000|rd_rn_rm(rt,rs1,rs2)); } static void emit_subs(int rs1,int rs2,int rt) { assem_debug("subs %s,%s,%s",regname[rt],regname[rs1],regname[rs2]); output_w32(0xe0500000|rd_rn_rm(rt,rs1,rs2)); } static void emit_zeroreg(int rt) { assem_debug("mov %s,#0",regname[rt]); output_w32(0xe3a00000|rd_rn_rm(rt,0,0)); } static void emit_loadlp(u_int imm,u_int rt) { add_literal((int)out,imm); assem_debug("ldr %s,pc+? [=%x]",regname[rt],imm); output_w32(0xe5900000|rd_rn_rm(rt,15,0)); } static void emit_movw(u_int imm,u_int rt) { assert(imm<65536); assem_debug("movw %s,#%d (0x%x)",regname[rt],imm,imm); output_w32(0xe3000000|rd_rn_rm(rt,0,0)|(imm&0xfff)|((imm<<4)&0xf0000)); } static void emit_movt(u_int imm,u_int rt) { assem_debug("movt %s,#%d (0x%x)",regname[rt],imm&0xffff0000,imm&0xffff0000); output_w32(0xe3400000|rd_rn_rm(rt,0,0)|((imm>>16)&0xfff)|((imm>>12)&0xf0000)); } static void emit_movimm(u_int imm,u_int rt) { u_int armval; if(genimm(imm,&armval)) { assem_debug("mov %s,#%d",regname[rt],imm); output_w32(0xe3a00000|rd_rn_rm(rt,0,0)|armval); }else if(genimm(~imm,&armval)) { assem_debug("mvn %s,#%d",regname[rt],imm); output_w32(0xe3e00000|rd_rn_rm(rt,0,0)|armval); }else if(imm<65536) { #ifdef ARMv5_ONLY assem_debug("mov %s,#%d",regname[rt],imm&0xFF00); output_w32(0xe3a00000|rd_rn_imm_shift(rt,0,imm>>8,8)); assem_debug("add %s,%s,#%d",regname[rt],regname[rt],imm&0xFF); output_w32(0xe2800000|rd_rn_imm_shift(rt,rt,imm&0xff,0)); #else emit_movw(imm,rt); #endif }else{ #ifdef ARMv5_ONLY emit_loadlp(imm,rt); #else emit_movw(imm&0x0000FFFF,rt); emit_movt(imm&0xFFFF0000,rt); #endif } } static void emit_pcreladdr(u_int rt) { assem_debug("add %s,pc,#?",regname[rt]); output_w32(0xe2800000|rd_rn_rm(rt,15,0)); } static void emit_loadreg(int r, int hr) { if((r&63)==0) emit_zeroreg(hr); else if(r==MMREG) emit_movimm(((int)memory_map-(int)&dynarec_local)>>2,hr); else { int addr=((int)reg)+((r&63)<<3)+((r&64)>>4); if((r&63)==HIREG) addr=(int)&hi+((r&64)>>4); if((r&63)==LOREG) addr=(int)&lo+((r&64)>>4); if(r==CCREG) addr=(int)&cycle_count; if(r==CSREG) addr=(int)&g_cp0_regs[CP0_STATUS_REG]; if(r==FSREG) addr=(int)&FCR31; if(r==INVCP) addr=(int)&invc_ptr; if(r==ROREG) addr=(int)&ram_offset; u_int offset = addr-(u_int)&dynarec_local; assert(offset<4096); assem_debug("ldr %s,fp+%d",regname[hr],offset); output_w32(0xe5900000|rd_rn_rm(hr,FP,0)|offset); } } static void emit_storereg(int r, int hr) { int addr=((int)reg)+((r&63)<<3)+((r&64)>>4); if((r&63)==HIREG) addr=(int)&hi+((r&64)>>4); if((r&63)==LOREG) addr=(int)&lo+((r&64)>>4); if(r==CCREG) addr=(int)&cycle_count; if(r==FSREG) addr=(int)&FCR31; u_int offset = addr-(u_int)&dynarec_local; assert(offset<4096); assem_debug("str %s,fp+%d",regname[hr],offset); output_w32(0xe5800000|rd_rn_rm(hr,FP,0)|offset); } static void emit_test(int rs, int rt) { assem_debug("tst %s,%s",regname[rs],regname[rt]); output_w32(0xe1100000|rd_rn_rm(0,rs,rt)); } static void emit_testimm(int rs,int imm) { u_int armval, ret; assem_debug("tst %s,#%d",regname[rs],imm); ret = genimm(imm,&armval); assert(ret); output_w32(0xe3100000|rd_rn_rm(0,rs,0)|armval); } static void emit_not(int rs,int rt) { assem_debug("mvn %s,%s",regname[rt],regname[rs]); output_w32(0xe1e00000|rd_rn_rm(rt,0,rs)); } static void emit_and(u_int rs1,u_int rs2,u_int rt) { assem_debug("and %s,%s,%s",regname[rt],regname[rs1],regname[rs2]); output_w32(0xe0000000|rd_rn_rm(rt,rs1,rs2)); } static void emit_or(u_int rs1,u_int rs2,u_int rt) { assem_debug("orr %s,%s,%s",regname[rt],regname[rs1],regname[rs2]); output_w32(0xe1800000|rd_rn_rm(rt,rs1,rs2)); } static void emit_or_and_set_flags(int rs1,int rs2,int rt) { assem_debug("orrs %s,%s,%s",regname[rt],regname[rs1],regname[rs2]); output_w32(0xe1900000|rd_rn_rm(rt,rs1,rs2)); } static void emit_xor(u_int rs1,u_int rs2,u_int rt) { assem_debug("eor %s,%s,%s",regname[rt],regname[rs1],regname[rs2]); output_w32(0xe0200000|rd_rn_rm(rt,rs1,rs2)); } static void emit_addimm(u_int rs,int imm,u_int rt) { assert(rs<16); assert(rt<16); if(imm!=0) { assert(imm>-65536&&imm<65536); u_int armval; if(genimm(imm,&armval)) { assem_debug("add %s,%s,#%d",regname[rt],regname[rs],imm); output_w32(0xe2800000|rd_rn_rm(rt,rs,0)|armval); }else if(genimm(-imm,&armval)) { assem_debug("sub %s,%s,#%d",regname[rt],regname[rs],imm); output_w32(0xe2400000|rd_rn_rm(rt,rs,0)|armval); }else if(imm<0) { assem_debug("sub %s,%s,#%d",regname[rt],regname[rs],(-imm)&0xFF00); assem_debug("sub %s,%s,#%d",regname[rt],regname[rt],(-imm)&0xFF); output_w32(0xe2400000|rd_rn_imm_shift(rt,rs,(-imm)>>8,8)); output_w32(0xe2400000|rd_rn_imm_shift(rt,rt,(-imm)&0xff,0)); }else{ assem_debug("add %s,%s,#%d",regname[rt],regname[rs],imm&0xFF00); assem_debug("add %s,%s,#%d",regname[rt],regname[rt],imm&0xFF); output_w32(0xe2800000|rd_rn_imm_shift(rt,rs,imm>>8,8)); output_w32(0xe2800000|rd_rn_imm_shift(rt,rt,imm&0xff,0)); } } else if(rs!=rt) emit_mov(rs,rt); } static void emit_addimm_and_set_flags(int imm,int rt) { assert(imm>-65536&&imm<65536); u_int armval; if(genimm(imm,&armval)) { assem_debug("adds %s,%s,#%d",regname[rt],regname[rt],imm); output_w32(0xe2900000|rd_rn_rm(rt,rt,0)|armval); }else if(genimm(-imm,&armval)) { assem_debug("subs %s,%s,#%d",regname[rt],regname[rt],imm); output_w32(0xe2500000|rd_rn_rm(rt,rt,0)|armval); }else if(imm<0) { assem_debug("sub %s,%s,#%d",regname[rt],regname[rt],(-imm)&0xFF00); assem_debug("subs %s,%s,#%d",regname[rt],regname[rt],(-imm)&0xFF); output_w32(0xe2400000|rd_rn_imm_shift(rt,rt,(-imm)>>8,8)); output_w32(0xe2500000|rd_rn_imm_shift(rt,rt,(-imm)&0xff,0)); }else{ assem_debug("add %s,%s,#%d",regname[rt],regname[rt],imm&0xFF00); assem_debug("adds %s,%s,#%d",regname[rt],regname[rt],imm&0xFF); output_w32(0xe2800000|rd_rn_imm_shift(rt,rt,imm>>8,8)); output_w32(0xe2900000|rd_rn_imm_shift(rt,rt,imm&0xff,0)); } } #ifndef RAM_OFFSET static void emit_addimm_no_flags(u_int imm,u_int rt) { emit_addimm(rt,imm,rt); } #endif static void emit_addnop(u_int r) { assert(r<16); assem_debug("add %s,%s,#0 (nop)",regname[r],regname[r]); output_w32(0xe2800000|rd_rn_rm(r,r,0)); } static void emit_adcimm(u_int rs,int imm,u_int rt) { u_int armval, ret; ret = genimm(imm,&armval); assert(ret); assem_debug("adc %s,%s,#%d",regname[rt],regname[rs],imm); output_w32(0xe2a00000|rd_rn_rm(rt,rs,0)|armval); } /*static void emit_sbcimm(int imm,u_int rt) { u_int armval, ret; ret = genimm(imm,&armval); assert(ret); assem_debug("sbc %s,%s,#%d",regname[rt],regname[rt],imm); output_w32(0xe2c00000|rd_rn_rm(rt,rt,0)|armval); }*/ static void emit_rscimm(int rs,int imm,u_int rt) { u_int armval, ret; ret = genimm(imm,&armval); assert(ret); assem_debug("rsc %s,%s,#%d",regname[rt],regname[rs],imm); output_w32(0xe2e00000|rd_rn_rm(rt,rs,0)|armval); } static void emit_addimm64_32(int rsh,int rsl,int imm,int rth,int rtl) { // TODO: if(genimm(imm,&armval)) ... // else emit_movimm(imm,HOST_TEMPREG); emit_adds(HOST_TEMPREG,rsl,rtl); emit_adcimm(rsh,0,rth); } #ifdef INVERTED_CARRY static void emit_sbb(int rs1,int rs2) { assem_debug("sbb %%%s,%%%s",regname[rs2],regname[rs1]); output_byte(0x19); output_modrm(3,rs1,rs2); } #endif static void emit_andimm(int rs,int imm,int rt) { u_int armval; if(imm==0) { emit_zeroreg(rt); }else if(genimm(imm,&armval)) { assem_debug("and %s,%s,#%d",regname[rt],regname[rs],imm); output_w32(0xe2000000|rd_rn_rm(rt,rs,0)|armval); }else if(genimm(~imm,&armval)) { assem_debug("bic %s,%s,#%d",regname[rt],regname[rs],imm); output_w32(0xe3c00000|rd_rn_rm(rt,rs,0)|armval); }else if(imm==65535) { #ifdef ARMv5_ONLY assem_debug("bic %s,%s,#FF000000",regname[rt],regname[rs]); output_w32(0xe3c00000|rd_rn_rm(rt,rs,0)|0x4FF); assem_debug("bic %s,%s,#00FF0000",regname[rt],regname[rt]); output_w32(0xe3c00000|rd_rn_rm(rt,rt,0)|0x8FF); #else assem_debug("uxth %s,%s",regname[rt],regname[rs]); output_w32(0xe6ff0070|rd_rn_rm(rt,0,rs)); #endif }else{ assert(imm>0&&imm<65535); #ifdef ARMv5_ONLY assem_debug("mov r14,#%d",imm&0xFF00); output_w32(0xe3a00000|rd_rn_imm_shift(HOST_TEMPREG,0,imm>>8,8)); assem_debug("add r14,r14,#%d",imm&0xFF); output_w32(0xe2800000|rd_rn_imm_shift(HOST_TEMPREG,HOST_TEMPREG,imm&0xff,0)); #else emit_movw(imm,HOST_TEMPREG); #endif assem_debug("and %s,%s,r14",regname[rt],regname[rs]); output_w32(0xe0000000|rd_rn_rm(rt,rs,HOST_TEMPREG)); } } static void emit_orimm(int rs,int imm,int rt) { u_int armval; if(imm==0) { if(rs!=rt) emit_mov(rs,rt); }else if(genimm(imm,&armval)) { assem_debug("orr %s,%s,#%d",regname[rt],regname[rs],imm); output_w32(0xe3800000|rd_rn_rm(rt,rs,0)|armval); }else{ assert(imm>0&&imm<65536); assem_debug("orr %s,%s,#%d",regname[rt],regname[rs],imm&0xFF00); assem_debug("orr %s,%s,#%d",regname[rt],regname[rs],imm&0xFF); output_w32(0xe3800000|rd_rn_imm_shift(rt,rs,imm>>8,8)); output_w32(0xe3800000|rd_rn_imm_shift(rt,rt,imm&0xff,0)); } } static void emit_xorimm(int rs,int imm,int rt) { u_int armval; if(imm==0) { if(rs!=rt) emit_mov(rs,rt); }else if(genimm(imm,&armval)) { assem_debug("eor %s,%s,#%d",regname[rt],regname[rs],imm); output_w32(0xe2200000|rd_rn_rm(rt,rs,0)|armval); }else{ assert(imm>0&&imm<65536); assem_debug("eor %s,%s,#%d",regname[rt],regname[rs],imm&0xFF00); assem_debug("eor %s,%s,#%d",regname[rt],regname[rs],imm&0xFF); output_w32(0xe2200000|rd_rn_imm_shift(rt,rs,imm>>8,8)); output_w32(0xe2200000|rd_rn_imm_shift(rt,rt,imm&0xff,0)); } } static void emit_shlimm(int rs,u_int imm,int rt) { assert(imm>0); assert(imm<32); //if(imm==1) ... assem_debug("lsl %s,%s,#%d",regname[rt],regname[rs],imm); output_w32(0xe1a00000|rd_rn_rm(rt,0,rs)|(imm<<7)); } static void emit_shrimm(int rs,u_int imm,int rt) { assert(imm>0); assert(imm<32); assem_debug("lsr %s,%s,#%d",regname[rt],regname[rs],imm); output_w32(0xe1a00000|rd_rn_rm(rt,0,rs)|0x20|(imm<<7)); } static void emit_sarimm(int rs,u_int imm,int rt) { assert(imm>0); assert(imm<32); assem_debug("asr %s,%s,#%d",regname[rt],regname[rs],imm); output_w32(0xe1a00000|rd_rn_rm(rt,0,rs)|0x40|(imm<<7)); } static void emit_rorimm(int rs,u_int imm,int rt) { assert(imm>0); assert(imm<32); assem_debug("ror %s,%s,#%d",regname[rt],regname[rs],imm); output_w32(0xe1a00000|rd_rn_rm(rt,0,rs)|0x60|(imm<<7)); } static void emit_shldimm(int rs,int rs2,u_int imm,int rt) { assem_debug("shld %%%s,%%%s,%d",regname[rt],regname[rs2],imm); assert(imm>0); assert(imm<32); //if(imm==1) ... assem_debug("lsl %s,%s,#%d",regname[rt],regname[rs],imm); output_w32(0xe1a00000|rd_rn_rm(rt,0,rs)|(imm<<7)); assem_debug("orr %s,%s,%s,lsr #%d",regname[rt],regname[rt],regname[rs2],32-imm); output_w32(0xe1800020|rd_rn_rm(rt,rt,rs2)|((32-imm)<<7)); } static void emit_shrdimm(int rs,int rs2,u_int imm,int rt) { assem_debug("shrd %%%s,%%%s,%d",regname[rt],regname[rs2],imm); assert(imm>0); assert(imm<32); //if(imm==1) ... assem_debug("lsr %s,%s,#%d",regname[rt],regname[rs],imm); output_w32(0xe1a00020|rd_rn_rm(rt,0,rs)|(imm<<7)); assem_debug("orr %s,%s,%s,lsl #%d",regname[rt],regname[rt],regname[rs2],32-imm); output_w32(0xe1800000|rd_rn_rm(rt,rt,rs2)|((32-imm)<<7)); } static void emit_shl(u_int rs,u_int shift,u_int rt) { assert(rs<16); assert(rt<16); assert(shift<16); //if(imm==1) ... assem_debug("lsl %s,%s,%s",regname[rt],regname[rs],regname[shift]); output_w32(0xe1a00000|rd_rn_rm(rt,0,rs)|0x10|(shift<<8)); } static void emit_shr(u_int rs,u_int shift,u_int rt) { assert(rs<16); assert(rt<16); assert(shift<16); assem_debug("lsr %s,%s,%s",regname[rt],regname[rs],regname[shift]); output_w32(0xe1a00000|rd_rn_rm(rt,0,rs)|0x30|(shift<<8)); } static void emit_sar(u_int rs,u_int shift,u_int rt) { assert(rs<16); assert(rt<16); assert(shift<16); assem_debug("asr %s,%s,%s",regname[rt],regname[rs],regname[shift]); output_w32(0xe1a00000|rd_rn_rm(rt,0,rs)|0x50|(shift<<8)); } static void emit_orrshl(u_int rs,u_int shift,u_int rt) { assert(rs<16); assert(rt<16); assert(shift<16); assem_debug("orr %s,%s,%s,lsl %s",regname[rt],regname[rt],regname[rs],regname[shift]); output_w32(0xe1800000|rd_rn_rm(rt,rt,rs)|0x10|(shift<<8)); } static void emit_orrshr(u_int rs,u_int shift,u_int rt) { assert(rs<16); assert(rt<16); assert(shift<16); assem_debug("orr %s,%s,%s,lsr %s",regname[rt],regname[rt],regname[rs],regname[shift]); output_w32(0xe1800000|rd_rn_rm(rt,rt,rs)|0x30|(shift<<8)); } static void emit_cmpimm(int rs,int imm) { u_int armval; if(genimm(imm,&armval)) { assem_debug("cmp %s,#%d",regname[rs],imm); output_w32(0xe3500000|rd_rn_rm(0,rs,0)|armval); }else if(genimm(-imm,&armval)) { assem_debug("cmn %s,#%d",regname[rs],imm); output_w32(0xe3700000|rd_rn_rm(0,rs,0)|armval); }else if(imm>0) { assert(imm<65536); #ifdef ARMv5_ONLY emit_movimm(imm,HOST_TEMPREG); #else emit_movw(imm,HOST_TEMPREG); #endif assem_debug("cmp %s,r14",regname[rs]); output_w32(0xe1500000|rd_rn_rm(0,rs,HOST_TEMPREG)); }else{ assert(imm>-65536); #ifdef ARMv5_ONLY emit_movimm(-imm,HOST_TEMPREG); #else emit_movw(-imm,HOST_TEMPREG); #endif assem_debug("cmn %s,r14",regname[rs]); output_w32(0xe1700000|rd_rn_rm(0,rs,HOST_TEMPREG)); } } static void emit_cmovne_imm(int imm,int rt) { assem_debug("movne %s,#%d",regname[rt],imm); u_int armval, ret; ret = genimm(imm,&armval); assert(ret); output_w32(0x13a00000|rd_rn_rm(rt,0,0)|armval); } static void emit_cmovl_imm(int imm,int rt) { assem_debug("movlt %s,#%d",regname[rt],imm); u_int armval, ret; ret = genimm(imm,&armval); assert(ret); output_w32(0xb3a00000|rd_rn_rm(rt,0,0)|armval); } static void emit_cmovb_imm(int imm,int rt) { assem_debug("movcc %s,#%d",regname[rt],imm); u_int armval, ret; ret = genimm(imm,&armval); assert(ret); output_w32(0x33a00000|rd_rn_rm(rt,0,0)|armval); } static void emit_cmovs_imm(int imm,int rt) { assem_debug("movmi %s,#%d",regname[rt],imm); u_int armval, ret; ret = genimm(imm,&armval); assert(ret); output_w32(0x43a00000|rd_rn_rm(rt,0,0)|armval); } static void emit_cmove_reg(int rs,int rt) { assem_debug("moveq %s,%s",regname[rt],regname[rs]); output_w32(0x01a00000|rd_rn_rm(rt,0,rs)); } static void emit_cmovne_reg(int rs,int rt) { assem_debug("movne %s,%s",regname[rt],regname[rs]); output_w32(0x11a00000|rd_rn_rm(rt,0,rs)); } static void emit_cmovl_reg(int rs,int rt) { assem_debug("movlt %s,%s",regname[rt],regname[rs]); output_w32(0xb1a00000|rd_rn_rm(rt,0,rs)); } static void emit_cmovs_reg(int rs,int rt) { assem_debug("movmi %s,%s",regname[rt],regname[rs]); output_w32(0x41a00000|rd_rn_rm(rt,0,rs)); } static void emit_slti32(int rs,int imm,int rt) { if(rs!=rt) emit_zeroreg(rt); emit_cmpimm(rs,imm); if(rs==rt) emit_movimm(0,rt); emit_cmovl_imm(1,rt); } static void emit_sltiu32(int rs,int imm,int rt) { if(rs!=rt) emit_zeroreg(rt); emit_cmpimm(rs,imm); if(rs==rt) emit_movimm(0,rt); emit_cmovb_imm(1,rt); } static void emit_slti64_32(int rsh,int rsl,int imm,int rt) { assert(rsh!=rt); emit_slti32(rsl,imm,rt); if(imm>=0) { emit_test(rsh,rsh); emit_cmovne_imm(0,rt); emit_cmovs_imm(1,rt); } else { emit_cmpimm(rsh,-1); emit_cmovne_imm(0,rt); emit_cmovl_imm(1,rt); } } static void emit_sltiu64_32(int rsh,int rsl,int imm,int rt) { assert(rsh!=rt); emit_sltiu32(rsl,imm,rt); if(imm>=0) { emit_test(rsh,rsh); emit_cmovne_imm(0,rt); } else { emit_cmpimm(rsh,-1); emit_cmovne_imm(1,rt); } } static void emit_cmp(int rs,int rt) { assem_debug("cmp %s,%s",regname[rs],regname[rt]); output_w32(0xe1500000|rd_rn_rm(0,rs,rt)); } static void emit_set_gz32(int rs, int rt) { //assem_debug("set_gz32"); emit_cmpimm(rs,1); emit_movimm(1,rt); emit_cmovl_imm(0,rt); } static void emit_set_nz32(int rs, int rt) { //assem_debug("set_nz32"); if(rs!=rt) emit_movs(rs,rt); else emit_test(rs,rs); emit_cmovne_imm(1,rt); } static void emit_set_gz64_32(int rsh, int rsl, int rt) { //assem_debug("set_gz64"); emit_set_gz32(rsl,rt); emit_test(rsh,rsh); emit_cmovne_imm(1,rt); emit_cmovs_imm(0,rt); } static void emit_set_nz64_32(int rsh, int rsl, int rt) { //assem_debug("set_nz64"); emit_or_and_set_flags(rsh,rsl,rt); emit_cmovne_imm(1,rt); } static void emit_set_if_less32(int rs1, int rs2, int rt) { //assem_debug("set if less (%%%s,%%%s),%%%s",regname[rs1],regname[rs2],regname[rt]); if(rs1!=rt&&rs2!=rt) emit_zeroreg(rt); emit_cmp(rs1,rs2); if(rs1==rt||rs2==rt) emit_movimm(0,rt); emit_cmovl_imm(1,rt); } static void emit_set_if_carry32(int rs1, int rs2, int rt) { //assem_debug("set if carry (%%%s,%%%s),%%%s",regname[rs1],regname[rs2],regname[rt]); if(rs1!=rt&&rs2!=rt) emit_zeroreg(rt); emit_cmp(rs1,rs2); if(rs1==rt||rs2==rt) emit_movimm(0,rt); emit_cmovb_imm(1,rt); } static void emit_set_if_less64_32(int u1, int l1, int u2, int l2, int rt) { //assem_debug("set if less64 (%%%s,%%%s,%%%s,%%%s),%%%s",regname[u1],regname[l1],regname[u2],regname[l2],regname[rt]); assert(u1!=rt); assert(u2!=rt); emit_cmp(l1,l2); emit_movimm(0,rt); emit_sbcs(u1,u2,HOST_TEMPREG); emit_cmovl_imm(1,rt); } static void emit_set_if_carry64_32(int u1, int l1, int u2, int l2, int rt) { //assem_debug("set if carry64 (%%%s,%%%s,%%%s,%%%s),%%%s",regname[u1],regname[l1],regname[u2],regname[l2],regname[rt]); assert(u1!=rt); assert(u2!=rt); emit_cmp(l1,l2); emit_movimm(0,rt); emit_sbcs(u1,u2,HOST_TEMPREG); emit_cmovb_imm(1,rt); } static void emit_call(int a) { assem_debug("bl %x (%x+%x)",a,(int)out,a-(int)out-8); u_int offset=genjmp(a); output_w32(0xeb000000|offset); } static void emit_jmp(int a) { assem_debug("b %x (%x+%x)",a,(int)out,a-(int)out-8); u_int offset=genjmp(a); output_w32(0xea000000|offset); } static void emit_jne(int a) { assem_debug("bne %x",a); u_int offset=genjmp(a); output_w32(0x1a000000|offset); } static void emit_jeq(int a) { assem_debug("beq %x",a); u_int offset=genjmp(a); output_w32(0x0a000000|offset); } static void emit_js(int a) { assem_debug("bmi %x",a); u_int offset=genjmp(a); output_w32(0x4a000000|offset); } static void emit_jns(int a) { assem_debug("bpl %x",a); u_int offset=genjmp(a); output_w32(0x5a000000|offset); } static void emit_jl(int a) { assem_debug("blt %x",a); u_int offset=genjmp(a); output_w32(0xba000000|offset); } static void emit_jge(int a) { assem_debug("bge %x",a); u_int offset=genjmp(a); output_w32(0xaa000000|offset); } static void emit_jno(int a) { assem_debug("bvc %x",a); u_int offset=genjmp(a); output_w32(0x7a000000|offset); } static void emit_jcc(int a) { assem_debug("bcc %x",a); u_int offset=genjmp(a); output_w32(0x3a000000|offset); } static void emit_jae(int a) { assem_debug("bcs %x",a); u_int offset=genjmp(a); output_w32(0x2a000000|offset); } static void emit_jb(int a) { assem_debug("bcc %x",a); u_int offset=genjmp(a); output_w32(0x3a000000|offset); } static void emit_pushreg(u_int r) { assem_debug("push %%%s",regname[r]); assert(0); } static void emit_popreg(u_int r) { assem_debug("pop %%%s",regname[r]); assert(0); } /* static void emit_callreg(u_int r) { assem_debug("call *%%%s",regname[r]); assert(0); } static void emit_jmpreg(u_int r) { assem_debug("mov pc,%s",regname[r]); output_w32(0xe1a00000|rd_rn_rm(15,0,r)); } */ static void emit_readword_indexed(int offset, int rs, int rt) { assert(offset>-4096&&offset<4096); assem_debug("ldr %s,%s+%d",regname[rt],regname[rs],offset); if(offset>=0) { output_w32(0xe5900000|rd_rn_rm(rt,rs,0)|offset); }else{ output_w32(0xe5100000|rd_rn_rm(rt,rs,0)|(-offset)); } } static void emit_readword_dualindexedx4(int rs1, int rs2, int rt) { assem_debug("ldr %s,%s,%s lsl #2",regname[rt],regname[rs1],regname[rs2]); output_w32(0xe7900000|rd_rn_rm(rt,rs1,rs2)|0x100); } static void emit_readword_indexed_tlb(int addr, int rs, int map, int rt) { if(map<0) emit_readword_indexed(addr, rs, rt); else { assert(addr==0); emit_readword_dualindexedx4(rs, map, rt); } } static void emit_readdword_indexed_tlb(int addr, int rs, int map, int rh, int rl) { if(map<0) { if(rh>=0) emit_readword_indexed(addr, rs, rh); emit_readword_indexed(addr+4, rs, rl); }else{ assert(rh!=rs); if(rh>=0) emit_readword_indexed_tlb(addr, rs, map, rh); emit_addimm(map,1,HOST_TEMPREG); emit_readword_indexed_tlb(addr, rs, HOST_TEMPREG, rl); } } static void emit_movsbl_indexed(int offset, int rs, int rt) { assert(offset>-256&&offset<256); assem_debug("ldrsb %s,%s+%d",regname[rt],regname[rs],offset); if(offset>=0) { output_w32(0xe1d000d0|rd_rn_rm(rt,rs,0)|((offset<<4)&0xf00)|(offset&0xf)); }else{ output_w32(0xe15000d0|rd_rn_rm(rt,rs,0)|(((-offset)<<4)&0xf00)|((-offset)&0xf)); } } static void emit_movsbl_indexed_tlb(int addr, int rs, int map, int rt) { if(map<0) emit_movsbl_indexed(addr, rs, rt); else { if(addr==0) { emit_shlimm(map,2,HOST_TEMPREG); assem_debug("ldrsb %s,%s+%s",regname[rt],regname[rs],regname[HOST_TEMPREG]); output_w32(0xe19000d0|rd_rn_rm(rt,rs,HOST_TEMPREG)); }else{ assert(addr>-256&&addr<256); assem_debug("add %s,%s,%s,lsl #2",regname[rt],regname[rs],regname[map]); output_w32(0xe0800000|rd_rn_rm(rt,rs,map)|(2<<7)); emit_movsbl_indexed(addr, rt, rt); } } } static void emit_movswl_indexed(int offset, int rs, int rt) { assert(offset>-256&&offset<256); assem_debug("ldrsh %s,%s+%d",regname[rt],regname[rs],offset); if(offset>=0) { output_w32(0xe1d000f0|rd_rn_rm(rt,rs,0)|((offset<<4)&0xf00)|(offset&0xf)); }else{ output_w32(0xe15000f0|rd_rn_rm(rt,rs,0)|(((-offset)<<4)&0xf00)|((-offset)&0xf)); } } static void emit_movzbl_indexed(int offset, int rs, int rt) { assert(offset>-4096&&offset<4096); assem_debug("ldrb %s,%s+%d",regname[rt],regname[rs],offset); if(offset>=0) { output_w32(0xe5d00000|rd_rn_rm(rt,rs,0)|offset); }else{ output_w32(0xe5500000|rd_rn_rm(rt,rs,0)|(-offset)); } } static void emit_movzbl_dualindexedx4(int rs1, int rs2, int rt) { assem_debug("ldrb %s,%s,%s lsl #2",regname[rt],regname[rs1],regname[rs2]); output_w32(0xe7d00000|rd_rn_rm(rt,rs1,rs2)|0x100); } static void emit_movzbl_indexed_tlb(int addr, int rs, int map, int rt) { if(map<0) emit_movzbl_indexed(addr, rs, rt); else { if(addr==0) { emit_movzbl_dualindexedx4(rs, map, rt); }else{ emit_addimm(rs,addr,rt); emit_movzbl_dualindexedx4(rt, map, rt); } } } static void emit_movzwl_indexed(int offset, int rs, int rt) { assert(offset>-256&&offset<256); assem_debug("ldrh %s,%s+%d",regname[rt],regname[rs],offset); if(offset>=0) { output_w32(0xe1d000b0|rd_rn_rm(rt,rs,0)|((offset<<4)&0xf00)|(offset&0xf)); }else{ output_w32(0xe15000b0|rd_rn_rm(rt,rs,0)|(((-offset)<<4)&0xf00)|((-offset)&0xf)); } } static void emit_readword(int addr, int rt) { u_int offset = addr-(u_int)&dynarec_local; assert(offset<4096); assem_debug("ldr %s,fp+%d",regname[rt],offset); output_w32(0xe5900000|rd_rn_rm(rt,FP,0)|offset); } static void emit_movsbl(int addr, int rt) { u_int offset = addr-(u_int)&dynarec_local; assert(offset<256); assem_debug("ldrsb %s,fp+%d",regname[rt],offset); output_w32(0xe1d000d0|rd_rn_rm(rt,FP,0)|((offset<<4)&0xf00)|(offset&0xf)); } static void emit_movswl(int addr, int rt) { u_int offset = addr-(u_int)&dynarec_local; assert(offset<256); assem_debug("ldrsh %s,fp+%d",regname[rt],offset); output_w32(0xe1d000f0|rd_rn_rm(rt,FP,0)|((offset<<4)&0xf00)|(offset&0xf)); } static void emit_movzbl(int addr, int rt) { u_int offset = addr-(u_int)&dynarec_local; assert(offset<4096); assem_debug("ldrb %s,fp+%d",regname[rt],offset); output_w32(0xe5d00000|rd_rn_rm(rt,FP,0)|offset); } static void emit_movzwl(int addr, int rt) { u_int offset = addr-(u_int)&dynarec_local; assert(offset<256); assem_debug("ldrh %s,fp+%d",regname[rt],offset); output_w32(0xe1d000b0|rd_rn_rm(rt,FP,0)|((offset<<4)&0xf00)|(offset&0xf)); } /* static void emit_movzwl_reg(int rs, int rt) { assem_debug("movzwl %%%s,%%%s",regname[rs]+1,regname[rt]); assert(0); } */ static void emit_writeword_indexed(int rt, int offset, int rs) { assert(offset>-4096&&offset<4096); assem_debug("str %s,%s+%d",regname[rt],regname[rs],offset); if(offset>=0) { output_w32(0xe5800000|rd_rn_rm(rt,rs,0)|offset); }else{ output_w32(0xe5000000|rd_rn_rm(rt,rs,0)|(-offset)); } } static void emit_writeword_dualindexedx4(int rt, int rs1, int rs2) { assem_debug("str %s,%s,%s lsl #2",regname[rt],regname[rs1],regname[rs2]); output_w32(0xe7800000|rd_rn_rm(rt,rs1,rs2)|0x100); } static void emit_writeword_indexed_tlb(int rt, int addr, int rs, int map, int temp) { if(map<0) emit_writeword_indexed(rt, addr, rs); else { assert(addr==0); emit_writeword_dualindexedx4(rt, rs, map); } } static void emit_writedword_indexed_tlb(int rh, int rl, int addr, int rs, int map, int temp) { if(map<0) { if(rh>=0) emit_writeword_indexed(rh, addr, rs); emit_writeword_indexed(rl, addr+4, rs); }else{ assert(rh>=0); if(temp!=rs) emit_addimm(map,1,temp); emit_writeword_indexed_tlb(rh, addr, rs, map, temp); if(temp!=rs) emit_writeword_indexed_tlb(rl, addr, rs, temp, temp); else { emit_addimm(rs,4,rs); emit_writeword_indexed_tlb(rl, addr, rs, map, temp); } } } static void emit_writehword_indexed(int rt, int offset, int rs) { assert(offset>-256&&offset<256); assem_debug("strh %s,%s+%d",regname[rt],regname[rs],offset); if(offset>=0) { output_w32(0xe1c000b0|rd_rn_rm(rt,rs,0)|((offset<<4)&0xf00)|(offset&0xf)); }else{ output_w32(0xe14000b0|rd_rn_rm(rt,rs,0)|(((-offset)<<4)&0xf00)|((-offset)&0xf)); } } static void emit_writebyte_indexed(int rt, int offset, int rs) { assert(offset>-4096&&offset<4096); assem_debug("strb %s,%s+%d",regname[rt],regname[rs],offset); if(offset>=0) { output_w32(0xe5c00000|rd_rn_rm(rt,rs,0)|offset); }else{ output_w32(0xe5400000|rd_rn_rm(rt,rs,0)|(-offset)); } } static void emit_writebyte_dualindexedx4(int rt, int rs1, int rs2) { assem_debug("strb %s,%s,%s lsl #2",regname[rt],regname[rs1],regname[rs2]); output_w32(0xe7c00000|rd_rn_rm(rt,rs1,rs2)|0x100); } static void emit_writebyte_indexed_tlb(int rt, int addr, int rs, int map, int temp) { if(map<0) emit_writebyte_indexed(rt, addr, rs); else { if(addr==0) { emit_writebyte_dualindexedx4(rt, rs, map); }else{ emit_addimm(rs,addr,temp); emit_writebyte_dualindexedx4(rt, temp, map); } } } static void emit_writeword(int rt, int addr) { u_int offset = addr-(u_int)&dynarec_local; assert(offset<4096); assem_debug("str %s,fp+%d",regname[rt],offset); output_w32(0xe5800000|rd_rn_rm(rt,FP,0)|offset); } static void emit_writehword(int rt, int addr) { u_int offset = addr-(u_int)&dynarec_local; assert(offset<256); assem_debug("strh %s,fp+%d",regname[rt],offset); output_w32(0xe1c000b0|rd_rn_rm(rt,FP,0)|((offset<<4)&0xf00)|(offset&0xf)); } static void emit_writebyte(int rt, int addr) { u_int offset = addr-(u_int)&dynarec_local; assert(offset<4096); assem_debug("strb %s,fp+%d",regname[rt],offset); output_w32(0xe5c00000|rd_rn_rm(rt,FP,0)|offset); } /* static void emit_mul(int rs) { assem_debug("mul %%%s",regname[rs]); assert(0); } */ static void emit_umull(u_int rs1, u_int rs2, u_int hi, u_int lo) { assem_debug("umull %s, %s, %s, %s",regname[lo],regname[hi],regname[rs1],regname[rs2]); assert(rs1<16); assert(rs2<16); assert(hi<16); assert(lo<16); output_w32(0xe0800090|(hi<<16)|(lo<<12)|(rs2<<8)|rs1); } static void emit_umlal(u_int rs1, u_int rs2, u_int hi, u_int lo) { assem_debug("umlal %s, %s, %s, %s",regname[lo],regname[hi],regname[rs1],regname[rs2]); assert(rs1<16); assert(rs2<16); assert(hi<16); assert(lo<16); output_w32(0xe0a00090|(hi<<16)|(lo<<12)|(rs2<<8)|rs1); } static void emit_smull(u_int rs1, u_int rs2, u_int hi, u_int lo) { assem_debug("smull %s, %s, %s, %s",regname[lo],regname[hi],regname[rs1],regname[rs2]); assert(rs1<16); assert(rs2<16); assert(hi<16); assert(lo<16); output_w32(0xe0c00090|(hi<<16)|(lo<<12)|(rs2<<8)|rs1); } static void emit_smlal(u_int rs1, u_int rs2, u_int hi, u_int lo) { assem_debug("smlal %s, %s, %s, %s",regname[lo],regname[hi],regname[rs1],regname[rs2]); assert(rs1<16); assert(rs2<16); assert(hi<16); assert(lo<16); output_w32(0xe0e00090|(hi<<16)|(lo<<12)|(rs2<<8)|rs1); } static void emit_clz(int rs,int rt) { assem_debug("clz %s,%s",regname[rt],regname[rs]); output_w32(0xe16f0f10|rd_rn_rm(rt,0,rs)); } static void emit_subcs(int rs1,int rs2,int rt) { assem_debug("subcs %s,%s,%s",regname[rt],regname[rs1],regname[rs2]); output_w32(0x20400000|rd_rn_rm(rt,rs1,rs2)); } static void emit_shrcc_imm(int rs,u_int imm,int rt) { assert(imm>0); assert(imm<32); assem_debug("lsrcc %s,%s,#%d",regname[rt],regname[rs],imm); output_w32(0x31a00000|rd_rn_rm(rt,0,rs)|0x20|(imm<<7)); } static void emit_negmi(int rs, int rt) { assem_debug("rsbmi %s,%s,#0",regname[rt],regname[rs]); output_w32(0x42600000|rd_rn_rm(rt,rs,0)); } static void emit_orreq(u_int rs1,u_int rs2,u_int rt) { assem_debug("orreq %s,%s,%s",regname[rt],regname[rs1],regname[rs2]); output_w32(0x01800000|rd_rn_rm(rt,rs1,rs2)); } static void emit_orrne(u_int rs1,u_int rs2,u_int rt) { assem_debug("orrne %s,%s,%s",regname[rt],regname[rs1],regname[rs2]); output_w32(0x11800000|rd_rn_rm(rt,rs1,rs2)); } static void emit_bic_lsl(u_int rs1,u_int rs2,u_int shift,u_int rt) { assem_debug("bic %s,%s,%s lsl %s",regname[rt],regname[rs1],regname[rs2],regname[shift]); output_w32(0xe1C00000|rd_rn_rm(rt,rs1,rs2)|0x10|(shift<<8)); } static void emit_biceq_lsl(u_int rs1,u_int rs2,u_int shift,u_int rt) { assem_debug("biceq %s,%s,%s lsl %s",regname[rt],regname[rs1],regname[rs2],regname[shift]); output_w32(0x01C00000|rd_rn_rm(rt,rs1,rs2)|0x10|(shift<<8)); } static void emit_bicne_lsl(u_int rs1,u_int rs2,u_int shift,u_int rt) { assem_debug("bicne %s,%s,%s lsl %s",regname[rt],regname[rs1],regname[rs2],regname[shift]); output_w32(0x11C00000|rd_rn_rm(rt,rs1,rs2)|0x10|(shift<<8)); } static void emit_bic_lsr(u_int rs1,u_int rs2,u_int shift,u_int rt) { assem_debug("bic %s,%s,%s lsr %s",regname[rt],regname[rs1],regname[rs2],regname[shift]); output_w32(0xe1C00000|rd_rn_rm(rt,rs1,rs2)|0x30|(shift<<8)); } static void emit_biceq_lsr(u_int rs1,u_int rs2,u_int shift,u_int rt) { assem_debug("biceq %s,%s,%s lsr %s",regname[rt],regname[rs1],regname[rs2],regname[shift]); output_w32(0x01C00000|rd_rn_rm(rt,rs1,rs2)|0x30|(shift<<8)); } static void emit_bicne_lsr(u_int rs1,u_int rs2,u_int shift,u_int rt) { assem_debug("bicne %s,%s,%s lsr %s",regname[rt],regname[rs1],regname[rs2],regname[shift]); output_w32(0x11C00000|rd_rn_rm(rt,rs1,rs2)|0x30|(shift<<8)); } static void emit_teq(int rs, int rt) { assem_debug("teq %s,%s",regname[rs],regname[rt]); output_w32(0xe1300000|rd_rn_rm(0,rs,rt)); } static void emit_rsbimm(int rs, int imm, int rt) { u_int armval, ret; ret = genimm(imm,&armval); assert(ret); assem_debug("rsb %s,%s,#%d",regname[rt],regname[rs],imm); output_w32(0xe2600000|rd_rn_rm(rt,rs,0)|armval); } // Load 2 immediates optimizing for small code size static void emit_mov2imm_compact(int imm1,u_int rt1,int imm2,u_int rt2) { emit_movimm(imm1,rt1); u_int armval; if(genimm(imm2-imm1,&armval)) { assem_debug("add %s,%s,#%d",regname[rt2],regname[rt1],imm2-imm1); output_w32(0xe2800000|rd_rn_rm(rt2,rt1,0)|armval); }else if(genimm(imm1-imm2,&armval)) { assem_debug("sub %s,%s,#%d",regname[rt2],regname[rt1],imm1-imm2); output_w32(0xe2400000|rd_rn_rm(rt2,rt1,0)|armval); } else emit_movimm(imm2,rt2); } // Conditionally select one of two immediates, optimizing for small code size // This will only be called if HAVE_CMOV_IMM is defined static void emit_cmov2imm_e_ne_compact(int imm1,int imm2,u_int rt) { u_int armval; if(genimm(imm2-imm1,&armval)) { emit_movimm(imm1,rt); assem_debug("addne %s,%s,#%d",regname[rt],regname[rt],imm2-imm1); output_w32(0x12800000|rd_rn_rm(rt,rt,0)|armval); }else if(genimm(imm1-imm2,&armval)) { emit_movimm(imm1,rt); assem_debug("subne %s,%s,#%d",regname[rt],regname[rt],imm1-imm2); output_w32(0x12400000|rd_rn_rm(rt,rt,0)|armval); } else { #ifdef ARMv5_ONLY emit_movimm(imm1,rt); add_literal((int)out,imm2); assem_debug("ldrne %s,pc+? [=%x]",regname[rt],imm2); output_w32(0x15900000|rd_rn_rm(rt,15,0)); #else emit_movw(imm1&0x0000FFFF,rt); if((imm1&0xFFFF)!=(imm2&0xFFFF)) { assem_debug("movwne %s,#%d (0x%x)",regname[rt],imm2&0xFFFF,imm2&0xFFFF); output_w32(0x13000000|rd_rn_rm(rt,0,0)|(imm2&0xfff)|((imm2<<4)&0xf0000)); } emit_movt(imm1&0xFFFF0000,rt); if((imm1&0xFFFF0000)!=(imm2&0xFFFF0000)) { assem_debug("movtne %s,#%d (0x%x)",regname[rt],imm2&0xffff0000,imm2&0xffff0000); output_w32(0x13400000|rd_rn_rm(rt,0,0)|((imm2>>16)&0xfff)|((imm2>>12)&0xf0000)); } #endif } } #if !defined(HOST_IMM8) // special case for checking invalid_code static void emit_cmpmem_indexedsr12_imm(int addr,int r,int imm) { assert(0); } #endif // special case for checking invalid_code static void emit_cmpmem_indexedsr12_reg(int base,int r,int imm) { assert(imm<128&&imm>=0); assert(r>=0&&r<16); assem_debug("ldrb lr,%s,%s lsr #12",regname[base],regname[r]); output_w32(0xe7d00000|rd_rn_rm(HOST_TEMPREG,base,r)|0x620); emit_cmpimm(HOST_TEMPREG,imm); } /* special case for tlb mapping */ static void emit_addsr12(int rs1,int rs2,int rt) { assem_debug("add %s,%s,%s lsr #12",regname[rt],regname[rs1],regname[rs2]); output_w32(0xe0800620|rd_rn_rm(rt,rs1,rs2)); } static void emit_readptr(intptr_t addr, int rt) { emit_readword(addr,rt); } static void emit_callne(int a) { assem_debug("blne %x",a); u_int offset=genjmp(a); output_w32(0x1b000000|offset); } static void emit_gen_ram_ptr(u_int addr, int hr) { emit_lea_rip((int)g_rdram-0x80000000+addr,hr); } #ifdef IMM_PREFETCH // Used to preload hash table entries static void emit_prefetch(void *addr) { assem_debug("prefetch %x",(int)addr); output_byte(0x0F); output_byte(0x18); output_modrm(0,5,1); output_w32((int)addr); } #endif #ifdef REG_PREFETCH static void emit_prefetchreg(int r) { assem_debug("pld %s",regname[r]); output_w32(0xf5d0f000|rd_rn_rm(0,r,0)); } #endif // Special case for mini_ht static void emit_ldreq_indexed(int rs, u_int offset, int rt) { assert(offset<4096); assem_debug("ldreq %s,[%s, #%d]",regname[rt],regname[rs],offset); output_w32(0x05900000|rd_rn_rm(rt,rs,0)|offset); } static void emit_flds(int r,int sr) { assem_debug("flds s%d,[%s]",sr,regname[r]); output_w32(0xed900a00|((sr&14)<<11)|((sr&1)<<22)|(r<<16)); } static void emit_vldr(int r,int vr) { assem_debug("vldr d%d,[%s]",vr,regname[r]); output_w32(0xed900b00|(vr<<12)|(r<<16)); } static void emit_fsts(int sr,int r) { assem_debug("fsts s%d,[%s]",sr,regname[r]); output_w32(0xed800a00|((sr&14)<<11)|((sr&1)<<22)|(r<<16)); } static void emit_vstr(int vr,int r) { assem_debug("vstr d%d,[%s]",vr,regname[r]); output_w32(0xed800b00|(vr<<12)|(r<<16)); } static void emit_ftosizs(int s,int d) { assem_debug("ftosizs s%d,s%d",d,s); output_w32(0xeebd0ac0|((d&14)<<11)|((d&1)<<22)|((s&14)>>1)|((s&1)<<5)); } static void emit_ftosizd(int s,int d) { assem_debug("ftosizd s%d,d%d",d,s); output_w32(0xeebd0bc0|((d&14)<<11)|((d&1)<<22)|(s&7)); } static void emit_fsitos(int s,int d) { assem_debug("fsitos s%d,s%d",d,s); output_w32(0xeeb80ac0|((d&14)<<11)|((d&1)<<22)|((s&14)>>1)|((s&1)<<5)); } static void emit_fsitod(int s,int d) { assem_debug("fsitod d%d,s%d",d,s); output_w32(0xeeb80bc0|((d&7)<<12)|((s&14)>>1)|((s&1)<<5)); } static void emit_fcvtds(int s,int d) { assem_debug("fcvtds d%d,s%d",d,s); output_w32(0xeeb70ac0|((d&7)<<12)|((s&14)>>1)|((s&1)<<5)); } static void emit_fcvtsd(int s,int d) { assem_debug("fcvtsd s%d,d%d",d,s); output_w32(0xeeb70bc0|((d&14)<<11)|((d&1)<<22)|(s&7)); } static void emit_fsqrts(int s,int d) { assem_debug("fsqrts d%d,s%d",d,s); output_w32(0xeeb10ac0|((d&14)<<11)|((d&1)<<22)|((s&14)>>1)|((s&1)<<5)); } static void emit_fsqrtd(int s,int d) { assem_debug("fsqrtd s%d,d%d",d,s); output_w32(0xeeb10bc0|((d&7)<<12)|(s&7)); } static void emit_fabss(int s,int d) { assem_debug("fabss d%d,s%d",d,s); output_w32(0xeeb00ac0|((d&14)<<11)|((d&1)<<22)|((s&14)>>1)|((s&1)<<5)); } static void emit_fabsd(int s,int d) { assem_debug("fabsd s%d,d%d",d,s); output_w32(0xeeb00bc0|((d&7)<<12)|(s&7)); } static void emit_fnegs(int s,int d) { assem_debug("fnegs d%d,s%d",d,s); output_w32(0xeeb10a40|((d&14)<<11)|((d&1)<<22)|((s&14)>>1)|((s&1)<<5)); } static void emit_fnegd(int s,int d) { assem_debug("fnegd s%d,d%d",d,s); output_w32(0xeeb10b40|((d&7)<<12)|(s&7)); } static void emit_fadds(int s1,int s2,int d) { assem_debug("fadds s%d,s%d,s%d",d,s1,s2); output_w32(0xee300a00|((d&14)<<11)|((d&1)<<22)|((s1&14)<<15)|((s1&1)<<7)|((s2&14)>>1)|((s2&1)<<5)); } static void emit_faddd(int s1,int s2,int d) { assem_debug("faddd d%d,d%d,d%d",d,s1,s2); output_w32(0xee300b00|((d&7)<<12)|((s1&7)<<16)|(s2&7)); } static void emit_fsubs(int s1,int s2,int d) { assem_debug("fsubs s%d,s%d,s%d",d,s1,s2); output_w32(0xee300a40|((d&14)<<11)|((d&1)<<22)|((s1&14)<<15)|((s1&1)<<7)|((s2&14)>>1)|((s2&1)<<5)); } static void emit_fsubd(int s1,int s2,int d) { assem_debug("fsubd d%d,d%d,d%d",d,s1,s2); output_w32(0xee300b40|((d&7)<<12)|((s1&7)<<16)|(s2&7)); } static void emit_fmuls(int s1,int s2,int d) { assem_debug("fmuls s%d,s%d,s%d",d,s1,s2); output_w32(0xee200a00|((d&14)<<11)|((d&1)<<22)|((s1&14)<<15)|((s1&1)<<7)|((s2&14)>>1)|((s2&1)<<5)); } static void emit_fmuld(int s1,int s2,int d) { assem_debug("fmuld d%d,d%d,d%d",d,s1,s2); output_w32(0xee200b00|((d&7)<<12)|((s1&7)<<16)|(s2&7)); } static void emit_fdivs(int s1,int s2,int d) { assem_debug("fdivs s%d,s%d,s%d",d,s1,s2); output_w32(0xee800a00|((d&14)<<11)|((d&1)<<22)|((s1&14)<<15)|((s1&1)<<7)|((s2&14)>>1)|((s2&1)<<5)); } static void emit_fdivd(int s1,int s2,int d) { assem_debug("fdivd d%d,d%d,d%d",d,s1,s2); output_w32(0xee800b00|((d&7)<<12)|((s1&7)<<16)|(s2&7)); } static void emit_fcmps(int x,int y) { assem_debug("fcmps s14, s15"); output_w32(0xeeb47a67); } static void emit_fcmpd(int x,int y) { assem_debug("fcmpd d6, d7"); output_w32(0xeeb46b47); } static void emit_fmstat() { assem_debug("fmstat"); output_w32(0xeef1fa10); } static void emit_bicne_imm(int rs,int imm,int rt) { u_int armval, ret; ret = genimm(imm,&armval); assert(ret); assem_debug("bicne %s,%s,#%d",regname[rt],regname[rs],imm); output_w32(0x13c00000|rd_rn_rm(rt,rs,0)|armval); } static void emit_biccs_imm(int rs,int imm,int rt) { u_int armval, ret; ret = genimm(imm,&armval); assert(ret); assem_debug("biccs %s,%s,#%d",regname[rt],regname[rs],imm); output_w32(0x23c00000|rd_rn_rm(rt,rs,0)|armval); } static void emit_bicvc_imm(int rs,int imm,int rt) { u_int armval, ret; ret = genimm(imm,&armval); assert(ret); assem_debug("bicvc %s,%s,#%d",regname[rt],regname[rs],imm); output_w32(0x73c00000|rd_rn_rm(rt,rs,0)|armval); } static void emit_bichi_imm(int rs,int imm,int rt) { u_int armval, ret; ret = genimm(imm,&armval); assert(ret); assem_debug("bichi %s,%s,#%d",regname[rt],regname[rs],imm); output_w32(0x83c00000|rd_rn_rm(rt,rs,0)|armval); } static void emit_orrvs_imm(int rs,int imm,int rt) { u_int armval, ret; ret = genimm(imm,&armval); assert(ret); assem_debug("orrvs %s,%s,#%d",regname[rt],regname[rs],imm); output_w32(0x63800000|rd_rn_rm(rt,rs,0)|armval); } static void emit_jno_unlikely(int a) { //emit_jno(a); assem_debug("addvc pc,pc,#? (%x)",/*a-(int)out-8,*/a); output_w32(0x72800000|rd_rn_rm(15,15,0)); } static void save_regs_all(u_int reglist) { int i; if(!reglist) return; assem_debug("stmia fp,{"); for(i=0;i<16;i++) if(reglist&(1<=0&&((i_dirty>>hr)&1)) { if(((regs[i].isconst>>hr)&1)&&i_regmap[hr]>0) { if(i_regmap[hr]<64 || !((i_is32>>(i_regmap[hr]&63))&1) ) { int value=constmap[i][hr]; if(value==0) { emit_zeroreg(HOST_TEMPREG); } else { emit_movimm(value,HOST_TEMPREG); } emit_storereg(i_regmap[hr],HOST_TEMPREG); if((i_is32>>i_regmap[hr])&1) { if(value!=-1&&value!=0) emit_sarimm(HOST_TEMPREG,31,HOST_TEMPREG); emit_storereg(i_regmap[hr]|64,HOST_TEMPREG); } } } } } } /* Stubs/epilogue */ static void literal_pool(int n) { if(!literalcount) return; if(n) { if((int)out-literals[0][0]<4096-n) return; } u_int *ptr; int i; for(i=0;i=0x7000000&&addr<0x7FFFFFF); //assert((target>=0x80000000&&target<0x80800000)||(target>0xA4000000&&target<0xA4001000)); //DEBUG > #ifdef DEBUG_CYCLE_COUNT emit_readword((int)&last_count,ECX); emit_add(HOST_CCREG,ECX,HOST_CCREG); emit_readword((int)&next_interupt,ECX); emit_writeword(HOST_CCREG,(int)&g_cp0_regs[CP0_COUNT_REG]); emit_sub(HOST_CCREG,ECX,HOST_CCREG); emit_writeword(ECX,(int)&last_count); #endif //DEBUG < emit_jmp(linker); } static void emit_extjump(int addr, int target) { emit_extjump2(addr, target, (int)dyna_linker); } static void emit_extjump_ds(int addr, int target) { emit_extjump2(addr, target, (int)dyna_linker_ds); } static void do_readstub(int n) { assem_debug("do_readstub %x",start+stubs[n][3]*4); literal_pool(256); set_jump_target(stubs[n][1],(int)out); int type=stubs[n][0]; int i=stubs[n][3]; int rs=stubs[n][4]; struct regstat *i_regs=(struct regstat *)stubs[n][5]; u_int reglist=stubs[n][7]; signed char *i_regmap=i_regs->regmap; int addr=get_reg(i_regmap,AGEN1+(i&1)); int rth,rt; int ds; if(itype[i]==C1LS||itype[i]==LOADLR) { rth=get_reg(i_regmap,FTEMP|64); rt=get_reg(i_regmap,FTEMP); }else{ rth=get_reg(i_regmap,rt1[i]|64); rt=get_reg(i_regmap,rt1[i]); } assert(rs>=0); if(addr<0) addr=rt; if(addr<0&&itype[i]!=C1LS&&itype[i]!=LOADLR) addr=get_reg(i_regmap,-1); assert(addr>=0); int ftable=0; if(type==LOADB_STUB||type==LOADBU_STUB) ftable=(int)readmemb; if(type==LOADH_STUB||type==LOADHU_STUB) ftable=(int)readmemh; if(type==LOADW_STUB) ftable=(int)readmem; if(type==LOADD_STUB) ftable=(int)readmemd; emit_writeword(rs,(int)&address); //emit_pusha(); save_regs(reglist); ds=i_regs!=®s[i]; int real_rs=(itype[i]==LOADLR)?-1:get_reg(i_regmap,rs1[i]); u_int cmask=ds?-1:(CALLER_SAVE_REGS|~i_regs->wasconst); if(!ds) load_all_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty&~(1<regmap_entry,i_regs->was32,i_regs->wasdirty&cmask&~(1<>rs1[i])&1)<<1)+ds,3); //emit_readword((int)&last_count,temp); //emit_add(cc,temp,cc); //emit_writeword(cc,(int)&g_cp0_regs[CP0_COUNT_REG]); //emit_mov(15,14); emit_call((int)&indirect_jump_indexed); //emit_callreg(rs); //emit_readword_dualindexedx4(rs,HOST_TEMPREG,15); // We really shouldn't need to update the count here, // but not doing so causes random crashes... emit_readword((int)&g_cp0_regs[CP0_COUNT_REG],HOST_TEMPREG); emit_readword((int)&next_interupt,2); emit_addimm(HOST_TEMPREG,-2*stubs[n][6]-2,HOST_TEMPREG); emit_writeword(2,(int)&last_count); emit_sub(HOST_TEMPREG,2,cc<0?HOST_TEMPREG:cc); if(cc<0) { emit_storereg(CCREG,HOST_TEMPREG); } //emit_popa(); restore_regs(reglist); //if((cc=get_reg(regmap,CCREG))>=0) { // emit_loadreg(CCREG,cc); //} if(rt>=0) { if(type==LOADB_STUB) emit_movsbl((int)&readmem_dword,rt); if(type==LOADBU_STUB) emit_movzbl((int)&readmem_dword,rt); if(type==LOADH_STUB) emit_movswl((int)&readmem_dword,rt); if(type==LOADHU_STUB) emit_movzwl((int)&readmem_dword,rt); if(type==LOADW_STUB) emit_readword((int)&readmem_dword,rt); if(type==LOADD_STUB) { emit_readword((int)&readmem_dword,rt); if(rth>=0) emit_readword(((int)&readmem_dword)+4,rth); } } emit_jmp(stubs[n][2]); // return address } static void inline_readstub(int type, int i, u_int addr, signed char regmap[], int target, int adj, u_int reglist) { int rs=get_reg(regmap,target); int rth=get_reg(regmap,target|64); int rt=get_reg(regmap,target); if(rs<0) rs=get_reg(regmap,-1); assert(rs>=0); int ftable=0; if(type==LOADB_STUB||type==LOADBU_STUB) ftable=(int)readmemb; if(type==LOADH_STUB||type==LOADHU_STUB) ftable=(int)readmemh; if(type==LOADW_STUB) ftable=(int)readmem; if(type==LOADD_STUB) ftable=(int)readmemd; emit_writeword(rs,(int)&address); //emit_pusha(); save_regs(reglist); if((signed int)addr>=(signed int)0xC0000000) { // Theoretically we can have a pagefault here, if the TLB has never // been enabled and the address is outside the range 80000000..BFFFFFFF // Write out the registers so the pagefault can be handled. This is // a very rare case and likely represents a bug. int ds=regmap!=regs[i].regmap; if(!ds) load_all_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty,i); if(!ds) wb_dirtys(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty); else wb_dirtys(branch_regs[i-1].regmap_entry,branch_regs[i-1].was32,branch_regs[i-1].wasdirty); } //emit_shrimm(rs,16,1); int cc=get_reg(regmap,CCREG); if(cc<0) { emit_loadreg(CCREG,2); } //emit_movimm(ftable,0); emit_movimm(((u_int *)ftable)[addr>>16],0); //emit_readword((int)&last_count,12); emit_addimm(cc<0?2:cc,CLOCK_DIVIDER*(adj+1),2); if((signed int)addr>=(signed int)0xC0000000) { // Pagefault address int ds=regmap!=regs[i].regmap; emit_movimm(start+i*4+(((regs[i].was32>>rs1[i])&1)<<1)+ds,3); } //emit_add(12,2,2); //emit_writeword(2,(int)&g_cp0_regs[CP0_COUNT_REG]); //emit_call(((u_int *)ftable)[addr>>16]); emit_call((int)&indirect_jump); // We really shouldn't need to update the count here, // but not doing so causes random crashes... emit_readword((int)&g_cp0_regs[CP0_COUNT_REG],HOST_TEMPREG); emit_readword((int)&next_interupt,2); emit_addimm(HOST_TEMPREG,-CLOCK_DIVIDER*(adj+1),HOST_TEMPREG); emit_writeword(2,(int)&last_count); emit_sub(HOST_TEMPREG,2,cc<0?HOST_TEMPREG:cc); if(cc<0) { emit_storereg(CCREG,HOST_TEMPREG); } //emit_popa(); restore_regs(reglist); if(rt>=0) { if(type==LOADB_STUB) emit_movsbl((int)&readmem_dword,rt); if(type==LOADBU_STUB) emit_movzbl((int)&readmem_dword,rt); if(type==LOADH_STUB) emit_movswl((int)&readmem_dword,rt); if(type==LOADHU_STUB) emit_movzwl((int)&readmem_dword,rt); if(type==LOADW_STUB) emit_readword((int)&readmem_dword,rt); if(type==LOADD_STUB) { emit_readword((int)&readmem_dword,rt); if(rth>=0) emit_readword(((int)&readmem_dword)+4,rth); } } } static void do_writestub(int n) { assem_debug("do_writestub %x",start+stubs[n][3]*4); literal_pool(256); set_jump_target(stubs[n][1],(int)out); int type=stubs[n][0]; int i=stubs[n][3]; int rs=stubs[n][4]; struct regstat *i_regs=(struct regstat *)stubs[n][5]; u_int reglist=stubs[n][7]; signed char *i_regmap=i_regs->regmap; int addr=get_reg(i_regmap,AGEN1+(i&1)); int rth,rt,r; int ds; if(itype[i]==C1LS) { rth=get_reg(i_regmap,FTEMP|64); rt=get_reg(i_regmap,r=FTEMP); }else{ rth=get_reg(i_regmap,rs2[i]|64); rt=get_reg(i_regmap,r=rs2[i]); } assert(rs>=0); assert(rt>=0); if(addr<0) addr=get_reg(i_regmap,-1); assert(addr>=0); int ftable=0; if(type==STOREB_STUB) ftable=(int)writememb; if(type==STOREH_STUB) ftable=(int)writememh; if(type==STOREW_STUB) ftable=(int)writemem; if(type==STORED_STUB) ftable=(int)writememd; emit_writeword(rs,(int)&address); //emit_shrimm(rs,16,rs); //emit_movmem_indexedx4(ftable,rs,rs); if(type==STOREB_STUB) emit_writebyte(rt,(int)&cpu_byte); if(type==STOREH_STUB) emit_writehword(rt,(int)&hword); if(type==STOREW_STUB) emit_writeword(rt,(int)&word); if(type==STORED_STUB) { emit_writeword(rt,(int)&dword); emit_writeword(r?rth:rt,(int)&dword+4); } //emit_pusha(); save_regs(reglist); ds=i_regs!=®s[i]; int real_rs=get_reg(i_regmap,rs1[i]); u_int cmask=ds?-1:(CALLER_SAVE_REGS|~i_regs->wasconst); if(!ds) load_all_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty&~(1<regmap_entry,i_regs->was32,i_regs->wasdirty&cmask&~(1<>rs1[i])&1)<<1)+ds,3); //emit_readword((int)&last_count,temp); //emit_addimm(cc,2*stubs[n][5]+2,cc); //emit_add(cc,temp,cc); //emit_writeword(cc,(int)&g_cp0_regs[CP0_COUNT_REG]); emit_call((int)&indirect_jump_indexed); //emit_callreg(rs); emit_readword((int)&g_cp0_regs[CP0_COUNT_REG],HOST_TEMPREG); emit_readword((int)&next_interupt,2); emit_addimm(HOST_TEMPREG,-2*stubs[n][6]-2,HOST_TEMPREG); emit_writeword(2,(int)&last_count); emit_sub(HOST_TEMPREG,2,cc<0?HOST_TEMPREG:cc); if(cc<0) { emit_storereg(CCREG,HOST_TEMPREG); } //emit_popa(); restore_regs(reglist); //if((cc=get_reg(regmap,CCREG))>=0) { // emit_loadreg(CCREG,cc); //} emit_jmp(stubs[n][2]); // return address } static void inline_writestub(int type, int i, u_int addr, signed char regmap[], int target, int adj, u_int reglist) { int rs=get_reg(regmap,-1); int rth=get_reg(regmap,target|64); int rt=get_reg(regmap,target); assert(rs>=0); assert(rt>=0); int ftable=0; if(type==STOREB_STUB) ftable=(int)writememb; if(type==STOREH_STUB) ftable=(int)writememh; if(type==STOREW_STUB) ftable=(int)writemem; if(type==STORED_STUB) ftable=(int)writememd; emit_writeword(rs,(int)&address); //emit_shrimm(rs,16,rs); //emit_movmem_indexedx4(ftable,rs,rs); if(type==STOREB_STUB) emit_writebyte(rt,(int)&cpu_byte); if(type==STOREH_STUB) emit_writehword(rt,(int)&hword); if(type==STOREW_STUB) emit_writeword(rt,(int)&word); if(type==STORED_STUB) { emit_writeword(rt,(int)&dword); emit_writeword(target?rth:rt,(int)&dword+4); } //emit_pusha(); save_regs(reglist); if((signed int)addr>=(signed int)0xC0000000) { // Theoretically we can have a pagefault here, if the TLB has never // been enabled and the address is outside the range 80000000..BFFFFFFF // Write out the registers so the pagefault can be handled. This is // a very rare case and likely represents a bug. int ds=regmap!=regs[i].regmap; if(!ds) load_all_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty,i); if(!ds) wb_dirtys(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty); else wb_dirtys(branch_regs[i-1].regmap_entry,branch_regs[i-1].was32,branch_regs[i-1].wasdirty); } //emit_shrimm(rs,16,1); int cc=get_reg(regmap,CCREG); if(cc<0) { emit_loadreg(CCREG,2); } //emit_movimm(ftable,0); emit_movimm(((u_int *)ftable)[addr>>16],0); //emit_readword((int)&last_count,12); emit_addimm(cc<0?2:cc,CLOCK_DIVIDER*(adj+1),2); if((signed int)addr>=(signed int)0xC0000000) { // Pagefault address int ds=regmap!=regs[i].regmap; emit_movimm(start+i*4+(((regs[i].was32>>rs1[i])&1)<<1)+ds,3); } //emit_add(12,2,2); //emit_writeword(2,(int)&g_cp0_regs[CP0_COUNT_REG]); //emit_call(((u_int *)ftable)[addr>>16]); emit_call((int)&indirect_jump); emit_readword((int)&g_cp0_regs[CP0_COUNT_REG],HOST_TEMPREG); emit_readword((int)&next_interupt,2); emit_addimm(HOST_TEMPREG,-CLOCK_DIVIDER*(adj+1),HOST_TEMPREG); emit_writeword(2,(int)&last_count); emit_sub(HOST_TEMPREG,2,cc<0?HOST_TEMPREG:cc); if(cc<0) { emit_storereg(CCREG,HOST_TEMPREG); } //emit_popa(); restore_regs(reglist); } static void do_unalignedwritestub(int n) { set_jump_target(stubs[n][1],(int)out); output_w32(0xef000000); emit_jmp(stubs[n][2]); // return address } void printregs(int edi,int esi,int ebp,int esp,int b,int d,int c,int a) { DebugMessage(M64MSG_VERBOSE, "regs: %x %x %x %x %x %x %x (%x)",a,b,c,d,ebp,esi,edi,(&edi)[-1]); } static void do_invstub(int n) { literal_pool(20); u_int reglist=stubs[n][3]; set_jump_target(stubs[n][1],(int)out); save_regs(reglist); if(stubs[n][4]!=0) emit_mov(stubs[n][4],0); emit_call((int)&invalidate_addr); restore_regs(reglist); emit_jmp(stubs[n][2]); // return address } static int do_dirty_stub(int i) { assem_debug("do_dirty_stub %x",start+i*4); // Careful about the code output here, verify_dirty needs to parse it. #ifdef ARMv5_ONLY emit_loadlp((int)start<(int)0xC0000000?(int)source:(int)start,1); emit_loadlp((int)copy,2); emit_loadlp(slen*4,3); #else emit_movw(((int)start<(int)0xC0000000?(u_int)source:(u_int)start)&0x0000FFFF,1); emit_movw(((u_int)copy)&0x0000FFFF,2); emit_movt(((int)start<(int)0xC0000000?(u_int)source:(u_int)start)&0xFFFF0000,1); emit_movt(((u_int)copy)&0xFFFF0000,2); emit_movw(slen*4,3); #endif emit_movimm(start+i*4,0); emit_call((int)start<(int)0xC0000000?(int)&verify_code:(int)&verify_code_vm); int entry=(int)out; load_regs_entry(i); if(entry==(int)out) entry=instr_addr[i]; emit_jmp(instr_addr[i]); return entry; } static void do_dirty_stub_ds() { // Careful about the code output here, verify_dirty needs to parse it. #ifdef ARMv5_ONLY emit_loadlp((int)start<(int)0xC0000000?(int)source:(int)start,1); emit_loadlp((int)copy,2); emit_loadlp(slen*4,3); #else emit_movw(((int)start<(int)0xC0000000?(u_int)source:(u_int)start)&0x0000FFFF,1); emit_movw(((u_int)copy)&0x0000FFFF,2); emit_movt(((int)start<(int)0xC0000000?(u_int)source:(u_int)start)&0xFFFF0000,1); emit_movt(((u_int)copy)&0xFFFF0000,2); emit_movw(slen*4,3); #endif emit_movimm(start+1,0); emit_call((int)&verify_code_ds); } static void do_cop1stub(int n) { literal_pool(256); assem_debug("do_cop1stub %x",start+stubs[n][3]*4); set_jump_target(stubs[n][1],(int)out); int i=stubs[n][3]; int rs=stubs[n][4]; struct regstat *i_regs=(struct regstat *)stubs[n][5]; int ds=stubs[n][6]; if(!ds) { load_all_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty,i); //if(i_regs!=®s[i]) DebugMessage(M64MSG_VERBOSE, "oops: regs[i]=%x i_regs=%x",(int)®s[i],(int)i_regs); } //else {DebugMessage(M64MSG_ERROR, "fp exception in delay slot");} wb_dirtys(i_regs->regmap_entry,i_regs->was32,i_regs->wasdirty); if(regs[i].regmap_entry[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG); emit_movimm(start+(i-ds)*4,EAX); // Get PC emit_addimm(HOST_CCREG,CLOCK_DIVIDER*ccadj[i],HOST_CCREG); // CHECK: is this right? There should probably be an extra cycle... emit_jmp(ds?(int)fp_exception_ds:(int)fp_exception); } /* TLB */ static int do_tlb_r(int s,int ar,int map,int cache,int x,int a,int shift,int c,u_int addr) { if(c) { if((signed int)addr>=(signed int)0xC0000000) { // address_generation already loaded the const emit_readword_dualindexedx4(FP,map,map); } else return -1; // No mapping } else { assert(s!=map); if(cache>=0) { // Use cached offset to memory map emit_addsr12(cache,s,map); }else{ emit_movimm(((int)memory_map-(int)&dynarec_local)>>2,map); emit_addsr12(map,s,map); } // Schedule this while we wait on the load //if(x) emit_xorimm(s,x,ar); if(shift>=0) emit_shlimm(s,3,shift); if(~a) emit_andimm(s,a,ar); emit_readword_dualindexedx4(FP,map,map); } return map; } static int do_tlb_r_branch(int map, int c, u_int addr, intptr_t *jaddr) { if(!c||(signed int)addr>=(signed int)0xC0000000) { emit_test(map,map); *jaddr=(intptr_t)out; emit_js(0); } return map; } static void gen_tlb_addr_r(int ar, int map) { if(map>=0) { assem_debug("add %s,%s,%s lsl #2",regname[ar],regname[ar],regname[map]); output_w32(0xe0800100|rd_rn_rm(ar,ar,map)); } } static int do_tlb_w(int s,int ar,int map,int cache,int x,int c,u_int addr) { if(c) { if(addr<0x80800000||addr>=0xC0000000) { // address_generation already loaded the const emit_readword_dualindexedx4(FP,map,map); } else return -1; // No mapping } else { assert(s!=map); if(cache>=0) { // Use cached offset to memory map emit_addsr12(cache,s,map); }else{ emit_movimm(((int)memory_map-(int)&dynarec_local)>>2,map); emit_addsr12(map,s,map); } // Schedule this while we wait on the load //if(x) emit_xorimm(s,x,ar); emit_readword_dualindexedx4(FP,map,map); } return map; } static void do_tlb_w_branch(int map, int c, u_int addr, intptr_t *jaddr) { if(!c||addr<0x80800000||addr>=0xC0000000) { emit_testimm(map,0x40000000); *jaddr=(intptr_t)out; emit_jne(0); } } static void gen_tlb_addr_w(int ar, int map) { if(map>=0) { assem_debug("add %s,%s,%s lsl #2",regname[ar],regname[ar],regname[map]); output_w32(0xe0800100|rd_rn_rm(ar,ar,map)); } } // This reverses the above operation static void gen_orig_addr_w(int ar, int map) { if(map>=0) { assem_debug("sub %s,%s,%s lsl #2",regname[ar],regname[ar],regname[map]); output_w32(0xe0400100|rd_rn_rm(ar,ar,map)); } } // Generate the address of the memory_map entry, relative to dynarec_local static void generate_map_const(u_int addr,int reg) { //DebugMessage(M64MSG_VERBOSE, "generate_map_const(%x,%s)",addr,regname[reg]); emit_movimm((addr>>12)+(((u_int)memory_map-(u_int)&dynarec_local)>>2),reg); } /* Special assem */ static void shift_assemble_arm(int i,struct regstat *i_regs) { if(rt1[i]) { if(opcode2[i]<=0x07) // SLLV/SRLV/SRAV { signed char s,t,shift; t=get_reg(i_regs->regmap,rt1[i]); s=get_reg(i_regs->regmap,rs1[i]); shift=get_reg(i_regs->regmap,rs2[i]); if(t>=0){ if(rs1[i]==0) { emit_zeroreg(t); } else if(rs2[i]==0) { assert(s>=0); if(s!=t) emit_mov(s,t); } else { emit_andimm(shift,31,HOST_TEMPREG); if(opcode2[i]==4) // SLLV { emit_shl(s,HOST_TEMPREG,t); } if(opcode2[i]==6) // SRLV { emit_shr(s,HOST_TEMPREG,t); } if(opcode2[i]==7) // SRAV { emit_sar(s,HOST_TEMPREG,t); } } } } else { // DSLLV/DSRLV/DSRAV signed char sh,sl,th,tl,shift; th=get_reg(i_regs->regmap,rt1[i]|64); tl=get_reg(i_regs->regmap,rt1[i]); sh=get_reg(i_regs->regmap,rs1[i]|64); sl=get_reg(i_regs->regmap,rs1[i]); shift=get_reg(i_regs->regmap,rs2[i]); if(tl>=0){ if(rs1[i]==0) { emit_zeroreg(tl); if(th>=0) emit_zeroreg(th); } else if(rs2[i]==0) { assert(sl>=0); if(sl!=tl) emit_mov(sl,tl); if(th>=0&&sh!=th) emit_mov(sh,th); } else { // FIXME: What if shift==tl ? assert(shift!=tl); int temp=get_reg(i_regs->regmap,-1); int real_th=th; if(th<0&&opcode2[i]!=0x14) {th=temp;} // DSLLV doesn't need a temporary register assert(sl>=0); assert(sh>=0); emit_andimm(shift,31,HOST_TEMPREG); if(opcode2[i]==0x14) // DSLLV { if(th>=0) emit_shl(sh,HOST_TEMPREG,th); emit_rsbimm(HOST_TEMPREG,32,HOST_TEMPREG); emit_orrshr(sl,HOST_TEMPREG,th); emit_andimm(shift,31,HOST_TEMPREG); emit_testimm(shift,32); emit_shl(sl,HOST_TEMPREG,tl); if(th>=0) emit_cmovne_reg(tl,th); emit_cmovne_imm(0,tl); } if(opcode2[i]==0x16) // DSRLV { assert(th>=0); emit_shr(sl,HOST_TEMPREG,tl); emit_rsbimm(HOST_TEMPREG,32,HOST_TEMPREG); emit_orrshl(sh,HOST_TEMPREG,tl); emit_andimm(shift,31,HOST_TEMPREG); emit_testimm(shift,32); emit_shr(sh,HOST_TEMPREG,th); emit_cmovne_reg(th,tl); if(real_th>=0) emit_cmovne_imm(0,th); } if(opcode2[i]==0x17) // DSRAV { assert(th>=0); emit_shr(sl,HOST_TEMPREG,tl); emit_rsbimm(HOST_TEMPREG,32,HOST_TEMPREG); if(real_th>=0) { assert(temp>=0); emit_sarimm(th,31,temp); } emit_orrshl(sh,HOST_TEMPREG,tl); emit_andimm(shift,31,HOST_TEMPREG); emit_testimm(shift,32); emit_sar(sh,HOST_TEMPREG,th); emit_cmovne_reg(th,tl); if(real_th>=0) emit_cmovne_reg(temp,th); } } } } } } #define shift_assemble shift_assemble_arm static void loadlr_assemble_arm(int i,struct regstat *i_regs) { int s,th,tl,temp,temp2,addr,map=-1,cache=-1; int offset; intptr_t jaddr=0; int memtarget,c=0; u_int hr,reglist=0; th=get_reg(i_regs->regmap,rt1[i]|64); tl=get_reg(i_regs->regmap,rt1[i]); s=get_reg(i_regs->regmap,rs1[i]); temp=get_reg(i_regs->regmap,-1); temp2=get_reg(i_regs->regmap,FTEMP); addr=get_reg(i_regs->regmap,AGEN1+(i&1)); assert(addr<0); offset=imm[i]; for(hr=0;hrregmap[hr]>=0) reglist|=1<=0) { c=(i_regs->wasconst>>s)&1; memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80800000; if(using_tlb&&((signed int)(constmap[i][s]+offset))>=(signed int)0xC0000000) memtarget=1; } if(!using_tlb) { if(!c) { #ifdef RAM_OFFSET map=get_reg(i_regs->regmap,ROREG); if(map<0) emit_loadreg(ROREG,map=HOST_TEMPREG); #endif emit_shlimm(addr,3,temp); if (opcode[i]==0x22||opcode[i]==0x26) { emit_andimm(addr,0xFFFFFFFC,temp2); // LWL/LWR }else{ emit_andimm(addr,0xFFFFFFF8,temp2); // LDL/LDR } emit_cmpimm(addr,0x800000); jaddr=(intptr_t)out; emit_jno(0); } else { if (opcode[i]==0x22||opcode[i]==0x26) { emit_movimm(((constmap[i][s]+offset)<<3)&24,temp); // LWL/LWR }else{ emit_movimm(((constmap[i][s]+offset)<<3)&56,temp); // LDL/LDR } } }else{ // using tlb int a; if(c) { a=-1; }else if (opcode[i]==0x22||opcode[i]==0x26) { a=0xFFFFFFFC; // LWL/LWR }else{ a=0xFFFFFFF8; // LDL/LDR } map=get_reg(i_regs->regmap,TLREG); cache=get_reg(i_regs->regmap,MMREG); // Get cached offset to memory_map assert(map>=0); reglist&=~(1<regmap,FTEMP,ccadj[i],reglist); if(rt1[i]) { assert(tl>=0); emit_andimm(temp,24,temp); if (opcode[i]==0x26) emit_xorimm(temp,24,temp); // LWR emit_movimm(-1,HOST_TEMPREG); if (opcode[i]==0x26) { emit_shr(temp2,temp,temp2); emit_bic_lsr(tl,HOST_TEMPREG,temp,tl); }else{ emit_shl(temp2,temp,temp2); emit_bic_lsl(tl,HOST_TEMPREG,temp,tl); } emit_or(temp2,tl,tl); } //emit_storereg(rt1[i],tl); // DEBUG } if (opcode[i]==0x1A||opcode[i]==0x1B) { // LDL/LDR int temp2h=get_reg(i_regs->regmap,FTEMP|64); if(!c||memtarget) { //if(th>=0) emit_readword_indexed((int)g_rdram-0x80000000,temp2,temp2h); //emit_readword_indexed((int)g_rdram-0x7FFFFFFC,temp2,temp2); emit_readdword_indexed_tlb(0,temp2,map,temp2h,temp2); if(jaddr) add_stub(LOADD_STUB,jaddr,(int)out,i,temp2,(intptr_t)i_regs,ccadj[i],reglist); } else inline_readstub(LOADD_STUB,i,(constmap[i][s]+offset)&0xFFFFFFF8,i_regs->regmap,FTEMP,ccadj[i],reglist); if(rt1[i]) { assert(th>=0); assert(tl>=0); emit_testimm(temp,32); emit_andimm(temp,24,temp); if (opcode[i]==0x1A) { // LDL emit_rsbimm(temp,32,HOST_TEMPREG); emit_shl(temp2h,temp,temp2h); emit_orrshr(temp2,HOST_TEMPREG,temp2h); emit_movimm(-1,HOST_TEMPREG); emit_shl(temp2,temp,temp2); emit_cmove_reg(temp2h,th); emit_biceq_lsl(tl,HOST_TEMPREG,temp,tl); emit_bicne_lsl(th,HOST_TEMPREG,temp,th); emit_orreq(temp2,tl,tl); emit_orrne(temp2,th,th); } if (opcode[i]==0x1B) { // LDR emit_xorimm(temp,24,temp); emit_rsbimm(temp,32,HOST_TEMPREG); emit_shr(temp2,temp,temp2); emit_orrshl(temp2h,HOST_TEMPREG,temp2); emit_movimm(-1,HOST_TEMPREG); emit_shr(temp2h,temp,temp2h); emit_cmovne_reg(temp2,tl); emit_bicne_lsr(th,HOST_TEMPREG,temp,th); emit_biceq_lsr(tl,HOST_TEMPREG,temp,tl); emit_orrne(temp2h,th,th); emit_orreq(temp2h,tl,tl); } } } } #define loadlr_assemble loadlr_assemble_arm static void cop0_assemble(int i,struct regstat *i_regs) { if(opcode2[i]==0) // MFC0 { if(rt1[i]) { signed char t=get_reg(i_regs->regmap,rt1[i]); char copr=(source[i]>>11)&0x1f; if(t>=0) { emit_addimm(FP,(int)&fake_pc-(int)&dynarec_local,0); emit_movimm((source[i]>>11)&0x1f,1); emit_writeword(0,(int)&PC); emit_writebyte(1,(int)&(fake_pc.f.r.nrd)); if(copr==9) { emit_readword((int)&last_count,ECX); emit_loadreg(CCREG,HOST_CCREG); // TODO: do proper reg alloc emit_add(HOST_CCREG,ECX,HOST_CCREG); emit_addimm(HOST_CCREG,CLOCK_DIVIDER*ccadj[i],HOST_CCREG); emit_writeword(HOST_CCREG,(int)&g_cp0_regs[CP0_COUNT_REG]); } emit_call((int)cached_interpreter_table.MFC0); emit_readword((int)&readmem_dword,t); } } } else if(opcode2[i]==4) // MTC0 { signed char s=get_reg(i_regs->regmap,rs1[i]); char copr=(source[i]>>11)&0x1f; assert(s>=0); emit_writeword(s,(int)&readmem_dword); wb_register(rs1[i],i_regs->regmap,i_regs->dirty,i_regs->is32); emit_addimm(FP,(int)&fake_pc-(int)&dynarec_local,0); emit_movimm((source[i]>>11)&0x1f,1); emit_writeword(0,(int)&PC); emit_writebyte(1,(int)&(fake_pc.f.r.nrd)); if(copr==9||copr==11||copr==12) { emit_readword((int)&last_count,ECX); emit_loadreg(CCREG,HOST_CCREG); // TODO: do proper reg alloc emit_add(HOST_CCREG,ECX,HOST_CCREG); emit_addimm(HOST_CCREG,CLOCK_DIVIDER*ccadj[i],HOST_CCREG); emit_writeword(HOST_CCREG,(int)&g_cp0_regs[CP0_COUNT_REG]); } // What a mess. The status register (12) can enable interrupts, // so needs a special case to handle a pending interrupt. // The interrupt must be taken immediately, because a subsequent // instruction might disable interrupts again. if(copr==12&&!is_delayslot) { emit_movimm(start+i*4+4,0); emit_movimm(0,1); emit_writeword(0,(int)&pcaddr); emit_writeword(1,(int)&pending_exception); } //else if(copr==12&&is_delayslot) emit_call((int)MTC0_R12); //else emit_call((int)cached_interpreter_table.MTC0); if(copr==9||copr==11||copr==12) { emit_readword((int)&g_cp0_regs[CP0_COUNT_REG],HOST_CCREG); emit_readword((int)&next_interupt,ECX); emit_addimm(HOST_CCREG,-CLOCK_DIVIDER*ccadj[i],HOST_CCREG); emit_sub(HOST_CCREG,ECX,HOST_CCREG); emit_writeword(ECX,(int)&last_count); emit_storereg(CCREG,HOST_CCREG); } if(copr==12) { assert(!is_delayslot); emit_readword((int)&pending_exception,14); } emit_loadreg(rs1[i],s); if(get_reg(i_regs->regmap,rs1[i]|64)>=0) emit_loadreg(rs1[i]|64,get_reg(i_regs->regmap,rs1[i]|64)); if(copr==12) { emit_test(14,14); emit_jne((int)&do_interrupt); } cop1_usable=0; } else { assert(opcode2[i]==0x10); if((source[i]&0x3f)==0x01) // TLBR emit_call((int)cached_interpreter_table.TLBR); if((source[i]&0x3f)==0x02) // TLBWI emit_call((int)TLBWI_new); if((source[i]&0x3f)==0x06) { // TLBWR // The TLB entry written by TLBWR is dependent on the count, // so update the cycle count emit_readword((int)&last_count,ECX); if(i_regs->regmap[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG); emit_add(HOST_CCREG,ECX,HOST_CCREG); emit_addimm(HOST_CCREG,CLOCK_DIVIDER*ccadj[i],HOST_CCREG); emit_writeword(HOST_CCREG,(int)&g_cp0_regs[CP0_COUNT_REG]); emit_call((int)TLBWR_new); } if((source[i]&0x3f)==0x08) // TLBP emit_call((int)cached_interpreter_table.TLBP); if((source[i]&0x3f)==0x18) // ERET { int count=ccadj[i]; if(i_regs->regmap[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG); emit_addimm(HOST_CCREG,CLOCK_DIVIDER*count,HOST_CCREG); // TODO: Should there be an extra cycle here? emit_jmp((int)jump_eret); } } } static void cop1_unusable(int i,struct regstat *i_regs) { // XXX: should just just do the exception instead if(!cop1_usable) { int jaddr=(int)out; emit_jmp(0); add_stub(FP_STUB,jaddr,(int)out,i,0,(intptr_t)i_regs,is_delayslot,0); cop1_usable=1; } } static void cop1_assemble(int i,struct regstat *i_regs) { // Check cop1 unusable if(!cop1_usable) { signed char rs=get_reg(i_regs->regmap,CSREG); assert(rs>=0); emit_testimm(rs,0x20000000); int jaddr=(int)out; emit_jeq(0); add_stub(FP_STUB,jaddr,(int)out,i,rs,(intptr_t)i_regs,is_delayslot,0); cop1_usable=1; } if (opcode2[i]==0) { // MFC1 signed char tl=get_reg(i_regs->regmap,rt1[i]); if(tl>=0) { emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],tl); emit_readword_indexed(0,tl,tl); } } else if (opcode2[i]==1) { // DMFC1 signed char tl=get_reg(i_regs->regmap,rt1[i]); signed char th=get_reg(i_regs->regmap,rt1[i]|64); if(tl>=0) { emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],tl); if(th>=0) emit_readword_indexed(4,tl,th); emit_readword_indexed(0,tl,tl); } } else if (opcode2[i]==4) { // MTC1 signed char sl=get_reg(i_regs->regmap,rs1[i]); signed char temp=get_reg(i_regs->regmap,-1); emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],temp); emit_writeword_indexed(sl,0,temp); } else if (opcode2[i]==5) { // DMTC1 signed char sl=get_reg(i_regs->regmap,rs1[i]); signed char sh=rs1[i]>0?get_reg(i_regs->regmap,rs1[i]|64):sl; signed char temp=get_reg(i_regs->regmap,-1); emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],temp); emit_writeword_indexed(sh,4,temp); emit_writeword_indexed(sl,0,temp); } else if (opcode2[i]==2) // CFC1 { signed char tl=get_reg(i_regs->regmap,rt1[i]); if(tl>=0) { u_int copr=(source[i]>>11)&0x1f; if(copr==0) emit_readword((int)&FCR0,tl); if(copr==31) emit_readword((int)&FCR31,tl); } } else if (opcode2[i]==6) // CTC1 { signed char sl=get_reg(i_regs->regmap,rs1[i]); u_int copr=(source[i]>>11)&0x1f; assert(sl>=0); if(copr==31) { emit_writeword(sl,(int)&FCR31); // Set the rounding mode //FIXME //char temp=get_reg(i_regs->regmap,-1); //emit_andimm(sl,3,temp); //emit_fldcw_indexed((int)&rounding_modes,temp); } } } static void fconv_assemble_arm(int i,struct regstat *i_regs) { signed char temp=get_reg(i_regs->regmap,-1); assert(temp>=0); // Check cop1 unusable if(!cop1_usable) { signed char rs=get_reg(i_regs->regmap,CSREG); assert(rs>=0); emit_testimm(rs,0x20000000); int jaddr=(int)out; emit_jeq(0); add_stub(FP_STUB,jaddr,(int)out,i,rs,(intptr_t)i_regs,is_delayslot,0); cop1_usable=1; } #if (defined(__VFP_FP__) && !defined(__SOFTFP__)) if(opcode2[i]==0x10&&(source[i]&0x3f)==0x0d) { // trunc_w_s emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],temp); emit_flds(temp,15); emit_ftosizs(15,15); // float->int, truncate if(((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f)) emit_readword((int)®_cop1_simple[(source[i]>>6)&0x1f],temp); emit_fsts(15,temp); return; } if(opcode2[i]==0x11&&(source[i]&0x3f)==0x0d) { // trunc_w_d emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],temp); emit_vldr(temp,7); emit_ftosizd(7,13); // double->int, truncate emit_readword((int)®_cop1_simple[(source[i]>>6)&0x1f],temp); emit_fsts(13,temp); return; } if(opcode2[i]==0x14&&(source[i]&0x3f)==0x20) { // cvt_s_w emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],temp); emit_flds(temp,13); if(((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f)) emit_readword((int)®_cop1_simple[(source[i]>>6)&0x1f],temp); emit_fsitos(13,15); emit_fsts(15,temp); return; } if(opcode2[i]==0x14&&(source[i]&0x3f)==0x21) { // cvt_d_w emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],temp); emit_flds(temp,13); emit_readword((int)®_cop1_double[(source[i]>>6)&0x1f],temp); emit_fsitod(13,7); emit_vstr(7,temp); return; } if(opcode2[i]==0x10&&(source[i]&0x3f)==0x21) { // cvt_d_s emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],temp); emit_flds(temp,13); emit_readword((int)®_cop1_double[(source[i]>>6)&0x1f],temp); emit_fcvtds(13,7); emit_vstr(7,temp); return; } if(opcode2[i]==0x11&&(source[i]&0x3f)==0x20) { // cvt_s_d emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],temp); emit_vldr(temp,7); emit_readword((int)®_cop1_simple[(source[i]>>6)&0x1f],temp); emit_fcvtsd(7,13); emit_fsts(13,temp); return; } #endif // C emulation code u_int hr,reglist=0; for(hr=0;hrregmap[hr]>=0) reglist|=1<>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_simple[(source[i]>> 6)&0x1f],ARG2_REG); emit_call((int)cvt_s_w); } if(opcode2[i]==0x14&&(source[i]&0x3f)==0x21) { emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG2_REG); emit_call((int)cvt_d_w); } if(opcode2[i]==0x15&&(source[i]&0x3f)==0x20) { emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_simple[(source[i]>> 6)&0x1f],ARG2_REG); emit_call((int)cvt_s_l); } if(opcode2[i]==0x15&&(source[i]&0x3f)==0x21) { emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG2_REG); emit_call((int)cvt_d_l); } if(opcode2[i]==0x10&&(source[i]&0x3f)==0x21) { emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG2_REG); emit_call((int)cvt_d_s); } if(opcode2[i]==0x10&&(source[i]&0x3f)==0x24) { emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_simple[(source[i]>> 6)&0x1f],ARG2_REG); emit_call((int)cvt_w_s); } if(opcode2[i]==0x10&&(source[i]&0x3f)==0x25) { emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG2_REG); emit_call((int)cvt_l_s); } if(opcode2[i]==0x11&&(source[i]&0x3f)==0x20) { emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_simple[(source[i]>> 6)&0x1f],ARG2_REG); emit_call((int)cvt_s_d); } if(opcode2[i]==0x11&&(source[i]&0x3f)==0x24) { emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_simple[(source[i]>> 6)&0x1f],ARG2_REG); emit_call((int)cvt_w_d); } if(opcode2[i]==0x11&&(source[i]&0x3f)==0x25) { emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG2_REG); emit_call((int)cvt_l_d); } if(opcode2[i]==0x10&&(source[i]&0x3f)==0x08) { emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG2_REG); emit_call((int)round_l_s); } if(opcode2[i]==0x10&&(source[i]&0x3f)==0x09) { emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG2_REG); emit_call((int)trunc_l_s); } if(opcode2[i]==0x10&&(source[i]&0x3f)==0x0a) { emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG2_REG); emit_call((int)ceil_l_s); } if(opcode2[i]==0x10&&(source[i]&0x3f)==0x0b) { emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG2_REG); emit_call((int)floor_l_s); } if(opcode2[i]==0x10&&(source[i]&0x3f)==0x0c) { emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_simple[(source[i]>> 6)&0x1f],ARG2_REG); emit_call((int)round_w_s); } if(opcode2[i]==0x10&&(source[i]&0x3f)==0x0d) { emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_simple[(source[i]>> 6)&0x1f],ARG2_REG); emit_call((int)trunc_w_s); } if(opcode2[i]==0x10&&(source[i]&0x3f)==0x0e) { emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_simple[(source[i]>> 6)&0x1f],ARG2_REG); emit_call((int)ceil_w_s); } if(opcode2[i]==0x10&&(source[i]&0x3f)==0x0f) { emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_simple[(source[i]>> 6)&0x1f],ARG2_REG); emit_call((int)floor_w_s); } if(opcode2[i]==0x11&&(source[i]&0x3f)==0x08) { emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG2_REG); emit_call((int)round_l_d); } if(opcode2[i]==0x11&&(source[i]&0x3f)==0x09) { emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG2_REG); emit_call((int)trunc_l_d); } if(opcode2[i]==0x11&&(source[i]&0x3f)==0x0a) { emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG2_REG); emit_call((int)ceil_l_d); } if(opcode2[i]==0x11&&(source[i]&0x3f)==0x0b) { emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG2_REG); emit_call((int)floor_l_d); } if(opcode2[i]==0x11&&(source[i]&0x3f)==0x0c) { emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_simple[(source[i]>> 6)&0x1f],ARG2_REG); emit_call((int)round_w_d); } if(opcode2[i]==0x11&&(source[i]&0x3f)==0x0d) { emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_simple[(source[i]>> 6)&0x1f],ARG2_REG); emit_call((int)trunc_w_d); } if(opcode2[i]==0x11&&(source[i]&0x3f)==0x0e) { emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_simple[(source[i]>> 6)&0x1f],ARG2_REG); emit_call((int)ceil_w_d); } if(opcode2[i]==0x11&&(source[i]&0x3f)==0x0f) { emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_simple[(source[i]>> 6)&0x1f],ARG2_REG); emit_call((int)floor_w_d); } restore_regs(reglist); } #define fconv_assemble fconv_assemble_arm static void fcomp_assemble(int i,struct regstat *i_regs) { #ifndef DISABLE_COP1 signed char fs=get_reg(i_regs->regmap,FSREG); signed char temp=get_reg(i_regs->regmap,-1); assert(temp>=0); // Check cop1 unusable if(!cop1_usable) { signed char cs=get_reg(i_regs->regmap,CSREG); assert(cs>=0); emit_testimm(cs,0x20000000); int jaddr=(int)out; emit_jeq(0); add_stub(FP_STUB,jaddr,(int)out,i,cs,(intptr_t)i_regs,is_delayslot,0); cop1_usable=1; } if((source[i]&0x3f)==0x30) { emit_andimm(fs,~0x800000,fs); return; } if((source[i]&0x3e)==0x38) { // sf/ngle - these should throw exceptions for NaNs emit_andimm(fs,~0x800000,fs); return; } #if (defined(__VFP_FP__) && !defined(__SOFTFP__)) if(opcode2[i]==0x10) { emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],temp); emit_readword((int)®_cop1_simple[(source[i]>>16)&0x1f],HOST_TEMPREG); emit_orimm(fs,0x800000,fs); emit_flds(temp,14); emit_flds(HOST_TEMPREG,15); emit_fcmps(14,15); emit_fmstat(); if((source[i]&0x3f)==0x31) emit_bicvc_imm(fs,0x800000,fs); // c_un_s if((source[i]&0x3f)==0x32) emit_bicne_imm(fs,0x800000,fs); // c_eq_s if((source[i]&0x3f)==0x33) {emit_bicne_imm(fs,0x800000,fs);emit_orrvs_imm(fs,0x800000,fs);} // c_ueq_s if((source[i]&0x3f)==0x34) emit_biccs_imm(fs,0x800000,fs); // c_olt_s if((source[i]&0x3f)==0x35) {emit_biccs_imm(fs,0x800000,fs);emit_orrvs_imm(fs,0x800000,fs);} // c_ult_s if((source[i]&0x3f)==0x36) emit_bichi_imm(fs,0x800000,fs); // c_ole_s if((source[i]&0x3f)==0x37) {emit_bichi_imm(fs,0x800000,fs);emit_orrvs_imm(fs,0x800000,fs);} // c_ule_s if((source[i]&0x3f)==0x3a) emit_bicne_imm(fs,0x800000,fs); // c_seq_s if((source[i]&0x3f)==0x3b) emit_bicne_imm(fs,0x800000,fs); // c_ngl_s if((source[i]&0x3f)==0x3c) emit_biccs_imm(fs,0x800000,fs); // c_lt_s if((source[i]&0x3f)==0x3d) emit_biccs_imm(fs,0x800000,fs); // c_nge_s if((source[i]&0x3f)==0x3e) emit_bichi_imm(fs,0x800000,fs); // c_le_s if((source[i]&0x3f)==0x3f) emit_bichi_imm(fs,0x800000,fs); // c_ngt_s emit_storereg(FSREG,fs); return; } if(opcode2[i]==0x11) { emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],temp); emit_readword((int)®_cop1_double[(source[i]>>16)&0x1f],HOST_TEMPREG); emit_orimm(fs,0x800000,fs); emit_vldr(temp,6); emit_vldr(HOST_TEMPREG,7); emit_fcmpd(6,7); emit_fmstat(); if((source[i]&0x3f)==0x31) emit_bicvc_imm(fs,0x800000,fs); // c_un_d if((source[i]&0x3f)==0x32) emit_bicne_imm(fs,0x800000,fs); // c_eq_d if((source[i]&0x3f)==0x33) {emit_bicne_imm(fs,0x800000,fs);emit_orrvs_imm(fs,0x800000,fs);} // c_ueq_d if((source[i]&0x3f)==0x34) emit_biccs_imm(fs,0x800000,fs); // c_olt_d if((source[i]&0x3f)==0x35) {emit_biccs_imm(fs,0x800000,fs);emit_orrvs_imm(fs,0x800000,fs);} // c_ult_d if((source[i]&0x3f)==0x36) emit_bichi_imm(fs,0x800000,fs); // c_ole_d if((source[i]&0x3f)==0x37) {emit_bichi_imm(fs,0x800000,fs);emit_orrvs_imm(fs,0x800000,fs);} // c_ule_d if((source[i]&0x3f)==0x3a) emit_bicne_imm(fs,0x800000,fs); // c_seq_d if((source[i]&0x3f)==0x3b) emit_bicne_imm(fs,0x800000,fs); // c_ngl_d if((source[i]&0x3f)==0x3c) emit_biccs_imm(fs,0x800000,fs); // c_lt_d if((source[i]&0x3f)==0x3d) emit_biccs_imm(fs,0x800000,fs); // c_nge_d if((source[i]&0x3f)==0x3e) emit_bichi_imm(fs,0x800000,fs); // c_le_d if((source[i]&0x3f)==0x3f) emit_bichi_imm(fs,0x800000,fs); // c_ngt_d emit_storereg(FSREG,fs); return; } #endif // C only u_int hr,reglist=0; for(hr=0;hrregmap[hr]>=0) reglist|=1<>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_simple[(source[i]>>16)&0x1f],ARG2_REG); if((source[i]&0x3f)==0x30) emit_call((int)c_f_s); if((source[i]&0x3f)==0x31) emit_call((int)c_un_s); if((source[i]&0x3f)==0x32) emit_call((int)c_eq_s); if((source[i]&0x3f)==0x33) emit_call((int)c_ueq_s); if((source[i]&0x3f)==0x34) emit_call((int)c_olt_s); if((source[i]&0x3f)==0x35) emit_call((int)c_ult_s); if((source[i]&0x3f)==0x36) emit_call((int)c_ole_s); if((source[i]&0x3f)==0x37) emit_call((int)c_ule_s); if((source[i]&0x3f)==0x38) emit_call((int)c_sf_s); if((source[i]&0x3f)==0x39) emit_call((int)c_ngle_s); if((source[i]&0x3f)==0x3a) emit_call((int)c_seq_s); if((source[i]&0x3f)==0x3b) emit_call((int)c_ngl_s); if((source[i]&0x3f)==0x3c) emit_call((int)c_lt_s); if((source[i]&0x3f)==0x3d) emit_call((int)c_nge_s); if((source[i]&0x3f)==0x3e) emit_call((int)c_le_s); if((source[i]&0x3f)==0x3f) emit_call((int)c_ngt_s); } if(opcode2[i]==0x11) { emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],ARG1_REG); emit_readword((int)®_cop1_double[(source[i]>>16)&0x1f],ARG2_REG); if((source[i]&0x3f)==0x30) emit_call((int)c_f_d); if((source[i]&0x3f)==0x31) emit_call((int)c_un_d); if((source[i]&0x3f)==0x32) emit_call((int)c_eq_d); if((source[i]&0x3f)==0x33) emit_call((int)c_ueq_d); if((source[i]&0x3f)==0x34) emit_call((int)c_olt_d); if((source[i]&0x3f)==0x35) emit_call((int)c_ult_d); if((source[i]&0x3f)==0x36) emit_call((int)c_ole_d); if((source[i]&0x3f)==0x37) emit_call((int)c_ule_d); if((source[i]&0x3f)==0x38) emit_call((int)c_sf_d); if((source[i]&0x3f)==0x39) emit_call((int)c_ngle_d); if((source[i]&0x3f)==0x3a) emit_call((int)c_seq_d); if((source[i]&0x3f)==0x3b) emit_call((int)c_ngl_d); if((source[i]&0x3f)==0x3c) emit_call((int)c_lt_d); if((source[i]&0x3f)==0x3d) emit_call((int)c_nge_d); if((source[i]&0x3f)==0x3e) emit_call((int)c_le_d); if((source[i]&0x3f)==0x3f) emit_call((int)c_ngt_d); } restore_regs(reglist); emit_loadreg(FSREG,fs); #else cop1_unusable(i, i_regs); #endif } static void float_assemble(int i,struct regstat *i_regs) { signed char temp=get_reg(i_regs->regmap,-1); assert(temp>=0); // Check cop1 unusable if(!cop1_usable) { signed char cs=get_reg(i_regs->regmap,CSREG); assert(cs>=0); emit_testimm(cs,0x20000000); int jaddr=(int)out; emit_jeq(0); add_stub(FP_STUB,jaddr,(int)out,i,cs,(intptr_t)i_regs,is_delayslot,0); cop1_usable=1; } #if (defined(__VFP_FP__) && !defined(__SOFTFP__)) if((source[i]&0x3f)==6) // mov { if(((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f)) { if(opcode2[i]==0x10) { emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],temp); emit_readword((int)®_cop1_simple[(source[i]>>6)&0x1f],HOST_TEMPREG); emit_readword_indexed(0,temp,temp); emit_writeword_indexed(temp,0,HOST_TEMPREG); } if(opcode2[i]==0x11) { emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],temp); emit_readword((int)®_cop1_double[(source[i]>>6)&0x1f],HOST_TEMPREG); emit_vldr(temp,7); emit_vstr(7,HOST_TEMPREG); } } return; } if((source[i]&0x3f)>3) { if(opcode2[i]==0x10) { emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],temp); emit_flds(temp,15); if(((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f)) { emit_readword((int)®_cop1_simple[(source[i]>>6)&0x1f],temp); } if((source[i]&0x3f)==4) // sqrt emit_fsqrts(15,15); if((source[i]&0x3f)==5) // abs emit_fabss(15,15); if((source[i]&0x3f)==7) // neg emit_fnegs(15,15); emit_fsts(15,temp); } if(opcode2[i]==0x11) { emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],temp); emit_vldr(temp,7); if(((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f)) { emit_readword((int)®_cop1_double[(source[i]>>6)&0x1f],temp); } if((source[i]&0x3f)==4) // sqrt emit_fsqrtd(7,7); if((source[i]&0x3f)==5) // abs emit_fabsd(7,7); if((source[i]&0x3f)==7) // neg emit_fnegd(7,7); emit_vstr(7,temp); } return; } if((source[i]&0x3f)<4) { if(opcode2[i]==0x10) { emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],temp); } if(opcode2[i]==0x11) { emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],temp); } if(((source[i]>>11)&0x1f)!=((source[i]>>16)&0x1f)) { if(opcode2[i]==0x10) { emit_readword((int)®_cop1_simple[(source[i]>>16)&0x1f],HOST_TEMPREG); emit_flds(temp,15); emit_flds(HOST_TEMPREG,13); if(((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f)) { if(((source[i]>>16)&0x1f)!=((source[i]>>6)&0x1f)) { emit_readword((int)®_cop1_simple[(source[i]>>6)&0x1f],temp); } } if((source[i]&0x3f)==0) emit_fadds(15,13,15); if((source[i]&0x3f)==1) emit_fsubs(15,13,15); if((source[i]&0x3f)==2) emit_fmuls(15,13,15); if((source[i]&0x3f)==3) emit_fdivs(15,13,15); if(((source[i]>>16)&0x1f)==((source[i]>>6)&0x1f)) { emit_fsts(15,HOST_TEMPREG); }else{ emit_fsts(15,temp); } } else if(opcode2[i]==0x11) { emit_readword((int)®_cop1_double[(source[i]>>16)&0x1f],HOST_TEMPREG); emit_vldr(temp,7); emit_vldr(HOST_TEMPREG,6); if(((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f)) { if(((source[i]>>16)&0x1f)!=((source[i]>>6)&0x1f)) { emit_readword((int)®_cop1_double[(source[i]>>6)&0x1f],temp); } } if((source[i]&0x3f)==0) emit_faddd(7,6,7); if((source[i]&0x3f)==1) emit_fsubd(7,6,7); if((source[i]&0x3f)==2) emit_fmuld(7,6,7); if((source[i]&0x3f)==3) emit_fdivd(7,6,7); if(((source[i]>>16)&0x1f)==((source[i]>>6)&0x1f)) { emit_vstr(7,HOST_TEMPREG); }else{ emit_vstr(7,temp); } } } else { if(opcode2[i]==0x10) { emit_flds(temp,15); if(((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f)) { emit_readword((int)®_cop1_simple[(source[i]>>6)&0x1f],temp); } if((source[i]&0x3f)==0) emit_fadds(15,15,15); if((source[i]&0x3f)==1) emit_fsubs(15,15,15); if((source[i]&0x3f)==2) emit_fmuls(15,15,15); if((source[i]&0x3f)==3) emit_fdivs(15,15,15); emit_fsts(15,temp); } else if(opcode2[i]==0x11) { emit_vldr(temp,7); if(((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f)) { emit_readword((int)®_cop1_double[(source[i]>>6)&0x1f],temp); } if((source[i]&0x3f)==0) emit_faddd(7,7,7); if((source[i]&0x3f)==1) emit_fsubd(7,7,7); if((source[i]&0x3f)==2) emit_fmuld(7,7,7); if((source[i]&0x3f)==3) emit_fdivd(7,7,7); emit_vstr(7,temp); } } return; } #endif u_int hr,reglist=0; for(hr=0;hrregmap[hr]>=0) reglist|=1<>11)&0x1f],ARG1_REG); if((source[i]&0x3f)<4) { emit_readword((int)®_cop1_simple[(source[i]>>16)&0x1f],ARG2_REG); emit_readword((int)®_cop1_simple[(source[i]>> 6)&0x1f],ARG3_REG); }else{ emit_readword((int)®_cop1_simple[(source[i]>> 6)&0x1f],ARG2_REG); } switch(source[i]&0x3f) { case 0x00: emit_call((int)add_s);break; case 0x01: emit_call((int)sub_s);break; case 0x02: emit_call((int)mul_s);break; case 0x03: emit_call((int)div_s);break; case 0x04: emit_call((int)sqrt_s);break; case 0x05: emit_call((int)abs_s);break; case 0x06: emit_call((int)mov_s);break; case 0x07: emit_call((int)neg_s);break; } restore_regs(reglist); } if(opcode2[i]==0x11) { // Double precision save_regs(reglist); emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],ARG1_REG); if((source[i]&0x3f)<4) { emit_readword((int)®_cop1_double[(source[i]>>16)&0x1f],ARG2_REG); emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG3_REG); }else{ emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG2_REG); } switch(source[i]&0x3f) { case 0x00: emit_call((int)add_d);break; case 0x01: emit_call((int)sub_d);break; case 0x02: emit_call((int)mul_d);break; case 0x03: emit_call((int)div_d);break; case 0x04: emit_call((int)sqrt_d);break; case 0x05: emit_call((int)abs_d);break; case 0x06: emit_call((int)mov_d);break; case 0x07: emit_call((int)neg_d);break; } restore_regs(reglist); } } static void multdiv_assemble_arm(int i,struct regstat *i_regs) { // case 0x18: MULT // case 0x19: MULTU // case 0x1A: DIV // case 0x1B: DIVU // case 0x1C: DMULT // case 0x1D: DMULTU // case 0x1E: DDIV // case 0x1F: DDIVU if(rs1[i]&&rs2[i]) { if((opcode2[i]&4)==0) // 32-bit { if(opcode2[i]==0x18) // MULT { signed char m1=get_reg(i_regs->regmap,rs1[i]); signed char m2=get_reg(i_regs->regmap,rs2[i]); signed char hi=get_reg(i_regs->regmap,HIREG); signed char lo=get_reg(i_regs->regmap,LOREG); assert(m1>=0); assert(m2>=0); assert(hi>=0); assert(lo>=0); emit_smull(m1,m2,hi,lo); } if(opcode2[i]==0x19) // MULTU { signed char m1=get_reg(i_regs->regmap,rs1[i]); signed char m2=get_reg(i_regs->regmap,rs2[i]); signed char hi=get_reg(i_regs->regmap,HIREG); signed char lo=get_reg(i_regs->regmap,LOREG); assert(m1>=0); assert(m2>=0); assert(hi>=0); assert(lo>=0); emit_umull(m1,m2,hi,lo); } if(opcode2[i]==0x1A) // DIV { signed char d1=get_reg(i_regs->regmap,rs1[i]); signed char d2=get_reg(i_regs->regmap,rs2[i]); assert(d1>=0); assert(d2>=0); signed char quotient=get_reg(i_regs->regmap,LOREG); signed char remainder=get_reg(i_regs->regmap,HIREG); assert(quotient>=0); assert(remainder>=0); emit_movs(d1,remainder); emit_negmi(remainder,remainder); emit_movs(d2,HOST_TEMPREG); emit_jeq((int)out+52); // Division by zero emit_negmi(HOST_TEMPREG,HOST_TEMPREG); emit_clz(HOST_TEMPREG,quotient); emit_shl(HOST_TEMPREG,quotient,HOST_TEMPREG); emit_orimm(quotient,1<<31,quotient); emit_shr(quotient,quotient,quotient); emit_cmp(remainder,HOST_TEMPREG); emit_subcs(remainder,HOST_TEMPREG,remainder); emit_adcs(quotient,quotient,quotient); emit_shrimm(HOST_TEMPREG,1,HOST_TEMPREG); emit_jcc((int)out-16); // -4 emit_teq(d1,d2); emit_negmi(quotient,quotient); emit_test(d1,d1); emit_negmi(remainder,remainder); } if(opcode2[i]==0x1B) // DIVU { signed char d1=get_reg(i_regs->regmap,rs1[i]); // dividend signed char d2=get_reg(i_regs->regmap,rs2[i]); // divisor assert(d1>=0); assert(d2>=0); signed char quotient=get_reg(i_regs->regmap,LOREG); signed char remainder=get_reg(i_regs->regmap,HIREG); assert(quotient>=0); assert(remainder>=0); emit_test(d2,d2); emit_jeq((int)out+44); // Division by zero emit_clz(d2,HOST_TEMPREG); emit_movimm(1<<31,quotient); emit_shl(d2,HOST_TEMPREG,d2); emit_mov(d1,remainder); emit_shr(quotient,HOST_TEMPREG,quotient); emit_cmp(remainder,d2); emit_subcs(remainder,d2,remainder); emit_adcs(quotient,quotient,quotient); emit_shrcc_imm(d2,1,d2); emit_jcc((int)out-16); // -4 } } else // 64-bit { if(opcode2[i]==0x1C) // DMULT { signed char m1h=get_reg(i_regs->regmap,rs1[i]|64); signed char m1l=get_reg(i_regs->regmap,rs1[i]); signed char m2h=get_reg(i_regs->regmap,rs2[i]|64); signed char m2l=get_reg(i_regs->regmap,rs2[i]); signed char rh=get_reg(i_regs->regmap,HIREG|64); signed char rl=get_reg(i_regs->regmap,HIREG); signed char temp=get_reg(i_regs->regmap,-1); assert(m1h>=0); assert(m2h>=0); assert(m1l>=0); assert(m2l>=0); assert(rh>=0); assert(rl>=0); assert(temp>=0); emit_umull(m1l,m2l,rh,rl); emit_storereg(LOREG,rl); emit_mov(rh,rl); emit_movimm(0, rh); emit_smlal(m1l,m2h,rh,rl); emit_mov(rh,temp); emit_testimm(m1l,0x80000000); emit_addne(temp,m2h,temp); emit_movimm(0, rh); emit_smlal(m1h,m2l,rh,rl); emit_testimm(m2l,0x80000000); emit_addne(rh,m1h,rh); emit_storereg(LOREG|64,rl); emit_sarimm(temp,31,rl); emit_adds(temp,rh,temp); emit_addsarimm(rl,rh,rh,31); emit_mov(temp,rl); emit_smlal(m1h,m2h,rh,rl); } if(opcode2[i]==0x1D) // DMULTU { signed char m1h=get_reg(i_regs->regmap,rs1[i]|64); signed char m1l=get_reg(i_regs->regmap,rs1[i]); signed char m2h=get_reg(i_regs->regmap,rs2[i]|64); signed char m2l=get_reg(i_regs->regmap,rs2[i]); assert(m1h>=0); assert(m2h>=0); assert(m1l>=0); assert(m2l>=0); signed char rh=get_reg(i_regs->regmap,HIREG|64); signed char rl=get_reg(i_regs->regmap,HIREG); signed char temp=get_reg(i_regs->regmap,-1); assert(rh>=0); assert(rl>=0); assert(temp>=0); emit_umull(m1l,m2l,rh,rl); emit_storereg(LOREG,rl); emit_mov(rh,rl); emit_movimm(0, rh); emit_umlal(m1l,m2h,rh,rl); emit_mov(rh,temp); emit_movimm(0, rh); emit_umlal(m1h,m2l,rh,rl); emit_storereg(LOREG|64,rl); emit_movimm(0, rl); emit_adds(temp,rh,temp); emit_adcimm(rl,0,rh); emit_mov(temp,rl); emit_umlal(m1h,m2h,rh,rl); } if(opcode2[i]==0x1E) // DDIV { signed char d1h=get_reg(i_regs->regmap,rs1[i]|64); signed char d1l=get_reg(i_regs->regmap,rs1[i]); signed char d2h=get_reg(i_regs->regmap,rs2[i]|64); signed char d2l=get_reg(i_regs->regmap,rs2[i]); assert(d1h>=0); assert(d2h>=0); assert(d1l>=0); assert(d2l>=0); save_regs(CALLER_SAVE_REGS); if(d1l!=0) emit_mov(d1l,0); if(d1h==0) emit_readword((int)&dynarec_local,1); else if(d1h>1) emit_mov(d1h,1); if(d2l<2) emit_readword((int)&dynarec_local+d2l*4,2); else if(d2l>2) emit_mov(d2l,2); if(d2h<3) emit_readword((int)&dynarec_local+d2h*4,3); else if(d2h>3) emit_mov(d2h,3); emit_call((int)&div64); restore_regs(CALLER_SAVE_REGS); signed char hih=get_reg(i_regs->regmap,HIREG|64); signed char hil=get_reg(i_regs->regmap,HIREG); signed char loh=get_reg(i_regs->regmap,LOREG|64); signed char lol=get_reg(i_regs->regmap,LOREG); if(hih>=0) emit_loadreg(HIREG|64,hih); if(hil>=0) emit_loadreg(HIREG,hil); if(loh>=0) emit_loadreg(LOREG|64,loh); if(lol>=0) emit_loadreg(LOREG,lol); } if(opcode2[i]==0x1F) // DDIVU { #if 0 u_int hr,reglist=0; for(hr=0;hrregmap[hr]>=0 && (i_regs->regmap[hr]&62)!=HIREG) reglist|=1<regmap,rs1[i]|64); signed char d1l=get_reg(i_regs->regmap,rs1[i]); signed char d2h=get_reg(i_regs->regmap,rs2[i]|64); signed char d2l=get_reg(i_regs->regmap,rs2[i]); assert(d1h>=0); assert(d2h>=0); assert(d1l>=0); assert(d2l>=0); save_regs(CALLER_SAVE_REGS); if(d1l!=0) emit_mov(d1l,0); if(d1h==0) emit_readword((int)&dynarec_local,1); else if(d1h>1) emit_mov(d1h,1); if(d2l<2) emit_readword((int)&dynarec_local+d2l*4,2); else if(d2l>2) emit_mov(d2l,2); if(d2h<3) emit_readword((int)&dynarec_local+d2h*4,3); else if(d2h>3) emit_mov(d2h,3); emit_call((int)&divu64); restore_regs(CALLER_SAVE_REGS); signed char hih=get_reg(i_regs->regmap,HIREG|64); signed char hil=get_reg(i_regs->regmap,HIREG); signed char loh=get_reg(i_regs->regmap,LOREG|64); signed char lol=get_reg(i_regs->regmap,LOREG); if(hih>=0) emit_loadreg(HIREG|64,hih); if(hil>=0) emit_loadreg(HIREG,hil); if(loh>=0) emit_loadreg(LOREG|64,loh); if(lol>=0) emit_loadreg(LOREG,lol); } } } else { /* Multiply by zero is zero. * MIPS does not have a divide by zero exception. * The result is undefined, we return zero. */ signed char hr=get_reg(i_regs->regmap,HIREG); signed char lr=get_reg(i_regs->regmap,LOREG); if(hr>=0) emit_zeroreg(hr); if(lr>=0) emit_zeroreg(lr); } } #define multdiv_assemble multdiv_assemble_arm static void do_preload_rhash(int r) { /* Don't need this for ARM. On x86, this puts the value 0xf8 into the * register. On ARM the hash can be done with a single instruction (below) */ } static void do_preload_rhtbl(int ht) { emit_addimm(FP,(int)&mini_ht-(int)&dynarec_local,ht); } static void do_rhash(int rs,int rh) { emit_andimm(rs,0xf8,rh); } static void do_miniht_load(int ht,int rh) { assem_debug("ldr %s,[%s,%s]!",regname[rh],regname[ht],regname[rh]); output_w32(0xe7b00000|rd_rn_rm(rh,ht,rh)); } static void do_miniht_jump(int rs,int rh,int ht) { emit_cmp(rh,rs); emit_ldreq_indexed(ht,4,15); #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK emit_mov(rs,7); emit_jmp(jump_vaddr_reg[7]); #else emit_jmp(jump_vaddr_reg[rs]); #endif } static void do_miniht_insert(u_int return_address,int rt,int temp) { #ifdef ARMv5_ONLY emit_movimm(return_address,rt); // PC into link register add_to_linker((int)out,return_address,1); emit_pcreladdr(temp); emit_writeword(rt,(int)&mini_ht[(return_address&0xFF)>>3][0]); emit_writeword(temp,(int)&mini_ht[(return_address&0xFF)>>3][1]); #else emit_movw(return_address&0x0000FFFF,rt); add_to_linker((int)out,return_address,1); emit_pcreladdr(temp); emit_writeword(temp,(int)&mini_ht[(return_address&0xFF)>>3][1]); emit_movt(return_address&0xFFFF0000,rt); emit_writeword(rt,(int)&mini_ht[(return_address&0xFF)>>3][0]); #endif } // Sign-extend to 64 bits and write out upper half of a register // This is useful where we have a 32-bit value in a register, and want to // keep it in a 32-bit register, but can't guarantee that it won't be read // as a 64-bit value later. static void wb_sx(signed char pre[],signed char entry[],uint64_t dirty, uint64_t is32_pre,uint64_t is32,uint64_t u,uint64_t uu) { if(is32_pre==is32) return; int hr,reg; for(hr=0;hr=0) { if((dirty>>hr)&1) { if( ((is32_pre&~is32&~uu)>>reg)&1 ) { emit_sarimm(hr,31,HOST_TEMPREG); emit_storereg(reg|64,HOST_TEMPREG); } } } //} } } } static void wb_valid(signed char pre[],signed char entry[],u_int dirty_pre,u_int dirty,uint64_t is32_pre,uint64_t u,uint64_t uu) { //if(dirty_pre==dirty) return; int hr,reg,new_hr; for(hr=0;hr>(reg&63))&1) { if(reg>0) { if(((dirty_pre&~dirty)>>hr)&1) { if(reg>0&®<36) { emit_storereg(reg,hr); if( ((is32_pre&~uu)>>reg)&1 ) { emit_sarimm(hr,31,HOST_TEMPREG); emit_storereg(reg|64,HOST_TEMPREG); } } else if(reg>=64) { emit_storereg(reg,hr); } } } } } } } /* using strd could possibly help but you'd have to allocate registers in pairs */ #if 0 static void wb_invalidate_arm(signed char pre[],signed char entry[],uint64_t dirty,uint64_t is32,uint64_t u,uint64_t uu) { int hr; int wrote=-1; for(hr=HOST_REGS-1;hr>=0;hr--) { if(hr!=EXCLUDE_REG) { if(pre[hr]!=entry[hr]) { if(pre[hr]>=0) { if((dirty>>hr)&1) { if(get_reg(entry,pre[hr])<0) { if(pre[hr]<64) { if(!((u>>pre[hr])&1)) { if(hr<10&&(~hr&1)&&(pre[hr+1]<0||wrote==hr+1)) { if( ((is32>>pre[hr])&1) && !((uu>>pre[hr])&1) ) { emit_sarimm(hr,31,hr+1); emit_strdreg(pre[hr],hr); } else emit_storereg(pre[hr],hr); }else{ emit_storereg(pre[hr],hr); if( ((is32>>pre[hr])&1) && !((uu>>pre[hr])&1) ) { emit_sarimm(hr,31,hr); emit_storereg(pre[hr]|64,hr); } } } }else{ if(!((uu>>(pre[hr]&63))&1) && !((is32>>(pre[hr]&63))&1)) { emit_storereg(pre[hr],hr); } } wrote=hr; } } } } } } for(hr=0;hr=0) { int nr; if((nr=get_reg(entry,pre[hr]))>=0) { emit_mov(hr,nr); } } } } } } #define wb_invalidate wb_invalidate_arm #endif /* Clearing the cache is rather slow on ARM Linux, so mark the areas * that need to be cleared, and then only clear these areas once. */ static void do_clear_cache() { int i,j; for (i=0;i<(1<<(TARGET_SIZE_2-17));i++) { u_int bitmap=needs_clear_cache[i]; if(bitmap) { u_int start,end; for(j=0;j<32;j++) { if(bitmap&(1<>2; #endif // Trampolines for jumps >32M int *ptr,*ptr2; ptr=(int *)jump_table_symbols; ptr2=(int *)((void *)BASE_ADDR+(1<=-33554432&&offset<33554432) { *ptr2=0xea000000|((offset>>2)&0xffffff); // direct branch }else{ *ptr2=0xe51ff004; // ldr pc,[pc,#-4] } ptr2++; *ptr2=*ptr; ptr++; ptr2++; } // Jumping thru the trampolines created above slows things down by about 1%. // If part of the cache is beyond the 32M limit, avoid using this area // initially. It will be used later if the cache gets full. if((u_int)dyna_linker-33554432>(u_int)BASE_ADDR) { if((u_int)dyna_linker-33554432<(u_int)BASE_ADDR+(1<<(TARGET_SIZE_2-1))) { out=(u_char *)(((u_int)dyna_linker-33554432)&~4095); expirep=((((int)out-BASE_ADDR)>>(TARGET_SIZE_2-16))+16384)&65535; } } } mupen64plus-video-gliden64/src/F3DEX2.h000664 001750 001750 00000005012 12655644434 020470 0ustar00sergiosergio000000 000000 #ifndef F3DEX2_H #define F3DEX2_H #define F3DEX2_MTX_STACKSIZE 18 #define F3DEX2_MTX_MODELVIEW 0x00 #define F3DEX2_MTX_PROJECTION 0x04 #define F3DEX2_MTX_MUL 0x00 #define F3DEX2_MTX_LOAD 0x02 #define F3DEX2_MTX_NOPUSH 0x00 #define F3DEX2_MTX_PUSH 0x01 #define F3DEX2_TEXTURE_ENABLE 0x00000000 #define F3DEX2_SHADING_SMOOTH 0x00200000 #define F3DEX2_CULL_FRONT 0x00000200 #define F3DEX2_CULL_BACK 0x00000400 #define F3DEX2_CULL_BOTH 0x00000600 #define F3DEX2_CLIPPING 0x00800000 #define F3DEX2_MV_VIEWPORT 8 #define F3DEX2_MWO_aLIGHT_1 0x00 #define F3DEX2_MWO_bLIGHT_1 0x04 #define F3DEX2_MWO_aLIGHT_2 0x18 #define F3DEX2_MWO_bLIGHT_2 0x1c #define F3DEX2_MWO_aLIGHT_3 0x30 #define F3DEX2_MWO_bLIGHT_3 0x34 #define F3DEX2_MWO_aLIGHT_4 0x48 #define F3DEX2_MWO_bLIGHT_4 0x4c #define F3DEX2_MWO_aLIGHT_5 0x60 #define F3DEX2_MWO_bLIGHT_5 0x64 #define F3DEX2_MWO_aLIGHT_6 0x78 #define F3DEX2_MWO_bLIGHT_6 0x7c #define F3DEX2_MWO_aLIGHT_7 0x90 #define F3DEX2_MWO_bLIGHT_7 0x94 #define F3DEX2_MWO_aLIGHT_8 0xa8 #define F3DEX2_MWO_bLIGHT_8 0xac #define F3DEX2_RDPHALF_2 0xF1 #define F3DEX2_SETOTHERMODE_H 0xE3 #define F3DEX2_SETOTHERMODE_L 0xE2 #define F3DEX2_RDPHALF_1 0xE1 #define F3DEX2_SPNOOP 0xE0 #define F3DEX2_ENDDL 0xDF #define F3DEX2_DL 0xDE #define F3DEX2_LOAD_UCODE 0xDD #define F3DEX2_MOVEMEM 0xDC #define F3DEX2_MOVEWORD 0xDB #define F3DEX2_MTX 0xDA #define F3DEX2_GEOMETRYMODE 0xD9 #define F3DEX2_POPMTX 0xD8 #define F3DEX2_TEXTURE 0xD7 #define F3DEX2_DMA_IO 0xD6 #define F3DEX2_SPECIAL_1 0xD5 #define F3DEX2_SPECIAL_2 0xD4 #define F3DEX2_SPECIAL_3 0xD3 #define F3DEX2_VTX 0x01 #define F3DEX2_MODIFYVTX 0x02 #define F3DEX2_CULLDL 0x03 #define F3DEX2_BRANCH_Z 0x04 #define F3DEX2_TRI1 0x05 #define F3DEX2_TRI2 0x06 #define F3DEX2_QUAD 0x07 #define F3DEX2_LINE3D 0x08 void F3DEX2_Mtx( u32 w0, u32 w1 ); void F3DEX2_MoveMem( u32 w0, u32 w1 ); void F3DEX2_Vtx( u32 w0, u32 w1 ); void F3DEX2_Reserved1( u32 w0, u32 w1 ); void F3DEX2_Tri1( u32 w0, u32 w1 ); void F3DEX2_PopMtx( u32 w0, u32 w1 ); void F3DEX2_MoveWord( u32 w0, u32 w1 ); void F3DEX2_Texture( u32 w0, u32 w1 ); void F3DEX2_SetOtherMode_H( u32 w0, u32 w1 ); void F3DEX2_SetOtherMode_L( u32 w0, u32 w1 ); void F3DEX2_GeometryMode( u32 w0, u32 w1 ); void F3DEX2_Line3D( u32 w0, u32 w1 ); void F3DEX2_DMAIO( u32 w0, u32 w1 ); void F3DEX2_Special_1( u32 w0, u32 w1 ); void F3DEX2_Special_2( u32 w0, u32 w1 ); void F3DEX2_Special_3( u32 w0, u32 w1 ); void F3DEX2_Quad( u32 w0, u32 w1 ); void F3DEX2_Init(); #endif mupen64plus-rsp-cxd4/matrix.h000664 001750 001750 00000026504 12655644434 017247 0ustar00sergiosergio000000 000000 /******************************************************************************\ * Project: RSP Disassembler * * Authors: Iconoclast * * Release: 2013.09.12 * * License: CC0 Public Domain Dedication * * * * To the extent possible under law, the author(s) have dedicated all copyright * * and related and neighboring rights to this software to the public domain * * worldwide. This software is distributed without any warranty. * * * * You should have received a copy of the CC0 Public Domain Dedication along * * with this software. * * If not, see . * \******************************************************************************/ #ifndef MATRIX_H #define MATRIX_H char disasm[24]; #define reserved_ "illegal" /* Or, "invalid". Change it to whatever, but it must NOT exceed 7 letters. */ static const char mnemonics_PRIMARY[64][8] = { "SPECIAL","REGIMM ","J ","JAL ","BEQ ","BNE ","BLEZ ","BGTZ ", "ADDI ","ADDIU ","SLTI ","SLTIU ","ANDI ","ORI ","XORI ","LUI ", "COP0 ",reserved_,"COP2 ",reserved_,reserved_,reserved_,reserved_,reserved_, reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_, "LB ","LH ",reserved_,"LW ","LBU ","LHU ",reserved_,reserved_, "SB ","SH ",reserved_,"SW ",reserved_,reserved_,reserved_,reserved_, reserved_,reserved_,"LWC2 ",reserved_,reserved_,reserved_,reserved_,reserved_, reserved_,reserved_,"SWC2 ",reserved_,reserved_,reserved_,reserved_,reserved_ }; static const char mnemonics_SPECIAL[64][8] = { "SLL ",reserved_,"SRL ","SRA ","SLLV ",reserved_,"SRLV ","SRAV ", "JR ","JALR ",reserved_,reserved_,reserved_,"BREAK ",reserved_,reserved_, reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_, reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_, "ADD ","ADDU ","SUB ","SUBU ","AND ","OR ","XOR ","NOR ", reserved_,reserved_,"SLT ","SLTU ",reserved_,reserved_,reserved_,reserved_, reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_, reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_ }; static const char mnemonics_REGIMM[32][8] = { "BLTZ ","BGEZ ",reserved_,reserved_,reserved_,reserved_,reserved_,reserved_, reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_, "BLTZAL ","BGEZAL ",reserved_,reserved_,reserved_,reserved_,reserved_,reserved_, reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_ }; static const char mnemonics_COP0[32][8] = { "MFC0 ",reserved_,reserved_,reserved_,"MTC0 ",reserved_,reserved_,reserved_, reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_, reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_, reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_ }; static const char mnemonics_COP2[32][8] = { "MFC2 ",reserved_,"CFC2 ",reserved_,"MTC2 ",reserved_,"CTC2 ",reserved_, reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_, "C2 ","C2 ","C2 ","C2 ","C2 ","C2 ","C2 ","C2 ", "C2 ","C2 ","C2 ","C2 ","C2 ","C2 ","C2 ","C2 " }; static const char mnemonics_LWC2[32][8] = { "LBV ","LSV ","LLV ","LDV ","LQV ","LRV ","LPV ","LUV ", "LHV ","LFV ",reserved_,"LTV ",reserved_,reserved_,reserved_,reserved_, reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_, reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_ }; static const char mnemonics_SWC2[32][8] = { "SBV ","SSV ","SLV ","SDV ","SQV ","SRV ","SPV ","SUV ", "SHV ","SFV ","SWV ","STV ",reserved_,reserved_,reserved_,reserved_, reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_, reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_ }; static const char mnemonics_C2[64][8] = { "VMULF ","VMULU ",reserved_,reserved_,"VMUDL ","VMUDM ","VMUDN ","VMUDH ", "VMACF ","VMACU ",reserved_,"VMACQ ","VMADL ","VMADM ","VMADN ","VMADH ", "VADD ","VSUB ",reserved_,"VABS ","VADDC ","VSUBC ",reserved_,reserved_, reserved_,reserved_,reserved_,reserved_,reserved_,"VSAW ",reserved_,reserved_, "VLT ","VEQ ","VNE ","VGE ","VCL ","VCH ","VCR ","VMRG ", "VAND ","VNAND ","VOR ","VNOR ","VXOR ","VNXOR ",reserved_,reserved_, "VRCP ","VRCPL ","VRCPH ","VMOV ","VRSQ ","VRSQL ","VRSQH ","VNOP ", reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_,reserved_ }; /* * This is a dynamic-style disassembler. If it was really coded entirely for * speed then the instruction decoding fetching would be more static, * but this was mostly written to be accurate and small on size, not fastest. */ static const char tokens_CR_V[4][4] = { "vco", "vcc", "vce", "vce" /* exception override: only three control registers */ }; static const char* computational_elements[16] = { "", /* vector operand */ "[]", "[0q]", "[1q]", /* scalar quarter */ "[0h]", "[1h]", "[2h]", "[3h]", /* scalar half */ "[0]", "[1]", "[2]", "[3]", "[4]", "[5]", "[6]", "[7]" /* scalar whole */ }; /* * Syntax above is strict RSP assembler: * 1. The letters must be lower-case, not upper-case. * 2. It is not legal to append a 'w' for the scalar whole elements. * 3. e==0x1 is impossible to set in the assembler; "[]" is just for debug. */ void disassemble(int IW) { register int ID; unsigned short imm = (IW & 0x0000FFFF); const signed int offset = -(IW & 0x00008000) | imm; const unsigned int target = IW%0x04000000 << 2; const int func = IW % 64; const int sa = (IW >> 6) & 31; const int rd = (IW & 0x0000FFFF) >> 11; const int rt = (IW >> 16) & 31; const int rs = (IW >> 21) & 31; const int op = (IW >> 26) & 63; if ((op & ~001) == 000) /* SPECIAL/REGIMM */ ID = op + 1; else if ((op & 075) == 020) /* COPz */ ID = (op & 002) ? 04 + 3*!!(IW & 0x02000000) : 03; else if ((op & 067) == 062) /* ?WC2 */ ID = 05 + !!(op & 010); else ID = 00; ID = (ID % 8) & 07; /* Help compiler see this as an aligned jump: */ switch (ID) { char opcode[8]; case 00: strcpy(opcode, mnemonics_PRIMARY[op]); if (op & 32) /* op > 31: scalar loads and stores */ sprintf(disasm, "%s $%u, %i($%u)", opcode, rt, offset, rs); else if (op & 8) /* 16 > op > 8: arithmetic/logical immediate op */ if (op == 0xF) /* LUI does not encode rs. */ sprintf(disasm, "%s $%u, 0x%04X", opcode, rt, imm); else sprintf(disasm, "%s $%u, $%u, 0x%04X", opcode, rt, rs, imm); else if (op & 4) /* 8 > op > 4: primary branches */ if (op & 2) /* BLEZ, BGTZ */ sprintf(disasm, "%s $%u, %i", opcode, rs, offset); else /* BEQ, BNE */ sprintf(disasm, "%s $%u, $%u, %i", opcode, rs, rt, offset); else if (op & 2) /* J and JAL */ sprintf(disasm, "%s 0x%07X", opcode, target); else /* RESERVED */ sprintf(disasm, "%s:%08X", opcode, IW); return; case 01: strcpy(opcode, mnemonics_SPECIAL[func]); if (func & 040) /* func > 31: arithmetic/logic R-op (omit traps) */ sprintf(disasm, "%s $%u, $%u, $%u", opcode, rd, rs, rt); else if (func < 8) /* scalar shifts */ if (func & 4) /* variable */ sprintf(disasm, "%s $%u, $%u, $%u", opcode, rd, rt, rs); else sprintf(disasm, "%s $%u, $%u, %u", opcode, rd, rt, sa); else if (func == 010) /* JR */ sprintf(disasm, "%s $%u", opcode, rs); else if (func == 011) /* JALR */ sprintf(disasm, "%s $%u, $%u", opcode, rd, rs); else if (func == 015) /* BREAK */ strcpy(disasm, opcode); /* sprintf "BREAK" + secret code mask */ else /* RESERVED */ sprintf(disasm, "%s:%08X", opcode, IW); return; case 02: strcpy(opcode, mnemonics_REGIMM[rt]); if ((rt & 016) == 000) /* BLTZ[AL] and BGEZ[AL] */ sprintf(disasm, "%s $%u, %i", opcode, rs, offset); else /* RESERVED */ sprintf(disasm, "%s:%08X", opcode, IW); return; case 03: strcpy(opcode, mnemonics_COP0[rs]); if ((rs & 033) != 000) sprintf(disasm, "%s:%08X", opcode, IW); /* RESERVED */ else /* M?C0 */ sprintf(disasm, "%s $%u, $c%u", opcode, rt, rd & 0xF); return; case 04: strcpy(opcode, mnemonics_COP2[rs]); if (opcode[0] == 'M') /* M?C2 */ sprintf(disasm, "%s $%u, $v%u[0x%X]", opcode, rt, rd, sa >> 1); else if (opcode[0] == 'C') /* C?C2 */ sprintf(disasm, "%s $%u, $%s", opcode, rt, tokens_CR_V[rd % 4]); else /* RESERVED */ sprintf(disasm, "%s:%08X", opcode, IW); return; case 05: strcpy(opcode, mnemonics_LWC2[rd]); if (opcode[0] != 'L') sprintf(disasm, "%s:%08X", opcode, IW); /* RESERVED */ else sprintf(disasm, "%s $v%u[0x%X], %i($%u)", opcode, rt, sa >> 1, -(IW & 0x00000040) | func, rs); return; case 06: strcpy(opcode, mnemonics_SWC2[rd]); if (opcode[0] != 'S') sprintf(disasm, "%s:%08X", opcode, IW); /* RESERVED */ else sprintf(disasm, "%s $v%u[0x%X], %i($%u)", opcode, rt, sa >> 1, -(IW & 0x00000040) | func, rs); return; case 07: strcpy(opcode, mnemonics_C2[func]); if (opcode[0] != 'V') sprintf(disasm, "%s:%08X", opcode, IW); /* RESERVED */ else if (func == 067) /* VNOP */ strcpy(disasm, opcode); else if (func >= 060) /* VRCP?, VRSQ?, and VMOV */ sprintf(disasm, "%s $v%u[%u], $v%u[0x%X]", opcode, sa, rd & 07, rt, rs & 0xF); else /* the most common vectors */ if (func == 035) /* VSAR "VSAW", unconditional element syntax */ sprintf(disasm, "%s $v%u, $v%u, $v%u[%u]", opcode, sa, rd, rt, rs & 07); /* rs&7: 00"High", 01"Middle", 02"Low" */ else /* conditional element syntax: e != 0x0 */ sprintf(disasm, "%s $v%u, $v%u, $v%u%s", opcode, sa, rd, rt, computational_elements[rs & 0xF]); return; } } #endif mupen64plus-core/doc/gpl-license000664 001750 001750 00000044326 12655644434 017752 0ustar00sergiosergio000000 000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. mupen64plus-video-gliden64/src/windows/ZilmarAPIImpl_windows.cpp000664 001750 001750 00000001640 12655644434 026011 0ustar00sergiosergio000000 000000 #include "GLideN64_Windows.h" #include "../PluginAPI.h" #include "../GLideN64.h" #include "../GLideNUI/GLideNUI.h" #include "../OpenGL.h" #include "../Config.h" #include "../Revision.h" void PluginAPI::DllAbout(/*HWND _hParent*/) { Config_LoadConfig(); wchar_t strIniFolderPath[PLUGIN_PATH_SIZE]; api().FindPluginPath(strIniFolderPath); RunAbout(strIniFolderPath); } void PluginAPI::CaptureScreen(char * _Directory) { video().setCaptureScreen(_Directory); } void PluginAPI::DllConfig(HWND _hParent) { Config_DoConfig(/*_hParent*/); } void PluginAPI::GetDllInfo(PLUGIN_INFO * PluginInfo) { PluginInfo->Version = 0x103; PluginInfo->Type = PLUGIN_TYPE_GFX; sprintf(PluginInfo->Name, "%s rev.%s", pluginName, PLUGIN_REVISION); PluginInfo->NormalMemory = FALSE; PluginInfo->MemoryBswaped = TRUE; } void PluginAPI::ReadScreen(void **_dest, long *_width, long *_height) { video().readScreen(_dest, _width, _height); } mupen64plus-rsp-hle/src/hle.h000664 001750 001750 00000004415 12655644434 017205 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-rsp-hle - hle.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef HLE_H #define HLE_H #include "hle_internal.h" void hle_init(struct hle_t* hle, unsigned char* dram, unsigned char* dmem, unsigned char* imem, unsigned int* mi_intr, unsigned int* sp_mem_addr, unsigned int* sp_dram_addr, unsigned int* sp_rd_length, unsigned int* sp_wr_length, unsigned int* sp_status, unsigned int* sp_dma_full, unsigned int* sp_dma_busy, unsigned int* sp_pc, unsigned int* sp_semaphore, unsigned int* dpc_start, unsigned int* dpc_end, unsigned int* dpc_current, unsigned int* dpc_status, unsigned int* dpc_clock, unsigned int* dpc_bufbusy, unsigned int* dpc_pipebusy, unsigned int* dpc_tmem, void* user_defined); void hle_execute(struct hle_t* hle); #endif mupen64plus-video-gliden64/src/Config.h000664 001750 001750 00000007524 12655644434 021014 0ustar00sergiosergio000000 000000 #ifndef CONFIG_H #define CONFIG_H #include #include "Types.h" #define CONFIG_VERSION_ONE 1U #define CONFIG_VERSION_TWO 2U #define CONFIG_VERSION_THREE 3U #define CONFIG_VERSION_FOUR 4U // Remove ValidityCheckMethod setting #define CONFIG_VERSION_FIVE 5U // Add shader storage option #define CONFIG_VERSION_SIX 6U // Change gamma correction options #define CONFIG_VERSION_CURRENT CONFIG_VERSION_SIX #define BILINEAR_3POINT 0 #define BILINEAR_STANDARD 1 const u32 gc_uMegabyte = 1024U * 1024U; struct Config { u32 version; std::string translationFile; struct { u32 fullscreen; u32 windowedWidth, windowedHeight; u32 fullscreenWidth, fullscreenHeight, fullscreenRefresh; u32 multisampling; u32 verticalSync; } video; struct { u32 maxAnisotropy; f32 maxAnisotropyF; u32 bilinearMode; u32 maxBytes; u32 screenShotFormat; } texture; struct { u32 enableFog; u32 enableNoise; u32 enableLOD; u32 enableHWLighting; u32 enableCustomSettings; u32 enableShadersStorage; u32 hacks; #ifdef ANDROID u32 forcePolygonOffset; f32 polygonOffsetFactor; f32 polygonOffsetUnits; #endif } generalEmulation; enum Aspect { aStretch = 0, a43 = 1, a169 = 2, aAdjust = 3, aTotal = 4 }; enum CopyToRDRAM { ctDisable = 0, ctSync, ctAsync }; enum BufferSwapMode { bsOnVerticalInterrupt = 0, bsOnVIOriginChange, bsOnColorImageChange }; struct { u32 enable; u32 copyAuxToRDRAM; u32 copyToRDRAM; u32 copyDepthToRDRAM; u32 copyFromRDRAM; u32 N64DepthCompare; u32 aspect; // 0: stretch ; 1: 4/3 ; 2: 16/9; 3: adjust u32 bufferSwapMode; // 0: on VI update call; 1: on VI origin change; 2: on main frame buffer update } frameBufferEmulation; struct { u32 txFilterMode; // Texture filtering mode, eg Sharpen u32 txEnhancementMode; // Texture enhancement mode, eg 2xSAI u32 txFilterIgnoreBG; // Do not apply filtering to backgrounds textures u32 txCacheSize; // Cache size in Mbytes u32 txHiresEnable; // Use high-resolution texture packs u32 txHiresFullAlphaChannel; // Use alpha channel fully u32 txHresAltCRC; // Use alternative method of paletted textures CRC calculation u32 txDump; // Dump textures u32 txForce16bpp; // Force use 16bit color textures u32 txCacheCompression; // Zip textures cache u32 txSaveCache; // Save texture cache to hard disk wchar_t txPath[PLUGIN_PATH_SIZE]; } textureFilter; struct { std::string name; u32 size; u8 color[4]; float colorf[4]; } font; struct { u32 enable; u32 thresholdLevel; u32 blendMode; u32 blurAmount; u32 blurStrength; } bloomFilter; struct { u32 force; f32 level; } gammaCorrection; void resetToDefaults(); }; #define hack_Ogre64 (1<<0) //Ogre Battle 64 background copy #define hack_noDepthFrameBuffers (1<<1) //Do not use depth buffers as texture #define hack_blurPauseScreen (1<<2) //Game copies frame buffer to depth buffer area, CPU blurs it. That image is used as background for pause screen. #define hack_scoreboard (1<<3) //Copy data from RDRAM to auxilary frame buffer. Scoreboard in Mario Tennis. #define hack_scoreboardJ (1<<4) //Copy data from RDRAM to auxilary frame buffer. Scoreboard in Mario Tennis (J). #define hack_pilotWings (1<<5) //Special blend mode for PilotWings. #define hack_subscreen (1<<6) //Fix subscreen delay in Zelda OOT and Doubutsu no Mori #define hack_blastCorps (1<<8) //Blast Corps black polygons #define hack_ignoreVIHeightChange (1<<9) //Do not reset FBO when VI height is changed. Space Invaders need it. #define hack_skipVIChangeCheck (1<<11) //Don't reset FBO when VI parameters changed. Zelda MM #define hack_ZeldaCamera (1<<12) //Special hack to detect and process Zelda MM camera. extern Config config; void Config_LoadConfig(); #ifndef MUPENPLUSAPI void Config_DoConfig(/*HWND hParent*/); #endif #endif // CONFIG_H mupen64plus-rsp-hle/src/hle.c000664 001750 001750 00000027214 12655644434 017202 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-rsp-hle - hle.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2012 Bobby Smiles * * Copyright (C) 2009 Richard Goedeken * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include "hle_external.h" #include "hle_internal.h" #include "memory.h" #include "m64p_plugin.h" #include "ucodes.h" #define min(a,b) (((a) < (b)) ? (a) : (b)) /* some rsp status flags */ #define SP_STATUS_HALT 0x1 #define SP_STATUS_BROKE 0x2 #define SP_STATUS_INTR_ON_BREAK 0x40 #define SP_STATUS_TASKDONE 0x200 /* some rdp status flags */ #define DP_STATUS_FREEZE 0x2 /* some mips interface interrupt flags */ #define MI_INTR_SP 0x1 /* helper functions prototypes */ static unsigned int sum_bytes(const unsigned char *bytes, unsigned int size); static void rsp_break(struct hle_t* hle, unsigned int setbits); static void forward_gfx_task(struct hle_t* hle); static bool try_fast_audio_dispatching(struct hle_t* hle); static bool try_fast_task_dispatching(struct hle_t* hle); static void normal_task_dispatching(struct hle_t* hle); static void non_task_dispatching(struct hle_t* hle); extern RSP_INFO rsp_info; /* local variables */ static const bool FORWARD_AUDIO = false, FORWARD_GFX = true; /* Global functions */ void hle_init(struct hle_t* hle, unsigned char* dram, unsigned char* dmem, unsigned char* imem, unsigned int* mi_intr, unsigned int* sp_mem_addr, unsigned int* sp_dram_addr, unsigned int* sp_rd_length, unsigned int* sp_wr_length, unsigned int* sp_status, unsigned int* sp_dma_full, unsigned int* sp_dma_busy, unsigned int* sp_pc, unsigned int* sp_semaphore, unsigned int* dpc_start, unsigned int* dpc_end, unsigned int* dpc_current, unsigned int* dpc_status, unsigned int* dpc_clock, unsigned int* dpc_bufbusy, unsigned int* dpc_pipebusy, unsigned int* dpc_tmem, void* user_defined) { hle->dram = dram; hle->dmem = dmem; hle->imem = imem; hle->mi_intr = mi_intr; hle->sp_mem_addr = sp_mem_addr; hle->sp_dram_addr = sp_dram_addr; hle->sp_rd_length = sp_rd_length; hle->sp_wr_length = sp_wr_length; hle->sp_status = sp_status; hle->sp_dma_full = sp_dma_full; hle->sp_dma_busy = sp_dma_busy; hle->sp_pc = sp_pc; hle->sp_semaphore = sp_semaphore; hle->dpc_start = dpc_start; hle->dpc_end = dpc_end; hle->dpc_current = dpc_current; hle->dpc_status = dpc_status; hle->dpc_clock = dpc_clock; hle->dpc_bufbusy = dpc_bufbusy; hle->dpc_pipebusy = dpc_pipebusy; hle->dpc_tmem = dpc_tmem; hle->user_defined = user_defined; } /** * Try to figure if the RSP was launched using osSpTask* functions * and not run directly (in which case DMEM[0xfc0-0xfff] is meaningless). * * Previously, the ucode_size field was used to determine this, * but it is not robust enough (hi Pokemon Stadium !) because games could write anything * in this field : most ucode_boot discard the value and just use 0xf7f anyway. * * Using ucode_boot_size should be more robust in this regard. **/ #define is_task(hle) ((*dmem_u32((hle), TASK_UCODE_BOOT_SIZE) <= 0x1000)) void hle_execute(struct hle_t* hle) { if (is_task(hle)) { if (!try_fast_task_dispatching(hle)) normal_task_dispatching(hle); rsp_break(hle, SP_STATUS_TASKDONE); return; } non_task_dispatching(hle); rsp_break(hle, 0); } /* local functions */ static unsigned int sum_bytes(const unsigned char *bytes, unsigned int size) { unsigned int sum = 0; const unsigned char *const bytes_end = bytes + size; while (bytes != bytes_end) sum += *bytes++; return sum; } static void rsp_break(struct hle_t* hle, unsigned int setbits) { *hle->sp_status |= setbits | SP_STATUS_BROKE | SP_STATUS_HALT; if ((*hle->sp_status & SP_STATUS_INTR_ON_BREAK)) { *hle->mi_intr |= MI_INTR_SP; if (rsp_info.CheckInterrupts) rsp_info.CheckInterrupts(); } } static void forward_gfx_task(struct hle_t* hle) { if (rsp_info.ProcessDlistList) rsp_info.ProcessDlistList(); } static bool try_fast_audio_dispatching(struct hle_t* hle) { uint32_t v; /* identify audio ucode by using the content of ucode_data */ uint32_t ucode_data = *dmem_u32(hle, TASK_UCODE_DATA); if (*dram_u32(hle, ucode_data) == 0x00000001) { if (*dram_u32(hle, ucode_data + 0x30) == 0xf0000f00) { v = *dram_u32(hle, ucode_data + 0x28); switch(v) { case 0x1e24138c: /* audio ABI (most common) */ alist_process_audio(hle); return true; case 0x1dc8138c: /* GoldenEye */ alist_process_audio_ge(hle); return true; case 0x1e3c1390: /* BlastCorp, DiddyKongRacing */ alist_process_audio_bc(hle); return true; default: HleWarnMessage(hle->user_defined, "ABI1 identification regression: v=%08x", v); } } else { v = *dram_u32(hle, ucode_data + 0x10); switch(v) { case 0x11181350: /* MarioKart, WaveRace (E) */ alist_process_nead_mk(hle); return true; case 0x111812e0: /* StarFox (J) */ alist_process_nead_sfj(hle); return true; case 0x110412ac: /* WaveRace (J RevB) */ alist_process_nead_wrjb(hle); return true; case 0x110412cc: /* StarFox/LylatWars (except J) */ alist_process_nead_sf(hle); return true; case 0x1cd01250: /* FZeroX */ alist_process_nead_fz(hle); return true; case 0x1f08122c: /* YoshisStory */ alist_process_nead_ys(hle); return true; case 0x1f38122c: /* 1080° Snowboarding */ alist_process_nead_1080(hle); return true; case 0x1f681230: /* Zelda OoT / Zelda MM (J, J RevA) */ alist_process_nead_oot(hle); return true; case 0x1f801250: /* Zelda MM (except J, J RevA, E Beta), PokemonStadium 2 */ alist_process_nead_mm(hle); return true; case 0x109411f8: /* Zelda MM (E Beta) */ alist_process_nead_mmb(hle); return true; case 0x1eac11b8: /* AnimalCrossing */ alist_process_nead_ac(hle); return true; case 0x00010010: /* MusyX v2 (IndianaJones, BattleForNaboo) */ musyx_v2_task(hle); return true; default: HleWarnMessage(hle->user_defined, "ABI2 identification regression: v=%08x", v); } } } else { v = *dram_u32(hle, ucode_data + 0x10); switch(v) { /* -- MusyX v1 -- Star Wars: Rogue Squadron Resident Evil 2 Polaris SnoCross 007: The World Is Not Enough Rugrats In Paris NBA ShowTime Hydro Thunder Tarzan Gauntlet Legends Rush 2049 */ case 0x00000001: musyx_v1_task(hle); return true; /* NAUDIO (many games) */ case 0x0000127c: alist_process_naudio(hle); return true; /* Banjo Kazooie */ case 0x00001280: alist_process_naudio_bk(hle); return true; /* Donkey Kong 64 */ case 0x1c58126c: alist_process_naudio_dk(hle); return true; /* Banjo Tooie * Jet Force Gemini * Mickey's SpeedWay USA * Perfect Dark */ case 0x1ae8143c: alist_process_naudio_mp3(hle); return true; case 0x1ab0140c: /* Conker's Bad Fur Day */ alist_process_naudio_cbfd(hle); return true; default: HleWarnMessage(hle->user_defined, "ABI3 identification regression: v=%08x", v); } } return false; } static bool try_fast_task_dispatching(struct hle_t* hle) { /* identify task ucode by its type */ switch (*dmem_u32(hle, TASK_TYPE)) { case 1: if (FORWARD_GFX) { forward_gfx_task(hle); return true; } break; case 2: if (FORWARD_AUDIO) { if (rsp_info.ProcessAlistList) rsp_info.ProcessAlistList(); return true; } if (try_fast_audio_dispatching(hle)) return true; break; case 7: if (rsp_info.ShowCFB) rsp_info.ShowCFB(); return true; } return false; } static void normal_task_dispatching(struct hle_t* hle) { const unsigned int sum = sum_bytes((void*)dram_u32(hle, *dmem_u32(hle, TASK_UCODE)), min(*dmem_u32(hle, TASK_UCODE_SIZE), 0xf80) >> 1); switch (sum) { /* StoreVe12: found in Zelda Ocarina of Time [misleading task->type == 4] */ case 0x278: /* Nothing to emulate */ return; /* GFX: Twintris [misleading task->type == 0] */ case 0x212ee: if (FORWARD_GFX) { forward_gfx_task(hle); return; } break; /* JPEG: found in Pokemon Stadium J */ case 0x2c85a: jpeg_decode_PS0(hle); return; /* JPEG: found in Zelda Ocarina of Time, Pokemon Stadium 1, Pokemon Stadium 2 */ case 0x2caa6: jpeg_decode_PS(hle); return; /* JPEG: found in Ogre Battle, Bottom of the 9th */ case 0x130de: case 0x278b0: jpeg_decode_OB(hle); return; } HleWarnMessage(hle->user_defined, "unknown OSTask: sum: %x PC:%x", sum, *hle->sp_pc); } static void non_task_dispatching(struct hle_t* hle) { const unsigned int sum = sum_bytes(hle->imem, 44); if (sum == 0x9e2) { /* CIC x105 ucode (used during boot of CIC x105 games) */ cicx105_ucode(hle); return; } HleWarnMessage(hle->user_defined, "unknown RSP code: sum: %x PC:%x", sum, *hle->sp_pc); } mupen64plus-video-gliden64/src/F3DDKR.h000664 001750 001750 00000000466 12655644434 020522 0ustar00sergiosergio000000 000000 #ifndef F3DDKR_H #define F3DDKR_H #define F3DDKR_VTX_APPEND 0x00010000 #define F3DDKR_DMA_MTX 0x01 #define F3DDKR_DMA_TEX_OFFSET 0x02 #define F3DDKR_DMA_VTX 0x04 #define F3DDKR_DMA_TRI 0x05 #define F3DDKR_DMA_DL 0x07 #define F3DDKR_DMA_OFFSETS 0xBF void F3DDKR_Init(); void F3DJFG_Init(); #endif mupen64plus-rsp-hle/src/rsp_api_export.ver000664 001750 001750 00000000155 12655644434 022035 0ustar00sergiosergio000000 000000 { global: PluginStartup; PluginShutdown; PluginGetVersion; DoRspCycles; InitiateRSP; RomClosed; local: *; }; libretro/msvc/msvc-2010.sln000664 001750 001750 00000002306 12655644434 016560 0ustar00sergiosergio000000 000000  Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "msvc-2010", "msvc-2010\msvc-2010.vcxproj", "{62F97835-3567-4EF3-ACDC-46F2CDECAF40}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {62F97835-3567-4EF3-ACDC-46F2CDECAF40}.Debug|Win32.ActiveCfg = Debug|Win32 {62F97835-3567-4EF3-ACDC-46F2CDECAF40}.Debug|Win32.Build.0 = Debug|Win32 {62F97835-3567-4EF3-ACDC-46F2CDECAF40}.Debug|x64.ActiveCfg = Debug|x64 {62F97835-3567-4EF3-ACDC-46F2CDECAF40}.Debug|x64.Build.0 = Debug|x64 {62F97835-3567-4EF3-ACDC-46F2CDECAF40}.Release|Win32.ActiveCfg = Release|Win32 {62F97835-3567-4EF3-ACDC-46F2CDECAF40}.Release|Win32.Build.0 = Release|Win32 {62F97835-3567-4EF3-ACDC-46F2CDECAF40}.Release|x64.ActiveCfg = Release|x64 {62F97835-3567-4EF3-ACDC-46F2CDECAF40}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal mupen64plus-rsp-cxd4/config.h000664 001750 001750 00000001023 12655644434 017175 0ustar00sergiosergio000000 000000 #ifndef _CXD4_CONFIG_H #define _CXD4_CONFIG_H #include extern unsigned char conf[32]; /* * The config file used to be a 32-byte EEPROM with binary settings storage. * It was found necessary for user and contributor convenience to replace. * * The current configuration system now uses Garteal's CFG text definitions. */ #define CFG_HLE_GFX (conf[0x00]) #define CFG_HLE_AUD (conf[0x01]) #define CFG_HLE_VID (conf[0x02]) /* reserved/unused */ #define CFG_HLE_JPG (conf[0x03]) /* unused */ #endif mupen64plus-rsp-hle/LICENSES000664 001750 001750 00000045572 12655644434 016636 0ustar00sergiosergio000000 000000 Mupen64Plus-rsp-hle LICENSE --------------------------- Mupen64Plus-rsp-hle is licensed under the GNU General Public License version 2. The authors of Mupen64Plus-rsp-hle are: * Richard Goedeken (Richard42) * Bobby Smiles * John Chadwick (NMN) * James Hood (Ebenblues) * Scott Gorman (okaygo) * Scott Knauert (Tillin9) * Jesse Dean (DarkJezter) * Louai Al-Khanji (slougi) * Bob Forder (orbitaldecay) * Jason Espinosa (hasone) * HyperHacker * and others. Mupen64Plus is based on GPL-licensed source code from Mupen64 v0.5, originally written by: * Hacktarux * Dave2001 * Zilmar * Gregor Anich (Blight) * Juha Luotio (JttL) * and others. GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. mupen64plus-video-gliden64/src/winlnxdefs.h000664 001750 001750 00000004113 12655644434 021757 0ustar00sergiosergio000000 000000 /** * Mupen64 - winlnxdefs.h * Copyright (C) 2002 Hacktarux * * Mupen64 homepage: http://mupen64.emulation64.com * email address: hacktarux@yahoo.fr * * If you want to contribute to the project please contact * me first (maybe someone is already making what you are * planning to do). * * * This program is free software; you can redistribute it and/ * or modify it under the terms of the GNU General Public Li- * cence as published by the Free Software Foundation; either * version 2 of the Licence, or any later version. * * This program is distributed in the hope that it will be use- * ful, but WITHOUT ANY WARRANTY; without even the implied war- * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public Licence for more details. * * You should have received a copy of the GNU General Public * Licence along with this program; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, * USA. * **/ #ifndef WINLNXDEFS_H #define WINLNXDEFS_H #include #include // PATH_MAX #include // malloc(), srand() #include #include #include // time() #include // readlink() #define timeGetTime() time( 0 ) typedef unsigned int BOOL, BOOLEAN; typedef unsigned int DWORD; typedef unsigned long long DWORD64, QWORD; typedef unsigned short WORD; typedef unsigned char BYTE, byte; typedef unsigned int UINT; typedef char CHAR; typedef short SHORT; typedef long LONG; typedef float FLOAT; typedef long __int32; typedef int HINSTANCE; typedef int HWND; typedef int WPARAM; typedef int LPARAM; typedef void* LPVOID; typedef const char *LPCSTR; // types /*#define BOOL unsigned int #define BOOLEAN unsigned int #define DWORD unsigned long #define WORD unsigned short #define BYTE unsigned char*/ #define __declspec(dllexport) #define _cdecl #define WINAPI //#define APIENTRY //#define EXPORT //#define CALL #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif #ifndef false #define false 0 #endif #ifndef true #define true 1 #endif #endif gles2rice/src/ucode.h000664 001750 001750 00000110404 12655644434 015635 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "UcodeDefs.h" #ifndef _UCODE_H_ #define _UCODE_H_ //typedef void (*RDPInstruction)(Gfx *gfx); typedef void (*RDPInstruction)(Gfx*); extern RDPInstruction *currentUcodeMap; typedef RDPInstruction UcodeMap[256] ; //#define UcodeFunc(name) void name(uint32_t, uint32_t) #define UcodeFunc(name) void name(Gfx*) UcodeFunc(RSP_RDP_Nothing); UcodeFunc(RSP_GBI0_Mtx); UcodeFunc(RSP_Mtx_DKR); UcodeFunc(RSP_GBI0_DL); UcodeFunc(RSP_DL_In_MEM_DKR); UcodeFunc(RSP_GBI0_Vtx); UcodeFunc(RSP_Vtx_DKR); UcodeFunc(RSP_Vtx_WRUS); UcodeFunc(RSP_Vtx_ShadowOfEmpire); UcodeFunc(RSP_GBI0_Tri4); UcodeFunc(RSP_DMA_Tri_DKR); UcodeFunc(DLParser_Set_Addr_Ucode6); UcodeFunc(RSP_MoveWord_DKR); UcodeFunc(RSP_Vtx_PD); UcodeFunc(RSP_Set_Vtx_CI_PD); UcodeFunc(RSP_Tri4_PD); UcodeFunc(RSP_GBI0_Sprite2DBase); UcodeFunc(RSP_GBI0_Sprite2DDraw); UcodeFunc(RSP_GBI1_Sprite2DBase); UcodeFunc(RSP_GBI1_Sprite2DScaleFlip); UcodeFunc(RSP_GBI1_Sprite2DDraw); UcodeFunc(RSP_GBI_Sprite2DBase); UcodeFunc(RSP_GBI_Sprite2D_PuzzleMaster64); UcodeFunc(RSP_GBI1_SpNoop); UcodeFunc(RSP_GBI1_Reserved); UcodeFunc(RSP_GBI1_Vtx); UcodeFunc(RSP_GBI1_MoveMem); UcodeFunc(RSP_GBI1_RDPHalf_Cont); UcodeFunc(RSP_GBI1_RDPHalf_2); UcodeFunc(RSP_GBI1_RDPHalf_1); UcodeFunc(RSP_GBI1_Line3D); UcodeFunc(RSP_GBI1_ClearGeometryMode); UcodeFunc(RSP_GBI1_SetGeometryMode); UcodeFunc(RSP_GBI1_EndDL); UcodeFunc(RSP_GBI1_SetOtherModeL); UcodeFunc(RSP_GBI1_SetOtherModeH); UcodeFunc(RSP_GBI1_Texture); UcodeFunc(RSP_GBI1_MoveWord); UcodeFunc(RSP_GBI1_PopMtx); UcodeFunc(RSP_GBI1_CullDL); UcodeFunc(RSP_GBI1_Tri1); UcodeFunc(RSP_GBI1_Tri2); UcodeFunc(RSP_GBI1_Noop); UcodeFunc(RSP_GBI1_ModifyVtx); UcodeFunc(RSP_GBI1_BranchZ); UcodeFunc(RSP_GBI1_LoadUCode); UcodeFunc(DLParser_TexRect); UcodeFunc(DLParser_TexRectFlip); UcodeFunc(DLParser_RDPLoadSync); UcodeFunc(DLParser_RDPPipeSync); UcodeFunc(DLParser_RDPTileSync); UcodeFunc(DLParser_RDPFullSync); UcodeFunc(DLParser_SetKeyGB); UcodeFunc(DLParser_SetKeyR); UcodeFunc(DLParser_SetConvert); UcodeFunc(DLParser_SetScissor); UcodeFunc(DLParser_SetPrimDepth); UcodeFunc(DLParser_RDPSetOtherMode); UcodeFunc(DLParser_LoadTLut); UcodeFunc(DLParser_SetTileSize); UcodeFunc(DLParser_LoadBlock); UcodeFunc(DLParser_LoadTile); UcodeFunc(DLParser_SetTile); UcodeFunc(DLParser_FillRect); UcodeFunc(DLParser_SetFillColor); UcodeFunc(DLParser_SetFogColor); UcodeFunc(DLParser_SetBlendColor); UcodeFunc(DLParser_SetPrimColor); UcodeFunc(DLParser_SetEnvColor); UcodeFunc(DLParser_SetCombine); UcodeFunc(DLParser_SetTImg); UcodeFunc(DLParser_SetZImg); UcodeFunc(DLParser_SetCImg); UcodeFunc(RSP_GBI2_DL); UcodeFunc(RSP_GBI2_CullDL); UcodeFunc(RSP_GBI2_EndDL); UcodeFunc(RSP_GBI2_MoveWord); UcodeFunc(RSP_GBI2_Texture); UcodeFunc(RSP_GBI2_GeometryMode); UcodeFunc(RSP_GBI2_SetOtherModeL); UcodeFunc(RSP_GBI2_SetOtherModeH); UcodeFunc(RSP_GBI2_MoveMem); UcodeFunc(RSP_GBI2_Mtx); UcodeFunc(RSP_GBI2_PopMtx); UcodeFunc(RSP_GBI2_Vtx); UcodeFunc(RSP_GBI2_Tri1); UcodeFunc(RSP_GBI2_Tri2); UcodeFunc(RSP_GBI2_Line3D); UcodeFunc(RSP_GBI2_DL_Count); UcodeFunc(RSP_GBI2_SubModule); UcodeFunc(RSP_GBI2_0x8); UcodeFunc(DLParser_Bomberman2TextRect); UcodeFunc(RSP_S2DEX_BG_1CYC_2); UcodeFunc(RSP_S2DEX_OBJ_RENDERMODE_2); UcodeFunc(RSP_S2DEX_SPObjLoadTxtr_Ucode1); UcodeFunc( RSP_S2DEX_BG_1CYC); UcodeFunc( RSP_S2DEX_BG_COPY); UcodeFunc( RSP_S2DEX_OBJ_RECTANGLE); UcodeFunc( RSP_S2DEX_OBJ_SPRITE); UcodeFunc( RSP_S2DEX_OBJ_MOVEMEM); UcodeFunc( RSP_S2DEX_SELECT_DL); UcodeFunc( RSP_S2DEX_OBJ_RENDERMODE); UcodeFunc( RSP_S2DEX_OBJ_RECTANGLE_R); UcodeFunc( RSP_S2DEX_SPObjLoadTxtr); UcodeFunc( RSP_S2DEX_SPObjLoadTxSprite); UcodeFunc( RSP_S2DEX_SPObjLoadTxRect); UcodeFunc( RSP_S2DEX_SPObjLoadTxRectR); UcodeFunc( RSP_S2DEX_RDPHALF_0); UcodeFunc( RSP_S2DEX_Yoshi_Unknown); UcodeFunc( RSP_RDP_InsertMatrix ); UcodeFunc( RSP_S2DEX_SPObjLoadTxtr ); UcodeFunc(RDP_TriFill); UcodeFunc(RDP_TriFillZ); UcodeFunc(RDP_TriTxtr); UcodeFunc(RDP_TriTxtrZ); UcodeFunc(RDP_TriShade); UcodeFunc(RDP_TriShadeZ); UcodeFunc(RDP_TriShadeTxtr); UcodeFunc(RDP_TriShadeTxtrZ); #ifdef DEBUGGER const char* ucodeNames_GBI1[256] = { "RSP_SPNOOP", "RSP_MTX", "Reserved0", "RSP_MOVEMEM", "RSP_VTX", "Reserved1", "RSP_DL", "Reserved2", "RSP_RESERVED3", "RSP_SPRITE2D", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", //10 "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", //20 "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", //30 "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", //40 "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", //50 "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", //60 "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", //70 "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", //80 "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", //90 "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", //A0 "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "RSP_LOAD_UCODE", //B0 "RSP_BRANCH_Z", "RSP_TRI2", "G_MODIFY_VERTEX", "RSP_RDPHALF_2", "RSP_RDPHALF_1", "RSP_LINE3D", "RSP_CLEARGEOMETRYMODE", "RSP_SETGEOMETRYMODE", "RSP_ENDDL", "RSP_SETOTHERMODE_L", "RSP_SETOTHERMODE_H", "RSP_TEXTURE", "RSP_MOVEWORD", "RSP_POPMTX", "RSP_CULLDL", "RSP_TRI1", //C0 "RDP_NOOP", "G_NOTHING", "G_YS_UNK1", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "RDP_TriFill", "RDP_TriFillZ", "RDP_TriTxtr", "RDP_TriTxtrZ", "RDP_TriShade", "RDP_TriShadeZ", "RDP_TriShadeTxtr", "RDP_TriShadeTxtrZ", //D0 "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", //E0 "G_NOTHING", "G_NOTHING", "G_NOTHING", "G_NOTHING", "RDP_TEXRECT", "RDP_TEXRECT_FLIP", "RDP_LOADSYNC", "RDP_PIPESYNC", "RDP_TILESYNC", "RDP_FULLSYNC", "RDP_SETKEYGB", "RDP_SETKEYR", "RDP_SETCONVERT", "RDP_SETSCISSOR", "RDP_SETPRIMDEPTH", "RDP_RDPSETOTHERMODE", //F0 "RDP_LOADTLUT", "G_NOTHING", "RDP_SETTILESIZE", "RDP_LOADBLOCK", "RDP_LOADTILE", "RDP_SETTILE", "RDP_FILLRECT", "RDP_SETFILLCOLOR", "RDP_SETFOGCOLOR", "RDP_SETBLENDCOLOR", "RDP_SETPRIMCOLOR", "RDP_SETENVCOLOR", "RDP_SETCOMBINE", "RDP_SETTIMG", "RDP_SETZIMG", "RDP_SETCIMG" }; const char* ucodeNames_GBI2[256] = { "NOOP", "GBI2_Vtx", "ModifyVtx", "GBI2_CullDL", "BranchZ", "GBI2_Tri1", "GBI2_Tri2","GBI2_Line3D", "Nothing", "ObjBG1CYC", "ObjBGCopy", "OBJ_RenderMode", "Nothing", "Nothing", "Nothing", "Nothing", //10 "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", //20 "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", //30 "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", //40 "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", //50 "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", //60 "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", //70 "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", //80 "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", //90 "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", //a0 "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Load_Ucode", //b0 "BranchZ", "Tri2_Goldeneye", "ModifyVtx", "RDPHalf_2", "RDPHalf_1", "Line3D", "ClearGeometryMode", "SetGeometryMode", "EndDL", "SetOtherMode_L", "SetOtherMode_H", "Texture", "MoveWord", "PopMtx", "CullDL", "Tri1", //c0 "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "RDP_TriFill", "RDP_TriFillZ", "RDP_TriTxtr", "RDP_TriTxtrZ", "RDP_TriShade", "RDP_TriShadeZ", "RDP_TriShadeTxtr", "RDP_TriShadeTxtrZ", //d0 "Nothing", "Nothing", "Nothing", "Nothing", "Nothing", "GBI2_DL_N", "GBI2_SubModule", "GBI2_Texture", "GBI2_PopMtx", "GBI2_SetGeometryMode", "GBI2_Mtx", "GBI2_MoveWord", "GBI2_MoveMem", "Load_Ucode", "GBI2_DL", "GBI2_EndDL", //e0 "SPNOOP", "RDPHalf_1", "GBI2_SetOtherMode_L", "GBI2_SetOtherMode_H", "TexRect", "TexRectFlip", "RDPLoadSync", "RDPPipeSync", "RDPTileSync", "RDPFullSync", "SetKeyGB", "SetKeyR", "SetConvert", "SetScissor", "SetPrimDepth", "RDPSetOtherMode", //f0 "LoadTLut", "Nothing", "SetTileSize", "LoadBlock", "LoadTile", "SetTile", "FillRect", "SetFillColor", "SetFogColor", "SetBlendColor", "SetPrimColor", "SetEnvColor", "SetCombine", "SetTImg", "SetZImg", "SetCImg", }; #endif typedef RDPInstruction UcodeMap[256] ; // Ucode: F3DEX, for most games UcodeMap ucodeMap1 = { RSP_GBI1_SpNoop, RSP_GBI0_Mtx, RSP_GBI1_Reserved, RSP_GBI1_MoveMem, RSP_GBI1_Vtx, RSP_GBI1_Reserved, RSP_GBI0_DL, RSP_GBI1_Reserved, RSP_GBI1_Reserved, RSP_GBI1_Sprite2DBase, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //10 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //20 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //30 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //40 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //50 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //60 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //70 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //80 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //90 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //a0 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_GBI1_LoadUCode, //b0 RSP_GBI1_BranchZ, RSP_GBI1_Tri2, RSP_GBI1_ModifyVtx, RSP_GBI1_RDPHalf_2, RSP_GBI1_RDPHalf_1, RSP_GBI1_Line3D, RSP_GBI1_ClearGeometryMode, RSP_GBI1_SetGeometryMode, RSP_GBI1_EndDL, RSP_GBI1_SetOtherModeL, RSP_GBI1_SetOtherModeH, RSP_GBI1_Texture, RSP_GBI1_MoveWord, RSP_GBI1_PopMtx, RSP_GBI1_CullDL, RSP_GBI1_Tri1, //c0 RSP_GBI1_Noop, RSP_S2DEX_SPObjLoadTxtr_Ucode1, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RDP_TriFill, RDP_TriFillZ, RDP_TriTxtr, RDP_TriTxtrZ, RDP_TriShade, RDP_TriShadeZ, RDP_TriShadeTxtr, RDP_TriShadeTxtrZ, //d0 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //e0 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, DLParser_TexRect, DLParser_TexRectFlip, DLParser_RDPLoadSync, DLParser_RDPPipeSync, DLParser_RDPTileSync, DLParser_RDPFullSync, DLParser_SetKeyGB, DLParser_SetKeyR, DLParser_SetConvert, DLParser_SetScissor, DLParser_SetPrimDepth, DLParser_RDPSetOtherMode, //f0 DLParser_LoadTLut, RSP_RDP_Nothing, DLParser_SetTileSize, DLParser_LoadBlock, DLParser_LoadTile, DLParser_SetTile, DLParser_FillRect, DLParser_SetFillColor, DLParser_SetFogColor, DLParser_SetBlendColor, DLParser_SetPrimColor, DLParser_SetEnvColor, DLParser_SetCombine, DLParser_SetTImg, DLParser_SetZImg, DLParser_SetCImg }; UcodeMap ucodeMap0= { RSP_GBI1_SpNoop, RSP_GBI0_Mtx, RSP_GBI1_Reserved, RSP_GBI1_MoveMem, RSP_GBI0_Vtx, RSP_GBI1_Reserved, RSP_GBI0_DL, RSP_GBI1_Reserved, RSP_GBI1_Reserved, RSP_GBI0_Sprite2DBase, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //10 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //20 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //30 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //40 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //50 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //60 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //70 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //80 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //90 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //a0 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //b0 RSP_RDP_Nothing, RSP_GBI0_Tri4, RSP_GBI1_RDPHalf_Cont, RSP_GBI1_RDPHalf_2, RSP_GBI1_RDPHalf_1, RSP_GBI1_Line3D, RSP_GBI1_ClearGeometryMode, RSP_GBI1_SetGeometryMode, RSP_GBI1_EndDL, RSP_GBI1_SetOtherModeL, RSP_GBI1_SetOtherModeH, RSP_GBI1_Texture, RSP_GBI1_MoveWord, RSP_GBI1_PopMtx, RSP_GBI1_CullDL, RSP_GBI1_Tri1, //c0 RSP_GBI1_Noop, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RDP_TriFill, RDP_TriFillZ, RDP_TriTxtr, RDP_TriTxtrZ, RDP_TriShade, RDP_TriShadeZ, RDP_TriShadeTxtr, RDP_TriShadeTxtrZ, //d0 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //e0 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, DLParser_TexRect, DLParser_TexRectFlip, DLParser_RDPLoadSync, DLParser_RDPPipeSync, DLParser_RDPTileSync, DLParser_RDPFullSync, DLParser_SetKeyGB, DLParser_SetKeyR, DLParser_SetConvert, DLParser_SetScissor, DLParser_SetPrimDepth, DLParser_RDPSetOtherMode, //f0 DLParser_LoadTLut, RSP_RDP_Nothing, DLParser_SetTileSize, DLParser_LoadBlock, DLParser_LoadTile, DLParser_SetTile, DLParser_FillRect, DLParser_SetFillColor, DLParser_SetFogColor, DLParser_SetBlendColor, DLParser_SetPrimColor, DLParser_SetEnvColor, DLParser_SetCombine, DLParser_SetTImg, DLParser_SetZImg, DLParser_SetCImg }; // Zelda and new games, F3DEX_GBI_2 UcodeMap ucodeMap5= { RSP_GBI1_Noop, RSP_GBI2_Vtx, RSP_GBI1_ModifyVtx, RSP_GBI2_CullDL, RSP_GBI1_BranchZ, RSP_GBI2_Tri1, RSP_GBI2_Tri2, RSP_GBI2_Line3D, RSP_GBI2_0x8, RSP_S2DEX_BG_1CYC, RSP_S2DEX_BG_COPY, RSP_S2DEX_OBJ_RENDERMODE, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //10 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //20 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //30 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //40 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //50 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //60 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //70 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //80 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //90 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //a0 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_GBI1_LoadUCode, //b0 RSP_GBI1_BranchZ, RSP_GBI0_Tri4, RSP_GBI1_ModifyVtx, RSP_GBI1_RDPHalf_2, RSP_GBI1_RDPHalf_1, RSP_GBI1_Line3D, RSP_GBI1_ClearGeometryMode, RSP_GBI1_SetGeometryMode, RSP_GBI1_EndDL, RSP_GBI1_SetOtherModeL, RSP_GBI1_SetOtherModeH, RSP_GBI1_Texture, RSP_GBI1_MoveWord, RSP_GBI1_PopMtx, RSP_GBI1_CullDL, RSP_GBI1_Tri1, //c0 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RDP_TriFill, RDP_TriFillZ, RDP_TriTxtr, RDP_TriTxtrZ, RDP_TriShade, RDP_TriShadeZ, RDP_TriShadeTxtr, RDP_TriShadeTxtrZ, //d0 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_GBI2_DL_Count, RSP_GBI2_SubModule, RSP_GBI2_Texture, RSP_GBI2_PopMtx, RSP_GBI2_GeometryMode, RSP_GBI2_Mtx, RSP_GBI2_MoveWord, RSP_GBI2_MoveMem, RSP_GBI1_LoadUCode, RSP_GBI2_DL, RSP_GBI2_EndDL, //e0 RSP_GBI1_SpNoop, RSP_GBI1_RDPHalf_1, RSP_GBI2_SetOtherModeL, RSP_GBI2_SetOtherModeH, DLParser_TexRect, DLParser_TexRectFlip, DLParser_RDPLoadSync, DLParser_RDPPipeSync, DLParser_RDPTileSync, DLParser_RDPFullSync, DLParser_SetKeyGB, DLParser_SetKeyR, DLParser_SetConvert, DLParser_SetScissor, DLParser_SetPrimDepth, DLParser_RDPSetOtherMode, //f0 DLParser_LoadTLut, RSP_RDP_Nothing, DLParser_SetTileSize, DLParser_LoadBlock, DLParser_LoadTile, DLParser_SetTile, DLParser_FillRect, DLParser_SetFillColor, DLParser_SetFogColor, DLParser_SetBlendColor, DLParser_SetPrimColor, DLParser_SetEnvColor, DLParser_SetCombine, DLParser_SetTImg, DLParser_SetZImg, DLParser_SetCImg }; // S2DEX 1.-- UcodeMap ucodeMap7= { RSP_GBI1_SpNoop, RSP_S2DEX_BG_1CYC_2, RSP_S2DEX_BG_COPY, RSP_S2DEX_OBJ_RECTANGLE, RSP_S2DEX_OBJ_SPRITE, RSP_S2DEX_OBJ_MOVEMEM, RSP_GBI0_DL, RSP_GBI1_Reserved, RSP_GBI1_Reserved, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //10 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //20 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //30 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //40 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //50 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //60 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //70 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //80 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //90 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //a0 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_GBI1_LoadUCode, //b0 RSP_S2DEX_SELECT_DL, RSP_S2DEX_OBJ_RENDERMODE_2, RSP_S2DEX_OBJ_RECTANGLE_R, RSP_GBI1_RDPHalf_2, RSP_GBI1_RDPHalf_1, RSP_GBI1_Line3D, RSP_GBI1_ClearGeometryMode, RSP_GBI1_SetGeometryMode, RSP_GBI1_EndDL, RSP_GBI1_SetOtherModeL, RSP_GBI1_SetOtherModeH, RSP_GBI1_Texture, RSP_GBI1_MoveWord, RSP_GBI1_PopMtx, RSP_GBI1_CullDL, RSP_GBI1_Tri1, //c0 RSP_GBI1_Noop, RSP_S2DEX_SPObjLoadTxtr, RSP_S2DEX_SPObjLoadTxSprite, RSP_S2DEX_SPObjLoadTxRect, RSP_S2DEX_SPObjLoadTxRectR, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RDP_TriFill, RDP_TriFillZ, RDP_TriTxtr, RDP_TriTxtrZ, RDP_TriShade, RDP_TriShadeZ, RDP_TriShadeTxtr, RDP_TriShadeTxtrZ, //d0 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //e0 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_S2DEX_RDPHALF_0, DLParser_TexRectFlip, DLParser_RDPLoadSync, DLParser_RDPPipeSync, DLParser_RDPTileSync, DLParser_RDPFullSync, DLParser_SetKeyGB, DLParser_SetKeyR, DLParser_SetConvert, DLParser_SetScissor, DLParser_SetPrimDepth, DLParser_RDPSetOtherMode, //f0 DLParser_LoadTLut, RSP_RDP_Nothing, DLParser_SetTileSize, DLParser_LoadBlock, DLParser_LoadTile, DLParser_SetTile, DLParser_FillRect, DLParser_SetFillColor, DLParser_SetFogColor, DLParser_SetBlendColor, DLParser_SetPrimColor, DLParser_SetEnvColor, DLParser_SetCombine, DLParser_SetTImg, DLParser_SetZImg, DLParser_SetCImg }; // Ucode 3 - S2DEX GBI2 UcodeMap ucodeMap3= { RSP_GBI1_Noop, RSP_S2DEX_OBJ_RECTANGLE, RSP_S2DEX_OBJ_SPRITE, RSP_GBI2_CullDL, RSP_S2DEX_SELECT_DL, RSP_S2DEX_SPObjLoadTxtr, RSP_S2DEX_SPObjLoadTxSprite, RSP_S2DEX_SPObjLoadTxRect, RSP_S2DEX_SPObjLoadTxRectR, RSP_S2DEX_BG_1CYC, RSP_S2DEX_BG_COPY, RSP_S2DEX_OBJ_RENDERMODE, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //10 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //20 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //30 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //40 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //50 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //60 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //70 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //80 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //90 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, //a0 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_GBI1_LoadUCode, //b0 RSP_GBI1_BranchZ, RSP_GBI0_Tri4, RSP_GBI1_ModifyVtx, RSP_GBI1_RDPHalf_2, RSP_GBI1_RDPHalf_1, RSP_GBI1_Line3D, RSP_GBI1_ClearGeometryMode, RSP_GBI1_SetGeometryMode, RSP_GBI1_EndDL, RSP_GBI1_SetOtherModeL, RSP_GBI1_SetOtherModeH, RSP_GBI1_Texture, RSP_GBI1_MoveWord, RSP_GBI1_PopMtx, RSP_GBI1_CullDL, RSP_GBI1_Tri1, //c0 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RDP_TriFill, RDP_TriFillZ, RDP_TriTxtr, RDP_TriTxtrZ, RDP_TriShade, RDP_TriShadeZ, RDP_TriShadeTxtr, RDP_TriShadeTxtrZ, //d0 RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_RDP_Nothing, RSP_GBI2_DL_Count, RSP_GBI2_SubModule, RSP_GBI2_Texture, RSP_GBI2_PopMtx, RSP_GBI2_GeometryMode, RSP_GBI2_Mtx, RSP_GBI2_MoveWord, RSP_GBI2_MoveMem, RSP_GBI1_LoadUCode, RSP_GBI2_DL, RSP_GBI2_EndDL, //e0 RSP_GBI1_SpNoop, RSP_GBI1_RDPHalf_1, RSP_GBI2_SetOtherModeL, RSP_GBI2_SetOtherModeH, DLParser_TexRect, DLParser_TexRectFlip, DLParser_RDPLoadSync, DLParser_RDPPipeSync, DLParser_RDPTileSync, DLParser_RDPFullSync, DLParser_SetKeyGB, DLParser_SetKeyR, DLParser_SetConvert, DLParser_SetScissor, DLParser_SetPrimDepth, DLParser_RDPSetOtherMode, //f0 DLParser_LoadTLut, RSP_RDP_Nothing, DLParser_SetTileSize, DLParser_LoadBlock, DLParser_LoadTile, DLParser_SetTile, DLParser_FillRect, DLParser_SetFillColor, DLParser_SetFogColor, DLParser_SetBlendColor, DLParser_SetPrimColor, DLParser_SetEnvColor, DLParser_SetCombine, DLParser_SetTImg, DLParser_SetZImg, DLParser_SetCImg }; RDPInstruction *currentUcodeMap = ucodeMap1; #endif gles2rice/src/typedefs.h000664 001750 001750 00000020322 12655644434 016360 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _TYPEDEFS_H_ #define _TYPEDEFS_H_ #include #include "osal_preproc.h" #include "VectorMath.h" typedef unsigned int COLOR; typedef struct _COORDRECT { int x1,y1; int x2,y2; } COORDRECT; #define COLOR_RGBA(r,g,b,a) (((r&0xFF)<<16) | ((g&0xFF)<<8) | ((b&0xFF)<<0) | ((a&0xFF)<<24)) #define SURFFMT_A8R8G8B8 21 #define RGBA_GETALPHA(rgb) ((rgb) >> 24) #define RGBA_GETRED(rgb) (((rgb) >> 16) & 0xff) #define RGBA_GETGREEN(rgb) (((rgb) >> 8) & 0xff) #define RGBA_GETBLUE(rgb) ((rgb) & 0xff) typedef XMATRIX Matrix; typedef void* LPRICETEXTURE ; typedef struct { uint32_t dwRGBA, dwRGBACopy; char x,y,z; // Direction uint8_t pad; } N64Light; typedef struct { unsigned int dwFormat:3; unsigned int dwSize:2; unsigned int dwWidth:10; uint32_t dwAddr; uint32_t bpl; } SetImgInfo; typedef struct { // Set by RDP_SetTile unsigned int dwFormat :3; // e.g. RGBA, YUV etc unsigned int dwSize :2; // e.g 4/8/16/32bpp unsigned int dwLine :9; // Ummm... unsigned int dwPalette :4; // 0..15 - a palette index? uint32_t dwTMem; // Texture memory location unsigned int bClampS :1; unsigned int bClampT :1; unsigned int bMirrorS :1; unsigned int bMirrorT :1; unsigned int dwMaskS :4; unsigned int dwMaskT :4; unsigned int dwShiftS :4; unsigned int dwShiftT :4; // Set by RDP_SetTileSize int sl; // Upper left S - 8:3 int tl; // Upper Left T - 8:3 int sh; // Lower Right S int th; // Lower Right T int hilite_sl; int hilite_tl; int hilite_sh; int hilite_th; float fsl; // Upper left S - 8:3 float ftl; // Upper Left T - 8:3 float fsh; // Lower Right S float fth; // Lower Right T float fhilite_sl; float fhilite_tl; float fhilite_sh; float fhilite_th; uint32_t dwDXT; uint32_t dwPitch; uint32_t dwWidth; uint32_t dwHeight; float fShiftScaleS; float fShiftScaleT; uint32_t lastTileCmd; bool bSizeIsValid; bool bForceWrapS; bool bForceWrapT; bool bForceClampS; bool bForceClampT; } Tile; typedef struct { float u; float v; } TexCord; typedef struct VECTOR2 { float x; float y; VECTOR2( float newx, float newy ) {x=newx; y=newy;} VECTOR2() {x=0; y=0;} } VECTOR2; typedef struct { short x; short y; } IVector2; typedef struct { short x; short y; short z; } IVector3; typedef struct { float x,y,z; float rhw; union { COLOR dcDiffuse; struct { uint8_t b; uint8_t g; uint8_t r; uint8_t a; }; }; COLOR dcSpecular; TexCord tcord[2]; } TLITVERTEX, *LPTLITVERTEX; typedef struct { float x,y,z; union { COLOR dcDiffuse; struct { uint8_t b; uint8_t g; uint8_t r; uint8_t a; }; }; COLOR dcSpecular; TexCord tcord[2]; } UTLITVERTEX, *LPUTLITVERTEX; typedef struct { float x,y,z; float rhw; union { COLOR dcDiffuse; struct { uint8_t b; uint8_t g; uint8_t r; uint8_t a; }; }; COLOR dcSpecular; } LITVERTEX, *LPLITVERTEX; typedef struct { float x,y,z; float rhw; COLOR dcDiffuse; } FILLRECTVERTEX, *LPFILLRECTVERTEX; #include "COLOR.h" #include "IColor.h" typedef struct { float x,y,z; float nx,ny,nz; union { COLOR dcDiffuse; struct { uint8_t b; uint8_t g; uint8_t r; uint8_t a; }; }; float u,v; }EXTERNAL_VERTEX, *LPSHADERVERTEX; typedef struct { union { struct { float x; float y; float z; float range; // Range == 0 for directional light // Range != 0 for point light, Zelda MM }; }; union { struct { uint8_t r; uint8_t g; uint8_t b; uint8_t a; }; uint32_t col; }; union { struct { float fr; float fg; float fb; float fa; }; float fcolors[4]; }; union { struct { float tx; float ty; float tz; float tdummy; }; }; union { struct { float ox; float oy; float oz; float odummy; }; }; } Light; typedef struct { char na; char nz; // b char ny; //g char nx; //r }NormalStruct; typedef struct { short y; short x; short flag; short z; short tv; short tu; union { struct { uint8_t a; uint8_t b; uint8_t g; uint8_t r; } rgba; NormalStruct norma; }; } FiddledVtx; typedef struct { short y; short x; uint8_t a; uint8_t b; short z; uint8_t g; uint8_t r; } FiddledVtxDKR; typedef struct { short y; short x; uint16_t cidx; short z; short t; short s; } N64VtxPD; class CTexture; class COGLTexture; class CDirectXTexture; struct TxtrCacheEntry; typedef struct { LPRICETEXTURE m_lpsTexturePtr; union { CTexture * m_pCTexture; CDirectXTexture * m_pCDirectXTexture; COGLTexture * m_pCOGLTexture; }; uint32_t m_dwTileWidth; uint32_t m_dwTileHeight; float m_fTexWidth; float m_fTexHeight; // Float to avoid converts when processing verts TxtrCacheEntry *pTextureEntry; } RenderTexture; typedef struct { unsigned int dwFormat; unsigned int dwSize; unsigned int dwWidth; unsigned int dwAddr; unsigned int dwLastWidth; unsigned int dwLastHeight; unsigned int dwHeight; unsigned int dwMemSize; bool bCopied; unsigned int dwCopiedAtFrame; unsigned int dwCRC; unsigned int lastUsedFrame; unsigned int bUsedByVIAtFrame; unsigned int lastSetAtUcode; } RecentCIInfo; typedef struct { uint32_t addr; uint32_t FrameCount; } RecentViOriginInfo; typedef enum { SHADE_DISABLED, SHADE_FLAT, SHADE_SMOOTH, } RenderShadeMode; typedef enum { TEXTURE_UV_FLAG_WRAP, TEXTURE_UV_FLAG_MIRROR, TEXTURE_UV_FLAG_CLAMP, } TextureUVFlag; typedef struct { TextureUVFlag N64flag; uint32_t realFlag; } UVFlagMap; typedef enum { FILTER_POINT, FILTER_LINEAR, } TextureFilter; typedef struct { TextureFilter N64filter; uint32_t realFilter; } TextureFilterMap; typedef struct { const char* description; int number; uint32_t setting; } BufferSettingInfo; typedef struct { const char* description; uint32_t setting; } SettingInfo; typedef union { uint8_t g_Tmem8bit[0x1000]; short g_Tmem16bit[0x800]; uint32_t g_Tmem32bit[0x300]; uint64_t g_Tmem64bit[0x200]; } TmemType; typedef struct { uint32_t dwFormat; uint32_t dwSize; bool bSetBy; uint32_t dwLoadAddress; uint32_t dwTotalWords; uint32_t dxt; bool bSwapped; uint32_t dwWidth; uint32_t dwLine; int sl; int sh; int tl; int th; uint32_t dwTmem; } TMEMLoadMapInfo; #endif gles2rice/src/Render.h000664 001750 001750 00000022640 12655644434 015761 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _RICE_RENDER_H #define _RICE_RENDER_H #include "Blender.h" #include "Combiner.h" #include "Config.h" #include "Debugger.h" #include "RenderBase.h" #include "RSP_Parser.h" #include "RSP_S2DEX.h" enum TextureChannel { TXT_RGB, TXT_ALPHA, TXT_RGBA, }; class CRender { protected: CRender(); TextureUVFlag TileUFlags[8]; TextureUVFlag TileVFlags[8]; public: float m_fScreenViewportMultX; float m_fScreenViewportMultY; uint32_t m_dwTexturePerspective; bool m_bAlphaTestEnable; bool m_bZUpdate; bool m_bZCompare; uint32_t m_dwZBias; TextureFilter m_dwMinFilter; TextureFilter m_dwMagFilter; uint32_t m_dwAlpha; uint64_t m_Mux; bool m_bBlendModeValid; CColorCombiner *m_pColorCombiner; CBlender *m_pAlphaBlender; virtual ~CRender(); inline bool IsTexel0Enable() {return m_pColorCombiner->m_bTex0Enabled;} inline bool IsTexel1Enable() {return m_pColorCombiner->m_bTex1Enabled;} inline bool IsTextureEnabled() { return (m_pColorCombiner->m_bTex0Enabled||m_pColorCombiner->m_bTex1Enabled); } inline RenderTexture& GetCurrentTexture() { return g_textures[gRSP.curTile]; } inline RenderTexture& GetTexture(uint32_t dwTile) { return g_textures[dwTile]; } void SetViewport(int nLeft, int nTop, int nRight, int nBottom, int maxZ); virtual void SetViewportRender() {} virtual void SetClipRatio(uint32_t type, uint32_t value); virtual void UpdateScissor() {} virtual void ApplyRDPScissor(bool force) {} virtual void UpdateClipRectangle(); virtual void UpdateScissorWithClipRatio(); virtual void ApplyScissorWithClipRatio(bool force) {} void SetTextureEnableAndScale(int dwTile, bool enable, float fScaleX, float fScaleY); virtual void SetFogEnable(bool bEnable) { DEBUGGER_IF_DUMP( (gRSP.bFogEnabled != bEnable && logFog ), TRACE1("Set Fog %s", bEnable? "enable":"disable")); gRSP.bFogEnabled = bEnable; } virtual void SetFogMinMax(float fMin, float fMax) = 0; virtual void TurnFogOnOff(bool flag)=0; virtual void SetFogColor(uint32_t r, uint32_t g, uint32_t b, uint32_t a) { gRDP.fogColor = COLOR_RGBA(r, g, b, a); } uint32_t GetFogColor() { return gRDP.fogColor; } void SetProjection(const Matrix & mat, bool bPush, bool bReplace); void SetWorldView(const Matrix & mat, bool bPush, bool bReplace); inline int GetProjectMatrixLevel(void) { return gRSP.projectionMtxTop; } inline int GetWorldViewMatrixLevel(void) { return gRSP.modelViewMtxTop; } inline void PopProjection() { if (gRSP.projectionMtxTop > 0) gRSP.projectionMtxTop--; else TRACE0("Popping past projection stack limits"); } void PopWorldView(); Matrix & GetWorldProjectMatrix(void); void SetWorldProjectMatrix(Matrix &mtx); void ResetMatrices(); inline RenderShadeMode GetShadeMode() { return gRSP.shadeMode; } void SetVtxTextureCoord(uint32_t dwV, float tu, float tv) { g_fVtxTxtCoords[dwV].x = tu; g_fVtxTxtCoords[dwV].y = tv; } virtual void RenderReset(); virtual void SetCombinerAndBlender(); virtual void SetMux(uint32_t dwMux0, uint32_t dwMux1); virtual void SetCullMode(bool bCullFront, bool bCullBack) { gRSP.bCullFront = bCullFront; gRSP.bCullBack = bCullBack; } virtual void BeginRendering(void) {CRender::gRenderReferenceCount++;} // For DirectX only virtual void EndRendering(void) { if( CRender::gRenderReferenceCount > 0 ) CRender::gRenderReferenceCount--; } virtual void ClearBuffer(bool cbuffer, bool zbuffer)=0; virtual void ClearZBuffer(float depth)=0; virtual void ClearBuffer(bool cbuffer, bool zbuffer, COORDRECT &rect) { ClearBuffer(cbuffer, zbuffer); } virtual void ZBufferEnable(bool bZBuffer)=0; virtual void SetZCompare(bool bZCompare)=0; virtual void SetZUpdate(bool bZUpdate)=0; virtual void SetZBias(int bias)=0; virtual void SetAlphaTestEnable(bool bAlphaTestEnable)=0; void SetTextureFilter(uint32_t dwFilter); virtual void ApplyTextureFilter() {} virtual void SetShadeMode(RenderShadeMode mode)=0; virtual void SetAlphaRef(uint32_t dwAlpha)=0; virtual void ForceAlphaRef(uint32_t dwAlpha)=0; virtual void InitOtherModes(void); void SetVertexTextureUVCoord(TLITVERTEX &v, float fTex0S, float fTex0T, float fTex1S, float fTex1T); void SetVertexTextureUVCoord(TLITVERTEX &v, float fTex0S, float fTex0T); void SetVertexTextureUVCoord(TLITVERTEX &v, const TexCord &fTex0, const TexCord &fTex1); void SetVertexTextureUVCoord(TLITVERTEX &v, const TexCord &fTex0); virtual COLOR PostProcessDiffuseColor(COLOR curDiffuseColor)=0; virtual COLOR PostProcessSpecularColor()=0; bool DrawTriangles(); virtual bool RenderFlushTris()=0; bool TexRect(int nX0, int nY0, int nX1, int nY1, float fS0, float fT0, float fScaleS, float fScaleT, bool colorFlag, uint32_t difcolor); bool TexRectFlip(int nX0, int nY0, int nX1, int nY1, float fS0, float fT0, float fS1, float fT1); bool FillRect(int nX0, int nY0, int nX1, int nY1, uint32_t dwColor); bool Line3D(uint32_t dwV0, uint32_t dwV1, uint32_t dwWidth); virtual void SetAddressUAllStages(uint32_t dwTile, TextureUVFlag dwFlag); // For DirectX only, fix me virtual void SetAddressVAllStages(uint32_t dwTile, TextureUVFlag dwFlag); // For DirectX only, fix me virtual void SetTextureUFlag(TextureUVFlag dwFlag, uint32_t tile)=0; virtual void SetTextureVFlag(TextureUVFlag dwFlag, uint32_t tile)=0; virtual void SetTexelRepeatFlags(uint32_t dwTile); virtual void SetAllTexelRepeatFlag(); virtual bool SetCurrentTexture(int tile, TxtrCacheEntry *pTextureEntry)=0; virtual bool SetCurrentTexture(int tile, CTexture *handler, uint32_t dwTileWidth, uint32_t dwTileHeight, TxtrCacheEntry *pTextureEntry) = 0; virtual bool InitDeviceObjects()=0; virtual bool ClearDeviceObjects()=0; virtual void Initialize(void); virtual void CleanUp(void); virtual void SetFillMode(FillMode mode)=0; void LoadSprite2D(Sprite2DInfo &info, uint32_t ucode); void LoadObjBGCopy(uObjBg &info); void LoadObjBG1CYC(uObjScaleBg &info); void LoadObjSprite(uObjTxSprite &info, bool useTIAddr); void LoadFrameBuffer(bool useVIreg, uint32_t left, uint32_t top, uint32_t width, uint32_t height); void LoadTextureFromMemory(void *buf, uint32_t left, uint32_t top, uint32_t width, uint32_t height, uint32_t pitch, uint32_t format); void LoadTxtrBufIntoTexture(void); void DrawSprite2D(Sprite2DInfo &info, uint32_t ucode); void DrawSpriteR(uObjTxSprite &sprite, bool initCombiner, uint32_t tile, uint32_t left, uint32_t top, uint32_t width, uint32_t height); void DrawSprite(uObjTxSprite &sprite, bool rectR); void DrawObjBGCopy(uObjBg &info); virtual void DrawSpriteR_Render(){}; virtual void DrawSimple2DTexture(float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, COLOR dif, COLOR spe, float z, float rhw)=0; void DrawFrameBuffer(bool useVIreg, uint32_t left, uint32_t top, uint32_t width, uint32_t height); void DrawObjBG1CYC(uObjScaleBg &bg, bool scaled); static CRender * g_pRender; static int gRenderReferenceCount; static CRender * GetRender(void); static bool IsAvailable(); protected: bool m_savedZBufferFlag; uint32_t m_savedMinFilter; uint32_t m_savedMagFilter; // FillRect virtual bool RenderFillRect(uint32_t dwColor, float depth)=0; VECTOR2 m_fillRectVtx[2]; // Line3D virtual bool RenderLine3D()=0; LITVERTEX m_line3DVtx[2]; VECTOR2 m_line3DVector[4]; // TexRect virtual bool RenderTexRect()=0; TexCord m_texRectTex1UV[2]; TexCord m_texRectTex2UV[2]; // DrawSimple2DTexture virtual void StartDrawSimple2DTexture(float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, COLOR dif, COLOR spe, float z, float rhw); // DrawSimpleRect virtual void StartDrawSimpleRect(int nX0, int nY0, int nX1, int nY1, uint32_t dwColor, float depth, float rhw); VECTOR2 m_simpleRectVtx[2]; bool RemapTextureCoordinate(float s0, float s1, uint32_t tileWidth, uint32_t mask, float textureWidth, float &u0, float &u1); }; #define ffloor(a) (((int(a))<=(a))?(float)(int(a)):((float)(int(a))-1)) bool SaveRGBBufferToFile(char *filename, unsigned char *buf, int width, int height, int pitch); bool SaveRGBABufferToPNGFile(char *filename, unsigned char *buf, int width, int height, int pitch); #endif //_RICE_RENDER_H mupen64plus-video-gliden64/src/gSP.cpp000664 001750 001750 00000215006 12655644434 020627 0ustar00sergiosergio000000 000000 #include #include #include #include #include "N64.h" #include "GLideN64.h" #include "Debug.h" #include "Types.h" #include "RSP.h" #include "GBI.h" #include "gSP.h" #include "gDP.h" #include "3DMath.h" #include "OpenGL.h" #include "CRC.h" #include #include "convert.h" #include "S2DEX.h" #include "VI.h" #include "FrameBuffer.h" #include "DepthBuffer.h" #include "Config.h" #include "Log.h" using namespace std; inline void gSPFlushTriangles() { if ((gSP.geometryMode & G_SHADING_SMOOTH) == 0) { video().getRender().drawTriangles(); return; } if ( (RSP.nextCmd != G_TRI1) && (RSP.nextCmd != G_TRI2) && (RSP.nextCmd != G_TRI4) && (RSP.nextCmd != G_QUAD) ) video().getRender().drawTriangles(); } void gSPCombineMatrices() { MultMatrix(gSP.matrix.projection, gSP.matrix.modelView[gSP.matrix.modelViewi], gSP.matrix.combined); gSP.changed &= ~CHANGED_MATRIX; } void gSPTriangle(s32 v0, s32 v1, s32 v2) { OGLRender & render = video().getRender(); if ((v0 < INDEXMAP_SIZE) && (v1 < INDEXMAP_SIZE) && (v2 < INDEXMAP_SIZE)) { if (render.isClipped(v0, v1, v2)) return; render.addTriangle(v0, v1, v2); if (config.frameBufferEmulation.N64DepthCompare != 0) render.drawTriangles(); } frameBufferList().setBufferChanged(); gDP.colorImage.height = (u32)max( gDP.colorImage.height, (u32)gDP.scissor.lry ); } void gSP1Triangle( const s32 v0, const s32 v1, const s32 v2) { gSPTriangle( v0, v1, v2); gSPFlushTriangles(); } void gSP2Triangles(const s32 v00, const s32 v01, const s32 v02, const s32 flag0, const s32 v10, const s32 v11, const s32 v12, const s32 flag1 ) { gSPTriangle( v00, v01, v02); gSPTriangle( v10, v11, v12); gSPFlushTriangles(); } void gSP4Triangles(const s32 v00, const s32 v01, const s32 v02, const s32 v10, const s32 v11, const s32 v12, const s32 v20, const s32 v21, const s32 v22, const s32 v30, const s32 v31, const s32 v32 ) { gSPTriangle(v00, v01, v02); gSPTriangle(v10, v11, v12); gSPTriangle(v20, v21, v22); gSPTriangle(v30, v31, v32); gSPFlushTriangles(); } gSPInfo gSP; f32 identityMatrix[4][4] = { { 1.0f, 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 0.0f, 1.0f } }; #ifdef __VEC4_OPT static void gSPTransformVertex4_default(u32 v, float mtx[4][4]) { float x, y, z, w; OGLRender & render = video().getRender(); for (int i = 0; i < 4; ++i) { SPVertex & vtx = render.getVertex(v+i); x = vtx.x; y = vtx.y; z = vtx.z; w = vtx.w; vtx.x = x * mtx[0][0] + y * mtx[1][0] + z * mtx[2][0] + mtx[3][0]; vtx.y = x * mtx[0][1] + y * mtx[1][1] + z * mtx[2][1] + mtx[3][1]; vtx.z = x * mtx[0][2] + y * mtx[1][2] + z * mtx[2][2] + mtx[3][2]; vtx.w = x * mtx[0][3] + y * mtx[1][3] + z * mtx[2][3] + mtx[3][3]; } } static void gSPTransformNormal4_default(u32 v, float mtx[4][4]) { float len, x, y, z; OGLRender & render = video().getRender(); for (int i = 0; i < 4; ++i) { SPVertex & vtx = render.getVertex(v+i); x = vtx.nx; y = vtx.ny; z = vtx.nz; vtx.nx = mtx[0][0]*x + mtx[1][0]*y + mtx[2][0]*z; vtx.ny = mtx[0][1]*x + mtx[1][1]*y + mtx[2][1]*z; vtx.nz = mtx[0][2]*x + mtx[1][2]*y + mtx[2][2]*z; len = vtx.nx*vtx.nx + vtx.ny*vtx.ny + vtx.nz*vtx.nz; if (len != 0.0f) { len = sqrtf(len); vtx.nx /= len; vtx.ny /= len; vtx.nz /= len; } } } static void gSPLightVertex4_default(u32 v) { gSPTransformNormal4(v, gSP.matrix.modelView[gSP.matrix.modelViewi]); OGLRender & render = video().getRender(); if (!config.generalEmulation.enableHWLighting) { for(int j = 0; j < 4; ++j) { SPVertex & vtx = render.getVertex(v+j); vtx.r = gSP.lights[gSP.numLights].r; vtx.g = gSP.lights[gSP.numLights].g; vtx.b = gSP.lights[gSP.numLights].b; vtx.HWLight = 0; for (int i = 0; i < gSP.numLights; ++i) { f32 intensity = DotProduct( &vtx.nx, &gSP.lights[i].x ); if (intensity < 0.0f) intensity = 0.0f; vtx.r += gSP.lights[i].r * intensity; vtx.g += gSP.lights[i].g * intensity; vtx.b += gSP.lights[i].b * intensity; } vtx.r = min(1.0f, vtx.r); vtx.g = min(1.0f, vtx.g); vtx.b = min(1.0f, vtx.b); } } else { for(int j = 0; j < 4; ++j) { SPVertex & vtx = render.getVertex(v+j); vtx.HWLight = gSP.numLights; vtx.r = vtx.nx; vtx.g = vtx.ny; vtx.b = vtx.nz; } } } static void gSPPointLightVertex4_default(u32 v, float _vPos[4][3]) { assert(_vPos != NULL); gSPTransformNormal4(v, gSP.matrix.modelView[gSP.matrix.modelViewi]); OGLRender & render = video().getRender(); for(int j = 0; j < 4; ++j) { SPVertex & vtx = render.getVertex(v+j); float light_intensity = 0.0f; vtx.HWLight = 0; vtx.r = gSP.lights[gSP.numLights].r; vtx.g = gSP.lights[gSP.numLights].g; vtx.b = gSP.lights[gSP.numLights].b; for (u32 l=0; l < gSP.numLights; ++l) { float lvec[3] = {gSP.lights[l].posx, gSP.lights[l].posy, gSP.lights[l].posz}; lvec[0] -= _vPos[j][0]; lvec[1] -= _vPos[j][1]; lvec[2] -= _vPos[j][2]; const float light_len2 = lvec[0]*lvec[0] + lvec[1]*lvec[1] + lvec[2]*lvec[2]; const float light_len = sqrtf(light_len2); const float at = gSP.lights[l].ca + light_len/65535.0f*gSP.lights[l].la + light_len2/65535.0f*gSP.lights[l].qa; if (at > 0.0f) light_intensity = 1/at; else light_intensity = 0.0f; if (light_intensity > 0.0f) { vtx.r += gSP.lights[l].r * light_intensity; vtx.g += gSP.lights[l].g * light_intensity; vtx.b += gSP.lights[l].b * light_intensity; } } if (vtx.r > 1.0f) vtx.r = 1.0f; if (vtx.g > 1.0f) vtx.g = 1.0f; if (vtx.b > 1.0f) vtx.b = 1.0f; } } static void gSPLightVertex4_CBFD(u32 v) { gSPTransformNormal4(v, gSP.matrix.modelView[gSP.matrix.modelViewi]); OGLRender & render = video().getRender(); for(int j = 0; j < 4; ++j) { SPVertex & vtx = render.getVertex(v+j); f32 r = gSP.lights[gSP.numLights].r; f32 g = gSP.lights[gSP.numLights].g; f32 b = gSP.lights[gSP.numLights].b; for (u32 l = 0; l < gSP.numLights; ++l) { const SPLight & light = gSP.lights[l]; const f32 vx = (vtx.x + gSP.vertexCoordMod[ 8])*gSP.vertexCoordMod[12] - light.posx; const f32 vy = (vtx.y + gSP.vertexCoordMod[ 9])*gSP.vertexCoordMod[13] - light.posy; const f32 vz = (vtx.z + gSP.vertexCoordMod[10])*gSP.vertexCoordMod[14] - light.posz; const f32 vw = (vtx.w + gSP.vertexCoordMod[11])*gSP.vertexCoordMod[15] - light.posw; const f32 len = (vx*vx+vy*vy+vz*vz+vw*vw)/65536.0f; f32 intensity = light.ca / len; if (intensity > 1.0f) intensity = 1.0f; r += light.r * intensity; g += light.g * intensity; b += light.b * intensity; } r = min(1.0f, r); g = min(1.0f, g); b = min(1.0f, b); vtx.r *= r; vtx.g *= g; vtx.b *= b; vtx.HWLight = 0; } } static void gSPPointLightVertex4_CBFD(u32 v, float _vPos[4][3]) { gSPTransformNormal4(v, gSP.matrix.modelView[gSP.matrix.modelViewi]); OGLRender & render = video().getRender(); for(int j = 0; j < 4; ++j) { SPVertex & vtx = render.getVertex(v+j); f32 r = gSP.lights[gSP.numLights].r; f32 g = gSP.lights[gSP.numLights].g; f32 b = gSP.lights[gSP.numLights].b; f32 intensity = 0.0f; for (u32 l = 0; l < gSP.numLights-1; ++l) { const SPLight & light = gSP.lights[l]; intensity = DotProduct( &vtx.nx, &light.x ); if (intensity < 0.0f) continue; if (light.ca > 0.0f) { const f32 vx = (vtx.x + gSP.vertexCoordMod[ 8])*gSP.vertexCoordMod[12] - light.posx; const f32 vy = (vtx.y + gSP.vertexCoordMod[ 9])*gSP.vertexCoordMod[13] - light.posy; const f32 vz = (vtx.z + gSP.vertexCoordMod[10])*gSP.vertexCoordMod[14] - light.posz; const f32 vw = (vtx.w + gSP.vertexCoordMod[11])*gSP.vertexCoordMod[15] - light.posw; const f32 len = (vx*vx+vy*vy+vz*vz+vw*vw)/65536.0f; float p_i = light.ca / len; if (p_i > 1.0f) p_i = 1.0f; intensity *= p_i; } r += light.r * intensity; g += light.g * intensity; b += light.b * intensity; } const SPLight & light = gSP.lights[gSP.numLights-1]; intensity = DotProduct( &vtx.nx, &light.x ); if (intensity > 0.0f) { r += light.r * intensity; g += light.g * intensity; b += light.b * intensity; } r = min(1.0f, r); g = min(1.0f, g); b = min(1.0f, b); vtx.r *= r; vtx.g *= g; vtx.b *= b; vtx.HWLight = 0; } } static void gSPBillboardVertex4_default(u32 v) { OGLRender & render = video().getRender(); int i = 0; SPVertex & vtx0 = render.getVertex(i); for (int j = 0; j < 4; ++j) { SPVertex & vtx = render.getVertex(v+j); vtx.x = vtx0.x; vtx.y = vtx0.y; vtx.z = vtx0.z; vtx.w = vtx0.w; } } void gSPClipVertex4(u32 v) { OGLRender & render = video().getRender(); for(int i = 0; i < 4; ++i) { SPVertex & vtx = render.getVertex(v+i); vtx.clip = 0; if (vtx.x > +vtx.w) vtx.clip |= CLIP_POSX; if (vtx.x < -vtx.w) vtx.clip |= CLIP_NEGX; if (vtx.y > +vtx.w) vtx.clip |= CLIP_POSY; if (vtx.y < -vtx.w) vtx.clip |= CLIP_NEGY; if (vtx.w < 0.01f) vtx.clip |= CLIP_Z; } } void gSPProcessVertex4(u32 v) { if (gSP.changed & CHANGED_MATRIX) gSPCombineMatrices(); OGLRender & render = video().getRender(); float vPos[4][3]; for(int i = 0; i < 4; ++i) { SPVertex & vtx = render.getVertex(v+i); vPos[i][0] = vtx.x; vPos[i][1] = vtx.y; vPos[i][2] = vtx.z; } gSPTransformVertex4(v, gSP.matrix.combined ); if (gSP.viewport.vscale[0] < 0) { for(int i = 0; i < 4; ++i) { SPVertex & vtx = render.getVertex(v+i); vtx.x = -vtx.x; } } if (gSP.matrix.billboard) gSPBillboardVertex4(v); if (gSP.geometryMode & G_LIGHTING) { if (gSP.geometryMode & G_POINT_LIGHTING) gSPPointLightVertex4(v, vPos); else gSPLightVertex4(v); if (GBI.isTextureGen() && gSP.geometryMode & G_TEXTURE_GEN) { for(int i = 0; i < 4; ++i) { SPVertex & vtx = render.getVertex(v+i); f32 fLightDir[3] = {vtx.nx, vtx.ny, vtx.nz}; f32 x, y; if (gSP.lookatEnable) { x = DotProduct(&gSP.lookat[0].x, fLightDir); y = DotProduct(&gSP.lookat[1].x, fLightDir); } else { x = fLightDir[0]; y = fLightDir[1]; } if (gSP.geometryMode & G_TEXTURE_GEN_LINEAR) { vtx.s = acosf(x) * 325.94931f; vtx.t = acosf(y) * 325.94931f; } else { // G_TEXTURE_GEN vtx.s = (x + 1.0f) * 512.0f; vtx.t = (y + 1.0f) * 512.0f; } } } } else { for(int i = 0; i < 4; ++i) render.getVertex(v+i).HWLight = 0; } gSPClipVertex4(v); } #endif static void gSPTransformVertex_default(float vtx[4], float mtx[4][4]) { float x, y, z, w; x = vtx[0]; y = vtx[1]; z = vtx[2]; w = vtx[3]; vtx[0] = x * mtx[0][0] + y * mtx[1][0] + z * mtx[2][0] + mtx[3][0]; vtx[1] = x * mtx[0][1] + y * mtx[1][1] + z * mtx[2][1] + mtx[3][1]; vtx[2] = x * mtx[0][2] + y * mtx[1][2] + z * mtx[2][2] + mtx[3][2]; vtx[3] = x * mtx[0][3] + y * mtx[1][3] + z * mtx[2][3] + mtx[3][3]; } static void gSPLightVertex_default(SPVertex & _vtx) { if (!config.generalEmulation.enableHWLighting) { _vtx.HWLight = 0; _vtx.r = gSP.lights[gSP.numLights].r; _vtx.g = gSP.lights[gSP.numLights].g; _vtx.b = gSP.lights[gSP.numLights].b; for (int i = 0; i < gSP.numLights; ++i){ f32 intensity = DotProduct( &_vtx.nx, &gSP.lights[i].x ); if (intensity < 0.0f) intensity = 0.0f; _vtx.r += gSP.lights[i].r * intensity; _vtx.g += gSP.lights[i].g * intensity; _vtx.b += gSP.lights[i].b * intensity; } _vtx.r = min(1.0f, _vtx.r); _vtx.g = min(1.0f, _vtx.g); _vtx.b = min(1.0f, _vtx.b); } else { _vtx.HWLight = gSP.numLights; _vtx.r = _vtx.nx; _vtx.g = _vtx.ny; _vtx.b = _vtx.nz; } } static void gSPPointLightVertex_default(SPVertex & _vtx, float * _vPos) { assert(_vPos != NULL); float light_intensity = 0.0f; _vtx.HWLight = 0; _vtx.r = gSP.lights[gSP.numLights].r; _vtx.g = gSP.lights[gSP.numLights].g; _vtx.b = gSP.lights[gSP.numLights].b; for (u32 l=0; l < gSP.numLights; ++l) { float lvec[3] = {gSP.lights[l].posx, gSP.lights[l].posy, gSP.lights[l].posz}; lvec[0] -= _vPos[0]; lvec[1] -= _vPos[1]; lvec[2] -= _vPos[2]; const float light_len2 = lvec[0]*lvec[0] + lvec[1]*lvec[1] + lvec[2]*lvec[2]; const float light_len = sqrtf(light_len2); const float at = gSP.lights[l].ca + light_len/65535.0f*gSP.lights[l].la + light_len2/65535.0f*gSP.lights[l].qa; if (at > 0.0f) light_intensity = 1/at;//DotProduct (lvec, nvec) / (light_len * normal_len * at); else light_intensity = 0.0f; if (light_intensity > 0.0f) { _vtx.r += gSP.lights[l].r * light_intensity; _vtx.g += gSP.lights[l].g * light_intensity; _vtx.b += gSP.lights[l].b * light_intensity; } } if (_vtx.r > 1.0f) _vtx.r = 1.0f; if (_vtx.g > 1.0f) _vtx.g = 1.0f; if (_vtx.b > 1.0f) _vtx.b = 1.0f; } static void gSPLightVertex_CBFD(SPVertex & _vtx) { f32 r = gSP.lights[gSP.numLights].r; f32 g = gSP.lights[gSP.numLights].g; f32 b = gSP.lights[gSP.numLights].b; for (u32 l = 0; l < gSP.numLights; ++l) { const SPLight & light = gSP.lights[l]; const f32 vx = (_vtx.x + gSP.vertexCoordMod[ 8])*gSP.vertexCoordMod[12] - light.posx; const f32 vy = (_vtx.y + gSP.vertexCoordMod[ 9])*gSP.vertexCoordMod[13] - light.posy; const f32 vz = (_vtx.z + gSP.vertexCoordMod[10])*gSP.vertexCoordMod[14] - light.posz; const f32 vw = (_vtx.w + gSP.vertexCoordMod[11])*gSP.vertexCoordMod[15] - light.posw; const f32 len = (vx*vx+vy*vy+vz*vz+vw*vw)/65536.0f; f32 intensity = light.ca / len; if (intensity > 1.0f) intensity = 1.0f; r += light.r * intensity; g += light.g * intensity; b += light.b * intensity; } r = min(1.0f, r); g = min(1.0f, g); b = min(1.0f, b); _vtx.r *= r; _vtx.g *= g; _vtx.b *= b; _vtx.HWLight = 0; } static void gSPPointLightVertex_CBFD(SPVertex & _vtx, float * /*_vPos*/) { f32 r = gSP.lights[gSP.numLights].r; f32 g = gSP.lights[gSP.numLights].g; f32 b = gSP.lights[gSP.numLights].b; f32 intensity = 0.0f; for (u32 l = 0; l < gSP.numLights-1; ++l) { const SPLight & light = gSP.lights[l]; intensity = DotProduct( &_vtx.nx, &light.x ); if (intensity < 0.0f) continue; if (light.ca > 0.0f) { const f32 vx = (_vtx.x + gSP.vertexCoordMod[ 8])*gSP.vertexCoordMod[12] - light.posx; const f32 vy = (_vtx.y + gSP.vertexCoordMod[ 9])*gSP.vertexCoordMod[13] - light.posy; const f32 vz = (_vtx.z + gSP.vertexCoordMod[10])*gSP.vertexCoordMod[14] - light.posz; const f32 vw = (_vtx.w + gSP.vertexCoordMod[11])*gSP.vertexCoordMod[15] - light.posw; const f32 len = (vx*vx+vy*vy+vz*vz+vw*vw)/65536.0f; float p_i = light.ca / len; if (p_i > 1.0f) p_i = 1.0f; intensity *= p_i; } r += light.r * intensity; g += light.g * intensity; b += light.b * intensity; } const SPLight & light = gSP.lights[gSP.numLights-1]; intensity = DotProduct( &_vtx.nx, &light.x ); if (intensity > 0.0f) { r += light.r * intensity; g += light.g * intensity; b += light.b * intensity; } r = min(1.0f, r); g = min(1.0f, g); b = min(1.0f, b); _vtx.r *= r; _vtx.g *= g; _vtx.b *= b; _vtx.HWLight = 0; } static void gSPBillboardVertex_default(u32 v, u32 i) { OGLRender & render = video().getRender(); SPVertex & vtx0 = render.getVertex(i); SPVertex & vtx = render.getVertex(v); vtx.x += vtx0.x; vtx.y += vtx0.y; vtx.z += vtx0.z; vtx.w += vtx0.w; } void gSPClipVertex(u32 v) { SPVertex & vtx = video().getRender().getVertex(v); vtx.clip = 0; if (vtx.x > +vtx.w) vtx.clip |= CLIP_POSX; if (vtx.x < -vtx.w) vtx.clip |= CLIP_NEGX; if (vtx.y > +vtx.w) vtx.clip |= CLIP_POSY; if (vtx.y < -vtx.w) vtx.clip |= CLIP_NEGY; if (vtx.w < 0.01f) vtx.clip |= CLIP_Z; } void gSPProcessVertex(u32 v) { if (gSP.changed & CHANGED_MATRIX) gSPCombineMatrices(); OGLVideo & ogl = video(); OGLRender & render = ogl.getRender(); SPVertex & vtx = render.getVertex(v); float vPos[3] = {(float)vtx.x, (float)vtx.y, (float)vtx.z}; gSPTransformVertex( &vtx.x, gSP.matrix.combined ); if (ogl.isAdjustScreen() && (gDP.colorImage.width > VI.width * 98 / 100)) { vtx.x *= ogl.getAdjustScale(); if (gSP.matrix.projection[3][2] == -1.f) vtx.w *= ogl.getAdjustScale(); } if (gSP.viewport.vscale[0] < 0) vtx.x = -vtx.x; if (gSP.matrix.billboard) { int i = 0; gSPBillboardVertex(v, i); } gSPClipVertex(v); if (gSP.geometryMode & G_LIGHTING) { TransformVectorNormalize( &vtx.nx, gSP.matrix.modelView[gSP.matrix.modelViewi] ); if (gSP.geometryMode & G_POINT_LIGHTING) gSPPointLightVertex(vtx, vPos); else gSPLightVertex(vtx); if (GBI.isTextureGen() && (gSP.geometryMode & G_TEXTURE_GEN) != 0) { f32 fLightDir[3] = {vtx.nx, vtx.ny, vtx.nz}; f32 x, y; if (gSP.lookatEnable) { x = DotProduct(&gSP.lookat[0].x, fLightDir); y = DotProduct(&gSP.lookat[1].x, fLightDir); } else { x = fLightDir[0]; y = fLightDir[1]; } if (gSP.geometryMode & G_TEXTURE_GEN_LINEAR) { vtx.s = acosf(x) * 325.94931f; vtx.t = acosf(y) * 325.94931f; } else { // G_TEXTURE_GEN vtx.s = (x + 1.0f) * 512.0f; vtx.t = (y + 1.0f) * 512.0f; } } } else vtx.HWLight = 0; } void gSPLoadUcodeEx( u32 uc_start, u32 uc_dstart, u16 uc_dsize ) { gSP.matrix.modelViewi = 0; gSP.changed |= CHANGED_MATRIX; gSP.status[0] = gSP.status[1] = gSP.status[2] = gSP.status[3] = 0; if ((((uc_start & 0x1FFFFFFF) + 4096) > RDRAMSize) || (((uc_dstart & 0x1FFFFFFF) + uc_dsize) > RDRAMSize)) return; GBI.loadMicrocode(uc_start, uc_dstart, uc_dsize); RSP.uc_start = uc_start; RSP.uc_dstart = uc_dstart; } void gSPNoOp() { gSPFlushTriangles(); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_IGNORED, "gSPNoOp();\n" ); #endif } void gSPMatrix( u32 matrix, u8 param ) { f32 mtx[4][4]; u32 address = RSP_SegmentToPhysical( matrix ); if (address + 64 > RDRAMSize) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR | DEBUG_MATRIX, "// Attempting to load matrix from invalid address\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_MATRIX, "gSPMatrix( 0x%08X, %s | %s | %s );\n", matrix, (param & G_MTX_PROJECTION) ? "G_MTX_PROJECTION" : "G_MTX_MODELVIEW", (param & G_MTX_LOAD) ? "G_MTX_LOAD" : "G_MTX_MUL", (param & G_MTX_PUSH) ? "G_MTX_PUSH" : "G_MTX_NOPUSH" ); #endif return; } RSP_LoadMatrix( mtx, address ); if (param & G_MTX_PROJECTION) { if (param & G_MTX_LOAD) CopyMatrix( gSP.matrix.projection, mtx ); else MultMatrix2( gSP.matrix.projection, mtx ); } else { if ((param & G_MTX_PUSH) && (gSP.matrix.modelViewi < (gSP.matrix.stackSize))) { CopyMatrix( gSP.matrix.modelView[gSP.matrix.modelViewi + 1], gSP.matrix.modelView[gSP.matrix.modelViewi] ); gSP.matrix.modelViewi++; } #ifdef DEBUG else DebugMsg( DEBUG_ERROR | DEBUG_MATRIX, "// Modelview stack overflow\n" ); #endif if (param & G_MTX_LOAD) CopyMatrix( gSP.matrix.modelView[gSP.matrix.modelViewi], mtx ); else MultMatrix2( gSP.matrix.modelView[gSP.matrix.modelViewi], mtx ); } gSP.changed |= CHANGED_MATRIX; #ifdef DEBUG DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED | DEBUG_MATRIX, "// %12.6f %12.6f %12.6f %12.6f\n", mtx[0][0], mtx[0][1], mtx[0][2], mtx[0][3] ); DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED | DEBUG_MATRIX, "// %12.6f %12.6f %12.6f %12.6f\n", mtx[1][0], mtx[1][1], mtx[1][2], mtx[1][3] ); DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED | DEBUG_MATRIX, "// %12.6f %12.6f %12.6f %12.6f\n", mtx[2][0], mtx[2][1], mtx[2][2], mtx[2][3] ); DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED | DEBUG_MATRIX, "// %12.6f %12.6f %12.6f %12.6f\n", mtx[3][0], mtx[3][1], mtx[3][2], mtx[3][3] ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_MATRIX, "gSPMatrix( 0x%08X, %s | %s | %s );\n", matrix, (param & G_MTX_PROJECTION) ? "G_MTX_PROJECTION" : "G_MTX_MODELVIEW", (param & G_MTX_LOAD) ? "G_MTX_LOAD" : "G_MTX_MUL", (param & G_MTX_PUSH) ? "G_MTX_PUSH" : "G_MTX_NOPUSH" ); #endif } void gSPDMAMatrix( u32 matrix, u8 index, u8 multiply ) { f32 mtx[4][4]; u32 address = gSP.DMAOffsets.mtx + RSP_SegmentToPhysical( matrix ); if (address + 64 > RDRAMSize) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR | DEBUG_MATRIX, "// Attempting to load matrix from invalid address\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_MATRIX, "gSPDMAMatrix( 0x%08X, %i, %s );\n", matrix, index, multiply ? "TRUE" : "FALSE" ); #endif return; } RSP_LoadMatrix(mtx, address); gSP.matrix.modelViewi = index; if (multiply) MultMatrix(gSP.matrix.modelView[0], mtx, gSP.matrix.modelView[gSP.matrix.modelViewi]); else CopyMatrix( gSP.matrix.modelView[gSP.matrix.modelViewi], mtx ); CopyMatrix( gSP.matrix.projection, identityMatrix ); gSP.changed |= CHANGED_MATRIX; #ifdef DEBUG DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED | DEBUG_MATRIX, "// %12.6f %12.6f %12.6f %12.6f\n", mtx[0][0], mtx[0][1], mtx[0][2], mtx[0][3] ); DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED | DEBUG_MATRIX, "// %12.6f %12.6f %12.6f %12.6f\n", mtx[1][0], mtx[1][1], mtx[1][2], mtx[1][3] ); DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED | DEBUG_MATRIX, "// %12.6f %12.6f %12.6f %12.6f\n", mtx[2][0], mtx[2][1], mtx[2][2], mtx[2][3] ); DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED | DEBUG_MATRIX, "// %12.6f %12.6f %12.6f %12.6f\n", mtx[3][0], mtx[3][1], mtx[3][2], mtx[3][3] ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_MATRIX, "gSPDMAMatrix( 0x%08X, %i, %s );\n", matrix, index, multiply ? "TRUE" : "FALSE" ); #endif } void gSPViewport( u32 v ) { u32 address = RSP_SegmentToPhysical( v ); if ((address + 16) > RDRAMSize) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR, "// Attempting to load viewport from invalid address\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPViewport( 0x%08X );\n", v ); #endif return; } gSP.viewport.vscale[0] = _FIXED2FLOAT( *(s16*)&gfx_info.RDRAM[address + 2], 2 ); gSP.viewport.vscale[1] = _FIXED2FLOAT( *(s16*)&gfx_info.RDRAM[address ], 2 ); gSP.viewport.vscale[2] = _FIXED2FLOAT( *(s16*)&gfx_info.RDRAM[address + 6], 10 );// * 0.00097847357f; gSP.viewport.vscale[3] = *(s16*)&gfx_info.RDRAM[address + 4]; gSP.viewport.vtrans[0] = _FIXED2FLOAT( *(s16*)&gfx_info.RDRAM[address + 10], 2 ); gSP.viewport.vtrans[1] = _FIXED2FLOAT( *(s16*)&gfx_info.RDRAM[address + 8], 2 ); gSP.viewport.vtrans[2] = _FIXED2FLOAT( *(s16*)&gfx_info.RDRAM[address + 14], 10 );// * 0.00097847357f; gSP.viewport.vtrans[3] = *(s16*)&gfx_info.RDRAM[address + 12]; gSP.viewport.x = gSP.viewport.vtrans[0] - gSP.viewport.vscale[0]; gSP.viewport.y = gSP.viewport.vtrans[1] - gSP.viewport.vscale[1]; gSP.viewport.width = fabs(gSP.viewport.vscale[0]) * 2; gSP.viewport.height = fabs(gSP.viewport.vscale[1] * 2); gSP.viewport.nearz = gSP.viewport.vtrans[2] - gSP.viewport.vscale[2]; gSP.viewport.farz = (gSP.viewport.vtrans[2] + gSP.viewport.vscale[2]) ; gSP.changed |= CHANGED_VIEWPORT; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPViewport( 0x%08X );\n", v ); #endif } void gSPForceMatrix( u32 mptr ) { u32 address = RSP_SegmentToPhysical( mptr ); if (address + 64 > RDRAMSize) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR | DEBUG_MATRIX, "// Attempting to load from invalid address" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_MATRIX, "gSPForceMatrix( 0x%08X );\n", mptr ); #endif return; } RSP_LoadMatrix(gSP.matrix.combined, address); gSP.changed &= ~CHANGED_MATRIX; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_MATRIX, "gSPForceMatrix( 0x%08X );\n", mptr ); #endif } void gSPLight( u32 l, s32 n ) { --n; u32 addrByte = RSP_SegmentToPhysical( l ); if ((addrByte + sizeof( Light )) > RDRAMSize) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR, "// Attempting to load light from invalid address\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPLight( 0x%08X, LIGHT_%i );\n", l, n ); #endif return; } Light *light = (Light*)&RDRAM[addrByte]; if (n < 8) { gSP.lights[n].r = light->r * 0.0039215689f; gSP.lights[n].g = light->g * 0.0039215689f; gSP.lights[n].b = light->b * 0.0039215689f; gSP.lights[n].x = light->x; gSP.lights[n].y = light->y; gSP.lights[n].z = light->z; Normalize( &gSP.lights[n].x ); u32 addrShort = addrByte >> 1; gSP.lights[n].posx = (float)(((short*)gfx_info.RDRAM)[(addrShort+4)^1]); gSP.lights[n].posy = (float)(((short*)gfx_info.RDRAM)[(addrShort+5)^1]); gSP.lights[n].posz = (float)(((short*)gfx_info.RDRAM)[(addrShort+6)^1]); gSP.lights[n].ca = (float)(gfx_info.RDRAM[(addrByte + 3) ^ 3]) / 16.0f; gSP.lights[n].la = (float)(gfx_info.RDRAM[(addrByte + 7) ^ 3]); gSP.lights[n].qa = (float)(gfx_info.RDRAM[(addrByte + 14) ^ 3]) / 8.0f; } if (config.generalEmulation.enableHWLighting != 0) gSP.changed |= CHANGED_LIGHT; #ifdef DEBUG DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED, "// x = %2.6f y = %2.6f z = %2.6f\n", _FIXED2FLOAT( light->x, 7 ), _FIXED2FLOAT( light->y, 7 ), _FIXED2FLOAT( light->z, 7 ) ); DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED, "// r = %3i g = %3i b = %3i\n", light->r, light->g, light->b ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPLight( 0x%08X, LIGHT_%i );\n", l, n ); #endif } void gSPLightCBFD( u32 l, s32 n ) { u32 addrByte = RSP_SegmentToPhysical( l ); if ((addrByte + sizeof( Light )) > RDRAMSize) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR, "// Attempting to load light from invalid address\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPLight( 0x%08X, LIGHT_%i );\n", l, n ); #endif return; } Light *light = (Light*)&RDRAM[addrByte]; if (n < 12) { gSP.lights[n].r = light->r * 0.0039215689f; gSP.lights[n].g = light->g * 0.0039215689f; gSP.lights[n].b = light->b * 0.0039215689f; gSP.lights[n].x = light->x; gSP.lights[n].y = light->y; gSP.lights[n].z = light->z; Normalize( &gSP.lights[n].x ); u32 addrShort = addrByte >> 1; gSP.lights[n].posx = (float)(((short*)gfx_info.RDRAM)[(addrShort+16)^1]); gSP.lights[n].posy = (float)(((short*)gfx_info.RDRAM)[(addrShort+17)^1]); gSP.lights[n].posz = (float)(((short*)gfx_info.RDRAM)[(addrShort+18)^1]); gSP.lights[n].posw = (float)(((short*)gfx_info.RDRAM)[(addrShort+19)^1]); gSP.lights[n].ca = (float)(gfx_info.RDRAM[(addrByte + 12) ^ 3]) / 16.0f; } if (config.generalEmulation.enableHWLighting != 0) gSP.changed |= CHANGED_LIGHT; #ifdef DEBUG DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED, "// x = %2.6f y = %2.6f z = %2.6f\n", _FIXED2FLOAT( light->x, 7 ), _FIXED2FLOAT( light->y, 7 ), _FIXED2FLOAT( light->z, 7 ) ); DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED, "// r = %3i g = %3i b = %3i\n", light->r, light->g, light->b ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPLight( 0x%08X, LIGHT_%i );\n", l, n ); #endif } void gSPLookAt( u32 _l, u32 _n ) { u32 address = RSP_SegmentToPhysical(_l); if ((address + sizeof(Light)) > RDRAMSize) { #ifdef DEBUG DebugMsg(DEBUG_HIGH | DEBUG_ERROR, "// Attempting to load light from invalid address\n"); DebugMsg(DEBUG_HIGH | DEBUG_HANDLED, "gSPLookAt( 0x%08X, LOOKAT_%i );\n", l, n); #endif return; } assert(_n < 2); Light *light = (Light*)&gfx_info.RDRAM[address]; gSP.lookat[_n].x = light->x; gSP.lookat[_n].y = light->y; gSP.lookat[_n].z = light->z; gSP.lookatEnable = (_n == 0) || (_n == 1 && (light->x != 0 || light->y != 0)); Normalize(&gSP.lookat[_n].x); } void gSPVertex( u32 a, u32 n, u32 v0 ) { u32 address = RSP_SegmentToPhysical(a); if ((address + sizeof( Vertex ) * n) > RDRAMSize) return; Vertex *vertex = (Vertex*)&gfx_info.RDRAM[address]; OGLRender & render = video().getRender(); if ((n + v0) <= INDEXMAP_SIZE) { unsigned int i = v0; #ifdef __VEC4_OPT for (; i < n - (n%4) + v0; i += 4) { u32 v = i; for(int j = 0; j < 4; ++j) { SPVertex & vtx = render.getVertex(v+j); vtx.x = vertex->x; vtx.y = vertex->y; vtx.z = vertex->z; //vtx.flag = vertex->flag; vtx.s = _FIXED2FLOAT( vertex->s, 5 ); vtx.t = _FIXED2FLOAT( vertex->t, 5 ); if (gSP.geometryMode & G_LIGHTING) { vtx.nx = vertex->normal.x; vtx.ny = vertex->normal.y; vtx.nz = vertex->normal.z; vtx.a = vertex->color.a * 0.0039215689f; } else { vtx.r = vertex->color.r * 0.0039215689f; vtx.g = vertex->color.g * 0.0039215689f; vtx.b = vertex->color.b * 0.0039215689f; vtx.a = vertex->color.a * 0.0039215689f; } vertex++; } gSPProcessVertex4(v); } #endif for (; i < n + v0; ++i) { u32 v = i; SPVertex & vtx = render.getVertex(v); vtx.x = vertex->x; vtx.y = vertex->y; vtx.z = vertex->z; vtx.s = _FIXED2FLOAT( vertex->s, 5 ); vtx.t = _FIXED2FLOAT( vertex->t, 5 ); if (gSP.geometryMode & G_LIGHTING) { vtx.nx = vertex->normal.x; vtx.ny = vertex->normal.y; vtx.nz = vertex->normal.z; vtx.a = vertex->color.a * 0.0039215689f; } else { vtx.r = vertex->color.r * 0.0039215689f; vtx.g = vertex->color.g * 0.0039215689f; vtx.b = vertex->color.b * 0.0039215689f; vtx.a = vertex->color.a * 0.0039215689f; } gSPProcessVertex(v); vertex++; } } else { LOG(LOG_ERROR, "Using Vertex outside buffer v0=%i, n=%i\n", v0, n); } } void gSPCIVertex( u32 a, u32 n, u32 v0 ) { u32 address = RSP_SegmentToPhysical( a ); if ((address + sizeof( PDVertex ) * n) > RDRAMSize) return; PDVertex *vertex = (PDVertex*)&gfx_info.RDRAM[address]; OGLRender & render = video().getRender(); if ((n + v0) <= INDEXMAP_SIZE) { unsigned int i = v0; #ifdef __VEC4_OPT for (; i < n - (n%4) + v0; i += 4) { u32 v = i; for(unsigned int j = 0; j < 4; ++j) { SPVertex & vtx = render.getVertex(v + j); vtx.x = vertex->x; vtx.y = vertex->y; vtx.z = vertex->z; vtx.s = _FIXED2FLOAT( vertex->s, 5 ); vtx.t = _FIXED2FLOAT( vertex->t, 5 ); u8 *color = &gfx_info.RDRAM[gSP.vertexColorBase + (vertex->ci & 0xff)]; if (gSP.geometryMode & G_LIGHTING) { vtx.nx = (s8)color[3]; vtx.ny = (s8)color[2]; vtx.nz = (s8)color[1]; vtx.a = color[0] * 0.0039215689f; } else { vtx.r = color[3] * 0.0039215689f; vtx.g = color[2] * 0.0039215689f; vtx.b = color[1] * 0.0039215689f; vtx.a = color[0] * 0.0039215689f; } vertex++; } gSPProcessVertex4(v); } #endif for(; i < n + v0; ++i) { u32 v = i; SPVertex & vtx = render.getVertex(v); vtx.x = vertex->x; vtx.y = vertex->y; vtx.z = vertex->z; vtx.s = _FIXED2FLOAT( vertex->s, 5 ); vtx.t = _FIXED2FLOAT( vertex->t, 5 ); u8 *color = &gfx_info.RDRAM[gSP.vertexColorBase + (vertex->ci & 0xff)]; if (gSP.geometryMode & G_LIGHTING) { vtx.nx = (s8)color[3]; vtx.ny = (s8)color[2]; vtx.nz = (s8)color[1]; vtx.a = color[0] * 0.0039215689f; } else { vtx.r = color[3] * 0.0039215689f; vtx.g = color[2] * 0.0039215689f; vtx.b = color[1] * 0.0039215689f; vtx.a = color[0] * 0.0039215689f; } gSPProcessVertex(v); vertex++; } } else { LOG(LOG_ERROR, "Using Vertex outside buffer v0=%i, n=%i\n", v0, n); } } void gSPDMAVertex( u32 a, u32 n, u32 v0 ) { u32 address = gSP.DMAOffsets.vtx + RSP_SegmentToPhysical(a); if ((address + 10 * n) > RDRAMSize) return; OGLRender & render = video().getRender(); if ((n + v0) <= INDEXMAP_SIZE) { u32 i = v0; #ifdef __VEC4_OPT for (; i < n - (n%4) + v0; i += 4) { u32 v = i; for(int j = 0; j < 4; ++j) { SPVertex & vtx = render.getVertex(v + j); vtx.x = *(s16*)&gfx_info.RDRAM[address ^ 2]; vtx.y = *(s16*)&gfx_info.RDRAM[(address + 2) ^ 2]; vtx.z = *(s16*)&gfx_info.RDRAM[(address + 4) ^ 2]; if (gSP.geometryMode & G_LIGHTING) { vtx.nx = *(s8*)&gfx_info.RDRAM[(address + 6) ^ 3]; vtx.ny = *(s8*)&gfx_info.RDRAM[(address + 7) ^ 3]; vtx.nz = *(s8*)&gfx_info.RDRAM[(address + 8) ^ 3]; vtx.a = *(u8*)&gfx_info.RDRAM[(address + 9) ^ 3] * 0.0039215689f; } else { vtx.r = *(u8*)&gfx_info.RDRAM[(address + 6) ^ 3] * 0.0039215689f; vtx.g = *(u8*)&gfx_info.RDRAM[(address + 7) ^ 3] * 0.0039215689f; vtx.b = *(u8*)&gfx_info.RDRAM[(address + 8) ^ 3] * 0.0039215689f; vtx.a = *(u8*)&gfx_info.RDRAM[(address + 9) ^ 3] * 0.0039215689f; } address += 10; } gSPProcessVertex4(v); } #endif for (; i < n + v0; ++i) { u32 v = i; SPVertex & vtx = render.getVertex(v); vtx.x = *(s16*)&gfx_info.RDRAM[address ^ 2]; vtx.y = *(s16*)&gfx_info.RDRAM[(address + 2) ^ 2]; vtx.z = *(s16*)&gfx_info.RDRAM[(address + 4) ^ 2]; if (gSP.geometryMode & G_LIGHTING) { vtx.nx = *(s8*)&gfx_info.RDRAM[(address + 6) ^ 3]; vtx.ny = *(s8*)&gfx_info.RDRAM[(address + 7) ^ 3]; vtx.nz = *(s8*)&gfx_info.RDRAM[(address + 8) ^ 3]; vtx.a = *(u8*)&gfx_info.RDRAM[(address + 9) ^ 3] * 0.0039215689f; } else { vtx.r = *(u8*)&gfx_info.RDRAM[(address + 6) ^ 3] * 0.0039215689f; vtx.g = *(u8*)&gfx_info.RDRAM[(address + 7) ^ 3] * 0.0039215689f; vtx.b = *(u8*)&gfx_info.RDRAM[(address + 8) ^ 3] * 0.0039215689f; vtx.a = *(u8*)&gfx_info.RDRAM[(address + 9) ^ 3] * 0.0039215689f; } gSPProcessVertex(v); address += 10; } } else { LOG(LOG_ERROR, "Using Vertex outside buffer v0=%i, n=%i\n", v0, n); } } void gSPCBFDVertex( u32 a, u32 n, u32 v0 ) { u32 address = RSP_SegmentToPhysical(a); if ((address + sizeof( Vertex ) * n) > RDRAMSize) return; Vertex *vertex = (Vertex*)&gfx_info.RDRAM[address]; OGLRender & render = video().getRender(); if ((n + v0) <= INDEXMAP_SIZE) { unsigned int i = v0; #ifdef __VEC4_OPT for (; i < n - (n%4) + v0; i += 4) { u32 v = i; for(int j = 0; j < 4; ++j) { SPVertex & vtx = render.getVertex(v+j); vtx.x = vertex->x; vtx.y = vertex->y; vtx.z = vertex->z; vtx.s = _FIXED2FLOAT( vertex->s, 5 ); vtx.t = _FIXED2FLOAT( vertex->t, 5 ); if (gSP.geometryMode & G_LIGHTING) { const u32 normaleAddrOffset = ((v0+v+j)<<1); vtx.nx = (float)(((s8*)gfx_info.RDRAM)[(gSP.vertexNormalBase + normaleAddrOffset + 0)^3]); vtx.ny = (float)(((s8*)gfx_info.RDRAM)[(gSP.vertexNormalBase + normaleAddrOffset + 1)^3]); vtx.nz = (float)((s16)(vertex->flag&0xFF)); vtx.a = vertex->color.a * 0.0039215689f; } vtx.r = vertex->color.r * 0.0039215689f; vtx.g = vertex->color.g * 0.0039215689f; vtx.b = vertex->color.b * 0.0039215689f; vtx.a = vertex->color.a * 0.0039215689f; vertex++; } gSPProcessVertex4(v); } #endif for (; i < n + v0; ++i) { u32 v = i; SPVertex & vtx = render.getVertex(v); vtx.x = vertex->x; vtx.y = vertex->y; vtx.z = vertex->z; vtx.s = _FIXED2FLOAT( vertex->s, 5 ); vtx.t = _FIXED2FLOAT( vertex->t, 5 ); if (gSP.geometryMode & G_LIGHTING) { const u32 normaleAddrOffset = (v<<1); vtx.nx = (float)(((s8*)gfx_info.RDRAM)[(gSP.vertexNormalBase + normaleAddrOffset + 0)^3]); vtx.ny = (float)(((s8*)gfx_info.RDRAM)[(gSP.vertexNormalBase + normaleAddrOffset + 1)^3]); vtx.nz = (float)((s8)(vertex->flag&0xFF)); } vtx.r = vertex->color.r * 0.0039215689f; vtx.g = vertex->color.g * 0.0039215689f; vtx.b = vertex->color.b * 0.0039215689f; vtx.a = vertex->color.a * 0.0039215689f; gSPProcessVertex(v); vertex++; } } else { LOG(LOG_ERROR, "Using Vertex outside buffer v0=%i, n=%i\n", v0, n); } } void gSPDisplayList( u32 dl ) { u32 address = RSP_SegmentToPhysical( dl ); if ((address + 8) > RDRAMSize) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR, "// Attempting to load display list from invalid address\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPDisplayList( 0x%08X );\n", dl ); #endif return; } if (RSP.PCi < (GBI.PCStackSize - 1)) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPDisplayList( 0x%08X );\n", dl ); #endif RSP.PCi++; RSP.PC[RSP.PCi] = address; RSP.nextCmd = _SHIFTR( *(u32*)&gfx_info.RDRAM[address], 24, 8 ); } else { assert(false); DebugMsg( DEBUG_HIGH | DEBUG_ERROR, "// PC stack overflow\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPDisplayList( 0x%08X );\n", dl ); } } void gSPBranchList( u32 dl ) { u32 address = RSP_SegmentToPhysical( dl ); if ((address + 8) > RDRAMSize) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR, "// Attempting to branch to display list at invalid address\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPBranchList( 0x%08X );\n", dl ); #endif return; } #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPBranchList( 0x%08X );\n", dl ); #endif RSP.PC[RSP.PCi] = address; RSP.nextCmd = _SHIFTR( *(u32*)&gfx_info.RDRAM[address], 24, 8 ); } void gSPBranchLessZ( u32 branchdl, u32 vtx, f32 zval ) { u32 address = RSP_SegmentToPhysical( branchdl ); if ((address + 8) > RDRAMSize) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR, "// Specified display list at invalid address\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPBranchLessZ( 0x%08X, %i, %i );\n", branchdl, vtx, zval ); #endif return; } SPVertex & v = video().getRender().getVertex(vtx); const float zTest = v.z / v.w; if (zTest > 1.0f || zTest <= zval || !GBI.isBranchLessZ()) RSP.PC[RSP.PCi] = address; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPBranchLessZ( 0x%08X, %i, %i );\n", branchdl, vtx, zval ); #endif } void gSPDlistCount(u32 count, u32 v) { u32 address = RSP_SegmentToPhysical( v ); if (address == 0 || (address + 8) > RDRAMSize) { DebugMsg( DEBUG_HIGH | DEBUG_ERROR, "// Attempting to branch to display list at invalid address\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPDlistCnt(%d, 0x%08X );\n", count, v ); return; } if (RSP.PCi >= 9) { DebugMsg( DEBUG_HIGH | DEBUG_ERROR, "// ** DL stack overflow **\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPDlistCnt(%d, 0x%08X );\n", count, v ); return; } DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPDlistCnt(%d, 0x%08X );\n", count, v ); ++RSP.PCi; // go to the next PC in the stack RSP.PC[RSP.PCi] = address; // jump to the address RSP.nextCmd = _SHIFTR( *(u32*)&gfx_info.RDRAM[address], 24, 8 ); RSP.count = count + 1; } void gSPSetDMAOffsets( u32 mtxoffset, u32 vtxoffset ) { gSP.DMAOffsets.mtx = mtxoffset; gSP.DMAOffsets.vtx = vtxoffset; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPSetDMAOffsets( 0x%08X, 0x%08X );\n", mtxoffset, vtxoffset ); #endif } void gSPSetDMATexOffset(u32 _addr) { gSP.DMAOffsets.tex_offset = RSP_SegmentToPhysical(_addr); gSP.DMAOffsets.tex_shift = 0; gSP.DMAOffsets.tex_count = 0; } void gSPSetVertexColorBase( u32 base ) { gSP.vertexColorBase = RSP_SegmentToPhysical( base ); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPSetVertexColorBase( 0x%08X );\n", base ); #endif } void gSPSetVertexNormaleBase( u32 base ) { gSP.vertexNormalBase = RSP_SegmentToPhysical( base ); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPSetVertexNormaleBase( 0x%08X );\n", base ); #endif } void gSPDMATriangles( u32 tris, u32 n ){ const u32 address = RSP_SegmentToPhysical( tris ); if (address + sizeof( DKRTriangle ) * n > RDRAMSize) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR | DEBUG_TRIANGLE, "// Attempting to load triangles from invalid address\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TRIANGLE, "gSPDMATriangles( 0x%08X, %i );\n" ); #endif return; } OGLRender & render = video().getRender(); render.setDMAVerticesSize(n * 3); DKRTriangle *triangles = (DKRTriangle*)&gfx_info.RDRAM[address]; SPVertex * pVtx = render.getDMAVerticesData(); for (u32 i = 0; i < n; ++i) { int mode = 0; if (!(triangles->flag & 0x40)) { if (gSP.viewport.vscale[0] > 0) mode |= G_CULL_BACK; else mode |= G_CULL_FRONT; } if ((gSP.geometryMode&G_CULL_BOTH) != mode) { render.drawDMATriangles(pVtx - render.getDMAVerticesData()); pVtx = render.getDMAVerticesData(); gSP.geometryMode &= ~G_CULL_BOTH; gSP.geometryMode |= mode; gSP.changed |= CHANGED_GEOMETRYMODE; } const s32 v0 = triangles->v0; const s32 v1 = triangles->v1; const s32 v2 = triangles->v2; if (render.isClipped(v0, v1, v2)) { ++triangles; continue; } *pVtx = render.getVertex(v0); pVtx->s = _FIXED2FLOAT(triangles->s0, 5); pVtx->t = _FIXED2FLOAT(triangles->t0, 5); ++pVtx; *pVtx = render.getVertex(v1); pVtx->s = _FIXED2FLOAT(triangles->s1, 5); pVtx->t = _FIXED2FLOAT(triangles->t1, 5); ++pVtx; *pVtx = render.getVertex(v2); pVtx->s = _FIXED2FLOAT(triangles->s2, 5); pVtx->t = _FIXED2FLOAT(triangles->t2, 5); ++pVtx; ++triangles; } render.drawDMATriangles(pVtx - render.getDMAVerticesData()); } void gSP1Quadrangle( s32 v0, s32 v1, s32 v2, s32 v3 ) { gSPTriangle( v0, v1, v2); gSPTriangle( v0, v2, v3); gSPFlushTriangles(); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TRIANGLE, "gSP1Quadrangle( %i, %i, %i, %i );\n", v0, v1, v2, v3 ); #endif } bool gSPCullVertices( u32 v0, u32 vn ) { if (vn < v0) { // Aidyn Chronicles - The First Mage seems to pass parameters in reverse order. const u32 v = v0; v0 = vn; vn = v; } u32 clip = 0; OGLRender & render = video().getRender(); for (u32 i = v0; i <= vn; ++i) { clip |= (~render.getVertex(i).clip) & CLIP_ALL; if (clip == CLIP_ALL) return false; } return true; } void gSPCullDisplayList( u32 v0, u32 vn ) { if (gSPCullVertices( v0, vn )) { if (RSP.PCi > 0) RSP.PCi--; else { #ifdef DEBUG DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED, "// End of display list, halting execution\n" ); #endif RSP.halt = TRUE; } #ifdef DEBUG DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED, "// Culling display list\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPCullDisplayList( %i, %i );\n\n", v0, vn ); #endif } #ifdef DEBUG else { DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED, "// Not culling display list\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPCullDisplayList( %i, %i );\n", v0, vn ); } #endif } void gSPPopMatrixN( u32 param, u32 num ) { if (gSP.matrix.modelViewi > num - 1) { gSP.matrix.modelViewi -= num; gSP.changed |= CHANGED_MATRIX; } #ifdef DEBUG else DebugMsg( DEBUG_HIGH | DEBUG_ERROR | DEBUG_MATRIX, "// Attempting to pop matrix stack below 0\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_MATRIX, "gSPPopMatrixN( %s, %i );\n", (param == G_MTX_MODELVIEW) ? "G_MTX_MODELVIEW" : (param == G_MTX_PROJECTION) ? "G_MTX_PROJECTION" : "G_MTX_INVALID", num ); #endif } void gSPPopMatrix( u32 param ) { switch (param) { case 0: // modelview if (gSP.matrix.modelViewi > 0) { gSP.matrix.modelViewi--; gSP.changed |= CHANGED_MATRIX; } break; case 1: // projection, can't break; default: DebugMsg( DEBUG_HIGH | DEBUG_ERROR | DEBUG_MATRIX, "// Attempting to pop matrix stack below 0\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_MATRIX, "gSPPopMatrix( %s );\n", (param == G_MTX_MODELVIEW) ? "G_MTX_MODELVIEW" : (param == G_MTX_PROJECTION) ? "G_MTX_PROJECTION" : "G_MTX_INVALID" ); } } void gSPSegment( s32 seg, s32 base ) { gSP.segment[seg] = base; DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPSegment( %s, 0x%08X );\n", SegmentText[seg], base ); } void gSPClipRatio( u32 r ) { } void gSPInsertMatrix( u32 where, u32 num ) { f32 fraction, integer; if (gSP.changed & CHANGED_MATRIX) gSPCombineMatrices(); if ((where & 0x3) || (where > 0x3C)) return; if (where < 0x20) { fraction = modff( gSP.matrix.combined[0][where >> 1], &integer ); gSP.matrix.combined[0][where >> 1] = (s16)_SHIFTR( num, 16, 16 ) + abs( (int)fraction ); fraction = modff( gSP.matrix.combined[0][(where >> 1) + 1], &integer ); gSP.matrix.combined[0][(where >> 1) + 1] = (s16)_SHIFTR( num, 0, 16 ) + abs( (int)fraction ); } else { f32 newValue; fraction = modff( gSP.matrix.combined[0][(where - 0x20) >> 1], &integer ); newValue = integer + _FIXED2FLOAT( _SHIFTR( num, 16, 16 ), 16); // Make sure the sign isn't lost if ((integer == 0.0f) && (fraction != 0.0f)) newValue = newValue * (fraction / abs( (int)fraction )); gSP.matrix.combined[0][(where - 0x20) >> 1] = newValue; fraction = modff( gSP.matrix.combined[0][((where - 0x20) >> 1) + 1], &integer ); newValue = integer + _FIXED2FLOAT( _SHIFTR( num, 0, 16 ), 16 ); // Make sure the sign isn't lost if ((integer == 0.0f) && (fraction != 0.0f)) newValue = newValue * (fraction / abs( (int)fraction )); gSP.matrix.combined[0][((where - 0x20) >> 1) + 1] = newValue; } } void gSPModifyVertex( u32 _vtx, u32 _where, u32 _val ) { s32 v = _vtx; OGLRender & render = video().getRender(); SPVertex & vtx0 = render.getVertex(v); switch (_where) { case G_MWO_POINT_RGBA: vtx0.r = _SHIFTR( _val, 24, 8 ) * 0.0039215689f; vtx0.g = _SHIFTR( _val, 16, 8 ) * 0.0039215689f; vtx0.b = _SHIFTR( _val, 8, 8 ) * 0.0039215689f; vtx0.a = _SHIFTR( _val, 0, 8 ) * 0.0039215689f; break; case G_MWO_POINT_ST: vtx0.s = _FIXED2FLOAT( (s16)_SHIFTR( _val, 16, 16 ), 5 ) / gSP.texture.scales; vtx0.t = _FIXED2FLOAT((s16)_SHIFTR(_val, 0, 16), 5) / gSP.texture.scalet; break; case G_MWO_POINT_XYSCREEN: { f32 scrX = _FIXED2FLOAT( (s16)_SHIFTR( _val, 16, 16 ), 2 ); f32 scrY = _FIXED2FLOAT( (s16)_SHIFTR( _val, 0, 16 ), 2 ); vtx0.x = (scrX - gSP.viewport.vtrans[0]) / gSP.viewport.vscale[0]; vtx0.x *= vtx0.w; vtx0.y = -(scrY - gSP.viewport.vtrans[1]) / gSP.viewport.vscale[1]; vtx0.y *= vtx0.w; vtx0.clip &= ~(CLIP_POSX | CLIP_NEGX | CLIP_POSY | CLIP_NEGY); } break; case G_MWO_POINT_ZSCREEN: { f32 scrZ = _FIXED2FLOAT((s16)_SHIFTR(_val, 16, 16), 15); vtx0.z = (scrZ - gSP.viewport.vtrans[2]) / (gSP.viewport.vscale[2]); vtx0.z *= vtx0.w; vtx0.clip &= ~CLIP_Z; } break; } } void gSPNumLights( s32 n ) { if (n <= 12) { gSP.numLights = n; if (config.generalEmulation.enableHWLighting != 0) gSP.changed |= CHANGED_LIGHT; } #ifdef DEBUG else DebugMsg( DEBUG_HIGH | DEBUG_ERROR, "// Setting an invalid number of lights\n" ); #endif #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPNumLights( %i );\n", n ); #endif } void gSPLightColor( u32 lightNum, u32 packedColor ) { --lightNum; if (lightNum < 8) { gSP.lights[lightNum].r = _SHIFTR( packedColor, 24, 8 ) * 0.0039215689f; gSP.lights[lightNum].g = _SHIFTR( packedColor, 16, 8 ) * 0.0039215689f; gSP.lights[lightNum].b = _SHIFTR( packedColor, 8, 8 ) * 0.0039215689f; if (config.generalEmulation.enableHWLighting != 0) gSP.changed |= CHANGED_LIGHT; } #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPLightColor( %i, 0x%08X );\n", lightNum, packedColor ); #endif } void gSPFogFactor( s16 fm, s16 fo ) { gSP.fog.multiplier = fm; gSP.fog.offset = fo; gSP.changed |= CHANGED_FOGPOSITION; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPFogFactor( %i, %i );\n", fm, fo ); #endif } void gSPPerspNormalize( u16 scale ) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_UNHANDLED, "gSPPerspNormalize( %i );\n", scale ); #endif } void gSPCoordMod(u32 _w0, u32 _w1) { if ((_w0&8) != 0) return; u32 idx = _SHIFTR(_w0, 1, 2); u32 pos = _w0&0x30; if (pos == 0) { gSP.vertexCoordMod[0+idx] = (f32)(s16)_SHIFTR(_w1, 16, 16); gSP.vertexCoordMod[1+idx] = (f32)(s16)_SHIFTR(_w1, 0, 16); } else if (pos == 0x10) { assert(idx < 3); gSP.vertexCoordMod[4+idx] = _SHIFTR(_w1, 16, 16)/65536.0f; gSP.vertexCoordMod[5+idx] = _SHIFTR(_w1, 0, 16)/65536.0f; gSP.vertexCoordMod[12+idx] = gSP.vertexCoordMod[0+idx] + gSP.vertexCoordMod[4+idx]; gSP.vertexCoordMod[13+idx] = gSP.vertexCoordMod[1+idx] + gSP.vertexCoordMod[5+idx]; } else if (pos == 0x20) { gSP.vertexCoordMod[8+idx] = (f32)(s16)_SHIFTR(_w1, 16, 16); gSP.vertexCoordMod[9+idx] = (f32)(s16)_SHIFTR(_w1, 0, 16); } } void gSPTexture( f32 sc, f32 tc, s32 level, s32 tile, s32 on ) { gSP.texture.on = on; if (on == 0) return; gSP.texture.scales = sc; gSP.texture.scalet = tc; if (gSP.texture.scales == 0.0f) gSP.texture.scales = 1.0f; if (gSP.texture.scalet == 0.0f) gSP.texture.scalet = 1.0f; gSP.texture.level = level; gSP.texture.tile = tile; gSP.textureTile[0] = &gDP.tiles[tile]; gSP.textureTile[1] = &gDP.tiles[(tile + 1) & 7]; gSP.changed |= CHANGED_TEXTURE; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gSPTexture( %f, %f, %i, %i, %i );\n", sc, tc, level, tile, on ); #endif } void gSPEndDisplayList() { if (RSP.PCi > 0) --RSP.PCi; else { #ifdef DEBUG DebugMsg( DEBUG_DETAIL | DEBUG_HANDLED, "// End of display list, halting execution\n" ); #endif RSP.halt = TRUE; } #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPEndDisplayList();\n\n" ); #endif } void gSPGeometryMode( u32 clear, u32 set ) { gSP.geometryMode = (gSP.geometryMode & ~clear) | set; gSP.changed |= CHANGED_GEOMETRYMODE; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPGeometryMode( %s%s%s%s%s%s%s%s%s%s, %s%s%s%s%s%s%s%s%s%s );\n", clear & G_SHADE ? "G_SHADE | " : "", clear & G_LIGHTING ? "G_LIGHTING | " : "", clear & G_SHADING_SMOOTH ? "G_SHADING_SMOOTH | " : "", clear & G_ZBUFFER ? "G_ZBUFFER | " : "", clear & G_TEXTURE_GEN ? "G_TEXTURE_GEN | " : "", clear & G_TEXTURE_GEN_LINEAR ? "G_TEXTURE_GEN_LINEAR | " : "", clear & G_CULL_FRONT ? "G_CULL_FRONT | " : "", clear & G_CULL_BACK ? "G_CULL_BACK | " : "", clear & G_FOG ? "G_FOG | " : "", clear & G_CLIPPING ? "G_CLIPPING" : "", set & G_SHADE ? "G_SHADE | " : "", set & G_LIGHTING ? "G_LIGHTING | " : "", set & G_SHADING_SMOOTH ? "G_SHADING_SMOOTH | " : "", set & G_ZBUFFER ? "G_ZBUFFER | " : "", set & G_TEXTURE_GEN ? "G_TEXTURE_GEN | " : "", set & G_TEXTURE_GEN_LINEAR ? "G_TEXTURE_GEN_LINEAR | " : "", set & G_CULL_FRONT ? "G_CULL_FRONT | " : "", set & G_CULL_BACK ? "G_CULL_BACK | " : "", set & G_FOG ? "G_FOG | " : "", set & G_CLIPPING ? "G_CLIPPING" : "" ); #endif } void gSPSetGeometryMode( u32 mode ) { gSP.geometryMode |= mode; gSP.changed |= CHANGED_GEOMETRYMODE; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPSetGeometryMode( %s%s%s%s%s%s%s%s%s%s );\n", mode & G_SHADE ? "G_SHADE | " : "", mode & G_LIGHTING ? "G_LIGHTING | " : "", mode & G_SHADING_SMOOTH ? "G_SHADING_SMOOTH | " : "", mode & G_ZBUFFER ? "G_ZBUFFER | " : "", mode & G_TEXTURE_GEN ? "G_TEXTURE_GEN | " : "", mode & G_TEXTURE_GEN_LINEAR ? "G_TEXTURE_GEN_LINEAR | " : "", mode & G_CULL_FRONT ? "G_CULL_FRONT | " : "", mode & G_CULL_BACK ? "G_CULL_BACK | " : "", mode & G_FOG ? "G_FOG | " : "", mode & G_CLIPPING ? "G_CLIPPING" : "" ); #endif } void gSPClearGeometryMode( u32 mode ) { gSP.geometryMode &= ~mode; gSP.changed |= CHANGED_GEOMETRYMODE; #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gSPClearGeometryMode( %s%s%s%s%s%s%s%s%s%s );\n", mode & G_SHADE ? "G_SHADE | " : "", mode & G_LIGHTING ? "G_LIGHTING | " : "", mode & G_SHADING_SMOOTH ? "G_SHADING_SMOOTH | " : "", mode & G_ZBUFFER ? "G_ZBUFFER | " : "", mode & G_TEXTURE_GEN ? "G_TEXTURE_GEN | " : "", mode & G_TEXTURE_GEN_LINEAR ? "G_TEXTURE_GEN_LINEAR | " : "", mode & G_CULL_FRONT ? "G_CULL_FRONT | " : "", mode & G_CULL_BACK ? "G_CULL_BACK | " : "", mode & G_FOG ? "G_FOG | " : "", mode & G_CLIPPING ? "G_CLIPPING" : "" ); #endif } void gSPSetOtherMode_H(u32 _length, u32 _shift, u32 _data) { const u32 mask = (((u64)1 << _length) - 1) << _shift; gDP.otherMode.h = (gDP.otherMode.h&(~mask)) | _data; if (mask & 0x00300000) // cycle type gDP.changed |= CHANGED_CYCLETYPE; } void gSPSetOtherMode_L(u32 _length, u32 _shift, u32 _data) { const u32 mask = (((u64)1 << _length) - 1) << _shift; gDP.otherMode.l = (gDP.otherMode.l&(~mask)) | _data; if (mask & 0x00000003) // alpha compare gDP.changed |= CHANGED_ALPHACOMPARE; if (mask & 0xFFFFFFF8) // rendermode / blender bits gDP.changed |= CHANGED_RENDERMODE; } void gSPLine3D( s32 v0, s32 v1, s32 flag ) { video().getRender().drawLine(v0, v1, 1.5f); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_UNHANDLED, "gSPLine3D( %i, %i, %i );\n", v0, v1, flag ); #endif } void gSPLineW3D( s32 v0, s32 v1, s32 wd, s32 flag ) { video().getRender().drawLine(v0, v1, 1.5f + wd * 0.5f); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_UNHANDLED, "gSPLineW3D( %i, %i, %i, %i );\n", v0, v1, wd, flag ); #endif } void gSPObjLoadTxtr( u32 tx ) { const u32 address = RSP_SegmentToPhysical( tx ); uObjTxtr *objTxtr = (uObjTxtr*)&gfx_info.RDRAM[address]; if ((gSP.status[objTxtr->block.sid >> 2] & objTxtr->block.mask) != objTxtr->block.flag) { switch (objTxtr->block.type) { case G_OBJLT_TXTRBLOCK: gDPSetTextureImage( 0, 1, 0, objTxtr->block.image ); gDPSetTile( 0, 1, 0, objTxtr->block.tmem, 7, 0, 0, 0, 0, 0, 0, 0 ); gDPLoadBlock( 7, 0, 0, ((objTxtr->block.tsize + 1) << 3) - 1, objTxtr->block.tline ); break; case G_OBJLT_TXTRTILE: gDPSetTextureImage( 0, 1, (objTxtr->tile.twidth + 1) << 1, objTxtr->tile.image ); gDPSetTile( 0, 1, (objTxtr->tile.twidth + 1) >> 2, objTxtr->tile.tmem, 7, 0, 0, 0, 0, 0, 0, 0 ); gDPLoadTile( 7, 0, 0, (((objTxtr->tile.twidth + 1) << 1) - 1) << 2, (((objTxtr->tile.theight + 1) >> 2) - 1) << 2 ); break; case G_OBJLT_TLUT: gDPSetTextureImage( 0, 2, 1, objTxtr->tlut.image ); gDPSetTile( 0, 2, 0, objTxtr->tlut.phead, 7, 0, 0, 0, 0, 0, 0, 0 ); gDPLoadTLUT( 7, 0, 0, objTxtr->tlut.pnum << 2, 0 ); break; } gSP.status[objTxtr->block.sid >> 2] = (gSP.status[objTxtr->block.sid >> 2] & ~objTxtr->block.mask) | (objTxtr->block.flag & objTxtr->block.mask); } } static void gSPSetSpriteTile(const uObjSprite *_pObjSprite) { const u32 w = max(_pObjSprite->imageW >> 5, 1); const u32 h = max(_pObjSprite->imageH >> 5, 1); gDPSetTile( _pObjSprite->imageFmt, _pObjSprite->imageSiz, _pObjSprite->imageStride, _pObjSprite->imageAdrs, 0, _pObjSprite->imagePal, G_TX_CLAMP, G_TX_CLAMP, 0, 0, 0, 0 ); gDPSetTileSize( 0, 0, 0, (w - 1) << 2, (h - 1) << 2 ); gSPTexture( 1.0f, 1.0f, 0, 0, TRUE ); gDP.otherMode.texturePersp = 1; } struct ObjData { f32 scaleW; f32 scaleH; u32 imageW; u32 imageH; f32 X0; f32 X1; f32 Y0; f32 Y1; bool flipS, flipT; ObjData(const uObjSprite *_pObjSprite) { scaleW = _FIXED2FLOAT(_pObjSprite->scaleW, 10); scaleH = _FIXED2FLOAT(_pObjSprite->scaleH, 10); imageW = _pObjSprite->imageW >> 5; imageH = _pObjSprite->imageH >> 5; X0 = _FIXED2FLOAT(_pObjSprite->objX, 2); X1 = X0 + imageW / scaleW; Y0 = _FIXED2FLOAT(_pObjSprite->objY, 2); Y1 = Y0 + imageH / scaleH; flipS = (_pObjSprite->imageFlags & 0x01) != 0; flipT = (_pObjSprite->imageFlags & 0x10) != 0; } }; struct ObjCoordinates { f32 ulx, uly, lrx, lry; f32 uls, ult, lrs, lrt; f32 z, w; ObjCoordinates(const uObjSprite *_pObjSprite, bool _useMatrix) { ObjData data(_pObjSprite); ulx = data.X0; lrx = data.X1; uly = data.Y0; lry = data.Y1; if (_useMatrix) { ulx = ulx/gSP.objMatrix.baseScaleX + gSP.objMatrix.X; lrx = lrx/gSP.objMatrix.baseScaleX + gSP.objMatrix.X; uly = uly/gSP.objMatrix.baseScaleY + gSP.objMatrix.Y; lry = lry/gSP.objMatrix.baseScaleY + gSP.objMatrix.Y; } uls = ult = 0; lrs = data.imageW - 1; lrt = data.imageH - 1; if (data.flipS) { uls = lrs; lrs = 0; } if (data.flipT) { ult = lrt; lrt = 0; } z = (gDP.otherMode.depthSource == G_ZS_PRIM) ? gDP.primDepth.z : gSP.viewport.nearz; w = 1.0f; } ObjCoordinates(const uObjScaleBg * _pObjScaleBg) { const f32 frameX = _FIXED2FLOAT(_pObjScaleBg->frameX, 2); const f32 frameY = _FIXED2FLOAT(_pObjScaleBg->frameY, 2); const f32 frameW = _FIXED2FLOAT(_pObjScaleBg->frameW, 2); const f32 frameH = _FIXED2FLOAT(_pObjScaleBg->frameH, 2); const f32 imageX = gSP.bgImage.imageX; const f32 imageY = gSP.bgImage.imageY; const f32 imageW = (f32)(_pObjScaleBg->imageW>>2); const f32 imageH = (f32)(_pObjScaleBg->imageH >> 2); // const f32 imageW = (f32)gSP.bgImage.width; // const f32 imageH = (f32)gSP.bgImage.height; const f32 scaleW = gSP.bgImage.scaleW; const f32 scaleH = gSP.bgImage.scaleH; ulx = frameX; uly = frameY; lrx = frameX + min(imageW/scaleW, frameW) - 1.0f; lry = frameY + min(imageH/scaleH, frameH) - 1.0f; if (gDP.otherMode.cycleType == G_CYC_COPY) { lrx += 1.0f; lry += 1.0f;; } uls = imageX; ult = imageY; lrs = uls + (lrx - ulx) * scaleW; lrt = ult + (lry - uly) * scaleH; if (gDP.otherMode.cycleType != G_CYC_COPY) { if ((gSP.objRendermode&G_OBJRM_SHRINKSIZE_1) != 0) { lrs -= 1.0f / scaleW; lrt -= 1.0f / scaleH; } else if ((gSP.objRendermode&G_OBJRM_SHRINKSIZE_2) != 0) { lrs -= 1.0f; lrt -= 1.0f; } } if ((_pObjScaleBg->imageFlip & 0x01) != 0) { ulx = lrx; lrx = frameX; } z = (gDP.otherMode.depthSource == G_ZS_PRIM) ? gDP.primDepth.z : gSP.viewport.nearz; w = 1.0f; } }; static void gSPDrawObjRect(const ObjCoordinates & _coords) { u32 v0 = 0, v1 = 1, v2 = 2, v3 = 3; OGLRender & render = video().getRender(); SPVertex & vtx0 = render.getVertex(v0); vtx0.x = _coords.ulx; vtx0.y = _coords.uly; vtx0.z = _coords.z; vtx0.w = _coords.w; vtx0.s = _coords.uls; vtx0.t = _coords.ult; SPVertex & vtx1 = render.getVertex(v1); vtx1.x = _coords.lrx; vtx1.y = _coords.uly; vtx1.z = _coords.z; vtx1.w = _coords.w; vtx1.s = _coords.lrs; vtx1.t = _coords.ult; SPVertex & vtx2 = render.getVertex(v2); vtx2.x = _coords.ulx; vtx2.y = _coords.lry; vtx2.z = _coords.z; vtx2.w = _coords.w; vtx2.s = _coords.uls; vtx2.t = _coords.lrt; SPVertex & vtx3 = render.getVertex(v3); vtx3.x = _coords.lrx; vtx3.y = _coords.lry; vtx3.z = _coords.z; vtx3.w = _coords.w; vtx3.s = _coords.lrs; vtx3.t = _coords.lrt; render.drawLLETriangle(4); gDP.colorImage.height = (u32)(max(gDP.colorImage.height, (u32)gDP.scissor.lry)); } static u16 _YUVtoRGBA(u8 y, u8 u, u8 v) { float r = y + (1.370705f * (v - 128)); float g = y - (0.698001f * (v - 128)) - (0.337633f * (u - 128)); float b = y + (1.732446f * (u - 128)); r *= 0.125f; g *= 0.125f; b *= 0.125f; //clipping the result if (r > 32) r = 32; if (g > 32) g = 32; if (b > 32) b = 32; if (r < 0) r = 0; if (g < 0) g = 0; if (b < 0) b = 0; u16 c = (u16)(((u16)(r) << 11) | ((u16)(g) << 6) | ((u16)(b) << 1) | 1); return c; } static void _drawYUVImageToFrameBuffer(const ObjCoordinates & _objCoords) { const u32 ulx = (u32)_objCoords.ulx; const u32 uly = (u32)_objCoords.uly; const u32 lrx = (u32)_objCoords.lrx; const u32 lry = (u32)_objCoords.lry; const u32 ci_width = gDP.colorImage.width; const u32 ci_height = gDP.colorImage.height; if (ulx >= ci_width) return; if (uly >= ci_height) return; u32 width = 16, height = 16; if (lrx > ci_width) width = ci_width - ulx; if (lry > ci_height) height = ci_height - uly; u32 * mb = (u32*)(gfx_info.RDRAM + gDP.textureImage.address); //pointer to the first macro block u16 * dst = (u16*)(gfx_info.RDRAM + gDP.colorImage.address); dst += ulx + uly * ci_width; //yuv macro block contains 16x16 texture. we need to put it in the proper place inside cimg for (u16 h = 0; h < 16; h++) { for (u16 w = 0; w < 16; w += 2) { u32 t = *(mb++); //each u32 contains 2 pixels if ((h < height) && (w < width)) //clipping. texture image may be larger than color image { u8 y0 = (u8)t & 0xFF; u8 v = (u8)(t >> 8) & 0xFF; u8 y1 = (u8)(t >> 16) & 0xFF; u8 u = (u8)(t >> 24) & 0xFF; *(dst++) = _YUVtoRGBA(y0, u, v); *(dst++) = _YUVtoRGBA(y1, u, v); } } dst += ci_width - 16; } FrameBuffer *pBuffer = frameBufferList().getCurrent(); if (pBuffer != NULL) pBuffer->m_isOBScreen = true; } void gSPObjRectangle(u32 _sp) { const u32 address = RSP_SegmentToPhysical(_sp); uObjSprite *objSprite = (uObjSprite*)&gfx_info.RDRAM[address]; gSPSetSpriteTile(objSprite); ObjCoordinates objCoords(objSprite, false); gSPDrawObjRect(objCoords); } void gSPObjRectangleR(u32 _sp) { const u32 address = RSP_SegmentToPhysical(_sp); const uObjSprite *objSprite = (uObjSprite*)&gfx_info.RDRAM[address]; gSPSetSpriteTile(objSprite); ObjCoordinates objCoords(objSprite, true); if (objSprite->imageFmt == G_IM_FMT_YUV && (config.generalEmulation.hacks&hack_Ogre64)) //Ogre Battle needs to copy YUV texture to frame buffer _drawYUVImageToFrameBuffer(objCoords); gSPDrawObjRect(objCoords); } #ifndef GLES2 static void _copyDepthBuffer() { if (!config.frameBufferEmulation.enable) return; // The game copies content of depth buffer into current color buffer // OpenGL has different format for color and depth buffers, so this trick can't be performed directly // To do that, depth buffer with address of current color buffer created and attached to the current FBO // It will be copy depth buffer DepthBufferList & dbList = depthBufferList(); dbList.saveBuffer(gDP.colorImage.address); // Take any frame buffer and attach source depth buffer to it, to blit it into copy depth buffer FrameBufferList & fbList = frameBufferList(); FrameBuffer * pTmpBuffer = fbList.findTmpBuffer(fbList.getCurrent()->m_startAddress); if (pTmpBuffer == NULL) return; DepthBuffer * pCopyBufferDepth = dbList.findBuffer(gSP.bgImage.address); if (pCopyBufferDepth == NULL) return; glBindFramebuffer(GL_READ_FRAMEBUFFER, pTmpBuffer->m_FBO); pCopyBufferDepth->setDepthAttachment(GL_READ_FRAMEBUFFER); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbList.getCurrent()->m_FBO); OGLVideo & ogl = video(); glBlitFramebuffer( 0, 0, ogl.getWidth(), ogl.getHeight(), 0, 0, ogl.getWidth(), ogl.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST ); // Restore objects if (pTmpBuffer->m_pDepthBuffer != NULL) pTmpBuffer->m_pDepthBuffer->setDepthAttachment(GL_READ_FRAMEBUFFER); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); // Set back current depth buffer dbList.saveBuffer(gDP.depthImageAddress); } #endif // GLES2 static void _loadBGImage(const uObjScaleBg * _bgInfo, bool _loadScale) { gSP.bgImage.address = RSP_SegmentToPhysical( _bgInfo->imagePtr ); const u32 imageW = _bgInfo->imageW >> 2; gSP.bgImage.width = imageW - imageW%2; const u32 imageH = _bgInfo->imageH >> 2; gSP.bgImage.height = imageH - imageH%2; gSP.bgImage.format = _bgInfo->imageFmt; gSP.bgImage.size = _bgInfo->imageSiz; gSP.bgImage.palette = _bgInfo->imagePal; gDP.tiles[0].textureMode = TEXTUREMODE_BGIMAGE; gSP.bgImage.imageX = _FIXED2FLOAT( _bgInfo->imageX, 5 ); gSP.bgImage.imageY = _FIXED2FLOAT( _bgInfo->imageY, 5 ); if (_loadScale) { gSP.bgImage.scaleW = _FIXED2FLOAT( _bgInfo->scaleW, 10 ); gSP.bgImage.scaleH = _FIXED2FLOAT( _bgInfo->scaleH, 10 ); } else gSP.bgImage.scaleW = gSP.bgImage.scaleH = 1.0f; if (config.frameBufferEmulation.enable) { FrameBuffer *pBuffer = frameBufferList().findBuffer(gSP.bgImage.address); if ((pBuffer != NULL) && pBuffer->m_size == gSP.bgImage.size && (!pBuffer->m_isDepthBuffer || pBuffer->m_changed)) { gDP.tiles[0].frameBuffer = pBuffer; gDP.tiles[0].textureMode = TEXTUREMODE_FRAMEBUFFER_BG; gDP.tiles[0].loadType = LOADTYPE_TILE; gDP.changed |= CHANGED_TMEM; if ((config.generalEmulation.hacks & hack_ZeldaCamera) != 0) { if (gDP.colorImage.address == gDP.depthImageAddress) frameBufferList().setCopyBuffer(frameBufferList().getCurrent()); } } } } void gSPBgRect1Cyc( u32 _bg ) { const u32 address = RSP_SegmentToPhysical( _bg ); uObjScaleBg *objScaleBg = (uObjScaleBg*)&gfx_info.RDRAM[address]; _loadBGImage(objScaleBg, true); #ifndef GLES2 if (gSP.bgImage.address == gDP.depthImageAddress || depthBufferList().findBuffer(gSP.bgImage.address) != NULL) _copyDepthBuffer(); // Zelda MM uses depth buffer copy in LoT and in pause screen. // In later case depth buffer is used as temporal color buffer, and usual rendering must be used. // Since both situations are hard to distinguish, do the both depth buffer copy and bg rendering. #endif // GLES2 gDP.otherMode.cycleType = G_CYC_1CYCLE; gDP.changed |= CHANGED_CYCLETYPE; gSPTexture(1.0f, 1.0f, 0, 0, TRUE); gDP.otherMode.texturePersp = 1; ObjCoordinates objCoords(objScaleBg); gSPDrawObjRect(objCoords); } void gSPBgRectCopy( u32 _bg ) { const u32 address = RSP_SegmentToPhysical( _bg ); uObjScaleBg *objBg = (uObjScaleBg*)&gfx_info.RDRAM[address]; _loadBGImage(objBg, false); #ifdef GL_IMAGE_TEXTURES_SUPPORT if (gSP.bgImage.address == gDP.depthImageAddress || depthBufferList().findBuffer(gSP.bgImage.address) != NULL) _copyDepthBuffer(); // See comment to gSPBgRect1Cyc #endif // GL_IMAGE_TEXTURES_SUPPORT gSPTexture( 1.0f, 1.0f, 0, 0, TRUE ); gDP.otherMode.texturePersp = 1; ObjCoordinates objCoords(objBg); gSPDrawObjRect(objCoords); } void gSPObjSprite(u32 _sp) { const u32 address = RSP_SegmentToPhysical( _sp ); uObjSprite *objSprite = (uObjSprite*)&gfx_info.RDRAM[address]; gSPSetSpriteTile(objSprite); ObjData data(objSprite); const f32 ulx = data.X0; const f32 uly = data.Y0; const f32 lrx = data.X1; const f32 lry = data.Y1; float uls = 0, lrs = data.imageW - 1, ult = 0, lrt = data.imageH - 1; if (objSprite->imageFlags & 0x01) { // flipS uls = lrs; lrs = 0; } if (objSprite->imageFlags & 0x10) { // flipT ult = lrt; lrt = 0; } const float z = (gDP.otherMode.depthSource == G_ZS_PRIM) ? gDP.primDepth.z : gSP.viewport.nearz; s32 v0 = 0, v1 = 1, v2 = 2, v3 = 3; OGLRender & render = video().getRender(); SPVertex & vtx0 = render.getVertex(v0); vtx0.x = gSP.objMatrix.A * ulx + gSP.objMatrix.B * uly + gSP.objMatrix.X; vtx0.y = gSP.objMatrix.C * ulx + gSP.objMatrix.D * uly + gSP.objMatrix.Y; vtx0.z = z; vtx0.w = 1.0f; vtx0.s = uls; vtx0.t = ult; SPVertex & vtx1 = render.getVertex(v1); vtx1.x = gSP.objMatrix.A * lrx + gSP.objMatrix.B * uly + gSP.objMatrix.X; vtx1.y = gSP.objMatrix.C * lrx + gSP.objMatrix.D * uly + gSP.objMatrix.Y; vtx1.z = z; vtx1.w = 1.0f; vtx1.s = lrs; vtx1.t = ult; SPVertex & vtx2 = render.getVertex(v2); vtx2.x = gSP.objMatrix.A * ulx + gSP.objMatrix.B * lry + gSP.objMatrix.X; vtx2.y = gSP.objMatrix.C * ulx + gSP.objMatrix.D * lry + gSP.objMatrix.Y; vtx2.z = z; vtx2.w = 1.0f; vtx2.s = uls; vtx2.t = lrt; SPVertex & vtx3 = render.getVertex(v3); vtx3.x = gSP.objMatrix.A * lrx + gSP.objMatrix.B * lry + gSP.objMatrix.X; vtx3.y = gSP.objMatrix.C * lrx + gSP.objMatrix.D * lry + gSP.objMatrix.Y; vtx3.z = z; vtx3.w = 1.0f; vtx3.s = lrs; vtx3.t = lrt; render.drawLLETriangle(4); frameBufferList().setBufferChanged(); gDP.colorImage.height = (u32)(max( gDP.colorImage.height, (u32)gDP.scissor.lry )); } static void _loadSpriteImage(const uSprite *_pSprite) { gSP.bgImage.address = RSP_SegmentToPhysical( _pSprite->imagePtr ); gSP.bgImage.width = _pSprite->stride; gSP.bgImage.height = _pSprite->imageY + _pSprite->imageH; gSP.bgImage.format = _pSprite->imageFmt; gSP.bgImage.size = _pSprite->imageSiz; gSP.bgImage.palette = 0; gDP.tiles[0].textureMode = TEXTUREMODE_BGIMAGE; gSP.bgImage.imageX = _pSprite->imageX; gSP.bgImage.imageY = _pSprite->imageY; gSP.bgImage.scaleW = gSP.bgImage.scaleH = 1.0f; if (config.frameBufferEmulation.enable != 0) { FrameBuffer *pBuffer = frameBufferList().findBuffer(gSP.bgImage.address); if (pBuffer != NULL) { gDP.tiles[0].frameBuffer = pBuffer; gDP.tiles[0].textureMode = TEXTUREMODE_FRAMEBUFFER_BG; gDP.tiles[0].loadType = LOADTYPE_TILE; gDP.changed |= CHANGED_TMEM; } } } void gSPSprite2DBase(u32 _base) { assert(RSP.nextCmd == 0xBE); const u32 address = RSP_SegmentToPhysical( _base ); uSprite *pSprite = (uSprite*)&gfx_info.RDRAM[address]; if (pSprite->tlutPtr != 0) { gDPSetTextureImage( 0, 2, 1, pSprite->tlutPtr ); gDPSetTile( 0, 2, 0, 256, 7, 0, 0, 0, 0, 0, 0, 0 ); gDPLoadTLUT( 7, 0, 0, 1020, 0 ); if (pSprite->imageFmt != G_IM_FMT_RGBA) gDP.otherMode.textureLUT = G_TT_RGBA16; else gDP.otherMode.textureLUT = G_TT_NONE; } else gDP.otherMode.textureLUT = G_TT_NONE; _loadSpriteImage(pSprite); gSPTexture( 1.0f, 1.0f, 0, 0, TRUE ); gDP.otherMode.texturePersp = 1; const f32 z = (gDP.otherMode.depthSource == G_ZS_PRIM) ? gDP.primDepth.z : gSP.viewport.nearz; const f32 w = 1.0f; f32 scaleX = 1.0f, scaleY = 1.0f; u32 flipX = 0, flipY = 0; do { u32 w0 = *(u32*)&gfx_info.RDRAM[RSP.PC[RSP.PCi]]; u32 w1 = *(u32*)&gfx_info.RDRAM[RSP.PC[RSP.PCi] + 4]; RSP.cmd = _SHIFTR( w0, 24, 8 ); RSP.PC[RSP.PCi] += 8; RSP.nextCmd = _SHIFTR( *(u32*)&gfx_info.RDRAM[RSP.PC[RSP.PCi]], 24, 8 ); if ( RSP.cmd == 0xBE ) { // gSPSprite2DScaleFlip scaleX = _FIXED2FLOAT( _SHIFTR(w1, 16, 16), 10 ); scaleY = _FIXED2FLOAT( _SHIFTR(w1, 0, 16), 10 ); flipX = _SHIFTR(w0, 8, 8); flipY = _SHIFTR(w0, 0, 8); continue; } // gSPSprite2DDraw const f32 frameX = _FIXED2FLOAT(((s16)_SHIFTR(w1, 16, 16)), 2); const f32 frameY = _FIXED2FLOAT(((s16)_SHIFTR(w1, 0, 16)), 2); const f32 frameW = pSprite->imageW / scaleX; const f32 frameH = pSprite->imageH / scaleY; f32 ulx, uly, lrx, lry; if (flipX != 0) { ulx = frameX + frameW; lrx = frameX; } else { ulx = frameX; lrx = frameX + frameW; } if (flipY != 0) { uly = frameY + frameH; lry = frameY; } else { uly = frameY; lry = frameY + frameH; } f32 uls = pSprite->imageX; f32 ult = pSprite->imageY; f32 lrs = uls + pSprite->imageW - 1; f32 lrt = ult + pSprite->imageH - 1; /* Hack for WCW Nitro. TODO : activate it later. if (WCW_NITRO) { gSP.bgImage.height /= scaleY; gSP.bgImage.imageY /= scaleY; ult /= scaleY; lrt /= scaleY; gSP.bgImage.width *= scaleY; } */ s32 v0 = 0, v1 = 1, v2 = 2, v3 = 3; OGLRender & render = video().getRender(); SPVertex & vtx0 = render.getVertex(v0); vtx0.x = ulx; vtx0.y = uly; vtx0.z = z; vtx0.w = w; vtx0.s = uls; vtx0.t = ult; SPVertex & vtx1 = render.getVertex(v1); vtx1.x = lrx; vtx1.y = uly; vtx1.z = z; vtx1.w = w; vtx1.s = lrs; vtx1.t = ult; SPVertex & vtx2 = render.getVertex(v2); vtx2.x = ulx; vtx2.y = lry; vtx2.z = z; vtx2.w = w; vtx2.s = uls; vtx2.t = lrt; SPVertex & vtx3 = render.getVertex(v3); vtx3.x = lrx; vtx3.y = lry; vtx3.z = z; vtx3.w = w; vtx3.s = lrs; vtx3.t = lrt; render.drawLLETriangle(4); } while (RSP.nextCmd == 0xBD || RSP.nextCmd == 0xBE); } void gSPObjLoadTxSprite(u32 txsp) { gSPObjLoadTxtr( txsp ); gSPObjSprite( txsp + sizeof( uObjTxtr ) ); } void gSPObjLoadTxRect(u32 txsp) { gSPObjLoadTxtr(txsp); gSPObjRectangle(txsp + sizeof(uObjTxtr)); } void gSPObjLoadTxRectR(u32 txsp) { gSPObjLoadTxtr( txsp ); gSPObjRectangleR( txsp + sizeof( uObjTxtr ) ); } void gSPObjMatrix( u32 mtx ) { u32 address = RSP_SegmentToPhysical( mtx ); uObjMtx *objMtx = (uObjMtx*)&gfx_info.RDRAM[address]; gSP.objMatrix.A = _FIXED2FLOAT( objMtx->A, 16 ); gSP.objMatrix.B = _FIXED2FLOAT( objMtx->B, 16 ); gSP.objMatrix.C = _FIXED2FLOAT( objMtx->C, 16 ); gSP.objMatrix.D = _FIXED2FLOAT( objMtx->D, 16 ); gSP.objMatrix.X = _FIXED2FLOAT( objMtx->X, 2 ); gSP.objMatrix.Y = _FIXED2FLOAT( objMtx->Y, 2 ); gSP.objMatrix.baseScaleX = _FIXED2FLOAT( objMtx->BaseScaleX, 10 ); gSP.objMatrix.baseScaleY = _FIXED2FLOAT( objMtx->BaseScaleY, 10 ); } void gSPObjSubMatrix( u32 mtx ) { u32 address = RSP_SegmentToPhysical(mtx); uObjSubMtx *objMtx = (uObjSubMtx*)&gfx_info.RDRAM[address]; gSP.objMatrix.X = _FIXED2FLOAT(objMtx->X, 2); gSP.objMatrix.Y = _FIXED2FLOAT(objMtx->Y, 2); gSP.objMatrix.baseScaleX = _FIXED2FLOAT(objMtx->BaseScaleX, 10); gSP.objMatrix.baseScaleY = _FIXED2FLOAT(objMtx->BaseScaleY, 10); } void gSPObjRendermode(u32 _mode) { gSP.objRendermode = _mode; } #ifdef __VEC4_OPT void (*gSPTransformVertex4)(u32 v, float mtx[4][4]) = gSPTransformVertex4_default; void (*gSPTransformNormal4)(u32 v, float mtx[4][4]) = gSPTransformNormal4_default; void (*gSPLightVertex4)(u32 v) = gSPLightVertex4_default; void (*gSPPointLightVertex4)(u32 v, float _vPos[4][3]) = gSPPointLightVertex4_default; void (*gSPBillboardVertex4)(u32 v) = gSPBillboardVertex4_default; #endif void (*gSPTransformVertex)(float vtx[4], float mtx[4][4]) = gSPTransformVertex_default; void (*gSPLightVertex)(SPVertex & _vtx) = gSPLightVertex_default; void (*gSPPointLightVertex)(SPVertex & _vtx, float * _vPos) = gSPPointLightVertex_default; void (*gSPBillboardVertex)(u32 v, u32 i) = gSPBillboardVertex_default; void gSPSetupFunctions() { if (GBI.getMicrocodeType() != F3DEX2CBFD) { #ifdef __VEC4_OPT gSPLightVertex4 = gSPLightVertex4_default; gSPPointLightVertex4 = gSPPointLightVertex4_default; #endif gSPLightVertex = gSPLightVertex_default; gSPPointLightVertex = gSPPointLightVertex_default; return; } #ifdef __VEC4_OPT gSPLightVertex4 = gSPLightVertex4_CBFD; gSPPointLightVertex4 = gSPPointLightVertex4_CBFD; #endif gSPLightVertex = gSPLightVertex_CBFD; gSPPointLightVertex = gSPPointLightVertex_CBFD; } mupen64plus-video-gliden64/src/CMakeLists.txt000664 001750 001750 00000014047 12655644434 022174 0ustar00sergiosergio000000 000000 cmake_minimum_required(VERSION 2.6) option(GLES2 "Set to ON if targeting a GLES2 device" ${GLES2}) option(PANDORA "Set to ON if targeting an OpenPandora" ${PANDORA}) option(MUPENPLUSAPI "Set to ON for Mupen64Plus plugin" ${MUPENPLUSAPI}) project( GLideN64 ) set(GLideN64_SOURCES 3DMath.cpp Combiner.cpp CommonPluginAPI.cpp Config.cpp CRC.cpp DepthBuffer.cpp F3D.cpp F3DDKR.cpp F3DEX.cpp F3DPD.cpp F3DWRUS.cpp F3DSWSE.cpp F3DEX2.cpp F3DEX2CBFD.cpp FrameBuffer.cpp GBI.cpp gDP.cpp GLideN64.cpp glState.cpp gSP.cpp Keys.cpp L3D.cpp L3DEX2.cpp L3DEX.cpp N64.cpp OpenGL.cpp RDP.cpp RSP.cpp S2DEX2.cpp S2DEX.cpp Turbo3D.cpp ZSort.cpp ShaderUtils.cpp Textures.cpp TextDrawer.cpp PostProcessor.cpp VI.cpp common/CommonAPIImpl_common.cpp ) #check if we're running on Raspberry Pi MESSAGE("Looking for bcm_host.h") if(EXISTS "/opt/vc/include/bcm_host.h") MESSAGE("bcm_host.h found") set(BCMHOST ON) set(GLES2 ON) add_definitions( -DVC ) include_directories( "/opt/vc/include" "/opt/vc/include/interface/vcos" "/opt/vc/include/interface/vmcs_host/linux" "/opt/vc/include/interface/vcos/pthreads" ) link_directories( "/opt/vc/lib" ) else(EXISTS "/opt/vc/include/bcm_host.h") MESSAGE("bcm_host.h not found") endif(EXISTS "/opt/vc/include/bcm_host.h") if(MUPENPLUSAPI) add_definitions( -DMUPENPLUSAPI -DTXFILTER_LIB ) include_directories( inc ) set(GLideN64_SOURCES_UNIX MupenPlusPluginAPI.cpp mupenplus/Config_mupenplus.cpp mupenplus/CommonAPIImpl_mupenplus.cpp mupenplus/MupenPlusAPIImpl.cpp mupenplus/OpenGL_mupenplus.cpp ) set(GLideN64_SOURCES_WIN ${GLideN64_SOURCES_UNIX} windows/GLFunctions_windows.cpp ) set(GLideN64_DLL_NAME mupen64plus-video-GLideN64) else(MUPENPLUSAPI) if(NOT UNIX) message(ERROR "UNIX build requires MUPENPLUSAPI!") endif(NOT UNIX) set(GLideN64_SOURCES_WIN ZilmarPluginAPI.cpp windows/Config_windows.cpp windows/CommonAPIImpl_windows.cpp windows/GLideN64_windows.cpp windows/GLFunctions.cpp windows/OpenGL_windows.cpp windows/ZilmarAPIImpl_windows.cpp ) set(GLideN64_DLL_NAME GLideN64) endif(MUPENPLUSAPI) add_subdirectory( osal ) include_directories( osal ) add_subdirectory( GLideNHQ ) include_directories( GLideNHQ ) if(UNIX) list(APPEND GLideN64_SOURCES ${GLideN64_SOURCES_UNIX}) if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") add_definitions( -DOS_MAC_OS_X ) elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") add_definitions( -DOS_LINUX ) endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") endif(UNIX) if(WIN32) list(APPEND GLideN64_SOURCES ${GLideN64_SOURCES_WIN}) add_definitions( -DOS_WINDOWS -D__WIN32__ -DWIN32 -D_WIN32_ASM -D_CRT_SECURE_NO_WARNINGS -D__MSC__ ) endif(WIN32) if(SDL) include(FindPkgConfig) pkg_check_modules(SDL REQUIRED sdl) include_directories(${SDL_INCLUDE_DIRS}) add_definitions( -DUSE_SDL ) endif(SDL) if(PANDORA) #Pandora as a SGX530, but it should share the bugs and limitations as SGX540 add_definitions( -DPANDORA -DPowerVR_SGX_540 -DGLES2 ) endif(PANDORA) if(UNIX OR BCMHOST) SET( FREETYPE_INCLUDE_DIRS "/usr/include/freetype2/" ) else(UNIX OR BCMHOST) SET( ENV{FREETYPE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../../freetype ) endif(UNIX OR BCMHOST) FIND_PACKAGE( Freetype REQUIRED ) include_directories( ${FREETYPE_INCLUDE_DIRS} ) if(OPT) add_definitions( -D__VEC4_OPT ) endif(OPT) # Build type if( NOT CMAKE_BUILD_TYPE) set( CMAKE_BUILD_TYPE Release) endif( NOT CMAKE_BUILD_TYPE) if( CMAKE_BUILD_TYPE STREQUAL "Debug") set( CMAKE_BUILD_TYPE Debug) set( DEBUG_BUILD TRUE) # add_definitions( # -DDEBUG # ) endif( CMAKE_BUILD_TYPE STREQUAL "Debug") if(GLES2) add_definitions( -DGLES2 ) list(APPEND GLideN64_SOURCES GLES2/GLSLCombiner_gles2.cpp GLES2/UniformSet.cpp ) SET(OPENGL_LIBRARIES -lGLESv2 -lEGL) else(GLES2) find_package(OpenGL REQUIRED) include_directories(${OpenGL_INCLUDE_DIRS}) link_directories(${OpenGL_LIBRARY_DIRS}) add_definitions(${OpenGL_DEFINITIONS}) if(NOT OPENGL_FOUND) message(ERROR " OPENGL not found!") endif(NOT OPENGL_FOUND) list(APPEND GLideN64_SOURCES OGL3X/GLSLCombiner_ogl3x.cpp OGL3X/UniformBlock.cpp ) endif(GLES2) if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") #check for G++ 4.8+ execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE G++_VERSION) if (G++_VERSION VERSION_LESS 4.8) message(SEND_ERROR "You need at least G++ 4.8 to compile GLideN64!") endif() SET(GCC_CPP11_COMPILE_FLAGS "-std=c++0x -static-libgcc -static-libstdc++") SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_CPP11_COMPILE_FLAGS}" ) SET(GCC_STATIC_LINK_FLAGS "-static-libgcc -static-libstdc++") SET( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_STATIC_LINK_FLAGS}" ) endif() add_library( ${GLideN64_DLL_NAME} SHARED ${GLideN64_SOURCES}) if( CMAKE_BUILD_TYPE STREQUAL "Debug") SET_TARGET_PROPERTIES( ${GLideN64_DLL_NAME} PROPERTIES LINKER_LANGUAGE CXX # Or else we get an error message, because cmake can't figure out from the ".o"-suffix that it is a C-linker we need. PREFIX "" LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/plugin/debug ) if(SDL) target_link_libraries(${GLideN64_DLL_NAME} PRIVATE ${OPENGL_LIBRARIES} ${SDL_LIBRARIES} ${FREETYPE_LIBRARIES} osald GLideNHQd ) else(SDL) target_link_libraries(${GLideN64_DLL_NAME} PRIVATE ${OPENGL_LIBRARIES} ${FREETYPE_LIBRARIES} osald GLideNHQd ) endif(SDL) endif( CMAKE_BUILD_TYPE STREQUAL "Debug") if( CMAKE_BUILD_TYPE STREQUAL "Release") SET_TARGET_PROPERTIES( ${GLideN64_DLL_NAME} PROPERTIES LINKER_LANGUAGE CXX # Or else we get an error message, because cmake can't figure out from the ".o"-suffix that it is a C-linker we need. PREFIX "" LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/plugin/release ) if(SDL) target_link_libraries(${GLideN64_DLL_NAME} ${OPENGL_LIBRARIES} ${SDL_LIBRARIES} ${FREETYPE_LIBRARIES} osal GLideNHQ ) else(SDL) target_link_libraries(${GLideN64_DLL_NAME} ${OPENGL_LIBRARIES} ${FREETYPE_LIBRARIES} osal GLideNHQ ) endif(SDL) endif( CMAKE_BUILD_TYPE STREQUAL "Release") mupen64plus-core/src/pi/000700 001750 001750 00000000000 12656647145 016235 5ustar00sergiosergio000000 000000 mupen64plus-core/src/r4300/recomp.c000664 001750 001750 00000204473 12655644434 020051 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - recomp.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #if defined(__GNUC__) #include #ifndef __MINGW32__ #include #endif #endif #include "api/m64p_types.h" #include "api/callbacks.h" #include "memory/memory.h" #include "cached_interp.h" #include "recomp.h" #include "recomph.h" //include for function prototypes #include "cp0_private.h" #include "r4300.h" #include "ops.h" #include "tlb.h" static void *malloc_exec(size_t size); static void free_exec(void *ptr, size_t length); // global variables : precomp_instr *dst; // destination structure for the recompiled instruction int code_length; // current real recompiled code length int max_code_length; // current recompiled code's buffer length unsigned char **inst_pointer; // output buffer for recompiled code precomp_block *dst_block; // the current block that we are recompiling uint32_t src; // the current recompiled instruction int fast_memory; int no_compiled_jump = 0; /* use cached interpreter instead of recompiler for jumps */ static void (*recomp_func)(void); // pointer to the dynarec's generator // function for the latest decoded opcode static const uint32_t *SRC; // currently recompiled instruction in the input stream static int check_nop; // next instruction is nop ? static int delay_slot_compiled = 0; static void RSV(void) { dst->ops = current_instruction_table.RESERVED; recomp_func = genreserved; } static void RFIN_BLOCK(void) { dst->ops = current_instruction_table.FIN_BLOCK; recomp_func = genfin_block; } static void RNOTCOMPILED(void) { dst->ops = current_instruction_table.NOTCOMPILED; recomp_func = gennotcompiled; } static void recompile_standard_i_type(void) { dst->f.i.rs = reg + ((src >> 21) & 0x1F); dst->f.i.rt = reg + ((src >> 16) & 0x1F); dst->f.i.immediate = (int16_t)src; } static void recompile_standard_j_type(void) { dst->f.j.inst_index = src & UINT32_C(0x3FFFFFF); } static void recompile_standard_r_type(void) { dst->f.r.rs = reg + ((src >> 21) & 0x1F); dst->f.r.rt = reg + ((src >> 16) & 0x1F); dst->f.r.rd = reg + ((src >> 11) & 0x1F); dst->f.r.sa = (src >> 6) & 0x1F; } static void recompile_standard_lf_type(void) { dst->f.lf.base = (src >> 21) & 0x1F; dst->f.lf.ft = (src >> 16) & 0x1F; dst->f.lf.offset = src & 0xFFFF; } static void recompile_standard_cf_type(void) { dst->f.cf.ft = (src >> 16) & 0x1F; dst->f.cf.fs = (src >> 11) & 0x1F; dst->f.cf.fd = (src >> 6) & 0x1F; } //------------------------------------------------------------------------- // SPECIAL //------------------------------------------------------------------------- static void RNOP(void) { dst->ops = current_instruction_table.NOP; recomp_func = gennop; } static void RSLL(void) { dst->ops = current_instruction_table.SLL; recomp_func = gensll; recompile_standard_r_type(); if (dst->f.r.rd == reg) RNOP(); } static void RSRL(void) { dst->ops = current_instruction_table.SRL; recomp_func = gensrl; recompile_standard_r_type(); if (dst->f.r.rd == reg) RNOP(); } static void RSRA(void) { dst->ops = current_instruction_table.SRA; recomp_func = gensra; recompile_standard_r_type(); if (dst->f.r.rd == reg) RNOP(); } static void RSLLV(void) { dst->ops = current_instruction_table.SLLV; recomp_func = gensllv; recompile_standard_r_type(); if (dst->f.r.rd == reg) RNOP(); } static void RSRLV(void) { dst->ops = current_instruction_table.SRLV; recomp_func = gensrlv; recompile_standard_r_type(); if (dst->f.r.rd == reg) RNOP(); } static void RSRAV(void) { dst->ops = current_instruction_table.SRAV; recomp_func = gensrav; recompile_standard_r_type(); if (dst->f.r.rd == reg) RNOP(); } static void RJR(void) { dst->ops = current_instruction_table.JR; recomp_func = genjr; recompile_standard_i_type(); } static void RJALR(void) { dst->ops = current_instruction_table.JALR; recomp_func = genjalr; recompile_standard_r_type(); } static void RSYSCALL(void) { dst->ops = current_instruction_table.SYSCALL; recomp_func = gensyscall; } static void RBREAK(void) { dst->ops = current_instruction_table.NI; recomp_func = genni; } static void RSYNC(void) { dst->ops = current_instruction_table.SYNC; recomp_func = gensync; } static void RMFHI(void) { dst->ops = current_instruction_table.MFHI; recomp_func = genmfhi; recompile_standard_r_type(); if (dst->f.r.rd == reg) RNOP(); } static void RMTHI(void) { dst->ops = current_instruction_table.MTHI; recomp_func = genmthi; recompile_standard_r_type(); } static void RMFLO(void) { dst->ops = current_instruction_table.MFLO; recomp_func = genmflo; recompile_standard_r_type(); if (dst->f.r.rd == reg) RNOP(); } static void RMTLO(void) { dst->ops = current_instruction_table.MTLO; recomp_func = genmtlo; recompile_standard_r_type(); } static void RDSLLV(void) { dst->ops = current_instruction_table.DSLLV; recomp_func = gendsllv; recompile_standard_r_type(); if (dst->f.r.rd == reg) RNOP(); } static void RDSRLV(void) { dst->ops = current_instruction_table.DSRLV; recomp_func = gendsrlv; recompile_standard_r_type(); if (dst->f.r.rd == reg) RNOP(); } static void RDSRAV(void) { dst->ops = current_instruction_table.DSRAV; recomp_func = gendsrav; recompile_standard_r_type(); if (dst->f.r.rd == reg) RNOP(); } static void RMULT(void) { dst->ops = current_instruction_table.MULT; recomp_func = genmult; recompile_standard_r_type(); } static void RMULTU(void) { dst->ops = current_instruction_table.MULTU; recomp_func = genmultu; recompile_standard_r_type(); } static void RDIV(void) { dst->ops = current_instruction_table.DIV; recomp_func = gendiv; recompile_standard_r_type(); } static void RDIVU(void) { dst->ops = current_instruction_table.DIVU; recomp_func = gendivu; recompile_standard_r_type(); } static void RDMULT(void) { dst->ops = current_instruction_table.DMULT; recomp_func = gendmult; recompile_standard_r_type(); } static void RDMULTU(void) { dst->ops = current_instruction_table.DMULTU; recomp_func = gendmultu; recompile_standard_r_type(); } static void RDDIV(void) { dst->ops = current_instruction_table.DDIV; recomp_func = genddiv; recompile_standard_r_type(); } static void RDDIVU(void) { dst->ops = current_instruction_table.DDIVU; recomp_func = genddivu; recompile_standard_r_type(); } static void RADD(void) { dst->ops = current_instruction_table.ADD; recomp_func = genadd; recompile_standard_r_type(); if (dst->f.r.rd == reg) RNOP(); } static void RADDU(void) { dst->ops = current_instruction_table.ADDU; recomp_func = genaddu; recompile_standard_r_type(); if (dst->f.r.rd == reg) RNOP(); } static void RSUB(void) { dst->ops = current_instruction_table.SUB; recomp_func = gensub; recompile_standard_r_type(); if (dst->f.r.rd == reg) RNOP(); } static void RSUBU(void) { dst->ops = current_instruction_table.SUBU; recomp_func = gensubu; recompile_standard_r_type(); if (dst->f.r.rd == reg) RNOP(); } static void RAND(void) { dst->ops = current_instruction_table.AND; recomp_func = genand; recompile_standard_r_type(); if(dst->f.r.rd == reg) RNOP(); } static void ROR(void) { dst->ops = current_instruction_table.OR; recomp_func = genor; recompile_standard_r_type(); if(dst->f.r.rd == reg) RNOP(); } static void RXOR(void) { dst->ops = current_instruction_table.XOR; recomp_func = genxor; recompile_standard_r_type(); if(dst->f.r.rd == reg) RNOP(); } static void RNOR(void) { dst->ops = current_instruction_table.NOR; recomp_func = gennor; recompile_standard_r_type(); if(dst->f.r.rd == reg) RNOP(); } static void RSLT(void) { dst->ops = current_instruction_table.SLT; recomp_func = genslt; recompile_standard_r_type(); if(dst->f.r.rd == reg) RNOP(); } static void RSLTU(void) { dst->ops = current_instruction_table.SLTU; recomp_func = gensltu; recompile_standard_r_type(); if(dst->f.r.rd == reg) RNOP(); } static void RDADD(void) { dst->ops = current_instruction_table.DADD; recomp_func = gendadd; recompile_standard_r_type(); if (dst->f.r.rd == reg) RNOP(); } static void RDADDU(void) { dst->ops = current_instruction_table.DADDU; recomp_func = gendaddu; recompile_standard_r_type(); if (dst->f.r.rd == reg) RNOP(); } static void RDSUB(void) { dst->ops = current_instruction_table.DSUB; recomp_func = gendsub; recompile_standard_r_type(); if (dst->f.r.rd == reg) RNOP(); } static void RDSUBU(void) { dst->ops = current_instruction_table.DSUBU; recomp_func = gendsubu; recompile_standard_r_type(); if (dst->f.r.rd == reg) RNOP(); } static void RTGE(void) { dst->ops = current_instruction_table.NI; recomp_func = genni; } static void RTGEU(void) { dst->ops = current_instruction_table.NI; recomp_func = genni; } static void RTLT(void) { dst->ops = current_instruction_table.NI; recomp_func = genni; } static void RTLTU(void) { dst->ops = current_instruction_table.NI; recomp_func = genni; } static void RTEQ(void) { dst->ops = current_instruction_table.TEQ; recomp_func = genteq; recompile_standard_r_type(); } static void RTNE(void) { dst->ops = current_instruction_table.NI; recomp_func = genni; } static void RDSLL(void) { dst->ops = current_instruction_table.DSLL; recomp_func = gendsll; recompile_standard_r_type(); if (dst->f.r.rd == reg) RNOP(); } static void RDSRL(void) { dst->ops = current_instruction_table.DSRL; recomp_func = gendsrl; recompile_standard_r_type(); if (dst->f.r.rd == reg) RNOP(); } static void RDSRA(void) { dst->ops = current_instruction_table.DSRA; recomp_func = gendsra; recompile_standard_r_type(); if (dst->f.r.rd == reg) RNOP(); } static void RDSLL32(void) { dst->ops = current_instruction_table.DSLL32; recomp_func = gendsll32; recompile_standard_r_type(); if (dst->f.r.rd == reg) RNOP(); } static void RDSRL32(void) { dst->ops = current_instruction_table.DSRL32; recomp_func = gendsrl32; recompile_standard_r_type(); if (dst->f.r.rd == reg) RNOP(); } static void RDSRA32(void) { dst->ops = current_instruction_table.DSRA32; recomp_func = gendsra32; recompile_standard_r_type(); if (dst->f.r.rd == reg) RNOP(); } static void (*recomp_special[64])(void) = { RSLL , RSV , RSRL , RSRA , RSLLV , RSV , RSRLV , RSRAV , RJR , RJALR , RSV , RSV , RSYSCALL, RBREAK , RSV , RSYNC , RMFHI, RMTHI , RMFLO, RMTLO, RDSLLV , RSV , RDSRLV , RDSRAV , RMULT, RMULTU, RDIV , RDIVU, RDMULT , RDMULTU, RDDIV , RDDIVU , RADD , RADDU , RSUB , RSUBU, RAND , ROR , RXOR , RNOR , RSV , RSV , RSLT , RSLTU, RDADD , RDADDU , RDSUB , RDSUBU , RTGE , RTGEU , RTLT , RTLTU, RTEQ , RSV , RTNE , RSV , RDSLL, RSV , RDSRL, RDSRA, RDSLL32 , RSV , RDSRL32, RDSRA32 }; //------------------------------------------------------------------------- // REGIMM //------------------------------------------------------------------------- static void RBLTZ(void) { uint32_t target; dst->ops = current_instruction_table.BLTZ; recomp_func = genbltz; recompile_standard_i_type(); target = dst->addr + dst->f.i.immediate*4 + 4; if (target == dst->addr) { if (check_nop) { dst->ops = current_instruction_table.BLTZ_IDLE; recomp_func = genbltz_idle; } } else if (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)) { dst->ops = current_instruction_table.BLTZ_OUT; recomp_func = genbltz_out; } } static void RBGEZ(void) { uint32_t target; dst->ops = current_instruction_table.BGEZ; recomp_func = genbgez; recompile_standard_i_type(); target = dst->addr + dst->f.i.immediate*4 + 4; if (target == dst->addr) { if (check_nop) { dst->ops = current_instruction_table.BGEZ_IDLE; recomp_func = genbgez_idle; } } else if (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)) { dst->ops = current_instruction_table.BGEZ_OUT; recomp_func = genbgez_out; } } static void RBLTZL(void) { uint32_t target; dst->ops = current_instruction_table.BLTZL; recomp_func = genbltzl; recompile_standard_i_type(); target = dst->addr + dst->f.i.immediate*4 + 4; if (target == dst->addr) { if (check_nop) { dst->ops = current_instruction_table.BLTZL_IDLE; recomp_func = genbltzl_idle; } } else if (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)) { dst->ops = current_instruction_table.BLTZL_OUT; recomp_func = genbltzl_out; } } static void RBGEZL(void) { uint32_t target; dst->ops = current_instruction_table.BGEZL; recomp_func = genbgezl; recompile_standard_i_type(); target = dst->addr + dst->f.i.immediate*4 + 4; if (target == dst->addr) { if (check_nop) { dst->ops = current_instruction_table.BGEZL_IDLE; recomp_func = genbgezl_idle; } } else if (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)) { dst->ops = current_instruction_table.BGEZL_OUT; recomp_func = genbgezl_out; } } static void RTGEI(void) { dst->ops = current_instruction_table.NI; recomp_func = genni; } static void RTGEIU(void) { dst->ops = current_instruction_table.NI; recomp_func = genni; } static void RTLTI(void) { dst->ops = current_instruction_table.NI; recomp_func = genni; } static void RTLTIU(void) { dst->ops = current_instruction_table.NI; recomp_func = genni; } static void RTEQI(void) { dst->ops = current_instruction_table.NI; recomp_func = genni; } static void RTNEI(void) { dst->ops = current_instruction_table.NI; recomp_func = genni; } static void RBLTZAL(void) { uint32_t target; dst->ops = current_instruction_table.BLTZAL; recomp_func = genbltzal; recompile_standard_i_type(); target = dst->addr + dst->f.i.immediate*4 + 4; if (target == dst->addr) { if (check_nop) { dst->ops = current_instruction_table.BLTZAL_IDLE; recomp_func = genbltzal_idle; } } else if (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)) { dst->ops = current_instruction_table.BLTZAL_OUT; recomp_func = genbltzal_out; } } static void RBGEZAL(void) { uint32_t target; dst->ops = current_instruction_table.BGEZAL; recomp_func = genbgezal; recompile_standard_i_type(); target = dst->addr + dst->f.i.immediate*4 + 4; if (target == dst->addr) { if (check_nop) { dst->ops = current_instruction_table.BGEZAL_IDLE; recomp_func = genbgezal_idle; } } else if (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)) { dst->ops = current_instruction_table.BGEZAL_OUT; recomp_func = genbgezal_out; } } static void RBLTZALL(void) { uint32_t target; dst->ops = current_instruction_table.BLTZALL; recomp_func = genbltzall; recompile_standard_i_type(); target = dst->addr + dst->f.i.immediate*4 + 4; if (target == dst->addr) { if (check_nop) { dst->ops = current_instruction_table.BLTZALL_IDLE; recomp_func = genbltzall_idle; } } else if (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)) { dst->ops = current_instruction_table.BLTZALL_OUT; recomp_func = genbltzall_out; } } static void RBGEZALL(void) { uint32_t target; dst->ops = current_instruction_table.BGEZALL; recomp_func = genbgezall; recompile_standard_i_type(); target = dst->addr + dst->f.i.immediate*4 + 4; if (target == dst->addr) { if (check_nop) { dst->ops = current_instruction_table.BGEZALL_IDLE; recomp_func = genbgezall_idle; } } else if (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)) { dst->ops = current_instruction_table.BGEZALL_OUT; recomp_func = genbgezall_out; } } static void (*recomp_regimm[32])(void) = { RBLTZ , RBGEZ , RBLTZL , RBGEZL , RSV , RSV, RSV , RSV, RTGEI , RTGEIU , RTLTI , RTLTIU , RTEQI, RSV, RTNEI, RSV, RBLTZAL, RBGEZAL, RBLTZALL, RBGEZALL, RSV , RSV, RSV , RSV, RSV , RSV , RSV , RSV , RSV , RSV, RSV , RSV }; //------------------------------------------------------------------------- // TLB //------------------------------------------------------------------------- static void RTLBR(void) { dst->ops = current_instruction_table.TLBR; recomp_func = gentlbr; } static void RTLBWI(void) { dst->ops = current_instruction_table.TLBWI; recomp_func = gentlbwi; } static void RTLBWR(void) { dst->ops = current_instruction_table.TLBWR; recomp_func = gentlbwr; } static void RTLBP(void) { dst->ops = current_instruction_table.TLBP; recomp_func = gentlbp; } static void RERET(void) { dst->ops = current_instruction_table.ERET; recomp_func = generet; } static void (*recomp_tlb[64])(void) = { RSV , RTLBR, RTLBWI, RSV, RSV, RSV, RTLBWR, RSV, RTLBP, RSV , RSV , RSV, RSV, RSV, RSV , RSV, RSV , RSV , RSV , RSV, RSV, RSV, RSV , RSV, RERET, RSV , RSV , RSV, RSV, RSV, RSV , RSV, RSV , RSV , RSV , RSV, RSV, RSV, RSV , RSV, RSV , RSV , RSV , RSV, RSV, RSV, RSV , RSV, RSV , RSV , RSV , RSV, RSV, RSV, RSV , RSV, RSV , RSV , RSV , RSV, RSV, RSV, RSV , RSV }; //------------------------------------------------------------------------- // COP0 //------------------------------------------------------------------------- static void RMFC0(void) { dst->ops = current_instruction_table.MFC0; recomp_func = genmfc0; recompile_standard_r_type(); dst->f.r.rd = (int64_t*)(g_cp0_regs + ((src >> 11) & 0x1F)); dst->f.r.nrd = (src >> 11) & 0x1F; if (dst->f.r.rt == reg) RNOP(); } static void RMTC0(void) { dst->ops = current_instruction_table.MTC0; recomp_func = genmtc0; recompile_standard_r_type(); dst->f.r.nrd = (src >> 11) & 0x1F; } static void RTLB(void) { recomp_tlb[(src & 0x3F)](); } static void (*recomp_cop0[32])(void) = { RMFC0, RSV, RSV, RSV, RMTC0, RSV, RSV, RSV, RSV , RSV, RSV, RSV, RSV , RSV, RSV, RSV, RTLB , RSV, RSV, RSV, RSV , RSV, RSV, RSV, RSV , RSV, RSV, RSV, RSV , RSV, RSV, RSV }; //------------------------------------------------------------------------- // BC //------------------------------------------------------------------------- static void RBC1F(void) { uint32_t target; dst->ops = current_instruction_table.BC1F; recomp_func = genbc1f; recompile_standard_i_type(); target = dst->addr + dst->f.i.immediate*4 + 4; if (target == dst->addr) { if (check_nop) { dst->ops = current_instruction_table.BC1F_IDLE; recomp_func = genbc1f_idle; } } else if (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)) { dst->ops = current_instruction_table.BC1F_OUT; recomp_func = genbc1f_out; } } static void RBC1T(void) { uint32_t target; dst->ops = current_instruction_table.BC1T; recomp_func = genbc1t; recompile_standard_i_type(); target = dst->addr + dst->f.i.immediate*4 + 4; if (target == dst->addr) { if (check_nop) { dst->ops = current_instruction_table.BC1T_IDLE; recomp_func = genbc1t_idle; } } else if (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)) { dst->ops = current_instruction_table.BC1T_OUT; recomp_func = genbc1t_out; } } static void RBC1FL(void) { uint32_t target; dst->ops = current_instruction_table.BC1FL; recomp_func = genbc1fl; recompile_standard_i_type(); target = dst->addr + dst->f.i.immediate*4 + 4; if (target == dst->addr) { if (check_nop) { dst->ops = current_instruction_table.BC1FL_IDLE; recomp_func = genbc1fl_idle; } } else if (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)) { dst->ops = current_instruction_table.BC1FL_OUT; recomp_func = genbc1fl_out; } } static void RBC1TL(void) { uint32_t target; dst->ops = current_instruction_table.BC1TL; recomp_func = genbc1tl; recompile_standard_i_type(); target = dst->addr + dst->f.i.immediate*4 + 4; if (target == dst->addr) { if (check_nop) { dst->ops = current_instruction_table.BC1TL_IDLE; recomp_func = genbc1tl_idle; } } else if (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)) { dst->ops = current_instruction_table.BC1TL_OUT; recomp_func = genbc1tl_out; } } static void (*recomp_bc[4])(void) = { RBC1F , RBC1T , RBC1FL, RBC1TL }; //------------------------------------------------------------------------- // S //------------------------------------------------------------------------- static void RADD_S(void) { dst->ops = current_instruction_table.ADD_S; recomp_func = genadd_s; recompile_standard_cf_type(); } static void RSUB_S(void) { dst->ops = current_instruction_table.SUB_S; recomp_func = gensub_s; recompile_standard_cf_type(); } static void RMUL_S(void) { dst->ops = current_instruction_table.MUL_S; recomp_func = genmul_s; recompile_standard_cf_type(); } static void RDIV_S(void) { dst->ops = current_instruction_table.DIV_S; recomp_func = gendiv_s; recompile_standard_cf_type(); } static void RSQRT_S(void) { dst->ops = current_instruction_table.SQRT_S; recomp_func = gensqrt_s; recompile_standard_cf_type(); } static void RABS_S(void) { dst->ops = current_instruction_table.ABS_S; recomp_func = genabs_s; recompile_standard_cf_type(); } static void RMOV_S(void) { dst->ops = current_instruction_table.MOV_S; recomp_func = genmov_s; recompile_standard_cf_type(); } static void RNEG_S(void) { dst->ops = current_instruction_table.NEG_S; recomp_func = genneg_s; recompile_standard_cf_type(); } static void RROUND_L_S(void) { dst->ops = current_instruction_table.ROUND_L_S; recomp_func = genround_l_s; recompile_standard_cf_type(); } static void RTRUNC_L_S(void) { dst->ops = current_instruction_table.TRUNC_L_S; recomp_func = gentrunc_l_s; recompile_standard_cf_type(); } static void RCEIL_L_S(void) { dst->ops = current_instruction_table.CEIL_L_S; recomp_func = genceil_l_s; recompile_standard_cf_type(); } static void RFLOOR_L_S(void) { dst->ops = current_instruction_table.FLOOR_L_S; recomp_func = genfloor_l_s; recompile_standard_cf_type(); } static void RROUND_W_S(void) { dst->ops = current_instruction_table.ROUND_W_S; recomp_func = genround_w_s; recompile_standard_cf_type(); } static void RTRUNC_W_S(void) { dst->ops = current_instruction_table.TRUNC_W_S; recomp_func = gentrunc_w_s; recompile_standard_cf_type(); } static void RCEIL_W_S(void) { dst->ops = current_instruction_table.CEIL_W_S; recomp_func = genceil_w_s; recompile_standard_cf_type(); } static void RFLOOR_W_S(void) { dst->ops = current_instruction_table.FLOOR_W_S; recomp_func = genfloor_w_s; recompile_standard_cf_type(); } static void RCVT_D_S(void) { dst->ops = current_instruction_table.CVT_D_S; recomp_func = gencvt_d_s; recompile_standard_cf_type(); } static void RCVT_W_S(void) { dst->ops = current_instruction_table.CVT_W_S; recomp_func = gencvt_w_s; recompile_standard_cf_type(); } static void RCVT_L_S(void) { dst->ops = current_instruction_table.CVT_L_S; recomp_func = gencvt_l_s; recompile_standard_cf_type(); } static void RC_F_S(void) { dst->ops = current_instruction_table.C_F_S; recomp_func = genc_f_s; recompile_standard_cf_type(); } static void RC_UN_S(void) { dst->ops = current_instruction_table.C_UN_S; recomp_func = genc_un_s; recompile_standard_cf_type(); } static void RC_EQ_S(void) { dst->ops = current_instruction_table.C_EQ_S; recomp_func = genc_eq_s; recompile_standard_cf_type(); } static void RC_UEQ_S(void) { dst->ops = current_instruction_table.C_UEQ_S; recomp_func = genc_ueq_s; recompile_standard_cf_type(); } static void RC_OLT_S(void) { dst->ops = current_instruction_table.C_OLT_S; recomp_func = genc_olt_s; recompile_standard_cf_type(); } static void RC_ULT_S(void) { dst->ops = current_instruction_table.C_ULT_S; recomp_func = genc_ult_s; recompile_standard_cf_type(); } static void RC_OLE_S(void) { dst->ops = current_instruction_table.C_OLE_S; recomp_func = genc_ole_s; recompile_standard_cf_type(); } static void RC_ULE_S(void) { dst->ops = current_instruction_table.C_ULE_S; recomp_func = genc_ule_s; recompile_standard_cf_type(); } static void RC_SF_S(void) { dst->ops = current_instruction_table.C_SF_S; recomp_func = genc_sf_s; recompile_standard_cf_type(); } static void RC_NGLE_S(void) { dst->ops = current_instruction_table.C_NGLE_S; recomp_func = genc_ngle_s; recompile_standard_cf_type(); } static void RC_SEQ_S(void) { dst->ops = current_instruction_table.C_SEQ_S; recomp_func = genc_seq_s; recompile_standard_cf_type(); } static void RC_NGL_S(void) { dst->ops = current_instruction_table.C_NGL_S; recomp_func = genc_ngl_s; recompile_standard_cf_type(); } static void RC_LT_S(void) { dst->ops = current_instruction_table.C_LT_S; recomp_func = genc_lt_s; recompile_standard_cf_type(); } static void RC_NGE_S(void) { dst->ops = current_instruction_table.C_NGE_S; recomp_func = genc_nge_s; recompile_standard_cf_type(); } static void RC_LE_S(void) { dst->ops = current_instruction_table.C_LE_S; recomp_func = genc_le_s; recompile_standard_cf_type(); } static void RC_NGT_S(void) { dst->ops = current_instruction_table.C_NGT_S; recomp_func = genc_ngt_s; recompile_standard_cf_type(); } static void (*recomp_s[64])(void) = { RADD_S , RSUB_S , RMUL_S , RDIV_S , RSQRT_S , RABS_S , RMOV_S , RNEG_S , RROUND_L_S, RTRUNC_L_S, RCEIL_L_S, RFLOOR_L_S, RROUND_W_S, RTRUNC_W_S, RCEIL_W_S, RFLOOR_W_S, RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RCVT_D_S , RSV , RSV , RCVT_W_S , RCVT_L_S , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RC_F_S , RC_UN_S , RC_EQ_S , RC_UEQ_S , RC_OLT_S , RC_ULT_S , RC_OLE_S , RC_ULE_S , RC_SF_S , RC_NGLE_S , RC_SEQ_S , RC_NGL_S , RC_LT_S , RC_NGE_S , RC_LE_S , RC_NGT_S }; //------------------------------------------------------------------------- // D //------------------------------------------------------------------------- static void RADD_D(void) { dst->ops = current_instruction_table.ADD_D; recomp_func = genadd_d; recompile_standard_cf_type(); } static void RSUB_D(void) { dst->ops = current_instruction_table.SUB_D; recomp_func = gensub_d; recompile_standard_cf_type(); } static void RMUL_D(void) { dst->ops = current_instruction_table.MUL_D; recomp_func = genmul_d; recompile_standard_cf_type(); } static void RDIV_D(void) { dst->ops = current_instruction_table.DIV_D; recomp_func = gendiv_d; recompile_standard_cf_type(); } static void RSQRT_D(void) { dst->ops = current_instruction_table.SQRT_D; recomp_func = gensqrt_d; recompile_standard_cf_type(); } static void RABS_D(void) { dst->ops = current_instruction_table.ABS_D; recomp_func = genabs_d; recompile_standard_cf_type(); } static void RMOV_D(void) { dst->ops = current_instruction_table.MOV_D; recomp_func = genmov_d; recompile_standard_cf_type(); } static void RNEG_D(void) { dst->ops = current_instruction_table.NEG_D; recomp_func = genneg_d; recompile_standard_cf_type(); } static void RROUND_L_D(void) { dst->ops = current_instruction_table.ROUND_L_D; recomp_func = genround_l_d; recompile_standard_cf_type(); } static void RTRUNC_L_D(void) { dst->ops = current_instruction_table.TRUNC_L_D; recomp_func = gentrunc_l_d; recompile_standard_cf_type(); } static void RCEIL_L_D(void) { dst->ops = current_instruction_table.CEIL_L_D; recomp_func = genceil_l_d; recompile_standard_cf_type(); } static void RFLOOR_L_D(void) { dst->ops = current_instruction_table.FLOOR_L_D; recomp_func = genfloor_l_d; recompile_standard_cf_type(); } static void RROUND_W_D(void) { dst->ops = current_instruction_table.ROUND_W_D; recomp_func = genround_w_d; recompile_standard_cf_type(); } static void RTRUNC_W_D(void) { dst->ops = current_instruction_table.TRUNC_W_D; recomp_func = gentrunc_w_d; recompile_standard_cf_type(); } static void RCEIL_W_D(void) { dst->ops = current_instruction_table.CEIL_W_D; recomp_func = genceil_w_d; recompile_standard_cf_type(); } static void RFLOOR_W_D(void) { dst->ops = current_instruction_table.FLOOR_W_D; recomp_func = genfloor_w_d; recompile_standard_cf_type(); } static void RCVT_S_D(void) { dst->ops = current_instruction_table.CVT_S_D; recomp_func = gencvt_s_d; recompile_standard_cf_type(); } static void RCVT_W_D(void) { dst->ops = current_instruction_table.CVT_W_D; recomp_func = gencvt_w_d; recompile_standard_cf_type(); } static void RCVT_L_D(void) { dst->ops = current_instruction_table.CVT_L_D; recomp_func = gencvt_l_d; recompile_standard_cf_type(); } static void RC_F_D(void) { dst->ops = current_instruction_table.C_F_D; recomp_func = genc_f_d; recompile_standard_cf_type(); } static void RC_UN_D(void) { dst->ops = current_instruction_table.C_UN_D; recomp_func = genc_un_d; recompile_standard_cf_type(); } static void RC_EQ_D(void) { dst->ops = current_instruction_table.C_EQ_D; recomp_func = genc_eq_d; recompile_standard_cf_type(); } static void RC_UEQ_D(void) { dst->ops = current_instruction_table.C_UEQ_D; recomp_func = genc_ueq_d; recompile_standard_cf_type(); } static void RC_OLT_D(void) { dst->ops = current_instruction_table.C_OLT_D; recomp_func = genc_olt_d; recompile_standard_cf_type(); } static void RC_ULT_D(void) { dst->ops = current_instruction_table.C_ULT_D; recomp_func = genc_ult_d; recompile_standard_cf_type(); } static void RC_OLE_D(void) { dst->ops = current_instruction_table.C_OLE_D; recomp_func = genc_ole_d; recompile_standard_cf_type(); } static void RC_ULE_D(void) { dst->ops = current_instruction_table.C_ULE_D; recomp_func = genc_ule_d; recompile_standard_cf_type(); } static void RC_SF_D(void) { dst->ops = current_instruction_table.C_SF_D; recomp_func = genc_sf_d; recompile_standard_cf_type(); } static void RC_NGLE_D(void) { dst->ops = current_instruction_table.C_NGLE_D; recomp_func = genc_ngle_d; recompile_standard_cf_type(); } static void RC_SEQ_D(void) { dst->ops = current_instruction_table.C_SEQ_D; recomp_func = genc_seq_d; recompile_standard_cf_type(); } static void RC_NGL_D(void) { dst->ops = current_instruction_table.C_NGL_D; recomp_func = genc_ngl_d; recompile_standard_cf_type(); } static void RC_LT_D(void) { dst->ops = current_instruction_table.C_LT_D; recomp_func = genc_lt_d; recompile_standard_cf_type(); } static void RC_NGE_D(void) { dst->ops = current_instruction_table.C_NGE_D; recomp_func = genc_nge_d; recompile_standard_cf_type(); } static void RC_LE_D(void) { dst->ops = current_instruction_table.C_LE_D; recomp_func = genc_le_d; recompile_standard_cf_type(); } static void RC_NGT_D(void) { dst->ops = current_instruction_table.C_NGT_D; recomp_func = genc_ngt_d; recompile_standard_cf_type(); } static void (*recomp_d[64])(void) = { RADD_D , RSUB_D , RMUL_D , RDIV_D , RSQRT_D , RABS_D , RMOV_D , RNEG_D , RROUND_L_D, RTRUNC_L_D, RCEIL_L_D, RFLOOR_L_D, RROUND_W_D, RTRUNC_W_D, RCEIL_W_D, RFLOOR_W_D, RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RCVT_S_D , RSV , RSV , RSV , RCVT_W_D , RCVT_L_D , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV , RC_F_D , RC_UN_D , RC_EQ_D , RC_UEQ_D , RC_OLT_D , RC_ULT_D , RC_OLE_D , RC_ULE_D , RC_SF_D , RC_NGLE_D , RC_SEQ_D , RC_NGL_D , RC_LT_D , RC_NGE_D , RC_LE_D , RC_NGT_D }; //------------------------------------------------------------------------- // W //------------------------------------------------------------------------- static void RCVT_S_W(void) { dst->ops = current_instruction_table.CVT_S_W; recomp_func = gencvt_s_w; recompile_standard_cf_type(); } static void RCVT_D_W(void) { dst->ops = current_instruction_table.CVT_D_W; recomp_func = gencvt_d_w; recompile_standard_cf_type(); } static void (*recomp_w[64])(void) = { RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV, RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV, RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV, RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV, RCVT_S_W, RCVT_D_W, RSV, RSV, RSV, RSV, RSV, RSV, RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV, RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV, RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV }; //------------------------------------------------------------------------- // L //------------------------------------------------------------------------- static void RCVT_S_L(void) { dst->ops = current_instruction_table.CVT_S_L; recomp_func = gencvt_s_l; recompile_standard_cf_type(); } static void RCVT_D_L(void) { dst->ops = current_instruction_table.CVT_D_L; recomp_func = gencvt_d_l; recompile_standard_cf_type(); } static void (*recomp_l[64])(void) = { RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV, RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV, RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV, RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV, RCVT_S_L, RCVT_D_L, RSV, RSV, RSV, RSV, RSV, RSV, RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV, RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV, RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV, }; //------------------------------------------------------------------------- // COP1 //------------------------------------------------------------------------- static void RMFC1(void) { dst->ops = current_instruction_table.MFC1; recomp_func = genmfc1; recompile_standard_r_type(); dst->f.r.nrd = (src >> 11) & 0x1F; if (dst->f.r.rt == reg) RNOP(); } static void RDMFC1(void) { dst->ops = current_instruction_table.DMFC1; recomp_func = gendmfc1; recompile_standard_r_type(); dst->f.r.nrd = (src >> 11) & 0x1F; if (dst->f.r.rt == reg) RNOP(); } static void RCFC1(void) { dst->ops = current_instruction_table.CFC1; recomp_func = gencfc1; recompile_standard_r_type(); dst->f.r.nrd = (src >> 11) & 0x1F; if (dst->f.r.rt == reg) RNOP(); } static void RMTC1(void) { dst->ops = current_instruction_table.MTC1; recompile_standard_r_type(); recomp_func = genmtc1; dst->f.r.nrd = (src >> 11) & 0x1F; } static void RDMTC1(void) { dst->ops = current_instruction_table.DMTC1; recompile_standard_r_type(); recomp_func = gendmtc1; dst->f.r.nrd = (src >> 11) & 0x1F; } static void RCTC1(void) { dst->ops = current_instruction_table.CTC1; recompile_standard_r_type(); recomp_func = genctc1; dst->f.r.nrd = (src >> 11) & 0x1F; } static void RBC(void) { recomp_bc[((src >> 16) & 3)](); } static void RS(void) { recomp_s[(src & 0x3F)](); } static void RD(void) { recomp_d[(src & 0x3F)](); } static void RW(void) { recomp_w[(src & 0x3F)](); } static void RL(void) { recomp_l[(src & 0x3F)](); } static void (*recomp_cop1[32])(void) = { RMFC1, RDMFC1, RCFC1, RSV, RMTC1, RDMTC1, RCTC1, RSV, RBC , RSV , RSV , RSV, RSV , RSV , RSV , RSV, RS , RD , RSV , RSV, RW , RL , RSV , RSV, RSV , RSV , RSV , RSV, RSV , RSV , RSV , RSV }; //------------------------------------------------------------------------- // R4300 //------------------------------------------------------------------------- static void RSPECIAL(void) { recomp_special[(src & 0x3F)](); } static void RREGIMM(void) { recomp_regimm[((src >> 16) & 0x1F)](); } static void RJ(void) { uint32_t target; dst->ops = current_instruction_table.J; recomp_func = genj; recompile_standard_j_type(); target = (dst->f.j.inst_index<<2) | (dst->addr & UINT32_C(0xF0000000)); if (target == dst->addr) { if (check_nop) { dst->ops = current_instruction_table.J_IDLE; recomp_func = genj_idle; } } else if (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)) { dst->ops = current_instruction_table.J_OUT; recomp_func = genj_out; } } static void RJAL(void) { uint32_t target; dst->ops = current_instruction_table.JAL; recomp_func = genjal; recompile_standard_j_type(); target = (dst->f.j.inst_index<<2) | (dst->addr & UINT32_C(0xF0000000)); if (target == dst->addr) { if (check_nop) { dst->ops = current_instruction_table.JAL_IDLE; recomp_func = genjal_idle; } } else if (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)) { dst->ops = current_instruction_table.JAL_OUT; recomp_func = genjal_out; } } static void RBEQ(void) { uint32_t target; dst->ops = current_instruction_table.BEQ; recomp_func = genbeq; recompile_standard_i_type(); target = dst->addr + dst->f.i.immediate*4 + 4; if (target == dst->addr) { if (check_nop) { dst->ops = current_instruction_table.BEQ_IDLE; recomp_func = genbeq_idle; } } else if (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)) { dst->ops = current_instruction_table.BEQ_OUT; recomp_func = genbeq_out; } } static void RBNE(void) { uint32_t target; dst->ops = current_instruction_table.BNE; recomp_func = genbne; recompile_standard_i_type(); target = dst->addr + dst->f.i.immediate*4 + 4; if (target == dst->addr) { if (check_nop) { dst->ops = current_instruction_table.BNE_IDLE; recomp_func = genbne_idle; } } else if (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)) { dst->ops = current_instruction_table.BNE_OUT; recomp_func = genbne_out; } } static void RBLEZ(void) { uint32_t target; dst->ops = current_instruction_table.BLEZ; recomp_func = genblez; recompile_standard_i_type(); target = dst->addr + dst->f.i.immediate*4 + 4; if (target == dst->addr) { if (check_nop) { dst->ops = current_instruction_table.BLEZ_IDLE; recomp_func = genblez_idle; } } else if (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)) { dst->ops = current_instruction_table.BLEZ_OUT; recomp_func = genblez_out; } } static void RBGTZ(void) { uint32_t target; dst->ops = current_instruction_table.BGTZ; recomp_func = genbgtz; recompile_standard_i_type(); target = dst->addr + dst->f.i.immediate*4 + 4; if (target == dst->addr) { if (check_nop) { dst->ops = current_instruction_table.BGTZ_IDLE; recomp_func = genbgtz_idle; } } else if (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)) { dst->ops = current_instruction_table.BGTZ_OUT; recomp_func = genbgtz_out; } } static void RADDI(void) { dst->ops = current_instruction_table.ADDI; recomp_func = genaddi; recompile_standard_i_type(); if(dst->f.i.rt == reg) RNOP(); } static void RADDIU(void) { dst->ops = current_instruction_table.ADDIU; recomp_func = genaddiu; recompile_standard_i_type(); if(dst->f.i.rt == reg) RNOP(); } static void RSLTI(void) { dst->ops = current_instruction_table.SLTI; recomp_func = genslti; recompile_standard_i_type(); if(dst->f.i.rt == reg) RNOP(); } static void RSLTIU(void) { dst->ops = current_instruction_table.SLTIU; recomp_func = gensltiu; recompile_standard_i_type(); if(dst->f.i.rt == reg) RNOP(); } static void RANDI(void) { dst->ops = current_instruction_table.ANDI; recomp_func = genandi; recompile_standard_i_type(); if(dst->f.i.rt == reg) RNOP(); } static void RORI(void) { dst->ops = current_instruction_table.ORI; recomp_func = genori; recompile_standard_i_type(); if (dst->f.i.rt == reg) RNOP(); } static void RXORI(void) { dst->ops = current_instruction_table.XORI; recomp_func = genxori; recompile_standard_i_type(); if (dst->f.i.rt == reg) RNOP(); } static void RLUI(void) { dst->ops = current_instruction_table.LUI; recomp_func = genlui; recompile_standard_i_type(); if (dst->f.i.rt == reg) RNOP(); } static void RCOP0(void) { recomp_cop0[((src >> 21) & 0x1F)](); } static void RCOP1(void) { recomp_cop1[((src >> 21) & 0x1F)](); } static void RBEQL(void) { uint32_t target; dst->ops = current_instruction_table.BEQL; recomp_func = genbeql; recompile_standard_i_type(); target = dst->addr + dst->f.i.immediate*4 + 4; if (target == dst->addr) { if (check_nop) { dst->ops = current_instruction_table.BEQL_IDLE; recomp_func = genbeql_idle; } } else if (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)) { dst->ops = current_instruction_table.BEQL_OUT; recomp_func = genbeql_out; } } static void RBNEL(void) { uint32_t target; dst->ops = current_instruction_table.BNEL; recomp_func = genbnel; recompile_standard_i_type(); target = dst->addr + dst->f.i.immediate*4 + 4; if (target == dst->addr) { if (check_nop) { dst->ops = current_instruction_table.BNEL_IDLE; recomp_func = genbnel_idle; } } else if (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)) { dst->ops = current_instruction_table.BNEL_OUT; recomp_func = genbnel_out; } } static void RBLEZL(void) { uint32_t target; dst->ops = current_instruction_table.BLEZL; recomp_func = genblezl; recompile_standard_i_type(); target = dst->addr + dst->f.i.immediate*4 + 4; if (target == dst->addr) { if (check_nop) { dst->ops = current_instruction_table.BLEZL_IDLE; recomp_func = genblezl_idle; } } else if (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)) { dst->ops = current_instruction_table.BLEZL_OUT; recomp_func = genblezl_out; } } static void RBGTZL(void) { uint32_t target; dst->ops = current_instruction_table.BGTZL; recomp_func = genbgtzl; recompile_standard_i_type(); target = dst->addr + dst->f.i.immediate*4 + 4; if (target == dst->addr) { if (check_nop) { dst->ops = current_instruction_table.BGTZL_IDLE; recomp_func = genbgtzl_idle; } } else if (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)) { dst->ops = current_instruction_table.BGTZL_OUT; recomp_func = genbgtzl_out; } } static void RDADDI(void) { dst->ops = current_instruction_table.DADDI; recomp_func = gendaddi; recompile_standard_i_type(); if(dst->f.i.rt == reg) RNOP(); } static void RDADDIU(void) { dst->ops = current_instruction_table.DADDIU; recomp_func = gendaddiu; recompile_standard_i_type(); if(dst->f.i.rt == reg) RNOP(); } static void RLDL(void) { dst->ops = current_instruction_table.LDL; recomp_func = genldl; recompile_standard_i_type(); if(dst->f.i.rt == reg) RNOP(); } static void RLDR(void) { dst->ops = current_instruction_table.LDR; recomp_func = genldr; recompile_standard_i_type(); if(dst->f.i.rt == reg) RNOP(); } static void RLB(void) { dst->ops = current_instruction_table.LB; recomp_func = genlb; recompile_standard_i_type(); if (dst->f.i.rt == reg) RNOP(); } static void RLH(void) { dst->ops = current_instruction_table.LH; recomp_func = genlh; recompile_standard_i_type(); if (dst->f.i.rt == reg) RNOP(); } static void RLWL(void) { dst->ops = current_instruction_table.LWL; recomp_func = genlwl; recompile_standard_i_type(); if (dst->f.i.rt == reg) RNOP(); } static void RLW(void) { dst->ops = current_instruction_table.LW; recomp_func = genlw; recompile_standard_i_type(); if (dst->f.i.rt == reg) RNOP(); } static void RLBU(void) { dst->ops = current_instruction_table.LBU; recomp_func = genlbu; recompile_standard_i_type(); if(dst->f.i.rt == reg) RNOP(); } static void RLHU(void) { dst->ops = current_instruction_table.LHU; recomp_func = genlhu; recompile_standard_i_type(); if(dst->f.i.rt == reg) RNOP(); } static void RLWR(void) { dst->ops = current_instruction_table.LWR; recomp_func = genlwr; recompile_standard_i_type(); if(dst->f.i.rt == reg) RNOP(); } static void RLWU(void) { dst->ops = current_instruction_table.LWU; recomp_func = genlwu; recompile_standard_i_type(); if(dst->f.i.rt == reg) RNOP(); } static void RSB(void) { dst->ops = current_instruction_table.SB; recomp_func = gensb; recompile_standard_i_type(); } static void RSH(void) { dst->ops = current_instruction_table.SH; recomp_func = gensh; recompile_standard_i_type(); } static void RSWL(void) { dst->ops = current_instruction_table.SWL; recomp_func = genswl; recompile_standard_i_type(); } static void RSW(void) { dst->ops = current_instruction_table.SW; recomp_func = gensw; recompile_standard_i_type(); } static void RSDL(void) { dst->ops = current_instruction_table.SDL; recomp_func = gensdl; recompile_standard_i_type(); } static void RSDR(void) { dst->ops = current_instruction_table.SDR; recomp_func = gensdr; recompile_standard_i_type(); } static void RSWR(void) { dst->ops = current_instruction_table.SWR; recomp_func = genswr; recompile_standard_i_type(); } static void RCACHE(void) { recomp_func = gencache; dst->ops = current_instruction_table.CACHE; } static void RLL(void) { recomp_func = genll; dst->ops = current_instruction_table.LL; recompile_standard_i_type(); if(dst->f.i.rt == reg) RNOP(); } static void RLWC1(void) { dst->ops = current_instruction_table.LWC1; recomp_func = genlwc1; recompile_standard_lf_type(); } static void RLLD(void) { dst->ops = current_instruction_table.NI; recomp_func = genni; recompile_standard_i_type(); } static void RLDC1(void) { dst->ops = current_instruction_table.LDC1; recomp_func = genldc1; recompile_standard_lf_type(); } static void RLD(void) { dst->ops = current_instruction_table.LD; recomp_func = genld; recompile_standard_i_type(); if (dst->f.i.rt == reg) RNOP(); } static void RSC(void) { dst->ops = current_instruction_table.SC; recomp_func = gensc; recompile_standard_i_type(); if (dst->f.i.rt == reg) RNOP(); } static void RSWC1(void) { dst->ops = current_instruction_table.SWC1; recomp_func = genswc1; recompile_standard_lf_type(); } static void RSCD(void) { dst->ops = current_instruction_table.NI; recomp_func = genni; recompile_standard_i_type(); } static void RSDC1(void) { dst->ops = current_instruction_table.SDC1; recomp_func = gensdc1; recompile_standard_lf_type(); } static void RSD(void) { dst->ops = current_instruction_table.SD; recomp_func = gensd; recompile_standard_i_type(); } static void (*recomp_ops[64])(void) = { RSPECIAL, RREGIMM, RJ , RJAL , RBEQ , RBNE , RBLEZ , RBGTZ , RADDI , RADDIU , RSLTI, RSLTIU, RANDI, RORI , RXORI , RLUI , RCOP0 , RCOP1 , RSV , RSV , RBEQL, RBNEL, RBLEZL, RBGTZL, RDADDI , RDADDIU, RLDL , RLDR , RSV , RSV , RSV , RSV , RLB , RLH , RLWL , RLW , RLBU , RLHU , RLWR , RLWU , RSB , RSH , RSWL , RSW , RSDL , RSDR , RSWR , RCACHE, RLL , RLWC1 , RSV , RSV , RLLD , RLDC1, RSV , RLD , RSC , RSWC1 , RSV , RSV , RSCD , RSDC1, RSV , RSD }; static int get_block_length(const precomp_block *block) { return (block->end-block->start)/4; } static size_t get_block_memsize(const precomp_block *block) { int length = get_block_length(block); return ((length+1)+(length>>2)) * sizeof(precomp_instr); } /********************************************************************** ******************** initialize an empty block *********************** **********************************************************************/ void init_block(precomp_block *block) { int i, length, already_exist = 1; static int init_length; start_section(COMPILER_SECTION); #ifdef CORE_DBG DebugMessage(M64MSG_INFO, "init block %x - %x", (int) block->start, (int) block->end); #endif length = get_block_length(block); if (!block->block) { size_t memsize = get_block_memsize(block); if (r4300emu == CORE_DYNAREC) { block->block = (precomp_instr *) malloc_exec(memsize); if (!block->block) { DebugMessage(M64MSG_ERROR, "Memory error: couldn't allocate executable memory for dynamic recompiler. Try to use an interpreter mode."); return; } } else { block->block = (precomp_instr *) malloc(memsize); if (!block->block) { DebugMessage(M64MSG_ERROR, "Memory error: couldn't allocate memory for cached interpreter."); return; } } memset(block->block, 0, memsize); already_exist = 0; } if (r4300emu == CORE_DYNAREC) { if (!block->code) { max_code_length = 32768; block->code = (unsigned char *) malloc_exec(max_code_length); } else { max_code_length = block->max_code_length; } code_length = 0; inst_pointer = &block->code; if (block->jumps_table) { free(block->jumps_table); block->jumps_table = NULL; } if (block->riprel_table) { free(block->riprel_table); block->riprel_table = NULL; } init_assembler(NULL, 0, NULL, 0); init_cache(block->block); } if (!already_exist) { for (i=0; iblock + i; dst->addr = block->start + i*4; dst->reg_cache_infos.need_map = 0; dst->local_addr = code_length; #ifdef COMPARE_CORE if (r4300emu == CORE_DYNAREC) gendebug(); #endif RNOTCOMPILED(); if (r4300emu == CORE_DYNAREC) recomp_func(); } init_length = code_length; } else { code_length = init_length; /* recompile everything, overwrite old recompiled instructions */ for (i=0; iblock + i; dst->reg_cache_infos.need_map = 0; dst->local_addr = i * (init_length / length); dst->ops = current_instruction_table.NOTCOMPILED; } } if (r4300emu == CORE_DYNAREC) { free_all_registers(); /* calling pass2 of the assembler is not necessary here because all of the code emitted by gennotcompiled() and gendebug() is position-independent and contains no jumps . */ block->code_length = code_length; block->max_code_length = max_code_length; free_assembler(&block->jumps_table, &block->jumps_number, &block->riprel_table, &block->riprel_number); } /* here we're marking the block as a valid code even if it's not compiled * yet as the game should have already set up the code correctly. */ invalid_code[block->start>>12] = 0; if (block->end < UINT32_C(0x80000000) || block->start >= UINT32_C(0xc0000000)) { uint32_t paddr = virtual_to_physical_address(block->start, TLB_FAST_READ); invalid_code[paddr>>12] = 0; if (!blocks[paddr>>12]) { blocks[paddr>>12] = (precomp_block *) malloc(sizeof(precomp_block)); blocks[paddr>>12]->code = NULL; blocks[paddr>>12]->block = NULL; blocks[paddr>>12]->jumps_table = NULL; blocks[paddr>>12]->riprel_table = NULL; blocks[paddr>>12]->start = paddr & ~UINT32_C(0xFFF); blocks[paddr>>12]->end = (paddr & ~UINT32_C(0xFFF)) + UINT32_C(0x1000); } init_block(blocks[paddr>>12]); paddr += block->end - block->start - 4; invalid_code[paddr>>12] = 0; if (!blocks[paddr>>12]) { blocks[paddr>>12] = (precomp_block *) malloc(sizeof(precomp_block)); blocks[paddr>>12]->code = NULL; blocks[paddr>>12]->block = NULL; blocks[paddr>>12]->jumps_table = NULL; blocks[paddr>>12]->riprel_table = NULL; blocks[paddr>>12]->start = paddr & ~UINT32_C(0xFFF); blocks[paddr>>12]->end = (paddr & ~UINT32_C(0xFFF)) + UINT32_C(0x1000); } init_block(blocks[paddr>>12]); } else { uint32_t alt_addr = block->start ^ UINT32_C(0x20000000); if (invalid_code[alt_addr >> 12]) { if (!blocks[alt_addr >> 12]) { blocks[alt_addr >> 12] = (precomp_block *) malloc(sizeof(precomp_block)); blocks[alt_addr >> 12]->code = NULL; blocks[alt_addr >> 12]->block = NULL; blocks[alt_addr >> 12]->jumps_table = NULL; blocks[alt_addr >> 12]->riprel_table = NULL; blocks[alt_addr >> 12]->start = alt_addr & ~UINT32_C(0xFFF); blocks[alt_addr >> 12]->end = (alt_addr & ~UINT32_C(0xFFF)) + UINT32_C(0x1000); } init_block(blocks[alt_addr >> 12]); } } end_section(COMPILER_SECTION); } void free_block(precomp_block *block) { size_t memsize = get_block_memsize(block); if (block->block) { if (r4300emu == CORE_DYNAREC) free_exec(block->block, memsize); else free(block->block); block->block = NULL; } if (block->code) { free_exec(block->code, block->max_code_length); block->code = NULL; } if (block->jumps_table) { free(block->jumps_table); block->jumps_table = NULL; } if (block->riprel_table) { free(block->riprel_table); block->riprel_table = NULL; } } /********************************************************************** ********************* recompile a block of code ********************** **********************************************************************/ void recompile_block(const uint32_t *source, precomp_block *block, unsigned int func) { uint32_t i; int length, finished=0; start_section(COMPILER_SECTION); length = (block->end-block->start)/4; dst_block = block; block->adler32 = 0; if (r4300emu == CORE_DYNAREC) { code_length = block->code_length; max_code_length = block->max_code_length; inst_pointer = &block->code; init_assembler(block->jumps_table, block->jumps_number, block->riprel_table, block->riprel_number); init_cache(block->block + (func & 0xFFF) / 4); } for (i = (func & 0xFFF) / 4; finished != 2; i++) { if(block->start < UINT32_C(0x80000000) || block->start >= UINT32_C(0xc0000000)) { uint32_t address2 = virtual_to_physical_address(block->start + i*4, TLB_READ); if(blocks[address2>>12]->block[(address2 & UINT32_C(0xFFF))/4].ops == current_instruction_table.NOTCOMPILED) blocks[address2>>12]->block[(address2 & UINT32_C(0xFFF))/4].ops = current_instruction_table.NOTCOMPILED2; } SRC = source + i; src = source[i]; check_nop = source[i+1] == 0; dst = block->block + i; dst->addr = block->start + i*4; dst->reg_cache_infos.need_map = 0; dst->local_addr = code_length; #ifdef COMPARE_CORE if (r4300emu == CORE_DYNAREC) gendebug(); #endif recomp_func = NULL; recomp_ops[((src >> 26) & 0x3F)](); if (r4300emu == CORE_DYNAREC) recomp_func(); dst = block->block + i; /*if ((dst+1)->ops != NOTCOMPILED && !delay_slot_compiled && i < length) { if (r4300emu == CORE_DYNAREC) genlink_subblock(); finished = 2; }*/ if (delay_slot_compiled) { delay_slot_compiled--; free_all_registers(); } if (i >= length-2+(length>>2)) finished = 2; if (i >= (length-1) && (block->start == UINT32_C(0xa4000000) || block->start >= UINT32_C(0xc0000000) || block->end < UINT32_C(0x80000000))) finished = 2; if (dst->ops == current_instruction_table.ERET || finished == 1) finished = 2; if (/*i >= length &&*/ (dst->ops == current_instruction_table.J || dst->ops == current_instruction_table.J_OUT || dst->ops == current_instruction_table.JR) && !(i >= (length-1) && (block->start >= UINT32_C(0xc0000000) || block->end < UINT32_C(0x80000000)))) finished = 1; } if (i >= length) { dst = block->block + i; dst->addr = block->start + i*4; dst->reg_cache_infos.need_map = 0; dst->local_addr = code_length; #ifdef COMPARE_CORE if (r4300emu == CORE_DYNAREC) gendebug(); #endif RFIN_BLOCK(); if (r4300emu == CORE_DYNAREC) recomp_func(); i++; if (i < length-1+(length>>2)) // useful when last opcode is a jump { dst = block->block + i; dst->addr = block->start + i*4; dst->reg_cache_infos.need_map = 0; dst->local_addr = code_length; #ifdef COMPARE_CORE if (r4300emu == CORE_DYNAREC) gendebug(); #endif RFIN_BLOCK(); if (r4300emu == CORE_DYNAREC) recomp_func(); i++; } } else if (r4300emu == CORE_DYNAREC) genlink_subblock(); if (r4300emu == CORE_DYNAREC) { free_all_registers(); passe2(block->block, (func&0xFFF)/4, i, block); block->code_length = code_length; block->max_code_length = max_code_length; free_assembler(&block->jumps_table, &block->jumps_number, &block->riprel_table, &block->riprel_number); } #ifdef CORE_DBG DebugMessage(M64MSG_INFO, "block recompiled (%x-%x)", (int)func, (int)(block->start+i*4)); #endif end_section(COMPILER_SECTION); } static int is_jump(void) { recomp_ops[((src >> 26) & 0x3F)](); return (dst->ops == current_instruction_table.J || dst->ops == current_instruction_table.J_OUT || dst->ops == current_instruction_table.J_IDLE || dst->ops == current_instruction_table.JAL || dst->ops == current_instruction_table.JAL_OUT || dst->ops == current_instruction_table.JAL_IDLE || dst->ops == current_instruction_table.BEQ || dst->ops == current_instruction_table.BEQ_OUT || dst->ops == current_instruction_table.BEQ_IDLE || dst->ops == current_instruction_table.BNE || dst->ops == current_instruction_table.BNE_OUT || dst->ops == current_instruction_table.BNE_IDLE || dst->ops == current_instruction_table.BLEZ || dst->ops == current_instruction_table.BLEZ_OUT || dst->ops == current_instruction_table.BLEZ_IDLE || dst->ops == current_instruction_table.BGTZ || dst->ops == current_instruction_table.BGTZ_OUT || dst->ops == current_instruction_table.BGTZ_IDLE || dst->ops == current_instruction_table.BEQL || dst->ops == current_instruction_table.BEQL_OUT || dst->ops == current_instruction_table.BEQL_IDLE || dst->ops == current_instruction_table.BNEL || dst->ops == current_instruction_table.BNEL_OUT || dst->ops == current_instruction_table.BNEL_IDLE || dst->ops == current_instruction_table.BLEZL || dst->ops == current_instruction_table.BLEZL_OUT || dst->ops == current_instruction_table.BLEZL_IDLE || dst->ops == current_instruction_table.BGTZL || dst->ops == current_instruction_table.BGTZL_OUT || dst->ops == current_instruction_table.BGTZL_IDLE || dst->ops == current_instruction_table.JR || dst->ops == current_instruction_table.JALR || dst->ops == current_instruction_table.BLTZ || dst->ops == current_instruction_table.BLTZ_OUT || dst->ops == current_instruction_table.BLTZ_IDLE || dst->ops == current_instruction_table.BGEZ || dst->ops == current_instruction_table.BGEZ_OUT || dst->ops == current_instruction_table.BGEZ_IDLE || dst->ops == current_instruction_table.BLTZL || dst->ops == current_instruction_table.BLTZL_OUT || dst->ops == current_instruction_table.BLTZL_IDLE || dst->ops == current_instruction_table.BGEZL || dst->ops == current_instruction_table.BGEZL_OUT || dst->ops == current_instruction_table.BGEZL_IDLE || dst->ops == current_instruction_table.BLTZAL || dst->ops == current_instruction_table.BLTZAL_OUT || dst->ops == current_instruction_table.BLTZAL_IDLE || dst->ops == current_instruction_table.BGEZAL || dst->ops == current_instruction_table.BGEZAL_OUT || dst->ops == current_instruction_table.BGEZAL_IDLE || dst->ops == current_instruction_table.BLTZALL || dst->ops == current_instruction_table.BLTZALL_OUT || dst->ops == current_instruction_table.BLTZALL_IDLE || dst->ops == current_instruction_table.BGEZALL || dst->ops == current_instruction_table.BGEZALL_OUT || dst->ops == current_instruction_table.BGEZALL_IDLE || dst->ops == current_instruction_table.BC1F || dst->ops == current_instruction_table.BC1F_OUT || dst->ops == current_instruction_table.BC1F_IDLE || dst->ops == current_instruction_table.BC1T || dst->ops == current_instruction_table.BC1T_OUT || dst->ops == current_instruction_table.BC1T_IDLE || dst->ops == current_instruction_table.BC1FL || dst->ops == current_instruction_table.BC1FL_OUT || dst->ops == current_instruction_table.BC1FL_IDLE || dst->ops == current_instruction_table.BC1TL || dst->ops == current_instruction_table.BC1TL_OUT || dst->ops == current_instruction_table.BC1TL_IDLE); } /********************************************************************** ************ recompile only one opcode (use for delay slot) ********** **********************************************************************/ void recompile_opcode(void) { SRC++; src = *SRC; dst++; dst->addr = (dst-1)->addr + 4; dst->reg_cache_infos.need_map = 0; if(!is_jump()) { recomp_func = NULL; recomp_ops[((src >> 26) & 0x3F)](); if (r4300emu == CORE_DYNAREC) recomp_func(); } else { RNOP(); if (r4300emu == CORE_DYNAREC) recomp_func(); } delay_slot_compiled = 2; } /********************************************************************** ************** allocate memory with executable bit set *************** **********************************************************************/ static void *malloc_exec(size_t size) { #if defined(WIN32) return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); #elif defined(__GNUC__) #ifndef MAP_ANONYMOUS #ifdef MAP_ANON #define MAP_ANONYMOUS MAP_ANON #endif #endif void *block = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (block == MAP_FAILED) { DebugMessage(M64MSG_ERROR, "Memory error: couldn't allocate %zi byte block of aligned RWX memory.", size); return NULL; } return block; #else return malloc(size); #endif } /********************************************************************** ************* reallocate memory with executable bit set ************** **********************************************************************/ void *realloc_exec(void *ptr, size_t oldsize, size_t newsize) { void* block = malloc_exec(newsize); if (block) { size_t copysize; if (oldsize < newsize) copysize = oldsize; else copysize = newsize; memcpy(block, ptr, copysize); } free_exec(ptr, oldsize); return block; } /********************************************************************** **************** frees memory with executable bit set **************** **********************************************************************/ static void free_exec(void *ptr, size_t length) { #if defined(WIN32) VirtualFree(ptr, 0, MEM_RELEASE); #elif defined(__GNUC__) munmap(ptr, length); #else free(ptr); #endif } mupen64plus-core/src/r4300/recomp.h000664 001750 001750 00000006607 12655644434 020055 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - recomp.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_R4300_RECOMP_H #define M64P_R4300_RECOMP_H #include #if defined(__LIBRETRO_WIN64__) #define __x86_64__ #endif #include #include "hacktarux_dynarec/assemble_struct.h" typedef struct _precomp_instr { void (*ops)(void); union { struct { int64_t *rs; int64_t *rt; int16_t immediate; } i; struct { uint32_t inst_index; } j; struct { int64_t *rs; int64_t *rt; int64_t *rd; uint8_t sa; uint8_t nrd; } r; struct { uint8_t base; uint8_t ft; int16_t offset; } lf; struct { uint8_t ft; uint8_t fs; uint8_t fd; } cf; } f; uint32_t addr; /* word-aligned instruction address in r4300 address space */ unsigned int local_addr; /* byte offset to start of corresponding x86_64 instructions, from start of code block */ reg_cache_struct reg_cache_infos; } precomp_instr; typedef struct _precomp_block { precomp_instr *block; uint32_t start; uint32_t end; uint8_t *code; unsigned int code_length; unsigned int max_code_length; void *jumps_table; int jumps_number; void *riprel_table; int riprel_number; unsigned int adler32; } precomp_block; void recompile_block(const uint32_t *source, precomp_block *block, uint32_t func); void init_block(precomp_block *block); void free_block(precomp_block *block); void recompile_opcode(void); void dyna_jump(void); void dyna_start(void *code); void dyna_stop(void); void *realloc_exec(void *ptr, size_t oldsize, size_t newsize); extern precomp_instr *dst; /* precomp_instr structure for instruction being recompiled */ extern int no_compiled_jump; #ifdef DYNAREC #include "hacktarux_dynarec/assemble.h" #endif #include "hacktarux_dynarec/regcache.h" #endif /* M64P_R4300_RECOMP_H */ mupen64plus-video-gliden64/LICENCE000664 001750 001750 00000046115 12655644434 017633 0ustar00sergiosergio000000 000000 GLideN64 LICENSE ------------------------------------ GLideN64 is licensed under the GNU General Public License version 2. The author of GLideN64 is Sergey Lipskiy (c) 2014-2015 Credits: * The project started from sources of glN64 project, author Orkin. * The project contains source code fragments of glN64 ported to Android by yongzh (freeman.yong@gmail.com). The original source code of gles2n64 is available at: http://code.google.com/p/gles2n64/ * Some ucodes ported from sources of Glide64 project, author Sergey Lipskiy * LLE code ported from z64 OpenGL LLE plugin, author ziggy. * Bloom is based on shaders by Nathaniel Meyer, Copyright:Nutty Software, www.nutty.ca. * GLideNHQ hi-res textures library is OpenGL port of GlideHQ library. Author of GlideHQ is Hiroshi Morii aka KoolSmoky, Copyright (C) 2007. Author of the GLideNHQ port is Sergey Lipskiy. GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. libretro/SDL_opengles2.h000664 001750 001750 00000002111 12655644434 016305 0ustar00sergiosergio000000 000000 /* SDL - Simple DirectMedia Layer Copyright (C) 1997-2012 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Sam Lantinga slouken@libsdl.org */ /** @file SDL_opengl.h * This is a simple file to encapsulate the OpenGL API headers */ #ifndef _SDL_OPENGLES2_LIBRETRO_H #define _SDL_OPENGLES2_LIBRETRO_H #include "opengl_state_machine.h" #include "glsym/rglgen.h" #endif glide2gl/src/Glide64/ucode05.h000664 001750 001750 00000021507 12655644434 017017 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** int cur_mtx = 0; int billboarding = 0; int vtx_last = 0; uint32_t dma_offset_mtx = 0; uint32_t dma_offset_vtx = 0; static void uc5_dma_offsets(uint32_t w0, uint32_t w1) { dma_offset_mtx = _SHIFTR( w0, 0, 24); dma_offset_vtx = _SHIFTR( w1, 0, 24); vtx_last = 0; } static void uc5_matrix(uint32_t w0, uint32_t w1) { // Use segment offset to get the address uint32_t addr = dma_offset_mtx + RSP_SegmentToPhysical(w1); uint8_t index = _SHIFTR(w0, 16, 4); uint8_t multiply; if (index == 0) //DKR { index = _SHIFTR(w0, 22, 2); multiply = 0; } else //JF multiply = _SHIFTR(w0, 23, 1); cur_mtx = index; if (multiply) { DECLAREALIGN16VAR(m[4][4]); DECLAREALIGN16VAR(m_src[4][4]); load_matrix(m, addr); memcpy (m_src, rdp.dkrproj[0], 64); MulMatrices(m, m_src, rdp.dkrproj[index]); } else load_matrix(rdp.dkrproj[index], addr); g_gdp.flags |= UPDATE_MULT_MAT; } static void uc5_vertex(uint32_t w0, uint32_t w1) { int i, first, prj, n; uint32_t addr = dma_offset_vtx + RSP_SegmentToPhysical(w1); // | cccc cccc 1111 1??? 0000 0002 2222 2222 | cmd1 = address | // c = vtx command // 1 = method #1 of getting count // 2 = method #2 of getting count // ? = unknown, but used // 0 = unused n = _SHIFTR( w0, 19, 5); if (settings.hacks&hack_Diddy) n++; if (w0 & G_FOG) { if (billboarding) vtx_last = 1; } else vtx_last = 0; first = vtx_last + _SHIFTR(w0, 9, 5);; prj = cur_mtx; for (i = first; i < first + n; i++) { VERTEX *v = (VERTEX*)&rdp.vtx[i]; int start = (i-first) * 10; float x = (float)((int16_t*)gfx_info.RDRAM)[(((addr+start) >> 1) + 0)^1]; float y = (float)((int16_t*)gfx_info.RDRAM)[(((addr+start) >> 1) + 1)^1]; float z = (float)((int16_t*)gfx_info.RDRAM)[(((addr+start) >> 1) + 2)^1]; v->x = x*rdp.dkrproj[prj][0][0] + y*rdp.dkrproj[prj][1][0] + z*rdp.dkrproj[prj][2][0] + rdp.dkrproj[prj][3][0]; v->y = x*rdp.dkrproj[prj][0][1] + y*rdp.dkrproj[prj][1][1] + z*rdp.dkrproj[prj][2][1] + rdp.dkrproj[prj][3][1]; v->z = x*rdp.dkrproj[prj][0][2] + y*rdp.dkrproj[prj][1][2] + z*rdp.dkrproj[prj][2][2] + rdp.dkrproj[prj][3][2]; v->w = x*rdp.dkrproj[prj][0][3] + y*rdp.dkrproj[prj][1][3] + z*rdp.dkrproj[prj][2][3] + rdp.dkrproj[prj][3][3]; if (billboarding) { v->x += rdp.vtx[0].x; v->y += rdp.vtx[0].y; v->z += rdp.vtx[0].z; v->w += rdp.vtx[0].w; } if (fabs(v->w) < 0.001) v->w = 0.001f; v->oow = 1.0f / v->w; v->x_w = v->x * v->oow; v->y_w = v->y * v->oow; v->z_w = v->z * v->oow; v->uv_calculated = 0xFFFFFFFF; v->screen_translated = 0; v->shade_mod = 0; v->scr_off = 0; if (v->x < -v->w) v->scr_off |= 1; if (v->x > v->w) v->scr_off |= 2; if (v->y < -v->w) v->scr_off |= 4; if (v->y > v->w) v->scr_off |= 8; if (v->w < 0.1f) v->scr_off |= 16; if (fabs(v->z_w) > 1.0) v->scr_off |= 32; v->r = ((uint8_t*)gfx_info.RDRAM)[(addr+start + 6)^3]; v->g = ((uint8_t*)gfx_info.RDRAM)[(addr+start + 7)^3]; v->b = ((uint8_t*)gfx_info.RDRAM)[(addr+start + 8)^3]; v->a = ((uint8_t*)gfx_info.RDRAM)[(addr+start + 9)^3]; CalculateFog (v); } vtx_last += n; } static void uc5_tridma(uint32_t w0, uint32_t w1) { int i; uint32_t addr = RSP_SegmentToPhysical(w1); int num = _SHIFTR( w0, 4, 12); vtx_last = 0; // we've drawn something, so the vertex index needs resetting // | cccc cccc 2222 0000 1111 1111 1111 0000 | cmd1 = address | // c = tridma command // 1 = method #1 of getting count // 2 = method #2 of getting count // 0 = unused for (i = 0; i < num; i++) { int flags; VERTEX *v[3]; unsigned cull_mode = GR_CULL_NEGATIVE; int start = i << 4; int v0 = gfx_info.RDRAM[addr+start]; int v1 = gfx_info.RDRAM[addr+start+1]; int v2 = gfx_info.RDRAM[addr+start+2]; v[0] = &rdp.vtx[v0]; v[1] = &rdp.vtx[v1]; v[2] = &rdp.vtx[v2]; flags = gfx_info.RDRAM[addr+start+3]; if (flags & 0x40) { // no cull rdp.flags &= ~CULLMASK; cull_mode = GR_CULL_DISABLE; } else { // front cull rdp.flags &= ~CULLMASK; if (rdp.view_scale[0] < 0) { rdp.flags |= CULL_BACK; // agh, backwards culling cull_mode = GR_CULL_POSITIVE; } else rdp.flags |= CULL_FRONT; } grCullMode(cull_mode); start += 4; v[0]->ou = (float)((int16_t*)gfx_info.RDRAM)[((addr+start) >> 1) + 5] / 32.0f; v[0]->ov = (float)((int16_t*)gfx_info.RDRAM)[((addr+start) >> 1) + 4] / 32.0f; v[1]->ou = (float)((int16_t*)gfx_info.RDRAM)[((addr+start) >> 1) + 3] / 32.0f; v[1]->ov = (float)((int16_t*)gfx_info.RDRAM)[((addr+start) >> 1) + 2] / 32.0f; v[2]->ou = (float)((int16_t*)gfx_info.RDRAM)[((addr+start) >> 1) + 1] / 32.0f; v[2]->ov = (float)((int16_t*)gfx_info.RDRAM)[((addr+start) >> 1) + 0] / 32.0f; v[0]->uv_calculated = 0xFFFFFFFF; v[1]->uv_calculated = 0xFFFFFFFF; v[2]->uv_calculated = 0xFFFFFFFF; cull_trianglefaces(v, 1, true, true, 0); } } static void uc5_dl_in_mem(uint32_t w0, uint32_t w1) { gSPDlistCount_G64(_SHIFTR(w0, 16, 8), w1); } static void uc5_moveword(uint32_t w0, uint32_t w1) { switch (_SHIFTR( w0, 0, 8)) { case 0x02: billboarding = w1 & 1; break; case G_MW_CLIP: if (((rdp.cmd0>>8)&0xFFFF) == 0x04) { rdp.clip_ratio = (float)vi_integer_sqrt(w1); g_gdp.flags |= UPDATE_VIEWPORT; } break; case G_MW_SEGMENT: rdp.segment[(w0 >> 10) & 0x0F] = w1; break; case G_MW_FOG: rdp.fog_multiplier = (int16_t)(w1 >> 16); rdp.fog_offset = (int16_t)(w1 & 0x0000FFFF); break; case 0x0a: // moveword matrix select cur_mtx = _SHIFTR( w1, 6, 2); FRDP ("matrix select - mtx: %d\n", cur_mtx); break; } } static void uc5_setgeometrymode(uint32_t w0, uint32_t w1) { rdp.geom_mode |= w1; if (w1 & 0x00000001) // Z-Buffer enable { if (!(rdp.flags & ZBUF_ENABLED)) { rdp.flags |= ZBUF_ENABLED; g_gdp.flags |= UPDATE_ZBUF_ENABLED; } } if (w1 & 0x00010000) // Fog enable { if (!(rdp.flags & FOG_ENABLED)) { rdp.flags |= FOG_ENABLED; g_gdp.flags |= UPDATE_FOG_ENABLED; } } } static void uc5_cleargeometrymode(uint32_t w0, uint32_t w1) { rdp.geom_mode &= (~w1); if (w1 & 0x00000001) // Z-Buffer enable { if (rdp.flags & ZBUF_ENABLED) { rdp.flags ^= ZBUF_ENABLED; g_gdp.flags |= UPDATE_ZBUF_ENABLED; } } if (w1 & 0x00010000) // Fog enable { if (rdp.flags & FOG_ENABLED) { rdp.flags ^= FOG_ENABLED; g_gdp.flags |= UPDATE_FOG_ENABLED; } } } glide2gl/src/Glide64/rdp.h000664 001750 001750 00000051261 12655644434 016340 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** #ifndef RDP_H #define RDP_H #include "rdp_common/gdp.h" #include "Gfx_1.3.h" extern uint32_t frame_count; // frame counter extern uint32_t gfx_plugin_accuracy; #define MAX_CACHE 1024*4 #define MAX_TRI_CACHE 768 // this is actually # of vertices, not triangles #define MAX_VTX 256 #define MAX_TMU 2 // Supported flags #define SUP_TEXMIRROR 0x00000001 // Clipping flags #define CLIP_XMAX 0x00000001 #define CLIP_XMIN 0x00000002 #define CLIP_YMAX 0x00000004 #define CLIP_YMIN 0x00000008 #define CLIP_WMIN 0x00000010 #define CLIP_ZMAX 0x00000020 #define CLIP_ZMIN 0x00000040 // Flags #define RDP_ALPHA_COMPARE 0x00000003 #define RDP_Z_SOURCE_SEL 0x00000004 #define RDP_Z_UPDATE_ENABLE 0x00000020 #define RDP_CYCLE_TYPE 0x00300000 #define RDP_TEX_LOD_ENABLE 0x00010000 #define RDP_PERSP_TEX_ENABLE 0x00080000 #define RDP_FORCE_BLEND 0x00004000 #define RDP_COLOR_ON_CVG 0x00000080 #define RDP_ALPHA_CVG_SELECT 0x00002000 #define ZBUF_ENABLED 0x00000001 #define ZBUF_DECAL 0x00000002 #define ZBUF_COMPARE 0x00000004 #define ZBUF_UPDATE 0x00000008 #define ALPHA_COMPARE 0x00000010 #define CULL_FRONT 0x00001000 // * must be here #define CULL_BACK 0x00002000 // * must be here #define FOG_ENABLED 0x00010000 #define CULLMASK 0x00003000 #define CULLSHIFT 12 #define CMB_MULT 0x00000001 #define CMB_SET 0x00000002 #define CMB_SUB 0x00000004 #define CMB_ADD 0x00000008 #define CMB_A_MULT 0x00000010 #define CMB_A_SET 0x00000020 #define CMB_A_SUB 0x00000040 #define CMB_A_ADD 0x00000080 #define CMB_SETSHADE_SHADEALPHA 0x00000100 #define CMB_INTER 0x00000200 #define CMB_MULT_OWN_ALPHA 0x00000400 #define CMB_COL_SUB_OWN 0x00000800 #if defined _MSC_VER #define DECLAREALIGN16VAR(var) __declspec(align(16)) float (var) #else #define DECLAREALIGN16VAR(var) float (var) __attribute__ ((aligned(16))) #endif //Frame buffer emulation options #define fb_emulation (1<<0) //frame buffer emulation #define fb_hwfbe (1<<1) //hardware frame buffer emualtion #define fb_motionblur (1<<2) //emulate motion blur #define fb_ref (1<<3) //read every frame #define fb_read_alpha (1<<4) //read alpha #define fb_hwfbe_buf_clear (1<<5) //clear auxiliary texture frame buffers #define fb_depth_render (1<<6) //enable software depth render #define fb_optimize_texrect (1<<7) //fast texrect rendering with hwfbe #define fb_ignore_aux_copy (1<<8) //do not copy auxiliary frame buffers #define fb_useless_is_useless (1<<10) // #define fb_get_info (1<<11) //get frame buffer info #define fb_read_back_to_screen (1<<12) //render N64 frame buffer to screen #define fb_read_back_to_screen2 (1<<13) //render N64 frame buffer to screen #define fb_cpu_write_hack (1<<14) //show images writed directly by CPU #define fb_emulation_enabled ((settings.frame_buffer&fb_emulation)>0) #define fb_hwfbe_enabled ((settings.frame_buffer&(fb_emulation|fb_hwfbe))==(fb_emulation|fb_hwfbe)) #define fb_depth_render_enabled ((settings.frame_buffer&fb_depth_render)>0) //Special game hacks #define hack_ASB (1<<0) //All-Star Baseball games #define hack_Banjo2 (1<<1) //Banjo Tooie #define hack_BAR (1<<2) //Beetle Adventure Racing #define hack_Chopper (1<<3) //Chopper Attack #define hack_Diddy (1<<4) //diddy kong racing #define hack_Fifa98 (1<<5) //FIFA - Road to World Cup 98 #define hack_Fzero (1<<6) //F-Zero #define hack_GoldenEye (1<<7) //Golden Eye #define hack_Hyperbike (1<<8) //Top Gear Hyper Bike #define hack_ISS64 (1<<9) //International Superstar Soccer 64 #define hack_KI (1<<10) //Killer Instinct #define hack_Knockout (1<<11) //Knockout Kings 2000 #define hack_Lego (1<<12) //LEGO Racers #define hack_MK64 (1<<13) //Mario Kart #define hack_Megaman (1<<14) //Megaman64 #define hack_Makers (1<<15) //Mischief-makers #define hack_WCWnitro (1<<16) //WCW Nitro #define hack_Ogre64 (1<<17) //Ogre Battle 64 #define hack_Pilotwings (1<<18) //Pilotwings #define hack_PMario (1<<19) //Paper Mario #define hack_PPL (1<<20) //pokemon puzzle league requires many special fixes #define hack_RE2 (1<<21) //Resident Evil 2 #define hack_Starcraft (1<<22) //StarCraft64 #define hack_Supercross (1<<23) //Supercross 2000 #define hack_TGR (1<<24) //Top Gear Rally #define hack_TGR2 (1<<25) //Top Gear Rally 2 #define hack_Tonic (1<<26) //tonic trouble #define hack_Yoshi (1<<27) //Yoshi Story #define hack_Zelda (1<<28) //zeldas hacks #define hack_Blastcorps (1<<29) /* Blast Corps */ #define hack_OOT (1<<30) /* Zelda OOT hacks */ #define FBCRCMODE_NONE 0 #define FBCRCMODE_FAST 1 #define FBCRCMODE_SAFE 2 // Clipping (scissors) typedef struct { uint32_t ul_x; uint32_t ul_y; uint32_t lr_x; uint32_t lr_y; } SCISSOR; typedef struct { uint32_t depth_bias; uint32_t res_x, scr_res_x; uint32_t res_y, scr_res_y; int vsync; int filtering; int fog; int buff_clear; int swapmode; bool swapmode_retro; int lodmode; int aspectmode; uint32_t frame_buffer; unsigned fb_crc_mode; //Debug int autodetect_ucode; int ucode; int unk_as_red; int unk_clear; // Special fixes int offset_x, offset_y; int scale_x, scale_y; int fast_crc; int alt_tex_size; int flame_corona; //hack for zeldas flame's corona int increase_texrect_edge; // add 1 to lower right corner coordinates of texrect int decrease_fillrect_edge; // sub 1 from lower right corner coordinates of fillrect int stipple_mode; //used for dithered alpha emulation uint32_t stipple_pattern; //used for dithered alpha emulation int force_microcheck; //check microcode each frame, for mixed F3DEX-S2DEX games int force_quad3d; //force 0xb5 command to be quad, not line 3d int clip_zmin; //enable near z clipping int adjust_aspect; //adjust screen aspect for wide screen mode int force_calc_sphere; //use spheric mapping only, Ridge Racer 64 int pal230; //set special scale for PAL games int correct_viewport; //correct viewport values int zmode_compare_less; //force GR_CMP_LESS for zmode=0 (opaque)and zmode=1 (interpenetrating) int old_style_adither; //apply alpha dither regardless of alpha_dither_mode int n64_z_scale; //scale vertex z value before writing to depth buffer, as N64 does. uint32_t hacks; } SETTINGS; typedef struct { uint8_t hk_ref; uint8_t hk_motionblur; uint8_t hk_filtering; } HOTKEY_INFO; typedef struct { uint32_t tmem_ptr[MAX_TMU]; uint32_t tex_max_addr; } VOODOO; // This structure is what is passed in by rdp:settextureimage typedef struct { int set_by; // 0-loadblock 1-loadtile } TEXTURE_IMAGE; // This structure is a tile descriptor (as used by rdp:settile and rdp:settilesize) typedef struct { // rdp:settilesize // TODO - eventually remove these float f_ul_s; float f_ul_t; uint32_t width; uint32_t height; // uc0:texture uint8_t on; float s_scale; float t_scale; uint16_t org_s_scale; uint16_t org_t_scale; } TILE; // This structure forms the lookup table for cached textures typedef struct { uint32_t addr; // address in RDRAM uint32_t crc; // CRC check uint32_t palette; // Palette # uint32_t width; // width uint32_t height; // height uint32_t format; // format uint32_t size; // size uint32_t last_used; // what frame # was this texture last used (used for replacing) uint32_t line; uint32_t flags; // clamp/wrap/mirror flags uint32_t realwidth; // width of actual texture uint32_t realheight; // height of actual texture uint32_t lod; uint32_t aspect; uint8_t set_by; uint8_t texrecting; float scale_x; // texture scaling float scale_y; float scale; // general scale to 256 GrTexInfo t_info; // texture info (glide) uint32_t tmem_addr; // addres in texture memory (glide) int uses; // 1 triangle that uses this texture int splitheight; float c_off; // ul center texel offset (both x and y) float c_scl_x; // scale to lower-right center-texel x float c_scl_y; // scale to lower-right center-texel y uint32_t mod, mod_color, mod_color1, mod_color2, mod_factor; } CACHE_LUT; typedef struct { float col[4]; // diffuse light value color (RGBA) float dir[3]; // direction towards light source (normalized float x, y, z, w; // light position float ca, la, qa; uint32_t nonblack; uint32_t nonzero; } LIGHT; typedef struct { int clampdiffs, clampdifft; int clampens, clampent; int masksclamped, masktclamped; int notlutswitch, tlutswitch; } FAKETILE; typedef enum { CI_MAIN, //0, main color image CI_ZIMG, //1, depth image CI_UNKNOWN, //2, status is unknown CI_USELESS, //3, status is unclear CI_OLD_COPY, //4, auxiliary color image, copy of last color image from previous frame CI_COPY, //5, auxiliary color image, copy of previous color image CI_COPY_SELF, //6, main color image, it's content will be used to draw into itself CI_ZCOPY, //7, auxiliary color image, copy of depth image CI_AUX, //8, auxiliary color image CI_AUX_COPY //9, auxiliary color image, partial copy of previous color image } CI_STATUS; // Frame buffers typedef struct { uint32_t addr; //color image address uint8_t format; uint8_t size; uint16_t width; uint16_t height; CI_STATUS status; int changed; } COLOR_IMAGE; typedef struct { int32_t tmu; uint32_t addr; //address of color image uint32_t end_addr; uint32_t tex_addr; //address in video memory uint32_t width; //width of color image uint32_t height; //height of color image uint8_t format; //format of color image uint8_t size; //format of color image uint8_t clear; //flag. texture buffer must be cleared uint8_t drawn; //flag. if equal to 1, this image was already drawn in current frame uint32_t crc; //checksum of the color image float scr_width; //width of rendered image float scr_height; //height of rendered image uint32_t tex_width; //width of texture buffer uint32_t tex_height; //height of texture buffer int tile; uint16_t tile_uls; //shift from left bound of the texture uint16_t tile_ult; //shift from top of the texture uint32_t v_shift; //shift from top of the texture uint32_t u_shift; //shift from left of the texture float lr_u; float lr_v; float u_scale; //used to map vertex u,v coordinates into hires texture float v_scale; //used to map vertex u,v coordinates into hires texture CACHE_LUT * cache; //pointer to texture cache item GrTexInfo info; uint16_t t_mem; } TBUFF_COLOR_IMAGE; typedef struct { int32_t tmu; uint32_t begin; //start of the block in video memory uint32_t end; //end of the block in video memory uint8_t count; //number of allocated texture buffers int clear_allowed; //stack of buffers can be cleared TBUFF_COLOR_IMAGE images[256]; } TEXTURE_BUFFER; #define NUMTEXBUF 92 #define FOG_MODE_DISABLED 0 #define FOG_MODE_ENABLED 1 #define FOG_MODE_BLEND 2 #define FOG_MODE_BLEND_INVERSE 3 #define NOISE_MODE_NONE 0 #define NOISE_MODE_COMBINE 1 #define NOISE_MODE_TEXTURE 2 struct RDP { uint32_t u_cull_mode; float vi_width; float vi_height; float offset_x, offset_y, offset_x_bak, offset_y_bak; float scale_x, scale_1024, scale_x_bak; float scale_y, scale_768, scale_y_bak; float view_scale[3]; float view_trans[3]; float clip_min_x, clip_max_x, clip_min_y, clip_max_y; float clip_ratio; int updatescreen; // Program counter uint32_t pc[10]; // Display List PC stack uint32_t pc_i; // current PC index in the stack int dl_count; // number of instructions before returning int LLE; // Segments uint32_t segment[16]; // Segment pointer // Marks the end of DList execution (done in uc?:enddl) int halt; // Next command uint32_t cmd0; uint32_t cmd1; uint32_t cmd2; uint32_t cmd3; // Clipping SCISSOR scissor; int scissor_set; // Colors unsigned noise; float col[4]; // color multiplier float coladd[4]; // color add/subtract float shade_factor; float col_2[4]; uint32_t cmb_flags, cmb_flags_2; // Matrices DECLAREALIGN16VAR(model[4][4]); DECLAREALIGN16VAR(proj[4][4]); DECLAREALIGN16VAR(combined[4][4]); DECLAREALIGN16VAR(dkrproj[3][4][4]); DECLAREALIGN16VAR(model_stack[32][4][4]); // 32 deep, will warn if overflow int model_i; // index in the model matrix stack int model_stack_size; // Textures TEXTURE_IMAGE timg; // 1 for each tmem address TILE tiles[8]; // 8 tile descriptors uint32_t addr[512]; // 512 addresses (used to determine address loaded from) int cur_tile; // current tile int mipmap_level; int last_tile; // last tile set int last_tile_size; // last tile size set int t0, t1; int tex; int filter_mode; // Texture palette uint16_t pal_8[256]; uint32_t pal_8_crc[16]; uint32_t pal_256_crc; uint8_t tlut_mode; int force_wrap; // Lighting uint32_t num_lights; LIGHT light[12]; float light_vector[12][3]; float lookat[2][3]; int use_lookat; // Combine modes uint32_t cycle1, cycle2; uint8_t fbl_a0, fbl_b0, fbl_c0, fbl_d0; uint8_t fbl_a1, fbl_b1, fbl_c1, fbl_d1; // float YUV_C0, YUV_C1, YUV_C2, YUV_C3, YUV_C4; //YUV textures conversion coefficients // What needs updating uint32_t flags; uint32_t tex_ctr; // incremented every time textures are updated int allow_combine; // allow combine updating? int s2dex_tex_loaded; uint16_t bg_image_height; // Debug stuff uint32_t rm; // use othermode_l instead, this just as a check for changes uint32_t render_mode_changed; uint32_t geom_mode; uint32_t othermode_h; uint32_t othermode_l; // used to check if in texrect while loading texture uint8_t texrecting; //frame buffer related slots. Added by Gonetz uint32_t cimg, ocimg, tmpzimg, vi_org_reg; COLOR_IMAGE maincimg[2]; uint32_t last_drawn_ci_addr; uint32_t main_ci, main_ci_end, main_ci_bg, main_ci_last_tex_addr, zimg_end, last_bg; uint32_t ci_width, ci_height, ci_end; uint32_t zi_width; int zi_lrx, zi_lry; uint8_t ci_count, num_of_ci, main_ci_index, copy_ci_index, copy_zi_index; int swap_ci_index, black_ci_index; uint32_t ci_upper_bound, ci_lower_bound; int motionblur, fb_drawn, fb_drawn_front, read_previous_ci, read_whole_frame; CI_STATUS ci_status; int skip_drawing; //rendering is not required. used for frame buffer emulation //fog related slots. Added by Gonetz float fog_multiplier, fog_offset; unsigned fog_mode; // Clipping int clip; // clipping flags VERTEX *vtx1; //[256] copy vertex buffer #1 (used for clipping) VERTEX *vtx2; //[256] copy vertex buffer #2 VERTEX *vtxbuf; // current vertex buffer (reset to vtx, used to determine current vertex buffer) VERTEX *vtxbuf2; int n_global; // Used to pass the number of vertices from clip_z to clip_tri int vtx_buffer; CACHE_LUT *cache[MAX_TMU]; //[MAX_CACHE] CACHE_LUT *cur_cache[MAX_TMU]; int n_cached[MAX_TMU]; // Vertices VERTEX *vtx; //[MAX_VTX] COLOR_IMAGE *frame_buffers; //[NUMTEXBUF+2] char RomName[21]; }; void ChangeSize(void); extern struct RDP rdp; extern SETTINGS settings; extern VOODOO voodoo; extern uint32_t offset_textures; extern uint32_t offset_texbuf1; extern int ucode_error_report; // RDP functions void rdp_free(void); void rdp_new(void); void rdp_reset(void); extern const char *ACmp[]; extern const char *Mode0[]; extern const char *Mode1[]; extern const char *Mode2[]; extern const char *Mode3[]; extern const char *Alpha0[]; #define Alpha1 Alpha0 extern const char *Alpha2[]; #define Alpha3 Alpha0 extern const char *FBLa[]; extern const char *FBLb[]; extern const char *FBLc[]; extern const char *FBLd[]; extern const char *str_zs[]; extern const char *str_yn[]; extern const char *str_offon[]; extern const char *str_cull[]; // I=intensity probably extern const char *str_format[]; extern const char *str_size[]; extern const char *str_cm[]; extern const char *str_lod[]; extern const char *str_aspect[]; extern const char *str_filter[]; extern const char *str_tlut[]; extern const char *CIStatus[]; #define FBL_D_1 2 #define FBL_D_0 3 #ifndef HIWORD #define HIWORD(a) ((uint32_t)(a) >> 16) #endif #ifndef LOWORD #define LOWORD(a) ((a) & 0xFFFF) #endif // Convert from u0/v0/u1/v1 to the real coordinates without regard to tmu static INLINE void ConvertCoordsKeep (VERTEX *v, int n) { int i; for (i = 0; i < n; i++) { v[i].coord[0] = v[i].u[0]; v[i].coord[1] = v[i].v[0]; v[i].coord[2] = v[i].u[1]; v[i].coord[3] = v[i].v[1]; } } // Convert from u0/v0/u1/v1 to the real coordinates based on the tmu they are on static INLINE void ConvertCoordsConvert (VERTEX *v, int n) { int i; for (i = 0; i < n; i++) { v[i].coord[(rdp.t0 << 1) ] = v[i].u[0]; v[i].coord[(rdp.t0 << 1)+1] = v[i].v[0]; v[i].coord[(rdp.t1 << 1) ] = v[i].u[1]; v[i].coord[(rdp.t1 << 1)+1] = v[i].v[1]; } } static INLINE void CalculateFog (VERTEX *v) { if (rdp.flags & FOG_ENABLED) { if (v->w < 0.0f) v->f = 0.0f; else v->f = min(255.0f, max(0.0f, v->z_w * rdp.fog_multiplier + rdp.fog_offset)); v->a = (uint8_t)v->f; } else v->f = 1.0f; } static INLINE void glideSetVertexFlatShading(VERTEX *v, VERTEX **vtx, uint32_t w1) { int flag = min(2, (w1 >> 24) & 3); v->a = vtx[flag]->a; v->b = vtx[flag]->b; v->g = vtx[flag]->g; v->r = vtx[flag]->r; } static INLINE void glideSetVertexPrimShading(VERTEX *v, uint32_t prim_color) { v->r = (uint8_t)g_gdp.prim_color.r; v->g = (uint8_t)g_gdp.prim_color.g; v->b = (uint8_t)g_gdp.prim_color.b; v->a = (uint8_t)g_gdp.prim_color.a; } static INLINE uint32_t vi_integer_sqrt(uint32_t a) { unsigned long op = a, res = 0, one = 1 << 30; while (one > op) one >>= 2; while (one != 0) { if (op >= res + one) { op -= res + one; res += one << 1; } res >>= 1; one >>= 2; } return res; } static INLINE float get_float_color_clamped(float col) { if (col > 1.0f) col = 1.0f; if (col < 0.0f) col = 0.0f; return col; } void newSwapBuffers(void); extern void rdp_setfuncs(void); extern int SwapOK; // ** utility functions void load_palette (uint32_t addr, uint16_t start, uint16_t count); #endif // ifndef RDP_H gles2n64/src/Turbo3D.h000664 001750 001750 00000000126 12655644434 015504 0ustar00sergiosergio000000 000000 #ifndef GLN64_TURBO3D_H #define GLN64_TURBO3D_H void RunTurbo3D(void); #endif mupen64plus-core/src/api/vidext.h000664 001750 001750 00000004007 12655644434 020064 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-core - api/vidext.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2009 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file contains the definitions for the video extension functions which * will be called from other Core modules. */ #ifndef API_VIDEXT_H #define API_VIDEXT_H #include "m64p_types.h" /* global function for use by frontend.c */ extern m64p_error OverrideVideoFunctions(m64p_video_extension_functions *VideoFunctionStruct); /* these functions are only used by the core */ extern int VidExt_InFullscreenMode(void); extern int VidExt_VideoRunning(void); #endif /* API_VIDEXT_H */ mupen64plus-core/src/r4300/hacktarux_dynarec/gr4300.c000664 001750 001750 00000276057 12655644434 023211 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - gr4300.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2007 Richard Goedeken (Richard42) * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "assemble.h" #include "regcache.h" #include "interpret.h" #include "api/debugger.h" #include "main/main.h" #include "memory/memory.h" #include "r4300/r4300.h" #include "r4300/cached_interp.h" #include "r4300/cp0_private.h" #include "r4300/cp1_private.h" #include "r4300/interupt.h" #include "r4300/ops.h" #include "r4300/recomph.h" #include "r4300/exception.h" #if !defined(offsetof) #define offsetof(TYPE,MEMBER) ((unsigned int) &((TYPE*)0)->MEMBER) #endif static precomp_instr fake_instr; #ifdef COMPARE_CORE #ifdef __x86_64__ static int64_t debug_reg_storage[8]; #else static int eax, ebx, ecx, edx, esp, ebp, esi, edi; #endif #endif int branch_taken = 0; /* static functions */ static void genupdate_count(unsigned int addr) { #if !defined(COMPARE_CORE) && !defined(DBG) mov_reg32_imm32(EAX, addr); #ifdef __x86_64__ sub_xreg32_m32rel(EAX, (unsigned int*)(&last_addr)); shr_reg32_imm8(EAX, 2); mov_xreg32_m32rel(EDX, (void*)&count_per_op); mul_reg32(EDX); add_m32rel_xreg32((unsigned int*)(&g_cp0_regs[CP0_COUNT_REG]), EAX); #else sub_reg32_m32(EAX, (unsigned int*)(&last_addr)); shr_reg32_imm8(EAX, 2); mov_reg32_imm32(EDX, count_per_op); mul_reg32(EDX); add_m32_reg32((unsigned int*)(&g_cp0_regs[CP0_COUNT_REG]), EAX); #endif #else #ifdef __x86_64__ mov_reg64_imm64(RAX, (uint64_t) (dst+1)); mov_m64rel_xreg64((uint64_t *)(&PC), RAX); mov_reg64_imm64(RAX, (uint64_t)update_count); call_reg64(RAX); #else mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(dst+1)); mov_reg32_imm32(EAX, (unsigned int)update_count); call_reg32(EAX); #endif #endif } static void gencheck_interupt(uint64_t instr_structure) { #ifdef __x86_64__ mov_xreg32_m32rel(EAX, (void*)(&next_interupt)); cmp_xreg32_m32rel(EAX, (void*)&g_cp0_regs[CP0_COUNT_REG]); ja_rj(0); jump_start_rel8(); mov_reg64_imm64(RAX, (uint64_t) instr_structure); mov_m64rel_xreg64((uint64_t *)(&PC), RAX); mov_reg64_imm64(RAX, (uint64_t) gen_interupt); call_reg64(RAX); jump_end_rel8(); #else mov_eax_memoffs32(&next_interupt); cmp_reg32_m32(EAX, &g_cp0_regs[CP0_COUNT_REG]); ja_rj(17); mov_m32_imm32((unsigned int*)(&PC), instr_structure); // 10 mov_reg32_imm32(EAX, (unsigned int)gen_interupt); // 5 call_reg32(EAX); // 2 #endif } static void gencheck_interupt_out(unsigned int addr) { #ifdef __x86_64__ mov_xreg32_m32rel(EAX, (void*)(&next_interupt)); cmp_xreg32_m32rel(EAX, (void*)&g_cp0_regs[CP0_COUNT_REG]); ja_rj(0); jump_start_rel8(); mov_m32rel_imm32((unsigned int*)(&fake_instr.addr), addr); mov_reg64_imm64(RAX, (uint64_t) (&fake_instr)); mov_m64rel_xreg64((uint64_t *)(&PC), RAX); mov_reg64_imm64(RAX, (uint64_t) gen_interupt); call_reg64(RAX); jump_end_rel8(); #else mov_eax_memoffs32(&next_interupt); cmp_reg32_m32(EAX, &g_cp0_regs[CP0_COUNT_REG]); ja_rj(27); mov_m32_imm32((unsigned int*)(&fake_instr.addr), addr); mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(&fake_instr)); mov_reg32_imm32(EAX, (unsigned int)gen_interupt); call_reg32(EAX); #endif } static void genbeq_test(void) { int rs_64bit = is64((unsigned int *)dst->f.i.rs); int rt_64bit = is64((unsigned int *)dst->f.i.rt); if (rs_64bit == 0 && rt_64bit == 0) { #ifdef __x86_64__ int rs = allocate_register_32((unsigned int *)dst->f.i.rs); int rt = allocate_register_32((unsigned int *)dst->f.i.rt); cmp_reg32_reg32(rs, rt); sete_m8rel((unsigned char *) &branch_taken); #else int rs = allocate_register((unsigned int *)dst->f.i.rs); int rt = allocate_register((unsigned int *)dst->f.i.rt); cmp_reg32_reg32(rs, rt); jne_rj(12); mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10 #endif } else if (rs_64bit == -1) { #ifdef __x86_64__ int rt = allocate_register_64((uint64_t *)dst->f.i.rt); cmp_xreg64_m64rel(rt, (uint64_t *) dst->f.i.rs); sete_m8rel((unsigned char *) &branch_taken); #else int rt1 = allocate_64_register1((unsigned int *)dst->f.i.rt); int rt2 = allocate_64_register2((unsigned int *)dst->f.i.rt); cmp_reg32_m32(rt1, (unsigned int *)dst->f.i.rs); jne_rj(20); cmp_reg32_m32(rt2, ((unsigned int *)dst->f.i.rs)+1); // 6 jne_rj(12); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10 #endif } else if (rt_64bit == -1) { #ifdef __x86_64__ int rs = allocate_register_64((uint64_t *)dst->f.i.rs); cmp_xreg64_m64rel(rs, (uint64_t *)dst->f.i.rt); sete_m8rel((unsigned char *) &branch_taken); #else int rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs); int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs); cmp_reg32_m32(rs1, (unsigned int *)dst->f.i.rt); jne_rj(20); cmp_reg32_m32(rs2, ((unsigned int *)dst->f.i.rt)+1); // 6 jne_rj(12); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10 #endif } else { #ifdef __x86_64__ int rs = allocate_register_64((uint64_t *)dst->f.i.rs); int rt = allocate_register_64((uint64_t *)dst->f.i.rt); cmp_reg64_reg64(rs, rt); sete_m8rel((unsigned char *) &branch_taken); #else int rs1, rs2, rt1, rt2; if (!rs_64bit) { rt1 = allocate_64_register1((unsigned int *)dst->f.i.rt); rt2 = allocate_64_register2((unsigned int *)dst->f.i.rt); rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs); rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs); } else { rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs); rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs); rt1 = allocate_64_register1((unsigned int *)dst->f.i.rt); rt2 = allocate_64_register2((unsigned int *)dst->f.i.rt); } cmp_reg32_reg32(rs1, rt1); jne_rj(16); cmp_reg32_reg32(rs2, rt2); // 2 jne_rj(12); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10 #endif } } static void genbne_test(void) { int rs_64bit = is64((unsigned int *)dst->f.i.rs); int rt_64bit = is64((unsigned int *)dst->f.i.rt); #ifdef __x86_64__ if (rs_64bit == 0 && rt_64bit == 0) { int rs = allocate_register_32((unsigned int *)dst->f.i.rs); int rt = allocate_register_32((unsigned int *)dst->f.i.rt); cmp_reg32_reg32(rs, rt); setne_m8rel((unsigned char *) &branch_taken); } else if (rs_64bit == -1) { int rt = allocate_register_64((uint64_t *) dst->f.i.rt); cmp_xreg64_m64rel(rt, (uint64_t *)dst->f.i.rs); setne_m8rel((unsigned char *) &branch_taken); } else if (rt_64bit == -1) { int rs = allocate_register_64((uint64_t *) dst->f.i.rs); cmp_xreg64_m64rel(rs, (uint64_t *)dst->f.i.rt); setne_m8rel((unsigned char *) &branch_taken); } else { int rs = allocate_register_64((uint64_t *)dst->f.i.rs); int rt = allocate_register_64((uint64_t *)dst->f.i.rt); cmp_reg64_reg64(rs, rt); setne_m8rel((unsigned char *) &branch_taken); } #else if (!rs_64bit && !rt_64bit) { int rs = allocate_register((unsigned int *)dst->f.i.rs); int rt = allocate_register((unsigned int *)dst->f.i.rt); cmp_reg32_reg32(rs, rt); je_rj(12); mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10 } else if (rs_64bit == -1) { int rt1 = allocate_64_register1((unsigned int *)dst->f.i.rt); int rt2 = allocate_64_register2((unsigned int *)dst->f.i.rt); cmp_reg32_m32(rt1, (unsigned int *)dst->f.i.rs); jne_rj(20); cmp_reg32_m32(rt2, ((unsigned int *)dst->f.i.rs)+1); // 6 jne_rj(12); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10 } else if (rt_64bit == -1) { int rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs); int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs); cmp_reg32_m32(rs1, (unsigned int *)dst->f.i.rt); jne_rj(20); cmp_reg32_m32(rs2, ((unsigned int *)dst->f.i.rt)+1); // 6 jne_rj(12); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10 } else { int rs1, rs2, rt1, rt2; if (!rs_64bit) { rt1 = allocate_64_register1((unsigned int *)dst->f.i.rt); rt2 = allocate_64_register2((unsigned int *)dst->f.i.rt); rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs); rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs); } else { rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs); rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs); rt1 = allocate_64_register1((unsigned int *)dst->f.i.rt); rt2 = allocate_64_register2((unsigned int *)dst->f.i.rt); } cmp_reg32_reg32(rs1, rt1); jne_rj(16); cmp_reg32_reg32(rs2, rt2); // 2 jne_rj(12); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10 } #endif } static void genblez_test(void) { int rs_64bit = is64((unsigned int *)dst->f.i.rs); #ifdef __x86_64__ if (rs_64bit == 0) { int rs = allocate_register_32((unsigned int *)dst->f.i.rs); cmp_reg32_imm32(rs, 0); setle_m8rel((unsigned char *) &branch_taken); } else { int rs = allocate_register_64((uint64_t *)dst->f.i.rs); cmp_reg64_imm8(rs, 0); setle_m8rel((unsigned char *) &branch_taken); } #else if (!rs_64bit) { int rs = allocate_register((unsigned int *)dst->f.i.rs); cmp_reg32_imm32(rs, 0); jg_rj(12); mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10 } else if (rs_64bit == -1) { cmp_m32_imm32(((unsigned int *)dst->f.i.rs)+1, 0); jg_rj(14); jne_rj(24); // 2 cmp_m32_imm32((unsigned int *)dst->f.i.rs, 0); // 10 je_rj(12); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10 } else { int rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs); int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs); cmp_reg32_imm32(rs2, 0); jg_rj(10); jne_rj(20); // 2 cmp_reg32_imm32(rs1, 0); // 6 je_rj(12); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10 } #endif } static void genbgtz_test(void) { int rs_64bit = is64((unsigned int *)dst->f.i.rs); #ifdef __x86_64__ if (rs_64bit == 0) { int rs = allocate_register_32((unsigned int *)dst->f.i.rs); cmp_reg32_imm32(rs, 0); setg_m8rel((unsigned char *) &branch_taken); } else { int rs = allocate_register_64((uint64_t *)dst->f.i.rs); cmp_reg64_imm8(rs, 0); setg_m8rel((unsigned char *) &branch_taken); } #else if (!rs_64bit) { int rs = allocate_register((unsigned int *)dst->f.i.rs); cmp_reg32_imm32(rs, 0); jle_rj(12); mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10 } else if (rs_64bit == -1) { cmp_m32_imm32(((unsigned int *)dst->f.i.rs)+1, 0); jl_rj(14); jne_rj(24); // 2 cmp_m32_imm32((unsigned int *)dst->f.i.rs, 0); // 10 jne_rj(12); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10 } else { int rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs); int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs); cmp_reg32_imm32(rs2, 0); jl_rj(10); jne_rj(20); // 2 cmp_reg32_imm32(rs1, 0); // 6 jne_rj(12); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10 } #endif } #ifdef __x86_64__ static void ld_register_alloc(int *pGpr1, int *pGpr2, int *pBase1, int *pBase2) { int gpr1, gpr2, base1, base2 = 0; #ifdef COMPARE_CORE free_registers_move_start(); // to maintain parity with 32-bit core #endif if (dst->f.i.rs == dst->f.i.rt) { allocate_register_32((unsigned int*)dst->f.r.rs); // tell regcache we need to read RS register here gpr1 = allocate_register_32_w((unsigned int*)dst->f.r.rt); // tell regcache we will modify RT register during this instruction gpr2 = lock_register(lru_register()); // free and lock least recently used register for usage here add_reg32_imm32(gpr1, (int)dst->f.i.immediate); mov_reg32_reg32(gpr2, gpr1); } else { gpr2 = allocate_register_32((unsigned int*)dst->f.r.rs); // tell regcache we need to read RS register here gpr1 = allocate_register_32_w((unsigned int*)dst->f.r.rt); // tell regcache we will modify RT register during this instruction free_register(gpr2); // write out gpr2 if dirty because I'm going to trash it right now add_reg32_imm32(gpr2, (int)dst->f.i.immediate); mov_reg32_reg32(gpr1, gpr2); lock_register(gpr2); // lock the freed gpr2 it so it doesn't get returned in the lru query } base1 = lock_register(lru_base_register()); // get another lru register if (!fast_memory) { base2 = lock_register(lru_base_register()); // and another one if necessary unlock_register(base2); } unlock_register(base1); // unlock the locked registers (they are unlock_register(gpr2); set_register_state(gpr1, NULL, 0, 0); // clear gpr1 state because it hasn't been written yet - // we don't want it to be pushed/popped around read_rdramX call *pGpr1 = gpr1; *pGpr2 = gpr2; *pBase1 = base1; *pBase2 = base2; } #endif /* global functions */ void gennotcompiled(void) { #ifdef __x86_64__ free_registers_move_start(); mov_reg64_imm64(RAX, (uint64_t) dst); mov_memoffs64_rax((uint64_t *) &PC); /* RIP-relative will not work here */ mov_reg64_imm64(RAX, (uint64_t) cached_interpreter_table.NOTCOMPILED); call_reg64(RAX); #else free_all_registers(); simplify_access(); mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(dst)); mov_reg32_imm32(EAX, (unsigned int)cached_interpreter_table.NOTCOMPILED); call_reg32(EAX); #endif } void genlink_subblock(void) { free_all_registers(); jmp(dst->addr+4); } #ifdef COMPARE_CORE extern unsigned int op_R4300; /* api/debugger.c */ void gendebug(void) { free_all_registers(); #ifdef __x86_64__ mov_memoffs64_rax((uint64_t *) &debug_reg_storage); mov_reg64_imm64(RAX, (uint64_t) &debug_reg_storage); mov_preg64pimm8_reg64(RAX, 8, RBX); mov_preg64pimm8_reg64(RAX, 16, RCX); mov_preg64pimm8_reg64(RAX, 24, RDX); mov_preg64pimm8_reg64(RAX, 32, RSP); mov_preg64pimm8_reg64(RAX, 40, RBP); mov_preg64pimm8_reg64(RAX, 48, RSI); mov_preg64pimm8_reg64(RAX, 56, RDI); mov_reg64_imm64(RAX, (uint64_t) dst); mov_memoffs64_rax((uint64_t *) &PC); mov_reg32_imm32(EAX, (unsigned int) src); mov_memoffs32_eax((unsigned int *) &op); mov_reg64_imm64(RAX, (uint64_t) CoreCompareCallback); call_reg64(RAX); mov_reg64_imm64(RAX, (uint64_t) &debug_reg_storage); mov_reg64_preg64pimm8(RDI, RAX, 56); mov_reg64_preg64pimm8(RSI, RAX, 48); mov_reg64_preg64pimm8(RBP, RAX, 40); mov_reg64_preg64pimm8(RSP, RAX, 32); mov_reg64_preg64pimm8(RDX, RAX, 24); mov_reg64_preg64pimm8(RCX, RAX, 16); mov_reg64_preg64pimm8(RBX, RAX, 8); mov_reg64_preg64(RAX, RAX); #else mov_m32_reg32((unsigned int*)&eax, EAX); mov_m32_reg32((unsigned int*)&ebx, EBX); mov_m32_reg32((unsigned int*)&ecx, ECX); mov_m32_reg32((unsigned int*)&edx, EDX); mov_m32_reg32((unsigned int*)&esp, ESP); mov_m32_reg32((unsigned int*)&ebp, EBP); mov_m32_reg32((unsigned int*)&esi, ESI); mov_m32_reg32((unsigned int*)&edi, EDI); mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(dst)); mov_m32_imm32((unsigned int*)(&op), (unsigned int)(src)); mov_reg32_imm32(EAX, (unsigned int) CoreCompareCallback); call_reg32(EAX); mov_reg32_m32(EAX, (unsigned int*)&eax); mov_reg32_m32(EBX, (unsigned int*)&ebx); mov_reg32_m32(ECX, (unsigned int*)&ecx); mov_reg32_m32(EDX, (unsigned int*)&edx); mov_reg32_m32(ESP, (unsigned int*)&esp); mov_reg32_m32(EBP, (unsigned int*)&ebp); mov_reg32_m32(ESI, (unsigned int*)&esi); mov_reg32_m32(EDI, (unsigned int*)&edi); #endif } #endif void gencallinterp(uintptr_t addr, int jump) { #ifdef __x86_64__ free_registers_move_start(); if (jump) mov_m32rel_imm32((unsigned int*)(&dyna_interp), 1); mov_reg64_imm64(RAX, (uint64_t) dst); mov_m64rel_xreg64((uint64_t *)(&PC), RAX); mov_reg64_imm64(RAX, addr); call_reg64(RAX); if (jump) { mov_m32rel_imm32((unsigned int*)(&dyna_interp), 0); mov_reg64_imm64(RAX, (uint64_t)dyna_jump); call_reg64(RAX); } #else free_all_registers(); simplify_access(); if (jump) mov_m32_imm32((unsigned int*)(&dyna_interp), 1); mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(dst)); mov_reg32_imm32(EAX, addr); call_reg32(EAX); if (jump) { mov_m32_imm32((unsigned int*)(&dyna_interp), 0); mov_reg32_imm32(EAX, (unsigned int)dyna_jump); call_reg32(EAX); } #endif } void gendelayslot(void) { #ifdef __x86_64__ mov_m32rel_imm32((void*)(&delay_slot), 1); recompile_opcode(); free_all_registers(); genupdate_count(dst->addr+4); mov_m32rel_imm32((void*)(&delay_slot), 0); #else mov_m32_imm32(&delay_slot, 1); recompile_opcode(); free_all_registers(); genupdate_count(dst->addr+4); mov_m32_imm32(&delay_slot, 0); #endif } void genni(void) { gencallinterp((native_type)cached_interpreter_table.NI, 0); } void genreserved(void) { gencallinterp((native_type)cached_interpreter_table.RESERVED, 0); } void genfin_block(void) { gencallinterp((native_type)cached_interpreter_table.FIN_BLOCK, 0); } void gencheck_interupt_reg(void) // addr is in EAX { #ifdef __x86_64__ mov_xreg32_m32rel(EBX, (void*)&next_interupt); cmp_xreg32_m32rel(EBX, (void*)&g_cp0_regs[CP0_COUNT_REG]); ja_rj(0); jump_start_rel8(); mov_m32rel_xreg32((unsigned int*)(&fake_instr.addr), EAX); mov_reg64_imm64(RAX, (uint64_t) (&fake_instr)); mov_m64rel_xreg64((uint64_t *)(&PC), RAX); mov_reg64_imm64(RAX, (uint64_t) gen_interupt); call_reg64(RAX); jump_end_rel8(); #else mov_reg32_m32(EBX, &next_interupt); cmp_reg32_m32(EBX, &g_cp0_regs[CP0_COUNT_REG]); ja_rj(22); mov_memoffs32_eax((unsigned int*)(&fake_instr.addr)); // 5 mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(&fake_instr)); // 10 mov_reg32_imm32(EAX, (unsigned int)gen_interupt); // 5 call_reg32(EAX); // 2 #endif } void gennop(void) { } void genj(void) { #ifdef INTERPRET_J gencallinterp((native_type)cached_interpreter_table.J, 1); #else unsigned int naddr; if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.J, 1); return; } gendelayslot(); naddr = ((dst-1)->f.j.inst_index<<2) | (dst->addr & 0xF0000000); #ifdef __x86_64__ mov_m32rel_imm32((void*)(&last_addr), naddr); #else mov_m32_imm32(&last_addr, naddr); #endif gencheck_interupt((native_type) &actual->block[(naddr-actual->start)/4]); jmp(naddr); #endif } void genj_out(void) { #ifdef INTERPRET_J_OUT gencallinterp((native_type)cached_interpreter_table.J_OUT, 1); #else unsigned int naddr; if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.J_OUT, 1); return; } gendelayslot(); naddr = ((dst-1)->f.j.inst_index<<2) | (dst->addr & 0xF0000000); #ifdef __x86_64__ mov_m32rel_imm32((void*)(&last_addr), naddr); gencheck_interupt_out(naddr); mov_m32rel_imm32(&jump_to_address, naddr); mov_reg64_imm64(RAX, (uint64_t) (dst+1)); mov_m64rel_xreg64((uint64_t *)(&PC), RAX); mov_reg64_imm64(RAX, (uint64_t)jump_to_func); call_reg64(RAX); #else mov_m32_imm32(&last_addr, naddr); gencheck_interupt_out(naddr); mov_m32_imm32(&jump_to_address, naddr); mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(dst+1)); mov_reg32_imm32(EAX, (unsigned int)jump_to_func); call_reg32(EAX); #endif #endif } void genj_idle(void) { #ifdef INTERPRET_J_IDLE gencallinterp((native_type)cached_interpreter_table.J_IDLE, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.J_IDLE, 1); return; } #ifdef __x86_64__ mov_xreg32_m32rel(EAX, (unsigned int *)(&next_interupt)); sub_xreg32_m32rel(EAX, (unsigned int *)(&g_cp0_regs[CP0_COUNT_REG])); cmp_reg32_imm8(EAX, 3); jbe_rj(12); and_eax_imm32(0xFFFFFFFC); // 5 add_m32rel_xreg32((unsigned int *)(&g_cp0_regs[CP0_COUNT_REG]), EAX); // 7 #else mov_eax_memoffs32((unsigned int *)(&next_interupt)); sub_reg32_m32(EAX, (unsigned int *)(&g_cp0_regs[CP0_COUNT_REG])); cmp_reg32_imm8(EAX, 3); jbe_rj(11); and_eax_imm32(0xFFFFFFFC); // 5 add_m32_reg32((unsigned int *)(&g_cp0_regs[CP0_COUNT_REG]), EAX); // 6 #endif genj(); #endif } void genjal(void) { #ifdef INTERPRET_JAL gencallinterp((native_type)cached_interpreter_table.JAL, 1); #else unsigned int naddr; if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.JAL, 1); return; } gendelayslot(); #ifdef __x86_64__ mov_m32rel_imm32((unsigned int *)(reg + 31), dst->addr + 4); if (((dst->addr + 4) & 0x80000000)) mov_m32rel_imm32((unsigned int *)(®[31])+1, 0xFFFFFFFF); else mov_m32rel_imm32((unsigned int *)(®[31])+1, 0); naddr = ((dst-1)->f.j.inst_index<<2) | (dst->addr & 0xF0000000); mov_m32rel_imm32((void*)(&last_addr), naddr); #else mov_m32_imm32((unsigned int *)(reg + 31), dst->addr + 4); if (((dst->addr + 4) & 0x80000000)) mov_m32_imm32((unsigned int *)(®[31])+1, 0xFFFFFFFF); else mov_m32_imm32((unsigned int *)(®[31])+1, 0); naddr = ((dst-1)->f.j.inst_index<<2) | (dst->addr & 0xF0000000); mov_m32_imm32(&last_addr, naddr); #endif gencheck_interupt((native_type) &actual->block[(naddr-actual->start)/4]); jmp(naddr); #endif } void genjal_out(void) { #ifdef INTERPRET_JAL_OUT gencallinterp((native_type)cached_interpreter_table.JAL_OUT, 1); #else unsigned int naddr; if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.JAL_OUT, 1); return; } gendelayslot(); #ifdef __x86_64__ mov_m32rel_imm32((unsigned int *)(reg + 31), dst->addr + 4); if (((dst->addr + 4) & 0x80000000)) mov_m32rel_imm32((unsigned int *)(®[31])+1, 0xFFFFFFFF); else mov_m32rel_imm32((unsigned int *)(®[31])+1, 0); naddr = ((dst-1)->f.j.inst_index<<2) | (dst->addr & 0xF0000000); mov_m32rel_imm32((void*)(&last_addr), naddr); gencheck_interupt_out(naddr); mov_m32rel_imm32(&jump_to_address, naddr); mov_reg64_imm64(RAX, (uint64_t) (dst+1)); mov_m64rel_xreg64((uint64_t *)(&PC), RAX); mov_reg64_imm64(RAX, (uint64_t) jump_to_func); call_reg64(RAX); #else mov_m32_imm32((unsigned int *)(reg + 31), dst->addr + 4); if (((dst->addr + 4) & 0x80000000)) mov_m32_imm32((unsigned int *)(®[31])+1, 0xFFFFFFFF); else mov_m32_imm32((unsigned int *)(®[31])+1, 0); naddr = ((dst-1)->f.j.inst_index<<2) | (dst->addr & 0xF0000000); mov_m32_imm32(&last_addr, naddr); gencheck_interupt_out(naddr); mov_m32_imm32(&jump_to_address, naddr); mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(dst+1)); mov_reg32_imm32(EAX, (unsigned int)jump_to_func); call_reg32(EAX); #endif #endif } void genjal_idle(void) { #ifdef INTERPRET_JAL_IDLE gencallinterp((native_type)cached_interpreter_table.JAL_IDLE, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.JAL_IDLE, 1); return; } #ifdef __x86_64__ mov_xreg32_m32rel(EAX, (unsigned int *)(&next_interupt)); sub_xreg32_m32rel(EAX, (unsigned int *)(&g_cp0_regs[CP0_COUNT_REG])); cmp_reg32_imm8(EAX, 3); jbe_rj(12); and_eax_imm32(0xFFFFFFFC); // 5 add_m32rel_xreg32((unsigned int *)(&g_cp0_regs[CP0_COUNT_REG]), EAX); // 7 #else mov_eax_memoffs32((unsigned int *)(&next_interupt)); sub_reg32_m32(EAX, (unsigned int *)(&g_cp0_regs[CP0_COUNT_REG])); cmp_reg32_imm8(EAX, 3); jbe_rj(11); and_eax_imm32(0xFFFFFFFC); add_m32_reg32((unsigned int *)(&g_cp0_regs[CP0_COUNT_REG]), EAX); #endif genjal(); #endif } void gentest(void) { #ifdef __x86_64__ cmp_m32rel_imm32((unsigned int *)(&branch_taken), 0); je_near_rj(0); jump_start_rel32(); mov_m32rel_imm32((void*)(&last_addr), dst->addr + (dst-1)->f.i.immediate*4); gencheck_interupt((uint64_t) (dst + (dst-1)->f.i.immediate)); jmp(dst->addr + (dst-1)->f.i.immediate*4); jump_end_rel32(); mov_m32rel_imm32((void*)(&last_addr), dst->addr + 4); #else cmp_m32_imm32((unsigned int *)(&branch_taken), 0); je_near_rj(0); jump_start_rel32(); mov_m32_imm32(&last_addr, dst->addr + (dst-1)->f.i.immediate*4); gencheck_interupt((unsigned int)(dst + (dst-1)->f.i.immediate)); jmp(dst->addr + (dst-1)->f.i.immediate*4); jump_end_rel32(); mov_m32_imm32(&last_addr, dst->addr + 4); #endif gencheck_interupt((native_type)(dst + 1)); jmp(dst->addr + 4); } void genbeq(void) { #ifdef INTERPRET_BEQ gencallinterp((native_type)cached_interpreter_table.BEQ, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BEQ, 1); return; } genbeq_test(); gendelayslot(); gentest(); #endif } void gentest_out(void) { #ifdef __x86_64__ cmp_m32rel_imm32((unsigned int *)(&branch_taken), 0); je_near_rj(0); jump_start_rel32(); mov_m32rel_imm32((void*)(&last_addr), dst->addr + (dst-1)->f.i.immediate*4); gencheck_interupt_out(dst->addr + (dst-1)->f.i.immediate*4); mov_m32rel_imm32(&jump_to_address, dst->addr + (dst-1)->f.i.immediate*4); mov_reg64_imm64(RAX, (uint64_t) (dst+1)); mov_m64rel_xreg64((uint64_t *)(&PC), RAX); mov_reg64_imm64(RAX, (uint64_t) jump_to_func); call_reg64(RAX); jump_end_rel32(); mov_m32rel_imm32((void*)(&last_addr), dst->addr + 4); #else cmp_m32_imm32((unsigned int *)(&branch_taken), 0); je_near_rj(0); jump_start_rel32(); mov_m32_imm32(&last_addr, dst->addr + (dst-1)->f.i.immediate*4); gencheck_interupt_out(dst->addr + (dst-1)->f.i.immediate*4); mov_m32_imm32(&jump_to_address, dst->addr + (dst-1)->f.i.immediate*4); mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(dst+1)); mov_reg32_imm32(EAX, (unsigned int)jump_to_func); call_reg32(EAX); jump_end_rel32(); mov_m32_imm32(&last_addr, dst->addr + 4); #endif gencheck_interupt((native_type) (dst + 1)); jmp(dst->addr + 4); } void genbeq_out(void) { #ifdef INTERPRET_BEQ_OUT gencallinterp((native_type)cached_interpreter_table.BEQ_OUT, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BEQ_OUT, 1); return; } genbeq_test(); gendelayslot(); gentest_out(); #endif } void gentest_idle(void) { int reg; reg = lru_register(); free_register(reg); #ifdef __x86_64__ cmp_m32rel_imm32((unsigned int *)(&branch_taken), 0); je_near_rj(0); jump_start_rel32(); mov_xreg32_m32rel(reg, (unsigned int *)(&next_interupt)); sub_xreg32_m32rel(reg, (unsigned int *)(&g_cp0_regs[CP0_COUNT_REG])); cmp_reg32_imm8(reg, 3); jbe_rj(0); jump_start_rel8(); and_reg32_imm32(reg, 0xFFFFFFFC); add_m32rel_xreg32((unsigned int *)(&g_cp0_regs[CP0_COUNT_REG]), reg); jump_end_rel8(); #else cmp_m32_imm32((unsigned int *)(&branch_taken), 0); je_near_rj(0); jump_start_rel32(); mov_reg32_m32(reg, (unsigned int *)(&next_interupt)); sub_reg32_m32(reg, (unsigned int *)(&g_cp0_regs[CP0_COUNT_REG])); cmp_reg32_imm8(reg, 5); jbe_rj(18); sub_reg32_imm32(reg, 2); // 6 and_reg32_imm32(reg, 0xFFFFFFFC); // 6 add_m32_reg32((unsigned int *)(&g_cp0_regs[CP0_COUNT_REG]), reg); // 6 #endif jump_end_rel32(); } void genbeq_idle(void) { #ifdef INTERPRET_BEQ_IDLE gencallinterp((native_type)cached_interpreter_table.BEQ_IDLE, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BEQ_IDLE, 1); return; } genbeq_test(); gentest_idle(); genbeq(); #endif } void genbne(void) { #ifdef INTERPRET_BNE gencallinterp((native_type)cached_interpreter_table.BNE, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BNE, 1); return; } genbne_test(); gendelayslot(); gentest(); #endif } void genbne_out(void) { #ifdef INTERPRET_BNE_OUT gencallinterp((native_type)cached_interpreter_table.BNE_OUT, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BNE_OUT, 1); return; } genbne_test(); gendelayslot(); gentest_out(); #endif } void genbne_idle(void) { #ifdef INTERPRET_BNE_IDLE gencallinterp((native_type)cached_interpreter_table.BNE_IDLE, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BNE_IDLE, 1); return; } genbne_test(); gentest_idle(); genbne(); #endif } void genblez(void) { #ifdef INTERPRET_BLEZ gencallinterp((native_type)cached_interpreter_table.BLEZ, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BLEZ, 1); return; } genblez_test(); gendelayslot(); gentest(); #endif } void genblez_out(void) { #ifdef INTERPRET_BLEZ_OUT gencallinterp((native_type)cached_interpreter_table.BLEZ_OUT, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BLEZ_OUT, 1); return; } genblez_test(); gendelayslot(); gentest_out(); #endif } void genblez_idle(void) { #ifdef INTERPRET_BLEZ_IDLE gencallinterp((native_type)cached_interpreter_table.BLEZ_IDLE, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BLEZ_IDLE, 1); return; } genblez_test(); gentest_idle(); genblez(); #endif } void genbgtz(void) { #ifdef INTERPRET_BGTZ gencallinterp((native_type)cached_interpreter_table.BGTZ, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BGTZ, 1); return; } genbgtz_test(); gendelayslot(); gentest(); #endif } void genbgtz_out(void) { #ifdef INTERPRET_BGTZ_OUT gencallinterp((native_type)cached_interpreter_table.BGTZ_OUT, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BGTZ_OUT, 1); return; } genbgtz_test(); gendelayslot(); gentest_out(); #endif } void genbgtz_idle(void) { #ifdef INTERPRET_BGTZ_IDLE gencallinterp((native_type)cached_interpreter_table.BGTZ_IDLE, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BGTZ_IDLE, 1); return; } genbgtz_test(); gentest_idle(); genbgtz(); #endif } void genaddi(void) { #ifdef INTERPRET_ADDI gencallinterp((native_type)cached_interpreter_table.ADDI, 0); #else #ifdef __x86_64__ int rs = allocate_register_32((unsigned int *)dst->f.i.rs); int rt = allocate_register_32_w((unsigned int *)dst->f.i.rt); #else int rs = allocate_register((unsigned int *)dst->f.i.rs); int rt = allocate_register_w((unsigned int *)dst->f.i.rt); #endif mov_reg32_reg32(rt, rs); add_reg32_imm32(rt,(int)dst->f.i.immediate); #endif } void genaddiu(void) { #ifdef INTERPRET_ADDIU gencallinterp((native_type)cached_interpreter_table.ADDIU, 0); #else #ifdef __x86_64__ int rs = allocate_register_32((unsigned int *)dst->f.i.rs); int rt = allocate_register_32_w((unsigned int *)dst->f.i.rt); #else int rs = allocate_register((unsigned int *)dst->f.i.rs); int rt = allocate_register_w((unsigned int *)dst->f.i.rt); #endif mov_reg32_reg32(rt, rs); add_reg32_imm32(rt,(int)dst->f.i.immediate); #endif } void genslti(void) { #ifdef INTERPRET_SLTI gencallinterp((native_type)cached_interpreter_table.SLTI, 0); #else #ifdef __x86_64__ int rs = allocate_register_64((uint64_t *) dst->f.i.rs); int rt = allocate_register_64_w((uint64_t *) dst->f.i.rt); int imm = (int) dst->f.i.immediate; cmp_reg64_imm32(rs, imm); setl_reg8(rt); and_reg64_imm8(rt, 1); #else int rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs); int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs); int rt = allocate_register_w((unsigned int *)dst->f.i.rt); int64_t imm = (int64_t)dst->f.i.immediate; cmp_reg32_imm32(rs2, (unsigned int)(imm >> 32)); jl_rj(17); jne_rj(8); // 2 cmp_reg32_imm32(rs1, (unsigned int)imm); // 6 jl_rj(7); // 2 mov_reg32_imm32(rt, 0); // 5 jmp_imm_short(5); // 2 mov_reg32_imm32(rt, 1); // 5 #endif #endif } void gensltiu(void) { #ifdef INTERPRET_SLTIU gencallinterp((native_type)cached_interpreter_table.SLTIU, 0); #else #ifdef __x86_64__ int rs = allocate_register_64((uint64_t *)dst->f.i.rs); int rt = allocate_register_64_w((uint64_t *)dst->f.i.rt); int imm = (int) dst->f.i.immediate; cmp_reg64_imm32(rs, imm); setb_reg8(rt); and_reg64_imm8(rt, 1); #else int rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs); int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs); int rt = allocate_register_w((unsigned int *)dst->f.i.rt); int64_t imm = (int64_t)dst->f.i.immediate; cmp_reg32_imm32(rs2, (unsigned int)(imm >> 32)); jb_rj(17); jne_rj(8); // 2 cmp_reg32_imm32(rs1, (unsigned int)imm); // 6 jb_rj(7); // 2 mov_reg32_imm32(rt, 0); // 5 jmp_imm_short(5); // 2 mov_reg32_imm32(rt, 1); // 5 #endif #endif } void genandi(void) { #ifdef INTERPRET_ANDI gencallinterp((native_type)cached_interpreter_table.ANDI, 0); #else #ifdef __x86_64__ int rs = allocate_register_64((uint64_t *)dst->f.i.rs); int rt = allocate_register_64_w((uint64_t *)dst->f.i.rt); mov_reg64_reg64(rt, rs); and_reg64_imm32(rt, (unsigned short)dst->f.i.immediate); #else int rs = allocate_register((unsigned int *)dst->f.i.rs); int rt = allocate_register_w((unsigned int *)dst->f.i.rt); mov_reg32_reg32(rt, rs); and_reg32_imm32(rt, (unsigned short)dst->f.i.immediate); #endif #endif } void genori(void) { #ifdef INTERPRET_ORI gencallinterp((native_type)cached_interpreter_table.ORI, 0); #else #ifdef __x86_64__ int rs = allocate_register_64((uint64_t *) dst->f.i.rs); int rt = allocate_register_64_w((uint64_t *) dst->f.i.rt); mov_reg64_reg64(rt, rs); or_reg64_imm32(rt, (unsigned short)dst->f.i.immediate); #else int rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs); int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs); int rt1 = allocate_64_register1_w((unsigned int *)dst->f.i.rt); int rt2 = allocate_64_register2_w((unsigned int *)dst->f.i.rt); mov_reg32_reg32(rt1, rs1); mov_reg32_reg32(rt2, rs2); or_reg32_imm32(rt1, (unsigned short)dst->f.i.immediate); #endif #endif } void genxori(void) { #ifdef INTERPRET_XORI gencallinterp((native_type)cached_interpreter_table.XORI, 0); #else #ifdef __x86_64__ int rs = allocate_register_64((uint64_t *)dst->f.i.rs); int rt = allocate_register_64_w((uint64_t *)dst->f.i.rt); mov_reg64_reg64(rt, rs); xor_reg64_imm32(rt, (unsigned short)dst->f.i.immediate); #else int rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs); int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs); int rt1 = allocate_64_register1_w((unsigned int *)dst->f.i.rt); int rt2 = allocate_64_register2_w((unsigned int *)dst->f.i.rt); mov_reg32_reg32(rt1, rs1); mov_reg32_reg32(rt2, rs2); xor_reg32_imm32(rt1, (unsigned short)dst->f.i.immediate); #endif #endif } void genlui(void) { #ifdef INTERPRET_LUI gencallinterp((native_type)cached_interpreter_table.LUI, 0); #else #ifdef __x86_64__ int rt = allocate_register_32_w((unsigned int *)dst->f.i.rt); #else int rt = allocate_register_w((unsigned int *)dst->f.i.rt); #endif mov_reg32_imm32(rt, (unsigned int)dst->f.i.immediate << 16); #endif } void gentestl(void) { #ifdef __x86_64__ cmp_m32rel_imm32((unsigned int *)(&branch_taken), 0); je_near_rj(0); jump_start_rel32(); gendelayslot(); mov_m32rel_imm32((void*)(&last_addr), dst->addr + (dst-1)->f.i.immediate*4); gencheck_interupt((uint64_t) (dst + (dst-1)->f.i.immediate)); jmp(dst->addr + (dst-1)->f.i.immediate*4); jump_end_rel32(); genupdate_count(dst->addr-4); mov_m32rel_imm32((void*)(&last_addr), dst->addr + 4); #else cmp_m32_imm32((unsigned int *)(&branch_taken), 0); je_near_rj(0); jump_start_rel32(); gendelayslot(); mov_m32_imm32(&last_addr, dst->addr + (dst-1)->f.i.immediate*4); gencheck_interupt((unsigned int)(dst + (dst-1)->f.i.immediate)); jmp(dst->addr + (dst-1)->f.i.immediate*4); jump_end_rel32(); genupdate_count(dst->addr+4); mov_m32_imm32(&last_addr, dst->addr + 4); #endif gencheck_interupt((native_type) (dst + 1)); jmp(dst->addr + 4); } void genbeql(void) { #ifdef INTERPRET_BEQL gencallinterp((native_type)cached_interpreter_table.BEQL, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BEQL, 1); return; } genbeq_test(); free_all_registers(); gentestl(); #endif } void gentestl_out(void) { #ifdef __x86_64__ cmp_m32rel_imm32((unsigned int *)(&branch_taken), 0); je_near_rj(0); jump_start_rel32(); gendelayslot(); mov_m32rel_imm32((void*)(&last_addr), dst->addr + (dst-1)->f.i.immediate*4); gencheck_interupt_out(dst->addr + (dst-1)->f.i.immediate*4); mov_m32rel_imm32(&jump_to_address, dst->addr + (dst-1)->f.i.immediate*4); mov_reg64_imm64(RAX, (uint64_t) (dst+1)); mov_m64rel_xreg64((uint64_t *)(&PC), RAX); mov_reg64_imm64(RAX, (uint64_t) jump_to_func); call_reg64(RAX); jump_end_rel32(); genupdate_count(dst->addr-4); mov_m32rel_imm32((void*)(&last_addr), dst->addr + 4); #else cmp_m32_imm32((unsigned int *)(&branch_taken), 0); je_near_rj(0); jump_start_rel32(); gendelayslot(); mov_m32_imm32(&last_addr, dst->addr + (dst-1)->f.i.immediate*4); gencheck_interupt_out(dst->addr + (dst-1)->f.i.immediate*4); mov_m32_imm32(&jump_to_address, dst->addr + (dst-1)->f.i.immediate*4); mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(dst+1)); mov_reg32_imm32(EAX, (unsigned int)jump_to_func); call_reg32(EAX); jump_end_rel32(); genupdate_count(dst->addr+4); mov_m32_imm32(&last_addr, dst->addr + 4); #endif gencheck_interupt((native_type)(dst + 1)); jmp(dst->addr + 4); } void genbeql_out(void) { #ifdef INTERPRET_BEQL_OUT gencallinterp((native_type)cached_interpreter_table.BEQL_OUT, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BEQL_OUT, 1); return; } genbeq_test(); free_all_registers(); gentestl_out(); #endif } void genbeql_idle(void) { #ifdef INTERPRET_BEQL_IDLE gencallinterp((native_type)cached_interpreter_table.BEQL_IDLE, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BEQL_IDLE, 1); return; } genbeq_test(); gentest_idle(); genbeql(); #endif } void genbnel(void) { #ifdef INTERPRET_BNEL gencallinterp((native_type)cached_interpreter_table.BNEL, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BNEL, 1); return; } genbne_test(); free_all_registers(); gentestl(); #endif } void genbnel_out(void) { #ifdef INTERPRET_BNEL_OUT gencallinterp((native_type)cached_interpreter_table.BNEL_OUT, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BNEL_OUT, 1); return; } genbne_test(); free_all_registers(); gentestl_out(); #endif } void genbnel_idle(void) { #ifdef INTERPRET_BNEL_IDLE gencallinterp((native_type)cached_interpreter_table.BNEL_IDLE, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BNEL_IDLE, 1); return; } genbne_test(); gentest_idle(); genbnel(); #endif } void genblezl(void) { #ifdef INTERPRET_BLEZL gencallinterp((native_type)cached_interpreter_table.BLEZL, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BLEZL, 1); return; } genblez_test(); free_all_registers(); gentestl(); #endif } void genblezl_out(void) { #ifdef INTERPRET_BLEZL_OUT gencallinterp((native_type)cached_interpreter_table.BLEZL_OUT, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BLEZL_OUT, 1); return; } genblez_test(); free_all_registers(); gentestl_out(); #endif } void genblezl_idle(void) { #ifdef INTERPRET_BLEZL_IDLE gencallinterp((native_type)cached_interpreter_table.BLEZL_IDLE, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BLEZL_IDLE, 1); return; } genblez_test(); gentest_idle(); genblezl(); #endif } void genbgtzl(void) { #ifdef INTERPRET_BGTZL gencallinterp((native_type)cached_interpreter_table.BGTZL, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BGTZL, 1); return; } genbgtz_test(); free_all_registers(); gentestl(); #endif } void genbgtzl_out(void) { #ifdef INTERPRET_BGTZL_OUT gencallinterp((native_type)cached_interpreter_table.BGTZL_OUT, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BGTZL_OUT, 1); return; } genbgtz_test(); free_all_registers(); gentestl_out(); #endif } void genbgtzl_idle(void) { #ifdef INTERPRET_BGTZL_IDLE gencallinterp((native_type)cached_interpreter_table.BGTZL_IDLE, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BGTZL_IDLE, 1); return; } genbgtz_test(); gentest_idle(); genbgtzl(); #endif } void gendaddi(void) { #ifdef INTERPRET_DADDI gencallinterp((native_type)cached_interpreter_table.DADDI, 0); #else #ifdef __x86_64__ int rs = allocate_register_64((uint64_t *)dst->f.i.rs); int rt = allocate_register_64_w((uint64_t *)dst->f.i.rt); mov_reg64_reg64(rt, rs); add_reg64_imm32(rt, (int) dst->f.i.immediate); #else int rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs); int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs); int rt1 = allocate_64_register1_w((unsigned int *)dst->f.i.rt); int rt2 = allocate_64_register2_w((unsigned int *)dst->f.i.rt); mov_reg32_reg32(rt1, rs1); mov_reg32_reg32(rt2, rs2); add_reg32_imm32(rt1, dst->f.i.immediate); adc_reg32_imm32(rt2, (int)dst->f.i.immediate>>31); #endif #endif } void gendaddiu(void) { #ifdef INTERPRET_DADDIU gencallinterp((native_type)cached_interpreter_table.DADDIU, 0); #else #ifdef __x86_64__ int rs = allocate_register_64((uint64_t *)dst->f.i.rs); int rt = allocate_register_64_w((uint64_t *)dst->f.i.rt); mov_reg64_reg64(rt, rs); add_reg64_imm32(rt, (int) dst->f.i.immediate); #else int rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs); int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs); int rt1 = allocate_64_register1_w((unsigned int *)dst->f.i.rt); int rt2 = allocate_64_register2_w((unsigned int *)dst->f.i.rt); mov_reg32_reg32(rt1, rs1); mov_reg32_reg32(rt2, rs2); add_reg32_imm32(rt1, dst->f.i.immediate); adc_reg32_imm32(rt2, (int)dst->f.i.immediate>>31); #endif #endif } void gencache(void) { } void genldl(void) { #ifdef INTERPRET_LD gencallinterp((unsigned int)cached_interpreter_table.LD, 0); #else #ifdef __x86_64__ gencallinterp((native_type)cached_interpreter_table.LDL, 0); #else free_all_registers(); simplify_access(); mov_eax_memoffs32((unsigned int *)dst->f.i.rs); add_eax_imm32((int)dst->f.i.immediate); mov_reg32_reg32(EBX, EAX); if(fast_memory) { and_eax_imm32(0xDF800000); cmp_eax_imm32(0x80000000); } else { shr_reg32_imm8(EAX, 16); mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)readmemd); cmp_reg32_imm32(EAX, (unsigned int)read_rdramd); } je_rj(51); mov_m32_imm32((unsigned int *)(&PC), (unsigned int)(dst+1)); // 10 mov_m32_reg32((unsigned int *)(&address), EBX); // 6 mov_m32_imm32((unsigned int *)(&rdword), (unsigned int)dst->f.i.rt); // 10 shr_reg32_imm8(EBX, 16); // 3 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)readmemd); // 7 call_reg32(EBX); // 2 mov_eax_memoffs32((unsigned int *)(dst->f.i.rt)); // 5 mov_reg32_m32(ECX, (unsigned int *)(dst->f.i.rt)+1); // 6 jmp_imm_short(18); // 2 and_reg32_imm32(EBX, 0x7FFFFF); // 6 mov_reg32_preg32pimm32(EAX, EBX, ((unsigned int)g_rdram)+4); // 6 mov_reg32_preg32pimm32(ECX, EBX, ((unsigned int)g_rdram)); // 6 set_64_register_state(EAX, ECX, (unsigned int*)dst->f.i.rt, 1); #endif #endif } void genldr(void) { gencallinterp((native_type)cached_interpreter_table.LDR, 0); } void genlb(void) { #ifdef INTERPRET_LB gencallinterp((native_type)cached_interpreter_table.LB, 0); #else #ifdef __x86_64__ int gpr1, gpr2, base1, base2 = 0; free_registers_move_start(); ld_register_alloc(&gpr1, &gpr2, &base1, &base2); mov_reg64_imm64(base1, (uint64_t) readmemb); if(fast_memory) { and_reg32_imm32(gpr1, 0xDF800000); cmp_reg32_imm32(gpr1, 0x80000000); } else { mov_reg64_imm64(base2, (uint64_t) read_rdramb); shr_reg32_imm8(gpr1, 16); mov_reg64_preg64x8preg64(gpr1, gpr1, base1); cmp_reg64_reg64(gpr1, base2); } je_rj(0); jump_start_rel8(); mov_reg64_imm64(gpr1, (uint64_t) (dst+1)); mov_m64rel_xreg64((uint64_t *)(&PC), gpr1); mov_m32rel_xreg32((unsigned int *)(&address), gpr2); mov_reg64_imm64(gpr1, (uint64_t) dst->f.i.rt); mov_m64rel_xreg64((uint64_t *)(&rdword), gpr1); shr_reg32_imm8(gpr2, 16); mov_reg64_preg64x8preg64(gpr2, gpr2, base1); call_reg64(gpr2); movsx_xreg32_m8rel(gpr1, (unsigned char *)dst->f.i.rt); jmp_imm_short(24); jump_end_rel8(); mov_reg64_imm64(base1, (uint64_t) g_rdram); // 10 and_reg32_imm32(gpr2, 0x7FFFFF); // 6 xor_reg8_imm8(gpr2, 3); // 4 movsx_reg32_8preg64preg64(gpr1, gpr2, base1); // 4 set_register_state(gpr1, (unsigned int*)dst->f.i.rt, 1, 0); #else free_all_registers(); simplify_access(); mov_eax_memoffs32((unsigned int *)dst->f.i.rs); add_eax_imm32((int)dst->f.i.immediate); mov_reg32_reg32(EBX, EAX); if(fast_memory) { and_eax_imm32(0xDF800000); cmp_eax_imm32(0x80000000); } else { shr_reg32_imm8(EAX, 16); mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)readmemb); cmp_reg32_imm32(EAX, (unsigned int)read_rdramb); } je_rj(47); mov_m32_imm32((unsigned int *)&PC, (unsigned int)(dst+1)); // 10 mov_m32_reg32((unsigned int *)(&address), EBX); // 6 mov_m32_imm32((unsigned int *)(&rdword), (unsigned int)dst->f.i.rt); // 10 shr_reg32_imm8(EBX, 16); // 3 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)readmemb); // 7 call_reg32(EBX); // 2 movsx_reg32_m8(EAX, (unsigned char *)dst->f.i.rt); // 7 jmp_imm_short(16); // 2 and_reg32_imm32(EBX, 0x7FFFFF); // 6 xor_reg8_imm8(BL, 3); // 3 movsx_reg32_8preg32pimm32(EAX, EBX, (unsigned int)g_rdram); // 7 set_register_state(EAX, (unsigned int*)dst->f.i.rt, 1, 0); #endif #endif } void genlh(void) { #ifdef INTERPRET_LH gencallinterp((native_type)cached_interpreter_table.LH, 0); #else #ifdef __x86_64__ int gpr1, gpr2, base1, base2 = 0; free_registers_move_start(); ld_register_alloc(&gpr1, &gpr2, &base1, &base2); mov_reg64_imm64(base1, (uint64_t) readmemh); if(fast_memory) { and_reg32_imm32(gpr1, 0xDF800000); cmp_reg32_imm32(gpr1, 0x80000000); } else { mov_reg64_imm64(base2, (uint64_t) read_rdramh); shr_reg32_imm8(gpr1, 16); mov_reg64_preg64x8preg64(gpr1, gpr1, base1); cmp_reg64_reg64(gpr1, base2); } je_rj(0); jump_start_rel8(); mov_reg64_imm64(gpr1, (uint64_t) (dst+1)); mov_m64rel_xreg64((uint64_t *)(&PC), gpr1); mov_m32rel_xreg32((unsigned int *)(&address), gpr2); mov_reg64_imm64(gpr1, (uint64_t) dst->f.i.rt); mov_m64rel_xreg64((uint64_t *)(&rdword), gpr1); shr_reg32_imm8(gpr2, 16); mov_reg64_preg64x8preg64(gpr2, gpr2, base1); call_reg64(gpr2); movsx_xreg32_m16rel(gpr1, (unsigned short *)dst->f.i.rt); jmp_imm_short(24); jump_end_rel8(); mov_reg64_imm64(base1, (uint64_t) g_rdram); // 10 and_reg32_imm32(gpr2, 0x7FFFFF); // 6 xor_reg8_imm8(gpr2, 2); // 4 movsx_reg32_16preg64preg64(gpr1, gpr2, base1); // 4 set_register_state(gpr1, (unsigned int*)dst->f.i.rt, 1, 0); #else free_all_registers(); simplify_access(); mov_eax_memoffs32((unsigned int *)dst->f.i.rs); add_eax_imm32((int)dst->f.i.immediate); mov_reg32_reg32(EBX, EAX); if(fast_memory) { and_eax_imm32(0xDF800000); cmp_eax_imm32(0x80000000); } else { shr_reg32_imm8(EAX, 16); mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)readmemh); cmp_reg32_imm32(EAX, (unsigned int)read_rdramh); } je_rj(47); mov_m32_imm32((unsigned int *)&PC, (unsigned int)(dst+1)); // 10 mov_m32_reg32((unsigned int *)(&address), EBX); // 6 mov_m32_imm32((unsigned int *)(&rdword), (unsigned int)dst->f.i.rt); // 10 shr_reg32_imm8(EBX, 16); // 3 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)readmemh); // 7 call_reg32(EBX); // 2 movsx_reg32_m16(EAX, (unsigned short *)dst->f.i.rt); // 7 jmp_imm_short(16); // 2 and_reg32_imm32(EBX, 0x7FFFFF); // 6 xor_reg8_imm8(BL, 2); // 3 movsx_reg32_16preg32pimm32(EAX, EBX, (unsigned int)g_rdram); // 7 set_register_state(EAX, (unsigned int*)dst->f.i.rt, 1, 0); #endif #endif } void genlwl(void) { gencallinterp((native_type)cached_interpreter_table.LWL, 0); } void genlw(void) { #ifdef INTERPRET_LW gencallinterp((native_type)cached_interpreter_table.LW, 0); #else #ifdef __x86_64__ int gpr1, gpr2, base1, base2 = 0; free_registers_move_start(); ld_register_alloc(&gpr1, &gpr2, &base1, &base2); mov_reg64_imm64(base1, (uint64_t) readmem); if(fast_memory) { and_reg32_imm32(gpr1, 0xDF800000); cmp_reg32_imm32(gpr1, 0x80000000); } else { mov_reg64_imm64(base2, (uint64_t) read_rdram); shr_reg32_imm8(gpr1, 16); mov_reg64_preg64x8preg64(gpr1, gpr1, base1); cmp_reg64_reg64(gpr1, base2); } jne_rj(21); mov_reg64_imm64(base1, (uint64_t) g_rdram); // 10 and_reg32_imm32(gpr2, 0x7FFFFF); // 6 mov_reg32_preg64preg64(gpr1, gpr2, base1); // 3 jmp_imm_short(0); // 2 jump_start_rel8(); mov_reg64_imm64(gpr1, (uint64_t) (dst+1)); mov_m64rel_xreg64((uint64_t *)(&PC), gpr1); mov_m32rel_xreg32((unsigned int *)(&address), gpr2); mov_reg64_imm64(gpr1, (uint64_t) dst->f.i.rt); mov_m64rel_xreg64((uint64_t *)(&rdword), gpr1); shr_reg32_imm8(gpr2, 16); mov_reg64_preg64x8preg64(gpr1, gpr2, base1); call_reg64(gpr1); mov_xreg32_m32rel(gpr1, (unsigned int *)(dst->f.i.rt)); jump_end_rel8(); set_register_state(gpr1, (unsigned int*)dst->f.i.rt, 1, 0); // set gpr1 state as dirty, and bound to r4300 reg RT #else free_all_registers(); simplify_access(); mov_eax_memoffs32((unsigned int *)dst->f.i.rs); add_eax_imm32((int)dst->f.i.immediate); mov_reg32_reg32(EBX, EAX); if(fast_memory) { and_eax_imm32(0xDF800000); cmp_eax_imm32(0x80000000); } else { shr_reg32_imm8(EAX, 16); mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)readmem); cmp_reg32_imm32(EAX, (unsigned int)read_rdram); } je_rj(45); mov_m32_imm32((unsigned int *)&PC, (unsigned int)(dst+1)); // 10 mov_m32_reg32((unsigned int *)(&address), EBX); // 6 mov_m32_imm32((unsigned int *)(&rdword), (unsigned int)dst->f.i.rt); // 10 shr_reg32_imm8(EBX, 16); // 3 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)readmem); // 7 call_reg32(EBX); // 2 mov_eax_memoffs32((unsigned int *)(dst->f.i.rt)); // 5 jmp_imm_short(12); // 2 and_reg32_imm32(EBX, 0x7FFFFF); // 6 mov_reg32_preg32pimm32(EAX, EBX, (unsigned int)g_rdram); // 6 set_register_state(EAX, (unsigned int*)dst->f.i.rt, 1, 0); #endif #endif } void genlbu(void) { #ifdef INTERPRET_LBU gencallinterp((native_type)cached_interpreter_table.LBU, 0); #else #ifdef __x86_64__ int gpr1, gpr2, base1, base2 = 0; free_registers_move_start(); ld_register_alloc(&gpr1, &gpr2, &base1, &base2); mov_reg64_imm64(base1, (uint64_t) readmemb); if(fast_memory) { and_reg32_imm32(gpr1, 0xDF800000); cmp_reg32_imm32(gpr1, 0x80000000); } else { mov_reg64_imm64(base2, (uint64_t) read_rdramb); shr_reg32_imm8(gpr1, 16); mov_reg64_preg64x8preg64(gpr1, gpr1, base1); cmp_reg64_reg64(gpr1, base2); } je_rj(0); jump_start_rel8(); mov_reg64_imm64(gpr1, (uint64_t) (dst+1)); mov_m64rel_xreg64((uint64_t *)(&PC), gpr1); mov_m32rel_xreg32((unsigned int *)(&address), gpr2); mov_reg64_imm64(gpr1, (uint64_t) dst->f.i.rt); mov_m64rel_xreg64((uint64_t *)(&rdword), gpr1); shr_reg32_imm8(gpr2, 16); mov_reg64_preg64x8preg64(gpr2, gpr2, base1); call_reg64(gpr2); mov_xreg32_m32rel(gpr1, (unsigned int *)dst->f.i.rt); jmp_imm_short(23); jump_end_rel8(); mov_reg64_imm64(base1, (uint64_t) g_rdram); // 10 and_reg32_imm32(gpr2, 0x7FFFFF); // 6 xor_reg8_imm8(gpr2, 3); // 4 mov_reg32_preg64preg64(gpr1, gpr2, base1); // 3 and_reg32_imm32(gpr1, 0xFF); set_register_state(gpr1, (unsigned int*)dst->f.i.rt, 1, 0); #else free_all_registers(); simplify_access(); mov_eax_memoffs32((unsigned int *)dst->f.i.rs); add_eax_imm32((int)dst->f.i.immediate); mov_reg32_reg32(EBX, EAX); if(fast_memory) { and_eax_imm32(0xDF800000); cmp_eax_imm32(0x80000000); } else { shr_reg32_imm8(EAX, 16); mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)readmemb); cmp_reg32_imm32(EAX, (unsigned int)read_rdramb); } je_rj(46); mov_m32_imm32((unsigned int *)&PC, (unsigned int)(dst+1)); // 10 mov_m32_reg32((unsigned int *)(&address), EBX); // 6 mov_m32_imm32((unsigned int *)(&rdword), (unsigned int)dst->f.i.rt); // 10 shr_reg32_imm8(EBX, 16); // 3 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)readmemb); // 7 call_reg32(EBX); // 2 mov_reg32_m32(EAX, (unsigned int *)dst->f.i.rt); // 6 jmp_imm_short(15); // 2 and_reg32_imm32(EBX, 0x7FFFFF); // 6 xor_reg8_imm8(BL, 3); // 3 mov_reg32_preg32pimm32(EAX, EBX, (unsigned int)g_rdram); // 6 and_eax_imm32(0xFF); set_register_state(EAX, (unsigned int*)dst->f.i.rt, 1, 0); #endif #endif } void genlhu(void) { #ifdef INTERPRET_LHU gencallinterp((native_type)cached_interpreter_table.LHU, 0); #else #ifdef __x86_64__ int gpr1, gpr2, base1, base2 = 0; free_registers_move_start(); ld_register_alloc(&gpr1, &gpr2, &base1, &base2); mov_reg64_imm64(base1, (uint64_t) readmemh); if(fast_memory) { and_reg32_imm32(gpr1, 0xDF800000); cmp_reg32_imm32(gpr1, 0x80000000); } else { mov_reg64_imm64(base2, (uint64_t) read_rdramh); shr_reg32_imm8(gpr1, 16); mov_reg64_preg64x8preg64(gpr1, gpr1, base1); cmp_reg64_reg64(gpr1, base2); } je_rj(0); jump_start_rel8(); mov_reg64_imm64(gpr1, (uint64_t) (dst+1)); mov_m64rel_xreg64((uint64_t *)(&PC), gpr1); mov_m32rel_xreg32((unsigned int *)(&address), gpr2); mov_reg64_imm64(gpr1, (uint64_t) dst->f.i.rt); mov_m64rel_xreg64((uint64_t *)(&rdword), gpr1); shr_reg32_imm8(gpr2, 16); mov_reg64_preg64x8preg64(gpr2, gpr2, base1); call_reg64(gpr2); mov_xreg32_m32rel(gpr1, (unsigned int *)dst->f.i.rt); jmp_imm_short(23); jump_end_rel8(); mov_reg64_imm64(base1, (uint64_t) g_rdram); // 10 and_reg32_imm32(gpr2, 0x7FFFFF); // 6 xor_reg8_imm8(gpr2, 2); // 4 mov_reg32_preg64preg64(gpr1, gpr2, base1); // 3 and_reg32_imm32(gpr1, 0xFFFF); set_register_state(gpr1, (unsigned int*)dst->f.i.rt, 1, 0); #else free_all_registers(); simplify_access(); mov_eax_memoffs32((unsigned int *)dst->f.i.rs); add_eax_imm32((int)dst->f.i.immediate); mov_reg32_reg32(EBX, EAX); if(fast_memory) { and_eax_imm32(0xDF800000); cmp_eax_imm32(0x80000000); } else { shr_reg32_imm8(EAX, 16); mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)readmemh); cmp_reg32_imm32(EAX, (unsigned int)read_rdramh); } je_rj(46); mov_m32_imm32((unsigned int *)&PC, (unsigned int)(dst+1)); // 10 mov_m32_reg32((unsigned int *)(&address), EBX); // 6 mov_m32_imm32((unsigned int *)(&rdword), (unsigned int)dst->f.i.rt); // 10 shr_reg32_imm8(EBX, 16); // 3 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)readmemh); // 7 call_reg32(EBX); // 2 mov_reg32_m32(EAX, (unsigned int *)dst->f.i.rt); // 6 jmp_imm_short(15); // 2 and_reg32_imm32(EBX, 0x7FFFFF); // 6 xor_reg8_imm8(BL, 2); // 3 mov_reg32_preg32pimm32(EAX, EBX, (unsigned int)g_rdram); // 6 and_eax_imm32(0xFFFF); set_register_state(EAX, (unsigned int*)dst->f.i.rt, 1, 0); #endif #endif } void genlwr(void) { gencallinterp((native_type)cached_interpreter_table.LWR, 0); } void genlwu(void) { #ifdef INTERPRET_LWU gencallinterp((native_type)cached_interpreter_table.LWU, 0); #else #ifdef __x86_64__ int gpr1, gpr2, base1, base2 = 0; free_registers_move_start(); ld_register_alloc(&gpr1, &gpr2, &base1, &base2); mov_reg64_imm64(base1, (uint64_t) readmem); if(fast_memory) { and_reg32_imm32(gpr1, 0xDF800000); cmp_reg32_imm32(gpr1, 0x80000000); } else { mov_reg64_imm64(base2, (uint64_t) read_rdram); shr_reg32_imm8(gpr1, 16); mov_reg64_preg64x8preg64(gpr1, gpr1, base1); cmp_reg64_reg64(gpr1, base2); } je_rj(0); jump_start_rel8(); mov_reg64_imm64(gpr1, (uint64_t) (dst+1)); mov_m64rel_xreg64((uint64_t *)(&PC), gpr1); mov_m32rel_xreg32((unsigned int *)(&address), gpr2); mov_reg64_imm64(gpr1, (uint64_t) dst->f.i.rt); mov_m64rel_xreg64((uint64_t *)(&rdword), gpr1); shr_reg32_imm8(gpr2, 16); mov_reg64_preg64x8preg64(gpr2, gpr2, base1); call_reg64(gpr2); mov_xreg32_m32rel(gpr1, (unsigned int *)dst->f.i.rt); jmp_imm_short(19); jump_end_rel8(); mov_reg64_imm64(base1, (uint64_t) g_rdram); // 10 and_reg32_imm32(gpr2, 0x7FFFFF); // 6 mov_reg32_preg64preg64(gpr1, gpr2, base1); // 3 set_register_state(gpr1, (unsigned int*)dst->f.i.rt, 1, 1); #else free_all_registers(); simplify_access(); mov_eax_memoffs32((unsigned int *)dst->f.i.rs); add_eax_imm32((int)dst->f.i.immediate); mov_reg32_reg32(EBX, EAX); if(fast_memory) { and_eax_imm32(0xDF800000); cmp_eax_imm32(0x80000000); } else { shr_reg32_imm8(EAX, 16); mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)readmem); cmp_reg32_imm32(EAX, (unsigned int)read_rdram); } je_rj(45); mov_m32_imm32((unsigned int *)(&PC), (unsigned int)(dst+1)); // 10 mov_m32_reg32((unsigned int *)(&address), EBX); // 6 mov_m32_imm32((unsigned int *)(&rdword), (unsigned int)dst->f.i.rt); // 10 shr_reg32_imm8(EBX, 16); // 3 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)readmem); // 7 call_reg32(EBX); // 2 mov_eax_memoffs32((unsigned int *)(dst->f.i.rt)); // 5 jmp_imm_short(12); // 2 and_reg32_imm32(EBX, 0x7FFFFF); // 6 mov_reg32_preg32pimm32(EAX, EBX, (unsigned int)g_rdram); // 6 xor_reg32_reg32(EBX, EBX); set_64_register_state(EAX, EBX, (unsigned int*)dst->f.i.rt, 1); #endif #endif } void gensb(void) { #ifdef INTERPRET_SB gencallinterp((native_type)cached_interpreter_table.SB, 0); #else #ifdef __x86_64__ free_registers_move_start(); mov_xreg8_m8rel(CL, (unsigned char *)dst->f.i.rt); mov_xreg32_m32rel(EAX, (unsigned int *)dst->f.i.rs); add_eax_imm32((int)dst->f.i.immediate); mov_reg32_reg32(EBX, EAX); mov_reg64_imm64(RSI, (uint64_t) writememb); if(fast_memory) { and_eax_imm32(0xDF800000); cmp_eax_imm32(0x80000000); } else { mov_reg64_imm64(RDI, (uint64_t) write_rdramb); shr_reg32_imm8(EAX, 16); mov_reg64_preg64x8preg64(RAX, RAX, RSI); cmp_reg64_reg64(RAX, RDI); } je_rj(49); mov_reg64_imm64(RAX, (uint64_t) (dst+1)); // 10 mov_m64rel_xreg64((uint64_t *)(&PC), RAX); // 7 mov_m32rel_xreg32((unsigned int *)(&address), EBX); // 7 mov_m8rel_xreg8((unsigned char *)(&cpu_byte), CL); // 7 shr_reg32_imm8(EBX, 16); // 3 mov_reg64_preg64x8preg64(RBX, RBX, RSI); // 4 call_reg64(RBX); // 2 mov_xreg32_m32rel(EAX, (unsigned int *)(&address)); // 7 jmp_imm_short(25); // 2 mov_reg64_imm64(RSI, (uint64_t) g_rdram); // 10 mov_reg32_reg32(EAX, EBX); // 2 and_reg32_imm32(EBX, 0x7FFFFF); // 6 xor_reg8_imm8(BL, 3); // 4 mov_preg64preg64_reg8(RBX, RSI, CL); // 3 mov_reg64_imm64(RSI, (uint64_t) invalid_code); mov_reg32_reg32(EBX, EAX); shr_reg32_imm8(EBX, 12); cmp_preg64preg64_imm8(RBX, RSI, 0); jne_rj(65); mov_reg64_imm64(RDI, (uint64_t) blocks); // 10 mov_reg32_reg32(ECX, EBX); // 2 mov_reg64_preg64x8preg64(RBX, RBX, RDI); // 4 mov_reg64_preg64pimm32(RBX, RBX, (int) offsetof(precomp_block, block)); // 7 mov_reg64_imm64(RDI, (uint64_t) cached_interpreter_table.NOTCOMPILED); // 10 and_eax_imm32(0xFFF); // 5 shr_reg32_imm8(EAX, 2); // 3 mov_reg32_imm32(EDX, sizeof(precomp_instr)); // 5 mul_reg32(EDX); // 2 mov_reg64_preg64preg64pimm32(RAX, RAX, RBX, (int) offsetof(precomp_instr, ops)); // 8 cmp_reg64_reg64(RAX, RDI); // 3 je_rj(4); // 2 mov_preg64preg64_imm8(RCX, RSI, 1); // 4 #else free_all_registers(); simplify_access(); mov_reg8_m8(CL, (unsigned char *)dst->f.i.rt); mov_eax_memoffs32((unsigned int *)dst->f.i.rs); add_eax_imm32((int)dst->f.i.immediate); mov_reg32_reg32(EBX, EAX); if(fast_memory) { and_eax_imm32(0xDF800000); cmp_eax_imm32(0x80000000); } else { shr_reg32_imm8(EAX, 16); mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)writememb); cmp_reg32_imm32(EAX, (unsigned int)write_rdramb); } je_rj(41); mov_m32_imm32((unsigned int *)(&PC), (unsigned int)(dst+1)); // 10 mov_m32_reg32((unsigned int *)(&address), EBX); // 6 mov_m8_reg8((unsigned char *)(&cpu_byte), CL); // 6 shr_reg32_imm8(EBX, 16); // 3 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)writememb); // 7 call_reg32(EBX); // 2 mov_eax_memoffs32((unsigned int *)(&address)); // 5 jmp_imm_short(17); // 2 mov_reg32_reg32(EAX, EBX); // 2 and_reg32_imm32(EBX, 0x7FFFFF); // 6 xor_reg8_imm8(BL, 3); // 3 mov_preg32pimm32_reg8(EBX, (unsigned int)g_rdram, CL); // 6 mov_reg32_reg32(EBX, EAX); shr_reg32_imm8(EBX, 12); cmp_preg32pimm32_imm8(EBX, (unsigned int)invalid_code, 0); jne_rj(54); mov_reg32_reg32(ECX, EBX); // 2 shl_reg32_imm8(EBX, 2); // 3 mov_reg32_preg32pimm32(EBX, EBX, (unsigned int)blocks); // 6 mov_reg32_preg32pimm32(EBX, EBX, (int)&actual->block - (int)actual); // 6 and_eax_imm32(0xFFF); // 5 shr_reg32_imm8(EAX, 2); // 3 mov_reg32_imm32(EDX, sizeof(precomp_instr)); // 5 mul_reg32(EDX); // 2 mov_reg32_preg32preg32pimm32(EAX, EAX, EBX, (int)&dst->ops - (int)dst); // 7 cmp_reg32_imm32(EAX, (unsigned int)cached_interpreter_table.NOTCOMPILED); // 6 je_rj(7); // 2 mov_preg32pimm32_imm8(ECX, (unsigned int)invalid_code, 1); // 7 #endif #endif } void gensh(void) { #ifdef INTERPRET_SH gencallinterp((native_type)cached_interpreter_table.SH, 0); #else #if defined(__x86_64__) free_registers_move_start(); mov_xreg16_m16rel(CX, (unsigned short *)dst->f.i.rt); mov_xreg32_m32rel(EAX, (unsigned int *)dst->f.i.rs); add_eax_imm32((int)dst->f.i.immediate); mov_reg32_reg32(EBX, EAX); mov_reg64_imm64(RSI, (uint64_t) writememh); if(fast_memory) { and_eax_imm32(0xDF800000); cmp_eax_imm32(0x80000000); } else { mov_reg64_imm64(RDI, (uint64_t) write_rdramh); shr_reg32_imm8(EAX, 16); mov_reg64_preg64x8preg64(RAX, RAX, RSI); cmp_reg64_reg64(RAX, RDI); } je_rj(50); mov_reg64_imm64(RAX, (uint64_t) (dst+1)); // 10 mov_m64rel_xreg64((uint64_t *)(&PC), RAX); // 7 mov_m32rel_xreg32((unsigned int *)(&address), EBX); // 7 mov_m16rel_xreg16((unsigned short *)(&hword), CX); // 8 shr_reg32_imm8(EBX, 16); // 3 mov_reg64_preg64x8preg64(RBX, RBX, RSI); // 4 call_reg64(RBX); // 2 mov_xreg32_m32rel(EAX, (unsigned int *)(&address)); // 7 jmp_imm_short(26); // 2 mov_reg64_imm64(RSI, (uint64_t) g_rdram); // 10 mov_reg32_reg32(EAX, EBX); // 2 and_reg32_imm32(EBX, 0x7FFFFF); // 6 xor_reg8_imm8(BL, 2); // 4 mov_preg64preg64_reg16(RBX, RSI, CX); // 4 mov_reg64_imm64(RSI, (uint64_t) invalid_code); mov_reg32_reg32(EBX, EAX); shr_reg32_imm8(EBX, 12); cmp_preg64preg64_imm8(RBX, RSI, 0); jne_rj(65); mov_reg64_imm64(RDI, (uint64_t) blocks); // 10 mov_reg32_reg32(ECX, EBX); // 2 mov_reg64_preg64x8preg64(RBX, RBX, RDI); // 4 mov_reg64_preg64pimm32(RBX, RBX, (int) offsetof(precomp_block, block)); // 7 mov_reg64_imm64(RDI, (uint64_t) cached_interpreter_table.NOTCOMPILED); // 10 and_eax_imm32(0xFFF); // 5 shr_reg32_imm8(EAX, 2); // 3 mov_reg32_imm32(EDX, sizeof(precomp_instr)); // 5 mul_reg32(EDX); // 2 mov_reg64_preg64preg64pimm32(RAX, RAX, RBX, (int) offsetof(precomp_instr, ops)); // 8 cmp_reg64_reg64(RAX, RDI); // 3 je_rj(4); // 2 mov_preg64preg64_imm8(RCX, RSI, 1); // 4 #else free_all_registers(); simplify_access(); mov_reg16_m16(CX, (unsigned short *)dst->f.i.rt); mov_eax_memoffs32((unsigned int *)dst->f.i.rs); add_eax_imm32((int)dst->f.i.immediate); mov_reg32_reg32(EBX, EAX); if(fast_memory) { and_eax_imm32(0xDF800000); cmp_eax_imm32(0x80000000); } else { shr_reg32_imm8(EAX, 16); mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)writememh); cmp_reg32_imm32(EAX, (unsigned int)write_rdramh); } je_rj(42); mov_m32_imm32((unsigned int *)(&PC), (unsigned int)(dst+1)); // 10 mov_m32_reg32((unsigned int *)(&address), EBX); // 6 mov_m16_reg16((unsigned short *)(&hword), CX); // 7 shr_reg32_imm8(EBX, 16); // 3 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)writememh); // 7 call_reg32(EBX); // 2 mov_eax_memoffs32((unsigned int *)(&address)); // 5 jmp_imm_short(18); // 2 mov_reg32_reg32(EAX, EBX); // 2 and_reg32_imm32(EBX, 0x7FFFFF); // 6 xor_reg8_imm8(BL, 2); // 3 mov_preg32pimm32_reg16(EBX, (unsigned int)g_rdram, CX); // 7 mov_reg32_reg32(EBX, EAX); shr_reg32_imm8(EBX, 12); cmp_preg32pimm32_imm8(EBX, (unsigned int)invalid_code, 0); jne_rj(54); mov_reg32_reg32(ECX, EBX); // 2 shl_reg32_imm8(EBX, 2); // 3 mov_reg32_preg32pimm32(EBX, EBX, (unsigned int)blocks); // 6 mov_reg32_preg32pimm32(EBX, EBX, (int)&actual->block - (int)actual); // 6 and_eax_imm32(0xFFF); // 5 shr_reg32_imm8(EAX, 2); // 3 mov_reg32_imm32(EDX, sizeof(precomp_instr)); // 5 mul_reg32(EDX); // 2 mov_reg32_preg32preg32pimm32(EAX, EAX, EBX, (int)&dst->ops - (int)dst); // 7 cmp_reg32_imm32(EAX, (unsigned int)cached_interpreter_table.NOTCOMPILED); // 6 je_rj(7); // 2 mov_preg32pimm32_imm8(ECX, (unsigned int)invalid_code, 1); // 7 #endif #endif } void genswl(void) { gencallinterp((native_type)cached_interpreter_table.SWL, 0); } void gensw(void) { #ifdef INTERPRET_SW gencallinterp((native_type)cached_interpreter_table.SW, 0); #else #ifdef __x86_64__ free_registers_move_start(); mov_xreg32_m32rel(ECX, (unsigned int *)dst->f.i.rt); mov_xreg32_m32rel(EAX, (unsigned int *)dst->f.i.rs); add_eax_imm32((int)dst->f.i.immediate); mov_reg32_reg32(EBX, EAX); mov_reg64_imm64(RSI, (uint64_t) writemem); if(fast_memory) { and_eax_imm32(0xDF800000); cmp_eax_imm32(0x80000000); } else { mov_reg64_imm64(RDI, (uint64_t) write_rdram); shr_reg32_imm8(EAX, 16); mov_reg64_preg64x8preg64(RAX, RAX, RSI); cmp_reg64_reg64(RAX, RDI); } je_rj(49); mov_reg64_imm64(RAX, (uint64_t) (dst+1)); // 10 mov_m64rel_xreg64((uint64_t *)(&PC), RAX); // 7 mov_m32rel_xreg32((unsigned int *)(&address), EBX); // 7 mov_m32rel_xreg32((unsigned int *)(&word), ECX); // 7 shr_reg32_imm8(EBX, 16); // 3 mov_reg64_preg64x8preg64(RBX, RBX, RSI); // 4 call_reg64(RBX); // 2 mov_xreg32_m32rel(EAX, (unsigned int *)(&address)); // 7 jmp_imm_short(21); // 2 mov_reg64_imm64(RSI, (uint64_t) g_rdram); // 10 mov_reg32_reg32(EAX, EBX); // 2 and_reg32_imm32(EBX, 0x7FFFFF); // 6 mov_preg64preg64_reg32(RBX, RSI, ECX); // 3 mov_reg64_imm64(RSI, (uint64_t) invalid_code); mov_reg32_reg32(EBX, EAX); shr_reg32_imm8(EBX, 12); cmp_preg64preg64_imm8(RBX, RSI, 0); jne_rj(65); mov_reg64_imm64(RDI, (uint64_t) blocks); // 10 mov_reg32_reg32(ECX, EBX); // 2 mov_reg64_preg64x8preg64(RBX, RBX, RDI); // 4 mov_reg64_preg64pimm32(RBX, RBX, (int) offsetof(precomp_block, block)); // 7 mov_reg64_imm64(RDI, (uint64_t) cached_interpreter_table.NOTCOMPILED); // 10 and_eax_imm32(0xFFF); // 5 shr_reg32_imm8(EAX, 2); // 3 mov_reg32_imm32(EDX, sizeof(precomp_instr)); // 5 mul_reg32(EDX); // 2 mov_reg64_preg64preg64pimm32(RAX, RAX, RBX, (int) offsetof(precomp_instr, ops)); // 8 cmp_reg64_reg64(RAX, RDI); // 3 je_rj(4); // 2 mov_preg64preg64_imm8(RCX, RSI, 1); // 4 #else free_all_registers(); simplify_access(); mov_reg32_m32(ECX, (unsigned int *)dst->f.i.rt); mov_eax_memoffs32((unsigned int *)dst->f.i.rs); add_eax_imm32((int)dst->f.i.immediate); mov_reg32_reg32(EBX, EAX); if(fast_memory) { and_eax_imm32(0xDF800000); cmp_eax_imm32(0x80000000); } else { shr_reg32_imm8(EAX, 16); mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)writemem); cmp_reg32_imm32(EAX, (unsigned int)write_rdram); } je_rj(41); mov_m32_imm32((unsigned int *)(&PC), (unsigned int)(dst+1)); // 10 mov_m32_reg32((unsigned int *)(&address), EBX); // 6 mov_m32_reg32((unsigned int *)(&word), ECX); // 6 shr_reg32_imm8(EBX, 16); // 3 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)writemem); // 7 call_reg32(EBX); // 2 mov_eax_memoffs32((unsigned int *)(&address)); // 5 jmp_imm_short(14); // 2 mov_reg32_reg32(EAX, EBX); // 2 and_reg32_imm32(EBX, 0x7FFFFF); // 6 mov_preg32pimm32_reg32(EBX, (unsigned int)g_rdram, ECX); // 6 mov_reg32_reg32(EBX, EAX); shr_reg32_imm8(EBX, 12); cmp_preg32pimm32_imm8(EBX, (unsigned int)invalid_code, 0); jne_rj(54); mov_reg32_reg32(ECX, EBX); // 2 shl_reg32_imm8(EBX, 2); // 3 mov_reg32_preg32pimm32(EBX, EBX, (unsigned int)blocks); // 6 mov_reg32_preg32pimm32(EBX, EBX, (int)&actual->block - (int)actual); // 6 and_eax_imm32(0xFFF); // 5 shr_reg32_imm8(EAX, 2); // 3 mov_reg32_imm32(EDX, sizeof(precomp_instr)); // 5 mul_reg32(EDX); // 2 mov_reg32_preg32preg32pimm32(EAX, EAX, EBX, (int)&dst->ops - (int)dst); // 7 cmp_reg32_imm32(EAX, (unsigned int)cached_interpreter_table.NOTCOMPILED); // 6 je_rj(7); // 2 mov_preg32pimm32_imm8(ECX, (unsigned int)invalid_code, 1); // 7 #endif #endif } void gensdl(void) { gencallinterp((native_type)cached_interpreter_table.SDL, 0); } void gensdr(void) { gencallinterp((native_type)cached_interpreter_table.SDR, 0); } void genswr(void) { gencallinterp((native_type)cached_interpreter_table.SWR, 0); } void gencheck_cop1_unusable(void) { #ifdef __x86_64__ free_registers_move_start(); test_m32rel_imm32((unsigned int*)&g_cp0_regs[CP0_STATUS_REG], 0x20000000); #else free_all_registers(); simplify_access(); test_m32_imm32((unsigned int*)&g_cp0_regs[CP0_STATUS_REG], 0x20000000); #endif jne_rj(0); jump_start_rel8(); gencallinterp((native_type)check_cop1_unusable, 0); jump_end_rel8(); } void genlwc1(void) { #ifdef INTERPRET_LWC1 gencallinterp((native_type)cached_interpreter_table.LWC1, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg32_m32rel(EAX, (unsigned int *)(®[dst->f.lf.base])); add_eax_imm32((int)dst->f.lf.offset); mov_reg32_reg32(EBX, EAX); mov_reg64_imm64(RSI, (uint64_t) readmem); if(fast_memory) { and_eax_imm32(0xDF800000); cmp_eax_imm32(0x80000000); } else { mov_reg64_imm64(RDI, (uint64_t) read_rdram); shr_reg32_imm8(EAX, 16); mov_reg64_preg64x8preg64(RAX, RAX, RSI); cmp_reg64_reg64(RAX, RDI); } je_rj(49); mov_reg64_imm64(RAX, (uint64_t) (dst+1)); // 10 mov_m64rel_xreg64((uint64_t *)(&PC), RAX); // 7 mov_m32rel_xreg32((unsigned int *)(&address), EBX); // 7 mov_xreg64_m64rel(RDX, (uint64_t *)(®_cop1_simple[dst->f.lf.ft])); // 7 mov_m64rel_xreg64((uint64_t *)(&rdword), RDX); // 7 shr_reg32_imm8(EBX, 16); // 3 mov_reg64_preg64x8preg64(RBX, RBX, RSI); // 4 call_reg64(RBX); // 2 jmp_imm_short(28); // 2 mov_reg64_imm64(RSI, (uint64_t) g_rdram); // 10 and_reg32_imm32(EBX, 0x7FFFFF); // 6 mov_reg32_preg64preg64(EAX, RBX, RSI); // 3 mov_xreg64_m64rel(RBX, (uint64_t *)(®_cop1_simple[dst->f.lf.ft])); // 7 mov_preg64_reg32(RBX, EAX); // 2 #else mov_eax_memoffs32((unsigned int *)(®[dst->f.lf.base])); add_eax_imm32((int)dst->f.lf.offset); mov_reg32_reg32(EBX, EAX); if(fast_memory) { and_eax_imm32(0xDF800000); cmp_eax_imm32(0x80000000); } else { shr_reg32_imm8(EAX, 16); mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)readmem); cmp_reg32_imm32(EAX, (unsigned int)read_rdram); } je_rj(42); mov_m32_imm32((unsigned int *)(&PC), (unsigned int)(dst+1)); // 10 mov_m32_reg32((unsigned int *)(&address), EBX); // 6 mov_reg32_m32(EDX, (unsigned int*)(®_cop1_simple[dst->f.lf.ft])); // 6 mov_m32_reg32((unsigned int *)(&rdword), EDX); // 6 shr_reg32_imm8(EBX, 16); // 3 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)readmem); // 7 call_reg32(EBX); // 2 jmp_imm_short(20); // 2 and_reg32_imm32(EBX, 0x7FFFFF); // 6 mov_reg32_preg32pimm32(EAX, EBX, (unsigned int)g_rdram); // 6 mov_reg32_m32(EBX, (unsigned int*)(®_cop1_simple[dst->f.lf.ft])); // 6 mov_preg32_reg32(EBX, EAX); // 2 #endif #endif } void genldc1(void) { #ifdef INTERPRET_LDC1 gencallinterp((native_type)cached_interpreter_table.LDC1, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg32_m32rel(EAX, (unsigned int *)(®[dst->f.lf.base])); add_eax_imm32((int)dst->f.lf.offset); mov_reg32_reg32(EBX, EAX); mov_reg64_imm64(RSI, (uint64_t) readmemd); if(fast_memory) { and_eax_imm32(0xDF800000); cmp_eax_imm32(0x80000000); } else { mov_reg64_imm64(RDI, (uint64_t) read_rdramd); shr_reg32_imm8(EAX, 16); mov_reg64_preg64x8preg64(RAX, RAX, RSI); cmp_reg64_reg64(RAX, RDI); } je_rj(49); mov_reg64_imm64(RAX, (uint64_t) (dst+1)); // 10 mov_m64rel_xreg64((uint64_t *)(&PC), RAX); // 7 mov_m32rel_xreg32((unsigned int *)(&address), EBX); // 7 mov_xreg64_m64rel(RDX, (uint64_t *)(®_cop1_double[dst->f.lf.ft])); // 7 mov_m64rel_xreg64((uint64_t *)(&rdword), RDX); // 7 shr_reg32_imm8(EBX, 16); // 3 mov_reg64_preg64x8preg64(RBX, RBX, RSI); // 4 call_reg64(RBX); // 2 jmp_imm_short(39); // 2 mov_reg64_imm64(RSI, (uint64_t) g_rdram); // 10 and_reg32_imm32(EBX, 0x7FFFFF); // 6 mov_reg64_preg64preg64(RAX, RBX, RSI); // 4 mov_xreg64_m64rel(RBX, (uint64_t *)(®_cop1_double[dst->f.lf.ft])); // 7 mov_preg64pimm32_reg32(RBX, 4, EAX); // 6 shr_reg64_imm8(RAX, 32); // 4 mov_preg64_reg32(RBX, EAX); // 2 #else mov_eax_memoffs32((unsigned int *)(®[dst->f.lf.base])); add_eax_imm32((int)dst->f.lf.offset); mov_reg32_reg32(EBX, EAX); if(fast_memory) { and_eax_imm32(0xDF800000); cmp_eax_imm32(0x80000000); } else { shr_reg32_imm8(EAX, 16); mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)readmemd); cmp_reg32_imm32(EAX, (unsigned int)read_rdramd); } je_rj(42); mov_m32_imm32((unsigned int *)(&PC), (unsigned int)(dst+1)); // 10 mov_m32_reg32((unsigned int *)(&address), EBX); // 6 mov_reg32_m32(EDX, (unsigned int*)(®_cop1_double[dst->f.lf.ft])); // 6 mov_m32_reg32((unsigned int *)(&rdword), EDX); // 6 shr_reg32_imm8(EBX, 16); // 3 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)readmemd); // 7 call_reg32(EBX); // 2 jmp_imm_short(32); // 2 and_reg32_imm32(EBX, 0x7FFFFF); // 6 mov_reg32_preg32pimm32(EAX, EBX, ((unsigned int)g_rdram)+4); // 6 mov_reg32_preg32pimm32(ECX, EBX, ((unsigned int)g_rdram)); // 6 mov_reg32_m32(EBX, (unsigned int*)(®_cop1_double[dst->f.lf.ft])); // 6 mov_preg32_reg32(EBX, EAX); // 2 mov_preg32pimm32_reg32(EBX, 4, ECX); // 6 #endif #endif } void genld(void) { #if defined(INTERPRET_LD) || !defined(__x86_64__) gencallinterp((native_type)cached_interpreter_table.LD, 0); #else free_registers_move_start(); mov_xreg32_m32rel(EAX, (unsigned int *)dst->f.i.rs); add_eax_imm32((int)dst->f.i.immediate); mov_reg32_reg32(EBX, EAX); mov_reg64_imm64(RSI, (uint64_t) readmemd); if(fast_memory) { and_eax_imm32(0xDF800000); cmp_eax_imm32(0x80000000); } else { mov_reg64_imm64(RDI, (uint64_t) read_rdramd); shr_reg32_imm8(EAX, 16); mov_reg64_preg64x8preg64(RAX, RAX, RSI); cmp_reg64_reg64(RAX, RDI); } je_rj(59); mov_reg64_imm64(RAX, (uint64_t) (dst+1)); // 10 mov_m64rel_xreg64((uint64_t *)(&PC), RAX); // 7 mov_m32rel_xreg32((unsigned int *)(&address), EBX); // 7 mov_reg64_imm64(RAX, (uint64_t) dst->f.i.rt); // 10 mov_m64rel_xreg64((uint64_t *)(&rdword), RAX); // 7 shr_reg32_imm8(EBX, 16); // 3 mov_reg64_preg64x8preg64(RBX, RBX, RSI); // 4 call_reg64(RBX); // 2 mov_xreg64_m64rel(RAX, (uint64_t *)(dst->f.i.rt)); // 7 jmp_imm_short(33); // 2 mov_reg64_imm64(RSI, (uint64_t) g_rdram); // 10 and_reg32_imm32(EBX, 0x7FFFFF); // 6 mov_reg32_preg64preg64(EAX, RBX, RSI); // 3 mov_reg32_preg64preg64pimm32(EBX, RBX, RSI, 4); // 7 shl_reg64_imm8(RAX, 32); // 4 or_reg64_reg64(RAX, RBX); // 3 set_register_state(RAX, (unsigned int*)dst->f.i.rt, 1, 1); #endif } void genswc1(void) { #ifdef INTERPRET_SWC1 gencallinterp((native_type)cached_interpreter_table.SWC1, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RDX, (uint64_t *)(®_cop1_simple[dst->f.lf.ft])); mov_reg32_preg64(ECX, RDX); mov_xreg32_m32rel(EAX, (unsigned int *)(®[dst->f.lf.base])); add_eax_imm32((int)dst->f.lf.offset); mov_reg32_reg32(EBX, EAX); mov_reg64_imm64(RSI, (uint64_t) writemem); if(fast_memory) { and_eax_imm32(0xDF800000); cmp_eax_imm32(0x80000000); } else { mov_reg64_imm64(RDI, (uint64_t) write_rdram); shr_reg32_imm8(EAX, 16); mov_reg64_preg64x8preg64(RAX, RAX, RSI); cmp_reg64_reg64(RAX, RDI); } je_rj(49); mov_reg64_imm64(RAX, (uint64_t) (dst+1)); // 10 mov_m64rel_xreg64((uint64_t *)(&PC), RAX); // 7 mov_m32rel_xreg32((unsigned int *)(&address), EBX); // 7 mov_m32rel_xreg32((unsigned int *)(&word), ECX); // 7 shr_reg32_imm8(EBX, 16); // 3 mov_reg64_preg64x8preg64(RBX, RBX, RSI); // 4 call_reg64(RBX); // 2 mov_xreg32_m32rel(EAX, (unsigned int *)(&address)); // 7 jmp_imm_short(21); // 2 mov_reg64_imm64(RSI, (uint64_t) g_rdram); // 10 mov_reg32_reg32(EAX, EBX); // 2 and_reg32_imm32(EBX, 0x7FFFFF); // 6 mov_preg64preg64_reg32(RBX, RSI, ECX); // 3 mov_reg64_imm64(RSI, (uint64_t) invalid_code); mov_reg32_reg32(EBX, EAX); shr_reg32_imm8(EBX, 12); cmp_preg64preg64_imm8(RBX, RSI, 0); jne_rj(65); mov_reg64_imm64(RDI, (uint64_t) blocks); // 10 mov_reg32_reg32(ECX, EBX); // 2 mov_reg64_preg64x8preg64(RBX, RBX, RDI); // 4 mov_reg64_preg64pimm32(RBX, RBX, (int) offsetof(precomp_block, block)); // 7 mov_reg64_imm64(RDI, (uint64_t) cached_interpreter_table.NOTCOMPILED); // 10 and_eax_imm32(0xFFF); // 5 shr_reg32_imm8(EAX, 2); // 3 mov_reg32_imm32(EDX, sizeof(precomp_instr)); // 5 mul_reg32(EDX); // 2 mov_reg64_preg64preg64pimm32(RAX, RAX, RBX, (int) offsetof(precomp_instr, ops)); // 8 cmp_reg64_reg64(RAX, RDI); // 3 je_rj(4); // 2 mov_preg64preg64_imm8(RCX, RSI, 1); // 4 #else mov_reg32_m32(EDX, (unsigned int*)(®_cop1_simple[dst->f.lf.ft])); mov_reg32_preg32(ECX, EDX); mov_eax_memoffs32((unsigned int *)(®[dst->f.lf.base])); add_eax_imm32((int)dst->f.lf.offset); mov_reg32_reg32(EBX, EAX); if(fast_memory) { and_eax_imm32(0xDF800000); cmp_eax_imm32(0x80000000); } else { shr_reg32_imm8(EAX, 16); mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)writemem); cmp_reg32_imm32(EAX, (unsigned int)write_rdram); } je_rj(41); mov_m32_imm32((unsigned int *)(&PC), (unsigned int)(dst+1)); // 10 mov_m32_reg32((unsigned int *)(&address), EBX); // 6 mov_m32_reg32((unsigned int *)(&word), ECX); // 6 shr_reg32_imm8(EBX, 16); // 3 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)writemem); // 7 call_reg32(EBX); // 2 mov_eax_memoffs32((unsigned int *)(&address)); // 5 jmp_imm_short(14); // 2 mov_reg32_reg32(EAX, EBX); // 2 and_reg32_imm32(EBX, 0x7FFFFF); // 6 mov_preg32pimm32_reg32(EBX, (unsigned int)g_rdram, ECX); // 6 mov_reg32_reg32(EBX, EAX); shr_reg32_imm8(EBX, 12); cmp_preg32pimm32_imm8(EBX, (unsigned int)invalid_code, 0); jne_rj(54); mov_reg32_reg32(ECX, EBX); // 2 shl_reg32_imm8(EBX, 2); // 3 mov_reg32_preg32pimm32(EBX, EBX, (unsigned int)blocks); // 6 mov_reg32_preg32pimm32(EBX, EBX, (int)&actual->block - (int)actual); // 6 and_eax_imm32(0xFFF); // 5 shr_reg32_imm8(EAX, 2); // 3 mov_reg32_imm32(EDX, sizeof(precomp_instr)); // 5 mul_reg32(EDX); // 2 mov_reg32_preg32preg32pimm32(EAX, EAX, EBX, (int)&dst->ops - (int)dst); // 7 cmp_reg32_imm32(EAX, (unsigned int)cached_interpreter_table.NOTCOMPILED); // 6 je_rj(7); // 2 mov_preg32pimm32_imm8(ECX, (unsigned int)invalid_code, 1); // 7 #endif #endif } void gensdc1(void) { #ifdef INTERPRET_SDC1 gencallinterp((native_type)cached_interpreter_table.SDC1, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RSI, (uint64_t *)(®_cop1_double[dst->f.lf.ft])); mov_reg32_preg64(ECX, RSI); mov_reg32_preg64pimm32(EDX, RSI, 4); mov_xreg32_m32rel(EAX, (unsigned int *)(®[dst->f.lf.base])); add_eax_imm32((int)dst->f.lf.offset); mov_reg32_reg32(EBX, EAX); mov_reg64_imm64(RSI, (uint64_t) writememd); if(fast_memory) { and_eax_imm32(0xDF800000); cmp_eax_imm32(0x80000000); } else { mov_reg64_imm64(RDI, (uint64_t) write_rdramd); shr_reg32_imm8(EAX, 16); mov_reg64_preg64x8preg64(RAX, RAX, RSI); cmp_reg64_reg64(RAX, RDI); } je_rj(56); mov_reg64_imm64(RAX, (uint64_t) (dst+1)); // 10 mov_m64rel_xreg64((uint64_t *)(&PC), RAX); // 7 mov_m32rel_xreg32((unsigned int *)(&address), EBX); // 7 mov_m32rel_xreg32((unsigned int *)(&dword), ECX); // 7 mov_m32rel_xreg32((unsigned int *)(&dword)+1, EDX); // 7 shr_reg32_imm8(EBX, 16); // 3 mov_reg64_preg64x8preg64(RBX, RBX, RSI); // 4 call_reg64(RBX); // 2 mov_xreg32_m32rel(EAX, (unsigned int *)(&address)); // 7 jmp_imm_short(28); // 2 mov_reg64_imm64(RSI, (uint64_t) g_rdram); // 10 mov_reg32_reg32(EAX, EBX); // 2 and_reg32_imm32(EBX, 0x7FFFFF); // 6 mov_preg64preg64pimm32_reg32(RBX, RSI, 4, ECX); // 7 mov_preg64preg64_reg32(RBX, RSI, EDX); // 3 mov_reg64_imm64(RSI, (uint64_t) invalid_code); mov_reg32_reg32(EBX, EAX); shr_reg32_imm8(EBX, 12); cmp_preg64preg64_imm8(RBX, RSI, 0); jne_rj(65); mov_reg64_imm64(RDI, (uint64_t) blocks); // 10 mov_reg32_reg32(ECX, EBX); // 2 mov_reg64_preg64x8preg64(RBX, RBX, RDI); // 4 mov_reg64_preg64pimm32(RBX, RBX, (int) offsetof(precomp_block, block)); // 7 mov_reg64_imm64(RDI, (uint64_t) cached_interpreter_table.NOTCOMPILED); // 10 and_eax_imm32(0xFFF); // 5 shr_reg32_imm8(EAX, 2); // 3 mov_reg32_imm32(EDX, sizeof(precomp_instr)); // 5 mul_reg32(EDX); // 2 mov_reg64_preg64preg64pimm32(RAX, RAX, RBX, (int) offsetof(precomp_instr, ops)); // 8 cmp_reg64_reg64(RAX, RDI); // 3 je_rj(4); // 2 mov_preg64preg64_imm8(RCX, RSI, 1); // 4 #else mov_reg32_m32(ESI, (unsigned int*)(®_cop1_double[dst->f.lf.ft])); mov_reg32_preg32(ECX, ESI); mov_reg32_preg32pimm32(EDX, ESI, 4); mov_eax_memoffs32((unsigned int *)(®[dst->f.lf.base])); add_eax_imm32((int)dst->f.lf.offset); mov_reg32_reg32(EBX, EAX); if(fast_memory) { and_eax_imm32(0xDF800000); cmp_eax_imm32(0x80000000); } else { shr_reg32_imm8(EAX, 16); mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)writememd); cmp_reg32_imm32(EAX, (unsigned int)write_rdramd); } je_rj(47); mov_m32_imm32((unsigned int *)(&PC), (unsigned int)(dst+1)); // 10 mov_m32_reg32((unsigned int *)(&address), EBX); // 6 mov_m32_reg32((unsigned int *)(&dword), ECX); // 6 mov_m32_reg32((unsigned int *)(&dword)+1, EDX); // 6 shr_reg32_imm8(EBX, 16); // 3 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)writememd); // 7 call_reg32(EBX); // 2 mov_eax_memoffs32((unsigned int *)(&address)); // 5 jmp_imm_short(20); // 2 mov_reg32_reg32(EAX, EBX); // 2 and_reg32_imm32(EBX, 0x7FFFFF); // 6 mov_preg32pimm32_reg32(EBX, ((unsigned int)g_rdram)+4, ECX); // 6 mov_preg32pimm32_reg32(EBX, ((unsigned int)g_rdram)+0, EDX); // 6 mov_reg32_reg32(EBX, EAX); shr_reg32_imm8(EBX, 12); cmp_preg32pimm32_imm8(EBX, (unsigned int)invalid_code, 0); jne_rj(54); mov_reg32_reg32(ECX, EBX); // 2 shl_reg32_imm8(EBX, 2); // 3 mov_reg32_preg32pimm32(EBX, EBX, (unsigned int)blocks); // 6 mov_reg32_preg32pimm32(EBX, EBX, (int)&actual->block - (int)actual); // 6 and_eax_imm32(0xFFF); // 5 shr_reg32_imm8(EAX, 2); // 3 mov_reg32_imm32(EDX, sizeof(precomp_instr)); // 5 mul_reg32(EDX); // 2 mov_reg32_preg32preg32pimm32(EAX, EAX, EBX, (int)&dst->ops - (int)dst); // 7 cmp_reg32_imm32(EAX, (unsigned int)cached_interpreter_table.NOTCOMPILED); // 6 je_rj(7); // 2 mov_preg32pimm32_imm8(ECX, (unsigned int)invalid_code, 1); // 7 #endif #endif } void gensd(void) { #ifdef INTERPRET_SD gencallinterp((native_type)cached_interpreter_table.SD, 0); #else #ifdef __x86_64__ free_registers_move_start(); mov_xreg32_m32rel(ECX, (unsigned int *)dst->f.i.rt); mov_xreg32_m32rel(EDX, ((unsigned int *)dst->f.i.rt)+1); mov_xreg32_m32rel(EAX, (unsigned int *)dst->f.i.rs); add_eax_imm32((int)dst->f.i.immediate); mov_reg32_reg32(EBX, EAX); mov_reg64_imm64(RSI, (uint64_t) writememd); if(fast_memory) { and_eax_imm32(0xDF800000); cmp_eax_imm32(0x80000000); } else { mov_reg64_imm64(RDI, (uint64_t) write_rdramd); shr_reg32_imm8(EAX, 16); mov_reg64_preg64x8preg64(RAX, RAX, RSI); cmp_reg64_reg64(RAX, RDI); } je_rj(56); mov_reg64_imm64(RAX, (uint64_t) (dst+1)); // 10 mov_m64rel_xreg64((uint64_t *)(&PC), RAX); // 7 mov_m32rel_xreg32((unsigned int *)(&address), EBX); // 7 mov_m32rel_xreg32((unsigned int *)(&dword), ECX); // 7 mov_m32rel_xreg32((unsigned int *)(&dword)+1, EDX); // 7 shr_reg32_imm8(EBX, 16); // 3 mov_reg64_preg64x8preg64(RBX, RBX, RSI); // 4 call_reg64(RBX); // 2 mov_xreg32_m32rel(EAX, (unsigned int *)(&address)); // 7 jmp_imm_short(28); // 2 mov_reg64_imm64(RSI, (uint64_t) g_rdram); // 10 mov_reg32_reg32(EAX, EBX); // 2 and_reg32_imm32(EBX, 0x7FFFFF); // 6 mov_preg64preg64pimm32_reg32(RBX, RSI, 4, ECX); // 7 mov_preg64preg64_reg32(RBX, RSI, EDX); // 3 mov_reg64_imm64(RSI, (uint64_t) invalid_code); mov_reg32_reg32(EBX, EAX); shr_reg32_imm8(EBX, 12); cmp_preg64preg64_imm8(RBX, RSI, 0); jne_rj(65); mov_reg64_imm64(RDI, (uint64_t) blocks); // 10 mov_reg32_reg32(ECX, EBX); // 2 mov_reg64_preg64x8preg64(RBX, RBX, RDI); // 4 mov_reg64_preg64pimm32(RBX, RBX, (int) offsetof(precomp_block, block)); // 7 mov_reg64_imm64(RDI, (uint64_t) cached_interpreter_table.NOTCOMPILED); // 10 and_eax_imm32(0xFFF); // 5 shr_reg32_imm8(EAX, 2); // 3 mov_reg32_imm32(EDX, sizeof(precomp_instr)); // 5 mul_reg32(EDX); // 2 mov_reg64_preg64preg64pimm32(RAX, RAX, RBX, (int) offsetof(precomp_instr, ops)); // 8 cmp_reg64_reg64(RAX, RDI); // 3 je_rj(4); // 2 mov_preg64preg64_imm8(RCX, RSI, 1); // 4 #else free_all_registers(); simplify_access(); mov_reg32_m32(ECX, (unsigned int *)dst->f.i.rt); mov_reg32_m32(EDX, ((unsigned int *)dst->f.i.rt)+1); mov_eax_memoffs32((unsigned int *)dst->f.i.rs); add_eax_imm32((int)dst->f.i.immediate); mov_reg32_reg32(EBX, EAX); if(fast_memory) { and_eax_imm32(0xDF800000); cmp_eax_imm32(0x80000000); } else { shr_reg32_imm8(EAX, 16); mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)writememd); cmp_reg32_imm32(EAX, (unsigned int)write_rdramd); } je_rj(47); mov_m32_imm32((unsigned int *)(&PC), (unsigned int)(dst+1)); // 10 mov_m32_reg32((unsigned int *)(&address), EBX); // 6 mov_m32_reg32((unsigned int *)(&dword), ECX); // 6 mov_m32_reg32((unsigned int *)(&dword)+1, EDX); // 6 shr_reg32_imm8(EBX, 16); // 3 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)writememd); // 7 call_reg32(EBX); // 2 mov_eax_memoffs32((unsigned int *)(&address)); // 5 jmp_imm_short(20); // 2 mov_reg32_reg32(EAX, EBX); // 2 and_reg32_imm32(EBX, 0x7FFFFF); // 6 mov_preg32pimm32_reg32(EBX, ((unsigned int)g_rdram)+4, ECX); // 6 mov_preg32pimm32_reg32(EBX, ((unsigned int)g_rdram)+0, EDX); // 6 mov_reg32_reg32(EBX, EAX); shr_reg32_imm8(EBX, 12); cmp_preg32pimm32_imm8(EBX, (unsigned int)invalid_code, 0); jne_rj(54); mov_reg32_reg32(ECX, EBX); // 2 shl_reg32_imm8(EBX, 2); // 3 mov_reg32_preg32pimm32(EBX, EBX, (unsigned int)blocks); // 6 mov_reg32_preg32pimm32(EBX, EBX, (int)&actual->block - (int)actual); // 6 and_eax_imm32(0xFFF); // 5 shr_reg32_imm8(EAX, 2); // 3 mov_reg32_imm32(EDX, sizeof(precomp_instr)); // 5 mul_reg32(EDX); // 2 mov_reg32_preg32preg32pimm32(EAX, EAX, EBX, (int)&dst->ops - (int)dst); // 7 cmp_reg32_imm32(EAX, (unsigned int)cached_interpreter_table.NOTCOMPILED); // 6 je_rj(7); // 2 mov_preg32pimm32_imm8(ECX, (unsigned int)invalid_code, 1); // 7 #endif #endif } void genll(void) { gencallinterp((native_type)cached_interpreter_table.LL, 0); } void gensc(void) { gencallinterp((native_type)cached_interpreter_table.SC, 0); } glide2gl/000700 001750 001750 00000000000 12656647145 013377 5ustar00sergiosergio000000 000000 gles2n64/src/Turbo3D.c000664 001750 001750 00000007563 12655644434 015513 0ustar00sergiosergio000000 000000 #include "Turbo3D.h" #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gSP.h" #include "gDP.h" #include "OpenGL.h" /******************Turbo3D microcode*************************/ struct T3DGlobState { u16 pad0; u16 perspNorm; u32 flag; u32 othermode0; u32 othermode1; u32 segBases[16]; /* the viewport to use */ s16 vsacle1; s16 vsacle0; s16 vsacle3; s16 vsacle2; s16 vtrans1; s16 vtrans0; s16 vtrans3; s16 vtrans2; u32 rdpCmds; }; struct T3DState { u32 renderState; /* render state */ u32 textureState; /* texture state */ u8 flag; u8 triCount; /* how many tris? */ u8 vtxV0; /* where to load verts? */ u8 vtxCount; /* how many verts? */ u32 rdpCmds; /* ptr (segment address) to RDP DL */ u32 othermode0; u32 othermode1; }; struct T3DTriN { u8 flag, v2, v1, v0; /* flag is which one for flat shade */ }; static void Turbo3D_ProcessRDP(u32 _cmds) { u32 addr = RSP_SegmentToPhysical(_cmds) >> 2; if (addr != 0) { __RSP.bLLE = true; u32 w0 = ((u32*)gfx_info.RDRAM)[addr++]; u32 w1 = ((u32*)gfx_info.RDRAM)[addr++]; __RSP.cmd = _SHIFTR( w0, 24, 8 ); while (w0 + w1 != 0) { GBI.cmd[__RSP.cmd]( w0, w1 ); w0 = ((u32*)gfx_info.RDRAM)[addr++]; w1 = ((u32*)gfx_info.RDRAM)[addr++]; __RSP.cmd = _SHIFTR( w0, 24, 8 ); if (__RSP.cmd == 0xE4 || __RSP.cmd == 0xE5) { __RDP.w2 = ((u32*)gfx_info.RDRAM)[addr++]; __RDP.w3 = ((u32*)gfx_info.RDRAM)[addr++]; } } __RSP.bLLE = false; } } static void Turbo3D_LoadGlobState(u32 pgstate) { uint32_t s; const u32 addr = RSP_SegmentToPhysical(pgstate); struct T3DGlobState *gstate = (struct T3DGlobState*)&gfx_info.RDRAM[addr]; const u32 w0 = gstate->othermode0; const u32 w1 = gstate->othermode1; gDPSetOtherMode( _SHIFTR( w0, 0, 24 ), // mode0 w1 ); // mode1 for (s = 0; s < 16; ++s) gSPSegment(s, gstate->segBases[s] & 0x00FFFFFF); gSPViewport(pgstate + 80); Turbo3D_ProcessRDP(gstate->rdpCmds); } static void Turbo3D_LoadObject(u32 pstate, u32 pvtx, u32 ptri) { u32 addr = RSP_SegmentToPhysical(pstate); struct T3DState *ostate = (struct T3DState*)&gfx_info.RDRAM[addr]; const u32 tile = (ostate->textureState)&7; gSP.texture.tile = tile; gSP.textureTile[0] = &gDP.tiles[tile]; gSP.textureTile[1] = &gDP.tiles[(tile + 1) & 7]; gSP.texture.scales = 1.0f; gSP.texture.scalet = 1.0f; const u32 w0 = ostate->othermode0; const u32 w1 = ostate->othermode1; gDPSetOtherMode( _SHIFTR( w0, 0, 24 ), // mode0 w1 ); // mode1 gSPSetGeometryMode(ostate->renderState); if ((ostate->flag&1) == 0) //load matrix gSPForceMatrix(pstate + sizeof(struct T3DState)); gSPClearGeometryMode(G_LIGHTING); gSPSetGeometryMode(G_SHADING_SMOOTH); if (pvtx != 0) //load vtx gSPVertex(pvtx, ostate->vtxCount, ostate->vtxV0); Turbo3D_ProcessRDP(ostate->rdpCmds); if (ptri != 0) { unsigned t; addr = RSP_SegmentToPhysical(ptri); for (t = 0; t < ostate->triCount; ++t) { struct T3DTriN * tri = (struct T3DTriN*)&gfx_info.RDRAM[addr]; addr += 4; gSPTriangle(tri->v0, tri->v1, tri->v2); } OGL_DrawTriangles(); } } void RunTurbo3D(void) { u32 pstate; do { u32 addr = __RSP.PC[__RSP.PCi] >> 2; const u32 pgstate = ((u32*)gfx_info.RDRAM)[addr++]; pstate = ((u32*)gfx_info.RDRAM)[addr++]; const u32 pvtx = ((u32*)gfx_info.RDRAM)[addr++]; const u32 ptri = ((u32*)gfx_info.RDRAM)[addr]; if (pstate == 0) { __RSP.halt = 1; break; } if (pgstate != 0) Turbo3D_LoadGlobState(pgstate); Turbo3D_LoadObject(pstate, pvtx, ptri); // Go to the next instruction __RSP.PC[__RSP.PCi] += 16; } while (pstate != 0); } mupen64plus-core/src/vi/vi_controller.h000664 001750 001750 00000004743 12655644434 021316 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - vi_controller.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_VI_VI_CONTROLLER_H #define M64P_VI_VI_CONTROLLER_H #include #ifndef VI_REG #define VI_REG(a) ((a & 0xFFFF) >> 2) #endif struct r4300_core; enum vi_registers { VI_STATUS_REG, VI_ORIGIN_REG, VI_WIDTH_REG, VI_V_INTR_REG, VI_CURRENT_REG, VI_BURST_REG, VI_V_SYNC_REG, VI_H_SYNC_REG, VI_LEAP_REG, VI_H_START_REG, VI_V_START_REG, VI_V_BURST_REG, VI_X_SCALE_REG, VI_Y_SCALE_REG, VI_REGS_COUNT }; struct vi_controller { uint32_t regs[VI_REGS_COUNT]; unsigned int field; unsigned int delay; unsigned int next_vi; struct r4300_core* r4300; }; void connect_vi(struct vi_controller* vi, struct r4300_core* r4300); void init_vi(struct vi_controller* vi); int read_vi_regs(void* opaque, uint32_t address, uint32_t* value); int write_vi_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask); void vi_vertical_interrupt_event(struct vi_controller* vi); #endif libretro-common/libco/ppc.c000664 001750 001750 00000027343 12655644434 017056 0ustar00sergiosergio000000 000000 /* libco.ppc (2010-10-17) author: blargg license: public domain */ /* PowerPC 32/64 using embedded or external asm, with optional floating-point and AltiVec save/restore */ #define LIBCO_C #include #include #include #include #define LIBCO_MPROTECT (__unix__ && !LIBCO_PPC_ASM) #if LIBCO_MPROTECT #include #include #endif /* State format (offsets in 32-bit words) +0 Pointer to swap code Rest of function descriptor for entry function +8 PC +10 SP Special regs GPRs FPRs VRs stack */ enum { state_size = 1024 }; enum { above_stack = 2048 }; enum { stack_align = 256 }; static thread_local cothread_t co_active_handle = 0; /**** Determine environment ****/ #define LIBCO_PPC64 (_ARCH_PPC64 || __PPC64__ || __ppc64__ || __powerpc64__) /* Whether function calls are indirect through a descriptor, or are directly to function */ #ifndef LIBCO_PPCDESC #if !_CALL_SYSV && (_CALL_AIX || _CALL_AIXDESC || LIBCO_PPC64) #define LIBCO_PPCDESC 1 #endif #endif #ifdef LIBCO_PPC_ASM #ifdef __cplusplus extern "C" #endif /* Swap code is in ppc.S */ void co_swap_asm( cothread_t, cothread_t ); #define CO_SWAP_ASM( x, y ) co_swap_asm( x, y ) #else /* Swap code is here in array. Please leave dieassembly comments, as they make it easy to see what it does, and reorder instructions if one wants to see whether that improves performance. */ static const uint32_t libco_ppc_code [] = { #if LIBCO_PPC64 0x7d000026, /* mfcr r8 */ 0xf8240028, /* std r1,40(r4) */ 0x7d2802a6, /* mflr r9 */ 0xf9c40048, /* std r14,72(r4) */ 0xf9e40050, /* std r15,80(r4) */ 0xfa040058, /* std r16,88(r4) */ 0xfa240060, /* std r17,96(r4) */ 0xfa440068, /* std r18,104(r4) */ 0xfa640070, /* std r19,112(r4) */ 0xfa840078, /* std r20,120(r4) */ 0xfaa40080, /* std r21,128(r4) */ 0xfac40088, /* std r22,136(r4) */ 0xfae40090, /* std r23,144(r4) */ 0xfb040098, /* std r24,152(r4) */ 0xfb2400a0, /* std r25,160(r4) */ 0xfb4400a8, /* std r26,168(r4) */ 0xfb6400b0, /* std r27,176(r4) */ 0xfb8400b8, /* std r28,184(r4) */ 0xfba400c0, /* std r29,192(r4) */ 0xfbc400c8, /* std r30,200(r4) */ 0xfbe400d0, /* std r31,208(r4) */ 0xf9240020, /* std r9,32(r4) */ 0xe8e30020, /* ld r7,32(r3) */ 0xe8230028, /* ld r1,40(r3) */ 0x48000009, /* bl 1 */ 0x7fe00008, /* trap */ 0x91040030,/*1:stw r8,48(r4) */ 0x80c30030, /* lwz r6,48(r3) */ 0x7ce903a6, /* mtctr r7 */ 0xe9c30048, /* ld r14,72(r3) */ 0xe9e30050, /* ld r15,80(r3) */ 0xea030058, /* ld r16,88(r3) */ 0xea230060, /* ld r17,96(r3) */ 0xea430068, /* ld r18,104(r3) */ 0xea630070, /* ld r19,112(r3) */ 0xea830078, /* ld r20,120(r3) */ 0xeaa30080, /* ld r21,128(r3) */ 0xeac30088, /* ld r22,136(r3) */ 0xeae30090, /* ld r23,144(r3) */ 0xeb030098, /* ld r24,152(r3) */ 0xeb2300a0, /* ld r25,160(r3) */ 0xeb4300a8, /* ld r26,168(r3) */ 0xeb6300b0, /* ld r27,176(r3) */ 0xeb8300b8, /* ld r28,184(r3) */ 0xeba300c0, /* ld r29,192(r3) */ 0xebc300c8, /* ld r30,200(r3) */ 0xebe300d0, /* ld r31,208(r3) */ 0x7ccff120, /* mtcr r6 */ #else 0x7d000026, /* mfcr r8 */ 0x90240028, /* stw r1,40(r4) */ 0x7d2802a6, /* mflr r9 */ 0x91a4003c, /* stw r13,60(r4) */ 0x91c40040, /* stw r14,64(r4) */ 0x91e40044, /* stw r15,68(r4) */ 0x92040048, /* stw r16,72(r4) */ 0x9224004c, /* stw r17,76(r4) */ 0x92440050, /* stw r18,80(r4) */ 0x92640054, /* stw r19,84(r4) */ 0x92840058, /* stw r20,88(r4) */ 0x92a4005c, /* stw r21,92(r4) */ 0x92c40060, /* stw r22,96(r4) */ 0x92e40064, /* stw r23,100(r4) */ 0x93040068, /* stw r24,104(r4) */ 0x9324006c, /* stw r25,108(r4) */ 0x93440070, /* stw r26,112(r4) */ 0x93640074, /* stw r27,116(r4) */ 0x93840078, /* stw r28,120(r4) */ 0x93a4007c, /* stw r29,124(r4) */ 0x93c40080, /* stw r30,128(r4) */ 0x93e40084, /* stw r31,132(r4) */ 0x91240020, /* stw r9,32(r4) */ 0x80e30020, /* lwz r7,32(r3) */ 0x80230028, /* lwz r1,40(r3) */ 0x48000009, /* bl 1 */ 0x7fe00008, /* trap */ 0x91040030,/*1:stw r8,48(r4) */ 0x80c30030, /* lwz r6,48(r3) */ 0x7ce903a6, /* mtctr r7 */ 0x81a3003c, /* lwz r13,60(r3) */ 0x81c30040, /* lwz r14,64(r3) */ 0x81e30044, /* lwz r15,68(r3) */ 0x82030048, /* lwz r16,72(r3) */ 0x8223004c, /* lwz r17,76(r3) */ 0x82430050, /* lwz r18,80(r3) */ 0x82630054, /* lwz r19,84(r3) */ 0x82830058, /* lwz r20,88(r3) */ 0x82a3005c, /* lwz r21,92(r3) */ 0x82c30060, /* lwz r22,96(r3) */ 0x82e30064, /* lwz r23,100(r3) */ 0x83030068, /* lwz r24,104(r3) */ 0x8323006c, /* lwz r25,108(r3) */ 0x83430070, /* lwz r26,112(r3) */ 0x83630074, /* lwz r27,116(r3) */ 0x83830078, /* lwz r28,120(r3) */ 0x83a3007c, /* lwz r29,124(r3) */ 0x83c30080, /* lwz r30,128(r3) */ 0x83e30084, /* lwz r31,132(r3) */ 0x7ccff120, /* mtcr r6 */ #endif #ifndef LIBCO_PPC_NOFP 0xd9c400e0, /* stfd f14,224(r4) */ 0xd9e400e8, /* stfd f15,232(r4) */ 0xda0400f0, /* stfd f16,240(r4) */ 0xda2400f8, /* stfd f17,248(r4) */ 0xda440100, /* stfd f18,256(r4) */ 0xda640108, /* stfd f19,264(r4) */ 0xda840110, /* stfd f20,272(r4) */ 0xdaa40118, /* stfd f21,280(r4) */ 0xdac40120, /* stfd f22,288(r4) */ 0xdae40128, /* stfd f23,296(r4) */ 0xdb040130, /* stfd f24,304(r4) */ 0xdb240138, /* stfd f25,312(r4) */ 0xdb440140, /* stfd f26,320(r4) */ 0xdb640148, /* stfd f27,328(r4) */ 0xdb840150, /* stfd f28,336(r4) */ 0xdba40158, /* stfd f29,344(r4) */ 0xdbc40160, /* stfd f30,352(r4) */ 0xdbe40168, /* stfd f31,360(r4) */ 0xc9c300e0, /* lfd f14,224(r3) */ 0xc9e300e8, /* lfd f15,232(r3) */ 0xca0300f0, /* lfd f16,240(r3) */ 0xca2300f8, /* lfd f17,248(r3) */ 0xca430100, /* lfd f18,256(r3) */ 0xca630108, /* lfd f19,264(r3) */ 0xca830110, /* lfd f20,272(r3) */ 0xcaa30118, /* lfd f21,280(r3) */ 0xcac30120, /* lfd f22,288(r3) */ 0xcae30128, /* lfd f23,296(r3) */ 0xcb030130, /* lfd f24,304(r3) */ 0xcb230138, /* lfd f25,312(r3) */ 0xcb430140, /* lfd f26,320(r3) */ 0xcb630148, /* lfd f27,328(r3) */ 0xcb830150, /* lfd f28,336(r3) */ 0xcba30158, /* lfd f29,344(r3) */ 0xcbc30160, /* lfd f30,352(r3) */ 0xcbe30168, /* lfd f31,360(r3) */ #endif #ifdef __ALTIVEC__ 0x7ca042a6, /* mfvrsave r5 */ 0x39040180, /* addi r8,r4,384 */ 0x39240190, /* addi r9,r4,400 */ 0x70a00fff, /* andi. r0,r5,4095 */ 0x90a40034, /* stw r5,52(r4) */ 0x4182005c, /* beq- 2 */ 0x7e8041ce, /* stvx v20,r0,r8 */ 0x39080020, /* addi r8,r8,32 */ 0x7ea049ce, /* stvx v21,r0,r9 */ 0x39290020, /* addi r9,r9,32 */ 0x7ec041ce, /* stvx v22,r0,r8 */ 0x39080020, /* addi r8,r8,32 */ 0x7ee049ce, /* stvx v23,r0,r9 */ 0x39290020, /* addi r9,r9,32 */ 0x7f0041ce, /* stvx v24,r0,r8 */ 0x39080020, /* addi r8,r8,32 */ 0x7f2049ce, /* stvx v25,r0,r9 */ 0x39290020, /* addi r9,r9,32 */ 0x7f4041ce, /* stvx v26,r0,r8 */ 0x39080020, /* addi r8,r8,32 */ 0x7f6049ce, /* stvx v27,r0,r9 */ 0x39290020, /* addi r9,r9,32 */ 0x7f8041ce, /* stvx v28,r0,r8 */ 0x39080020, /* addi r8,r8,32 */ 0x7fa049ce, /* stvx v29,r0,r9 */ 0x39290020, /* addi r9,r9,32 */ 0x7fc041ce, /* stvx v30,r0,r8 */ 0x7fe049ce, /* stvx v31,r0,r9 */ 0x80a30034,/*2:lwz r5,52(r3) */ 0x39030180, /* addi r8,r3,384 */ 0x39230190, /* addi r9,r3,400 */ 0x70a00fff, /* andi. r0,r5,4095 */ 0x7ca043a6, /* mtvrsave r5 */ 0x4d820420, /* beqctr */ 0x7e8040ce, /* lvx v20,r0,r8 */ 0x39080020, /* addi r8,r8,32 */ 0x7ea048ce, /* lvx v21,r0,r9 */ 0x39290020, /* addi r9,r9,32 */ 0x7ec040ce, /* lvx v22,r0,r8 */ 0x39080020, /* addi r8,r8,32 */ 0x7ee048ce, /* lvx v23,r0,r9 */ 0x39290020, /* addi r9,r9,32 */ 0x7f0040ce, /* lvx v24,r0,r8 */ 0x39080020, /* addi r8,r8,32 */ 0x7f2048ce, /* lvx v25,r0,r9 */ 0x39290020, /* addi r9,r9,32 */ 0x7f4040ce, /* lvx v26,r0,r8 */ 0x39080020, /* addi r8,r8,32 */ 0x7f6048ce, /* lvx v27,r0,r9 */ 0x39290020, /* addi r9,r9,32 */ 0x7f8040ce, /* lvx v28,r0,r8 */ 0x39080020, /* addi r8,r8,32 */ 0x7fa048ce, /* lvx v29,r0,r9 */ 0x39290020, /* addi r9,r9,32 */ 0x7fc040ce, /* lvx v30,r0,r8 */ 0x7fe048ce, /* lvx v31,r0,r9 */ #endif 0x4e800420, /* bctr */ }; #if LIBCO_PPCDESC /* Function call goes through indirect descriptor */ #define CO_SWAP_ASM( x, y ) \ ((void (*)( cothread_t, cothread_t )) (uintptr_t) x)( x, y ) #else /* Function call goes directly to code */ #define CO_SWAP_ASM( x, y ) \ ((void (*)( cothread_t, cothread_t )) (uintptr_t) libco_ppc_code)( x, y ) #endif #endif static uint32_t* co_create_( unsigned size, uintptr_t entry ) { uint32_t* t = (uint32_t*) malloc( size ); (void) entry; #if LIBCO_PPCDESC if ( t ) { /* Copy entry's descriptor */ memcpy( t, (void*) entry, sizeof (void*) * 3 ); /* Set function pointer to swap routine */ #ifdef LIBCO_PPC_ASM *(const void**) t = *(void**) &co_swap_asm; #else *(const void**) t = libco_ppc_code; #endif } #endif return t; } cothread_t co_create( unsigned int size, void (*entry_)( void ) ) { uintptr_t entry = (uintptr_t) entry_; uint32_t* t = NULL; /* Be sure main thread was successfully allocated */ if ( co_active() ) { size += state_size + above_stack + stack_align; t = co_create_( size, entry ); } if ( t ) { uintptr_t sp; int shift; /* Save current registers into new thread, so that any special ones will have proper values when thread is begun */ CO_SWAP_ASM( t, t ); #if LIBCO_PPCDESC /* Get real address */ entry = (uintptr_t) *(void**) entry; #endif /* Put stack near end of block, and align */ sp = (uintptr_t) t + size - above_stack; sp -= sp % stack_align; /* On PPC32, we save and restore GPRs as 32 bits. For PPC64, we save and restore them as 64 bits, regardless of the size the ABI uses. So, we manually write pointers at the proper size. We always save and restore at the same address, and since PPC is big-endian, we must put the low byte first on PPC32. */ /* If uintptr_t is 32 bits, >>32 is undefined behavior, so we do two shifts and don't have to care how many bits uintptr_t is. */ #if LIBCO_PPC64 shift = 16; #else shift = 0; #endif /* Set up so entry will be called on next swap */ t [8] = (uint32_t) (entry >> shift >> shift); t [9] = (uint32_t) entry; t [10] = (uint32_t) (sp >> shift >> shift); t [11] = (uint32_t) sp; } return t; } void co_delete( cothread_t t ) { free(t); } static void co_init_( void ) { #if LIBCO_MPROTECT /* TODO: pre- and post-pad PPC code so that this doesn't make other data executable and writable */ long page_size = sysconf( _SC_PAGESIZE ); if ( page_size > 0 ) { uintptr_t align = page_size; uintptr_t begin = (uintptr_t) libco_ppc_code; uintptr_t end = begin + sizeof libco_ppc_code; /* Align beginning and end */ end += align - 1; end -= end % align; begin -= begin % align; mprotect( (void*) begin, end - begin, PROT_READ | PROT_WRITE | PROT_EXEC ); } #endif co_active_handle = co_create_( state_size, (uintptr_t) &co_switch ); } cothread_t co_active(void) { if (!co_active_handle) co_init_(); return co_active_handle; } void co_switch(cothread_t t) { cothread_t old = co_active_handle; co_active_handle = t; CO_SWAP_ASM( t, old ); } mupen64plus-video-gliden64/src/GLideNHQ/TxInternal.h000664 001750 001750 00000003315 12655644434 023224 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __INTERNAL_H__ #define __INTERNAL_H__ #include "Ext_TxFilter.h" #include "txWidestringWrapper.h" #ifdef WIN32 #define KBHIT(key) ((GetAsyncKeyState(key) & 0x8001) == 0x8001) #else #define KBHIT(key) (0) #endif #ifdef OS_WINDOWS #include #include "glext.h" #elif defined(GLES2) #include #include #define GL_COLOR_INDEX8_EXT 0x80E5 #elif defined(GLES3) #include #include #define GL_COLOR_INDEX8_EXT 0x80E5 #elif defined(GLES3_1) #include #include #define GL_COLOR_INDEX8_EXT 0x80E5 #elif defined(OS_MAC_OS_X) #include #include #elif defined(OS_LINUX) #include #include #endif // OS_WINDOWS /* in-memory zlib texture compression */ #define GL_TEXFMT_GZ 0x80000000 #endif /* __INTERNAL_H__ */ mupen64plus-core/src/vi/vi_controller.c000664 001750 001750 00000010106 12655644434 021277 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - vi_controller.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "vi_controller.h" #include "main/main.h" #include "memory/memory.h" #include "plugin/plugin.h" #include "r4300/r4300_core.h" #include "r4300/interupt.h" #include void connect_vi(struct vi_controller* vi, struct r4300_core* r4300) { vi->r4300 = r4300; } /* Initializes the VI. */ void init_vi(struct vi_controller* vi) { memset(vi->regs, 0, VI_REGS_COUNT*sizeof(uint32_t)); vi->field = 0; vi->delay = vi->next_vi = 5000; } /* Reads a word from the VI MMIO register space. */ int read_vi_regs(void* opaque, uint32_t address, uint32_t *word) { struct vi_controller* vi = (struct vi_controller*)opaque; uint32_t reg = VI_REG(address); const uint32_t* cp0_regs = r4300_cp0_regs(); if (reg == VI_CURRENT_REG) { cp0_update_count(); vi->regs[VI_CURRENT_REG] = (vi->delay - (vi->next_vi - cp0_regs[CP0_COUNT_REG]))/1500; vi->regs[VI_CURRENT_REG] = (vi->regs[VI_CURRENT_REG] & (~1)) | vi->field; } *word = vi->regs[reg]; return 0; } /* Writes a word to the VI MMIO register space. */ int write_vi_regs(void* opaque, uint32_t address, uint32_t word, uint32_t mask) { struct vi_controller* vi = (struct vi_controller*)opaque; uint32_t reg = VI_REG(address); switch (reg) { case VI_STATUS_REG: if ((vi->regs[VI_STATUS_REG] & mask) != (word & mask)) { vi->regs[VI_STATUS_REG] = MASKED_WRITE(&vi->regs[VI_STATUS_REG], word, mask); gfx.viStatusChanged(); } return 0; case VI_WIDTH_REG: if ((vi->regs[VI_WIDTH_REG] & mask) != (word & mask)) { vi->regs[VI_WIDTH_REG] = MASKED_WRITE(&vi->regs[VI_WIDTH_REG], word, mask); gfx.viWidthChanged(); } return 0; case VI_CURRENT_REG: clear_rcp_interrupt(vi->r4300, MI_INTR_VI); return 0; } vi->regs[reg] = MASKED_WRITE(&vi->regs[reg], word, mask); return 0; } void vi_vertical_interrupt_event(struct vi_controller* vi) { gfx.updateScreen(); /* allow main module to do things on VI event */ new_vi(); /* toggle vi field if in interlaced mode */ vi->field ^= (vi->regs[VI_STATUS_REG] >> 6) & 0x1; /* schedule next vertical interrupt */ if (vi->regs[VI_V_SYNC_REG] == 0) vi->delay = 500000; else vi->delay = (vi->regs[VI_V_SYNC_REG] + 1) * VI_REFRESH; vi->next_vi += vi->delay; add_interupt_event_count(VI_INT, vi->next_vi); /* trigger interrupt */ raise_rcp_interrupt(vi->r4300, MI_INTR_VI); } mupen64plus-core/src/dd/dd_rom.h000664 001750 001750 00000004107 12655644434 017644 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - dd_rom.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2015 LuigiBlood * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef __DDROM_H__ #define __DDROM_H__ #include #include "api/m64p_types.h" struct dd_rom { uint8_t* rom; size_t rom_size; }; void connect_dd_rom(struct dd_rom* dd_rom, uint8_t* rom, size_t rom_size); /* ROM Loading and Saving functions */ m64p_error open_ddrom(const unsigned char* romimage, unsigned int size); m64p_error close_ddrom(void); extern unsigned char* g_ddrom; extern int g_ddrom_size; int read_dd_ipl(void* opaque, uint32_t address, uint32_t* value); int write_dd_ipl(void* opaque, uint32_t address, uint32_t value, uint32_t mask); #endif mupen64plus-video-gliden64/src/3DMath.h000664 001750 001750 00000001651 12655644434 020662 0ustar00sergiosergio000000 000000 #ifndef _3DMATH_H #define _3DMATH_H #include #include void MultMatrix( float m0[4][4], float m1[4][4], float dest[4][4]); void MultMatrix2(float m0[4][4], float m1[4][4] ); void TransformVectorNormalize(float vec[3], float mtx[4][4]); inline void CopyMatrix( float m0[4][4], float m1[4][4] ) { memcpy( m0, m1, 16 * sizeof( float ) ); } inline void Transpose3x3Matrix( float mtx[4][4] ) { float tmp; tmp = mtx[0][1]; mtx[0][1] = mtx[1][0]; mtx[1][0] = tmp; tmp = mtx[0][2]; mtx[0][2] = mtx[2][0]; mtx[2][0] = tmp; tmp = mtx[1][2]; mtx[1][2] = mtx[2][1]; mtx[2][1] = tmp; } inline void Normalize(float v[3]) { float len; len = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; if (len != 0.0) { len = sqrtf( len ); v[0] /= len; v[1] /= len; v[2] /= len; } } inline float DotProduct(const float v0[3], const float v1[3]) { float dot = v0[0]*v1[0] + v0[1]*v1[1] + v0[2]*v1[2]; return dot; } #endif gles2n64/src/ShaderCombiner.h000664 001750 001750 00000024205 12655644434 017113 0ustar00sergiosergio000000 000000 #ifndef SHADERCOMBINER_H #define SHADERCOMBINER_H #ifdef __cplusplus extern "C" { #endif #define SC_FOGENABLED 0x1 #define SC_ALPHAENABLED 0x2 #define SC_ALPHAGREATER 0x4 #define SC_2CYCLE 0x8 #define SC_POSITION 0 #define SC_COLOR 1 #define SC_TEXCOORD0 2 #define SC_TEXCOORD1 3 #define SC_SetUniform1i(A, B) glUniform1i(scProgramCurrent->uniforms.A.loc, B) #define SC_SetUniform1f(A, B) glUniform1f(scProgramCurrent->uniforms.A.loc, B) #define SC_SetUniform4fv(A, B) glUniform4fv(scProgramCurrent->uniforms.A.loc, 1, B) #define SC_SetUniform2f(A, B, C) glUniform2f(scProgramCurrent->uniforms.A.loc, B, C) #define SC_ForceUniform1i(A, B) glUniform1i(scProgramCurrent->uniforms.A.loc, B) #define SC_ForceUniform1f(A, B) glUniform1f(scProgramCurrent->uniforms.A.loc, B) #define SC_ForceUniform4fv(A, B) glUniform4fv(scProgramCurrent->uniforms.A.loc, 1, B) #define SC_ForceUniform2f(A, B, C) glUniform2f(scProgramCurrent->uniforms.A.loc, B, C) /* Color combiner constants: */ #define G_CCMUX_COMBINED 0 #define G_CCMUX_TEXEL0 1 #define G_CCMUX_TEXEL1 2 #define G_CCMUX_PRIMITIVE 3 #define G_CCMUX_SHADE 4 #define G_CCMUX_ENVIRONMENT 5 #define G_CCMUX_CENTER 6 #define G_CCMUX_SCALE 6 #define G_CCMUX_COMBINED_ALPHA 7 #define G_CCMUX_TEXEL0_ALPHA 8 #define G_CCMUX_TEXEL1_ALPHA 9 #define G_CCMUX_PRIMITIVE_ALPHA 10 #define G_CCMUX_SHADE_ALPHA 11 #define G_CCMUX_ENV_ALPHA 12 #define G_CCMUX_LOD_FRACTION 13 #define G_CCMUX_PRIM_LOD_FRAC 14 #define G_CCMUX_NOISE 7 #define G_CCMUX_K4 7 #define G_CCMUX_K5 15 #define G_CCMUX_1 6 #define G_CCMUX_0 31 /* Alpha combiner constants: */ #define G_ACMUX_COMBINED 0 #define G_ACMUX_TEXEL0 1 #define G_ACMUX_TEXEL1 2 #define G_ACMUX_PRIMITIVE 3 #define G_ACMUX_SHADE 4 #define G_ACMUX_ENVIRONMENT 5 #define G_ACMUX_LOD_FRACTION 0 #define G_ACMUX_PRIM_LOD_FRAC 6 #define G_ACMUX_1 6 #define G_ACMUX_0 7 #define EncodeCombineMode( a0, b0, c0, d0, Aa0, Ab0, Ac0, Ad0, \ a1, b1, c1, d1, Aa1, Ab1, Ac1, Ad1 ) \ (u64)(((u64)(_SHIFTL( G_CCMUX_##a0, 20, 4 ) | _SHIFTL( G_CCMUX_##c0, 15, 5 ) | \ _SHIFTL( G_ACMUX_##Aa0, 12, 3 ) | _SHIFTL( G_ACMUX_##Ac0, 9, 3 ) | \ _SHIFTL( G_CCMUX_##a1, 5, 4 ) | _SHIFTL( G_CCMUX_##c1, 0, 5 )) << 32) | \ (u64)(_SHIFTL( G_CCMUX_##b0, 28, 4 ) | _SHIFTL( G_CCMUX_##d0, 15, 3 ) | \ _SHIFTL( G_ACMUX_##Ab0, 12, 3 ) | _SHIFTL( G_ACMUX_##Ad0, 9, 3 ) | \ _SHIFTL( G_CCMUX_##b1, 24, 4 ) | _SHIFTL( G_ACMUX_##Aa1, 21, 3 ) | \ _SHIFTL( G_ACMUX_##Ac1, 18, 3 ) | _SHIFTL( G_CCMUX_##d1, 6, 3 ) | \ _SHIFTL( G_ACMUX_##Ab1, 3, 3 ) | _SHIFTL( G_ACMUX_##Ad1, 0, 3 ))) #define G_CC_PRIMITIVE 0, 0, 0, PRIMITIVE, 0, 0, 0, PRIMITIVE #define G_CC_SHADE 0, 0, 0, SHADE, 0, 0, 0, SHADE #define G_CC_MODULATEI TEXEL0, 0, SHADE, 0, 0, 0, 0, SHADE #define G_CC_MODULATEIA TEXEL0, 0, SHADE, 0, TEXEL0, 0, SHADE, 0 #define G_CC_MODULATEIDECALA TEXEL0, 0, SHADE, 0, 0, 0, 0, TEXEL0 #define G_CC_MODULATERGB G_CC_MODULATEI #define G_CC_MODULATERGBA G_CC_MODULATEIA #define G_CC_MODULATERGBDECALA G_CC_MODULATEIDECALA #define G_CC_MODULATEI_PRIM TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE #define G_CC_MODULATEIA_PRIM TEXEL0, 0, PRIMITIVE, 0, TEXEL0, 0, PRIMITIVE, 0 #define G_CC_MODULATEIDECALA_PRIM TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, TEXEL0 #define G_CC_MODULATERGB_PRIM G_CC_MODULATEI_PRIM #define G_CC_MODULATERGBA_PRIM G_CC_MODULATEIA_PRIM #define G_CC_MODULATERGBDECALA_PRIM G_CC_MODULATEIDECALA_PRIM #define G_CC_DECALRGB 0, 0, 0, TEXEL0, 0, 0, 0, SHADE #define G_CC_DECALRGBA 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0 #define G_CC_BLENDI ENVIRONMENT, SHADE, TEXEL0, SHADE, 0, 0, 0, SHADE #define G_CC_BLENDIA ENVIRONMENT, SHADE, TEXEL0, SHADE, TEXEL0, 0, SHADE, 0 #define G_CC_BLENDIDECALA ENVIRONMENT, SHADE, TEXEL0, SHADE, 0, 0, 0, TEXEL0 #define G_CC_BLENDRGBA TEXEL0, SHADE, TEXEL0_ALPHA, SHADE, 0, 0, 0, SHADE #define G_CC_BLENDRGBDECALA TEXEL0, SHADE, TEXEL0_ALPHA, SHADE, 0, 0, 0, TEXEL0 #define G_CC_ADDRGB 1, 0, TEXEL0, SHADE, 0, 0, 0, SHADE #define G_CC_ADDRGBDECALA 1, 0, TEXEL0, SHADE, 0, 0, 0, TEXEL0 #define G_CC_REFLECTRGB ENVIRONMENT, 0, TEXEL0, SHADE, 0, 0, 0, SHADE #define G_CC_REFLECTRGBDECALA ENVIRONMENT, 0, TEXEL0, SHADE, 0, 0, 0, TEXEL0 #define G_CC_HILITERGB PRIMITIVE, SHADE, TEXEL0, SHADE, 0, 0, 0, SHADE #define G_CC_HILITERGBA PRIMITIVE, SHADE, TEXEL0, SHADE, PRIMITIVE, SHADE, TEXEL0, SHADE #define G_CC_HILITERGBDECALA PRIMITIVE, SHADE, TEXEL0, SHADE, 0, 0, 0, TEXEL0 #define G_CC_SHADEDECALA 0, 0, 0, SHADE, 0, 0, 0, TEXEL0 #define G_CC_BLENDPE PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, SHADE, 0 #define G_CC_BLENDPEDECALA PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, 0, 0, 0, TEXEL0 #define _G_CC_BLENDPE ENVIRONMENT, PRIMITIVE, TEXEL0, PRIMITIVE, TEXEL0, 0, SHADE, 0 #define _G_CC_BLENDPEDECALA ENVIRONMENT, PRIMITIVE, TEXEL0, PRIMITIVE, 0, 0, 0, TEXEL0 #define _G_CC_TWOCOLORTEX PRIMITIVE, SHADE, TEXEL0, SHADE, 0, 0, 0, SHADE #define _G_CC_SPARSEST PRIMITIVE, TEXEL0, LOD_FRACTION, TEXEL0, PRIMITIVE, TEXEL0, LOD_FRACTION, TEXEL0 #define G_CC_TEMPLERP TEXEL1, TEXEL0, PRIM_LOD_FRAC, TEXEL0, TEXEL1, TEXEL0, PRIM_LOD_FRAC, TEXEL0 #define G_CC_TRILERP TEXEL1, TEXEL0, LOD_FRACTION, TEXEL0, TEXEL1, TEXEL0, LOD_FRACTION, TEXEL0 #define G_CC_INTERFERENCE TEXEL0, 0, TEXEL1, 0, TEXEL0, 0, TEXEL1, 0 #define G_CC_1CYUV2RGB TEXEL0, K4, K5, TEXEL0, 0, 0, 0, SHADE #define G_CC_YUV2RGB TEXEL1, K4, K5, TEXEL1, 0, 0, 0, 0 #define G_CC_PASS2 0, 0, 0, COMBINED, 0, 0, 0, COMBINED #define G_CC_MODULATEI2 COMBINED, 0, SHADE, 0, 0, 0, 0, SHADE #define G_CC_MODULATEIA2 COMBINED, 0, SHADE, 0, COMBINED, 0, SHADE, 0 #define G_CC_MODULATERGB2 G_CC_MODULATEI2 #define G_CC_MODULATERGBA2 G_CC_MODULATEIA2 #define G_CC_MODULATEI_PRIM2 COMBINED, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE #define G_CC_MODULATEIA_PRIM2 COMBINED, 0, PRIMITIVE, 0, COMBINED, 0, PRIMITIVE, 0 #define G_CC_MODULATERGB_PRIM2 G_CC_MODULATEI_PRIM2 #define G_CC_MODULATERGBA_PRIM2 G_CC_MODULATEIA_PRIM2 #define G_CC_DECALRGB2 0, 0, 0, COMBINED, 0, 0, 0, SHADE #define G_CC_BLENDI2 ENVIRONMENT, SHADE, COMBINED, SHADE, 0, 0, 0, SHADE #define G_CC_BLENDIA2 ENVIRONMENT, SHADE, COMBINED, SHADE, COMBINED, 0, SHADE, 0 #define G_CC_CHROMA_KEY2 TEXEL0, CENTER, SCALE, 0, 0, 0, 0, 0 #define G_CC_HILITERGB2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, 0, 0, 0, SHADE #define G_CC_HILITERGBA2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, ENVIRONMENT, COMBINED, TEXEL0, COMBINED #define G_CC_HILITERGBDECALA2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, 0, 0, 0, TEXEL0 #define G_CC_HILITERGBPASSA2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, 0, 0, 0, COMBINED // Internal combiner commands #define LOAD 0 #define SUB 1 #define MUL 2 #define ADD 3 #define INTER 4 // Internal generalized combiner inputs #define COMBINED 0 #define TEXEL0 1 #define TEXEL1 2 #define PRIMITIVE 3 #define SHADE 4 #define ENVIRONMENT 5 #define CENTER 6 #define SCALE 7 #define COMBINED_ALPHA 8 #define TEXEL0_ALPHA 9 #define TEXEL1_ALPHA 10 #define PRIMITIVE_ALPHA 11 #define SHADE_ALPHA 12 #define ENV_ALPHA 13 #define LOD_FRACTION 14 #define PRIM_LOD_FRAC 15 #define NOISE 16 #define K4 17 #define K5 18 #define ONE 19 #define ZERO 20 #define UNKNOWN 21 struct iUniform {GLint loc; int val;}; struct fUniform {GLint loc; float val;}; struct fv2Uniform {GLint loc; float val[2];}; struct fv4Uniform {GLint loc; float val[4];}; typedef struct { struct iUniform uTex0, uTex1, uTexNoise; struct iUniform uEnableFog; struct fUniform uFogScale, uFogOffset, uAlphaRef, uPrimLODFrac, uRenderState, uK4, uK5; struct fv4Uniform uEnvColor, uPrimColor, uFogColor; struct fv2Uniform uTexScale, uTexOffset[2], uCacheShiftScale[2], uCacheScale[2], uCacheOffset[2]; } UniformLocation; typedef struct ShaderProgram { GLint program; GLint fragment; GLint vertex; int usesT0; //uses texcoord0 attrib int usesT1; //uses texcoord1 attrib int usesCol; //uses color attrib int usesNoise; //requires noise texture UniformLocation uniforms; gDPCombine combine; u32 flags; struct ShaderProgram *left, *right; u32 lastUsed; } ShaderProgram; //dmux flags: #define SC_IGNORE_RGB0 (1<<0) #define SC_IGNORE_ALPHA0 (1<<1) #define SC_IGNORE_RGB1 (1<<2) #define SC_IGNORE_ALPHA1 (1<<3) struct CombineCycle { int sa, sb, m, a; }; typedef struct { gDPCombine combine; struct CombineCycle decode[4]; int flags; } DecodedMux; extern int CCEncodeA[]; extern int CCEncodeB[]; extern int CCEncodeC[]; extern int CCEncodeD[]; extern int ACEncodeA[]; extern int ACEncodeB[]; extern int ACEncodeC[]; extern int ACEncodeD[]; extern ShaderProgram *scProgramRoot; extern ShaderProgram *scProgramCurrent; extern int scProgramChanged; extern int scProgramCount; void Combiner_Init(void); void Combiner_Destroy(void); void Combiner_Set(u64 mux, int flags); void ShaderCombiner_UpdateBlendColor(void); void ShaderCombiner_UpdateEnvColor(void); void ShaderCombiner_UpdateFogColor(void); void ShaderCombiner_UpdatePrimColor(void); void ShaderCombiner_UpdateKeyColor(void); void ShaderCombiner_UpdateLightParameters(void); void ShaderCombiner_UpdateConvertColor(void); #ifdef __cplusplus } #endif #endif mupen64plus-core/src/dd/dd_rom.c000664 001750 001750 00000013446 12655644434 017645 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - dd_rom.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2015 LuigiBlood * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include "dd_rom.h" #include "../pi/pi_controller.h" #include "../api/callbacks.h" #include "../api/config.h" #include "../api/m64p_config.h" #include "../api/m64p_types.h" #include "../main/main.h" #include "../main/rom.h" #include "../main/util.h" /* Global loaded DDrom memory space. */ unsigned char* g_ddrom = NULL; /* Global loaded DDrom size. */ int g_ddrom_size = 0; static const uint8_t Z64_SIGNATURE[4] = { 0x80, 0x27, 0x07, 0x40 }; static const uint8_t V64_SIGNATURE[4] = { 0x27, 0x80, 0x40, 0x07 }; static const uint8_t N64_SIGNATURE[4] = { 0x40, 0x07, 0x27, 0x80 }; /* Tests if a file is a valid 64DD IPL rom by checking the first 4 bytes. */ static int is_valid_rom(const unsigned char *buffer) { if (memcmp(buffer, Z64_SIGNATURE, sizeof(Z64_SIGNATURE)) == 0 || memcmp(buffer, V64_SIGNATURE, sizeof(V64_SIGNATURE)) == 0 || memcmp(buffer, N64_SIGNATURE, sizeof(N64_SIGNATURE)) == 0) return 1; else return 0; } /* Copies the source block of memory to the destination block of memory while * switching the endianness of .v64 and .n64 images to the .z64 format, which * is native to the Nintendo 64. The data extraction routines and MD5 hashing * function may only act on the .z64 big-endian format. * * IN: src: The source block of memory. This must be a valid Nintendo 64 ROM * image of 'len' bytes. * len: The length of the source and destination, in bytes. * OUT: dst: The destination block of memory. This must be a valid buffer for * at least 'len' bytes. * imagetype: A pointer to a byte that gets updated with the value of * V64IMAGE, N64IMAGE or Z64IMAGE according to the format of * the source block. The value is undefined if 'src' does not * represent a valid Nintendo 64 ROM image. */ static void swap_copy_rom(void* dst, const void* src, size_t len, unsigned char* imagetype) { if (memcmp(src, V64_SIGNATURE, sizeof(V64_SIGNATURE)) == 0) { size_t i; const uint16_t* src16 = (const uint16_t*)src; uint16_t* dst16 = (uint16_t*)dst; *imagetype = V64IMAGE; /* .v64 images have byte-swapped half-words (16-bit). */ for (i = 0; i < len; i += 2) { *dst16++ = m64p_swap16(*src16++); } } else if (memcmp(src, N64_SIGNATURE, sizeof(N64_SIGNATURE)) == 0) { size_t i; const uint32_t* src32 = (const uint32_t*)src; uint32_t* dst32 = (uint32_t*)dst; *imagetype = N64IMAGE; /* .n64 images have byte-swapped words (32-bit). */ for (i = 0; i < len; i += 4) { *dst32++ = m64p_swap32(*src32++); } } else { *imagetype = Z64IMAGE; memcpy(dst, src, len); } } void connect_dd_rom(struct dd_rom* dd_rom, uint8_t* rom, size_t rom_size) { dd_rom->rom = rom; dd_rom->rom_size = rom_size; } m64p_error open_ddrom(const unsigned char* romimage, unsigned int size) { unsigned char imagetype; /* check input requirements */ if (g_ddrom != NULL) { DebugMessage(M64MSG_ERROR, "open_ddrom(): previous ROM image was not freed"); return M64ERR_INTERNAL; } if (romimage == NULL || !is_valid_rom(romimage)) { DebugMessage(M64MSG_ERROR, "open_ddrom(): not a valid ROM image"); return M64ERR_INPUT_INVALID; } /* Clear Byte-swapped flag, since ROM is now deleted. */ g_DDMemHasBeenBSwapped = 0; /* allocate new buffer for ROM and copy into this buffer */ g_ddrom_size = size; g_ddrom = (unsigned char *)malloc(size); if (g_ddrom == NULL) return M64ERR_NO_MEMORY; swap_copy_rom(g_ddrom, romimage, size, &imagetype); DebugMessage(M64MSG_STATUS, "Retail 64DD IPL loaded!"); return M64ERR_SUCCESS; } m64p_error close_ddrom(void) { if (g_ddrom == NULL) return M64ERR_INVALID_STATE; free(g_ddrom); g_ddrom = NULL; /* Clear Byte-swapped flag, since ROM is now deleted. */ g_DDMemHasBeenBSwapped = 0; DebugMessage(M64MSG_STATUS, "Rom closed."); return M64ERR_SUCCESS; } int read_dd_ipl(void* opaque, uint32_t address, uint32_t* value) { struct pi_controller* pi = (struct pi_controller*)opaque; uint32_t offset = address & 0x3FFFFC; if (pi->dd_rom.rom == NULL || pi->dd_rom.rom_size == 0) { *value = 0; return 0; } *value = *(uint32_t*)(pi->dd_rom.rom + offset); return 0; } int write_dd_ipl(void* opaque, uint32_t address, uint32_t value, uint32_t mask) { return 0; } glide2gl/src/Glide64/Help/Glide64 compatibility list.html000664 001750 001750 00001211502 12655644434 024141 0ustar00sergiosergio000000 000000 .::Glide64 compatibility list::.
Compatibility List 
for Glide64 1.0
 
Game Name:  RSP Microcode Playability Level Relative speed Comments
007 - The World is Not Enough F3DEX2.XX 5 Normal Compatible
1080 Snowboarding F3DEX1.XX 5 Normal Compatible. Use "Read every frame" option to see correct TV monitors (slow)
40 Winks F3DEX2.XX 5 Normal Compatible
64 Oozumou F3DEX1.XX 5 Normal Compatible
64 Oozumou 2 F3DEX1.XX 5 Normal Compatible
64 Trump Collection - Alice no Wakuwaku Trump World F3DEX1.XX 5 Normal Compatible
64 de Hakken!! Tamagotchi Minna de Tamagotchi World F3DTEX/A  3 Slow Major gfx errors
AI Shogi 3 F3DEX1.XX 5 Fast Compatible. Use 1964
Aerofighter's Assault RSP SW 2.0X 5 Normal Compatible
AeroGauge F3DEX1.XX 5 Fast Compatible
Aidyn Chronicles - The First Mage F3DEX2.XX 5 Normal Compatible
Airboarder 64  F3DEX1.XX 5 Fast Compatible
Akumajou Dracula Makushiroku - Real Action Adventure F3DEX2.XX 5 Normal Compatible. Use "Read every frame" option to see correct menu (slow)
Akumajou Dracula Makushiroku-Legend of Cornell F3DEX2.XX 5 Normal Compatible. Enable hi-res mode for correct menus
All Star Tennis '99 F3DEX1.XX 5 Fast Compatible
All-Star Baseball 99 F3DEX1.XX 5 Normal Compatible. Use "Get frame buffer info" option with Mupen or use "Read every frame" option to see correct TV monitors (slow). Minor gfx errors
All-Star Baseball 2000 F3DEX2.XX 5 Normal Compatible. Use Nemu 0.8. Use "Read every frame" option to see correct TV monitors (slow)
All-Star Baseball 2001 F3DEX1.XX 5 Normal Compatible. Use Nemu 0.8. Use "Read every frame" option to see correct TV monitors (slow)
Armorines - Project S.W.A.R.M. F3DEX2.XX 5 Normal Compatible
Army Men - Air Combat F3DEX2.XX 5 Normal Compatible
Army Men - Sarge's Heroes F3DEX2.XX 5 Normal Compatible
Army Men - Sarge's Heroes 2 F3DEX2.XX 5 Normal Compatible
Asteroids Hyper 64 F3DEX2.XX 5 Fast Compatible
Automobili Lamborghini F3DEX1.XX 5 Normal Compatible. Minor gfx errors
Baku Bomberman F3DEX1.XX 5 Normal Compatible. Use "Get frame buffer info" option with Mupen or use "Read every frame" option to see intro correctly (slow)
Baku Bomberman 2 F3DEX2.XX 5 Normal Compatible
Bakuretsu Muteki Bangaioh F3DEX1.XX 5 Slow Compatible
Bakushou Jinsei 64 - Mezase! (Game of Life) RSP SW 2.0X 5 Slow Compatible. Use "Read every frame" option to have correct gfx in game
Banjo to Kazooie no Dai Bouken F3DEX1.XX 5 Normal Compatible. Use "Read every frame" option (slow) or "Get frame buffer info" option with Mupen to see puzzle effect   
Banjo to Kazooie no Dai Bouken 2 F3DEX2.XX 5 Normal Compatible
Banjo-Kazooie F3DEX1.XX 5 Normal Compatible. Use "Read every frame" option (slow) or "Get frame buffer info" option to see puzzle effect with Mupen   
Banjo-Tooie F3DEX2.XX 5 Normal Compatible
Bass Hunter 64 F3DEX2.XX 5 Normal Compatible
Bass Rush - ECOGEAR PowerWorm Championship F3DEX2.XX 5 Normal Compatible
Bass Tsuri No.1 - Shigesato Itoi's Bass Fishing F3DEX2.XX 5 Normal Compatible
Bassmasters 2000 F3DEX2.XX 5 Normal Compatible
Batman Beyond - Return of the Joker F3DEX2.XX 5 Normal Compatible
BattleTanx F3DEX1.XX 5 Fast Compatible
BattleTanx - Global Assault F3DEX2.XX 5 Fast Compatible
Battlezone - Rise of the Black Dogs F3DEX2.XX 5 Normal Compatible
Beetle Adventure Racing F3DEX2.XX 5 Normal Compatible
Big Mountain 2000 F3DEX2.XX 5 Fast Compatible
Bio F.R.E.A.K.S. F3DEX1.XX 5 Normal Compatible
Bio Hazard 2 F3DEX1.XX 5 Normal Compatible
Blast Corps RSP SW 2.0X 5 Normal Compatible. Use PJ64. Minor gfx errors
Blast Dozer RSP SW 2.0X 5 Normal Compatible. Use PJ64. Minor gfx errors
Blues Brothers 2000 F3DEX2.XX 5 Normal Compatible
Body Harvest F3DEX1.XX 5 Normal Compatible. Use "Read every frame" option (slow) or "Get frame buffer info" with Mupen to have correct menu
Bokujo Monogatari 2 F3DEX2.XX 5 Normal Compatible
Bomberman 64 F3DEX1.XX 5 Normal Compatible. Use "Get frame buffer info" option with Mupen or use "Read every frame" option to see intro correctly (slow)
Bomberman64 - The Second Attack F3DEX2.XX 5 Normal Compatible
Bomberman Hero F3DEX1.XX 5 Fast Compatible. 
Bottom of the 9th F3DEX2.XX 5 Fast Compatible. Use "Read every frame" option (slow) to see correct intro
Brunswick Circuit Pro Bowling F3DEX1.XX 5 Fast Compatible
Buck Bumble F3DEX2.XX 5 Normal Compatible
Bug's Life, A F3DEX1.XX 5 Normal Compatible
Bust-A-Move '99 F3DEX1.XX 5 Fast Compatible
Bust-A-Move 2 - Arcade Edition F3DEX1.XX 5 Fast Compatible
Bust-A-Move 3 DX F3DEX1.XX 5 Fast Compatible
California Speed F3DEX2.XX 5 Normal Compatible
Carmageddon 64 F3DEX2.XX 5 Fast Compatible
Castlevania F3DEX2.XX 5 Normal Compatible. Use "Read every frame" option to see correct menu (slow)
Castlevania - Legacy of Darkness F3DEX2.XX 5 Normal Compatible. Enable hi-res mode for correct menus
Centre Court Tennis F3DEX1.XX 5 Fast Compatible
Chameleon Twist F3DEX1.XX 5 Fast Compatible
Chameleon Twist 2 F3DEX2.XX 5 Normal Compatible
Charlie Blast's Territory F3DEX1.XX 5 Fast Compatible
Chopper Attack RSP SW 2.0X 5 Fast Compatible
Choro Q 64 F3DEX1.XX 5 Fast Compatible
Choro Q 64 II F3DEX2.XX 5 Fast Compatible. Use "Read every frame" option (slow) or "Get frame buffer info" option with Mupen to see correct menu
Chou Kuukan Night Pro Yakyuu King F3DEX1.XX 5 Normal Compatible
Chou Kuukan Night Pro Yakyuu King 2 F3DEX1.XX 5 Normal Compatible
Chou Snobow Kids F3DEX2.XX 5 Fast Compatible
City-Tour GP - Zennihon GT Senshuken F3DEX1.XX 5 Normal Compatible
Clay Fighter - Sculptor's Cut F3DEX1.XX 5 Slow Compatible
Clay Fighter 63 1-3 F3DEX1.XX 5 Slow Compatible
Command & Conquer F3DEX2.XX 3 Fast Not playable
Conker's Bad Fur Day F3DEXGB2.08 5 Normal Compatible. Use "Read every frame" option (slow) to get black and white effect during “It’s war” cut scene and Buga pixellisation effect
Cruis'n Exotica F3DEX2.XX 5 Fast Compatible
Cruis'n USA RSP SW 2.0X 5 Fast Compatible
Cruis'n World F3DEX2.XX 5 Fast Compatible
Custom Robo F3DEX2.XX 5 Normal Compatible
Custom Robo V2 F3DEX2.XX 5 Normal Compatible
CyberTiger  F3DEX2.XX 5 Normal Compatible
Dance Dance Revolution - Disney Dancing Museum F3DEX2.XX 5 Normal Compatible
Dark Rift TURBO3D 5 Normal Compatible
Deadly Arts F3DEX1.XX 5 Slow Compatible
Défi au Tetris Magique S2DEX.XX 5 Normal Compatible
Densha de GO! 64 F3DEX2.XX 5 Normal Compatible. Use 1964
Derby Stallion F3DEX2.XX 5 Normal Compatible. Use Nemu 0.8
Destruction Derby 64 F3DEX1.XX 5 Slow Compatible
Dezaemon 3D F3DEX1.XX 5 Fast Compatible
Diddy Kong Racing RSP SW DKR 5 Fast Compatible
Disney's Donald Duck - Goin' Quackers F3DEX1.XX 5 Normal Compatible. Use "Read every frame" option to see correct transition effects in menu
Disney's Tarzan F3DEX2.XX 5 Normal Compatible. Use PJ64
Donald Duck - Quack Attack F3DEX1.XX 5 Normal Compatible. Use "Read every frame" option to see correct transition effect in menu
Donkey Kong 64 F3DEX2.XX 5 Normal Compatible. Use PJ64
Doom 64 F3DEX1.XX 5 Fast Compatible
Doraemon - Mittsu no Seireiseki F3DEX2.XX 5 Fast Compatible
Doraemon 2 - Hikari no Shinden F3DEX1.XX 5 Fast Compatible
Doraemon 3 - Nobi Dai no Machi SOS! F3DEX1.XX 5 Fast Compatible. Use 1964 
Doubutsu no Mori F3DEX2.XX 5 Normal Compatible
Dr. Mario 64 F3DEX2.XX 5 Normal Compatible
Dual Heroes F3DEX1.XX 5 Normal Compatible
Duck Dodgers Starring Daffy Duck F3DEX2.XX 5 Slow Compatible
Duke Nukem - ZER0 H0UR F3DEX2.XX 5 Fast Compatible
Duke Nukem 64 RSPSW 2.0X 5 Normal Compatible. Minor gfx errors
ECW Hardcore Revolution F3DEX2.XX 5 Fast Compatible
Earthworm Jim 3D F3DEX1.XX 5 Normal Compatible
Eikou no Saint Andrew RSP SW 2.0X 2 Normal Compatible, Use "Read every frame" option (slow) or "Get frame buffer info" with Mupen to have correct background in game
Elmo's Letter Adventure F3DEX1.XX 5 Normal Compatible
Elmo's Number Journey F3DEX1.XX 5 Normal Compatible
Eltale Monsters F3DEX1.XX 5 Fast Compatible
Excitebike 64 F3DEX2.XX 5 Normal Compatible
Extreme-G F3DEX1.XX 5 Normal Compatible. Minor gfx errors 
Extreme-G XG2 F3DEX2.XX 5 Normal Compatible
F-1 Pole Position 64 F3DEX1.XX 5 Fast Compatible. Use "Read every frame" option (slow) or "Get frame buffer info" with Mupen to have correct menu
F-1 World Grand Prix F3DEX1.XX 5 Normal Compatible
F-1 World Grand Prix II F3DEX2.XX 5 Normal Compatible
F-Zero X F3DEX2.XX 5 Normal Compatible
F1 Racing Championship F3DEX2.XX 5 Normal Compatible. Use Mupen
FIFA - Road to World Cup 98 RSP SW 2.0X 5 Slow Compatible
FIFA 99 F3DEX1.XX 5 Normal Compatible
FIFA Soccer 64 RSP SW 2.0X 5 Normal Compatible. Use 1964
Famista 64 F3DEX2.XX 5 Normal Compatible. Use "Read every frame" option (slow) or "Get frame buffer info" with Mupen to have ground in game
Fighter Destiny 2 F3DEX2.XX 5 Fast Compatible
Fighter's Destiny F3DEX1.XX 5 Fast Compatible
Fighting Cup F3DEX1.XX 5 Fast Compatible
Fighting Force 64 F3DEX1.XX 5 Normal Compatible
Fire Electric Pen F3DEX1.XX 5 Normal Compatible
Flying Dragon F3DEX1.XX 5 Normal Compatible. Minor gfx errors
Forsaken 64 F3DEX1.XX 5 Fast Compatible
Frogger 2 (Alpha) F3DEX2.XX 5 Fast Compatible
FoxSportsCollege Hoops ‘99 F3DEX2.XX 5 Normal Compatible
Fushigi no Dungeon - Fuurai no Shiren 2 F3DEX2.XX 5 Normal Compatible. Use "Read every frame" option (slow) or "Get frame buffer info" with Mupen to have backgrounds in menus 
G.A.S.P! Fighter's NEXTream F3DEX2.XX 5 Normal Compatible. Use (J) version or use Mupen
GT 64 - Championship Edition F3DEX1.XX 5 Normal Compatible
Ganbare Goemon - Derudero Douchuu Obake Tenkomori F3DEX2.XX 5 Fast Compatible
Ganbare Goemon - Mononoke Sugoroku F3DEX2.XX 5 Normal Compatible
Ganbare Goemon - Neo Momoyama Bakufu no Odori F3DEX1.XX 5 Normal Compatible
Ganbare Nippon Olympics 2000 F3DEX2.XX 5 Fast Compatible
Gauntlet Legends F3DEX2.XX 2 Normal Missing gfx. Flickerings. Use PJ64
Getter Love !! Cho Renai Party Game F3DEX2.XX 5 Fast Compatible
Gex 3 - Deep Cover Gecko F3DEX2.XX 5 Fast Compatible
Gex 64 - Enter the Gecko F3DEX1.XX 5 Fast Compatible
Glover F3DEX1.XX 5 Normal Compatible (For (E) version use Mupen)
Goemon's Great Adventure F3DEX2.XX 5 Fast Compatible
Golden Nugget 64 RSP SW 2.0X 5 Fast Compatible. Use 1964 or Mupen
GoldenEye 007 RSP SW 2.0G 5 Slow Compatible
HVS Adventure Racing F3DEX2.XX 5 Normal Compatible. Use PJ64 Audio Fix Edition
Hamster Monogatari 64 S2DEX.XX 5 Normal Compatible
Hanafuda 64 - Tenshi no Yakusoku F3DEX2.XX 5 Normal Compatible. Use 1964
Harukanaru Augusta Masters 98 F3DEX1.XX 5 Normal Compatible
Harvest Moon 64 F3DEX2.XX 5 Fast Compatible
Heiwa Pachinko World 64 F3DEX2.XX 3 Normal Gfx errors
Hercules - The Legendary Journeys F3DEX2.XX 5 Normal Compatible. Minor gfx errors
Hexen F3DEX1.XX 5 Normal Compatible. Use "Read every frame" option (slow) to see texts at objectives screen
Hey You, Pikachu! F3DEX2.XX 3 Normal Gfx errors (needs voice pak)
Hiryuu no Ken Twin F3DEX1.XX 5 Normal Compatible. Minor gfx errors
Holy Magic Century F3DEX1.XX 5 Fast Compatible
Hoshi no Kirby 64 F3DEX2.XX 5 Normal Compatible. Use Mupen for correct status bar
Hot Wheels Turbo Racing F3DEX2.XX 5 Slow Compatible
Human Grand Prix - New Generation F3DEX1.XX 5 Normal Compatible. Use "Read every frame" option (slow) or "Get frame buffer info" with Mupen to have correct menu
Hybrid Heaven F3DEX2.XX 5 Normal Compatible
Hydro Thunder F3DEX2.XX 5 Normal Compatible. Use PJ64
Ide Yosuke no Mahjong Juku F3DEX1.XX 5 Normal  Compatible. Use Nemu 0.8 (disable audio HLE)
Iggy's Reckin' Balls F3DEX1.XX 5 Normal Compatible
Iggy-kun no Bura Bura Poyon F3DEX1.XX 5 Normal Compatible
In-Fisherman Bass Hunter 64 F3DEX2.XX 5 Normal Compatible
Indiana Jones and the Infernal Machine ? 0 ? Unsupported. Microcode not implemented
Indy Racing 2000 F3DEX2.XX 5 Normal Compatible
International Superstar Soccer '98 F3DEX1.XX 5 Normal Compatible. Use “Read every frame” option to see correct effects after scoring a goal  
International Superstar Soccer 2000 F3DEX2.XX 5 Normal Compatible. Use “Read every frame” option to see correct effects after scoring a goal  
International Superstar Soccer 64 F3DEX1.XX 5 Normal Compatible. Minor gfx errors
International Track &  Field 2000 F3DEX2.XX 5 Normal Compatible
International Track & Field Summer Games F3DEX2.XX 5 Normal Compatible
J. League Dynamite Soccer 64 F3DEX1.XX 5 Normal Compatible
J. League Eleven Beat 1997 F3DEX1.XX 5 Normal Compatible
J. League Live 64 F3DEX1.XX 5 Normal Compatible
J. League Tactics Soccer F3DEX2.XX 5 Normal Compatible
Jangou Simulation Mahjong Do 64 F3DEX1.XX 5 Normal Compatible
Jeopardy! RSP SW 2.0X 5 Normal Compatible
Jeremy McGrath Supercross 2000 F3DEX2.XX 5 Fast Compatible
Jet Force Gemini RSP SW RARE4 5 Normal Compatible
Jikkyou G1 Stable F3DEX2.XX 5 Normal Compatible
Jikkyou J. League 1999 - Perfect Striker 2 F3DEX2.XX 5 Normal Compatible. Use “Read every frame” option to see correct effects after scoring a goal  
Jikkyou J. League Perfect Striker RSP SW 2.0X 5 Normal Compatible. Use “Read every frame” option to see correct effects after scoring a goal  
Jikkyou Powerful Pro Yakyuu - Basic Han 2001 F3DEX2.XX 5 Normal Compatible
Jikkyou Powerful Pro Yakyuu 2000 F3DEX2.XX 5 Normal Compatible
Jikkyou Powerful Pro Yakyuu 4 F3DEX1.XX 5 Normal Compatible
Jikkyou Powerful Pro Yakyuu 5 F3DEX1.XX 5 Normal Compatible
Jikkyou Powerful Pro Yakyuu 6 F3DEX2.XX 5 Normal Compatible
Jikkyou World Cup France '98 RSP SW 2.0X 5 Normal Compatible. Use “Read every frame” option to see correct effects after scoring a goal  
Jikkyou World Soccer 3 RSP SW 2.0X 5 Normal Compatible
Jinsei Game 64 F3DEX2.XX 5 Normal Compatible
John Romero's Daikatana F3DEX2.XX 5 Normal Compatible
Kakutou Denshou - F-Cup Maniax F3DEX2.XX 5 Normal Compatible
Ken Griffey Jr.'s Slugfest F3DEX2.XX 5 Normal Compatible
Killer Instinct Gold RSP SW 2.0X 5 Fast Compatible
King Hill 64 - Extreme Snowboarding F3DEX2.XX 5 Normal Compatible. Minor gfx errors.
Kiratto Kaiketsu! 64 Tanteidan F3DEX1.XX 5 Normal Compatible
Kirby 64 - The Crystal Shards F3DEX2.XX 5 Fast Compatible. Use Mupen for correct status bar
Knife Edge - Nose Gunner F3DEX2.XX 5 Fast Compatible
Knockout Kings 2000 F3DEX2.XX 5 Fast Compatible. Use 1964. Minor gfx errors
Kobe Bryant NBA Courtside F3DEX1.XX 5 Fast Compatible
Kuiki-Uhabi-Suigo RSP SW 2.0X 2 Normal Gfx errors
LEGO Racers F3DEX2.XX 5 Depends Compatible
Last Legion UX ? 0 ? Unsupported. Microcode not implemented
Legend of Zelda, The - Ocarina of Time F3DEX 2.06H 5 *Mostly* Fast Compatible
Legend of Zelda 2, The - Majora's Mask F3DEX2.XX 5 Normal Compatible
Legend of Zelda, The - Ocarina of Time - Master Quest F3DEX 2.06H 5 *Mostly* Fast Compatible
Les Razmoket - La Chasse aux Trésors F3DEX2.XX 5 Normal Compatible
Let's Smash Tennis F3DEX1.XX 5 Normal Compatible
Lode Runner 3-D F3DEX2.XX 5 Normal Compatible
Looney Tunes - Duck Dodgers F3DEX2.XX 5 Slow Compatible
Lylat Wars F3DEX1.XX 5 Fast Compatible
MRC - Multi Racing Championship F3DEX1.XX 5 Fast Compatible
Mace - The Dark Age F3DEX1.XX 5 Normal Compatible.
Madden Football 64 F3DEX1.XX 5 Slow Compatible
Madden NFL 2000 F3DEX1.XX 5 Slow Compatible
Madden NFL 2001 F3DEX1.XX 5 Slow Compatible
Madden NFL 2002 F3DEX1.XX 5 Normal Compatible
Madden NFL 99 F3DEX1.XX 5 Normal Compatible
Magical Tetris Challenge F3DEX1.XX 5 Normal Compatible
Mahjong 64 RSP SW 2.0X 5 Normal Compatible
Mahjong Hourouki Classic RSP SW 2.0X 5 Normal Compatible
Mahjong Master RSP SW 2.0X 5 Normal Compatible. Minors gfx errors
Major League Baseball Featuring Ken Griffey Jr. F3DEX1.XX 3 Normal Gfx errors
Mario Golf F3DEX2.XX 5 Normal Compatible
Mario Kart 64 F3DEX1.XX 5 Fast Compatible. Use “Read every frame” option (slow) or use "Get frame buffer info" with Mupen to see correct billboards
Mario Party F3DEX2.XX 5 Fast Compatible
Mario Party 2 F3DEX2.XX 5 Fast Compatible
Mario Party 3 F3DEX2.XX 5 Fast Compatible
Mario Story F3DEX2.XX 5 Normal Compatible
Mario Tennis F3DEX2.XX 4 Unstable Various gfx errors.
Mario No Photopie ? 0 ? Unsupported
Mega Man 64 F3DEX2.XX 5 Fast Compatible
Mia Hamm Soccer ZSortp 0.33 5 Fast Compatible. Minors gfx errors
Michael Owens WLS 2000 ZSortp 0.33 5 Fast Compatible. Minors gfx errors
Mickey no Racing Challenge USA RSP SW RARE4 5 Fast Compatible
Mickey's Speedway USA RSP SW RARE4 5 Fast Compatible
Micro Machines 64 Turbo F3DEX1.XX 5 Fast Compatible
Midway's Greatest Arcade Hits Volume 1 RSP SW 2.0X 3 Normal Only few games are fully playable
Mike Piazza's Strike Zone F3DEX1.XX 5 Fast Compatible
Milo's Astro Lanes F3DEX1.XX 5 Normal Compatible
Mischief Makers RSP SW 2.0X 5 Normal Compatible
Mission Impossible F3DEX1.XX 5 Normal Compatible
Monaco Grand Prix F3DEX2.XX 5 Normal Compatible. Use Mupen64
Monaco Grand Prix - Racing Simulation 2 F3DEX2.XX 5 Normal Compatible. Use 1964
Monopoly F3DEX2.XX 5 Fast Compatible
Monster Truck Madness 64 F3DEX2.XX 5 Normal Compatible
Morita Shougi 64 RSP SW 2.0X 5 Normal Compatible
Mortal Kombat 4 F3DEX1.XX 5 Scene dependent Compatible
Mortal Kombat Mythologies - Sub-Zero F3DEX1.XX 5 Fast Compatible
Mortal Kombat Trilogy RSP SW 0.2X 5 Fast Compatible
Ms. Pac-Man - Maze Madness F3DEX2.XX 5 Normal Compatible
Mystical Ninja 2 - Starring Goemon  F3DEX1.XX 5 Normal Compatible
Mystical Ninja - Starring Goemon F3DEX1.XX 5 Normal Compatible
NASCAR 99 F3DEX2.XX 5 Normal Compatible
NASCAR 2000 F3DEX2.XX 5 Normal Compatible
NBA Courtside 2 - Featuring Kobe Bryant F3DEX2.XX 5 Normal Compatible
NBA Hangtime RSP SW 2.0X 5 Slow Compatible
NBA In the Zone '98 F3DEX1.XX 5 Fast Compatible
NBA In the Zone '99 F3DEX2.XX 5 Fast Compatible
NBA In the Zone 2 F3DEX2.XX 5 Normal Compatible
NBA In the Zone 2000 F3DEX2.XX 5 Normal Compatible
NBA Jam 2000 F3DEX2.XX 5 Slow Compatible
NBA Jam 99 F3DEX2.XX 5 Normal Compatible
NBA Live 2000 F3DEX2.XX 5 Normal Compatible
NBA Live 99 F3DEX2.XX 5 Normal Compatible
NBA Showtime - NBA on NBC F3DEX2.XX 5 Slow Compatible. Use PJ64
NFL Blitz F3DEX2.XX 5 Fast Compatible
NFL Blitz - Special Edition F3DEX2.XX 5 Fast Compatible
NFL Blitz 2000 F3DEX2.XX 5 Fast Compatible
NFL Blitz 2001 F3DEX2.XX 5 Fast Compatible
NFL Quarterback Club 2000 F3DEX2.XX 5 Normal Compatible. Use Nemu 0.8
NFL Quarterback Club 2001 F3DEX2.XX 5 Normal Compatible. Use Nemu 0.8
NFL Quarterback Club 98 F3DEX1.XX 5 Normal Compatible. Use Mupen
NFL Quarterback Club 99 F3DEX2.XX 5 Normal Compatible. Use Nemu 0.8
NHL 99 F3DEX2.XX 5 Normal Compatible
NHL Blades of Steel '99 F3DEX2.XX 5 Normal Compatible
NHL Breakaway 98 F3DEX1.XX 5 Normal Compatible
NHL Breakaway 99 F3DEX2.XX 5 Normal Compatible
NHL Pro 99 F3DEX2.XX 5 Normal Compatible
Nagano Winter Olympics '98 F3DEX1.XX 5 Normal Compatible
Namco Museum 64 F3DEX1.XX 5 Normal Compatible
Neon Genesis Evangelion F3DEX2.XX 5 Normal Compatible
New Tetris, The F3DEX2.XX 5 Normal Compatible. Use Mupen                                                                                      
Nightmare Creatures F3DEX2.XX 5 Normal Compatible. Use PJ64
Nintama Rantarou Gallery 64 S2DEX.XX 5 Slow Compatible
Nintendo All-Star! Dairantou Smash Brothers F3DEX2.XX 5 Normal Compatible
Nuclear Strike 64 F3DEX2.XX 5 Normal Compatible
Nushi Zuri 64 F3DEX1.XX 5 Normal Compatible. Use “Read every frame” option (slow) or use "Get frame buffer info" with Mupen to have backgrounds in game
Nushi Zuri 64 - Shiokaze ni Notte F3DEX2.XX 2 Normal Missing gfx in game
O.D.T F3DEX2.XX 5 Normal Compatible
Off Road Challenge F3DEX1.XX 5 Normal Compatible
Ogre Battle 64 - Person of Lordly Caliber F3DEX2.XX 5 Normal Compatible. Use PJ64 or 1964 0.8.5 (Win9X users must use 1964 0.8.5 or Nemu 0.8, to get backgrounds). Use "Read every frame" option to see screen transition effects (slow)
Olympic Hockey Nagano '98 F3DEX1.XX 5 Normal Compatible
Onegai Monster F3DEX2.XX 5 Normal Compatible
Operation WinBack F3DEX2.XX 5 Fast Compatible, but a gray square sometimes appear on the screen. Missing sky
PD Ultraman Battle Collection 64 F3DEX2.XX 5 Normal Compatible
PGA European Tour F3DEX2.XX 5 Normal Compatible. Minor gfx errors
Pachinko 365 Nichi RSP SW 2.0X 2 Normal Compatible
Paper Mario F3DEX2.XX 5 Fast Compatible. Minor gfx errors
Paperboy F3DEX2.XX 5 Normal Compatible
Parlor! Pro 64 Pachinko Jikki Simulation Game S2DEX.XX 5 Normal Compatible
Penny Racers F3DEX1.XX 5 Fast Compatible
Perfect Dark RSP SW PD 5 Slow Compatible. Use "Read every frame" (slow) or "Get frame buffer info" with Mupen to get correct pause menu in game
Pikachu Genki Dechu F3DEX2.XX 3 Normal Gfx errors (needs voice pak)
Pilot Wings F3DEX1.XX 5 Fast Compatible
Pocket Monsters Snap F3DEX2.XX 5 Normal Compatible. Use "Read every frame" option when selecting shots for professor Oak
Pokemon Puzzle League S2DEX.XX 5 Normal Compatible
Pokemon Snap F3DEX2.XX 5 Normal Compatible. Use "Read every frame" option when selecting shots for professor Oak
Pokemon Stadium F3DEX2.XX 5 Fast Compatible
Pokemon Stadium 2 F3DEX2.XX 5 Normal Compatible
Polaris SnoCross F3DEX2.XX 5 Normal Compatible
Power League Baseball 64 F3DEX2.XX 4 Normal Compatible
Power Rangers - Lightspeed Rescue F3DEX2.XX 5 Normal Compatible
Powerpuff Girls, The - Chemical X-traction F3DEX1.XX 5 Normal Compatible
Premier Manager 64 F3DEX2.XX 5 Fast Compatible
Pro Mahjong Kiwame 64 RSP SW 2.0X 5 Normal Compatible
Pro Majhong Tsuwamono 64 S2DEX.XX 5 Slow Compatible
Puyo Puyo 4 - Puyo Puyo Party S2DEX.XX 5 Normal Compatible
Puyo Puyo Sun 64 RSP SW 2.0X 5 Normal Compatible
Puzzle Bobble 64 F3DEX1.XX 5 Normal Compatible
Quake 64 F3DEX1.XX 5 Fast Compatible
Quake II F3DEX1.XX 5 Normal Compatible, Use "Read every frame" (slow) or "Get frame buffer info" with Mupen to get correct pause menu in game
Quest 64 F3DEX1.XX 5 Fast Compatible
RR64 - Ridge Racer 64 F3DEX2.XX 5 Fast Compatible. Pause menu doesn't work correctly with Voodoo 1-3
RTL World League Soccer 2000 ZSortp 0.33 5 Fast Compatible. Minor gfx errors
Racing Simulation 2 F3DEX2.XX 5 Normal Compatible. Use 1964. Minor gfx errors
Rakuga Kids F3DEX2.XX 5 Normal Compatible
Rally '99 F3DEX2.XX 5 Normal Compatible
Rally Challenge 2000 F3DEX2.XX 5 Normal Compatible
Rampage - World Tour F3DEX1.XX 5 Fast Compatible
Rampage 2 - Universal Tour F3DEX1.XX 5 Normal Compatible
Rat Attack F3DEX1.XX 5 Fast Compatible
Rayman 2 - The Great Escape F3DEX1.XX 5 Normal Compatible. Use "Read every frame" option to see correct transition effects in game
Razor Freestyle Scooter F3DEX2.XX 5 Normal Compatible
Re-Volt F3DEX2.XX 5 Fast Compatible. Use PJ64
Ready 2 Rumble Boxing F3DEX1.XX 5 Fast Compatible
Ready 2 Rumble Boxing Round 2 F3DEX1.XX 5 Fast Compatible
Resident Evil 2 F3DEX2.XX 5 Normal Compatible
Road Rash 64  F3DEX2.XX 5 Normal Compatible
Roadsters F3DEX2.XX 5 Normal Compatible
Robotech - Crystal Dreams (Beta) F3DEX2.XX 5 Normal Compatible
Robot Ponkottsu 64 - Caramel of the 7 Seas F3DEX2.XX 5 Normal Compatible
Robotron 64 F3DEX1.XX 5 Fast Compatible
Rocket - Robot on Wheels F3DEX2.XX 5 Fast Compatible
Rockman Dash F3DEX2.XX 5 Fast Compatible
Rugrats - Scavenger Hunt F3DEX2.XX 5 Fast Compatible
Rugrats - Treasure Hunt F3DEX2.XX 5 Fast Compatible
Rugrats in Paris - The Movie F3DEX2.XX 5 Fast Compatible
Rush 2 - Extreme Racing USA  F3DEX2.XX 5 Normal Compatible
S.C.A.R.S. F3DEX2.XX 5 Fast Compatible
SD Hiryuu no Ken Densetsu F3DEX1.XX 5 Normal Compatible. Minor gfx errors
San Francisco Rush - Extreme Racing F3DEX1.XX 5 Normal Compatible
San Francisco Rush 2049 F3DEX2.XX 5 Normal Compatible
Scooby-Doo - Classic Creep Capers F3DEX2.XX 5 Normal Compatible. Sky in game doesn't work correctly with Voodoo 1-3
Shadow Man  F3DEX2.XX 5 Normal Compatible. Use "Read every frame" option (slow) or "Get frame buffer info" with Mupen to have correct pause menu in game
Shadowgate 64 - Trials of the Four Towers F3DEX2.XX 5 Fast Compatible
Sim City 2000 S2DEX.XX 5 Normal Compatible
Snow Speeders F3DEX2.XX 5 Normal Compatible
Snowboard Kids F3DEX1.XX 5 Normal Compatible
Snowboard Kids 2 F3DEX2.XX 5 Normal Compatible
Sonic Wings Assault RSP SW 2.0X 5 Slow Compatible
South Park F3DEX2.XX 5 Fast Compatible
SouthPark - Chef's Luv Shack F3DEX2.XX 5 Fast Compatible
South Park Rally F3DEX2.XX 5 Fast Compatible
Space Dynamites TURBO3D 5 Normal Compatible
Space Invaders  F3DEX2.XX 5 Fast Compatible
Space Station Silicon Valley F3DEX1.XX 5 Normal Compatible
Spider-Man  F3DEX2.XX 5 Fast Compatible
Star Fox 64 F3DEX1.XX 5 Fast Compatible
Star Soldier - Vanishing Earth F3DEX1.XX 5 Fast Compatible
Star Twins RSP SW RARE4 5 Normal Compatible. Use "Get frame buffer info" option with Mupen or use “Read every frame” option (slow) to see correct TV
Star Wars - Rogue Squadron ? 0 ? Unsupported. Microcode not implemented
Star Wars - Shadows of the Empire RSP SW 2.0D EXT 5 Normal Compatible
Star Wars Episode I - Battle for Naboo ? 0 ? Unsupported. Microcode not implemented
Star Wars Episode I - Racer F3DEX2.XX 5 Normal Compatible
StarCraft 64  F3DEX2.XX 5 Normal Compatible
Starshot - Space Circus Fever F3DEX2.XX 5 Normal Compatible
Stunt Racer 64 ? 0 ? Unsupported
Super B-Daman - Battle Phoenix 64 F3DEX1.XX 5 Fast Compatible
Super Bowling 64 F3DEX2.XX 3 Fast Gfx errors
Super Mario 64  RSP SW 2.0X 5 Fast Compatible
Super Robot Spirits F3DEX1.XX 5 Normal Compatible
Super Robot Taisen 64 RSP SW 2.0X 5 Normal Compatible
Super Smash Bros. F3DEX2.XX 5 Normal Compatible
Super Speed Race 64 F3DEX1.XX 5 Fast Compatible
Supercross 2000 F3DEX2.XX 5 Normal Compatible
Superman  F3DEX1.XX 5 Normal Compatible
Susume! taisen puzzle dama toukon ! Marumata Chou S2DEX.XX 5 Normal Compatible
Taz Express RSP SW 2.0X 5 Normal Compatible. Use Mupen 0.4 
Telefoot Soccer 2000 ZSortp 0.33 5 Normal Compatible. Minor gfx errors
Tetris 64 RSP SW 2.0X 5 Normal Compatible
Tetrisphere RSP SW 2.0X 5 Fast Compatible
Tigger's Honey Hunt F3DEX2.XX 5 Normal Compatible
Tom Clancy's Rainbow Six F3DEX2.XX 5 Normal Compatible
Tom and Jerry in Fists of Furry F3DEX1.XX 5 Normal Compatible
Tonic Trouble F3DEX1.XX 5 Normal Compatible. Use "Read every frame" option to see correct transition effects for pause menu in game
Tony Hawk's Pro Skater F3DEX2.XX 5 Fast Compatible. Use PJ64
Tony Hawk's Pro Skater 2 F3DEX2.XX 5 Fast Compatible
Tony Hawk's Pro Skater 3 F3DEX2.XX 5 Fast Compatible
Toon Panic F3DEX2.XX 5 Fast Compatible
Top Gear Hyper-Bike F3DEX2.XX 2 Normal Major gfx errors. Use Mupen
Top Gear Overdrive F3DEX2.XX 4 Normal Gfx errors. Use Mupen
Top Gear Rally F3DEX1.XX 5 Normal Compatible
Top Gear Rally 2 F3DEX2.XX 5 Normal Compatible
Toukon Roads ? 0 ? Unsupported. Microcode not implemented
Toukon Roads 2 ? 0 ? Unsupported. Microcode not implemented
Toy Story 2  F3DEX1.XX 5 Normal Compatible
Transformers - Beast Wars Metals 64 F3DEX2.XX 5 Fast Compatible
Transformers - Beast Wars Transmetal F3DEX2.XX 5 Fast Compatible
Triple Play 2000  F3DEX2.XX 5 Normal Compatible. Use "Get frame buffer info" option with Mupen or use "Read every frame" option to see correct TV monitors (slow)
Tsumi to Batsu - Chikyuu no Keishousha F3DEX2.XX 5 Normal Compatible
Turok - Dinosaur Hunter F3DEX1.XX 5 Fast Compatible
Turok - Rage Wars F3DEX2.XX 5 Normal Compatible
Turok 2 - Seeds of Evil F3DEX2.XX 5 Slow Compatible
Turok 3 - Shadow of Oblivion F3DEX2.XX 5 Slow Compatible
Twisted Edge Extreme Snowboarding F3DEX2.XX 5 Slow Compatible. Minor gfx errors
V-Rally Edition 99 F3DEX2.XX 5 Slow Compatible. Minor gfx errors
Vigilante 8  F3DEX2.XX 2 Slow Many gfx errors
Vigilante 8 - 2nd Offense F3DEX2.XX 2 Slow Many gfx errors
Virtual Chess 64 F3DEX1.XX 5 Slow Compatible
Virtual Pool 64 F3DEX1.XX 5 Fast Compatible
Virtual Pro Wrestling 2  - Oudou Keishou F3DEX2.XX 5 Normal Compatible. Use "Read every frame" option to see motion blur effects during intro
Virtual Pro Wrestling 64 F3DEX1.XX 5 Normal Compatible
WCW Backstage Assault F3DEX2.XX 5 Normal Compatible
WCW Mayhem F3DEX2.XX 5 Normal Compatible
WCW Nitro F3DEX1.XX 5 Normal Compatible
WCW vs. nWo - World Tour F3DEX1.XX 5 Normal Compatible
WCW-nWo Revenge F3DEX2.XX 5 Normal Compatible
WWF - War Zone F3DEX2.XX 5 Fast Compatible. Use "Get frame buffer info" option with Mupen or use "Read every frame" option to see correct TV monitors (slow)
WWF Attitude F3DEX2.XX 5 Fast Compatible
WWF No Mercy F3DEX2.XX 5 Fast Compatible
WWF WrestleMania 2000 F3DEX2.XX 5 Normal Compatible. Use "Read every frame" option to see motion blur effects during intro
Waialae Country Club - True Golf Classics F3DEX1.XX 5 Normal Compatible. Minor gfx errors
War Gods RSP SW 2.0X 5 Fast Compatible
Wave Race 64 RSP SW 2.0D EXT 5 Fast Compatible
Wave Race 64 Shindou Edition F3DEX1.XX 5 Normal Compatible
Wayne Gretzky's 3D Hockey '98 F3DEX1.XX 5 Fast Compatible
Wetrix F3DEX1.XX 5 Normal Compatible
Wheel of Fortune RSP SW 2.0X 5 Slow Compatible
Wild Choppers RSP SW 2.0X 5 Normal Compatible
WinBack - Covert Operations F3DEX2.XX 5 Fast Compatible, but a gray square sometimes appear on the screen. Missing sky
Wipeout 64 F3DEX1.XX 5 Fast Compatible
Wonder Project J2 RSP SW 2.0X 5 Normal Compatible
World Cup 98 F3DEX1.XX 5 Normal Compatible
World Driver Championship ? 0 ? Unsupported
Worms - Armageddon F3DEX2.XX 5 Normal Compatible
Xena Warrior Princess - Talisman of Fate F3DEX2.XX 5 Fast Compatible
Yakouchuu II - Satsujun Kouru F3DEX2.XX 4 Normal Use Nemu 0.8 (disable audio HLE). No movies
Yoshi's Story S2DEX.XX 5 Normal Compatible. Minor texture errors. Use "Read every frame" option to see transition effects 
Yuke Yuke!! Trouble Makers RSP SW 2.0X 5 Normal Compatible
Zelda no Densetsu 2 - Mujura no Kamen F3DEX2.XX 5 Normal Compatible
Zelda no Densetsu - Toki no Ocarina F3DEX 2.06H 5 *Mostly* Fast Compatible
Zool - Majou Tsukai Densetsu F3DEX1.XX 5 Normal Compatible
   
glide2gl/src/Glide64/Help/Glide64 Known Issues.html000664 001750 001750 00000136651 12655644434 022676 0ustar00sergiosergio000000 000000 Glide64 Known Issues
Current Version: 9.07 (year: 2009, month: 07)
Known issues
Game Description Correct with 
 following plugin:
64 de Hakken!! Tamagotchi Minna de Tamagotchi World Missing or wrong textures everywhere Ziggy LLE
All-Star Baseball '99 Missing gfx in menu Rice, Jabo
Bio Freaks Missing transition effects during intro None
Blast Corps missing 2d gfx in menu and game; missing noise effects  Jabo software
Command & Conquer Briefing menu error. Intro texture errors. (Intro only )Ziggy LLE
Derby Stallion 64 textures problem during demo Rice
Donkey kong 64 Wide screen doesn t work  
Excitebike 64 sky textures sliced in multiplayer to check
Extreme-G Wrong title: the blue square must not appear (coverage?) NONE
FX-Zero:  Wrong or missing (fb ?) effects in menu Jabo Software
Gauntlet Legends 64 Missing status bar, flickering (fb+core issue ?) NONE
Gex 3, Deep Cover Gecko Bad water NONE
Glover strange blue line in sky sometimes Ziggy LLE
Harvest Moon 64 (Bokujo Monogatari 2) Problem with shadows Ziggy LLE
Hey You, Pikachu Missing gfx Rice
Jet force gemini Coronas behave slighly incorrectly Wonder++
Kuiki-Uhabi-Suigo Missing jigsaw (microcode issue ? ) Ziggy LLE
Mahjong Master Pictures of the character are wrong. Menu doesn't show the japanese letters Rice/SP8
Major League Baseball Featuring Ken Griffey Jr Wrong textures in game Jabo soft/Rice
Mario Tennis Gfx errors to check
Mia Hamm Soccer/Michael Owens WLS/Telefoot/RTL World League Soccer Missing title; wrong transition effect None
Midway's Greatest Arcade Hits Volume 1 gfx errors in lot of mini games to check
Mission Impossible missing dithering color alpha effect in menu NONE
Monster Truck Madness 64 Letters have some very small gfx issue to check
Nascar 2000 Split screen in multiplayer doesn't work correctly. Jabo Software
Nushi Zuri 64 - Shiokaze ni Notte Missing gfx in game (blender ?) Direct64, LLE
Operation WinBack A gray square sometimes appear on the screen; missing sky Ziggy LLE
OgreBattle 64 the shadows in menu are wrong NONE
Parlor! Pro 64 Pachinko Jikki Simulation Game small texture issue in game Rice
PGA European Tour colors seems wrong / jauge doesn t work Jabo
Pikachu Genki Dech Missing and stretched textures Rice
Pilotwings Wrong shadows (coverage?) None
Space Silicon Valley Missing on TV dithering color alpha (noise) NONE
Starfox 64 Missing dithering color alpha (noise) at logo NONE
Super Bowling 64 In game, the two part of the screen is mixed Rice (hack)
Super Robot Spirit In menu, just before beginning a new game there is a problem in this screen: it's seems that there is only half of the screen for the flames ( checked on real system) Rice
Super Speed Race 64 Sliced textures in menu Rice
Top Gear Hyper-Bike wrong texture, problem of framebuffer effect NONE
Top Gear Overdrive Resolution change causes gfx glitches in menu NONE
Turok 2 Flashlight doesn't work Ziggy LLE
Twine title screen during demo is wrong; shadow at entrance of 1st level should be displayed Jabo
Twisted Edge Extreme Snowboarding wrong background in game to check
Vigilante 8 No menus, missing textures and many gfx errors Jabo software
Vigilante 8 - 2nd Offense No menus, depth problem, missing textures and many gfx errors Jabo software
Wipeout 64 wrong sky in some particular places, ok with jabo Jabo
Yoshi's Story cut textures Jabo
 
Framebuffer issues
NOTE: HWFBE or fb notification with Mupen is correct solution in terms of speed and quality. Only when REFB is needed or when the fb effect
is not emulated that it is considered as an issue.
Game Description
Akumajou Dracula Makushiroku: Real Action Adventure REFB needed to get motion blur in intro and correct gfx in menu Jabo
All-Star Baseball 2000, 2001 Monitors requires REFB. NONE
Bakushou Jinsei 64 - Mezase Needs REFB to be playable (or background will be missing) (Mupen doesn t handle fb effect correctly=disabled) NONE
Beetle Adventure Racing Unemulated fb effects in menu (scrolling effect); shadows on cars needs REFB Ziggy LLE
Blast Corps wrong depth with shadows with HWFBE to check
Bottom of the 9th needs REFB for correct intro; With HWFBE only one of the 2 of the player heads are displayed in game NONE
Castlevania - Legacy of Darkness REFB needed to get motion blur in intro and correct gfx in menu Jabo
Dobutsu no Mori (Animal Forest) The character menu is uncorrect due to an unhandeld fb effect Direct64
Donkey Kong 64 The zipper screen issue is a framebuffer effects (needs REFB) (Mupen doesn t support this game) NONE
Extreme-G Missing transfer effects in after select the car Direct64
iss98/2000/Jikkyou World Cup France '98/J. League Perfect Striker  Missing fb effect when a goal is scored GLN64 0.41
The New tetris Missing fb effect in menu (partially working with HWBFE) Direct64
Micromachines 64 Missing shadows for some elements of the environment Jabo software
Ogre Battle 64 - Person of Lordly Caliber Screen transition effects requires REFB. to check
Tonic Trouble texts for the screen just before going in game needs REFB (side effect of cpu gfx effect ?) NONE
WWF WrestleMania 2000 /Virtual Pro Wrestling 2 REFB is needed to get motion blur in intro Ziggy LLE
Yoshi's Story  Transition "page" level needs REFB to check
 
Pending investigation
Game Description
F1 Pole position 64 Wrong use of dithering alpha for texts ?
 
Non-working games
Game Description
Indiana Jones and the Infernal Machine Unimplemented microcode Jabo/ Ziggy LLE
Last Legion U Unimplemented microcode Jabo/ Ziggy LLE
Star Wars - Rogue Squadron Unimplemented microcode Jabo/ Ziggy LLE
Star Wars Episode I - Battle for Naboo Unimplemented microcode Jabo/ Ziggy LLE
Toukon Road - Brave Spirits Unimplemented microcode Jabo/ Ziggy LLE
Toukon Roads - The Next Generation Unimplemented microcode Jabo/ Ziggy LLE
 
Emu issues
Game Description
Ai Shougi 3 Textures are completely distorted (use 1964!)
Banjo Tooie Random crashes
Dobutsu no Mori NES games crash emulation
Hoshi no Kirby 64 Minor gfx errors with the status bar (use Mupen!)
Kirby 64 - The Crystal Shards Minor gfx errors with the status bar (use Mupen!)
Mario No Photopie Special card issues
NBA Courtside 2 - Featuring Kobe Bryant     CPU gfx effect issue >> Missing intro. (TIP: set "Frame Buffer R/W: Yes" with 1964 : got some gfx but broken)
Yakouchuu II - Satsujun Kouru:  CPU gfx effect issue >> Missing movies
 
Wrapper issues
Game Description
Depth issue when using HWFBE, mostly with fbo:International Track and Field Summer Games, NFL98 TV screen (?), others  
 
Unknown issues
Game Description
Stunt Racer 64 Microcode issue and core issues
World Driver Championship Microcode issue and core issues
Credits :) Current list's maintainer: Olivieryuyu
A BIG thanks to:
Raziel64, MasterPhW, Noxious Ninja, TRS, Straight, Knuckles, Flash, Milen, Jelta, Federelli, Clements, Doomulation, etc.
They are issues' hunters :D (so am i, hehe)
And a Very special thanks to:
Dave2001 for starting, Gugaman and Gonetz (^_^ He is tha man! ^_^ Thks a lot pal :) ) for enhancing and fixing
the best video plugin and showing the true power of 3DFX and Glide. And to the N64 emulators' authors & betatesters!
Hacktarux, Mulord and Ziggy for making the best Glide Wrapper out there.
gles2n64/src/ShaderCombiner.c000664 001750 001750 00000067532 12655644434 017120 0ustar00sergiosergio000000 000000 #include #include #include "OpenGL.h" #include "ShaderCombiner.h" #include "Common.h" #include "Textures.h" #include "Config.h" //(sa - sb) * m + a static const u32 saRGBExpanded[] = { COMBINED, TEXEL0, TEXEL1, PRIMITIVE, SHADE, ENVIRONMENT, ONE, NOISE, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO }; static const u32 sbRGBExpanded[] = { COMBINED, TEXEL0, TEXEL1, PRIMITIVE, SHADE, ENVIRONMENT, CENTER, K4, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO }; static const u32 mRGBExpanded[] = { COMBINED, TEXEL0, TEXEL1, PRIMITIVE, SHADE, ENVIRONMENT, SCALE, COMBINED_ALPHA, TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA, SHADE_ALPHA, ENV_ALPHA, LOD_FRACTION, PRIM_LOD_FRAC, K5, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO }; static const u32 aRGBExpanded[] = { COMBINED, TEXEL0, TEXEL1, PRIMITIVE, SHADE, ENVIRONMENT, ONE, ZERO }; static const u32 saAExpanded[] = { COMBINED, TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA, SHADE_ALPHA, ENV_ALPHA, ONE, ZERO }; static const u32 sbAExpanded[] = { COMBINED, TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA, SHADE_ALPHA, ENV_ALPHA, ONE, ZERO }; static const u32 mAExpanded[] = { LOD_FRACTION, TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA, SHADE_ALPHA, ENV_ALPHA, PRIM_LOD_FRAC, ZERO, }; static const u32 aAExpanded[] = { COMBINED, TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA, SHADE_ALPHA, ENV_ALPHA, ONE, ZERO }; ShaderProgram *scProgramRoot = NULL; ShaderProgram *scProgramCurrent = NULL; int scProgramChanged = 0; int scProgramCount = 0; GLint _vertex_shader = 0; const char *_frag_header = " \n" #if defined(__LIBRETRO__) && !defined(HAVE_OPENGLES2) // Desktop GL fix "#version 120 \n" "#define highp \n" "#define lowp \n" "#define mediump \n" #endif "uniform sampler2D uTex0; \n"\ "uniform sampler2D uTex1; \n"\ "uniform sampler2D uTexNoise; \n"\ "uniform lowp vec4 uEnvColor; \n"\ "uniform lowp vec4 uPrimColor; \n"\ "uniform lowp vec4 uFogColor; \n"\ "uniform highp float uAlphaRef; \n"\ "uniform lowp float uPrimLODFrac; \n"\ "uniform lowp float uK4; \n"\ "uniform lowp float uK5; \n"\ " \n"\ "varying lowp float vFactor; \n"\ "varying lowp vec4 vShadeColor; \n"\ "varying mediump vec2 vTexCoord0; \n"\ "varying mediump vec2 vTexCoord1; \n"\ " \n"\ "void main() \n"\ "{ \n"\ "lowp vec4 lFragColor; \n"; const char *_vert = " \n" #if defined(__LIBRETRO__) && !defined(HAVE_OPENGLES2) // Desktop GL fix "#version 120 \n" "#define highp \n" "#define lowp \n" "#define mediump \n" #endif "attribute highp vec4 aPosition; \n"\ "attribute lowp vec4 aColor; \n"\ "attribute highp vec2 aTexCoord0; \n"\ "attribute highp vec2 aTexCoord1; \n"\ " \n"\ "uniform bool uEnableFog; \n"\ "uniform float uFogScale, uFogOffset; \n"\ "uniform float uRenderState; \n"\ " \n"\ "uniform mediump vec2 uTexScale; \n"\ "uniform mediump vec2 uTexOffset[2]; \n"\ "uniform mediump vec2 uCacheShiftScale[2]; \n"\ "uniform mediump vec2 uCacheScale[2]; \n"\ "uniform mediump vec2 uCacheOffset[2]; \n"\ " \n"\ "varying lowp float vFactor; \n"\ "varying lowp vec4 vShadeColor; \n"\ "varying mediump vec2 vTexCoord0; \n"\ "varying mediump vec2 vTexCoord1; \n"\ " \n"\ "void main() \n"\ "{ \n"\ "gl_Position = aPosition; \n"\ "vShadeColor = aColor; \n"\ " \n"\ "if (uRenderState == 1.0) \n"\ "{ \n"\ "vTexCoord0 = (aTexCoord0 * (uTexScale[0] * \n"\ " uCacheShiftScale[0]) + (uCacheOffset[0] - \n"\ " uTexOffset[0])) * uCacheScale[0]; \n"\ "vTexCoord1 = (aTexCoord0 * (uTexScale[1] * \n"\ " uCacheShiftScale[1]) + (uCacheOffset[1] - \n"\ " uTexOffset[1])) * uCacheScale[1]; \n"\ "} \n"\ "else \n"\ "{ \n"\ "vTexCoord0 = aTexCoord0; \n"\ "vTexCoord1 = aTexCoord1; \n"\ "} \n"\ " \n"; const char * _vertfog = " \n"\ "if (uEnableFog) \n"\ "{ \n"\ "vFactor = max(-1.0, aPosition.z / aPosition.w) \n"\ " * uFogScale + uFogOffset; \n"\ "vFactor = clamp(vFactor, 0.0, 1.0); \n"\ "} \n"; const char * _vertzhack = " \n"\ "if (uRenderState == 1.0) \n"\ "{ \n"\ "gl_Position.z = (gl_Position.z + gl_Position.w*9.0) * 0.1; \n"\ "} \n"; static const char * _color_param_str(int param) { switch(param) { case COMBINED: return "lFragColor.rgb"; case TEXEL0: return "lTex0.rgb"; case TEXEL1: return "lTex1.rgb"; case PRIMITIVE: return "uPrimColor.rgb"; case SHADE: return "vShadeColor.rgb"; case ENVIRONMENT: return "uEnvColor.rgb"; case CENTER: return "vec3(0.0)"; case SCALE: return "vec3(0.0)"; case COMBINED_ALPHA: return "vec3(lFragColor.a)"; case TEXEL0_ALPHA: return "vec3(lTex0.a)"; case TEXEL1_ALPHA: return "vec3(lTex1.a)"; case PRIMITIVE_ALPHA: return "vec3(uPrimColor.a)"; case SHADE_ALPHA: return "vec3(vShadeColor.a)"; case ENV_ALPHA: return "vec3(uEnvColor.a)"; case LOD_FRACTION: return "vec3(0.0)"; case PRIM_LOD_FRAC: return "vec3(uPrimLODFrac)"; case NOISE: return "lNoise.rgb"; case K4: return "vec3(uK4)"; case K5: return "vec3(uK5)"; case ONE: return "vec3(1.0)"; case ZERO: return "vec3(0.0)"; default: return "vec3(0.0)"; } } static const char * _alpha_param_str(int param) { switch(param) { case COMBINED: return "lFragColor.a"; case TEXEL0: return "lTex0.a"; case TEXEL1: return "lTex1.a"; case PRIMITIVE: return "uPrimColor.a"; case SHADE: return "vShadeColor.a"; case ENVIRONMENT: return "uEnvColor.a"; case CENTER: return "0.0"; case SCALE: return "0.0"; case COMBINED_ALPHA: return "lFragColor.a"; case TEXEL0_ALPHA: return "lTex0.a"; case TEXEL1_ALPHA: return "lTex1.a"; case PRIMITIVE_ALPHA: return "uPrimColor.a"; case SHADE_ALPHA: return "vShadeColor.a"; case ENV_ALPHA: return "uEnvColor.a"; case LOD_FRACTION: return "0.0"; case PRIM_LOD_FRAC: return "uPrimLODFrac"; case NOISE: return "lNoise.a"; case K4: return "uK4"; case K5: return "uK5"; case ONE: return "1.0"; case ZERO: return "0.0"; default: return "0.0"; } } static bool mux_find(DecodedMux *dmux, int index, int src) { if (dmux->decode[index].sa == src) return true; if (dmux->decode[index].sb == src) return true; if (dmux->decode[index].m == src) return true; if (dmux->decode[index].a == src) return true; return false; } static bool mux_swap(DecodedMux *dmux, int cycle, int src0, int src1) { int i, r; r = false; for(i = 0; i < 2; i++) { int ii = (cycle == 0) ? i : (2+i); { if (dmux->decode[ii].sa == src0) {dmux->decode[ii].sa = src1; r=true;} else if (dmux->decode[ii].sa == src1) {dmux->decode[ii].sa = src0; r=true;} if (dmux->decode[ii].sb == src0) {dmux->decode[ii].sb = src1; r=true;} else if (dmux->decode[ii].sb == src1) {dmux->decode[ii].sb = src0; r=true;} if (dmux->decode[ii].m == src0) {dmux->decode[ii].m = src1; r=true;} else if (dmux->decode[ii].m == src1) {dmux->decode[ii].m = src0; r=true;} if (dmux->decode[ii].a == src0) {dmux->decode[ii].a = src1; r=true;} else if (dmux->decode[ii].a == src1) {dmux->decode[ii].a = src0; r=true;} } } return r; } static bool mux_replace(DecodedMux *dmux, int cycle, int src, int dest) { int i, r; r = false; for(i = 0; i < 2; i++) { int ii = (cycle == 0) ? i : (2+i); if (dmux->decode[ii].sa == src) {dmux->decode[ii].sa = dest; r=true;} if (dmux->decode[ii].sb == src) {dmux->decode[ii].sb = dest; r=true;} if (dmux->decode[ii].m == src) {dmux->decode[ii].m = dest; r=true;} if (dmux->decode[ii].a == src) {dmux->decode[ii].a = dest; r=true;} } return r; } static void *mux_new(u64 dmux, bool cycle2) { int i; DecodedMux *mux = malloc(sizeof(DecodedMux)); mux->combine.mux = dmux; mux->flags = 0; //set to ZERO. for(i = 0; i < 4;i++) { mux->decode[i].sa = ZERO; mux->decode[i].sb = ZERO; mux->decode[i].m = ZERO; mux->decode[i].a = ZERO; } //rgb cycle 0 mux->decode[0].sa = saRGBExpanded[mux->combine.saRGB0]; mux->decode[0].sb = sbRGBExpanded[mux->combine.sbRGB0]; mux->decode[0].m = mRGBExpanded[mux->combine.mRGB0]; mux->decode[0].a = aRGBExpanded[mux->combine.aRGB0]; mux->decode[1].sa = saAExpanded[mux->combine.saA0]; mux->decode[1].sb = sbAExpanded[mux->combine.sbA0]; mux->decode[1].m = mAExpanded[mux->combine.mA0]; mux->decode[1].a = aAExpanded[mux->combine.aA0]; if (cycle2) { //rgb cycle 1 mux->decode[2].sa = saRGBExpanded[mux->combine.saRGB1]; mux->decode[2].sb = sbRGBExpanded[mux->combine.sbRGB1]; mux->decode[2].m = mRGBExpanded[mux->combine.mRGB1]; mux->decode[2].a = aRGBExpanded[mux->combine.aRGB1]; mux->decode[3].sa = saAExpanded[mux->combine.saA1]; mux->decode[3].sb = sbAExpanded[mux->combine.sbA1]; mux->decode[3].m = mAExpanded[mux->combine.mA1]; mux->decode[3].a = aAExpanded[mux->combine.aA1]; //texel 0/1 are swapped in 2nd cycle. mux_swap(mux, 1, TEXEL0, TEXEL1); mux_swap(mux, 1, TEXEL0_ALPHA, TEXEL1_ALPHA); } //simplifying mux: if (mux_replace(mux, G_CYC_1CYCLE, LOD_FRACTION, ZERO) || mux_replace(mux, G_CYC_2CYCLE, LOD_FRACTION, ZERO)) LOG(LOG_VERBOSE, "SC Replacing LOD_FRACTION with ZERO\n"); #if 1 if (mux_replace(mux, G_CYC_1CYCLE, K4, ZERO) || mux_replace(mux, G_CYC_2CYCLE, K4, ZERO)) LOG(LOG_VERBOSE, "SC Replacing K4 with ZERO\n"); if (mux_replace(mux, G_CYC_1CYCLE, K5, ZERO) || mux_replace(mux, G_CYC_2CYCLE, K5, ZERO)) LOG(LOG_VERBOSE, "SC Replacing K5 with ZERO\n"); #endif if (mux_replace(mux, G_CYC_1CYCLE, CENTER, ZERO) || mux_replace(mux, G_CYC_2CYCLE, CENTER, ZERO)) LOG(LOG_VERBOSE, "SC Replacing CENTER with ZERO\n"); if (mux_replace(mux, G_CYC_1CYCLE, SCALE, ZERO) || mux_replace(mux, G_CYC_2CYCLE, SCALE, ZERO)) LOG(LOG_VERBOSE, "SC Replacing SCALE with ZERO\n"); //Combiner has initial value of zero in cycle 0 if (mux_replace(mux, G_CYC_1CYCLE, COMBINED, ZERO)) LOG(LOG_VERBOSE, "SC Setting CYCLE1 COMBINED to ZERO\n"); if (mux_replace(mux, G_CYC_1CYCLE, COMBINED_ALPHA, ZERO)) LOG(LOG_VERBOSE, "SC Setting CYCLE1 COMBINED_ALPHA to ZERO\n"); if (!config.enableNoise) { if (mux_replace(mux, G_CYC_1CYCLE, NOISE, ZERO)) LOG(LOG_VERBOSE, "SC Setting CYCLE1 NOISE to ZERO\n"); if (mux_replace(mux, G_CYC_2CYCLE, NOISE, ZERO)) LOG(LOG_VERBOSE, "SC Setting CYCLE2 NOISE to ZERO\n"); } //mutiplying by zero: (A-B)*0 + C = C for(i = 0 ; i < 4; i++) { if (mux->decode[i].m == ZERO) { mux->decode[i].sa = ZERO; mux->decode[i].sb = ZERO; } } //(A1-B1)*C1 + D1 //(A2-B2)*C2 + D2 //1. ((A1-B1)*C1 + D1 - B2)*C2 + D2 = A1*C1*C2 - B1*C1*C2 + D1*C2 - B2*C2 + D2 //2. (A2 - (A1-B1)*C1 - D1)*C2 + D2 = A2*C2 - A1*C1*C2 + B1*C1*C2 - D1*C2 + D2 //3. (A2 - B2)*((A1-B1)*C1 + D1) + D2 = A2*A1*C1 - A2*B1*C1 + A2*D1 - B2*A1*C1 + B2*B1*C1 - B2*D1 + D2 //4. (A2-B2)*C2 + (A1-B1)*C1 + D1 = A2*C2 - B2*C2 + A1*C1 - B1*C1 + D1 if (cycle2) { if (!mux_find(mux, 2, COMBINED)) mux->flags |= SC_IGNORE_RGB0; if (!(mux_find(mux, 2, COMBINED_ALPHA) || mux_find(mux, 3, COMBINED_ALPHA) || mux_find(mux, 3, COMBINED))) mux->flags |= SC_IGNORE_ALPHA0; if (mux->decode[2].sa == ZERO && mux->decode[2].sb == ZERO && mux->decode[2].m == ZERO && mux->decode[2].a == COMBINED) mux->flags |= SC_IGNORE_RGB1; if (mux->decode[3].sa == ZERO && mux->decode[3].sb == ZERO && mux->decode[3].m == ZERO && (mux->decode[3].a == COMBINED_ALPHA || mux->decode[3].a == COMBINED)) mux->flags |= SC_IGNORE_ALPHA1; } return mux; } static int program_compare(ShaderProgram *prog, DecodedMux *dmux, u32 flags) { if (prog) return ((prog->combine.mux == dmux->combine.mux) && (prog->flags == flags)); return 1; } static void glcompiler_error(GLint shader) { int len, i; char* log; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len); log = (char*) malloc(len + 1); glGetShaderInfoLog(shader, len, &i, log); log[len] = 0; LOG(LOG_ERROR, "COMPILE ERROR: %s \n", log); free(log); } static void gllinker_error(GLint program) { int len, i; char* log; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len); log = (char*)malloc(len + 1); glGetProgramInfoLog(program, len, &i, log); log[len] = 0; LOG(LOG_ERROR, "LINK ERROR: %s \n", log); free(log); } static void locate_attributes(ShaderProgram *p) { glBindAttribLocation(p->program, SC_POSITION, "aPosition"); glBindAttribLocation(p->program, SC_COLOR, "aColor"); glBindAttribLocation(p->program, SC_TEXCOORD0, "aTexCoord0"); glBindAttribLocation(p->program, SC_TEXCOORD1, "aTexCoord1"); } #define LocateUniform(A) \ p->uniforms.A.loc = glGetUniformLocation(p->program, #A); static void locate_uniforms(ShaderProgram *p) { LocateUniform(uTex0); LocateUniform(uTex1); LocateUniform(uTexNoise); LocateUniform(uEnvColor); LocateUniform(uPrimColor); LocateUniform(uPrimLODFrac); LocateUniform(uK4); LocateUniform(uK5); LocateUniform(uFogColor); LocateUniform(uEnableFog); LocateUniform(uRenderState); LocateUniform(uFogScale); LocateUniform(uFogOffset); LocateUniform(uAlphaRef); LocateUniform(uTexScale); LocateUniform(uTexOffset[0]); LocateUniform(uTexOffset[1]); LocateUniform(uCacheShiftScale[0]); LocateUniform(uCacheShiftScale[1]); LocateUniform(uCacheScale[0]); LocateUniform(uCacheScale[1]); LocateUniform(uCacheOffset[0]); LocateUniform(uCacheOffset[1]); } static void force_uniforms(void) { SC_ForceUniform1i(uTex0, 0); SC_ForceUniform1i(uTex1, 1); SC_ForceUniform1i(uTexNoise, 2); SC_ForceUniform4fv(uEnvColor, &gDP.envColor.r); SC_ForceUniform4fv(uPrimColor, &gDP.primColor.r); SC_ForceUniform1f(uPrimLODFrac, gDP.primColor.l); SC_ForceUniform1f(uK4, gDP.convert.k4); SC_ForceUniform1f(uK5, gDP.convert.k5); SC_ForceUniform4fv(uFogColor, &gDP.fogColor.r); SC_ForceUniform1i(uEnableFog, ((gSP.geometryMode & G_FOG))); SC_ForceUniform1f(uRenderState, (float) OGL.renderState); SC_ForceUniform1f(uFogScale, (float) gSP.fog.multiplier / 256.0f); SC_ForceUniform1f(uFogOffset, (float) gSP.fog.offset / 255.0f); SC_ForceUniform1f(uAlphaRef, (gDP.otherMode.cvgXAlpha) ? 0.5f : gDP.blendColor.a); SC_ForceUniform2f(uTexScale, gSP.texture.scales, gSP.texture.scalet); if (gSP.textureTile[0]) SC_ForceUniform2f(uTexOffset[0], gSP.textureTile[0]->fuls, gSP.textureTile[0]->fult); else SC_ForceUniform2f(uTexOffset[0], 0.0f, 0.0f); if (gSP.textureTile[1]) SC_ForceUniform2f(uTexOffset[1], gSP.textureTile[1]->fuls, gSP.textureTile[1]->fult); else SC_ForceUniform2f(uTexOffset[1], 0.0f, 0.0f); if (cache.current[0]) { SC_ForceUniform2f(uCacheShiftScale[0], cache.current[0]->shiftScaleS, cache.current[0]->shiftScaleT); SC_ForceUniform2f(uCacheScale[0], cache.current[0]->scaleS, cache.current[0]->scaleT); SC_ForceUniform2f(uCacheOffset[0], cache.current[0]->offsetS, cache.current[0]->offsetT); } else { SC_ForceUniform2f(uCacheShiftScale[0], 1.0f, 1.0f); SC_ForceUniform2f(uCacheScale[0], 1.0f, 1.0f); SC_ForceUniform2f(uCacheOffset[0], 0.0f, 0.0f); } if (cache.current[1]) { SC_ForceUniform2f(uCacheShiftScale[1], cache.current[1]->shiftScaleS, cache.current[1]->shiftScaleT); SC_ForceUniform2f(uCacheScale[1], cache.current[1]->scaleS, cache.current[1]->scaleT); SC_ForceUniform2f(uCacheOffset[1], cache.current[1]->offsetS, cache.current[1]->offsetT); } else { SC_ForceUniform2f(uCacheShiftScale[1], 1.0f, 1.0f); SC_ForceUniform2f(uCacheScale[1], 1.0f, 1.0f); SC_ForceUniform2f(uCacheOffset[1], 0.0f, 0.0f); } } void Combiner_Init(void) { //compile vertex shader: GLint success; const char *src[1]; char buff[4096], *str; str = buff; str += sprintf(str, "%s", _vert); str += sprintf(str, "%s", _vertfog); if (config.zHack) str += sprintf(str, "%s", _vertzhack); str += sprintf(str, "}\n\n"); src[0] = buff; _vertex_shader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(_vertex_shader, 1, (const char**) src, NULL); glCompileShader(_vertex_shader); glGetShaderiv(_vertex_shader, GL_COMPILE_STATUS, &success); if (!success) glcompiler_error(_vertex_shader); gDP.otherMode.cycleType = G_CYC_1CYCLE; } static void Combiner_DeletePrograms(ShaderProgram *prog) { if (prog) { Combiner_DeletePrograms(prog->left); Combiner_DeletePrograms(prog->right); glDeleteProgram(prog->program); //glDeleteShader(prog->fragment); free(prog); scProgramCount--; } } void Combiner_Destroy(void) { Combiner_DeletePrograms(scProgramRoot); glDeleteShader(_vertex_shader); scProgramCount = scProgramChanged = 0; scProgramRoot = scProgramCurrent = NULL; } static ShaderProgram *ShaderCombiner_Compile(DecodedMux *dmux, int flags) { int i, j; GLint success, len[1]; char frag[4096], *src[1], *buffer; ShaderProgram *prog; buffer = (char*)frag; prog = (ShaderProgram*) malloc(sizeof(ShaderProgram)); prog->left = prog->right = NULL; prog->usesT0 = prog->usesT1 = prog->usesCol = prog->usesNoise = 0; prog->combine = dmux->combine; prog->flags = flags; prog->vertex = _vertex_shader; for(i = 0; i < ((flags & SC_2CYCLE) ? 4 : 2); i++) { //make sure were not ignoring cycle: if ((dmux->flags&(1<usesT0 |= (dmux->decode[i].sa == TEXEL0 || dmux->decode[i].sa == TEXEL0_ALPHA); prog->usesT1 |= (dmux->decode[i].sa == TEXEL1 || dmux->decode[i].sa == TEXEL1_ALPHA); prog->usesCol |= (dmux->decode[i].sa == SHADE || dmux->decode[i].sa == SHADE_ALPHA); prog->usesNoise |= (dmux->decode[i].sa == NOISE); prog->usesT0 |= (dmux->decode[i].sb == TEXEL0 || dmux->decode[i].sb == TEXEL0_ALPHA); prog->usesT1 |= (dmux->decode[i].sb == TEXEL1 || dmux->decode[i].sb == TEXEL1_ALPHA); prog->usesCol |= (dmux->decode[i].sb == SHADE || dmux->decode[i].sb == SHADE_ALPHA); prog->usesNoise |= (dmux->decode[i].sb == NOISE); prog->usesT0 |= (dmux->decode[i].m == TEXEL0 || dmux->decode[i].m == TEXEL0_ALPHA); prog->usesT1 |= (dmux->decode[i].m == TEXEL1 || dmux->decode[i].m == TEXEL1_ALPHA); prog->usesCol |= (dmux->decode[i].m == SHADE || dmux->decode[i].m == SHADE_ALPHA); prog->usesNoise |= (dmux->decode[i].m == NOISE); prog->usesT0 |= (dmux->decode[i].a == TEXEL0 || dmux->decode[i].a == TEXEL0_ALPHA); prog->usesT1 |= (dmux->decode[i].a == TEXEL1 || dmux->decode[i].a == TEXEL1_ALPHA); prog->usesCol |= (dmux->decode[i].a == SHADE || dmux->decode[i].a == SHADE_ALPHA); prog->usesNoise |= (dmux->decode[i].a == NOISE); } } } buffer += sprintf(buffer, "%s", _frag_header); if (prog->usesT0) buffer += sprintf(buffer, "lowp vec4 lTex0 = texture2D(uTex0, vTexCoord0); \n"); if (prog->usesT1) buffer += sprintf(buffer, "lowp vec4 lTex1 = texture2D(uTex1, vTexCoord1); \n"); if (prog->usesNoise) buffer += sprintf(buffer, "lowp vec4 lNoise = texture2D(uTexNoise, (1.0 / 1024.0) * gl_FragCoord.st); \n"); for(i = 0; i < ((flags & SC_2CYCLE) ? 2 : 1); i++) { if ((dmux->flags&(1<<(i*2))) == 0) { buffer += sprintf(buffer, "lFragColor.rgb = (%s - %s) * %s + %s; \n", _color_param_str(dmux->decode[i*2].sa), _color_param_str(dmux->decode[i*2].sb), _color_param_str(dmux->decode[i*2].m), _color_param_str(dmux->decode[i*2].a) ); } if ((dmux->flags&(1<<(i*2+1))) == 0) { buffer += sprintf(buffer, "lFragColor.a = (%s - %s) * %s + %s; \n", _alpha_param_str(dmux->decode[i*2+1].sa), _alpha_param_str(dmux->decode[i*2+1].sb), _alpha_param_str(dmux->decode[i*2+1].m), _alpha_param_str(dmux->decode[i*2+1].a) ); } buffer += sprintf(buffer, "gl_FragColor = lFragColor; \n"); }; //fog if (flags&SC_FOGENABLED) { buffer += sprintf(buffer, "gl_FragColor = mix(gl_FragColor, uFogColor, vFactor); \n"); } //alpha function if (flags&SC_ALPHAENABLED) { if (flags&SC_ALPHAGREATER) buffer += sprintf(buffer, "if (gl_FragColor.a < uAlphaRef) %s;\n", config.hackAlpha ? "gl_FragColor.a = 0" : "discard"); else buffer += sprintf(buffer, "if (gl_FragColor.a <= uAlphaRef) %s;\n", config.hackAlpha ? "gl_FragColor.a = 0" : "discard"); } buffer += sprintf(buffer, "} \n\n"); *buffer = 0; prog->program = glCreateProgram(); //Compile: src[0] = frag; len[0] = min(4096, strlen(frag)); prog->fragment = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(prog->fragment, 1, (const char**) src, len); glCompileShader(prog->fragment); glGetShaderiv(prog->fragment, GL_COMPILE_STATUS, &success); if (!success) glcompiler_error(prog->fragment); //link locate_attributes(prog); glAttachShader(prog->program, prog->fragment); glAttachShader(prog->program, prog->vertex); glLinkProgram(prog->program); glGetProgramiv(prog->program, GL_LINK_STATUS, &success); if (!success) gllinker_error(prog->program); //remove fragment shader: glDeleteShader(prog->fragment); locate_uniforms(prog); return prog; } void Combiner_Set(u64 mux, int flags) { DecodedMux *dmux; ShaderProgram *root, *prog; //determine flags if (flags == -1) { flags = 0; if ((gSP.geometryMode & G_FOG)) flags |= SC_FOGENABLED; if ((gDP.otherMode.alphaCompare == G_AC_THRESHOLD) && !(gDP.otherMode.alphaCvgSel)) { flags |= SC_ALPHAENABLED; if (gDP.blendColor.a > 0.0f) flags |= SC_ALPHAGREATER; } else if (gDP.otherMode.cvgXAlpha) { flags |= SC_ALPHAENABLED; flags |= SC_ALPHAGREATER; } if (gDP.otherMode.cycleType == G_CYC_2CYCLE) flags |= SC_2CYCLE; } dmux = (DecodedMux*)mux_new(mux, flags & SC_2CYCLE); //if already bound: if (scProgramCurrent) { if (program_compare(scProgramCurrent, dmux, flags)) { scProgramChanged = 0; return; } } //traverse binary tree for cached programs scProgramChanged = 1; root = (ShaderProgram*)scProgramRoot; prog = (ShaderProgram*)root; while(!program_compare(prog, dmux, flags)) { root = prog; if (prog->combine.mux < dmux->combine.mux) prog = prog->right; else prog = prog->left; } //build new program if (!prog) { scProgramCount++; prog = ShaderCombiner_Compile(dmux, flags); if (!root) scProgramRoot = prog; else if (root->combine.mux < dmux->combine.mux) root->right = prog; else root->left = prog; } prog->lastUsed = OGL.frame_dl; scProgramCurrent = prog; glUseProgram(prog->program); force_uniforms(); if (dmux) free(dmux); } void ShaderCombiner_UpdateBlendColor(void) { SC_SetUniform1f(uAlphaRef, (gDP.otherMode.cvgXAlpha) ? 0.5f : gDP.blendColor.a); } void ShaderCombiner_UpdateEnvColor(void) { SC_SetUniform4fv(uEnvColor, &gDP.envColor.r); } void ShaderCombiner_UpdateFogColor(void) { SC_SetUniform4fv(uFogColor, &gDP.fogColor.r ); } void ShaderCombiner_UpdateConvertColor(void) { SC_SetUniform1f(uK4, gDP.convert.k4); SC_SetUniform1f(uK5, gDP.convert.k5); } void ShaderCombiner_UpdatePrimColor(void) { SC_SetUniform4fv(uPrimColor, &gDP.primColor.r); SC_SetUniform1f(uPrimLODFrac, gDP.primColor.l); } void ShaderCombiner_UpdateKeyColor(void) { } void ShaderCombiner_UpdateLightParameters(void) { } gles2n64/src/L3D.h000664 001750 001750 00000000335 12655644434 014606 0ustar00sergiosergio000000 000000 #ifndef L3D_H #define L3D_H #ifdef __cplusplus extern "C" { #endif #include "Types.h" #define L3D_LINE3D 0xB5 void L3D_Line3D( u32 w0, u32 w1 ); void L3D_Init(void); #ifdef __cplusplus } #endif #endif glide2gl/src/Glide64/turbo3D.h000664 001750 001750 00000023703 12655644434 017075 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** // // Created by Gonetz, 2008 // //**************************************************************** #include "GBI.h" /******************Turbo3D microcode*************************/ struct t3dGlobState { uint16_t pad0; uint16_t perspNorm; uint32_t flag; uint32_t othermode0; uint32_t othermode1; uint32_t segBases[16]; /* the viewport to use */ int16_t vsacle1; int16_t vsacle0; int16_t vsacle3; int16_t vsacle2; int16_t vtrans1; int16_t vtrans0; int16_t vtrans3; int16_t vtrans2; uint32_t rdpCmds; }; struct t3dState { uint32_t renderState; /* render state */ uint32_t textureState; /* texture state */ uint8_t flag; uint8_t triCount; /* how many tris? */ uint8_t vtxV0; /* where to load verts? */ uint8_t vtxCount; /* how many verts? */ uint32_t rdpCmds; /* ptr (segment address) to RDP DL */ uint32_t othermode0; uint32_t othermode1; }; struct t3dTriN { uint8_t flag, v2, v1, v0; /* flag is which one for flat shade */ }; static void t3dProcessRDP(uint32_t a) { if (a) { rdp.LLE = 1; rdp.cmd0 = ((uint32_t*)gfx_info.RDRAM)[a++]; rdp.cmd1 = ((uint32_t*)gfx_info.RDRAM)[a++]; while (rdp.cmd0 + rdp.cmd1) { uint32_t cmd; gfx_instruction[0][rdp.cmd0>>24](rdp.cmd0, rdp.cmd1); rdp.cmd0 = ((uint32_t*)gfx_info.RDRAM)[a++]; rdp.cmd1 = ((uint32_t*)gfx_info.RDRAM)[a++]; cmd = rdp.cmd0>>24; if (cmd == G_TEXRECT || cmd == G_TEXRECTFLIP) { rdp.cmd2 = ((uint32_t*)gfx_info.RDRAM)[a++]; rdp.cmd3 = ((uint32_t*)gfx_info.RDRAM)[a++]; } } rdp.LLE = 0; } } static void t3dLoadGlobState(uint32_t pgstate) { int s; int16_t scale_x, scale_y, scale_z, trans_x, trans_y, trans_z; struct t3dGlobState *gstate = (struct t3dGlobState*)&gfx_info.RDRAM[RSP_SegmentToPhysical(pgstate)]; FRDP ("Global state. pad0: %04lx, perspNorm: %04lx, flag: %08lx\n", gstate->pad0, gstate->perspNorm, gstate->flag); rdp.cmd0 = gstate->othermode0; rdp.cmd1 = gstate->othermode1; rdp_setothermode(rdp.cmd0, rdp.cmd1); for (s = 0; s < 16; s++) rdp.segment[s] = gstate->segBases[s]; scale_x = gstate->vsacle0 / 4; scale_y = gstate->vsacle1 / 4;; scale_z = gstate->vsacle2; trans_x = gstate->vtrans0 / 4; trans_y = gstate->vtrans1 / 4; trans_z = gstate->vtrans2; rdp.view_scale[0] = scale_x * rdp.scale_x; rdp.view_scale[1] = -scale_y * rdp.scale_y; rdp.view_scale[2] = 32.0f * scale_z; rdp.view_trans[0] = trans_x * rdp.scale_x; rdp.view_trans[1] = trans_y * rdp.scale_y; rdp.view_trans[2] = 32.0f * trans_z; g_gdp.flags |= UPDATE_VIEWPORT; FRDP ("viewport scale(%d, %d, %d), trans(%d, %d, %d)\n", scale_x, scale_y, scale_z, trans_x, trans_y, trans_z); t3dProcessRDP(RSP_SegmentToPhysical(gstate->rdpCmds) >> 2); } static void t3d_vertex(uint32_t addr, uint32_t v0, uint32_t n) { uint32_t i; float x, y, z; n <<= 4; for (i = 0; i < n; i+=16) { VERTEX *v = &rdp.vtx[v0 + (i>>4)]; x = (float)((int16_t*)gfx_info.RDRAM)[(((addr+i) >> 1) + 0)^1]; y = (float)((int16_t*)gfx_info.RDRAM)[(((addr+i) >> 1) + 1)^1]; z = (float)((int16_t*)gfx_info.RDRAM)[(((addr+i) >> 1) + 2)^1]; v->flags = ((uint16_t*)gfx_info.RDRAM)[(((addr+i) >> 1) + 3)^1]; v->ou = 2.0f * (float)((int16_t*)gfx_info.RDRAM)[(((addr+i) >> 1) + 4)^1]; v->ov = 2.0f * (float)((int16_t*)gfx_info.RDRAM)[(((addr+i) >> 1) + 5)^1]; v->uv_scaled = 0; v->r = ((uint8_t*)gfx_info.RDRAM)[(addr+i + 12)^3]; v->g = ((uint8_t*)gfx_info.RDRAM)[(addr+i + 13)^3]; v->b = ((uint8_t*)gfx_info.RDRAM)[(addr+i + 14)^3]; v->a = ((uint8_t*)gfx_info.RDRAM)[(addr+i + 15)^3]; v->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0]; v->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1]; v->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2]; v->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3]; if (fabs(v->w) < 0.001) v->w = 0.001f; v->oow = 1.0f / v->w; v->x_w = v->x * v->oow; v->y_w = v->y * v->oow; v->z_w = v->z * v->oow; v->uv_calculated = 0xFFFFFFFF; v->screen_translated = 0; v->shade_mod = 0; v->scr_off = 0; if (v->x < -v->w) v->scr_off |= 1; if (v->x > v->w) v->scr_off |= 2; if (v->y < -v->w) v->scr_off |= 4; if (v->y > v->w) v->scr_off |= 8; if (v->w < 0.1f) v->scr_off |= 16; #ifdef EXTREME_LOGGING FRDP ("v%d - x: %f, y: %f, z: %f, w: %f, u: %f, v: %f, f: %f, z_w: %f, r=%d, g=%d, b=%d, a=%d\n", i>>4, v->x, v->y, v->z, v->w, v->ou*rdp.tiles[rdp.cur_tile].s_scale, v->ov*rdp.tiles[rdp.cur_tile].t_scale, v->f, v->z_w, v->r, v->g, v->b, v->a); #endif } } static void t3dLoadObject(uint32_t pstate, uint32_t pvtx, uint32_t ptri) { int t; struct t3dState *ostate = (struct t3dState*)&gfx_info.RDRAM[RSP_SegmentToPhysical(pstate)]; rdp.cur_tile = (ostate->textureState)&7; LRDP("Loading Turbo3D object\n"); FRDP("tile: %d\n", rdp.cur_tile); if (rdp.tiles[rdp.cur_tile].s_scale < 0.001f) rdp.tiles[rdp.cur_tile].s_scale = 0.015625; if (rdp.tiles[rdp.cur_tile].t_scale < 0.001f) rdp.tiles[rdp.cur_tile].t_scale = 0.015625; #ifdef EXTREME_LOGGING FRDP("renderState: %08lx, textureState: %08lx, othermode0: %08lx, othermode1: %08lx, rdpCmds: %08lx, triCount : %d, v0: %d, vn: %d\n", ostate->renderState, ostate->textureState, ostate->othermode0, ostate->othermode1, ostate->rdpCmds, ostate->triCount, ostate->vtxV0, ostate->vtxCount); #endif rdp.cmd0 = ostate->othermode0; rdp.cmd1 = ostate->othermode1; rdp_setothermode(rdp.cmd0, rdp.cmd1); rdp.cmd1 = ostate->renderState; uc0_setgeometrymode(rdp.cmd0, rdp.cmd1); if (!(ostate->flag&1)) //load matrix { uint32_t addr = RSP_SegmentToPhysical(pstate+sizeof(struct t3dState)) & BMASK; load_matrix(rdp.combined, addr); #ifdef EXTREME_LOGGING FRDP ("{%f,%f,%f,%f}\n", rdp.combined[0][0], rdp.combined[0][1], rdp.combined[0][2], rdp.combined[0][3]); FRDP ("{%f,%f,%f,%f}\n", rdp.combined[1][0], rdp.combined[1][1], rdp.combined[1][2], rdp.combined[1][3]); FRDP ("{%f,%f,%f,%f}\n", rdp.combined[2][0], rdp.combined[2][1], rdp.combined[2][2], rdp.combined[2][3]); FRDP ("{%f,%f,%f,%f}\n", rdp.combined[3][0], rdp.combined[3][1], rdp.combined[3][2], rdp.combined[3][3]); #endif } rdp.geom_mode &= ~G_LIGHTING; rdp.geom_mode |= UPDATE_SCISSOR; if (pvtx) //load vtx t3d_vertex(RSP_SegmentToPhysical(pvtx), ostate->vtxV0, ostate->vtxCount); t3dProcessRDP(RSP_SegmentToPhysical(ostate->rdpCmds) >> 2); if (ptri) { uint32_t a; update(); a = RSP_SegmentToPhysical(ptri); for (t = 0; t < ostate->triCount; t++) { VERTEX *v[3]; struct t3dTriN *tri = (struct t3dTriN*)&gfx_info.RDRAM[a]; v[0] = &rdp.vtx[tri->v0]; v[1] = &rdp.vtx[tri->v1]; v[2] = &rdp.vtx[tri->v2]; cull_trianglefaces(v, 1, false, true, 0); a += 4; } } } static void Turbo3D(void) { uint32_t a, pgstate, pstate, pvtx, ptri; LRDP("Start Turbo3D microcode\n"); settings.ucode = ucode_Fast3D; a = 0; pgstate = 0; pstate = 0; pvtx = 0; ptri = 0; do { a = rdp.pc[rdp.pc_i] & BMASK; pgstate = ((uint32_t*)gfx_info.RDRAM)[a>>2]; pstate = ((uint32_t*)gfx_info.RDRAM)[(a>>2)+1]; pvtx = ((uint32_t*)gfx_info.RDRAM)[(a>>2)+2]; ptri = ((uint32_t*)gfx_info.RDRAM)[(a>>2)+3]; FRDP("GlobalState: %08lx, Object: %08lx, Vertices: %08lx, Triangles: %08lx\n", pgstate, pstate, pvtx, ptri); if (!pstate) { rdp.halt = 1; break; } if (pgstate) t3dLoadGlobState(pgstate); t3dLoadObject(pstate, pvtx, ptri); // Go to the next instruction rdp.pc[rdp.pc_i] += 16; } while (pstate); // rdp_fullsync(); settings.ucode = ucode_Turbo3d; } mupen64plus-video-gliden64/src/GLideNHQ/GlideHQ.rc000664 001750 001750 00000005220 12655644434 022563 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "bldno.h" #define ID(id) id #define VS_FILE_INFO ID(16) /* Version stamp res type */ #define VS_VERSION_INFO ID(1) /* Version stamp res ID */ #define VS_USER_DEFINED ID(100) /* User-defined res IDs */ #define VOS_DOS_WINDOWS32 0x00010004L #define VFT_DLL 0x00000002L #define VER_PRERELEASE 0 #define VER_PRIVATEBUILD 0 #define VER_DEBUG 0 #define VERSIONNAME "GlideHQ.dll\0" #define PRODNAME "GlideHQ\0" #define DESCRIPT "Texture filtering DLL\0" #define COPYRIGHTSTR "Copyright (C) 2007 Hiroshi Morii\0" #define CONTACTSTR "Hiroshi Morii http://www.3dfxzone.it/koolsmoky\0" #define MANVERSION 1 #define MANREVISION 02 #define MINVERSION 00 #define VERSIONSTR "1.02.00." BUILD_NUMBER_STR VS_VERSION_INFO VERSIONINFO FILEVERSION MANVERSION, MANREVISION, 0, BUILD_NUMBER PRODUCTVERSION MANVERSION, MANREVISION, 0, BUILD_NUMBER FILEFLAGSMASK 0x0030003FL FILEFLAGS (VER_PRIVATEBUILD|VER_PRERELEASE|VER_DEBUG) FILEOS VOS_DOS_WINDOWS32 FILETYPE VFT_DLL FILESUBTYPE 0 BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904E4" BEGIN VALUE "FileDescription", DESCRIPT VALUE "FileVersion", VERSIONSTR VALUE "InternalName", VERSIONNAME VALUE "LegalCopyright", COPYRIGHTSTR VALUE "OriginalFilename", VERSIONNAME VALUE "ProductName", PRODNAME VALUE "ProductVersion", VERSIONSTR VALUE "Contact", CONTACTSTR END END BLOCK "VarFileInfo" BEGIN /* the following line should be extended for localized versions */ VALUE "Translation", 0x409, 1252 END END gles2n64/src/L3D.c000664 001750 001750 00000005155 12655644434 014606 0ustar00sergiosergio000000 000000 #include "gles2N64.h" #include "Debug.h" #include "F3D.h" #include "L3D.h" #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gSP.h" #include "gDP.h" #include "GBI.h" void L3D_Line3D( u32 w0, u32 w1 ) { u32 wd = _SHIFTR( w1, 0, 8 ); if (wd == 0) gSPLine3D( _SHIFTR( w1, 16, 8 ) / 10, _SHIFTR( w1, 8, 8 ) / 10, _SHIFTR( w1, 24, 8 ) ); else gSPLineW3D( _SHIFTR( w1, 16, 8 ) / 10, _SHIFTR( w1, 8, 8 ) / 10, wd, _SHIFTR( w1, 24, 8 ) ); } void L3D_Init(void) { gSPSetupFunctions(); // Set GeometryMode flags GBI_InitFlags( F3D ); GBI.PCStackSize = 10; // GBI Command Command Value Command Function GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_MTX, F3D_MTX, F3D_Mtx ); GBI_SetGBI( G_RESERVED0, F3D_RESERVED0, F3D_Reserved0 ); GBI_SetGBI( G_MOVEMEM, F3D_MOVEMEM, F3D_MoveMem ); GBI_SetGBI( G_VTX, F3D_VTX, F3D_Vtx ); GBI_SetGBI( G_RESERVED1, F3D_RESERVED1, F3D_Reserved1 ); GBI_SetGBI( G_DL, F3D_DL, F3D_DList ); GBI_SetGBI( G_RESERVED2, F3D_RESERVED2, F3D_Reserved2 ); GBI_SetGBI( G_RESERVED3, F3D_RESERVED3, F3D_Reserved3 ); GBI_SetGBI( G_SPRITE2D_BASE, F3D_SPRITE2D_BASE, F3D_Sprite2D_Base ); // GBI_SetGBI( G_TRI1, F3D_TRI1, F3D_Tri1 ); GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3D_CullDL ); GBI_SetGBI( G_POPMTX, F3D_POPMTX, F3D_PopMtx ); GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3D_MoveWord ); GBI_SetGBI( G_TEXTURE, F3D_TEXTURE, F3D_Texture ); GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L ); GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL ); GBI_SetGBI( G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, F3D_SetGeometryMode ); GBI_SetGBI( G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE, F3D_ClearGeometryMode ); GBI_SetGBI( G_LINE3D, L3D_LINE3D, L3D_Line3D ); GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_RDPHALF_CONT, F3D_RDPHALF_CONT, F3D_RDPHalf_Cont ); // GBI_SetGBI( G_TRI4, F3D_TRI4, F3D_Tri4 ); } mupen64plus-rsp-hle/src/cicx105.c000664 001750 001750 00000004655 12655644434 017612 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-rsp-hle - cicx105.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2012 Bobby Smiles * * Copyright (C) 2009 Richard Goedeken * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include "hle_internal.h" /** * During IPL3 stage of CIC x105 games, the RSP performs some checks and transactions * necessary for booting the game. * * We only implement the needed DMA transactions for booting. * * Found in Banjo-Tooie, Zelda, Perfect Dark, ...) **/ void cicx105_ucode(struct hle_t* hle) { /* memcpy is okay to use because access constrains are met (alignment, size) */ unsigned int i; unsigned char *dst = hle->dram + 0x2fb1f0; unsigned char *src = hle->imem + 0x120; /* dma_read(0x1120, 0x1e8, 0x1e8) */ memcpy(hle->imem + 0x120, hle->dram + 0x1e8, 0x1f0); /* dma_write(0x1120, 0x2fb1f0, 0xfe817000) */ for (i = 0; i < 24; ++i) { memcpy(dst, src, 8); dst += 0xff0; src += 0x8; } } gles2rice/src/RiceConfig.cpp000664 001750 001750 00000150376 12655644434 017115 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "../../libretro/SDL.h" #define M64P_PLUGIN_PROTOTYPES 1 #include "osal_preproc.h" #include "m64p_types.h" #include "m64p_plugin.h" #include "m64p_config.h" #include "Config.h" #include "Debugger.h" #include "DeviceBuilder.h" #include "RenderBase.h" #include "TextureManager.h" #include "Video.h" #ifdef _MSC_VER #define strncasecmp _strnicmp #endif #define INI_FILE "RiceVideoLinux.ini" #ifdef __cplusplus extern "C" { #endif extern uint32_t screen_width, screen_height; extern retro_environment_t environ_cb; #ifdef __cplusplus } #endif static m64p_handle l_ConfigVideoRice = NULL; static m64p_handle l_ConfigVideoGeneral = NULL; //static int FindIniEntry(uint32_t dwCRC1, uint32_t dwCRC2, uint8_t nCountryID, char* szName, int PrintInfo); const char *frameBufferSettings[] = { "None (default)", "Hide Framebuffer Effects", "Basic Framebuffer", "Basic & Write Back", "Write Back & Reload", "Write Back Every Frame", "With Emulator", "Basic Framebuffer & With Emulator", "With Emulator Read Only", "With Emulator Write Only", }; const int resolutions[][2] = { {320, 240}, {400, 300}, {480, 360}, {512, 384}, {640, 480}, {800, 600}, {1024, 768}, {1152, 864}, {1280, 960}, {1400, 1050}, {1600, 1200}, {1920, 1440}, {2048, 1536}, }; const int numberOfResolutions = sizeof(resolutions)/sizeof(int)/2; const char* resolutionsS[] = { "320 x 240", "400 x 300", "480 x 360", "512 x 384", "640 x 480", "800 x 600", "1024 x 768", "1152 x 864", "1280 x 960", "1400 x 1050", "1600 x 1200", "1920 x 1440", "2048 x 1536" }; const char *frameBufferWriteBackControlSettings[] = { "Every Frame (default)", "Every 2 Frames", "Every 3 Frames", "Every 4 Frames", "Every 5 Frames", "Every 6 Frames", "Every 7 Frames", "Every 8 Frames", }; const char *renderToTextureSettings[] = { "None (default)", "Hide Render-to-texture Effects", "Basic Render-to-texture", "Basic & Write Back", "Write Back & Reload", }; const char *screenUpdateSettings[] = { "At VI origin update", "At VI origin change", "At CI change", "At the 1st CI change", "At the 1st drawing", "Before clear the screen", "At VI origin update after screen is drawn (default)", }; WindowSettingStruct windowSetting; GlobalOptions options; RomOptions defaultRomOptions; RomOptions currentRomOptions; FrameBufferOptions frameBufferOptions; //std::vector IniSections; //bool bIniIsChanged = false; //char szIniFileName[300]; SettingInfo TextureQualitySettings[] = { {"Default", FORCE_DEFAULT_FILTER}, {"32-bit Texture", FORCE_POINT_FILTER}, {"16-bit Texture", FORCE_LINEAR_FILTER}, }; SettingInfo ForceTextureFilterSettings[] = { {"N64 Default Texture Filter", FORCE_DEFAULT_FILTER}, {"Force Nearest Filter (faster, low quality)", FORCE_POINT_FILTER}, {"Force Linear Filter (slower, better quality)", FORCE_LINEAR_FILTER}, }; SettingInfo TextureEnhancementSettings[] = { {"N64 original texture (No enhancement)", TEXTURE_NO_ENHANCEMENT}, {"2x (Double the texture size)", TEXTURE_2X_ENHANCEMENT}, {"2xSaI", TEXTURE_2XSAI_ENHANCEMENT}, {"hq2x", TEXTURE_HQ2X_ENHANCEMENT}, {"lq2x", TEXTURE_LQ2X_ENHANCEMENT}, {"hq4x", TEXTURE_HQ4X_ENHANCEMENT}, {"Sharpen", TEXTURE_SHARPEN_ENHANCEMENT}, {"Sharpen More", TEXTURE_SHARPEN_MORE_ENHANCEMENT}, }; SettingInfo TextureEnhancementControlSettings[] = { {"Normal", TEXTURE_ENHANCEMENT_NORMAL}, {"Smooth", TEXTURE_ENHANCEMENT_WITH_SMOOTH_FILTER_1}, {"Less smooth", TEXTURE_ENHANCEMENT_WITH_SMOOTH_FILTER_2}, {"2xSaI smooth", TEXTURE_ENHANCEMENT_WITH_SMOOTH_FILTER_3}, {"Less 2xSaI smooth", TEXTURE_ENHANCEMENT_WITH_SMOOTH_FILTER_4}, }; SettingInfo colorQualitySettings[] = { {"16-bit", TEXTURE_FMT_A4R4G4B4}, {"32-bit (def)", TEXTURE_FMT_A8R8G8B8}, }; const char* strDXDeviceDescs[] = { "HAL", "REF" }; SettingInfo openGLDepthBufferSettings[] = { {"16-bit (def)", 16}, {"32-bit", 32}, }; RenderEngineSetting OpenGLRenderSettings[] = { {"To Fit Your Video Card", OGL_DEVICE}, {"OpenGL 1.1 (Lowest)", OGL_1_1_DEVICE}, {"OpenGL 1.2/1.3", OGL_1_2_DEVICE}, {"OpenGL 1.4", OGL_1_4_DEVICE}, //{"OpenGL 1.4, the 2nd combiner", OGL_1_4_V2_DEVICE}, {"OpenGL for Nvidia TNT or better", OGL_TNT2_DEVICE}, {"OpenGL for Nvidia GeForce or better ", NVIDIA_OGL_DEVICE}, {"OpenGL Fragment Program Extension", OGL_FRAGMENT_PROGRAM}, }; SettingInfo OnScreenDisplaySettings[] = { {"Display Nothing", ONSCREEN_DISPLAY_NOTHING}, {"Display DList Per Second", ONSCREEN_DISPLAY_DLIST_PER_SECOND}, {"Display Frame Per Second", ONSCREEN_DISPLAY_FRAME_PER_SECOND}, {"Display Debug Information Only", ONSCREEN_DISPLAY_DEBUG_INFORMATION_ONLY}, {"Display Messages From CPU Core Only", ONSCREEN_DISPLAY_TEXT_FROM_CORE_ONLY}, {"Display DList Per Second With Core Msgs", ONSCREEN_DISPLAY_DLIST_PER_SECOND_WITH_CORE_MSG}, {"Display Frame Per Second With Core Msgs", ONSCREEN_DISPLAY_FRAME_PER_SECOND_WITH_CORE_MSG}, {"Display Debug Information With Core Msgs", ONSCREEN_DISPLAY_DEBUG_INFORMATION_WITH_CORE_MSG}, }; const int numberOfOpenGLRenderEngineSettings = sizeof(OpenGLRenderSettings)/sizeof(RenderEngineSetting); void GenerateFrameBufferOptions(void) { // OpenGL does not support much yet if( currentRomOptions.N64FrameBufferEmuType != FRM_BUF_NONE ) currentRomOptions.N64FrameBufferEmuType = FRM_BUF_IGNORE; if( currentRomOptions.N64RenderToTextureEmuType != TXT_BUF_NONE ) currentRomOptions.N64RenderToTextureEmuType = TXT_BUF_IGNORE; frameBufferOptions.bUpdateCIInfo = false; frameBufferOptions.bCheckBackBufs = false; frameBufferOptions.bWriteBackBufToRDRAM = false; frameBufferOptions.bLoadBackBufFromRDRAM = false; frameBufferOptions.bIgnore = true; frameBufferOptions.bSupportRenderTextures = false; frameBufferOptions.bCheckRenderTextures = false; frameBufferOptions.bRenderTextureWriteBack = false; frameBufferOptions.bLoadRDRAMIntoRenderTexture = false; frameBufferOptions.bProcessCPUWrite = false; frameBufferOptions.bProcessCPURead = false; frameBufferOptions.bAtEachFrameUpdate = false; frameBufferOptions.bIgnoreRenderTextureIfHeightUnknown = false; switch( currentRomOptions.N64FrameBufferEmuType ) { case FRM_BUF_NONE: break; case FRM_BUF_COMPLETE: frameBufferOptions.bAtEachFrameUpdate = true; frameBufferOptions.bProcessCPUWrite = true; frameBufferOptions.bProcessCPURead = true; frameBufferOptions.bUpdateCIInfo = true; break; case FRM_BUF_WRITEBACK_AND_RELOAD: frameBufferOptions.bLoadBackBufFromRDRAM = true; case FRM_BUF_BASIC_AND_WRITEBACK: frameBufferOptions.bWriteBackBufToRDRAM = true; case FRM_BUF_BASIC: frameBufferOptions.bCheckBackBufs = true; case FRM_BUF_IGNORE: frameBufferOptions.bUpdateCIInfo = true; break; case FRM_BUF_BASIC_AND_WITH_EMULATOR: // Banjo Kazooie frameBufferOptions.bCheckBackBufs = true; case FRM_BUF_WITH_EMULATOR: frameBufferOptions.bUpdateCIInfo = true; frameBufferOptions.bProcessCPUWrite = true; frameBufferOptions.bProcessCPURead = true; break; case FRM_BUF_WITH_EMULATOR_READ_ONLY: frameBufferOptions.bUpdateCIInfo = true; frameBufferOptions.bProcessCPURead = true; break; case FRM_BUF_WITH_EMULATOR_WRITE_ONLY: frameBufferOptions.bUpdateCIInfo = true; frameBufferOptions.bProcessCPUWrite = true; break; } switch( currentRomOptions.N64RenderToTextureEmuType ) { case TXT_BUF_NONE: frameBufferOptions.bSupportRenderTextures = false; break; case TXT_BUF_WRITE_BACK_AND_RELOAD: frameBufferOptions.bLoadRDRAMIntoRenderTexture = true; case TXT_BUF_WRITE_BACK: frameBufferOptions.bRenderTextureWriteBack = true; case TXT_BUF_NORMAL: frameBufferOptions.bCheckRenderTextures = true; frameBufferOptions.bIgnore = false; case TXT_BUF_IGNORE: frameBufferOptions.bUpdateCIInfo = true; frameBufferOptions.bSupportRenderTextures = true; break; } if( currentRomOptions.screenUpdateSetting >= SCREEN_UPDATE_AT_CI_CHANGE ) { frameBufferOptions.bUpdateCIInfo = true; } } bool InitConfiguration(void) { if (ConfigOpenSection("Video-General", &l_ConfigVideoGeneral) != M64ERR_SUCCESS) { DebugMessage(M64MSG_ERROR, "Unable to open Video-General configuration section"); return FALSE; } if (ConfigOpenSection("Video-Rice", &l_ConfigVideoRice) != M64ERR_SUCCESS) { DebugMessage(M64MSG_ERROR, "Unable to open Video-Rice configuration section"); return FALSE; } ConfigSetDefaultBool(l_ConfigVideoGeneral, "Fullscreen", 0, "Use fullscreen mode if True, or windowed mode if False "); ConfigSetDefaultInt(l_ConfigVideoGeneral, "ScreenWidth", 640, "Width of output window or fullscreen width"); ConfigSetDefaultInt(l_ConfigVideoGeneral, "ScreenHeight", 480, "Height of output window or fullscreen height"); ConfigSetDefaultBool(l_ConfigVideoGeneral, "VerticalSync", 0, "If true, activate the SDL_GL_SWAP_CONTROL attribute"); ConfigSetDefaultInt(l_ConfigVideoRice, "FrameBufferSetting", FRM_BUF_NONE, "Frame Buffer Emulation (0=ROM default, 1=disable)"); ConfigSetDefaultInt(l_ConfigVideoRice, "FrameBufferWriteBackControl", FRM_BUF_WRITEBACK_NORMAL, "Frequency to write back the frame buffer (0=every frame, 1=every other frame, etc)"); ConfigSetDefaultInt(l_ConfigVideoRice, "RenderToTexture", TXT_BUF_NONE, "Render-to-texture emulation (0=none, 1=ignore, 2=normal, 3=write back, 4=write back and reload)"); #if defined(WIN32) ConfigSetDefaultInt(l_ConfigVideoRice, "ScreenUpdateSetting", SCREEN_UPDATE_AT_1ST_CI_CHANGE, "Control when the screen will be updated (0=ROM default, 1=VI origin update, 2=VI origin change, 3=CI change, 4=first CI change, 5=first primitive draw, 6=before screen clear, 7=after screen drawn)"); // SCREEN_UPDATE_AT_VI_UPDATE_AND_DRAWN #else ConfigSetDefaultInt(l_ConfigVideoRice, "ScreenUpdateSetting", SCREEN_UPDATE_AT_VI_UPDATE, "Control when the screen will be updated (0=ROM default, 1=VI origin update, 2=VI origin change, 3=CI change, 4=first CI change, 5=first primitive draw, 6=before screen clear, 7=after screen drawn)"); // SCREEN_UPDATE_AT_VI_UPDATE_AND_DRAWN #endif ConfigSetDefaultBool(l_ConfigVideoRice, "NormalAlphaBlender", FALSE, "Force to use normal alpha blender"); ConfigSetDefaultBool(l_ConfigVideoRice, "FastTextureLoading", FALSE, "Use a faster algorithm to speed up texture loading and CRC computation"); ConfigSetDefaultBool(l_ConfigVideoRice, "AccurateTextureMapping", TRUE, "Use different texture coordinate clamping code"); ConfigSetDefaultBool(l_ConfigVideoRice, "InN64Resolution", FALSE, "Force emulated frame buffers to be in N64 native resolution"); ConfigSetDefaultBool(l_ConfigVideoRice, "SaveVRAM", FALSE, "Try to reduce Video RAM usage (should never be used)"); ConfigSetDefaultBool(l_ConfigVideoRice, "DoubleSizeForSmallTxtrBuf", FALSE, "Enable this option to have better render-to-texture quality"); ConfigSetDefaultBool(l_ConfigVideoRice, "DefaultCombinerDisable", FALSE, "Force to use normal color combiner"); ConfigSetDefaultBool(l_ConfigVideoRice, "EnableHacks", TRUE, "Enable game-specific settings from INI file"); ConfigSetDefaultBool(l_ConfigVideoRice, "WinFrameMode", FALSE, "If enabled, graphics will be drawn in WinFrame mode instead of solid and texture mode"); ConfigSetDefaultBool(l_ConfigVideoRice, "FullTMEMEmulation", FALSE, "N64 Texture Memory Full Emulation (may fix some games, may break others)"); ConfigSetDefaultBool(l_ConfigVideoRice, "OpenGLVertexClipper", FALSE, "Enable vertex clipper for fog operations"); ConfigSetDefaultBool(l_ConfigVideoRice, "SkipFrame", FALSE, "If this option is enabled, the plugin will skip every other frame"); ConfigSetDefaultBool(l_ConfigVideoRice, "TexRectOnly", FALSE, "If enabled, texture enhancement will be done only for TxtRect ucode"); ConfigSetDefaultBool(l_ConfigVideoRice, "SmallTextureOnly", FALSE, "If enabled, texture enhancement will be done only for textures width+height<=128"); ConfigSetDefaultBool(l_ConfigVideoRice, "LoadHiResCRCOnly", TRUE, "Select hi-resolution textures based only on the CRC and ignore format+size information (Glide64 compatibility)"); ConfigSetDefaultBool(l_ConfigVideoRice, "LoadHiResTextures", FALSE, "Enable hi-resolution texture file loading"); ConfigSetDefaultBool(l_ConfigVideoRice, "DumpTexturesToFiles", FALSE, "Enable texture dumping"); ConfigSetDefaultBool(l_ConfigVideoRice, "ShowFPS", FALSE, "Display On-screen FPS"); ConfigSetDefaultInt(l_ConfigVideoRice, "Mipmapping", 2, "Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear"); ConfigSetDefaultInt(l_ConfigVideoRice, "FogMethod", 0, "Enable, Disable or Force fog generation (0=Disable, 1=Enable n64 choose, 2=Force Fog)"); ConfigSetDefaultInt(l_ConfigVideoRice, "ForceTextureFilter", 0, "Force to use texture filtering or not (0=auto: n64 choose, 1=force no filtering, 2=force filtering)"); ConfigSetDefaultInt(l_ConfigVideoRice, "TextureEnhancement", 0, "Primary texture enhancement filter (0=None, 1=2X, 2=2XSAI, 3=HQ2X, 4=LQ2X, 5=HQ4X, 6=Sharpen, 7=Sharpen More, 8=External, 9=Mirrored)"); ConfigSetDefaultInt(l_ConfigVideoRice, "TextureEnhancementControl", 0, "Secondary texture enhancement filter (0 = none, 1-4 = filtered)"); ConfigSetDefaultInt(l_ConfigVideoRice, "TextureQuality", TXT_QUALITY_DEFAULT, "Color bit depth to use for textures (0=default, 1=32 bits, 2=16 bits)"); ConfigSetDefaultInt(l_ConfigVideoRice, "OpenGLDepthBufferSetting", 16, "Z-buffer depth (only 16 or 32)"); ConfigSetDefaultInt(l_ConfigVideoRice, "MultiSampling", 0, "Enable/Disable MultiSampling (0=off, 2,4,8,16=quality)"); ConfigSetDefaultInt(l_ConfigVideoRice, "ColorQuality", TEXTURE_FMT_A8R8G8B8, "Color bit depth for rendering window (0=32 bits, 1=16 bits)"); ConfigSetDefaultInt(l_ConfigVideoRice, "OpenGLRenderSetting", OGL_DEVICE, "OpenGL level to support (0=auto, 1=OGL_1.1, 2=OGL_1.2, 3=OGL_1.3, 4=OGL_1.4, 5=OGL_1.4_V2, 6=OGL_TNT2, 7=NVIDIA_OGL, 8=OGL_FRAGMENT_PROGRAM)"); return TRUE; } bool isMMXSupported() { unsigned cpu = 0; if (perf_get_cpu_features_cb) cpu = perf_get_cpu_features_cb(); if (cpu & RETRO_SIMD_MMX) return true; return false; } static void ReadConfiguration(void) { struct retro_variable var = { "mupen64-screensize", 0 }; bool ret = environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var); if (ret && var.value) { if (sscanf(var.value ? var.value : "640x480", "%dx%d", &screen_width, &screen_height) != 2) { screen_width = 640; screen_height = 480; } } else { screen_width = 640; screen_height =480; } windowSetting.uDisplayWidth = screen_width; windowSetting.uDisplayHeight = screen_height; windowSetting.bVerticalSync = ConfigGetParamBool(l_ConfigVideoGeneral, "VerticalSync"); defaultRomOptions.N64FrameBufferEmuType = ConfigGetParamInt(l_ConfigVideoRice, "FrameBufferSetting"); defaultRomOptions.N64FrameBufferWriteBackControl = ConfigGetParamInt(l_ConfigVideoRice, "FrameBufferWriteBackControl"); defaultRomOptions.N64RenderToTextureEmuType = ConfigGetParamInt(l_ConfigVideoRice, "RenderToTexture"); defaultRomOptions.screenUpdateSetting = ConfigGetParamInt(l_ConfigVideoRice, "screenUpdateSetting"); defaultRomOptions.bNormalBlender = ConfigGetParamBool(l_ConfigVideoRice, "NormalAlphaBlender"); defaultRomOptions.bFastTexCRC = ConfigGetParamBool(l_ConfigVideoRice, "FastTextureLoading"); defaultRomOptions.bAccurateTextureMapping = ConfigGetParamBool(l_ConfigVideoRice, "AccurateTextureMapping"); defaultRomOptions.bInN64Resolution = ConfigGetParamBool(l_ConfigVideoRice, "InN64Resolution"); defaultRomOptions.bSaveVRAM = ConfigGetParamBool(l_ConfigVideoRice, "SaveVRAM"); defaultRomOptions.bDoubleSizeForSmallTxtrBuf = ConfigGetParamBool(l_ConfigVideoRice, "DoubleSizeForSmallTxtrBuf"); defaultRomOptions.bNormalCombiner = ConfigGetParamBool(l_ConfigVideoRice, "DefaultCombinerDisable"); options.bEnableHacks = ConfigGetParamBool(l_ConfigVideoRice, "EnableHacks"); options.bWinFrameMode = ConfigGetParamBool(l_ConfigVideoRice, "WinFrameMode"); options.bFullTMEM = ConfigGetParamBool(l_ConfigVideoRice, "FullTMEMEmulation"); options.bOGLVertexClipper = ConfigGetParamBool(l_ConfigVideoRice, "OpenGLVertexClipper"); options.bSkipFrame = ConfigGetParamBool(l_ConfigVideoRice, "SkipFrame"); options.bTexRectOnly = ConfigGetParamBool(l_ConfigVideoRice, "TexRectOnly"); options.bSmallTextureOnly = ConfigGetParamBool(l_ConfigVideoRice, "SmallTextureOnly"); options.bLoadHiResTextures = ConfigGetParamBool(l_ConfigVideoRice, "LoadHiResTextures"); options.bLoadHiResCRCOnly = ConfigGetParamBool(l_ConfigVideoRice, "LoadHiResCRCOnly"); options.bDumpTexturesToFiles = ConfigGetParamBool(l_ConfigVideoRice, "DumpTexturesToFiles"); options.mipmapping = TEXTURE_NO_MIPMAP; //options.mipmapping = ConfigGetParamInt(l_ConfigVideoRice, "Mipmapping"); options.fogMethod = ConfigGetParamInt(l_ConfigVideoRice, "FogMethod"); options.forceTextureFilter = ConfigGetParamInt(l_ConfigVideoRice, "ForceTextureFilter"); options.textureEnhancement = ConfigGetParamInt(l_ConfigVideoRice, "TextureEnhancement"); options.textureEnhancementControl = ConfigGetParamInt(l_ConfigVideoRice, "TextureEnhancementControl"); options.textureQuality = ConfigGetParamInt(l_ConfigVideoRice, "TextureQuality"); options.OpenglDepthBufferSetting = ConfigGetParamInt(l_ConfigVideoRice, "OpenGLDepthBufferSetting"); options.multiSampling = ConfigGetParamInt(l_ConfigVideoRice, "MultiSampling"); options.colorQuality = ConfigGetParamInt(l_ConfigVideoRice, "ColorQuality"); options.OpenglRenderSetting = ConfigGetParamInt(l_ConfigVideoRice, "OpenGLRenderSetting"); CDeviceBuilder::SelectDeviceType((SupportedDeviceType)options.OpenglRenderSetting); status.isMMXSupported = isMMXSupported(); ProcessVertexData = ProcessVertexDataNoSSE; } bool LoadConfiguration(void) { #if 0 IniSections.clear(); bIniIsChanged = false; strcpy(szIniFileName, INI_FILE); if (!ReadIniFile()) { DebugMessage(M64MSG_ERROR, "Unable to read ini file from disk"); return FALSE; } #endif if (l_ConfigVideoGeneral == NULL || l_ConfigVideoRice == NULL) { DebugMessage(M64MSG_ERROR, "Rice Video configuration sections are not open!"); return FALSE; } // Read config parameters from core config API and set up internal variables ReadConfiguration(); return TRUE; } void GenerateCurrentRomOptions() { currentRomOptions.N64FrameBufferEmuType =g_curRomInfo.dwFrameBufferOption; currentRomOptions.N64FrameBufferWriteBackControl =defaultRomOptions.N64FrameBufferWriteBackControl; currentRomOptions.N64RenderToTextureEmuType =g_curRomInfo.dwRenderToTextureOption; currentRomOptions.screenUpdateSetting =g_curRomInfo.dwScreenUpdateSetting; currentRomOptions.bNormalCombiner =g_curRomInfo.dwNormalCombiner; currentRomOptions.bNormalBlender =g_curRomInfo.dwNormalBlender; currentRomOptions.bFastTexCRC =g_curRomInfo.dwFastTextureCRC; currentRomOptions.bAccurateTextureMapping =g_curRomInfo.dwAccurateTextureMapping; options.enableHackForGames = NO_HACK_FOR_GAME; if ((strncmp((char*)g_curRomInfo.szGameName, "BANJO TOOIE", 11) == 0)) { options.enableHackForGames = HACK_FOR_BANJO_TOOIE; } else if ((strncmp((char*)g_curRomInfo.szGameName, "DR.MARIO", 8) == 0)) { options.enableHackForGames = HACK_FOR_DR_MARIO; } else if ((strncasecmp((char*)g_curRomInfo.szGameName, "Pilot", 5) == 0)) { options.enableHackForGames = HACK_FOR_PILOT_WINGS; } else if ((strncasecmp((char*)g_curRomInfo.szGameName, "YOSHI", 5) == 0)) { options.enableHackForGames = HACK_FOR_YOSHI; } else if ((strncasecmp((char*)g_curRomInfo.szGameName, "NITRO", 5) == 0)) { options.enableHackForGames = HACK_FOR_NITRO; } else if ((strncasecmp((char*)g_curRomInfo.szGameName, "TONY HAWK", 9) == 0)) { options.enableHackForGames = HACK_FOR_TONYHAWK; } else if ((strncasecmp((char*)g_curRomInfo.szGameName, "THPS", 4) == 0)) { options.enableHackForGames = HACK_FOR_TONYHAWK; } else if ((strncasecmp((char*)g_curRomInfo.szGameName, "SPIDERMAN", 9) == 0)) { options.enableHackForGames = HACK_FOR_TONYHAWK; } else if ((strncasecmp((char*)g_curRomInfo.szGameName, "NASCAR", 6) == 0)) { options.enableHackForGames = HACK_FOR_NASCAR; } else if ((strstr((char*)g_curRomInfo.szGameName, "ZELDA") != 0) && (strstr((char*)g_curRomInfo.szGameName, "MASK") != 0)) { options.enableHackForGames = HACK_FOR_ZELDA_MM; } else if ((strstr((char*)g_curRomInfo.szGameName, "ZELDA") != 0)) { options.enableHackForGames = HACK_FOR_ZELDA; } else if ((strstr((char*)g_curRomInfo.szGameName, "Ogre") != 0)) { options.enableHackForGames = HACK_FOR_OGRE_BATTLE; } else if ((strstr((char*)g_curRomInfo.szGameName, "TWINE") != 0)) { options.enableHackForGames = HACK_FOR_TWINE; } else if ((strstr((char*)g_curRomInfo.szGameName, "Squadron") != 0)) { options.enableHackForGames = HACK_FOR_ROGUE_SQUADRON; } else if ((strstr((char*)g_curRomInfo.szGameName, "Baseball") != 0) && (strstr((char*)g_curRomInfo.szGameName, "Star") != 0)) { options.enableHackForGames = HACK_FOR_ALL_STAR_BASEBALL; } else if ((strstr((char*)g_curRomInfo.szGameName, "Tigger") != 0) && (strstr((char*)g_curRomInfo.szGameName, "Honey") != 0)) { options.enableHackForGames = HACK_FOR_TIGER_HONEY_HUNT; } else if ((strstr((char*)g_curRomInfo.szGameName, "Bust") != 0) && (strstr((char*)g_curRomInfo.szGameName, "Move") != 0)) { options.enableHackForGames = HACK_FOR_BUST_A_MOVE; } else if ((strncasecmp((char*)g_curRomInfo.szGameName, "MarioTennis",11) == 0)) { options.enableHackForGames = HACK_FOR_MARIO_TENNIS; } else if ((strncasecmp((char*)g_curRomInfo.szGameName, "SUPER BOWLING",13) == 0)) { options.enableHackForGames = HACK_FOR_SUPER_BOWLING; } else if ((strncasecmp((char*)g_curRomInfo.szGameName, "CONKER",6) == 0)) { options.enableHackForGames = HACK_FOR_CONKER; } else if ((strncasecmp((char*)g_curRomInfo.szGameName, "MK_MYTHOLOGIES",14) == 0)) { options.enableHackForGames = HACK_REVERSE_Y_COOR; } else if ((strncasecmp((char*)g_curRomInfo.szGameName, "Fighting Force",14) == 0)) { options.enableHackForGames = HACK_REVERSE_XY_COOR; } else if ((strncasecmp((char*)g_curRomInfo.szGameName, "GOLDENEYE",9) == 0)) { options.enableHackForGames = HACK_FOR_GOLDEN_EYE; } else if ((strncasecmp((char*)g_curRomInfo.szGameName, "F-ZERO",6) == 0)) { options.enableHackForGames = HACK_FOR_FZERO; } else if ((strncasecmp((char*)g_curRomInfo.szGameName, "Command&Conquer",15) == 0)) { options.enableHackForGames = HACK_FOR_COMMANDCONQUER; } else if ((strncasecmp((char*)g_curRomInfo.szGameName, "READY 2 RUMBLE",14) == 0)) { options.enableHackForGames = HACK_FOR_RUMBLE; } else if ((strncasecmp((char*)g_curRomInfo.szGameName, "READY to RUMBLE",15) == 0)) { options.enableHackForGames = HACK_FOR_RUMBLE; } else if ((strncasecmp((char*)g_curRomInfo.szGameName, "South Park Rally",16) == 0)) { options.enableHackForGames = HACK_FOR_SOUTH_PARK_RALLY; } else if ((strncasecmp((char*)g_curRomInfo.szGameName, "Extreme G 2",11) == 0)) { options.enableHackForGames = HACK_FOR_EXTREME_G2; } else if ((strncasecmp((char*)g_curRomInfo.szGameName, "MarioGolf64",11) == 0)) { options.enableHackForGames = HACK_FOR_MARIO_GOLF; } else if ((strncasecmp((char*)g_curRomInfo.szGameName, "MLB FEATURING",13) == 0)) { options.enableHackForGames = HACK_FOR_MLB; } else if ((strncasecmp((char*)g_curRomInfo.szGameName, "POLARISSNOCROSS",15) == 0)) { options.enableHackForGames = HACK_FOR_POLARISSNOCROSS; } else if ((strncasecmp((char*)g_curRomInfo.szGameName, "TOP GEAR RALLY",14) == 0)) { options.enableHackForGames = HACK_FOR_TOPGEARRALLY; } else if ((strncasecmp((char*)g_curRomInfo.szGameName, "DUKE NUKEM",10) == 0)) { options.enableHackForGames = HACK_FOR_DUKE_NUKEM; } else if ((strncasecmp((char*)g_curRomInfo.szGameName, "MARIOKART64",11) == 0)) { options.enableHackForGames = HACK_FOR_MARIO_KART; } if (options.enableHackForGames != NO_HACK_FOR_GAME) DebugMessage(M64MSG_INFO, "Enabled hacks for game: '%s'", g_curRomInfo.szGameName); if( currentRomOptions.N64FrameBufferEmuType == 0 ) currentRomOptions.N64FrameBufferEmuType = defaultRomOptions.N64FrameBufferEmuType; else currentRomOptions.N64FrameBufferEmuType--; if( currentRomOptions.N64RenderToTextureEmuType == 0 ) currentRomOptions.N64RenderToTextureEmuType = defaultRomOptions.N64RenderToTextureEmuType; else currentRomOptions.N64RenderToTextureEmuType--; if( currentRomOptions.screenUpdateSetting == 0 ) currentRomOptions.screenUpdateSetting = defaultRomOptions.screenUpdateSetting; #if 0 if( currentRomOptions.bNormalCombiner == 0 ) currentRomOptions.bNormalCombiner = defaultRomOptions.bNormalCombiner; else currentRomOptions.bNormalCombiner--; if( currentRomOptions.bNormalBlender == 0 ) currentRomOptions.bNormalBlender = defaultRomOptions.bNormalBlender; else currentRomOptions.bNormalBlender--; if( currentRomOptions.bFastTexCRC == 0 ) currentRomOptions.bFastTexCRC = defaultRomOptions.bFastTexCRC; else currentRomOptions.bFastTexCRC--; if( currentRomOptions.bAccurateTextureMapping == 0 ) currentRomOptions.bAccurateTextureMapping = defaultRomOptions.bAccurateTextureMapping; else currentRomOptions.bAccurateTextureMapping--; #endif options.bUseFullTMEM = ((options.bFullTMEM && (g_curRomInfo.dwFullTMEM == 0)) || g_curRomInfo.dwFullTMEM == 2); GenerateFrameBufferOptions(); if( options.enableHackForGames == HACK_FOR_MARIO_GOLF || options.enableHackForGames == HACK_FOR_MARIO_TENNIS ) { frameBufferOptions.bIgnoreRenderTextureIfHeightUnknown = true; } } void Ini_GetRomOptions(LPGAMESETTING pGameSetting) { #if 0 int i; i = FindIniEntry(pGameSetting->romheader.dwCRC1, pGameSetting->romheader.dwCRC2, pGameSetting->romheader.nCountryID, (char*)pGameSetting->szGameName, 1); pGameSetting->bDisableTextureCRC = IniSections[i].bDisableTextureCRC; pGameSetting->bDisableCulling = IniSections[i].bDisableCulling; pGameSetting->bIncTexRectEdge = IniSections[i].bIncTexRectEdge; pGameSetting->bZHack = IniSections[i].bZHack; pGameSetting->bTextureScaleHack = IniSections[i].bTextureScaleHack; pGameSetting->bPrimaryDepthHack = IniSections[i].bPrimaryDepthHack; pGameSetting->bTexture1Hack = IniSections[i].bTexture1Hack; pGameSetting->bFastLoadTile = IniSections[i].bFastLoadTile; pGameSetting->bUseSmallerTexture = IniSections[i].bUseSmallerTexture; pGameSetting->VIWidth = IniSections[i].VIWidth; pGameSetting->VIHeight = IniSections[i].VIHeight; pGameSetting->UseCIWidthAndRatio = IniSections[i].UseCIWidthAndRatio; pGameSetting->dwFullTMEM = IniSections[i].dwFullTMEM; pGameSetting->bTxtSizeMethod2 = IniSections[i].bTxtSizeMethod2; pGameSetting->bEnableTxtLOD = IniSections[i].bEnableTxtLOD; pGameSetting->dwFastTextureCRC = IniSections[i].dwFastTextureCRC; pGameSetting->bEmulateClear = IniSections[i].bEmulateClear; pGameSetting->bForceScreenClear = IniSections[i].bForceScreenClear; pGameSetting->dwAccurateTextureMapping = IniSections[i].dwAccurateTextureMapping; pGameSetting->dwNormalBlender = IniSections[i].dwNormalBlender; pGameSetting->bDisableBlender = IniSections[i].bDisableBlender; pGameSetting->dwNormalCombiner = IniSections[i].dwNormalCombiner; pGameSetting->bForceDepthBuffer = IniSections[i].bForceDepthBuffer; pGameSetting->bDisableObjBG = IniSections[i].bDisableObjBG; pGameSetting->dwFrameBufferOption = IniSections[i].dwFrameBufferOption; pGameSetting->dwRenderToTextureOption = IniSections[i].dwRenderToTextureOption; pGameSetting->dwScreenUpdateSetting = IniSections[i].dwScreenUpdateSetting; #endif } void Ini_StoreRomOptions(LPGAMESETTING pGameSetting) { #if 0 int i; i = FindIniEntry(pGameSetting->romheader.dwCRC1, pGameSetting->romheader.dwCRC2, pGameSetting->romheader.nCountryID, (char*)pGameSetting->szGameName, 0); if( IniSections[i].bDisableTextureCRC !=pGameSetting->bDisableTextureCRC ) { IniSections[i].bDisableTextureCRC =pGameSetting->bDisableTextureCRC ; bIniIsChanged=true; } if( IniSections[i].bDisableCulling !=pGameSetting->bDisableCulling ) { IniSections[i].bDisableCulling =pGameSetting->bDisableCulling ; bIniIsChanged=true; } if( IniSections[i].dwFastTextureCRC !=pGameSetting->dwFastTextureCRC ) { IniSections[i].dwFastTextureCRC =pGameSetting->dwFastTextureCRC ; bIniIsChanged=true; } if( IniSections[i].bEmulateClear !=pGameSetting->bEmulateClear ) { IniSections[i].bEmulateClear =pGameSetting->bEmulateClear ; bIniIsChanged=true; } if( IniSections[i].dwNormalBlender !=pGameSetting->dwNormalBlender ) { IniSections[i].dwNormalBlender =pGameSetting->dwNormalBlender ; bIniIsChanged=true; } if( IniSections[i].bDisableBlender !=pGameSetting->bDisableBlender ) { IniSections[i].bDisableBlender =pGameSetting->bDisableBlender ; bIniIsChanged=true; } if( IniSections[i].bForceScreenClear !=pGameSetting->bForceScreenClear ) { IniSections[i].bForceScreenClear =pGameSetting->bForceScreenClear ; bIniIsChanged=true; } if( IniSections[i].dwAccurateTextureMapping !=pGameSetting->dwAccurateTextureMapping ) { IniSections[i].dwAccurateTextureMapping =pGameSetting->dwAccurateTextureMapping ; bIniIsChanged=true; } if( IniSections[i].dwNormalCombiner !=pGameSetting->dwNormalCombiner ) { IniSections[i].dwNormalCombiner =pGameSetting->dwNormalCombiner ; bIniIsChanged=true; } if( IniSections[i].bForceDepthBuffer !=pGameSetting->bForceDepthBuffer ) { IniSections[i].bForceDepthBuffer =pGameSetting->bForceDepthBuffer ; bIniIsChanged=true; } if( IniSections[i].bDisableObjBG !=pGameSetting->bDisableObjBG ) { IniSections[i].bDisableObjBG =pGameSetting->bDisableObjBG ; bIniIsChanged=true; } if( IniSections[i].dwFrameBufferOption !=pGameSetting->dwFrameBufferOption ) { IniSections[i].dwFrameBufferOption =pGameSetting->dwFrameBufferOption ; bIniIsChanged=true; } if( IniSections[i].dwRenderToTextureOption !=pGameSetting->dwRenderToTextureOption ) { IniSections[i].dwRenderToTextureOption =pGameSetting->dwRenderToTextureOption ; bIniIsChanged=true; } if( IniSections[i].dwScreenUpdateSetting !=pGameSetting->dwScreenUpdateSetting ) { IniSections[i].dwScreenUpdateSetting =pGameSetting->dwScreenUpdateSetting ; bIniIsChanged=true; } if( IniSections[i].bIncTexRectEdge != pGameSetting->bIncTexRectEdge ) { IniSections[i].bIncTexRectEdge =pGameSetting->bIncTexRectEdge; bIniIsChanged=true; } if( IniSections[i].bZHack != pGameSetting->bZHack ) { IniSections[i].bZHack =pGameSetting->bZHack; bIniIsChanged=true; } if( IniSections[i].bTextureScaleHack != pGameSetting->bTextureScaleHack ) { IniSections[i].bTextureScaleHack =pGameSetting->bTextureScaleHack; bIniIsChanged=true; } if( IniSections[i].bPrimaryDepthHack != pGameSetting->bPrimaryDepthHack ) { IniSections[i].bPrimaryDepthHack =pGameSetting->bPrimaryDepthHack; bIniIsChanged=true; } if( IniSections[i].bTexture1Hack != pGameSetting->bTexture1Hack ) { IniSections[i].bTexture1Hack =pGameSetting->bTexture1Hack; bIniIsChanged=true; } if( IniSections[i].bFastLoadTile != pGameSetting->bFastLoadTile ) { IniSections[i].bFastLoadTile =pGameSetting->bFastLoadTile; bIniIsChanged=true; } if( IniSections[i].bUseSmallerTexture != pGameSetting->bUseSmallerTexture ) { IniSections[i].bUseSmallerTexture =pGameSetting->bUseSmallerTexture; bIniIsChanged=true; } if( IniSections[i].VIWidth != pGameSetting->VIWidth ) { IniSections[i].VIWidth =pGameSetting->VIWidth; bIniIsChanged=true; } if( IniSections[i].VIHeight != pGameSetting->VIHeight ) { IniSections[i].VIHeight =pGameSetting->VIHeight; bIniIsChanged=true; } if( IniSections[i].UseCIWidthAndRatio != pGameSetting->UseCIWidthAndRatio ) { IniSections[i].UseCIWidthAndRatio =pGameSetting->UseCIWidthAndRatio; bIniIsChanged=true; } if( IniSections[i].dwFullTMEM != pGameSetting->dwFullTMEM ) { IniSections[i].dwFullTMEM =pGameSetting->dwFullTMEM; bIniIsChanged=true; } if( IniSections[i].bTxtSizeMethod2 != pGameSetting->bTxtSizeMethod2 ) { IniSections[i].bTxtSizeMethod2 =pGameSetting->bTxtSizeMethod2; bIniIsChanged=true; } if( IniSections[i].bEnableTxtLOD != pGameSetting->bEnableTxtLOD ) { IniSections[i].bEnableTxtLOD =pGameSetting->bEnableTxtLOD; bIniIsChanged=true; } if( bIniIsChanged ) { WriteIniFile(); TRACE0("Rom option is changed and saved"); } #endif } //std::ifstream& getline( std::ifstream &is, char *str ); #if 0 char * left(const char * src, int nchars) { static char dst[300]; strncpy(dst,src,nchars); dst[nchars]=0; return dst; } char * right(const char *src, int nchars) { static char dst[300]; int srclen = strlen(src); if (nchars >= srclen) { strcpy(dst, src); } else { strncpy(dst, src + srclen - nchars, nchars); dst[nchars]=0; } return dst; } char * tidy(char * s) { char * p = s + strlen(s); p--; while (p >= s && (*p == ' ' || *p == 0xa || *p == '\n') ) { *p = 0; p--; } return s; } bool ReadIniFile() { std::ifstream inifile; char readinfo[100]; const char *ini_filepath = ConfigGetSharedDataFilepath(szIniFileName); DebugMessage(M64MSG_VERBOSE, "Reading .ini file: %s", ini_filepath); inifile.open(ini_filepath); if (inifile.fail()) { return FALSE; } while (getline(inifile,readinfo)/*&§ionno<999*/) { tidy(readinfo); if (readinfo[0] == '/') continue; if (!strcasecmp(readinfo,"")==0) { if (readinfo[0] == '{') //if a section heading { section newsection; readinfo[strlen(readinfo)-1]='\0'; strcpy(newsection.crccheck, readinfo+1); newsection.bDisableTextureCRC = FALSE; newsection.bDisableCulling = FALSE; newsection.bIncTexRectEdge = FALSE; newsection.bZHack = FALSE; newsection.bTextureScaleHack = FALSE; newsection.bFastLoadTile = FALSE; newsection.bUseSmallerTexture = FALSE; newsection.bPrimaryDepthHack = FALSE; newsection.bTexture1Hack = FALSE; newsection.bDisableObjBG = FALSE; newsection.VIWidth = -1; newsection.VIHeight = -1; newsection.UseCIWidthAndRatio = NOT_USE_CI_WIDTH_AND_RATIO; newsection.dwFullTMEM = 0; newsection.bTxtSizeMethod2 = FALSE; newsection.bEnableTxtLOD = FALSE; newsection.bEmulateClear = FALSE; newsection.bForceScreenClear = FALSE; newsection.bDisableBlender = FALSE; newsection.bForceDepthBuffer = FALSE; newsection.dwFastTextureCRC = 0; newsection.dwAccurateTextureMapping = 0; newsection.dwNormalBlender = 0; newsection.dwNormalCombiner = 0; newsection.dwFrameBufferOption = 0; newsection.dwRenderToTextureOption = 0; newsection.dwScreenUpdateSetting = 0; #if 0 IniSections.push_back(newsection); #endif } else { #if 0 int sectionno = IniSections.size() - 1; if (strcasecmp(left(readinfo,4), "Name")==0) strcpy(IniSections[sectionno].name,right(readinfo,strlen(readinfo)-5)); if (strcasecmp(left(readinfo,17), "DisableTextureCRC")==0) IniSections[sectionno].bDisableTextureCRC=true; if (strcasecmp(left(readinfo,14), "DisableCulling")==0) IniSections[sectionno].bDisableCulling=true; if (strcasecmp(left(readinfo,16), "PrimaryDepthHack")==0) IniSections[sectionno].bPrimaryDepthHack=true; if (strcasecmp(left(readinfo,12), "Texture1Hack")==0) IniSections[sectionno].bTexture1Hack=true; if (strcasecmp(left(readinfo,12), "FastLoadTile")==0) IniSections[sectionno].bFastLoadTile=true; if (strcasecmp(left(readinfo,17), "UseSmallerTexture")==0) IniSections[sectionno].bUseSmallerTexture=true; if (strcasecmp(left(readinfo,14), "IncTexRectEdge")==0) IniSections[sectionno].bIncTexRectEdge=true; if (strcasecmp(left(readinfo,5), "ZHack")==0) IniSections[sectionno].bZHack=true; if (strcasecmp(left(readinfo,16), "TexRectScaleHack")==0) IniSections[sectionno].bTextureScaleHack=true; if (strcasecmp(left(readinfo,7), "VIWidth")==0) IniSections[sectionno].VIWidth = strtol(right(readinfo,3),NULL,10); if (strcasecmp(left(readinfo,8), "VIHeight")==0) IniSections[sectionno].VIHeight = strtol(right(readinfo,3),NULL,10); if (strcasecmp(left(readinfo,18), "UseCIWidthAndRatio")==0) IniSections[sectionno].UseCIWidthAndRatio = strtol(right(readinfo,1),NULL,10); if (strcasecmp(left(readinfo,8), "FullTMEM")==0) IniSections[sectionno].dwFullTMEM = strtol(right(readinfo,1),NULL,10); if (strcasecmp(left(readinfo,24), "AlternativeTxtSizeMethod")==0) IniSections[sectionno].bTxtSizeMethod2 = strtol(right(readinfo,1),NULL,10); if (strcasecmp(left(readinfo,12), "EnableTxtLOD")==0) IniSections[sectionno].bEnableTxtLOD = strtol(right(readinfo,1),NULL,10); if (strcasecmp(left(readinfo,12), "DisableObjBG")==0) IniSections[sectionno].bDisableObjBG = strtol(right(readinfo,1),NULL,10); if (strcasecmp(left(readinfo,16), "ForceScreenClear")==0) IniSections[sectionno].bForceScreenClear = strtol(right(readinfo,1),NULL,10); if (strcasecmp(left(readinfo,22), "AccurateTextureMapping")==0) IniSections[sectionno].dwAccurateTextureMapping = strtol(right(readinfo,1),NULL,10); if (strcasecmp(left(readinfo,14), "FastTextureCRC")==0) IniSections[sectionno].dwFastTextureCRC = strtol(right(readinfo,1),NULL,10); if (strcasecmp(left(readinfo,12), "EmulateClear")==0) IniSections[sectionno].bEmulateClear = strtol(right(readinfo,1),NULL,10); if (strcasecmp(left(readinfo,18), "NormalAlphaBlender")==0) IniSections[sectionno].dwNormalBlender = strtol(right(readinfo,1),NULL,10); if (strcasecmp(left(readinfo,19), "DisableAlphaBlender")==0) IniSections[sectionno].bDisableBlender = strtol(right(readinfo,1),NULL,10); if (strcasecmp(left(readinfo,19), "NormalColorCombiner")==0) IniSections[sectionno].dwNormalCombiner = strtol(right(readinfo,1),NULL,10); if (strcasecmp(left(readinfo,16), "ForceDepthBuffer")==0) IniSections[sectionno].bForceDepthBuffer = strtol(right(readinfo,1),NULL,10); if (strcasecmp(left(readinfo,20), "FrameBufferEmulation")==0) IniSections[sectionno].dwFrameBufferOption = strtol(readinfo+21,NULL,10); if (strcasecmp(left(readinfo,15), "RenderToTexture")==0) IniSections[sectionno].dwRenderToTextureOption = strtol(right(readinfo,1),NULL,10); if (strcasecmp(left(readinfo,19), "ScreenUpdateSetting")==0) IniSections[sectionno].dwScreenUpdateSetting = strtol(right(readinfo,1),NULL,10); #endif } } } //inifile.close(); return TRUE; } //read a line from the ini file std::ifstream & getline(std::ifstream & is, char *str) { char buf[100]; is.getline(buf,100); strcpy( str,buf); return is; } void WriteIniFile() { uint32_t i; FILE * fhIn; FILE * fhOut; /* get path to game-hack INI file and read it */ const char *ini_filepath = ConfigGetSharedDataFilepath(szIniFileName); if (ini_filepath == NULL) return; fhIn = fopen(ini_filepath, "r"); if (fhIn == NULL) return; fseek(fhIn, 0L, SEEK_END); long filelen = ftell(fhIn); fseek(fhIn, 0L, SEEK_SET); char *chIniData = (char *) malloc(filelen + 1); if (chIniData == NULL) { fclose(fhIn); return; } long bytesread = fread(chIniData, 1, filelen, fhIn); fclose(fhIn); if (bytesread != filelen) { free(chIniData); return; } chIniData[filelen] = 0; /* now try to open the file for writing */ fhOut = fopen(ini_filepath, "w"); if (fhOut == NULL) { free(chIniData); return; } // Mark all sections and needing to be written for (i = 0; i < IniSections.size(); i++) { IniSections[i].bOutput = false; } char *thisline = chIniData; while ((thisline - chIniData) < filelen) { char *nextline = strchr(thisline, '\n'); if (nextline == NULL) nextline = thisline + strlen(thisline) + 1; else nextline++; if (thisline[0] == '{') { bool bFound = false; // Start of section tidy((char*) thisline); thisline[strlen(thisline) - 1] = '\0'; for (i = 0; i < IniSections.size(); i++) { if (IniSections[i].bOutput) continue; if (strcasecmp((char*) thisline + 1, IniSections[i].crccheck) == 0) { // Output this CRC OutputSectionDetails(i, fhOut); IniSections[i].bOutput = true; bFound = true; break; } } if (!bFound) { // Do what? This should never happen, unless the user // replaces the inifile while game is running! } } else if (thisline[0] == '/') { // Comment fputs((char*) thisline, fhOut); } thisline = nextline; } // Input buffer done- process any new entries! for (i = 0; i < IniSections.size(); i++) { // Skip any that have not been done. if (IniSections[i].bOutput) continue; // Output this CRC OutputSectionDetails(i, fhOut); IniSections[i].bOutput = true; } fclose(fhOut); free(chIniData); bIniIsChanged = false; } void OutputSectionDetails(uint32_t i, FILE * fh) { fprintf(fh, "{%s}\n", IniSections[i].crccheck); fprintf(fh, "Name=%s\n", IniSections[i].name); //fprintf(fh, "UCode=%d\n", IniSections[i].ucode); // Tri-state variables if (IniSections[i].dwAccurateTextureMapping != 0) fprintf(fh, "AccurateTextureMapping=%d\n", IniSections[i].dwAccurateTextureMapping); if (IniSections[i].dwFastTextureCRC != 0) fprintf(fh, "FastTextureCRC=%d\n", IniSections[i].dwFastTextureCRC); if (IniSections[i].dwNormalBlender != 0) fprintf(fh, "NormalAlphaBlender=%d\n", IniSections[i].dwNormalBlender); if (IniSections[i].dwNormalCombiner != 0) fprintf(fh, "NormalColorCombiner=%d\n", IniSections[i].dwNormalCombiner); // Normal bi-state variables if (IniSections[i].bDisableTextureCRC) fprintf(fh, "DisableTextureCRC\n"); if (IniSections[i].bDisableCulling) fprintf(fh, "DisableCulling\n"); if (IniSections[i].bPrimaryDepthHack) fprintf(fh, "PrimaryDepthHack\n"); if (IniSections[i].bTexture1Hack) fprintf(fh, "Texture1Hack\n"); if (IniSections[i].bFastLoadTile) fprintf(fh, "FastLoadTile\n"); if (IniSections[i].bUseSmallerTexture) fprintf(fh, "UseSmallerTexture\n"); if (IniSections[i].bIncTexRectEdge) fprintf(fh, "IncTexRectEdge\n"); if (IniSections[i].bZHack) fprintf(fh, "ZHack\n"); if (IniSections[i].bTextureScaleHack) fprintf(fh, "TexRectScaleHack\n"); if (IniSections[i].VIWidth > 0) fprintf(fh, "VIWidth=%d\n", IniSections[i].VIWidth); if (IniSections[i].VIHeight > 0) fprintf(fh, "VIHeight=%d\n", IniSections[i].VIHeight); if (IniSections[i].UseCIWidthAndRatio > 0) fprintf(fh, "UseCIWidthAndRatio=%d\n", IniSections[i].UseCIWidthAndRatio); if (IniSections[i].dwFullTMEM > 0) fprintf(fh, "FullTMEM=%d\n", IniSections[i].dwFullTMEM); if (IniSections[i].bTxtSizeMethod2 != FALSE ) fprintf(fh, "AlternativeTxtSizeMethod=%d\n", IniSections[i].bTxtSizeMethod2); if (IniSections[i].bEnableTxtLOD != FALSE ) fprintf(fh, "EnableTxtLOD=%d\n", IniSections[i].bEnableTxtLOD); if (IniSections[i].bDisableObjBG != 0 ) fprintf(fh, "DisableObjBG=%d\n", IniSections[i].bDisableObjBG); if (IniSections[i].bForceScreenClear != 0) fprintf(fh, "ForceScreenClear=%d\n", IniSections[i].bForceScreenClear); if (IniSections[i].bEmulateClear != 0) fprintf(fh, "EmulateClear=%d\n", IniSections[i].bEmulateClear); if (IniSections[i].bDisableBlender != 0) fprintf(fh, "DisableAlphaBlender=%d\n", IniSections[i].bDisableBlender); if (IniSections[i].bForceDepthBuffer != 0) fprintf(fh, "ForceDepthBuffer=%d\n", IniSections[i].bForceDepthBuffer); if (IniSections[i].dwFrameBufferOption != 0) fprintf(fh, "FrameBufferEmulation=%d\n", IniSections[i].dwFrameBufferOption); if (IniSections[i].dwRenderToTextureOption != 0) fprintf(fh, "RenderToTexture=%d\n", IniSections[i].dwRenderToTextureOption); if (IniSections[i].dwScreenUpdateSetting != 0) fprintf(fh, "ScreenUpdateSetting=%d\n", IniSections[i].dwScreenUpdateSetting); fprintf(fh, "\n"); // Spacer } // Find the entry corresponding to the specified rom. // If the rom is not found, a new entry is created // The resulting value is returned void __cdecl DebuggerAppendMsg (const char * Message, ...); static int FindIniEntry(uint32_t dwCRC1, uint32_t dwCRC2, uint8_t nCountryID, char* szName, int PrintInfo) { uint32_t i; unsigned char szCRC[50+1]; // Generate the CRC-ID for this rom: sprintf((char*)szCRC, "%08x%08x-%02x", (unsigned int)dwCRC1, (unsigned int)dwCRC2, nCountryID); for (i = 0; i < IniSections.size(); i++) { if (strcasecmp((char*)szCRC, IniSections[i].crccheck) == 0) { if (PrintInfo) DebugMessage(M64MSG_INFO, "Found ROM '%s', CRC %s", IniSections[i].name, szCRC); return i; } } // Add new entry!!! section newsection; if (PrintInfo) DebugMessage(M64MSG_INFO, "ROM (CRC %s) not found in INI file", szCRC); strcpy(newsection.crccheck, (char*)szCRC); strncpy(newsection.name, szName, 50); newsection.bDisableTextureCRC = FALSE; newsection.bDisableCulling = FALSE; newsection.bIncTexRectEdge = FALSE; newsection.bZHack = FALSE; newsection.bTextureScaleHack = FALSE; newsection.bFastLoadTile = FALSE; newsection.bUseSmallerTexture = FALSE; newsection.bPrimaryDepthHack = FALSE; newsection.bTexture1Hack = FALSE; newsection.bDisableObjBG = FALSE; newsection.VIWidth = -1; newsection.VIHeight = -1; newsection.UseCIWidthAndRatio = NOT_USE_CI_WIDTH_AND_RATIO; newsection.dwFullTMEM = 0; newsection.bTxtSizeMethod2 = FALSE; newsection.bEnableTxtLOD = FALSE; newsection.bEmulateClear = FALSE; newsection.bForceScreenClear = FALSE; newsection.bDisableBlender = FALSE; newsection.bForceDepthBuffer = FALSE; newsection.dwFastTextureCRC = 0; newsection.dwAccurateTextureMapping = 0; newsection.dwNormalBlender = 0; newsection.dwNormalCombiner = 0; newsection.dwFrameBufferOption = 0; newsection.dwRenderToTextureOption = 0; newsection.dwScreenUpdateSetting = 0; IniSections.push_back(newsection); bIniIsChanged = true; // Flag to indicate we should be updated return IniSections.size()-1; // -1 takes into account increment } #endif GameSetting g_curRomInfo; void ROM_GetRomNameFromHeader(unsigned char * szName, ROMHeader * pHdr) { unsigned char * p; memcpy(szName, pHdr->szName, 20); szName[20] = '\0'; p = szName + (strlen((char*)szName) -1); // -1 to skip null while (p >= szName && *p == ' ') { *p = 0; p--; } } uint32_t CountryCodeToTVSystem(uint32_t countryCode) { uint32_t system; switch(countryCode) { /* Demo */ case 0: system = TV_SYSTEM_NTSC; break; case '7': system = TV_SYSTEM_NTSC; break; case 0x41: system = TV_SYSTEM_NTSC; break; /* Germany */ case 0x44: system = TV_SYSTEM_PAL; break; /* USA */ case 0x45: system = TV_SYSTEM_NTSC; break; /* France */ case 0x46: system = TV_SYSTEM_PAL; break; /* Italy */ case 'I': system = TV_SYSTEM_PAL; break; /* Japan */ case 0x4A: system = TV_SYSTEM_NTSC; break; /* Europe - PAL */ case 0x50: system = TV_SYSTEM_PAL; break; case 'S': /* Spain */ system = TV_SYSTEM_PAL; break; /* Australia */ case 0x55: system = TV_SYSTEM_PAL; break; case 0x58: system = TV_SYSTEM_PAL; break; /* Australia */ case 0x59: system = TV_SYSTEM_PAL; break; case 0x20: case 0x21: case 0x38: case 0x70: system = TV_SYSTEM_PAL; break; /* ??? */ default: system = TV_SYSTEM_PAL; break; } return system; } mupen64plus-video-gliden64/src/L3D.h000664 001750 001750 00000000210 12655644434 020152 0ustar00sergiosergio000000 000000 #ifndef L3D_H #define L3D_H #include "Types.h" #define L3D_LINE3D 0xB5 void L3D_Line3D( u32 w0, u32 w1 ); void L3D_Init(); #endif mupen64plus-core/doc/000700 001750 001750 00000000000 12656647145 015603 5ustar00sergiosergio000000 000000 gles2rice/src/OGLDecodedMux.cpp000664 001750 001750 00000007066 12655644434 017465 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "OGLDecodedMux.h" #ifndef max #define max(a,b) ((a) > (b) ? (a) : (b)) #endif //======================================================================== void COGLDecodedMux::Simplify(void) { DecodedMux::Simplify(); } void COGLDecodedMux::Reformat(void) { DecodedMux::Reformat(true); signed cond3 = max(splitType[0], splitType[1]); signed cond2 = max(cond3, splitType[2]); mType = (CombinerFormatType)max(cond2, splitType[3]); } void COGLExtDecodedMux::Simplify(void) //======================================================================== { COGLDecodedMux::Simplify(); FurtherFormatForOGL2(); Reformat(); // Reformat again } void COGLExtDecodedMux::FurtherFormatForOGL2(void) { // This function is used by OGL 1.2, no need to call this function // for Nvidia register combiner // And OGL 1.2 extension only supports 1 constant color, we can not use both PRIM and ENV // constant color, and we can not use SPECULAR color as the 2nd color. // To further format the mux. // - For each stage, allow only 1 texel, change the 2nd texel in the same stage to MUX_SHADE // - Only allow 1 constant color. Count PRIM and ENV, left the most used one, and change // the 2nd one to MUX_SHADE if (Count(MUX_PRIM, -1, MUX_MASK) >= Count(MUX_ENV, -1, MUX_MASK)) { ReplaceVal(MUX_ENV, MUX_PRIM, -1, MUX_MASK); //ReplaceVal(MUX_ENV, MUX_SHADE, -1, MUX_MASK); //ReplaceVal(MUX_ENV, MUX_1, -1, MUX_MASK); //ReplaceVal(MUX_PRIM, MUX_0, -1, MUX_MASK); } else { //ReplaceVal(MUX_PRIM, MUX_ENV, -1, MUX_MASK); //ReplaceVal(MUX_PRIM, MUX_SHADE, -1, MUX_MASK); ReplaceVal(MUX_PRIM, MUX_0, -1, MUX_MASK); } /* // Because OGL 1.2, we may use more than 1 texture unit, but for each texture unit, // we can not use multitexture to do color combiner. Each combiner stage can only // use 1 texture. if (IsUsed(MUX_TEXEL0, MUX_MASK) && IsUsed(MUX_TEXEL1, MUX_MASK)) { if (Count(MUX_TEXEL0, 0, MUX_MASK)+Count(MUX_TEXEL0, 1, MUX_MASK) >= Count(MUX_TEXEL1, 0, MUX_MASK)+Count(MUX_TEXEL1, 1, MUX_MASK)) { ReplaceVal(MUX_TEXEL1, MUX_TEXEL0, 0, MUX_MASK); ReplaceVal(MUX_TEXEL1, MUX_TEXEL0, 1, MUX_MASK); } else { ReplaceVal(MUX_TEXEL0, MUX_TEXEL1, 0, MUX_MASK); ReplaceVal(MUX_TEXEL0, MUX_TEXEL1, 1, MUX_MASK); } if (Count(MUX_TEXEL0, 2, MUX_MASK)+Count(MUX_TEXEL0, 3, MUX_MASK) >= Count(MUX_TEXEL1, 2, MUX_MASK)+Count(MUX_TEXEL1, 3, MUX_MASK)) { ReplaceVal(MUX_TEXEL1, MUX_TEXEL0, 2, MUX_MASK); ReplaceVal(MUX_TEXEL1, MUX_TEXEL0, 3, MUX_MASK); } else { ReplaceVal(MUX_TEXEL0, MUX_TEXEL1, 2, MUX_MASK); ReplaceVal(MUX_TEXEL0, MUX_TEXEL1, 3, MUX_MASK); } } */ } mupen64plus-core/src/plugin/emulate_game_controller_via_input_plugin.h000664 001750 001750 00000003427 12655644434 027637 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - emulate_game_controller_via_input_plugin.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_PLUGIN_EMULATE_GAME_CONTROLLER_VIA_INPUT_PLUGIN_H #define M64P_PLUGIN_EMULATE_GAME_CONTROLLER_VIA_INPUT_PLUGIN_H #include enum pak_type; int egcvip_is_connected(void* opaque, enum pak_type* pak); uint32_t egcvip_get_input(void* opaque); #endif gles2rice/src/RenderBase_neon.h000664 001750 001750 00000000512 12655644434 017565 0ustar00sergiosergio000000 000000 #define PV_NEON_ENABLE_LIGHT (1 << 0) #define PV_NEON_ENABLE_SHADE (1 << 1) #define PV_NEON_ENABLE_FOG (1 << 2) // unused #define PV_NEON_FOG_ALPHA (1 << 3) #define X_CLIP_MAX 0x1 #define X_CLIP_MIN 0x2 #define Y_CLIP_MAX 0x4 #define Y_CLIP_MIN 0x8 #define OFFSETOF_Light_fr 0x14 #define SIZEOF_Light 0x44 jni/Application.mk000664 001750 001750 00000000127 12655644434 015273 0ustar00sergiosergio000000 000000 APP_ABI := armeabi armeabi-v7a x86 APP_STL := gnustl_static APP_PLATFORM := android-9 mupen64plus-core/doc/emuwiki-api-doc/Mupen64Plus_v2.0_Core_Debugger.txt000664 001750 001750 00000032774 12655644434 027001 0ustar00sergiosergio000000 000000 [[Mupen64Plus v2.0 Core API v1.0|Mupen64Plus v2.0 API]] = Mupen64Plus v2.0 Core Debugger API = Most libmupen64plus functions return an m64p_error return code, which is an enumerated type defined in [[Mupen64Plus v2.0 headers#m64p_types.h|m64p_types.h]]. Front-end code should check the return value of each call to a libmupen64plus function. == General Debugger Functions == {| border="1" |Prototype |'''m64p_error DebugSetCallbacks(void (*dbg_frontend_init)(void), void (*dbg_frontend_update)(unsigned int pc), void (*dbg_frontend_vi)(void))''' |- |Input Parameters |'''dbg_frontend_init''' Pointer to function which is called when debugger is initialized.
'''dbg_frontend_update''' Pointer to function which is called after debugger hits a breakpoint or executes one instruction in stepping mode.
'''dbg_frontend_vi''' Pointer to function which is called during each vertical interrupt. |- |Requirements |The Mupen64Plus library must be built with debugger support and must be initialized before calling this function. |- |Usage |This function is called by the front-end to supply debugger callback function pointers. If debugger is enabled and then later disabled within the GUI, this function may be called with NULL pointers in order to disable the callbacks. |}
{| border="1" |Prototype |'''m64p_error DebugSetCoreCompare(void (*dbg_core_compare)(unsigned int), void (*dbg_core_data_sync)(int, void *))''' |- |Input Parameters |'''dbg_core_compare''' Pointer to function which is called after each R4300 instruction, for comparing the operation of one R4300 emulator core against another.
'''dbg_core_data_sync''' Pointer to function which is used to transfer data from the sending emulator core to the receiving core, such as controller button press or movement data. |- |Requirements |The Mupen64Plus library must be initialized before calling this function. |- |Usage |This function is called by the front-end to supply callback function pointers for the Core Comparison feature. This feature is designed to work as follows. The front-end application will set up some channel for communicating data between two separately running instances of mupen64plus. For example, the unix console front-end will use named FIFOs. The front-end will register callback functions for comparing the 2 cores' states via this DebugSetCoreCompare API call. When the dbg_core_compare callback fires, the front-end will use the DebugGetCPUDataPtr function (and DebugMemGetPointer function if desired) to transmit emulator core state data from the 'sending' instance to the 'receiving' instance. The receiving instance may then check the core state data against it's own internal state and report any discrepancies. When the dbg_core_data_sync callback fires, the front-end should transmit a block of data from the sending instance to the receiving instance. This is for the purposes of synchronizing events such as controller inputs or state loading commands, so that the 2 cores may stay synchronized. This feature does not require the M64CAPS_DEBUGGER capability to built into the core, but it does require the M64CAPS_CORE_COMPARE capability. |}
{| border="1" |Prototype |'''m64p_error DebugSetRunState(int runstate)''' |- |Input Parameters |'''runstate''' 0 == pause, 1 == single instruction step, 2 == run |- |Requirements |The Mupen64Plus library must be built with debugger support and must be initialized before calling this function. |- |Usage |This function sets the run state of the R4300 CPU emulator. |}
{| border="1" |Prototype |'''int DebugGetState(m64p_dbg_state statenum)''' |- |Input Parameters |'''statenum''' An m64p_dbg_state enumerated type specifying which debugger state variable to read. |- |Requirements |The Mupen64Plus library must be built with debugger support and must be initialized before calling this function. |- |Usage |This function reads and returns a debugger state variable, which are enumerated in [[Mupen64Plus v2.0 headers#m64p_types.h|m64p_types.h]]. |}
{| border="1" |Prototype |'''m64p_error DebugStep(void)''' |- |Requirements |The Mupen64Plus library must be built with debugger support and must be initialized, the emulator core must be executing a ROM, and the debugger must be active before calling this function. |- |Usage |This function signals the debugger to advance one instruction when in the stepping mode. |}
{| border="1" |Prototype |'''void DebugDecodeOp(unsigned int instruction, char *op, char *args, int pc)''' |- |Input Parameters |'''instruction''' 32-bit R4300 instruction opcode
'''op''' Pointer to character array to store decoded instruction mnemonic
'''args''' Pointer to character array to store instruction arguments
'''pc''' Program Counter address at which '''instruction''' is stored |- |Requirements |The Mupen64Plus library must be built with debugger support. |- |Usage |This is a helper function for the debugger front-end. This instruction takes a PC value and an R4300 instruction opcode and writes the disassembled instruction mnemonic and arguments into character buffers. This is intended to be used to display disassembled code. |} == Memory Functions == {| border="1" |Prototype |'''void * DebugMemGetRecompInfo(m64p_dbg_mem_info recomp_type, unsigned int address, int index)''' |- |Input Parameters |'''recomp_type''' Type of information to retrieve about a recompiled machine instruction. Must be a M64P_DBG_RECOMP_* type.
'''address''' Program Counter value (in N64 memory space) of R4300 instruction about which to retrieve the recompiled x86 instructions.
'''index''' Index of recompiled instruction about which to receive information. |- |Requirements |The Mupen64Plus library must be built with debugger support and must be initialized before calling this function. This function may not be available on all platforms. |- |Usage |This function is used by the front-end to retrieve disassembly information about recompiled code. For example, the dynamic recompiler may take a single R4300 instruction and compile it into 10 x86 instructions. This function may then be used to retrieve the disassembled code of the 10 x86 instructions. For '''recomp_type''' of M64P_DBG_RECOMP_OPCODE or M64P_DBG_RECOMP_ARGS, a character pointer will be returned which gives the disassembled instruction code. For '''recomp_type''' of M64P_DBG_RECOMP_ADDR, a pointer to the recompiled x86 instruction will be given. |}
{| border="1" |Prototype |'''int DebugMemGetMemInfo(m64p_dbg_mem_info mem_info_type, unsigned int address)''' |- |Input Parameters |'''mem_info_type''' Type of information to retrieve about an N64 memory location. Must be a M64P_DBG_MEM_* type.
'''address''' Memory location (in N64 memory space) about which to retrieve some information. |- |Requirements |The Mupen64Plus library must be built with debugger support and must be initialized before calling this function. |- |Usage |This function returns an integer value regarding the memory location '''address''', corresponding to the information requested by '''mem_info_type''', which is a type enumerated in [[Mupen64Plus v2.0 headers#m64p_types.h|m64p_types.h]]. For example, if '''address''' contains R4300 program code, the front-end may request the number of x86 instructions emitted by the dynamic recompiler by requesting M64P_DBG_MEM_NUM_RECOMPILED. |}
{| border="1" |Prototype |'''void * DebugMemGetPointer(m64p_dbg_memptr_type mem_ptr_type)''' |- |Input Parameters |'''mem_ptr_type''' Memory type to which a pointer is requested. |- |Requirements |The Mupen64Plus library must be initialized before calling this function. |- |Usage |This function returns a memory pointer (in x86 memory space) to a block of emulated N64 memory. This may be used to retrieve a pointer to a special N64 block (such as the serial, video, or audio registers) or the RDRAM. The '''m64p_dbg_memptr_type''' type is enumerated in [[Mupen64Plus v2.0 headers#m64p_types.h|m64p_types.h]] |}
{| border="1" |Prototype | {| |- |'''unsigned long long''' || '''DebugMemRead64(unsigned int address)''' |- |'''unsigned int''' || '''DebugMemRead32(unsigned int address)''' |- |'''unsigned short''' || '''DebugMemRead16(unsigned int address)''' |- |'''unsigned char''' || '''DebugMemRead8(unsigned int address)''' |} |- |Input Parameters |'''address''' Memory location (in N64 memory space) from which to retrieve a value.
|- |Requirements |The Mupen64Plus library must be built with debugger support and must be initialized before calling this function. |- |Usage |These functions retrieve a value from the emulated N64 memory. The returned value will be correctly byte-swapped for the host architecture. |}
{| border="1" |Prototype |'''void DebugMemWrite64(unsigned int address, unsigned long long value)'''
'''void DebugMemWrite32(unsigned int address, unsigned int value)'''
'''void DebugMemWrite16(unsigned int address, unsigned short value)'''
'''void DebugMemWrite8(unsigned int address, unsigned char value)''' |- |Input Parameters |'''address''' Memory location (in N64 memory space) to which to write a value.
'''value''' Value to write into emulated memory. |- |Requirements |The Mupen64Plus library must be built with debugger support and must be initialized before calling this function. |- |Usage |These functions write a value into the emulated N64 memory. The given value will be correctly byte-swapped before storage. |} == R4300 CPU Functions == {| border="1" |Prototype |'''void *DebugGetCPUDataPtr(m64p_dbg_cpu_data cpu_data_type)''' |- |Input Parameters |'''cpu_data_type''' CPU register type to which a pointer is requested.
|- |Requirements |The Mupen64Plus library must be initialized before calling this function. |- |Usage |This function returns a memory pointer (in x86 memory space) to a specific register in the emulated R4300 CPU. The '''m64p_dbg_cpu_data''' type is enumerated in [[Mupen64Plus v2.0 headers#m64p_types.h|m64p_types.h]]. It is important to note that when the R4300 CPU core is in the Cached Interpreter or Dynamic Recompiler modes, the address of the PC register is not constant; it will change after each instruction is executed. The pointers to all other registers will never change, as the other registers are global variables. |} == Breakpoint Functions == {| border="1" |Prototype |'''int DebugBreakpointLookup(unsigned int address, unsigned int size, unsigned int flags)''' |- |Input Parameters |'''address''' Starting address (in R4300 memory space) to search
'''size''' Size of address space in bytes to search
'''flags''' Breakpoint flags |- |Requirements |The Mupen64Plus library must be built with debugger support and must be initialized before calling this function. |- |Usage |This function searches through all current breakpoints in the debugger to find one that matches the given input parameters. If a matching breakpoint is found, the index number is returned. If no breakpoints are found, -1 is returned. |}
{| border="1" |Prototype |'''int DebugBreakpointCommand(m64p_dbg_bkp_command command, unsigned int index, void *ptr)''' |- |Input Parameters |'''command''' Enumerated value specifying the breakpoint command to execute
'''index''' Purpose varies by command, see table below
'''ptr''' Purpose varies by command, see table below |- |Requirements |The Mupen64Plus library must be built with debugger support and must be initialized before calling this function. |- |Usage |This function is used to process common breakpoint commands, such as adding, removing, or searching the breakpoints. The meanings of the '''index''' and '''ptr''' input parameters vary by command, and are given in the table below. The '''m64p_dbg_bkp_command''' type is enumerated in [[Mupen64Plus v2.0 headers#m64p_types.h|m64p_types.h]]. |}
{| border="1" !Command!!Return Value!!Function!!index Parameter!!ptr Parameter |- |M64P_BKP_CMD_ADD_ADDR |Index of new breakpoint |Add an execution breakpoint at a given R4300 address. |R4300 address |unused |- |M64P_BKP_CMD_ADD_STRUCT |Index of new breakpoint |Add a custom breakpoint specified in a breakpoint structure. |unused |Pointer to breakpoint struct of new breakpoint |- |M64P_BKP_CMD_REPLACE |unused |Replace an existing breakpoint with one specified by a breakpoint structure. |Index of breakpoint to replace |Pointer to breakpoint struct of new breakpoint |- |M64P_BKP_CMD_REMOVE_ADDR |unused |Remove an existing breakpoint |R4300 address of breakpoint to remove |unused |- |M64P_BKP_CMD_REMOVE_IDX |unused |Remove an existing breakpoint |Index of breakpoint to remove |unused |- |M64P_BKP_CMD_ENABLE |unused |Enable a specified breakpoint |Index of breakpoint to enable |unused |- |M64P_BKP_CMD_DISABLE |unused |Disable a specified breakpoint |Index of breakpoint to disable |unused |- |M64P_BKP_CMD_CHECK |Index of breakpoint if found, otherwise -1 |Search for an execution breakpoint at a given address |R4300 address at which to search |unused |} mupen64plus-core/src/r4300/hacktarux_dynarec/gcop1_w.c000664 001750 001750 00000005632 12655644434 023616 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - gcop1_w.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2007 Richard Goedeken (Richard42) * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include "assemble.h" #include "interpret.h" #include "r4300/recomph.h" #include "r4300/r4300.h" #include "r4300/ops.h" #include "r4300/cp1_private.h" void gencvt_s_w(void) { #ifdef INTERPRET_CVT_S_W gencallinterp((native_type)cached_interpreter_table.CVT_S_W, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fild_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fd])); fstp_preg64_dword(RAX); #else mov_eax_memoffs32((unsigned int*)(®_cop1_simple[dst->f.cf.fs])); fild_preg32_dword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_simple[dst->f.cf.fd])); fstp_preg32_dword(EAX); #endif #endif } void gencvt_d_w(void) { #ifdef INTERPRET_CVT_D_W gencallinterp((native_type)cached_interpreter_table.CVT_D_W, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fild_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fd])); fstp_preg64_qword(RAX); #else mov_eax_memoffs32((unsigned int*)(®_cop1_simple[dst->f.cf.fs])); fild_preg32_dword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fd])); fstp_preg32_qword(EAX); #endif #endif } libretro-common/include/glsym/glsym_gl.h000664 001750 001750 00000716300 12655644434 021602 0ustar00sergiosergio000000 000000 /* Copyright (C) 2010-2015 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this libretro SDK code part (glsym). * --------------------------------------------------------------------------------------- * * Permission is hereby granted, free of charge, * to any person obtaining a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef RGLGEN_DECL_H__ #define RGLGEN_DECL_H__ #ifdef __cplusplus extern "C" { #endif #ifdef GL_APIENTRY typedef void (GL_APIENTRY *RGLGENGLDEBUGPROC)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*); typedef void (GL_APIENTRY *RGLGENGLDEBUGPROCKHR)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*); #else #ifndef APIENTRY #define APIENTRY #endif #ifndef APIENTRYP #define APIENTRYP APIENTRY * #endif typedef void (APIENTRY *RGLGENGLDEBUGPROCARB)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*); typedef void (APIENTRY *RGLGENGLDEBUGPROC)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*); #endif #ifndef GL_OES_EGL_image typedef void *GLeglImageOES; #endif #if !defined(GL_OES_fixed_point) && !defined(HAVE_OPENGLES2) typedef GLint GLfixed; #endif #if defined(__MACH__) && !defined(OS_TARGET_IPHONE) && !defined(MAC_OS_X_VERSION_10_7) typedef long long int GLint64; typedef unsigned long long int GLuint64; typedef unsigned long long int GLuint64EXT; typedef struct __GLsync *GLsync; #endif typedef void (APIENTRYP RGLSYMGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); typedef void (APIENTRYP RGLSYMGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); typedef void (APIENTRYP RGLSYMGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); typedef void (APIENTRYP RGLSYMGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP RGLSYMGLACTIVETEXTUREPROC) (GLenum texture); typedef void (APIENTRYP RGLSYMGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert); typedef void (APIENTRYP RGLSYMGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); typedef void (APIENTRYP RGLSYMGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); typedef void (APIENTRYP RGLSYMGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); typedef void (APIENTRYP RGLSYMGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); typedef void (APIENTRYP RGLSYMGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); typedef void (APIENTRYP RGLSYMGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); typedef void (APIENTRYP RGLSYMGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, void *img); typedef void (APIENTRYP RGLSYMGLCLIENTACTIVETEXTUREPROC) (GLenum texture); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP RGLSYMGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat *m); typedef void (APIENTRYP RGLSYMGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble *m); typedef void (APIENTRYP RGLSYMGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat *m); typedef void (APIENTRYP RGLSYMGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble *m); typedef void (APIENTRYP RGLSYMGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); typedef void (APIENTRYP RGLSYMGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); typedef void (APIENTRYP RGLSYMGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount); typedef void (APIENTRYP RGLSYMGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP RGLSYMGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params); typedef void (APIENTRYP RGLSYMGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); typedef void (APIENTRYP RGLSYMGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params); typedef void (APIENTRYP RGLSYMGLFOGCOORDFPROC) (GLfloat coord); typedef void (APIENTRYP RGLSYMGLFOGCOORDFVPROC) (const GLfloat *coord); typedef void (APIENTRYP RGLSYMGLFOGCOORDDPROC) (GLdouble coord); typedef void (APIENTRYP RGLSYMGLFOGCOORDDVPROC) (const GLdouble *coord); typedef void (APIENTRYP RGLSYMGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const void *pointer); typedef void (APIENTRYP RGLSYMGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); typedef void (APIENTRYP RGLSYMGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); typedef void (APIENTRYP RGLSYMGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); typedef void (APIENTRYP RGLSYMGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); typedef void (APIENTRYP RGLSYMGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); typedef void (APIENTRYP RGLSYMGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); typedef void (APIENTRYP RGLSYMGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); typedef void (APIENTRYP RGLSYMGLSECONDARYCOLOR3IVPROC) (const GLint *v); typedef void (APIENTRYP RGLSYMGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); typedef void (APIENTRYP RGLSYMGLSECONDARYCOLOR3SVPROC) (const GLshort *v); typedef void (APIENTRYP RGLSYMGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); typedef void (APIENTRYP RGLSYMGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); typedef void (APIENTRYP RGLSYMGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); typedef void (APIENTRYP RGLSYMGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); typedef void (APIENTRYP RGLSYMGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); typedef void (APIENTRYP RGLSYMGLSECONDARYCOLOR3USVPROC) (const GLushort *v); typedef void (APIENTRYP RGLSYMGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); typedef void (APIENTRYP RGLSYMGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); typedef void (APIENTRYP RGLSYMGLWINDOWPOS2DVPROC) (const GLdouble *v); typedef void (APIENTRYP RGLSYMGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); typedef void (APIENTRYP RGLSYMGLWINDOWPOS2FVPROC) (const GLfloat *v); typedef void (APIENTRYP RGLSYMGLWINDOWPOS2IPROC) (GLint x, GLint y); typedef void (APIENTRYP RGLSYMGLWINDOWPOS2IVPROC) (const GLint *v); typedef void (APIENTRYP RGLSYMGLWINDOWPOS2SPROC) (GLshort x, GLshort y); typedef void (APIENTRYP RGLSYMGLWINDOWPOS2SVPROC) (const GLshort *v); typedef void (APIENTRYP RGLSYMGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP RGLSYMGLWINDOWPOS3DVPROC) (const GLdouble *v); typedef void (APIENTRYP RGLSYMGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP RGLSYMGLWINDOWPOS3FVPROC) (const GLfloat *v); typedef void (APIENTRYP RGLSYMGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); typedef void (APIENTRYP RGLSYMGLWINDOWPOS3IVPROC) (const GLint *v); typedef void (APIENTRYP RGLSYMGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP RGLSYMGLWINDOWPOS3SVPROC) (const GLshort *v); typedef void (APIENTRYP RGLSYMGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); typedef void (APIENTRYP RGLSYMGLBLENDEQUATIONPROC) (GLenum mode); typedef void (APIENTRYP RGLSYMGLGENQUERIESPROC) (GLsizei n, GLuint *ids); typedef void (APIENTRYP RGLSYMGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids); typedef GLboolean (APIENTRYP RGLSYMGLISQUERYPROC) (GLuint id); typedef void (APIENTRYP RGLSYMGLBEGINQUERYPROC) (GLenum target, GLuint id); typedef void (APIENTRYP RGLSYMGLENDQUERYPROC) (GLenum target); typedef void (APIENTRYP RGLSYMGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params); typedef void (APIENTRYP RGLSYMGLBINDBUFFERPROC) (GLenum target, GLuint buffer); typedef void (APIENTRYP RGLSYMGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers); typedef void (APIENTRYP RGLSYMGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers); typedef GLboolean (APIENTRYP RGLSYMGLISBUFFERPROC) (GLuint buffer); typedef void (APIENTRYP RGLSYMGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage); typedef void (APIENTRYP RGLSYMGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); typedef void (APIENTRYP RGLSYMGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, void *data); typedef void *(APIENTRYP RGLSYMGLMAPBUFFERPROC) (GLenum target, GLenum access); typedef GLboolean (APIENTRYP RGLSYMGLUNMAPBUFFERPROC) (GLenum target); typedef void (APIENTRYP RGLSYMGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, void **params); typedef void (APIENTRYP RGLSYMGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); typedef void (APIENTRYP RGLSYMGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs); typedef void (APIENTRYP RGLSYMGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); typedef void (APIENTRYP RGLSYMGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask); typedef void (APIENTRYP RGLSYMGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); typedef void (APIENTRYP RGLSYMGLATTACHSHADERPROC) (GLuint program, GLuint shader); typedef void (APIENTRYP RGLSYMGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name); typedef void (APIENTRYP RGLSYMGLCOMPILESHADERPROC) (GLuint shader); typedef GLuint (APIENTRYP RGLSYMGLCREATEPROGRAMPROC) (void); typedef GLuint (APIENTRYP RGLSYMGLCREATESHADERPROC) (GLenum type); typedef void (APIENTRYP RGLSYMGLDELETEPROGRAMPROC) (GLuint program); typedef void (APIENTRYP RGLSYMGLDELETESHADERPROC) (GLuint shader); typedef void (APIENTRYP RGLSYMGLDETACHSHADERPROC) (GLuint program, GLuint shader); typedef void (APIENTRYP RGLSYMGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); typedef void (APIENTRYP RGLSYMGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); typedef void (APIENTRYP RGLSYMGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); typedef void (APIENTRYP RGLSYMGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); typedef void (APIENTRYP RGLSYMGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); typedef GLint (APIENTRYP RGLSYMGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name); typedef void (APIENTRYP RGLSYMGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); typedef void (APIENTRYP RGLSYMGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); typedef void (APIENTRYP RGLSYMGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); typedef GLint (APIENTRYP RGLSYMGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); typedef void (APIENTRYP RGLSYMGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params); typedef void (APIENTRYP RGLSYMGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params); typedef void (APIENTRYP RGLSYMGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble *params); typedef void (APIENTRYP RGLSYMGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params); typedef void (APIENTRYP RGLSYMGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer); typedef GLboolean (APIENTRYP RGLSYMGLISPROGRAMPROC) (GLuint program); typedef GLboolean (APIENTRYP RGLSYMGLISSHADERPROC) (GLuint shader); typedef void (APIENTRYP RGLSYMGLLINKPROGRAMPROC) (GLuint program); typedef void (APIENTRYP RGLSYMGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); typedef void (APIENTRYP RGLSYMGLUSEPROGRAMPROC) (GLuint program); typedef void (APIENTRYP RGLSYMGLUNIFORM1FPROC) (GLint location, GLfloat v0); typedef void (APIENTRYP RGLSYMGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); typedef void (APIENTRYP RGLSYMGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); typedef void (APIENTRYP RGLSYMGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); typedef void (APIENTRYP RGLSYMGLUNIFORM1IPROC) (GLint location, GLint v0); typedef void (APIENTRYP RGLSYMGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); typedef void (APIENTRYP RGLSYMGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); typedef void (APIENTRYP RGLSYMGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); typedef void (APIENTRYP RGLSYMGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP RGLSYMGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP RGLSYMGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP RGLSYMGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP RGLSYMGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLVALIDATEPROGRAMPROC) (GLuint program); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); typedef void (APIENTRYP RGLSYMGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLCOLORMASKIPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); typedef void (APIENTRYP RGLSYMGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data); typedef void (APIENTRYP RGLSYMGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data); typedef void (APIENTRYP RGLSYMGLENABLEIPROC) (GLenum target, GLuint index); typedef void (APIENTRYP RGLSYMGLDISABLEIPROC) (GLenum target, GLuint index); typedef GLboolean (APIENTRYP RGLSYMGLISENABLEDIPROC) (GLenum target, GLuint index); typedef void (APIENTRYP RGLSYMGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode); typedef void (APIENTRYP RGLSYMGLENDTRANSFORMFEEDBACKPROC) (void); typedef void (APIENTRYP RGLSYMGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); typedef void (APIENTRYP RGLSYMGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer); typedef void (APIENTRYP RGLSYMGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); typedef void (APIENTRYP RGLSYMGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); typedef void (APIENTRYP RGLSYMGLCLAMPCOLORPROC) (GLenum target, GLenum clamp); typedef void (APIENTRYP RGLSYMGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode); typedef void (APIENTRYP RGLSYMGLENDCONDITIONALRENDERPROC) (void); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); typedef void (APIENTRYP RGLSYMGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint *params); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBI1IPROC) (GLuint index, GLint x); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBI2IPROC) (GLuint index, GLint x, GLint y); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBI3IPROC) (GLuint index, GLint x, GLint y, GLint z); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBI1UIPROC) (GLuint index, GLuint x); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBI2UIPROC) (GLuint index, GLuint x, GLuint y); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBI3UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBI1IVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBI2IVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBI3IVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBI1UIVPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBI2UIVPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBI3UIVPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBI4BVPROC) (GLuint index, const GLbyte *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBI4SVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBI4UBVPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBI4USVPROC) (GLuint index, const GLushort *v); typedef void (APIENTRYP RGLSYMGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint *params); typedef void (APIENTRYP RGLSYMGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint color, const GLchar *name); typedef GLint (APIENTRYP RGLSYMGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar *name); typedef void (APIENTRYP RGLSYMGLUNIFORM1UIPROC) (GLint location, GLuint v0); typedef void (APIENTRYP RGLSYMGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1); typedef void (APIENTRYP RGLSYMGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); typedef void (APIENTRYP RGLSYMGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); typedef void (APIENTRYP RGLSYMGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP RGLSYMGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP RGLSYMGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP RGLSYMGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP RGLSYMGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP RGLSYMGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint *params); typedef void (APIENTRYP RGLSYMGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint *params); typedef void (APIENTRYP RGLSYMGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint *value); typedef void (APIENTRYP RGLSYMGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint *value); typedef void (APIENTRYP RGLSYMGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); typedef const GLubyte *(APIENTRYP RGLSYMGLGETSTRINGIPROC) (GLenum name, GLuint index); typedef GLboolean (APIENTRYP RGLSYMGLISRENDERBUFFERPROC) (GLuint renderbuffer); typedef void (APIENTRYP RGLSYMGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); typedef void (APIENTRYP RGLSYMGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers); typedef void (APIENTRYP RGLSYMGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers); typedef void (APIENTRYP RGLSYMGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); typedef void (APIENTRYP RGLSYMGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef GLboolean (APIENTRYP RGLSYMGLISFRAMEBUFFERPROC) (GLuint framebuffer); typedef void (APIENTRYP RGLSYMGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); typedef void (APIENTRYP RGLSYMGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers); typedef void (APIENTRYP RGLSYMGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers); typedef GLenum (APIENTRYP RGLSYMGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); typedef void (APIENTRYP RGLSYMGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); typedef void (APIENTRYP RGLSYMGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); typedef void (APIENTRYP RGLSYMGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); typedef void (APIENTRYP RGLSYMGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); typedef void (APIENTRYP RGLSYMGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLGENERATEMIPMAPPROC) (GLenum target); typedef void (APIENTRYP RGLSYMGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); typedef void (APIENTRYP RGLSYMGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); typedef void (APIENTRYP RGLSYMGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); typedef void *(APIENTRYP RGLSYMGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); typedef void (APIENTRYP RGLSYMGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length); typedef void (APIENTRYP RGLSYMGLBINDVERTEXARRAYPROC) (GLuint array); typedef void (APIENTRYP RGLSYMGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays); typedef void (APIENTRYP RGLSYMGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays); typedef GLboolean (APIENTRYP RGLSYMGLISVERTEXARRAYPROC) (GLuint array); typedef void (APIENTRYP RGLSYMGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); typedef void (APIENTRYP RGLSYMGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); typedef void (APIENTRYP RGLSYMGLTEXBUFFERPROC) (GLenum target, GLenum internalformat, GLuint buffer); typedef void (APIENTRYP RGLSYMGLPRIMITIVERESTARTINDEXPROC) (GLuint index); typedef void (APIENTRYP RGLSYMGLCOPYBUFFERSUBDATAPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); typedef void (APIENTRYP RGLSYMGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); typedef void (APIENTRYP RGLSYMGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLGETACTIVEUNIFORMNAMEPROC) (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName); typedef GLuint (APIENTRYP RGLSYMGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar *uniformBlockName); typedef void (APIENTRYP RGLSYMGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); typedef void (APIENTRYP RGLSYMGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); typedef void (APIENTRYP RGLSYMGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); typedef void (APIENTRYP RGLSYMGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); typedef void (APIENTRYP RGLSYMGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); typedef void (APIENTRYP RGLSYMGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex); typedef void (APIENTRYP RGLSYMGLPROVOKINGVERTEXPROC) (GLenum mode); typedef GLsync (APIENTRYP RGLSYMGLFENCESYNCPROC) (GLenum condition, GLbitfield flags); typedef GLboolean (APIENTRYP RGLSYMGLISSYNCPROC) (GLsync sync); typedef void (APIENTRYP RGLSYMGLDELETESYNCPROC) (GLsync sync); typedef GLenum (APIENTRYP RGLSYMGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); typedef void (APIENTRYP RGLSYMGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); typedef void (APIENTRYP RGLSYMGLGETINTEGER64VPROC) (GLenum pname, GLint64 *data); typedef void (APIENTRYP RGLSYMGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); typedef void (APIENTRYP RGLSYMGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data); typedef void (APIENTRYP RGLSYMGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params); typedef void (APIENTRYP RGLSYMGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); typedef void (APIENTRYP RGLSYMGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); typedef void (APIENTRYP RGLSYMGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); typedef void (APIENTRYP RGLSYMGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat *val); typedef void (APIENTRYP RGLSYMGLSAMPLEMASKIPROC) (GLuint index, GLbitfield mask); typedef void (APIENTRYP RGLSYMGLBINDFRAGDATALOCATIONINDEXEDPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); typedef GLint (APIENTRYP RGLSYMGLGETFRAGDATAINDEXPROC) (GLuint program, const GLchar *name); typedef void (APIENTRYP RGLSYMGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers); typedef void (APIENTRYP RGLSYMGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers); typedef GLboolean (APIENTRYP RGLSYMGLISSAMPLERPROC) (GLuint sampler); typedef void (APIENTRYP RGLSYMGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler); typedef void (APIENTRYP RGLSYMGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param); typedef void (APIENTRYP RGLSYMGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint *param); typedef void (APIENTRYP RGLSYMGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param); typedef void (APIENTRYP RGLSYMGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat *param); typedef void (APIENTRYP RGLSYMGLSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, const GLint *param); typedef void (APIENTRYP RGLSYMGLSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, const GLuint *param); typedef void (APIENTRYP RGLSYMGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLGETSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat *params); typedef void (APIENTRYP RGLSYMGLGETSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, GLuint *params); typedef void (APIENTRYP RGLSYMGLQUERYCOUNTERPROC) (GLuint id, GLenum target); typedef void (APIENTRYP RGLSYMGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64 *params); typedef void (APIENTRYP RGLSYMGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64 *params); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBP1UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBP1UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBP2UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBP2UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBP3UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBP3UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBP4UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBP4UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); typedef void (APIENTRYP RGLSYMGLVERTEXP2UIPROC) (GLenum type, GLuint value); typedef void (APIENTRYP RGLSYMGLVERTEXP2UIVPROC) (GLenum type, const GLuint *value); typedef void (APIENTRYP RGLSYMGLVERTEXP3UIPROC) (GLenum type, GLuint value); typedef void (APIENTRYP RGLSYMGLVERTEXP3UIVPROC) (GLenum type, const GLuint *value); typedef void (APIENTRYP RGLSYMGLVERTEXP4UIPROC) (GLenum type, GLuint value); typedef void (APIENTRYP RGLSYMGLVERTEXP4UIVPROC) (GLenum type, const GLuint *value); typedef void (APIENTRYP RGLSYMGLTEXCOORDP1UIPROC) (GLenum type, GLuint coords); typedef void (APIENTRYP RGLSYMGLTEXCOORDP1UIVPROC) (GLenum type, const GLuint *coords); typedef void (APIENTRYP RGLSYMGLTEXCOORDP2UIPROC) (GLenum type, GLuint coords); typedef void (APIENTRYP RGLSYMGLTEXCOORDP2UIVPROC) (GLenum type, const GLuint *coords); typedef void (APIENTRYP RGLSYMGLTEXCOORDP3UIPROC) (GLenum type, GLuint coords); typedef void (APIENTRYP RGLSYMGLTEXCOORDP3UIVPROC) (GLenum type, const GLuint *coords); typedef void (APIENTRYP RGLSYMGLTEXCOORDP4UIPROC) (GLenum type, GLuint coords); typedef void (APIENTRYP RGLSYMGLTEXCOORDP4UIVPROC) (GLenum type, const GLuint *coords); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORDP1UIPROC) (GLenum texture, GLenum type, GLuint coords); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORDP1UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORDP2UIPROC) (GLenum texture, GLenum type, GLuint coords); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORDP2UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORDP3UIPROC) (GLenum texture, GLenum type, GLuint coords); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORDP3UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORDP4UIPROC) (GLenum texture, GLenum type, GLuint coords); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORDP4UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); typedef void (APIENTRYP RGLSYMGLNORMALP3UIPROC) (GLenum type, GLuint coords); typedef void (APIENTRYP RGLSYMGLNORMALP3UIVPROC) (GLenum type, const GLuint *coords); typedef void (APIENTRYP RGLSYMGLCOLORP3UIPROC) (GLenum type, GLuint color); typedef void (APIENTRYP RGLSYMGLCOLORP3UIVPROC) (GLenum type, const GLuint *color); typedef void (APIENTRYP RGLSYMGLCOLORP4UIPROC) (GLenum type, GLuint color); typedef void (APIENTRYP RGLSYMGLCOLORP4UIVPROC) (GLenum type, const GLuint *color); typedef void (APIENTRYP RGLSYMGLSECONDARYCOLORP3UIPROC) (GLenum type, GLuint color); typedef void (APIENTRYP RGLSYMGLSECONDARYCOLORP3UIVPROC) (GLenum type, const GLuint *color); typedef void (APIENTRYP RGLSYMGLMINSAMPLESHADINGPROC) (GLfloat value); typedef void (APIENTRYP RGLSYMGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode); typedef void (APIENTRYP RGLSYMGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); typedef void (APIENTRYP RGLSYMGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst); typedef void (APIENTRYP RGLSYMGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); typedef void (APIENTRYP RGLSYMGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect); typedef void (APIENTRYP RGLSYMGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect); typedef void (APIENTRYP RGLSYMGLUNIFORM1DPROC) (GLint location, GLdouble x); typedef void (APIENTRYP RGLSYMGLUNIFORM2DPROC) (GLint location, GLdouble x, GLdouble y); typedef void (APIENTRYP RGLSYMGLUNIFORM3DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP RGLSYMGLUNIFORM4DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP RGLSYMGLUNIFORM1DVPROC) (GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP RGLSYMGLUNIFORM2DVPROC) (GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP RGLSYMGLUNIFORM3DVPROC) (GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP RGLSYMGLUNIFORM4DVPROC) (GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP RGLSYMGLUNIFORMMATRIX2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP RGLSYMGLUNIFORMMATRIX3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP RGLSYMGLUNIFORMMATRIX4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP RGLSYMGLUNIFORMMATRIX2X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP RGLSYMGLUNIFORMMATRIX2X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP RGLSYMGLUNIFORMMATRIX3X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP RGLSYMGLUNIFORMMATRIX3X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP RGLSYMGLUNIFORMMATRIX4X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP RGLSYMGLUNIFORMMATRIX4X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP RGLSYMGLGETUNIFORMDVPROC) (GLuint program, GLint location, GLdouble *params); typedef GLint (APIENTRYP RGLSYMGLGETSUBROUTINEUNIFORMLOCATIONPROC) (GLuint program, GLenum shadertype, const GLchar *name); typedef GLuint (APIENTRYP RGLSYMGLGETSUBROUTINEINDEXPROC) (GLuint program, GLenum shadertype, const GLchar *name); typedef void (APIENTRYP RGLSYMGLGETACTIVESUBROUTINEUNIFORMIVPROC) (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values); typedef void (APIENTRYP RGLSYMGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); typedef void (APIENTRYP RGLSYMGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); typedef void (APIENTRYP RGLSYMGLUNIFORMSUBROUTINESUIVPROC) (GLenum shadertype, GLsizei count, const GLuint *indices); typedef void (APIENTRYP RGLSYMGLGETUNIFORMSUBROUTINEUIVPROC) (GLenum shadertype, GLint location, GLuint *params); typedef void (APIENTRYP RGLSYMGLGETPROGRAMSTAGEIVPROC) (GLuint program, GLenum shadertype, GLenum pname, GLint *values); typedef void (APIENTRYP RGLSYMGLPATCHPARAMETERIPROC) (GLenum pname, GLint value); typedef void (APIENTRYP RGLSYMGLPATCHPARAMETERFVPROC) (GLenum pname, const GLfloat *values); typedef void (APIENTRYP RGLSYMGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id); typedef void (APIENTRYP RGLSYMGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint *ids); typedef void (APIENTRYP RGLSYMGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids); typedef GLboolean (APIENTRYP RGLSYMGLISTRANSFORMFEEDBACKPROC) (GLuint id); typedef void (APIENTRYP RGLSYMGLPAUSETRANSFORMFEEDBACKPROC) (void); typedef void (APIENTRYP RGLSYMGLRESUMETRANSFORMFEEDBACKPROC) (void); typedef void (APIENTRYP RGLSYMGLDRAWTRANSFORMFEEDBACKPROC) (GLenum mode, GLuint id); typedef void (APIENTRYP RGLSYMGLDRAWTRANSFORMFEEDBACKSTREAMPROC) (GLenum mode, GLuint id, GLuint stream); typedef void (APIENTRYP RGLSYMGLBEGINQUERYINDEXEDPROC) (GLenum target, GLuint index, GLuint id); typedef void (APIENTRYP RGLSYMGLENDQUERYINDEXEDPROC) (GLenum target, GLuint index); typedef void (APIENTRYP RGLSYMGLGETQUERYINDEXEDIVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLRELEASESHADERCOMPILERPROC) (void); typedef void (APIENTRYP RGLSYMGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); typedef void (APIENTRYP RGLSYMGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); typedef void (APIENTRYP RGLSYMGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f); typedef void (APIENTRYP RGLSYMGLCLEARDEPTHFPROC) (GLfloat d); typedef void (APIENTRYP RGLSYMGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); typedef void (APIENTRYP RGLSYMGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); typedef void (APIENTRYP RGLSYMGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value); typedef void (APIENTRYP RGLSYMGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program); typedef void (APIENTRYP RGLSYMGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program); typedef GLuint (APIENTRYP RGLSYMGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar *const*strings); typedef void (APIENTRYP RGLSYMGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline); typedef void (APIENTRYP RGLSYMGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint *pipelines); typedef void (APIENTRYP RGLSYMGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines); typedef GLboolean (APIENTRYP RGLSYMGLISPROGRAMPIPELINEPROC) (GLuint pipeline); typedef void (APIENTRYP RGLSYMGLGETPROGRAMPIPELINEIVPROC) (GLuint pipeline, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint v0); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM1IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM1FPROC) (GLuint program, GLint location, GLfloat v0); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM1FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM1DPROC) (GLuint program, GLint location, GLdouble v0); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM1DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM1UIPROC) (GLuint program, GLint location, GLuint v0); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM1UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM2IPROC) (GLuint program, GLint location, GLint v0, GLint v1); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM2IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM2FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM2FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM2DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM2DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM2UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM2UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM3IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM3IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM3FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM3FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM3DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM3DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM3UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM3UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM4IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM4IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM4FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM4FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM4DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM4DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM4UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORM4UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORMMATRIX2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORMMATRIX3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORMMATRIX4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORMMATRIX2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORMMATRIX3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORMMATRIX4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORMMATRIX2X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORMMATRIX3X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORMMATRIX2X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORMMATRIX4X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORMMATRIX3X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORMMATRIX4X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORMMATRIX2X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORMMATRIX3X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORMMATRIX2X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORMMATRIX4X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORMMATRIX3X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORMMATRIX4X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP RGLSYMGLVALIDATEPROGRAMPIPELINEPROC) (GLuint pipeline); typedef void (APIENTRYP RGLSYMGLGETPROGRAMPIPELINEINFOLOGPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBL1DPROC) (GLuint index, GLdouble x); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBL2DPROC) (GLuint index, GLdouble x, GLdouble y); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBL3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBL4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBL1DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBL2DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBL3DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBL4DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBLPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); typedef void (APIENTRYP RGLSYMGLGETVERTEXATTRIBLDVPROC) (GLuint index, GLenum pname, GLdouble *params); typedef void (APIENTRYP RGLSYMGLVIEWPORTARRAYVPROC) (GLuint first, GLsizei count, const GLfloat *v); typedef void (APIENTRYP RGLSYMGLVIEWPORTINDEXEDFPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); typedef void (APIENTRYP RGLSYMGLVIEWPORTINDEXEDFVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP RGLSYMGLSCISSORARRAYVPROC) (GLuint first, GLsizei count, const GLint *v); typedef void (APIENTRYP RGLSYMGLSCISSORINDEXEDPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); typedef void (APIENTRYP RGLSYMGLSCISSORINDEXEDVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP RGLSYMGLDEPTHRANGEARRAYVPROC) (GLuint first, GLsizei count, const GLdouble *v); typedef void (APIENTRYP RGLSYMGLDEPTHRANGEINDEXEDPROC) (GLuint index, GLdouble n, GLdouble f); typedef void (APIENTRYP RGLSYMGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat *data); typedef void (APIENTRYP RGLSYMGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble *data); typedef void (APIENTRYP RGLSYMGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); typedef void (APIENTRYP RGLSYMGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); typedef void (APIENTRYP RGLSYMGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); typedef void (APIENTRYP RGLSYMGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); typedef void (APIENTRYP RGLSYMGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); typedef void (APIENTRYP RGLSYMGLMEMORYBARRIERPROC) (GLbitfield barriers); typedef void (APIENTRYP RGLSYMGLTEXSTORAGE1DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); typedef void (APIENTRYP RGLSYMGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); typedef void (APIENTRYP RGLSYMGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); typedef void (APIENTRYP RGLSYMGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) (GLenum mode, GLuint id, GLsizei instancecount); typedef void (APIENTRYP RGLSYMGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) (GLenum mode, GLuint id, GLuint stream, GLsizei instancecount); typedef void (APIENTRYP RGLSYMGLCLEARBUFFERDATAPROC) (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data); typedef void (APIENTRYP RGLSYMGLCLEARBUFFERSUBDATAPROC) (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); typedef void (APIENTRYP RGLSYMGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); typedef void (APIENTRYP RGLSYMGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect); typedef void (APIENTRYP RGLSYMGLCOPYIMAGESUBDATAPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); typedef void (APIENTRYP RGLSYMGLFRAMEBUFFERPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); typedef void (APIENTRYP RGLSYMGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLGETINTERNALFORMATI64VPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params); typedef void (APIENTRYP RGLSYMGLINVALIDATETEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); typedef void (APIENTRYP RGLSYMGLINVALIDATETEXIMAGEPROC) (GLuint texture, GLint level); typedef void (APIENTRYP RGLSYMGLINVALIDATEBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); typedef void (APIENTRYP RGLSYMGLINVALIDATEBUFFERDATAPROC) (GLuint buffer); typedef void (APIENTRYP RGLSYMGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments); typedef void (APIENTRYP RGLSYMGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP RGLSYMGLMULTIDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride); typedef void (APIENTRYP RGLSYMGLMULTIDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride); typedef void (APIENTRYP RGLSYMGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint *params); typedef GLuint (APIENTRYP RGLSYMGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name); typedef void (APIENTRYP RGLSYMGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); typedef void (APIENTRYP RGLSYMGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); typedef GLint (APIENTRYP RGLSYMGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar *name); typedef GLint (APIENTRYP RGLSYMGLGETPROGRAMRESOURCELOCATIONINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name); typedef void (APIENTRYP RGLSYMGLSHADERSTORAGEBLOCKBINDINGPROC) (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); typedef void (APIENTRYP RGLSYMGLTEXBUFFERRANGEPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); typedef void (APIENTRYP RGLSYMGLTEXSTORAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); typedef void (APIENTRYP RGLSYMGLTEXSTORAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); typedef void (APIENTRYP RGLSYMGLTEXTUREVIEWPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); typedef void (APIENTRYP RGLSYMGLBINDVERTEXBUFFERPROC) (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBIFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBLFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBBINDINGPROC) (GLuint attribindex, GLuint bindingindex); typedef void (APIENTRYP RGLSYMGLVERTEXBINDINGDIVISORPROC) (GLuint bindingindex, GLuint divisor); typedef void (APIENTRYP RGLSYMGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); typedef void (APIENTRYP RGLSYMGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); typedef void (APIENTRYP RGLSYMGLDEBUGMESSAGECALLBACKPROC) (RGLGENGLDEBUGPROC callback, const void *userParam); typedef GLuint (APIENTRYP RGLSYMGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); typedef void (APIENTRYP RGLSYMGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message); typedef void (APIENTRYP RGLSYMGLPOPDEBUGGROUPPROC) (void); typedef void (APIENTRYP RGLSYMGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); typedef void (APIENTRYP RGLSYMGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); typedef void (APIENTRYP RGLSYMGLOBJECTPTRLABELPROC) (const void *ptr, GLsizei length, const GLchar *label); typedef void (APIENTRYP RGLSYMGLGETOBJECTPTRLABELPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); typedef void (APIENTRYP RGLSYMGLBUFFERSTORAGEPROC) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); typedef void (APIENTRYP RGLSYMGLCLEARTEXIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, const void *data); typedef void (APIENTRYP RGLSYMGLCLEARTEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data); typedef void (APIENTRYP RGLSYMGLBINDBUFFERSBASEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint *buffers); typedef void (APIENTRYP RGLSYMGLBINDBUFFERSRANGEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizeiptr *sizes); typedef void (APIENTRYP RGLSYMGLBINDTEXTURESPROC) (GLuint first, GLsizei count, const GLuint *textures); typedef void (APIENTRYP RGLSYMGLBINDSAMPLERSPROC) (GLuint first, GLsizei count, const GLuint *samplers); typedef void (APIENTRYP RGLSYMGLBINDIMAGETEXTURESPROC) (GLuint first, GLsizei count, const GLuint *textures); typedef void (APIENTRYP RGLSYMGLBINDVERTEXBUFFERSPROC) (GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); typedef GLuint64 (APIENTRYP RGLSYMGLGETTEXTUREHANDLEARBPROC) (GLuint texture); typedef GLuint64 (APIENTRYP RGLSYMGLGETTEXTURESAMPLERHANDLEARBPROC) (GLuint texture, GLuint sampler); typedef void (APIENTRYP RGLSYMGLMAKETEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle); typedef void (APIENTRYP RGLSYMGLMAKETEXTUREHANDLENONRESIDENTARBPROC) (GLuint64 handle); typedef GLuint64 (APIENTRYP RGLSYMGLGETIMAGEHANDLEARBPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); typedef void (APIENTRYP RGLSYMGLMAKEIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle, GLenum access); typedef void (APIENTRYP RGLSYMGLMAKEIMAGEHANDLENONRESIDENTARBPROC) (GLuint64 handle); typedef void (APIENTRYP RGLSYMGLUNIFORMHANDLEUI64ARBPROC) (GLint location, GLuint64 value); typedef void (APIENTRYP RGLSYMGLUNIFORMHANDLEUI64VARBPROC) (GLint location, GLsizei count, const GLuint64 *value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORMHANDLEUI64ARBPROC) (GLuint program, GLint location, GLuint64 value); typedef void (APIENTRYP RGLSYMGLPROGRAMUNIFORMHANDLEUI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values); typedef GLboolean (APIENTRYP RGLSYMGLISTEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle); typedef GLboolean (APIENTRYP RGLSYMGLISIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBL1UI64ARBPROC) (GLuint index, GLuint64EXT x); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBL1UI64VARBPROC) (GLuint index, const GLuint64EXT *v); typedef void (APIENTRYP RGLSYMGLGETVERTEXATTRIBLUI64VARBPROC) (GLuint index, GLenum pname, GLuint64EXT *params); #ifdef __APPLE__ struct _cl_context; struct _cl_event; #endif typedef GLsync (APIENTRYP RGLSYMGLCREATESYNCFROMCLEVENTARBPROC) (struct _cl_context *context, struct _cl_event *event, GLbitfield flags); typedef void (APIENTRYP RGLSYMGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp); typedef void (APIENTRYP RGLSYMGLDISPATCHCOMPUTEGROUPSIZEARBPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z, GLuint group_size_x, GLuint group_size_y, GLuint group_size_z); typedef void (APIENTRYP RGLSYMGLDEBUGMESSAGECONTROLARBPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); typedef void (APIENTRYP RGLSYMGLDEBUGMESSAGEINSERTARBPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); typedef void (APIENTRYP RGLSYMGLDEBUGMESSAGECALLBACKARBPROC) (RGLGENGLDEBUGPROCARB callback, const void *userParam); typedef GLuint (APIENTRYP RGLSYMGLGETDEBUGMESSAGELOGARBPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); typedef void (APIENTRYP RGLSYMGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum *bufs); typedef void (APIENTRYP RGLSYMGLBLENDEQUATIONIARBPROC) (GLuint buf, GLenum mode); typedef void (APIENTRYP RGLSYMGLBLENDEQUATIONSEPARATEIARBPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); typedef void (APIENTRYP RGLSYMGLBLENDFUNCIARBPROC) (GLuint buf, GLenum src, GLenum dst); typedef void (APIENTRYP RGLSYMGLBLENDFUNCSEPARATEIARBPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); typedef void (APIENTRYP RGLSYMGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); typedef void (APIENTRYP RGLSYMGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); typedef void (APIENTRYP RGLSYMGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const void *string); typedef void (APIENTRYP RGLSYMGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); typedef void (APIENTRYP RGLSYMGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint *programs); typedef void (APIENTRYP RGLSYMGLGENPROGRAMSARBPROC) (GLsizei n, GLuint *programs); typedef void (APIENTRYP RGLSYMGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP RGLSYMGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); typedef void (APIENTRYP RGLSYMGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP RGLSYMGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); typedef void (APIENTRYP RGLSYMGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP RGLSYMGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); typedef void (APIENTRYP RGLSYMGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP RGLSYMGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); typedef void (APIENTRYP RGLSYMGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); typedef void (APIENTRYP RGLSYMGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); typedef void (APIENTRYP RGLSYMGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); typedef void (APIENTRYP RGLSYMGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); typedef void (APIENTRYP RGLSYMGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, void *string); typedef GLboolean (APIENTRYP RGLSYMGLISPROGRAMARBPROC) (GLuint program); typedef void (APIENTRYP RGLSYMGLPROGRAMPARAMETERIARBPROC) (GLuint program, GLenum pname, GLint value); typedef void (APIENTRYP RGLSYMGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); typedef void (APIENTRYP RGLSYMGLFRAMEBUFFERTEXTURELAYERARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); typedef void (APIENTRYP RGLSYMGLFRAMEBUFFERTEXTUREFACEARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); typedef void (APIENTRYP RGLSYMGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table); typedef void (APIENTRYP RGLSYMGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP RGLSYMGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP RGLSYMGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP RGLSYMGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, void *table); typedef void (APIENTRYP RGLSYMGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP RGLSYMGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data); typedef void (APIENTRYP RGLSYMGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP RGLSYMGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image); typedef void (APIENTRYP RGLSYMGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image); typedef void (APIENTRYP RGLSYMGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); typedef void (APIENTRYP RGLSYMGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP RGLSYMGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); typedef void (APIENTRYP RGLSYMGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP RGLSYMGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP RGLSYMGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP RGLSYMGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, void *image); typedef void (APIENTRYP RGLSYMGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP RGLSYMGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span); typedef void (APIENTRYP RGLSYMGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column); typedef void (APIENTRYP RGLSYMGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); typedef void (APIENTRYP RGLSYMGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP RGLSYMGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); typedef void (APIENTRYP RGLSYMGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP RGLSYMGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); typedef void (APIENTRYP RGLSYMGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); typedef void (APIENTRYP RGLSYMGLRESETHISTOGRAMPROC) (GLenum target); typedef void (APIENTRYP RGLSYMGLRESETMINMAXPROC) (GLenum target); typedef void (APIENTRYP RGLSYMGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC) (GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); typedef void (APIENTRYP RGLSYMGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC) (GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor); typedef void (APIENTRYP RGLSYMGLCURRENTPALETTEMATRIXARBPROC) (GLint index); typedef void (APIENTRYP RGLSYMGLMATRIXINDEXUBVARBPROC) (GLint size, const GLubyte *indices); typedef void (APIENTRYP RGLSYMGLMATRIXINDEXUSVARBPROC) (GLint size, const GLushort *indices); typedef void (APIENTRYP RGLSYMGLMATRIXINDEXUIVARBPROC) (GLint size, const GLuint *indices); typedef void (APIENTRYP RGLSYMGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); typedef void (APIENTRYP RGLSYMGLSAMPLECOVERAGEARBPROC) (GLfloat value, GLboolean invert); typedef void (APIENTRYP RGLSYMGLACTIVETEXTUREARBPROC) (GLenum texture); typedef void (APIENTRYP RGLSYMGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP RGLSYMGLGENQUERIESARBPROC) (GLsizei n, GLuint *ids); typedef void (APIENTRYP RGLSYMGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint *ids); typedef GLboolean (APIENTRYP RGLSYMGLISQUERYARBPROC) (GLuint id); typedef void (APIENTRYP RGLSYMGLBEGINQUERYARBPROC) (GLenum target, GLuint id); typedef void (APIENTRYP RGLSYMGLENDQUERYARBPROC) (GLenum target); typedef void (APIENTRYP RGLSYMGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint *params); typedef void (APIENTRYP RGLSYMGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP RGLSYMGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat *params); typedef GLenum (APIENTRYP RGLSYMGLGETGRAPHICSRESETSTATUSARBPROC) (void); typedef void (APIENTRYP RGLSYMGLGETNTEXIMAGEARBPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *img); typedef void (APIENTRYP RGLSYMGLREADNPIXELSARBPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); typedef void (APIENTRYP RGLSYMGLGETNCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, GLsizei bufSize, void *img); typedef void (APIENTRYP RGLSYMGLGETNUNIFORMFVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); typedef void (APIENTRYP RGLSYMGLGETNUNIFORMIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); typedef void (APIENTRYP RGLSYMGLGETNUNIFORMUIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params); typedef void (APIENTRYP RGLSYMGLGETNUNIFORMDVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); typedef void (APIENTRYP RGLSYMGLGETNMAPDVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); typedef void (APIENTRYP RGLSYMGLGETNMAPFVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); typedef void (APIENTRYP RGLSYMGLGETNMAPIVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLint *v); typedef void (APIENTRYP RGLSYMGLGETNPIXELMAPFVARBPROC) (GLenum map, GLsizei bufSize, GLfloat *values); typedef void (APIENTRYP RGLSYMGLGETNPIXELMAPUIVARBPROC) (GLenum map, GLsizei bufSize, GLuint *values); typedef void (APIENTRYP RGLSYMGLGETNPIXELMAPUSVARBPROC) (GLenum map, GLsizei bufSize, GLushort *values); typedef void (APIENTRYP RGLSYMGLGETNPOLYGONSTIPPLEARBPROC) (GLsizei bufSize, GLubyte *pattern); typedef void (APIENTRYP RGLSYMGLGETNCOLORTABLEARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table); typedef void (APIENTRYP RGLSYMGLGETNCONVOLUTIONFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *image); typedef void (APIENTRYP RGLSYMGLGETNSEPARABLEFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void *row, GLsizei columnBufSize, void *column, void *span); typedef void (APIENTRYP RGLSYMGLGETNHISTOGRAMARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); typedef void (APIENTRYP RGLSYMGLGETNMINMAXARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); typedef void (APIENTRYP RGLSYMGLMINSAMPLESHADINGARBPROC) (GLfloat value); typedef void (APIENTRYP RGLSYMGLDELETEOBJECTARBPROC) (GLhandleARB obj); typedef GLhandleARB (APIENTRYP RGLSYMGLGETHANDLEARBPROC) (GLenum pname); typedef void (APIENTRYP RGLSYMGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); typedef GLhandleARB (APIENTRYP RGLSYMGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); typedef void (APIENTRYP RGLSYMGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB **string, const GLint *length); typedef void (APIENTRYP RGLSYMGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); typedef GLhandleARB (APIENTRYP RGLSYMGLCREATEPROGRAMOBJECTARBPROC) (void); typedef void (APIENTRYP RGLSYMGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); typedef void (APIENTRYP RGLSYMGLLINKPROGRAMARBPROC) (GLhandleARB programObj); typedef void (APIENTRYP RGLSYMGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); typedef void (APIENTRYP RGLSYMGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); typedef void (APIENTRYP RGLSYMGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); typedef void (APIENTRYP RGLSYMGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); typedef void (APIENTRYP RGLSYMGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); typedef void (APIENTRYP RGLSYMGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); typedef void (APIENTRYP RGLSYMGLUNIFORM1IARBPROC) (GLint location, GLint v0); typedef void (APIENTRYP RGLSYMGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); typedef void (APIENTRYP RGLSYMGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); typedef void (APIENTRYP RGLSYMGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); typedef void (APIENTRYP RGLSYMGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP RGLSYMGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP RGLSYMGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP RGLSYMGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP RGLSYMGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP RGLSYMGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat *params); typedef void (APIENTRYP RGLSYMGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); typedef void (APIENTRYP RGLSYMGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj); typedef GLint (APIENTRYP RGLSYMGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); typedef void (APIENTRYP RGLSYMGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); typedef void (APIENTRYP RGLSYMGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat *params); typedef void (APIENTRYP RGLSYMGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint *params); typedef void (APIENTRYP RGLSYMGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); typedef void (APIENTRYP RGLSYMGLNAMEDSTRINGARBPROC) (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string); typedef void (APIENTRYP RGLSYMGLDELETENAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name); typedef void (APIENTRYP RGLSYMGLCOMPILESHADERINCLUDEARBPROC) (GLuint shader, GLsizei count, const GLchar *const*path, const GLint *length); typedef GLboolean (APIENTRYP RGLSYMGLISNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name); typedef void (APIENTRYP RGLSYMGLGETNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string); typedef void (APIENTRYP RGLSYMGLGETNAMEDSTRINGIVARBPROC) (GLint namelen, const GLchar *name, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLTEXPAGECOMMITMENTARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); typedef void (APIENTRYP RGLSYMGLTEXBUFFERARBPROC) (GLenum target, GLenum internalformat, GLuint buffer); typedef void (APIENTRYP RGLSYMGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); typedef void (APIENTRYP RGLSYMGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); typedef void (APIENTRYP RGLSYMGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); typedef void (APIENTRYP RGLSYMGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); typedef void (APIENTRYP RGLSYMGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); typedef void (APIENTRYP RGLSYMGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); typedef void (APIENTRYP RGLSYMGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, void *img); typedef void (APIENTRYP RGLSYMGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); typedef void (APIENTRYP RGLSYMGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); typedef void (APIENTRYP RGLSYMGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); typedef void (APIENTRYP RGLSYMGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); typedef void (APIENTRYP RGLSYMGLWEIGHTBVARBPROC) (GLint size, const GLbyte *weights); typedef void (APIENTRYP RGLSYMGLWEIGHTSVARBPROC) (GLint size, const GLshort *weights); typedef void (APIENTRYP RGLSYMGLWEIGHTIVARBPROC) (GLint size, const GLint *weights); typedef void (APIENTRYP RGLSYMGLWEIGHTFVARBPROC) (GLint size, const GLfloat *weights); typedef void (APIENTRYP RGLSYMGLWEIGHTDVARBPROC) (GLint size, const GLdouble *weights); typedef void (APIENTRYP RGLSYMGLWEIGHTUBVARBPROC) (GLint size, const GLubyte *weights); typedef void (APIENTRYP RGLSYMGLWEIGHTUSVARBPROC) (GLint size, const GLushort *weights); typedef void (APIENTRYP RGLSYMGLWEIGHTUIVARBPROC) (GLint size, const GLuint *weights); typedef void (APIENTRYP RGLSYMGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); typedef void (APIENTRYP RGLSYMGLVERTEXBLENDARBPROC) (GLint count); typedef void (APIENTRYP RGLSYMGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); typedef void (APIENTRYP RGLSYMGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers); typedef void (APIENTRYP RGLSYMGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers); typedef GLboolean (APIENTRYP RGLSYMGLISBUFFERARBPROC) (GLuint buffer); typedef void (APIENTRYP RGLSYMGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const void *data, GLenum usage); typedef void (APIENTRYP RGLSYMGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const void *data); typedef void (APIENTRYP RGLSYMGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, void *data); typedef void *(APIENTRYP RGLSYMGLMAPBUFFERARBPROC) (GLenum target, GLenum access); typedef GLboolean (APIENTRYP RGLSYMGLUNMAPBUFFERARBPROC) (GLenum target); typedef void (APIENTRYP RGLSYMGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, void **params); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort *v); typedef void (APIENTRYP RGLSYMGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); typedef void (APIENTRYP RGLSYMGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); typedef void (APIENTRYP RGLSYMGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); typedef void (APIENTRYP RGLSYMGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble *params); typedef void (APIENTRYP RGLSYMGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat *params); typedef void (APIENTRYP RGLSYMGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, void **pointer); typedef void (APIENTRYP RGLSYMGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name); typedef void (APIENTRYP RGLSYMGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); typedef GLint (APIENTRYP RGLSYMGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); typedef void (APIENTRYP RGLSYMGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); typedef void (APIENTRYP RGLSYMGLWINDOWPOS2DVARBPROC) (const GLdouble *v); typedef void (APIENTRYP RGLSYMGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); typedef void (APIENTRYP RGLSYMGLWINDOWPOS2FVARBPROC) (const GLfloat *v); typedef void (APIENTRYP RGLSYMGLWINDOWPOS2IARBPROC) (GLint x, GLint y); typedef void (APIENTRYP RGLSYMGLWINDOWPOS2IVARBPROC) (const GLint *v); typedef void (APIENTRYP RGLSYMGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); typedef void (APIENTRYP RGLSYMGLWINDOWPOS2SVARBPROC) (const GLshort *v); typedef void (APIENTRYP RGLSYMGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP RGLSYMGLWINDOWPOS3DVARBPROC) (const GLdouble *v); typedef void (APIENTRYP RGLSYMGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP RGLSYMGLWINDOWPOS3FVARBPROC) (const GLfloat *v); typedef void (APIENTRYP RGLSYMGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); typedef void (APIENTRYP RGLSYMGLWINDOWPOS3IVARBPROC) (const GLint *v); typedef void (APIENTRYP RGLSYMGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP RGLSYMGLWINDOWPOS3SVARBPROC) (const GLshort *v); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD1BOESPROC) (GLenum texture, GLbyte s); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD1BVOESPROC) (GLenum texture, const GLbyte *coords); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD2BOESPROC) (GLenum texture, GLbyte s, GLbyte t); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD2BVOESPROC) (GLenum texture, const GLbyte *coords); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD3BOESPROC) (GLenum texture, GLbyte s, GLbyte t, GLbyte r); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD3BVOESPROC) (GLenum texture, const GLbyte *coords); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD4BOESPROC) (GLenum texture, GLbyte s, GLbyte t, GLbyte r, GLbyte q); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD4BVOESPROC) (GLenum texture, const GLbyte *coords); typedef void (APIENTRYP RGLSYMGLTEXCOORD1BOESPROC) (GLbyte s); typedef void (APIENTRYP RGLSYMGLTEXCOORD1BVOESPROC) (const GLbyte *coords); typedef void (APIENTRYP RGLSYMGLTEXCOORD2BOESPROC) (GLbyte s, GLbyte t); typedef void (APIENTRYP RGLSYMGLTEXCOORD2BVOESPROC) (const GLbyte *coords); typedef void (APIENTRYP RGLSYMGLTEXCOORD3BOESPROC) (GLbyte s, GLbyte t, GLbyte r); typedef void (APIENTRYP RGLSYMGLTEXCOORD3BVOESPROC) (const GLbyte *coords); typedef void (APIENTRYP RGLSYMGLTEXCOORD4BOESPROC) (GLbyte s, GLbyte t, GLbyte r, GLbyte q); typedef void (APIENTRYP RGLSYMGLTEXCOORD4BVOESPROC) (const GLbyte *coords); typedef void (APIENTRYP RGLSYMGLVERTEX2BOESPROC) (GLbyte x); typedef void (APIENTRYP RGLSYMGLVERTEX2BVOESPROC) (const GLbyte *coords); typedef void (APIENTRYP RGLSYMGLVERTEX3BOESPROC) (GLbyte x, GLbyte y); typedef void (APIENTRYP RGLSYMGLVERTEX3BVOESPROC) (const GLbyte *coords); typedef void (APIENTRYP RGLSYMGLVERTEX4BOESPROC) (GLbyte x, GLbyte y, GLbyte z); typedef void (APIENTRYP RGLSYMGLVERTEX4BVOESPROC) (const GLbyte *coords); typedef void (APIENTRYP RGLSYMGLALPHAFUNCXOESPROC) (GLenum func, GLfixed ref); typedef void (APIENTRYP RGLSYMGLCLEARCOLORXOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); typedef void (APIENTRYP RGLSYMGLCLEARDEPTHXOESPROC) (GLfixed depth); typedef void (APIENTRYP RGLSYMGLCLIPPLANEXOESPROC) (GLenum plane, const GLfixed *equation); typedef void (APIENTRYP RGLSYMGLCOLOR4XOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); typedef void (APIENTRYP RGLSYMGLDEPTHRANGEXOESPROC) (GLfixed n, GLfixed f); typedef void (APIENTRYP RGLSYMGLFOGXOESPROC) (GLenum pname, GLfixed param); typedef void (APIENTRYP RGLSYMGLFOGXVOESPROC) (GLenum pname, const GLfixed *param); typedef void (APIENTRYP RGLSYMGLFRUSTUMXOESPROC) (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); typedef void (APIENTRYP RGLSYMGLGETCLIPPLANEXOESPROC) (GLenum plane, GLfixed *equation); typedef void (APIENTRYP RGLSYMGLGETFIXEDVOESPROC) (GLenum pname, GLfixed *params); typedef void (APIENTRYP RGLSYMGLGETTEXENVXVOESPROC) (GLenum target, GLenum pname, GLfixed *params); typedef void (APIENTRYP RGLSYMGLGETTEXPARAMETERXVOESPROC) (GLenum target, GLenum pname, GLfixed *params); typedef void (APIENTRYP RGLSYMGLLIGHTMODELXOESPROC) (GLenum pname, GLfixed param); typedef void (APIENTRYP RGLSYMGLLIGHTMODELXVOESPROC) (GLenum pname, const GLfixed *param); typedef void (APIENTRYP RGLSYMGLLIGHTXOESPROC) (GLenum light, GLenum pname, GLfixed param); typedef void (APIENTRYP RGLSYMGLLIGHTXVOESPROC) (GLenum light, GLenum pname, const GLfixed *params); typedef void (APIENTRYP RGLSYMGLLINEWIDTHXOESPROC) (GLfixed width); typedef void (APIENTRYP RGLSYMGLLOADMATRIXXOESPROC) (const GLfixed *m); typedef void (APIENTRYP RGLSYMGLMATERIALXOESPROC) (GLenum face, GLenum pname, GLfixed param); typedef void (APIENTRYP RGLSYMGLMATERIALXVOESPROC) (GLenum face, GLenum pname, const GLfixed *param); typedef void (APIENTRYP RGLSYMGLMULTMATRIXXOESPROC) (const GLfixed *m); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD4XOESPROC) (GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q); typedef void (APIENTRYP RGLSYMGLNORMAL3XOESPROC) (GLfixed nx, GLfixed ny, GLfixed nz); typedef void (APIENTRYP RGLSYMGLORTHOXOESPROC) (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); typedef void (APIENTRYP RGLSYMGLPOINTPARAMETERXVOESPROC) (GLenum pname, const GLfixed *params); typedef void (APIENTRYP RGLSYMGLPOINTSIZEXOESPROC) (GLfixed size); typedef void (APIENTRYP RGLSYMGLPOLYGONOFFSETXOESPROC) (GLfixed factor, GLfixed units); typedef void (APIENTRYP RGLSYMGLROTATEXOESPROC) (GLfixed angle, GLfixed x, GLfixed y, GLfixed z); typedef void (APIENTRYP RGLSYMGLSAMPLECOVERAGEOESPROC) (GLfixed value, GLboolean invert); typedef void (APIENTRYP RGLSYMGLSCALEXOESPROC) (GLfixed x, GLfixed y, GLfixed z); typedef void (APIENTRYP RGLSYMGLTEXENVXOESPROC) (GLenum target, GLenum pname, GLfixed param); typedef void (APIENTRYP RGLSYMGLTEXENVXVOESPROC) (GLenum target, GLenum pname, const GLfixed *params); typedef void (APIENTRYP RGLSYMGLTEXPARAMETERXOESPROC) (GLenum target, GLenum pname, GLfixed param); typedef void (APIENTRYP RGLSYMGLTEXPARAMETERXVOESPROC) (GLenum target, GLenum pname, const GLfixed *params); typedef void (APIENTRYP RGLSYMGLTRANSLATEXOESPROC) (GLfixed x, GLfixed y, GLfixed z); typedef void (APIENTRYP RGLSYMGLACCUMXOESPROC) (GLenum op, GLfixed value); typedef void (APIENTRYP RGLSYMGLBITMAPXOESPROC) (GLsizei width, GLsizei height, GLfixed xorig, GLfixed yorig, GLfixed xmove, GLfixed ymove, const GLubyte *bitmap); typedef void (APIENTRYP RGLSYMGLBLENDCOLORXOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); typedef void (APIENTRYP RGLSYMGLCLEARACCUMXOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); typedef void (APIENTRYP RGLSYMGLCOLOR3XOESPROC) (GLfixed red, GLfixed green, GLfixed blue); typedef void (APIENTRYP RGLSYMGLCOLOR3XVOESPROC) (const GLfixed *components); typedef void (APIENTRYP RGLSYMGLCOLOR4XVOESPROC) (const GLfixed *components); typedef void (APIENTRYP RGLSYMGLCONVOLUTIONPARAMETERXOESPROC) (GLenum target, GLenum pname, GLfixed param); typedef void (APIENTRYP RGLSYMGLCONVOLUTIONPARAMETERXVOESPROC) (GLenum target, GLenum pname, const GLfixed *params); typedef void (APIENTRYP RGLSYMGLEVALCOORD1XOESPROC) (GLfixed u); typedef void (APIENTRYP RGLSYMGLEVALCOORD1XVOESPROC) (const GLfixed *coords); typedef void (APIENTRYP RGLSYMGLEVALCOORD2XOESPROC) (GLfixed u, GLfixed v); typedef void (APIENTRYP RGLSYMGLEVALCOORD2XVOESPROC) (const GLfixed *coords); typedef void (APIENTRYP RGLSYMGLFEEDBACKBUFFERXOESPROC) (GLsizei n, GLenum type, const GLfixed *buffer); typedef void (APIENTRYP RGLSYMGLGETCONVOLUTIONPARAMETERXVOESPROC) (GLenum target, GLenum pname, GLfixed *params); typedef void (APIENTRYP RGLSYMGLGETHISTOGRAMPARAMETERXVOESPROC) (GLenum target, GLenum pname, GLfixed *params); typedef void (APIENTRYP RGLSYMGLGETLIGHTXOESPROC) (GLenum light, GLenum pname, GLfixed *params); typedef void (APIENTRYP RGLSYMGLGETMAPXVOESPROC) (GLenum target, GLenum query, GLfixed *v); typedef void (APIENTRYP RGLSYMGLGETMATERIALXOESPROC) (GLenum face, GLenum pname, GLfixed param); typedef void (APIENTRYP RGLSYMGLGETPIXELMAPXVPROC) (GLenum map, GLint size, GLfixed *values); typedef void (APIENTRYP RGLSYMGLGETTEXGENXVOESPROC) (GLenum coord, GLenum pname, GLfixed *params); typedef void (APIENTRYP RGLSYMGLGETTEXLEVELPARAMETERXVOESPROC) (GLenum target, GLint level, GLenum pname, GLfixed *params); typedef void (APIENTRYP RGLSYMGLINDEXXOESPROC) (GLfixed component); typedef void (APIENTRYP RGLSYMGLINDEXXVOESPROC) (const GLfixed *component); typedef void (APIENTRYP RGLSYMGLLOADTRANSPOSEMATRIXXOESPROC) (const GLfixed *m); typedef void (APIENTRYP RGLSYMGLMAP1XOESPROC) (GLenum target, GLfixed u1, GLfixed u2, GLint stride, GLint order, GLfixed points); typedef void (APIENTRYP RGLSYMGLMAP2XOESPROC) (GLenum target, GLfixed u1, GLfixed u2, GLint ustride, GLint uorder, GLfixed v1, GLfixed v2, GLint vstride, GLint vorder, GLfixed points); typedef void (APIENTRYP RGLSYMGLMAPGRID1XOESPROC) (GLint n, GLfixed u1, GLfixed u2); typedef void (APIENTRYP RGLSYMGLMAPGRID2XOESPROC) (GLint n, GLfixed u1, GLfixed u2, GLfixed v1, GLfixed v2); typedef void (APIENTRYP RGLSYMGLMULTTRANSPOSEMATRIXXOESPROC) (const GLfixed *m); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD1XOESPROC) (GLenum texture, GLfixed s); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD1XVOESPROC) (GLenum texture, const GLfixed *coords); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD2XOESPROC) (GLenum texture, GLfixed s, GLfixed t); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD2XVOESPROC) (GLenum texture, const GLfixed *coords); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD3XOESPROC) (GLenum texture, GLfixed s, GLfixed t, GLfixed r); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD3XVOESPROC) (GLenum texture, const GLfixed *coords); typedef void (APIENTRYP RGLSYMGLMULTITEXCOORD4XVOESPROC) (GLenum texture, const GLfixed *coords); typedef void (APIENTRYP RGLSYMGLNORMAL3XVOESPROC) (const GLfixed *coords); typedef void (APIENTRYP RGLSYMGLPASSTHROUGHXOESPROC) (GLfixed token); typedef void (APIENTRYP RGLSYMGLPIXELMAPXPROC) (GLenum map, GLint size, const GLfixed *values); typedef void (APIENTRYP RGLSYMGLPIXELSTOREXPROC) (GLenum pname, GLfixed param); typedef void (APIENTRYP RGLSYMGLPIXELTRANSFERXOESPROC) (GLenum pname, GLfixed param); typedef void (APIENTRYP RGLSYMGLPIXELZOOMXOESPROC) (GLfixed xfactor, GLfixed yfactor); typedef void (APIENTRYP RGLSYMGLPRIORITIZETEXTURESXOESPROC) (GLsizei n, const GLuint *textures, const GLfixed *priorities); typedef void (APIENTRYP RGLSYMGLRASTERPOS2XOESPROC) (GLfixed x, GLfixed y); typedef void (APIENTRYP RGLSYMGLRASTERPOS2XVOESPROC) (const GLfixed *coords); typedef void (APIENTRYP RGLSYMGLRASTERPOS3XOESPROC) (GLfixed x, GLfixed y, GLfixed z); typedef void (APIENTRYP RGLSYMGLRASTERPOS3XVOESPROC) (const GLfixed *coords); typedef void (APIENTRYP RGLSYMGLRASTERPOS4XOESPROC) (GLfixed x, GLfixed y, GLfixed z, GLfixed w); typedef void (APIENTRYP RGLSYMGLRASTERPOS4XVOESPROC) (const GLfixed *coords); typedef void (APIENTRYP RGLSYMGLRECTXOESPROC) (GLfixed x1, GLfixed y1, GLfixed x2, GLfixed y2); typedef void (APIENTRYP RGLSYMGLRECTXVOESPROC) (const GLfixed *v1, const GLfixed *v2); typedef void (APIENTRYP RGLSYMGLTEXCOORD1XOESPROC) (GLfixed s); typedef void (APIENTRYP RGLSYMGLTEXCOORD1XVOESPROC) (const GLfixed *coords); typedef void (APIENTRYP RGLSYMGLTEXCOORD2XOESPROC) (GLfixed s, GLfixed t); typedef void (APIENTRYP RGLSYMGLTEXCOORD2XVOESPROC) (const GLfixed *coords); typedef void (APIENTRYP RGLSYMGLTEXCOORD3XOESPROC) (GLfixed s, GLfixed t, GLfixed r); typedef void (APIENTRYP RGLSYMGLTEXCOORD3XVOESPROC) (const GLfixed *coords); typedef void (APIENTRYP RGLSYMGLTEXCOORD4XOESPROC) (GLfixed s, GLfixed t, GLfixed r, GLfixed q); typedef void (APIENTRYP RGLSYMGLTEXCOORD4XVOESPROC) (const GLfixed *coords); typedef void (APIENTRYP RGLSYMGLTEXGENXOESPROC) (GLenum coord, GLenum pname, GLfixed param); typedef void (APIENTRYP RGLSYMGLTEXGENXVOESPROC) (GLenum coord, GLenum pname, const GLfixed *params); typedef void (APIENTRYP RGLSYMGLVERTEX2XOESPROC) (GLfixed x); typedef void (APIENTRYP RGLSYMGLVERTEX2XVOESPROC) (const GLfixed *coords); typedef void (APIENTRYP RGLSYMGLVERTEX3XOESPROC) (GLfixed x, GLfixed y); typedef void (APIENTRYP RGLSYMGLVERTEX3XVOESPROC) (const GLfixed *coords); typedef void (APIENTRYP RGLSYMGLVERTEX4XOESPROC) (GLfixed x, GLfixed y, GLfixed z); typedef void (APIENTRYP RGLSYMGLVERTEX4XVOESPROC) (const GLfixed *coords); typedef GLbitfield (APIENTRYP RGLSYMGLQUERYMATRIXXOESPROC) (GLfixed *mantissa, GLint *exponent); typedef void (APIENTRYP RGLSYMGLCLEARDEPTHFOESPROC) (GLclampf depth); typedef void (APIENTRYP RGLSYMGLCLIPPLANEFOESPROC) (GLenum plane, const GLfloat *equation); typedef void (APIENTRYP RGLSYMGLDEPTHRANGEFOESPROC) (GLclampf n, GLclampf f); typedef void (APIENTRYP RGLSYMGLFRUSTUMFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); typedef void (APIENTRYP RGLSYMGLGETCLIPPLANEFOESPROC) (GLenum plane, GLfloat *equation); typedef void (APIENTRYP RGLSYMGLORTHOFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); typedef void (APIENTRYP RGLSYMGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param); typedef void (APIENTRYP RGLSYMGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param); typedef void (APIENTRYP RGLSYMGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP RGLSYMGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP RGLSYMGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP RGLSYMGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat *params); #define glDrawRangeElements __rglgen_glDrawRangeElements #define glTexImage3D __rglgen_glTexImage3D #define glTexSubImage3D __rglgen_glTexSubImage3D #define glCopyTexSubImage3D __rglgen_glCopyTexSubImage3D #define glActiveTexture __rglgen_glActiveTexture #define glSampleCoverage __rglgen_glSampleCoverage #define glCompressedTexImage3D __rglgen_glCompressedTexImage3D #define glCompressedTexImage2D __rglgen_glCompressedTexImage2D #define glCompressedTexImage1D __rglgen_glCompressedTexImage1D #define glCompressedTexSubImage3D __rglgen_glCompressedTexSubImage3D #define glCompressedTexSubImage2D __rglgen_glCompressedTexSubImage2D #define glCompressedTexSubImage1D __rglgen_glCompressedTexSubImage1D #define glGetCompressedTexImage __rglgen_glGetCompressedTexImage #define glClientActiveTexture __rglgen_glClientActiveTexture #define glMultiTexCoord1d __rglgen_glMultiTexCoord1d #define glMultiTexCoord1dv __rglgen_glMultiTexCoord1dv #define glMultiTexCoord1f __rglgen_glMultiTexCoord1f #define glMultiTexCoord1fv __rglgen_glMultiTexCoord1fv #define glMultiTexCoord1i __rglgen_glMultiTexCoord1i #define glMultiTexCoord1iv __rglgen_glMultiTexCoord1iv #define glMultiTexCoord1s __rglgen_glMultiTexCoord1s #define glMultiTexCoord1sv __rglgen_glMultiTexCoord1sv #define glMultiTexCoord2d __rglgen_glMultiTexCoord2d #define glMultiTexCoord2dv __rglgen_glMultiTexCoord2dv #define glMultiTexCoord2f __rglgen_glMultiTexCoord2f #define glMultiTexCoord2fv __rglgen_glMultiTexCoord2fv #define glMultiTexCoord2i __rglgen_glMultiTexCoord2i #define glMultiTexCoord2iv __rglgen_glMultiTexCoord2iv #define glMultiTexCoord2s __rglgen_glMultiTexCoord2s #define glMultiTexCoord2sv __rglgen_glMultiTexCoord2sv #define glMultiTexCoord3d __rglgen_glMultiTexCoord3d #define glMultiTexCoord3dv __rglgen_glMultiTexCoord3dv #define glMultiTexCoord3f __rglgen_glMultiTexCoord3f #define glMultiTexCoord3fv __rglgen_glMultiTexCoord3fv #define glMultiTexCoord3i __rglgen_glMultiTexCoord3i #define glMultiTexCoord3iv __rglgen_glMultiTexCoord3iv #define glMultiTexCoord3s __rglgen_glMultiTexCoord3s #define glMultiTexCoord3sv __rglgen_glMultiTexCoord3sv #define glMultiTexCoord4d __rglgen_glMultiTexCoord4d #define glMultiTexCoord4dv __rglgen_glMultiTexCoord4dv #define glMultiTexCoord4f __rglgen_glMultiTexCoord4f #define glMultiTexCoord4fv __rglgen_glMultiTexCoord4fv #define glMultiTexCoord4i __rglgen_glMultiTexCoord4i #define glMultiTexCoord4iv __rglgen_glMultiTexCoord4iv #define glMultiTexCoord4s __rglgen_glMultiTexCoord4s #define glMultiTexCoord4sv __rglgen_glMultiTexCoord4sv #define glLoadTransposeMatrixf __rglgen_glLoadTransposeMatrixf #define glLoadTransposeMatrixd __rglgen_glLoadTransposeMatrixd #define glMultTransposeMatrixf __rglgen_glMultTransposeMatrixf #define glMultTransposeMatrixd __rglgen_glMultTransposeMatrixd #define glBlendFuncSeparate __rglgen_glBlendFuncSeparate #define glMultiDrawArrays __rglgen_glMultiDrawArrays #define glMultiDrawElements __rglgen_glMultiDrawElements #define glPointParameterf __rglgen_glPointParameterf #define glPointParameterfv __rglgen_glPointParameterfv #define glPointParameteri __rglgen_glPointParameteri #define glPointParameteriv __rglgen_glPointParameteriv #define glFogCoordf __rglgen_glFogCoordf #define glFogCoordfv __rglgen_glFogCoordfv #define glFogCoordd __rglgen_glFogCoordd #define glFogCoorddv __rglgen_glFogCoorddv #define glFogCoordPointer __rglgen_glFogCoordPointer #define glSecondaryColor3b __rglgen_glSecondaryColor3b #define glSecondaryColor3bv __rglgen_glSecondaryColor3bv #define glSecondaryColor3d __rglgen_glSecondaryColor3d #define glSecondaryColor3dv __rglgen_glSecondaryColor3dv #define glSecondaryColor3f __rglgen_glSecondaryColor3f #define glSecondaryColor3fv __rglgen_glSecondaryColor3fv #define glSecondaryColor3i __rglgen_glSecondaryColor3i #define glSecondaryColor3iv __rglgen_glSecondaryColor3iv #define glSecondaryColor3s __rglgen_glSecondaryColor3s #define glSecondaryColor3sv __rglgen_glSecondaryColor3sv #define glSecondaryColor3ub __rglgen_glSecondaryColor3ub #define glSecondaryColor3ubv __rglgen_glSecondaryColor3ubv #define glSecondaryColor3ui __rglgen_glSecondaryColor3ui #define glSecondaryColor3uiv __rglgen_glSecondaryColor3uiv #define glSecondaryColor3us __rglgen_glSecondaryColor3us #define glSecondaryColor3usv __rglgen_glSecondaryColor3usv #define glSecondaryColorPointer __rglgen_glSecondaryColorPointer #define glWindowPos2d __rglgen_glWindowPos2d #define glWindowPos2dv __rglgen_glWindowPos2dv #define glWindowPos2f __rglgen_glWindowPos2f #define glWindowPos2fv __rglgen_glWindowPos2fv #define glWindowPos2i __rglgen_glWindowPos2i #define glWindowPos2iv __rglgen_glWindowPos2iv #define glWindowPos2s __rglgen_glWindowPos2s #define glWindowPos2sv __rglgen_glWindowPos2sv #define glWindowPos3d __rglgen_glWindowPos3d #define glWindowPos3dv __rglgen_glWindowPos3dv #define glWindowPos3f __rglgen_glWindowPos3f #define glWindowPos3fv __rglgen_glWindowPos3fv #define glWindowPos3i __rglgen_glWindowPos3i #define glWindowPos3iv __rglgen_glWindowPos3iv #define glWindowPos3s __rglgen_glWindowPos3s #define glWindowPos3sv __rglgen_glWindowPos3sv #define glBlendColor __rglgen_glBlendColor #define glBlendEquation __rglgen_glBlendEquation #define glGenQueries __rglgen_glGenQueries #define glDeleteQueries __rglgen_glDeleteQueries #define glIsQuery __rglgen_glIsQuery #define glBeginQuery __rglgen_glBeginQuery #define glEndQuery __rglgen_glEndQuery #define glGetQueryiv __rglgen_glGetQueryiv #define glGetQueryObjectiv __rglgen_glGetQueryObjectiv #define glGetQueryObjectuiv __rglgen_glGetQueryObjectuiv #define glBindBuffer __rglgen_glBindBuffer #define glDeleteBuffers __rglgen_glDeleteBuffers #define glGenBuffers __rglgen_glGenBuffers #define glIsBuffer __rglgen_glIsBuffer #define glBufferData __rglgen_glBufferData #define glBufferSubData __rglgen_glBufferSubData #define glGetBufferSubData __rglgen_glGetBufferSubData #define glMapBuffer __rglgen_glMapBuffer #define glUnmapBuffer __rglgen_glUnmapBuffer #define glGetBufferParameteriv __rglgen_glGetBufferParameteriv #define glGetBufferPointerv __rglgen_glGetBufferPointerv #define glBlendEquationSeparate __rglgen_glBlendEquationSeparate #define glDrawBuffers __rglgen_glDrawBuffers #define glStencilOpSeparate __rglgen_glStencilOpSeparate #define glStencilFuncSeparate __rglgen_glStencilFuncSeparate #define glStencilMaskSeparate __rglgen_glStencilMaskSeparate #define glAttachShader __rglgen_glAttachShader #define glBindAttribLocation __rglgen_glBindAttribLocation #define glCompileShader __rglgen_glCompileShader #define glCreateProgram __rglgen_glCreateProgram #define glCreateShader __rglgen_glCreateShader #define glDeleteProgram __rglgen_glDeleteProgram #define glDeleteShader __rglgen_glDeleteShader #define glDetachShader __rglgen_glDetachShader #define glDisableVertexAttribArray __rglgen_glDisableVertexAttribArray #define glEnableVertexAttribArray __rglgen_glEnableVertexAttribArray #define glGetActiveAttrib __rglgen_glGetActiveAttrib #define glGetActiveUniform __rglgen_glGetActiveUniform #define glGetAttachedShaders __rglgen_glGetAttachedShaders #define glGetAttribLocation __rglgen_glGetAttribLocation #define glGetProgramiv __rglgen_glGetProgramiv #define glGetProgramInfoLog __rglgen_glGetProgramInfoLog #define glGetShaderiv __rglgen_glGetShaderiv #define glGetShaderInfoLog __rglgen_glGetShaderInfoLog #define glGetShaderSource __rglgen_glGetShaderSource #define glGetUniformLocation __rglgen_glGetUniformLocation #define glGetUniformfv __rglgen_glGetUniformfv #define glGetUniformiv __rglgen_glGetUniformiv #define glGetVertexAttribdv __rglgen_glGetVertexAttribdv #define glGetVertexAttribfv __rglgen_glGetVertexAttribfv #define glGetVertexAttribiv __rglgen_glGetVertexAttribiv #define glGetVertexAttribPointerv __rglgen_glGetVertexAttribPointerv #define glIsProgram __rglgen_glIsProgram #define glIsShader __rglgen_glIsShader #define glLinkProgram __rglgen_glLinkProgram #define glShaderSource __rglgen_glShaderSource #define glUseProgram __rglgen_glUseProgram #define glUniform1f __rglgen_glUniform1f #define glUniform2f __rglgen_glUniform2f #define glUniform3f __rglgen_glUniform3f #define glUniform4f __rglgen_glUniform4f #define glUniform1i __rglgen_glUniform1i #define glUniform2i __rglgen_glUniform2i #define glUniform3i __rglgen_glUniform3i #define glUniform4i __rglgen_glUniform4i #define glUniform1fv __rglgen_glUniform1fv #define glUniform2fv __rglgen_glUniform2fv #define glUniform3fv __rglgen_glUniform3fv #define glUniform4fv __rglgen_glUniform4fv #define glUniform1iv __rglgen_glUniform1iv #define glUniform2iv __rglgen_glUniform2iv #define glUniform3iv __rglgen_glUniform3iv #define glUniform4iv __rglgen_glUniform4iv #define glUniformMatrix2fv __rglgen_glUniformMatrix2fv #define glUniformMatrix3fv __rglgen_glUniformMatrix3fv #define glUniformMatrix4fv __rglgen_glUniformMatrix4fv #define glValidateProgram __rglgen_glValidateProgram #define glVertexAttrib1d __rglgen_glVertexAttrib1d #define glVertexAttrib1dv __rglgen_glVertexAttrib1dv #define glVertexAttrib1f __rglgen_glVertexAttrib1f #define glVertexAttrib1fv __rglgen_glVertexAttrib1fv #define glVertexAttrib1s __rglgen_glVertexAttrib1s #define glVertexAttrib1sv __rglgen_glVertexAttrib1sv #define glVertexAttrib2d __rglgen_glVertexAttrib2d #define glVertexAttrib2dv __rglgen_glVertexAttrib2dv #define glVertexAttrib2f __rglgen_glVertexAttrib2f #define glVertexAttrib2fv __rglgen_glVertexAttrib2fv #define glVertexAttrib2s __rglgen_glVertexAttrib2s #define glVertexAttrib2sv __rglgen_glVertexAttrib2sv #define glVertexAttrib3d __rglgen_glVertexAttrib3d #define glVertexAttrib3dv __rglgen_glVertexAttrib3dv #define glVertexAttrib3f __rglgen_glVertexAttrib3f #define glVertexAttrib3fv __rglgen_glVertexAttrib3fv #define glVertexAttrib3s __rglgen_glVertexAttrib3s #define glVertexAttrib3sv __rglgen_glVertexAttrib3sv #define glVertexAttrib4Nbv __rglgen_glVertexAttrib4Nbv #define glVertexAttrib4Niv __rglgen_glVertexAttrib4Niv #define glVertexAttrib4Nsv __rglgen_glVertexAttrib4Nsv #define glVertexAttrib4Nub __rglgen_glVertexAttrib4Nub #define glVertexAttrib4Nubv __rglgen_glVertexAttrib4Nubv #define glVertexAttrib4Nuiv __rglgen_glVertexAttrib4Nuiv #define glVertexAttrib4Nusv __rglgen_glVertexAttrib4Nusv #define glVertexAttrib4bv __rglgen_glVertexAttrib4bv #define glVertexAttrib4d __rglgen_glVertexAttrib4d #define glVertexAttrib4dv __rglgen_glVertexAttrib4dv #define glVertexAttrib4f __rglgen_glVertexAttrib4f #define glVertexAttrib4fv __rglgen_glVertexAttrib4fv #define glVertexAttrib4iv __rglgen_glVertexAttrib4iv #define glVertexAttrib4s __rglgen_glVertexAttrib4s #define glVertexAttrib4sv __rglgen_glVertexAttrib4sv #define glVertexAttrib4ubv __rglgen_glVertexAttrib4ubv #define glVertexAttrib4uiv __rglgen_glVertexAttrib4uiv #define glVertexAttrib4usv __rglgen_glVertexAttrib4usv #define glVertexAttribPointer __rglgen_glVertexAttribPointer #define glUniformMatrix2x3fv __rglgen_glUniformMatrix2x3fv #define glUniformMatrix3x2fv __rglgen_glUniformMatrix3x2fv #define glUniformMatrix2x4fv __rglgen_glUniformMatrix2x4fv #define glUniformMatrix4x2fv __rglgen_glUniformMatrix4x2fv #define glUniformMatrix3x4fv __rglgen_glUniformMatrix3x4fv #define glUniformMatrix4x3fv __rglgen_glUniformMatrix4x3fv #define glColorMaski __rglgen_glColorMaski #define glGetBooleani_v __rglgen_glGetBooleani_v #define glGetIntegeri_v __rglgen_glGetIntegeri_v #define glEnablei __rglgen_glEnablei #define glDisablei __rglgen_glDisablei #define glIsEnabledi __rglgen_glIsEnabledi #define glBeginTransformFeedback __rglgen_glBeginTransformFeedback #define glEndTransformFeedback __rglgen_glEndTransformFeedback #define glBindBufferRange __rglgen_glBindBufferRange #define glBindBufferBase __rglgen_glBindBufferBase #define glTransformFeedbackVaryings __rglgen_glTransformFeedbackVaryings #define glGetTransformFeedbackVarying __rglgen_glGetTransformFeedbackVarying #define glClampColor __rglgen_glClampColor #define glBeginConditionalRender __rglgen_glBeginConditionalRender #define glEndConditionalRender __rglgen_glEndConditionalRender #define glVertexAttribIPointer __rglgen_glVertexAttribIPointer #define glGetVertexAttribIiv __rglgen_glGetVertexAttribIiv #define glGetVertexAttribIuiv __rglgen_glGetVertexAttribIuiv #define glVertexAttribI1i __rglgen_glVertexAttribI1i #define glVertexAttribI2i __rglgen_glVertexAttribI2i #define glVertexAttribI3i __rglgen_glVertexAttribI3i #define glVertexAttribI4i __rglgen_glVertexAttribI4i #define glVertexAttribI1ui __rglgen_glVertexAttribI1ui #define glVertexAttribI2ui __rglgen_glVertexAttribI2ui #define glVertexAttribI3ui __rglgen_glVertexAttribI3ui #define glVertexAttribI4ui __rglgen_glVertexAttribI4ui #define glVertexAttribI1iv __rglgen_glVertexAttribI1iv #define glVertexAttribI2iv __rglgen_glVertexAttribI2iv #define glVertexAttribI3iv __rglgen_glVertexAttribI3iv #define glVertexAttribI4iv __rglgen_glVertexAttribI4iv #define glVertexAttribI1uiv __rglgen_glVertexAttribI1uiv #define glVertexAttribI2uiv __rglgen_glVertexAttribI2uiv #define glVertexAttribI3uiv __rglgen_glVertexAttribI3uiv #define glVertexAttribI4uiv __rglgen_glVertexAttribI4uiv #define glVertexAttribI4bv __rglgen_glVertexAttribI4bv #define glVertexAttribI4sv __rglgen_glVertexAttribI4sv #define glVertexAttribI4ubv __rglgen_glVertexAttribI4ubv #define glVertexAttribI4usv __rglgen_glVertexAttribI4usv #define glGetUniformuiv __rglgen_glGetUniformuiv #define glBindFragDataLocation __rglgen_glBindFragDataLocation #define glGetFragDataLocation __rglgen_glGetFragDataLocation #define glUniform1ui __rglgen_glUniform1ui #define glUniform2ui __rglgen_glUniform2ui #define glUniform3ui __rglgen_glUniform3ui #define glUniform4ui __rglgen_glUniform4ui #define glUniform1uiv __rglgen_glUniform1uiv #define glUniform2uiv __rglgen_glUniform2uiv #define glUniform3uiv __rglgen_glUniform3uiv #define glUniform4uiv __rglgen_glUniform4uiv #define glTexParameterIiv __rglgen_glTexParameterIiv #define glTexParameterIuiv __rglgen_glTexParameterIuiv #define glGetTexParameterIiv __rglgen_glGetTexParameterIiv #define glGetTexParameterIuiv __rglgen_glGetTexParameterIuiv #define glClearBufferiv __rglgen_glClearBufferiv #define glClearBufferuiv __rglgen_glClearBufferuiv #define glClearBufferfv __rglgen_glClearBufferfv #define glClearBufferfi __rglgen_glClearBufferfi #define glGetStringi __rglgen_glGetStringi #define glIsRenderbuffer __rglgen_glIsRenderbuffer #define glBindRenderbuffer __rglgen_glBindRenderbuffer #define glDeleteRenderbuffers __rglgen_glDeleteRenderbuffers #define glGenRenderbuffers __rglgen_glGenRenderbuffers #define glRenderbufferStorage __rglgen_glRenderbufferStorage #define glGetRenderbufferParameteriv __rglgen_glGetRenderbufferParameteriv #define glIsFramebuffer __rglgen_glIsFramebuffer #define glBindFramebuffer __rglgen_glBindFramebuffer #define glDeleteFramebuffers __rglgen_glDeleteFramebuffers #define glGenFramebuffers __rglgen_glGenFramebuffers #define glCheckFramebufferStatus __rglgen_glCheckFramebufferStatus #define glFramebufferTexture1D __rglgen_glFramebufferTexture1D #define glFramebufferTexture2D __rglgen_glFramebufferTexture2D #define glFramebufferTexture3D __rglgen_glFramebufferTexture3D #define glFramebufferRenderbuffer __rglgen_glFramebufferRenderbuffer #define glGetFramebufferAttachmentParameteriv __rglgen_glGetFramebufferAttachmentParameteriv #define glGenerateMipmap __rglgen_glGenerateMipmap #define glBlitFramebuffer __rglgen_glBlitFramebuffer #define glRenderbufferStorageMultisample __rglgen_glRenderbufferStorageMultisample #define glFramebufferTextureLayer __rglgen_glFramebufferTextureLayer #define glMapBufferRange __rglgen_glMapBufferRange #define glFlushMappedBufferRange __rglgen_glFlushMappedBufferRange #define glBindVertexArray __rglgen_glBindVertexArray #define glDeleteVertexArrays __rglgen_glDeleteVertexArrays #define glGenVertexArrays __rglgen_glGenVertexArrays #define glIsVertexArray __rglgen_glIsVertexArray #define glDrawArraysInstanced __rglgen_glDrawArraysInstanced #define glDrawElementsInstanced __rglgen_glDrawElementsInstanced #define glTexBuffer __rglgen_glTexBuffer #define glPrimitiveRestartIndex __rglgen_glPrimitiveRestartIndex #define glCopyBufferSubData __rglgen_glCopyBufferSubData #define glGetUniformIndices __rglgen_glGetUniformIndices #define glGetActiveUniformsiv __rglgen_glGetActiveUniformsiv #define glGetActiveUniformName __rglgen_glGetActiveUniformName #define glGetUniformBlockIndex __rglgen_glGetUniformBlockIndex #define glGetActiveUniformBlockiv __rglgen_glGetActiveUniformBlockiv #define glGetActiveUniformBlockName __rglgen_glGetActiveUniformBlockName #define glUniformBlockBinding __rglgen_glUniformBlockBinding #define glDrawElementsBaseVertex __rglgen_glDrawElementsBaseVertex #define glDrawRangeElementsBaseVertex __rglgen_glDrawRangeElementsBaseVertex #define glDrawElementsInstancedBaseVertex __rglgen_glDrawElementsInstancedBaseVertex #define glMultiDrawElementsBaseVertex __rglgen_glMultiDrawElementsBaseVertex #define glProvokingVertex __rglgen_glProvokingVertex #define glFenceSync __rglgen_glFenceSync #define glIsSync __rglgen_glIsSync #define glDeleteSync __rglgen_glDeleteSync #define glClientWaitSync __rglgen_glClientWaitSync #define glWaitSync __rglgen_glWaitSync #define glGetInteger64v __rglgen_glGetInteger64v #define glGetSynciv __rglgen_glGetSynciv #define glGetInteger64i_v __rglgen_glGetInteger64i_v #define glGetBufferParameteri64v __rglgen_glGetBufferParameteri64v #define glFramebufferTexture __rglgen_glFramebufferTexture #define glTexImage2DMultisample __rglgen_glTexImage2DMultisample #define glTexImage3DMultisample __rglgen_glTexImage3DMultisample #define glGetMultisamplefv __rglgen_glGetMultisamplefv #define glSampleMaski __rglgen_glSampleMaski #define glBindFragDataLocationIndexed __rglgen_glBindFragDataLocationIndexed #define glGetFragDataIndex __rglgen_glGetFragDataIndex #define glGenSamplers __rglgen_glGenSamplers #define glDeleteSamplers __rglgen_glDeleteSamplers #define glIsSampler __rglgen_glIsSampler #define glBindSampler __rglgen_glBindSampler #define glSamplerParameteri __rglgen_glSamplerParameteri #define glSamplerParameteriv __rglgen_glSamplerParameteriv #define glSamplerParameterf __rglgen_glSamplerParameterf #define glSamplerParameterfv __rglgen_glSamplerParameterfv #define glSamplerParameterIiv __rglgen_glSamplerParameterIiv #define glSamplerParameterIuiv __rglgen_glSamplerParameterIuiv #define glGetSamplerParameteriv __rglgen_glGetSamplerParameteriv #define glGetSamplerParameterIiv __rglgen_glGetSamplerParameterIiv #define glGetSamplerParameterfv __rglgen_glGetSamplerParameterfv #define glGetSamplerParameterIuiv __rglgen_glGetSamplerParameterIuiv #define glQueryCounter __rglgen_glQueryCounter #define glGetQueryObjecti64v __rglgen_glGetQueryObjecti64v #define glGetQueryObjectui64v __rglgen_glGetQueryObjectui64v #define glVertexAttribDivisor __rglgen_glVertexAttribDivisor #define glVertexAttribP1ui __rglgen_glVertexAttribP1ui #define glVertexAttribP1uiv __rglgen_glVertexAttribP1uiv #define glVertexAttribP2ui __rglgen_glVertexAttribP2ui #define glVertexAttribP2uiv __rglgen_glVertexAttribP2uiv #define glVertexAttribP3ui __rglgen_glVertexAttribP3ui #define glVertexAttribP3uiv __rglgen_glVertexAttribP3uiv #define glVertexAttribP4ui __rglgen_glVertexAttribP4ui #define glVertexAttribP4uiv __rglgen_glVertexAttribP4uiv #define glVertexP2ui __rglgen_glVertexP2ui #define glVertexP2uiv __rglgen_glVertexP2uiv #define glVertexP3ui __rglgen_glVertexP3ui #define glVertexP3uiv __rglgen_glVertexP3uiv #define glVertexP4ui __rglgen_glVertexP4ui #define glVertexP4uiv __rglgen_glVertexP4uiv #define glTexCoordP1ui __rglgen_glTexCoordP1ui #define glTexCoordP1uiv __rglgen_glTexCoordP1uiv #define glTexCoordP2ui __rglgen_glTexCoordP2ui #define glTexCoordP2uiv __rglgen_glTexCoordP2uiv #define glTexCoordP3ui __rglgen_glTexCoordP3ui #define glTexCoordP3uiv __rglgen_glTexCoordP3uiv #define glTexCoordP4ui __rglgen_glTexCoordP4ui #define glTexCoordP4uiv __rglgen_glTexCoordP4uiv #define glMultiTexCoordP1ui __rglgen_glMultiTexCoordP1ui #define glMultiTexCoordP1uiv __rglgen_glMultiTexCoordP1uiv #define glMultiTexCoordP2ui __rglgen_glMultiTexCoordP2ui #define glMultiTexCoordP2uiv __rglgen_glMultiTexCoordP2uiv #define glMultiTexCoordP3ui __rglgen_glMultiTexCoordP3ui #define glMultiTexCoordP3uiv __rglgen_glMultiTexCoordP3uiv #define glMultiTexCoordP4ui __rglgen_glMultiTexCoordP4ui #define glMultiTexCoordP4uiv __rglgen_glMultiTexCoordP4uiv #define glNormalP3ui __rglgen_glNormalP3ui #define glNormalP3uiv __rglgen_glNormalP3uiv #define glColorP3ui __rglgen_glColorP3ui #define glColorP3uiv __rglgen_glColorP3uiv #define glColorP4ui __rglgen_glColorP4ui #define glColorP4uiv __rglgen_glColorP4uiv #define glSecondaryColorP3ui __rglgen_glSecondaryColorP3ui #define glSecondaryColorP3uiv __rglgen_glSecondaryColorP3uiv #define glMinSampleShading __rglgen_glMinSampleShading #define glBlendEquationi __rglgen_glBlendEquationi #define glBlendEquationSeparatei __rglgen_glBlendEquationSeparatei #define glBlendFunci __rglgen_glBlendFunci #define glBlendFuncSeparatei __rglgen_glBlendFuncSeparatei #define glDrawArraysIndirect __rglgen_glDrawArraysIndirect #define glDrawElementsIndirect __rglgen_glDrawElementsIndirect #define glUniform1d __rglgen_glUniform1d #define glUniform2d __rglgen_glUniform2d #define glUniform3d __rglgen_glUniform3d #define glUniform4d __rglgen_glUniform4d #define glUniform1dv __rglgen_glUniform1dv #define glUniform2dv __rglgen_glUniform2dv #define glUniform3dv __rglgen_glUniform3dv #define glUniform4dv __rglgen_glUniform4dv #define glUniformMatrix2dv __rglgen_glUniformMatrix2dv #define glUniformMatrix3dv __rglgen_glUniformMatrix3dv #define glUniformMatrix4dv __rglgen_glUniformMatrix4dv #define glUniformMatrix2x3dv __rglgen_glUniformMatrix2x3dv #define glUniformMatrix2x4dv __rglgen_glUniformMatrix2x4dv #define glUniformMatrix3x2dv __rglgen_glUniformMatrix3x2dv #define glUniformMatrix3x4dv __rglgen_glUniformMatrix3x4dv #define glUniformMatrix4x2dv __rglgen_glUniformMatrix4x2dv #define glUniformMatrix4x3dv __rglgen_glUniformMatrix4x3dv #define glGetUniformdv __rglgen_glGetUniformdv #define glGetSubroutineUniformLocation __rglgen_glGetSubroutineUniformLocation #define glGetSubroutineIndex __rglgen_glGetSubroutineIndex #define glGetActiveSubroutineUniformiv __rglgen_glGetActiveSubroutineUniformiv #define glGetActiveSubroutineUniformName __rglgen_glGetActiveSubroutineUniformName #define glGetActiveSubroutineName __rglgen_glGetActiveSubroutineName #define glUniformSubroutinesuiv __rglgen_glUniformSubroutinesuiv #define glGetUniformSubroutineuiv __rglgen_glGetUniformSubroutineuiv #define glGetProgramStageiv __rglgen_glGetProgramStageiv #define glPatchParameteri __rglgen_glPatchParameteri #define glPatchParameterfv __rglgen_glPatchParameterfv #define glBindTransformFeedback __rglgen_glBindTransformFeedback #define glDeleteTransformFeedbacks __rglgen_glDeleteTransformFeedbacks #define glGenTransformFeedbacks __rglgen_glGenTransformFeedbacks #define glIsTransformFeedback __rglgen_glIsTransformFeedback #define glPauseTransformFeedback __rglgen_glPauseTransformFeedback #define glResumeTransformFeedback __rglgen_glResumeTransformFeedback #define glDrawTransformFeedback __rglgen_glDrawTransformFeedback #define glDrawTransformFeedbackStream __rglgen_glDrawTransformFeedbackStream #define glBeginQueryIndexed __rglgen_glBeginQueryIndexed #define glEndQueryIndexed __rglgen_glEndQueryIndexed #define glGetQueryIndexediv __rglgen_glGetQueryIndexediv #define glReleaseShaderCompiler __rglgen_glReleaseShaderCompiler #define glShaderBinary __rglgen_glShaderBinary #define glGetShaderPrecisionFormat __rglgen_glGetShaderPrecisionFormat #define glDepthRangef __rglgen_glDepthRangef #define glClearDepthf __rglgen_glClearDepthf #define glGetProgramBinary __rglgen_glGetProgramBinary #define glProgramBinary __rglgen_glProgramBinary #define glProgramParameteri __rglgen_glProgramParameteri #define glUseProgramStages __rglgen_glUseProgramStages #define glActiveShaderProgram __rglgen_glActiveShaderProgram #define glCreateShaderProgramv __rglgen_glCreateShaderProgramv #define glBindProgramPipeline __rglgen_glBindProgramPipeline #define glDeleteProgramPipelines __rglgen_glDeleteProgramPipelines #define glGenProgramPipelines __rglgen_glGenProgramPipelines #define glIsProgramPipeline __rglgen_glIsProgramPipeline #define glGetProgramPipelineiv __rglgen_glGetProgramPipelineiv #define glProgramUniform1i __rglgen_glProgramUniform1i #define glProgramUniform1iv __rglgen_glProgramUniform1iv #define glProgramUniform1f __rglgen_glProgramUniform1f #define glProgramUniform1fv __rglgen_glProgramUniform1fv #define glProgramUniform1d __rglgen_glProgramUniform1d #define glProgramUniform1dv __rglgen_glProgramUniform1dv #define glProgramUniform1ui __rglgen_glProgramUniform1ui #define glProgramUniform1uiv __rglgen_glProgramUniform1uiv #define glProgramUniform2i __rglgen_glProgramUniform2i #define glProgramUniform2iv __rglgen_glProgramUniform2iv #define glProgramUniform2f __rglgen_glProgramUniform2f #define glProgramUniform2fv __rglgen_glProgramUniform2fv #define glProgramUniform2d __rglgen_glProgramUniform2d #define glProgramUniform2dv __rglgen_glProgramUniform2dv #define glProgramUniform2ui __rglgen_glProgramUniform2ui #define glProgramUniform2uiv __rglgen_glProgramUniform2uiv #define glProgramUniform3i __rglgen_glProgramUniform3i #define glProgramUniform3iv __rglgen_glProgramUniform3iv #define glProgramUniform3f __rglgen_glProgramUniform3f #define glProgramUniform3fv __rglgen_glProgramUniform3fv #define glProgramUniform3d __rglgen_glProgramUniform3d #define glProgramUniform3dv __rglgen_glProgramUniform3dv #define glProgramUniform3ui __rglgen_glProgramUniform3ui #define glProgramUniform3uiv __rglgen_glProgramUniform3uiv #define glProgramUniform4i __rglgen_glProgramUniform4i #define glProgramUniform4iv __rglgen_glProgramUniform4iv #define glProgramUniform4f __rglgen_glProgramUniform4f #define glProgramUniform4fv __rglgen_glProgramUniform4fv #define glProgramUniform4d __rglgen_glProgramUniform4d #define glProgramUniform4dv __rglgen_glProgramUniform4dv #define glProgramUniform4ui __rglgen_glProgramUniform4ui #define glProgramUniform4uiv __rglgen_glProgramUniform4uiv #define glProgramUniformMatrix2fv __rglgen_glProgramUniformMatrix2fv #define glProgramUniformMatrix3fv __rglgen_glProgramUniformMatrix3fv #define glProgramUniformMatrix4fv __rglgen_glProgramUniformMatrix4fv #define glProgramUniformMatrix2dv __rglgen_glProgramUniformMatrix2dv #define glProgramUniformMatrix3dv __rglgen_glProgramUniformMatrix3dv #define glProgramUniformMatrix4dv __rglgen_glProgramUniformMatrix4dv #define glProgramUniformMatrix2x3fv __rglgen_glProgramUniformMatrix2x3fv #define glProgramUniformMatrix3x2fv __rglgen_glProgramUniformMatrix3x2fv #define glProgramUniformMatrix2x4fv __rglgen_glProgramUniformMatrix2x4fv #define glProgramUniformMatrix4x2fv __rglgen_glProgramUniformMatrix4x2fv #define glProgramUniformMatrix3x4fv __rglgen_glProgramUniformMatrix3x4fv #define glProgramUniformMatrix4x3fv __rglgen_glProgramUniformMatrix4x3fv #define glProgramUniformMatrix2x3dv __rglgen_glProgramUniformMatrix2x3dv #define glProgramUniformMatrix3x2dv __rglgen_glProgramUniformMatrix3x2dv #define glProgramUniformMatrix2x4dv __rglgen_glProgramUniformMatrix2x4dv #define glProgramUniformMatrix4x2dv __rglgen_glProgramUniformMatrix4x2dv #define glProgramUniformMatrix3x4dv __rglgen_glProgramUniformMatrix3x4dv #define glProgramUniformMatrix4x3dv __rglgen_glProgramUniformMatrix4x3dv #define glValidateProgramPipeline __rglgen_glValidateProgramPipeline #define glGetProgramPipelineInfoLog __rglgen_glGetProgramPipelineInfoLog #define glVertexAttribL1d __rglgen_glVertexAttribL1d #define glVertexAttribL2d __rglgen_glVertexAttribL2d #define glVertexAttribL3d __rglgen_glVertexAttribL3d #define glVertexAttribL4d __rglgen_glVertexAttribL4d #define glVertexAttribL1dv __rglgen_glVertexAttribL1dv #define glVertexAttribL2dv __rglgen_glVertexAttribL2dv #define glVertexAttribL3dv __rglgen_glVertexAttribL3dv #define glVertexAttribL4dv __rglgen_glVertexAttribL4dv #define glVertexAttribLPointer __rglgen_glVertexAttribLPointer #define glGetVertexAttribLdv __rglgen_glGetVertexAttribLdv #define glViewportArrayv __rglgen_glViewportArrayv #define glViewportIndexedf __rglgen_glViewportIndexedf #define glViewportIndexedfv __rglgen_glViewportIndexedfv #define glScissorArrayv __rglgen_glScissorArrayv #define glScissorIndexed __rglgen_glScissorIndexed #define glScissorIndexedv __rglgen_glScissorIndexedv #define glDepthRangeArrayv __rglgen_glDepthRangeArrayv #define glDepthRangeIndexed __rglgen_glDepthRangeIndexed #define glGetFloati_v __rglgen_glGetFloati_v #define glGetDoublei_v __rglgen_glGetDoublei_v #define glDrawArraysInstancedBaseInstance __rglgen_glDrawArraysInstancedBaseInstance #define glDrawElementsInstancedBaseInstance __rglgen_glDrawElementsInstancedBaseInstance #define glDrawElementsInstancedBaseVertexBaseInstance __rglgen_glDrawElementsInstancedBaseVertexBaseInstance #define glGetInternalformativ __rglgen_glGetInternalformativ #define glGetActiveAtomicCounterBufferiv __rglgen_glGetActiveAtomicCounterBufferiv #define glBindImageTexture __rglgen_glBindImageTexture #define glMemoryBarrier __rglgen_glMemoryBarrier #define glTexStorage1D __rglgen_glTexStorage1D #define glTexStorage2D __rglgen_glTexStorage2D #define glTexStorage3D __rglgen_glTexStorage3D #define glDrawTransformFeedbackInstanced __rglgen_glDrawTransformFeedbackInstanced #define glDrawTransformFeedbackStreamInstanced __rglgen_glDrawTransformFeedbackStreamInstanced #define glClearBufferData __rglgen_glClearBufferData #define glClearBufferSubData __rglgen_glClearBufferSubData #define glDispatchCompute __rglgen_glDispatchCompute #define glDispatchComputeIndirect __rglgen_glDispatchComputeIndirect #define glCopyImageSubData __rglgen_glCopyImageSubData #define glFramebufferParameteri __rglgen_glFramebufferParameteri #define glGetFramebufferParameteriv __rglgen_glGetFramebufferParameteriv #define glGetInternalformati64v __rglgen_glGetInternalformati64v #define glInvalidateTexSubImage __rglgen_glInvalidateTexSubImage #define glInvalidateTexImage __rglgen_glInvalidateTexImage #define glInvalidateBufferSubData __rglgen_glInvalidateBufferSubData #define glInvalidateBufferData __rglgen_glInvalidateBufferData #define glInvalidateFramebuffer __rglgen_glInvalidateFramebuffer #define glInvalidateSubFramebuffer __rglgen_glInvalidateSubFramebuffer #define glMultiDrawArraysIndirect __rglgen_glMultiDrawArraysIndirect #define glMultiDrawElementsIndirect __rglgen_glMultiDrawElementsIndirect #define glGetProgramInterfaceiv __rglgen_glGetProgramInterfaceiv #define glGetProgramResourceIndex __rglgen_glGetProgramResourceIndex #define glGetProgramResourceName __rglgen_glGetProgramResourceName #define glGetProgramResourceiv __rglgen_glGetProgramResourceiv #define glGetProgramResourceLocation __rglgen_glGetProgramResourceLocation #define glGetProgramResourceLocationIndex __rglgen_glGetProgramResourceLocationIndex #define glShaderStorageBlockBinding __rglgen_glShaderStorageBlockBinding #define glTexBufferRange __rglgen_glTexBufferRange #define glTexStorage2DMultisample __rglgen_glTexStorage2DMultisample #define glTexStorage3DMultisample __rglgen_glTexStorage3DMultisample #define glTextureView __rglgen_glTextureView #define glBindVertexBuffer __rglgen_glBindVertexBuffer #define glVertexAttribFormat __rglgen_glVertexAttribFormat #define glVertexAttribIFormat __rglgen_glVertexAttribIFormat #define glVertexAttribLFormat __rglgen_glVertexAttribLFormat #define glVertexAttribBinding __rglgen_glVertexAttribBinding #define glVertexBindingDivisor __rglgen_glVertexBindingDivisor #define glDebugMessageControl __rglgen_glDebugMessageControl #define glDebugMessageInsert __rglgen_glDebugMessageInsert #define glDebugMessageCallback __rglgen_glDebugMessageCallback #define glGetDebugMessageLog __rglgen_glGetDebugMessageLog #define glPushDebugGroup __rglgen_glPushDebugGroup #define glPopDebugGroup __rglgen_glPopDebugGroup #define glObjectLabel __rglgen_glObjectLabel #define glGetObjectLabel __rglgen_glGetObjectLabel #define glObjectPtrLabel __rglgen_glObjectPtrLabel #define glGetObjectPtrLabel __rglgen_glGetObjectPtrLabel #define glBufferStorage __rglgen_glBufferStorage #define glClearTexImage __rglgen_glClearTexImage #define glClearTexSubImage __rglgen_glClearTexSubImage #define glBindBuffersBase __rglgen_glBindBuffersBase #define glBindBuffersRange __rglgen_glBindBuffersRange #define glBindTextures __rglgen_glBindTextures #define glBindSamplers __rglgen_glBindSamplers #define glBindImageTextures __rglgen_glBindImageTextures #define glBindVertexBuffers __rglgen_glBindVertexBuffers #define glGetTextureHandleARB __rglgen_glGetTextureHandleARB #define glGetTextureSamplerHandleARB __rglgen_glGetTextureSamplerHandleARB #define glMakeTextureHandleResidentARB __rglgen_glMakeTextureHandleResidentARB #define glMakeTextureHandleNonResidentARB __rglgen_glMakeTextureHandleNonResidentARB #define glGetImageHandleARB __rglgen_glGetImageHandleARB #define glMakeImageHandleResidentARB __rglgen_glMakeImageHandleResidentARB #define glMakeImageHandleNonResidentARB __rglgen_glMakeImageHandleNonResidentARB #define glUniformHandleui64ARB __rglgen_glUniformHandleui64ARB #define glUniformHandleui64vARB __rglgen_glUniformHandleui64vARB #define glProgramUniformHandleui64ARB __rglgen_glProgramUniformHandleui64ARB #define glProgramUniformHandleui64vARB __rglgen_glProgramUniformHandleui64vARB #define glIsTextureHandleResidentARB __rglgen_glIsTextureHandleResidentARB #define glIsImageHandleResidentARB __rglgen_glIsImageHandleResidentARB #define glVertexAttribL1ui64ARB __rglgen_glVertexAttribL1ui64ARB #define glVertexAttribL1ui64vARB __rglgen_glVertexAttribL1ui64vARB #define glGetVertexAttribLui64vARB __rglgen_glGetVertexAttribLui64vARB #define glCreateSyncFromCLeventARB __rglgen_glCreateSyncFromCLeventARB #define glClampColorARB __rglgen_glClampColorARB #define glDispatchComputeGroupSizeARB __rglgen_glDispatchComputeGroupSizeARB #define glDebugMessageControlARB __rglgen_glDebugMessageControlARB #define glDebugMessageInsertARB __rglgen_glDebugMessageInsertARB #define glDebugMessageCallbackARB __rglgen_glDebugMessageCallbackARB #define glGetDebugMessageLogARB __rglgen_glGetDebugMessageLogARB #define glDrawBuffersARB __rglgen_glDrawBuffersARB #define glBlendEquationiARB __rglgen_glBlendEquationiARB #define glBlendEquationSeparateiARB __rglgen_glBlendEquationSeparateiARB #define glBlendFunciARB __rglgen_glBlendFunciARB #define glBlendFuncSeparateiARB __rglgen_glBlendFuncSeparateiARB #define glDrawArraysInstancedARB __rglgen_glDrawArraysInstancedARB #define glDrawElementsInstancedARB __rglgen_glDrawElementsInstancedARB #define glProgramStringARB __rglgen_glProgramStringARB #define glBindProgramARB __rglgen_glBindProgramARB #define glDeleteProgramsARB __rglgen_glDeleteProgramsARB #define glGenProgramsARB __rglgen_glGenProgramsARB #define glProgramEnvParameter4dARB __rglgen_glProgramEnvParameter4dARB #define glProgramEnvParameter4dvARB __rglgen_glProgramEnvParameter4dvARB #define glProgramEnvParameter4fARB __rglgen_glProgramEnvParameter4fARB #define glProgramEnvParameter4fvARB __rglgen_glProgramEnvParameter4fvARB #define glProgramLocalParameter4dARB __rglgen_glProgramLocalParameter4dARB #define glProgramLocalParameter4dvARB __rglgen_glProgramLocalParameter4dvARB #define glProgramLocalParameter4fARB __rglgen_glProgramLocalParameter4fARB #define glProgramLocalParameter4fvARB __rglgen_glProgramLocalParameter4fvARB #define glGetProgramEnvParameterdvARB __rglgen_glGetProgramEnvParameterdvARB #define glGetProgramEnvParameterfvARB __rglgen_glGetProgramEnvParameterfvARB #define glGetProgramLocalParameterdvARB __rglgen_glGetProgramLocalParameterdvARB #define glGetProgramLocalParameterfvARB __rglgen_glGetProgramLocalParameterfvARB #define glGetProgramivARB __rglgen_glGetProgramivARB #define glGetProgramStringARB __rglgen_glGetProgramStringARB #define glIsProgramARB __rglgen_glIsProgramARB #define glProgramParameteriARB __rglgen_glProgramParameteriARB #define glFramebufferTextureARB __rglgen_glFramebufferTextureARB #define glFramebufferTextureLayerARB __rglgen_glFramebufferTextureLayerARB #define glFramebufferTextureFaceARB __rglgen_glFramebufferTextureFaceARB #define glColorTable __rglgen_glColorTable #define glColorTableParameterfv __rglgen_glColorTableParameterfv #define glColorTableParameteriv __rglgen_glColorTableParameteriv #define glCopyColorTable __rglgen_glCopyColorTable #define glGetColorTable __rglgen_glGetColorTable #define glGetColorTableParameterfv __rglgen_glGetColorTableParameterfv #define glGetColorTableParameteriv __rglgen_glGetColorTableParameteriv #define glColorSubTable __rglgen_glColorSubTable #define glCopyColorSubTable __rglgen_glCopyColorSubTable #define glConvolutionFilter1D __rglgen_glConvolutionFilter1D #define glConvolutionFilter2D __rglgen_glConvolutionFilter2D #define glConvolutionParameterf __rglgen_glConvolutionParameterf #define glConvolutionParameterfv __rglgen_glConvolutionParameterfv #define glConvolutionParameteri __rglgen_glConvolutionParameteri #define glConvolutionParameteriv __rglgen_glConvolutionParameteriv #define glCopyConvolutionFilter1D __rglgen_glCopyConvolutionFilter1D #define glCopyConvolutionFilter2D __rglgen_glCopyConvolutionFilter2D #define glGetConvolutionFilter __rglgen_glGetConvolutionFilter #define glGetConvolutionParameterfv __rglgen_glGetConvolutionParameterfv #define glGetConvolutionParameteriv __rglgen_glGetConvolutionParameteriv #define glGetSeparableFilter __rglgen_glGetSeparableFilter #define glSeparableFilter2D __rglgen_glSeparableFilter2D #define glGetHistogram __rglgen_glGetHistogram #define glGetHistogramParameterfv __rglgen_glGetHistogramParameterfv #define glGetHistogramParameteriv __rglgen_glGetHistogramParameteriv #define glGetMinmax __rglgen_glGetMinmax #define glGetMinmaxParameterfv __rglgen_glGetMinmaxParameterfv #define glGetMinmaxParameteriv __rglgen_glGetMinmaxParameteriv #define glHistogram __rglgen_glHistogram #define glMinmax __rglgen_glMinmax #define glResetHistogram __rglgen_glResetHistogram #define glResetMinmax __rglgen_glResetMinmax #define glMultiDrawArraysIndirectCountARB __rglgen_glMultiDrawArraysIndirectCountARB #define glMultiDrawElementsIndirectCountARB __rglgen_glMultiDrawElementsIndirectCountARB #define glVertexAttribDivisorARB __rglgen_glVertexAttribDivisorARB #define glCurrentPaletteMatrixARB __rglgen_glCurrentPaletteMatrixARB #define glMatrixIndexubvARB __rglgen_glMatrixIndexubvARB #define glMatrixIndexusvARB __rglgen_glMatrixIndexusvARB #define glMatrixIndexuivARB __rglgen_glMatrixIndexuivARB #define glMatrixIndexPointerARB __rglgen_glMatrixIndexPointerARB #define glSampleCoverageARB __rglgen_glSampleCoverageARB #define glActiveTextureARB __rglgen_glActiveTextureARB #define glClientActiveTextureARB __rglgen_glClientActiveTextureARB #define glMultiTexCoord1dARB __rglgen_glMultiTexCoord1dARB #define glMultiTexCoord1dvARB __rglgen_glMultiTexCoord1dvARB #define glMultiTexCoord1fARB __rglgen_glMultiTexCoord1fARB #define glMultiTexCoord1fvARB __rglgen_glMultiTexCoord1fvARB #define glMultiTexCoord1iARB __rglgen_glMultiTexCoord1iARB #define glMultiTexCoord1ivARB __rglgen_glMultiTexCoord1ivARB #define glMultiTexCoord1sARB __rglgen_glMultiTexCoord1sARB #define glMultiTexCoord1svARB __rglgen_glMultiTexCoord1svARB #define glMultiTexCoord2dARB __rglgen_glMultiTexCoord2dARB #define glMultiTexCoord2dvARB __rglgen_glMultiTexCoord2dvARB #define glMultiTexCoord2fARB __rglgen_glMultiTexCoord2fARB #define glMultiTexCoord2fvARB __rglgen_glMultiTexCoord2fvARB #define glMultiTexCoord2iARB __rglgen_glMultiTexCoord2iARB #define glMultiTexCoord2ivARB __rglgen_glMultiTexCoord2ivARB #define glMultiTexCoord2sARB __rglgen_glMultiTexCoord2sARB #define glMultiTexCoord2svARB __rglgen_glMultiTexCoord2svARB #define glMultiTexCoord3dARB __rglgen_glMultiTexCoord3dARB #define glMultiTexCoord3dvARB __rglgen_glMultiTexCoord3dvARB #define glMultiTexCoord3fARB __rglgen_glMultiTexCoord3fARB #define glMultiTexCoord3fvARB __rglgen_glMultiTexCoord3fvARB #define glMultiTexCoord3iARB __rglgen_glMultiTexCoord3iARB #define glMultiTexCoord3ivARB __rglgen_glMultiTexCoord3ivARB #define glMultiTexCoord3sARB __rglgen_glMultiTexCoord3sARB #define glMultiTexCoord3svARB __rglgen_glMultiTexCoord3svARB #define glMultiTexCoord4dARB __rglgen_glMultiTexCoord4dARB #define glMultiTexCoord4dvARB __rglgen_glMultiTexCoord4dvARB #define glMultiTexCoord4fARB __rglgen_glMultiTexCoord4fARB #define glMultiTexCoord4fvARB __rglgen_glMultiTexCoord4fvARB #define glMultiTexCoord4iARB __rglgen_glMultiTexCoord4iARB #define glMultiTexCoord4ivARB __rglgen_glMultiTexCoord4ivARB #define glMultiTexCoord4sARB __rglgen_glMultiTexCoord4sARB #define glMultiTexCoord4svARB __rglgen_glMultiTexCoord4svARB #define glGenQueriesARB __rglgen_glGenQueriesARB #define glDeleteQueriesARB __rglgen_glDeleteQueriesARB #define glIsQueryARB __rglgen_glIsQueryARB #define glBeginQueryARB __rglgen_glBeginQueryARB #define glEndQueryARB __rglgen_glEndQueryARB #define glGetQueryivARB __rglgen_glGetQueryivARB #define glGetQueryObjectivARB __rglgen_glGetQueryObjectivARB #define glGetQueryObjectuivARB __rglgen_glGetQueryObjectuivARB #define glPointParameterfARB __rglgen_glPointParameterfARB #define glPointParameterfvARB __rglgen_glPointParameterfvARB #define glGetGraphicsResetStatusARB __rglgen_glGetGraphicsResetStatusARB #define glGetnTexImageARB __rglgen_glGetnTexImageARB #define glReadnPixelsARB __rglgen_glReadnPixelsARB #define glGetnCompressedTexImageARB __rglgen_glGetnCompressedTexImageARB #define glGetnUniformfvARB __rglgen_glGetnUniformfvARB #define glGetnUniformivARB __rglgen_glGetnUniformivARB #define glGetnUniformuivARB __rglgen_glGetnUniformuivARB #define glGetnUniformdvARB __rglgen_glGetnUniformdvARB #define glGetnMapdvARB __rglgen_glGetnMapdvARB #define glGetnMapfvARB __rglgen_glGetnMapfvARB #define glGetnMapivARB __rglgen_glGetnMapivARB #define glGetnPixelMapfvARB __rglgen_glGetnPixelMapfvARB #define glGetnPixelMapuivARB __rglgen_glGetnPixelMapuivARB #define glGetnPixelMapusvARB __rglgen_glGetnPixelMapusvARB #define glGetnPolygonStippleARB __rglgen_glGetnPolygonStippleARB #define glGetnColorTableARB __rglgen_glGetnColorTableARB #define glGetnConvolutionFilterARB __rglgen_glGetnConvolutionFilterARB #define glGetnSeparableFilterARB __rglgen_glGetnSeparableFilterARB #define glGetnHistogramARB __rglgen_glGetnHistogramARB #define glGetnMinmaxARB __rglgen_glGetnMinmaxARB #define glMinSampleShadingARB __rglgen_glMinSampleShadingARB #define glDeleteObjectARB __rglgen_glDeleteObjectARB #define glGetHandleARB __rglgen_glGetHandleARB #define glDetachObjectARB __rglgen_glDetachObjectARB #define glCreateShaderObjectARB __rglgen_glCreateShaderObjectARB #define glShaderSourceARB __rglgen_glShaderSourceARB #define glCompileShaderARB __rglgen_glCompileShaderARB #define glCreateProgramObjectARB __rglgen_glCreateProgramObjectARB #define glAttachObjectARB __rglgen_glAttachObjectARB #define glLinkProgramARB __rglgen_glLinkProgramARB #define glUseProgramObjectARB __rglgen_glUseProgramObjectARB #define glValidateProgramARB __rglgen_glValidateProgramARB #define glUniform1fARB __rglgen_glUniform1fARB #define glUniform2fARB __rglgen_glUniform2fARB #define glUniform3fARB __rglgen_glUniform3fARB #define glUniform4fARB __rglgen_glUniform4fARB #define glUniform1iARB __rglgen_glUniform1iARB #define glUniform2iARB __rglgen_glUniform2iARB #define glUniform3iARB __rglgen_glUniform3iARB #define glUniform4iARB __rglgen_glUniform4iARB #define glUniform1fvARB __rglgen_glUniform1fvARB #define glUniform2fvARB __rglgen_glUniform2fvARB #define glUniform3fvARB __rglgen_glUniform3fvARB #define glUniform4fvARB __rglgen_glUniform4fvARB #define glUniform1ivARB __rglgen_glUniform1ivARB #define glUniform2ivARB __rglgen_glUniform2ivARB #define glUniform3ivARB __rglgen_glUniform3ivARB #define glUniform4ivARB __rglgen_glUniform4ivARB #define glUniformMatrix2fvARB __rglgen_glUniformMatrix2fvARB #define glUniformMatrix3fvARB __rglgen_glUniformMatrix3fvARB #define glUniformMatrix4fvARB __rglgen_glUniformMatrix4fvARB #define glGetObjectParameterfvARB __rglgen_glGetObjectParameterfvARB #define glGetObjectParameterivARB __rglgen_glGetObjectParameterivARB #define glGetInfoLogARB __rglgen_glGetInfoLogARB #define glGetAttachedObjectsARB __rglgen_glGetAttachedObjectsARB #define glGetUniformLocationARB __rglgen_glGetUniformLocationARB #define glGetActiveUniformARB __rglgen_glGetActiveUniformARB #define glGetUniformfvARB __rglgen_glGetUniformfvARB #define glGetUniformivARB __rglgen_glGetUniformivARB #define glGetShaderSourceARB __rglgen_glGetShaderSourceARB #define glNamedStringARB __rglgen_glNamedStringARB #define glDeleteNamedStringARB __rglgen_glDeleteNamedStringARB #define glCompileShaderIncludeARB __rglgen_glCompileShaderIncludeARB #define glIsNamedStringARB __rglgen_glIsNamedStringARB #define glGetNamedStringARB __rglgen_glGetNamedStringARB #define glGetNamedStringivARB __rglgen_glGetNamedStringivARB #define glTexPageCommitmentARB __rglgen_glTexPageCommitmentARB #define glTexBufferARB __rglgen_glTexBufferARB #define glCompressedTexImage3DARB __rglgen_glCompressedTexImage3DARB #define glCompressedTexImage2DARB __rglgen_glCompressedTexImage2DARB #define glCompressedTexImage1DARB __rglgen_glCompressedTexImage1DARB #define glCompressedTexSubImage3DARB __rglgen_glCompressedTexSubImage3DARB #define glCompressedTexSubImage2DARB __rglgen_glCompressedTexSubImage2DARB #define glCompressedTexSubImage1DARB __rglgen_glCompressedTexSubImage1DARB #define glGetCompressedTexImageARB __rglgen_glGetCompressedTexImageARB #define glLoadTransposeMatrixfARB __rglgen_glLoadTransposeMatrixfARB #define glLoadTransposeMatrixdARB __rglgen_glLoadTransposeMatrixdARB #define glMultTransposeMatrixfARB __rglgen_glMultTransposeMatrixfARB #define glMultTransposeMatrixdARB __rglgen_glMultTransposeMatrixdARB #define glWeightbvARB __rglgen_glWeightbvARB #define glWeightsvARB __rglgen_glWeightsvARB #define glWeightivARB __rglgen_glWeightivARB #define glWeightfvARB __rglgen_glWeightfvARB #define glWeightdvARB __rglgen_glWeightdvARB #define glWeightubvARB __rglgen_glWeightubvARB #define glWeightusvARB __rglgen_glWeightusvARB #define glWeightuivARB __rglgen_glWeightuivARB #define glWeightPointerARB __rglgen_glWeightPointerARB #define glVertexBlendARB __rglgen_glVertexBlendARB #define glBindBufferARB __rglgen_glBindBufferARB #define glDeleteBuffersARB __rglgen_glDeleteBuffersARB #define glGenBuffersARB __rglgen_glGenBuffersARB #define glIsBufferARB __rglgen_glIsBufferARB #define glBufferDataARB __rglgen_glBufferDataARB #define glBufferSubDataARB __rglgen_glBufferSubDataARB #define glGetBufferSubDataARB __rglgen_glGetBufferSubDataARB #define glMapBufferARB __rglgen_glMapBufferARB #define glUnmapBufferARB __rglgen_glUnmapBufferARB #define glGetBufferParameterivARB __rglgen_glGetBufferParameterivARB #define glGetBufferPointervARB __rglgen_glGetBufferPointervARB #define glVertexAttrib1dARB __rglgen_glVertexAttrib1dARB #define glVertexAttrib1dvARB __rglgen_glVertexAttrib1dvARB #define glVertexAttrib1fARB __rglgen_glVertexAttrib1fARB #define glVertexAttrib1fvARB __rglgen_glVertexAttrib1fvARB #define glVertexAttrib1sARB __rglgen_glVertexAttrib1sARB #define glVertexAttrib1svARB __rglgen_glVertexAttrib1svARB #define glVertexAttrib2dARB __rglgen_glVertexAttrib2dARB #define glVertexAttrib2dvARB __rglgen_glVertexAttrib2dvARB #define glVertexAttrib2fARB __rglgen_glVertexAttrib2fARB #define glVertexAttrib2fvARB __rglgen_glVertexAttrib2fvARB #define glVertexAttrib2sARB __rglgen_glVertexAttrib2sARB #define glVertexAttrib2svARB __rglgen_glVertexAttrib2svARB #define glVertexAttrib3dARB __rglgen_glVertexAttrib3dARB #define glVertexAttrib3dvARB __rglgen_glVertexAttrib3dvARB #define glVertexAttrib3fARB __rglgen_glVertexAttrib3fARB #define glVertexAttrib3fvARB __rglgen_glVertexAttrib3fvARB #define glVertexAttrib3sARB __rglgen_glVertexAttrib3sARB #define glVertexAttrib3svARB __rglgen_glVertexAttrib3svARB #define glVertexAttrib4NbvARB __rglgen_glVertexAttrib4NbvARB #define glVertexAttrib4NivARB __rglgen_glVertexAttrib4NivARB #define glVertexAttrib4NsvARB __rglgen_glVertexAttrib4NsvARB #define glVertexAttrib4NubARB __rglgen_glVertexAttrib4NubARB #define glVertexAttrib4NubvARB __rglgen_glVertexAttrib4NubvARB #define glVertexAttrib4NuivARB __rglgen_glVertexAttrib4NuivARB #define glVertexAttrib4NusvARB __rglgen_glVertexAttrib4NusvARB #define glVertexAttrib4bvARB __rglgen_glVertexAttrib4bvARB #define glVertexAttrib4dARB __rglgen_glVertexAttrib4dARB #define glVertexAttrib4dvARB __rglgen_glVertexAttrib4dvARB #define glVertexAttrib4fARB __rglgen_glVertexAttrib4fARB #define glVertexAttrib4fvARB __rglgen_glVertexAttrib4fvARB #define glVertexAttrib4ivARB __rglgen_glVertexAttrib4ivARB #define glVertexAttrib4sARB __rglgen_glVertexAttrib4sARB #define glVertexAttrib4svARB __rglgen_glVertexAttrib4svARB #define glVertexAttrib4ubvARB __rglgen_glVertexAttrib4ubvARB #define glVertexAttrib4uivARB __rglgen_glVertexAttrib4uivARB #define glVertexAttrib4usvARB __rglgen_glVertexAttrib4usvARB #define glVertexAttribPointerARB __rglgen_glVertexAttribPointerARB #define glEnableVertexAttribArrayARB __rglgen_glEnableVertexAttribArrayARB #define glDisableVertexAttribArrayARB __rglgen_glDisableVertexAttribArrayARB #define glGetVertexAttribdvARB __rglgen_glGetVertexAttribdvARB #define glGetVertexAttribfvARB __rglgen_glGetVertexAttribfvARB #define glGetVertexAttribivARB __rglgen_glGetVertexAttribivARB #define glGetVertexAttribPointervARB __rglgen_glGetVertexAttribPointervARB #define glBindAttribLocationARB __rglgen_glBindAttribLocationARB #define glGetActiveAttribARB __rglgen_glGetActiveAttribARB #define glGetAttribLocationARB __rglgen_glGetAttribLocationARB #define glWindowPos2dARB __rglgen_glWindowPos2dARB #define glWindowPos2dvARB __rglgen_glWindowPos2dvARB #define glWindowPos2fARB __rglgen_glWindowPos2fARB #define glWindowPos2fvARB __rglgen_glWindowPos2fvARB #define glWindowPos2iARB __rglgen_glWindowPos2iARB #define glWindowPos2ivARB __rglgen_glWindowPos2ivARB #define glWindowPos2sARB __rglgen_glWindowPos2sARB #define glWindowPos2svARB __rglgen_glWindowPos2svARB #define glWindowPos3dARB __rglgen_glWindowPos3dARB #define glWindowPos3dvARB __rglgen_glWindowPos3dvARB #define glWindowPos3fARB __rglgen_glWindowPos3fARB #define glWindowPos3fvARB __rglgen_glWindowPos3fvARB #define glWindowPos3iARB __rglgen_glWindowPos3iARB #define glWindowPos3ivARB __rglgen_glWindowPos3ivARB #define glWindowPos3sARB __rglgen_glWindowPos3sARB #define glWindowPos3svARB __rglgen_glWindowPos3svARB #define glMultiTexCoord1bOES __rglgen_glMultiTexCoord1bOES #define glMultiTexCoord1bvOES __rglgen_glMultiTexCoord1bvOES #define glMultiTexCoord2bOES __rglgen_glMultiTexCoord2bOES #define glMultiTexCoord2bvOES __rglgen_glMultiTexCoord2bvOES #define glMultiTexCoord3bOES __rglgen_glMultiTexCoord3bOES #define glMultiTexCoord3bvOES __rglgen_glMultiTexCoord3bvOES #define glMultiTexCoord4bOES __rglgen_glMultiTexCoord4bOES #define glMultiTexCoord4bvOES __rglgen_glMultiTexCoord4bvOES #define glTexCoord1bOES __rglgen_glTexCoord1bOES #define glTexCoord1bvOES __rglgen_glTexCoord1bvOES #define glTexCoord2bOES __rglgen_glTexCoord2bOES #define glTexCoord2bvOES __rglgen_glTexCoord2bvOES #define glTexCoord3bOES __rglgen_glTexCoord3bOES #define glTexCoord3bvOES __rglgen_glTexCoord3bvOES #define glTexCoord4bOES __rglgen_glTexCoord4bOES #define glTexCoord4bvOES __rglgen_glTexCoord4bvOES #define glVertex2bOES __rglgen_glVertex2bOES #define glVertex2bvOES __rglgen_glVertex2bvOES #define glVertex3bOES __rglgen_glVertex3bOES #define glVertex3bvOES __rglgen_glVertex3bvOES #define glVertex4bOES __rglgen_glVertex4bOES #define glVertex4bvOES __rglgen_glVertex4bvOES #define glAlphaFuncxOES __rglgen_glAlphaFuncxOES #define glClearColorxOES __rglgen_glClearColorxOES #define glClearDepthxOES __rglgen_glClearDepthxOES #define glClipPlanexOES __rglgen_glClipPlanexOES #define glColor4xOES __rglgen_glColor4xOES #define glDepthRangexOES __rglgen_glDepthRangexOES #define glFogxOES __rglgen_glFogxOES #define glFogxvOES __rglgen_glFogxvOES #define glFrustumxOES __rglgen_glFrustumxOES #define glGetClipPlanexOES __rglgen_glGetClipPlanexOES #define glGetFixedvOES __rglgen_glGetFixedvOES #define glGetTexEnvxvOES __rglgen_glGetTexEnvxvOES #define glGetTexParameterxvOES __rglgen_glGetTexParameterxvOES #define glLightModelxOES __rglgen_glLightModelxOES #define glLightModelxvOES __rglgen_glLightModelxvOES #define glLightxOES __rglgen_glLightxOES #define glLightxvOES __rglgen_glLightxvOES #define glLineWidthxOES __rglgen_glLineWidthxOES #define glLoadMatrixxOES __rglgen_glLoadMatrixxOES #define glMaterialxOES __rglgen_glMaterialxOES #define glMaterialxvOES __rglgen_glMaterialxvOES #define glMultMatrixxOES __rglgen_glMultMatrixxOES #define glMultiTexCoord4xOES __rglgen_glMultiTexCoord4xOES #define glNormal3xOES __rglgen_glNormal3xOES #define glOrthoxOES __rglgen_glOrthoxOES #define glPointParameterxvOES __rglgen_glPointParameterxvOES #define glPointSizexOES __rglgen_glPointSizexOES #define glPolygonOffsetxOES __rglgen_glPolygonOffsetxOES #define glRotatexOES __rglgen_glRotatexOES #define glSampleCoverageOES __rglgen_glSampleCoverageOES #define glScalexOES __rglgen_glScalexOES #define glTexEnvxOES __rglgen_glTexEnvxOES #define glTexEnvxvOES __rglgen_glTexEnvxvOES #define glTexParameterxOES __rglgen_glTexParameterxOES #define glTexParameterxvOES __rglgen_glTexParameterxvOES #define glTranslatexOES __rglgen_glTranslatexOES #define glAccumxOES __rglgen_glAccumxOES #define glBitmapxOES __rglgen_glBitmapxOES #define glBlendColorxOES __rglgen_glBlendColorxOES #define glClearAccumxOES __rglgen_glClearAccumxOES #define glColor3xOES __rglgen_glColor3xOES #define glColor3xvOES __rglgen_glColor3xvOES #define glColor4xvOES __rglgen_glColor4xvOES #define glConvolutionParameterxOES __rglgen_glConvolutionParameterxOES #define glConvolutionParameterxvOES __rglgen_glConvolutionParameterxvOES #define glEvalCoord1xOES __rglgen_glEvalCoord1xOES #define glEvalCoord1xvOES __rglgen_glEvalCoord1xvOES #define glEvalCoord2xOES __rglgen_glEvalCoord2xOES #define glEvalCoord2xvOES __rglgen_glEvalCoord2xvOES #define glFeedbackBufferxOES __rglgen_glFeedbackBufferxOES #define glGetConvolutionParameterxvOES __rglgen_glGetConvolutionParameterxvOES #define glGetHistogramParameterxvOES __rglgen_glGetHistogramParameterxvOES #define glGetLightxOES __rglgen_glGetLightxOES #define glGetMapxvOES __rglgen_glGetMapxvOES #define glGetMaterialxOES __rglgen_glGetMaterialxOES #define glGetPixelMapxv __rglgen_glGetPixelMapxv #define glGetTexGenxvOES __rglgen_glGetTexGenxvOES #define glGetTexLevelParameterxvOES __rglgen_glGetTexLevelParameterxvOES #define glIndexxOES __rglgen_glIndexxOES #define glIndexxvOES __rglgen_glIndexxvOES #define glLoadTransposeMatrixxOES __rglgen_glLoadTransposeMatrixxOES #define glMap1xOES __rglgen_glMap1xOES #define glMap2xOES __rglgen_glMap2xOES #define glMapGrid1xOES __rglgen_glMapGrid1xOES #define glMapGrid2xOES __rglgen_glMapGrid2xOES #define glMultTransposeMatrixxOES __rglgen_glMultTransposeMatrixxOES #define glMultiTexCoord1xOES __rglgen_glMultiTexCoord1xOES #define glMultiTexCoord1xvOES __rglgen_glMultiTexCoord1xvOES #define glMultiTexCoord2xOES __rglgen_glMultiTexCoord2xOES #define glMultiTexCoord2xvOES __rglgen_glMultiTexCoord2xvOES #define glMultiTexCoord3xOES __rglgen_glMultiTexCoord3xOES #define glMultiTexCoord3xvOES __rglgen_glMultiTexCoord3xvOES #define glMultiTexCoord4xvOES __rglgen_glMultiTexCoord4xvOES #define glNormal3xvOES __rglgen_glNormal3xvOES #define glPassThroughxOES __rglgen_glPassThroughxOES #define glPixelMapx __rglgen_glPixelMapx #define glPixelStorex __rglgen_glPixelStorex #define glPixelTransferxOES __rglgen_glPixelTransferxOES #define glPixelZoomxOES __rglgen_glPixelZoomxOES #define glPrioritizeTexturesxOES __rglgen_glPrioritizeTexturesxOES #define glRasterPos2xOES __rglgen_glRasterPos2xOES #define glRasterPos2xvOES __rglgen_glRasterPos2xvOES #define glRasterPos3xOES __rglgen_glRasterPos3xOES #define glRasterPos3xvOES __rglgen_glRasterPos3xvOES #define glRasterPos4xOES __rglgen_glRasterPos4xOES #define glRasterPos4xvOES __rglgen_glRasterPos4xvOES #define glRectxOES __rglgen_glRectxOES #define glRectxvOES __rglgen_glRectxvOES #define glTexCoord1xOES __rglgen_glTexCoord1xOES #define glTexCoord1xvOES __rglgen_glTexCoord1xvOES #define glTexCoord2xOES __rglgen_glTexCoord2xOES #define glTexCoord2xvOES __rglgen_glTexCoord2xvOES #define glTexCoord3xOES __rglgen_glTexCoord3xOES #define glTexCoord3xvOES __rglgen_glTexCoord3xvOES #define glTexCoord4xOES __rglgen_glTexCoord4xOES #define glTexCoord4xvOES __rglgen_glTexCoord4xvOES #define glTexGenxOES __rglgen_glTexGenxOES #define glTexGenxvOES __rglgen_glTexGenxvOES #define glVertex2xOES __rglgen_glVertex2xOES #define glVertex2xvOES __rglgen_glVertex2xvOES #define glVertex3xOES __rglgen_glVertex3xOES #define glVertex3xvOES __rglgen_glVertex3xvOES #define glVertex4xOES __rglgen_glVertex4xOES #define glVertex4xvOES __rglgen_glVertex4xvOES #define glQueryMatrixxOES __rglgen_glQueryMatrixxOES #define glClearDepthfOES __rglgen_glClearDepthfOES #define glClipPlanefOES __rglgen_glClipPlanefOES #define glDepthRangefOES __rglgen_glDepthRangefOES #define glFrustumfOES __rglgen_glFrustumfOES #define glGetClipPlanefOES __rglgen_glGetClipPlanefOES #define glOrthofOES __rglgen_glOrthofOES #define glImageTransformParameteriHP __rglgen_glImageTransformParameteriHP #define glImageTransformParameterfHP __rglgen_glImageTransformParameterfHP #define glImageTransformParameterivHP __rglgen_glImageTransformParameterivHP #define glImageTransformParameterfvHP __rglgen_glImageTransformParameterfvHP #define glGetImageTransformParameterivHP __rglgen_glGetImageTransformParameterivHP #define glGetImageTransformParameterfvHP __rglgen_glGetImageTransformParameterfvHP extern RGLSYMGLDRAWRANGEELEMENTSPROC __rglgen_glDrawRangeElements; extern RGLSYMGLTEXIMAGE3DPROC __rglgen_glTexImage3D; extern RGLSYMGLTEXSUBIMAGE3DPROC __rglgen_glTexSubImage3D; extern RGLSYMGLCOPYTEXSUBIMAGE3DPROC __rglgen_glCopyTexSubImage3D; extern RGLSYMGLACTIVETEXTUREPROC __rglgen_glActiveTexture; extern RGLSYMGLSAMPLECOVERAGEPROC __rglgen_glSampleCoverage; extern RGLSYMGLCOMPRESSEDTEXIMAGE3DPROC __rglgen_glCompressedTexImage3D; extern RGLSYMGLCOMPRESSEDTEXIMAGE2DPROC __rglgen_glCompressedTexImage2D; extern RGLSYMGLCOMPRESSEDTEXIMAGE1DPROC __rglgen_glCompressedTexImage1D; extern RGLSYMGLCOMPRESSEDTEXSUBIMAGE3DPROC __rglgen_glCompressedTexSubImage3D; extern RGLSYMGLCOMPRESSEDTEXSUBIMAGE2DPROC __rglgen_glCompressedTexSubImage2D; extern RGLSYMGLCOMPRESSEDTEXSUBIMAGE1DPROC __rglgen_glCompressedTexSubImage1D; extern RGLSYMGLGETCOMPRESSEDTEXIMAGEPROC __rglgen_glGetCompressedTexImage; extern RGLSYMGLCLIENTACTIVETEXTUREPROC __rglgen_glClientActiveTexture; extern RGLSYMGLMULTITEXCOORD1DPROC __rglgen_glMultiTexCoord1d; extern RGLSYMGLMULTITEXCOORD1DVPROC __rglgen_glMultiTexCoord1dv; extern RGLSYMGLMULTITEXCOORD1FPROC __rglgen_glMultiTexCoord1f; extern RGLSYMGLMULTITEXCOORD1FVPROC __rglgen_glMultiTexCoord1fv; extern RGLSYMGLMULTITEXCOORD1IPROC __rglgen_glMultiTexCoord1i; extern RGLSYMGLMULTITEXCOORD1IVPROC __rglgen_glMultiTexCoord1iv; extern RGLSYMGLMULTITEXCOORD1SPROC __rglgen_glMultiTexCoord1s; extern RGLSYMGLMULTITEXCOORD1SVPROC __rglgen_glMultiTexCoord1sv; extern RGLSYMGLMULTITEXCOORD2DPROC __rglgen_glMultiTexCoord2d; extern RGLSYMGLMULTITEXCOORD2DVPROC __rglgen_glMultiTexCoord2dv; extern RGLSYMGLMULTITEXCOORD2FPROC __rglgen_glMultiTexCoord2f; extern RGLSYMGLMULTITEXCOORD2FVPROC __rglgen_glMultiTexCoord2fv; extern RGLSYMGLMULTITEXCOORD2IPROC __rglgen_glMultiTexCoord2i; extern RGLSYMGLMULTITEXCOORD2IVPROC __rglgen_glMultiTexCoord2iv; extern RGLSYMGLMULTITEXCOORD2SPROC __rglgen_glMultiTexCoord2s; extern RGLSYMGLMULTITEXCOORD2SVPROC __rglgen_glMultiTexCoord2sv; extern RGLSYMGLMULTITEXCOORD3DPROC __rglgen_glMultiTexCoord3d; extern RGLSYMGLMULTITEXCOORD3DVPROC __rglgen_glMultiTexCoord3dv; extern RGLSYMGLMULTITEXCOORD3FPROC __rglgen_glMultiTexCoord3f; extern RGLSYMGLMULTITEXCOORD3FVPROC __rglgen_glMultiTexCoord3fv; extern RGLSYMGLMULTITEXCOORD3IPROC __rglgen_glMultiTexCoord3i; extern RGLSYMGLMULTITEXCOORD3IVPROC __rglgen_glMultiTexCoord3iv; extern RGLSYMGLMULTITEXCOORD3SPROC __rglgen_glMultiTexCoord3s; extern RGLSYMGLMULTITEXCOORD3SVPROC __rglgen_glMultiTexCoord3sv; extern RGLSYMGLMULTITEXCOORD4DPROC __rglgen_glMultiTexCoord4d; extern RGLSYMGLMULTITEXCOORD4DVPROC __rglgen_glMultiTexCoord4dv; extern RGLSYMGLMULTITEXCOORD4FPROC __rglgen_glMultiTexCoord4f; extern RGLSYMGLMULTITEXCOORD4FVPROC __rglgen_glMultiTexCoord4fv; extern RGLSYMGLMULTITEXCOORD4IPROC __rglgen_glMultiTexCoord4i; extern RGLSYMGLMULTITEXCOORD4IVPROC __rglgen_glMultiTexCoord4iv; extern RGLSYMGLMULTITEXCOORD4SPROC __rglgen_glMultiTexCoord4s; extern RGLSYMGLMULTITEXCOORD4SVPROC __rglgen_glMultiTexCoord4sv; extern RGLSYMGLLOADTRANSPOSEMATRIXFPROC __rglgen_glLoadTransposeMatrixf; extern RGLSYMGLLOADTRANSPOSEMATRIXDPROC __rglgen_glLoadTransposeMatrixd; extern RGLSYMGLMULTTRANSPOSEMATRIXFPROC __rglgen_glMultTransposeMatrixf; extern RGLSYMGLMULTTRANSPOSEMATRIXDPROC __rglgen_glMultTransposeMatrixd; extern RGLSYMGLBLENDFUNCSEPARATEPROC __rglgen_glBlendFuncSeparate; extern RGLSYMGLMULTIDRAWARRAYSPROC __rglgen_glMultiDrawArrays; extern RGLSYMGLMULTIDRAWELEMENTSPROC __rglgen_glMultiDrawElements; extern RGLSYMGLPOINTPARAMETERFPROC __rglgen_glPointParameterf; extern RGLSYMGLPOINTPARAMETERFVPROC __rglgen_glPointParameterfv; extern RGLSYMGLPOINTPARAMETERIPROC __rglgen_glPointParameteri; extern RGLSYMGLPOINTPARAMETERIVPROC __rglgen_glPointParameteriv; extern RGLSYMGLFOGCOORDFPROC __rglgen_glFogCoordf; extern RGLSYMGLFOGCOORDFVPROC __rglgen_glFogCoordfv; extern RGLSYMGLFOGCOORDDPROC __rglgen_glFogCoordd; extern RGLSYMGLFOGCOORDDVPROC __rglgen_glFogCoorddv; extern RGLSYMGLFOGCOORDPOINTERPROC __rglgen_glFogCoordPointer; extern RGLSYMGLSECONDARYCOLOR3BPROC __rglgen_glSecondaryColor3b; extern RGLSYMGLSECONDARYCOLOR3BVPROC __rglgen_glSecondaryColor3bv; extern RGLSYMGLSECONDARYCOLOR3DPROC __rglgen_glSecondaryColor3d; extern RGLSYMGLSECONDARYCOLOR3DVPROC __rglgen_glSecondaryColor3dv; extern RGLSYMGLSECONDARYCOLOR3FPROC __rglgen_glSecondaryColor3f; extern RGLSYMGLSECONDARYCOLOR3FVPROC __rglgen_glSecondaryColor3fv; extern RGLSYMGLSECONDARYCOLOR3IPROC __rglgen_glSecondaryColor3i; extern RGLSYMGLSECONDARYCOLOR3IVPROC __rglgen_glSecondaryColor3iv; extern RGLSYMGLSECONDARYCOLOR3SPROC __rglgen_glSecondaryColor3s; extern RGLSYMGLSECONDARYCOLOR3SVPROC __rglgen_glSecondaryColor3sv; extern RGLSYMGLSECONDARYCOLOR3UBPROC __rglgen_glSecondaryColor3ub; extern RGLSYMGLSECONDARYCOLOR3UBVPROC __rglgen_glSecondaryColor3ubv; extern RGLSYMGLSECONDARYCOLOR3UIPROC __rglgen_glSecondaryColor3ui; extern RGLSYMGLSECONDARYCOLOR3UIVPROC __rglgen_glSecondaryColor3uiv; extern RGLSYMGLSECONDARYCOLOR3USPROC __rglgen_glSecondaryColor3us; extern RGLSYMGLSECONDARYCOLOR3USVPROC __rglgen_glSecondaryColor3usv; extern RGLSYMGLSECONDARYCOLORPOINTERPROC __rglgen_glSecondaryColorPointer; extern RGLSYMGLWINDOWPOS2DPROC __rglgen_glWindowPos2d; extern RGLSYMGLWINDOWPOS2DVPROC __rglgen_glWindowPos2dv; extern RGLSYMGLWINDOWPOS2FPROC __rglgen_glWindowPos2f; extern RGLSYMGLWINDOWPOS2FVPROC __rglgen_glWindowPos2fv; extern RGLSYMGLWINDOWPOS2IPROC __rglgen_glWindowPos2i; extern RGLSYMGLWINDOWPOS2IVPROC __rglgen_glWindowPos2iv; extern RGLSYMGLWINDOWPOS2SPROC __rglgen_glWindowPos2s; extern RGLSYMGLWINDOWPOS2SVPROC __rglgen_glWindowPos2sv; extern RGLSYMGLWINDOWPOS3DPROC __rglgen_glWindowPos3d; extern RGLSYMGLWINDOWPOS3DVPROC __rglgen_glWindowPos3dv; extern RGLSYMGLWINDOWPOS3FPROC __rglgen_glWindowPos3f; extern RGLSYMGLWINDOWPOS3FVPROC __rglgen_glWindowPos3fv; extern RGLSYMGLWINDOWPOS3IPROC __rglgen_glWindowPos3i; extern RGLSYMGLWINDOWPOS3IVPROC __rglgen_glWindowPos3iv; extern RGLSYMGLWINDOWPOS3SPROC __rglgen_glWindowPos3s; extern RGLSYMGLWINDOWPOS3SVPROC __rglgen_glWindowPos3sv; extern RGLSYMGLBLENDCOLORPROC __rglgen_glBlendColor; extern RGLSYMGLBLENDEQUATIONPROC __rglgen_glBlendEquation; extern RGLSYMGLGENQUERIESPROC __rglgen_glGenQueries; extern RGLSYMGLDELETEQUERIESPROC __rglgen_glDeleteQueries; extern RGLSYMGLISQUERYPROC __rglgen_glIsQuery; extern RGLSYMGLBEGINQUERYPROC __rglgen_glBeginQuery; extern RGLSYMGLENDQUERYPROC __rglgen_glEndQuery; extern RGLSYMGLGETQUERYIVPROC __rglgen_glGetQueryiv; extern RGLSYMGLGETQUERYOBJECTIVPROC __rglgen_glGetQueryObjectiv; extern RGLSYMGLGETQUERYOBJECTUIVPROC __rglgen_glGetQueryObjectuiv; extern RGLSYMGLBINDBUFFERPROC __rglgen_glBindBuffer; extern RGLSYMGLDELETEBUFFERSPROC __rglgen_glDeleteBuffers; extern RGLSYMGLGENBUFFERSPROC __rglgen_glGenBuffers; extern RGLSYMGLISBUFFERPROC __rglgen_glIsBuffer; extern RGLSYMGLBUFFERDATAPROC __rglgen_glBufferData; extern RGLSYMGLBUFFERSUBDATAPROC __rglgen_glBufferSubData; extern RGLSYMGLGETBUFFERSUBDATAPROC __rglgen_glGetBufferSubData; extern RGLSYMGLMAPBUFFERPROC __rglgen_glMapBuffer; extern RGLSYMGLUNMAPBUFFERPROC __rglgen_glUnmapBuffer; extern RGLSYMGLGETBUFFERPARAMETERIVPROC __rglgen_glGetBufferParameteriv; extern RGLSYMGLGETBUFFERPOINTERVPROC __rglgen_glGetBufferPointerv; extern RGLSYMGLBLENDEQUATIONSEPARATEPROC __rglgen_glBlendEquationSeparate; extern RGLSYMGLDRAWBUFFERSPROC __rglgen_glDrawBuffers; extern RGLSYMGLSTENCILOPSEPARATEPROC __rglgen_glStencilOpSeparate; extern RGLSYMGLSTENCILFUNCSEPARATEPROC __rglgen_glStencilFuncSeparate; extern RGLSYMGLSTENCILMASKSEPARATEPROC __rglgen_glStencilMaskSeparate; extern RGLSYMGLATTACHSHADERPROC __rglgen_glAttachShader; extern RGLSYMGLBINDATTRIBLOCATIONPROC __rglgen_glBindAttribLocation; extern RGLSYMGLCOMPILESHADERPROC __rglgen_glCompileShader; extern RGLSYMGLCREATEPROGRAMPROC __rglgen_glCreateProgram; extern RGLSYMGLCREATESHADERPROC __rglgen_glCreateShader; extern RGLSYMGLDELETEPROGRAMPROC __rglgen_glDeleteProgram; extern RGLSYMGLDELETESHADERPROC __rglgen_glDeleteShader; extern RGLSYMGLDETACHSHADERPROC __rglgen_glDetachShader; extern RGLSYMGLDISABLEVERTEXATTRIBARRAYPROC __rglgen_glDisableVertexAttribArray; extern RGLSYMGLENABLEVERTEXATTRIBARRAYPROC __rglgen_glEnableVertexAttribArray; extern RGLSYMGLGETACTIVEATTRIBPROC __rglgen_glGetActiveAttrib; extern RGLSYMGLGETACTIVEUNIFORMPROC __rglgen_glGetActiveUniform; extern RGLSYMGLGETATTACHEDSHADERSPROC __rglgen_glGetAttachedShaders; extern RGLSYMGLGETATTRIBLOCATIONPROC __rglgen_glGetAttribLocation; extern RGLSYMGLGETPROGRAMIVPROC __rglgen_glGetProgramiv; extern RGLSYMGLGETPROGRAMINFOLOGPROC __rglgen_glGetProgramInfoLog; extern RGLSYMGLGETSHADERIVPROC __rglgen_glGetShaderiv; extern RGLSYMGLGETSHADERINFOLOGPROC __rglgen_glGetShaderInfoLog; extern RGLSYMGLGETSHADERSOURCEPROC __rglgen_glGetShaderSource; extern RGLSYMGLGETUNIFORMLOCATIONPROC __rglgen_glGetUniformLocation; extern RGLSYMGLGETUNIFORMFVPROC __rglgen_glGetUniformfv; extern RGLSYMGLGETUNIFORMIVPROC __rglgen_glGetUniformiv; extern RGLSYMGLGETVERTEXATTRIBDVPROC __rglgen_glGetVertexAttribdv; extern RGLSYMGLGETVERTEXATTRIBFVPROC __rglgen_glGetVertexAttribfv; extern RGLSYMGLGETVERTEXATTRIBIVPROC __rglgen_glGetVertexAttribiv; extern RGLSYMGLGETVERTEXATTRIBPOINTERVPROC __rglgen_glGetVertexAttribPointerv; extern RGLSYMGLISPROGRAMPROC __rglgen_glIsProgram; extern RGLSYMGLISSHADERPROC __rglgen_glIsShader; extern RGLSYMGLLINKPROGRAMPROC __rglgen_glLinkProgram; extern RGLSYMGLSHADERSOURCEPROC __rglgen_glShaderSource; extern RGLSYMGLUSEPROGRAMPROC __rglgen_glUseProgram; extern RGLSYMGLUNIFORM1FPROC __rglgen_glUniform1f; extern RGLSYMGLUNIFORM2FPROC __rglgen_glUniform2f; extern RGLSYMGLUNIFORM3FPROC __rglgen_glUniform3f; extern RGLSYMGLUNIFORM4FPROC __rglgen_glUniform4f; extern RGLSYMGLUNIFORM1IPROC __rglgen_glUniform1i; extern RGLSYMGLUNIFORM2IPROC __rglgen_glUniform2i; extern RGLSYMGLUNIFORM3IPROC __rglgen_glUniform3i; extern RGLSYMGLUNIFORM4IPROC __rglgen_glUniform4i; extern RGLSYMGLUNIFORM1FVPROC __rglgen_glUniform1fv; extern RGLSYMGLUNIFORM2FVPROC __rglgen_glUniform2fv; extern RGLSYMGLUNIFORM3FVPROC __rglgen_glUniform3fv; extern RGLSYMGLUNIFORM4FVPROC __rglgen_glUniform4fv; extern RGLSYMGLUNIFORM1IVPROC __rglgen_glUniform1iv; extern RGLSYMGLUNIFORM2IVPROC __rglgen_glUniform2iv; extern RGLSYMGLUNIFORM3IVPROC __rglgen_glUniform3iv; extern RGLSYMGLUNIFORM4IVPROC __rglgen_glUniform4iv; extern RGLSYMGLUNIFORMMATRIX2FVPROC __rglgen_glUniformMatrix2fv; extern RGLSYMGLUNIFORMMATRIX3FVPROC __rglgen_glUniformMatrix3fv; extern RGLSYMGLUNIFORMMATRIX4FVPROC __rglgen_glUniformMatrix4fv; extern RGLSYMGLVALIDATEPROGRAMPROC __rglgen_glValidateProgram; extern RGLSYMGLVERTEXATTRIB1DPROC __rglgen_glVertexAttrib1d; extern RGLSYMGLVERTEXATTRIB1DVPROC __rglgen_glVertexAttrib1dv; extern RGLSYMGLVERTEXATTRIB1FPROC __rglgen_glVertexAttrib1f; extern RGLSYMGLVERTEXATTRIB1FVPROC __rglgen_glVertexAttrib1fv; extern RGLSYMGLVERTEXATTRIB1SPROC __rglgen_glVertexAttrib1s; extern RGLSYMGLVERTEXATTRIB1SVPROC __rglgen_glVertexAttrib1sv; extern RGLSYMGLVERTEXATTRIB2DPROC __rglgen_glVertexAttrib2d; extern RGLSYMGLVERTEXATTRIB2DVPROC __rglgen_glVertexAttrib2dv; extern RGLSYMGLVERTEXATTRIB2FPROC __rglgen_glVertexAttrib2f; extern RGLSYMGLVERTEXATTRIB2FVPROC __rglgen_glVertexAttrib2fv; extern RGLSYMGLVERTEXATTRIB2SPROC __rglgen_glVertexAttrib2s; extern RGLSYMGLVERTEXATTRIB2SVPROC __rglgen_glVertexAttrib2sv; extern RGLSYMGLVERTEXATTRIB3DPROC __rglgen_glVertexAttrib3d; extern RGLSYMGLVERTEXATTRIB3DVPROC __rglgen_glVertexAttrib3dv; extern RGLSYMGLVERTEXATTRIB3FPROC __rglgen_glVertexAttrib3f; extern RGLSYMGLVERTEXATTRIB3FVPROC __rglgen_glVertexAttrib3fv; extern RGLSYMGLVERTEXATTRIB3SPROC __rglgen_glVertexAttrib3s; extern RGLSYMGLVERTEXATTRIB3SVPROC __rglgen_glVertexAttrib3sv; extern RGLSYMGLVERTEXATTRIB4NBVPROC __rglgen_glVertexAttrib4Nbv; extern RGLSYMGLVERTEXATTRIB4NIVPROC __rglgen_glVertexAttrib4Niv; extern RGLSYMGLVERTEXATTRIB4NSVPROC __rglgen_glVertexAttrib4Nsv; extern RGLSYMGLVERTEXATTRIB4NUBPROC __rglgen_glVertexAttrib4Nub; extern RGLSYMGLVERTEXATTRIB4NUBVPROC __rglgen_glVertexAttrib4Nubv; extern RGLSYMGLVERTEXATTRIB4NUIVPROC __rglgen_glVertexAttrib4Nuiv; extern RGLSYMGLVERTEXATTRIB4NUSVPROC __rglgen_glVertexAttrib4Nusv; extern RGLSYMGLVERTEXATTRIB4BVPROC __rglgen_glVertexAttrib4bv; extern RGLSYMGLVERTEXATTRIB4DPROC __rglgen_glVertexAttrib4d; extern RGLSYMGLVERTEXATTRIB4DVPROC __rglgen_glVertexAttrib4dv; extern RGLSYMGLVERTEXATTRIB4FPROC __rglgen_glVertexAttrib4f; extern RGLSYMGLVERTEXATTRIB4FVPROC __rglgen_glVertexAttrib4fv; extern RGLSYMGLVERTEXATTRIB4IVPROC __rglgen_glVertexAttrib4iv; extern RGLSYMGLVERTEXATTRIB4SPROC __rglgen_glVertexAttrib4s; extern RGLSYMGLVERTEXATTRIB4SVPROC __rglgen_glVertexAttrib4sv; extern RGLSYMGLVERTEXATTRIB4UBVPROC __rglgen_glVertexAttrib4ubv; extern RGLSYMGLVERTEXATTRIB4UIVPROC __rglgen_glVertexAttrib4uiv; extern RGLSYMGLVERTEXATTRIB4USVPROC __rglgen_glVertexAttrib4usv; extern RGLSYMGLVERTEXATTRIBPOINTERPROC __rglgen_glVertexAttribPointer; extern RGLSYMGLUNIFORMMATRIX2X3FVPROC __rglgen_glUniformMatrix2x3fv; extern RGLSYMGLUNIFORMMATRIX3X2FVPROC __rglgen_glUniformMatrix3x2fv; extern RGLSYMGLUNIFORMMATRIX2X4FVPROC __rglgen_glUniformMatrix2x4fv; extern RGLSYMGLUNIFORMMATRIX4X2FVPROC __rglgen_glUniformMatrix4x2fv; extern RGLSYMGLUNIFORMMATRIX3X4FVPROC __rglgen_glUniformMatrix3x4fv; extern RGLSYMGLUNIFORMMATRIX4X3FVPROC __rglgen_glUniformMatrix4x3fv; extern RGLSYMGLCOLORMASKIPROC __rglgen_glColorMaski; extern RGLSYMGLGETBOOLEANI_VPROC __rglgen_glGetBooleani_v; extern RGLSYMGLGETINTEGERI_VPROC __rglgen_glGetIntegeri_v; extern RGLSYMGLENABLEIPROC __rglgen_glEnablei; extern RGLSYMGLDISABLEIPROC __rglgen_glDisablei; extern RGLSYMGLISENABLEDIPROC __rglgen_glIsEnabledi; extern RGLSYMGLBEGINTRANSFORMFEEDBACKPROC __rglgen_glBeginTransformFeedback; extern RGLSYMGLENDTRANSFORMFEEDBACKPROC __rglgen_glEndTransformFeedback; extern RGLSYMGLBINDBUFFERRANGEPROC __rglgen_glBindBufferRange; extern RGLSYMGLBINDBUFFERBASEPROC __rglgen_glBindBufferBase; extern RGLSYMGLTRANSFORMFEEDBACKVARYINGSPROC __rglgen_glTransformFeedbackVaryings; extern RGLSYMGLGETTRANSFORMFEEDBACKVARYINGPROC __rglgen_glGetTransformFeedbackVarying; extern RGLSYMGLCLAMPCOLORPROC __rglgen_glClampColor; extern RGLSYMGLBEGINCONDITIONALRENDERPROC __rglgen_glBeginConditionalRender; extern RGLSYMGLENDCONDITIONALRENDERPROC __rglgen_glEndConditionalRender; extern RGLSYMGLVERTEXATTRIBIPOINTERPROC __rglgen_glVertexAttribIPointer; extern RGLSYMGLGETVERTEXATTRIBIIVPROC __rglgen_glGetVertexAttribIiv; extern RGLSYMGLGETVERTEXATTRIBIUIVPROC __rglgen_glGetVertexAttribIuiv; extern RGLSYMGLVERTEXATTRIBI1IPROC __rglgen_glVertexAttribI1i; extern RGLSYMGLVERTEXATTRIBI2IPROC __rglgen_glVertexAttribI2i; extern RGLSYMGLVERTEXATTRIBI3IPROC __rglgen_glVertexAttribI3i; extern RGLSYMGLVERTEXATTRIBI4IPROC __rglgen_glVertexAttribI4i; extern RGLSYMGLVERTEXATTRIBI1UIPROC __rglgen_glVertexAttribI1ui; extern RGLSYMGLVERTEXATTRIBI2UIPROC __rglgen_glVertexAttribI2ui; extern RGLSYMGLVERTEXATTRIBI3UIPROC __rglgen_glVertexAttribI3ui; extern RGLSYMGLVERTEXATTRIBI4UIPROC __rglgen_glVertexAttribI4ui; extern RGLSYMGLVERTEXATTRIBI1IVPROC __rglgen_glVertexAttribI1iv; extern RGLSYMGLVERTEXATTRIBI2IVPROC __rglgen_glVertexAttribI2iv; extern RGLSYMGLVERTEXATTRIBI3IVPROC __rglgen_glVertexAttribI3iv; extern RGLSYMGLVERTEXATTRIBI4IVPROC __rglgen_glVertexAttribI4iv; extern RGLSYMGLVERTEXATTRIBI1UIVPROC __rglgen_glVertexAttribI1uiv; extern RGLSYMGLVERTEXATTRIBI2UIVPROC __rglgen_glVertexAttribI2uiv; extern RGLSYMGLVERTEXATTRIBI3UIVPROC __rglgen_glVertexAttribI3uiv; extern RGLSYMGLVERTEXATTRIBI4UIVPROC __rglgen_glVertexAttribI4uiv; extern RGLSYMGLVERTEXATTRIBI4BVPROC __rglgen_glVertexAttribI4bv; extern RGLSYMGLVERTEXATTRIBI4SVPROC __rglgen_glVertexAttribI4sv; extern RGLSYMGLVERTEXATTRIBI4UBVPROC __rglgen_glVertexAttribI4ubv; extern RGLSYMGLVERTEXATTRIBI4USVPROC __rglgen_glVertexAttribI4usv; extern RGLSYMGLGETUNIFORMUIVPROC __rglgen_glGetUniformuiv; extern RGLSYMGLBINDFRAGDATALOCATIONPROC __rglgen_glBindFragDataLocation; extern RGLSYMGLGETFRAGDATALOCATIONPROC __rglgen_glGetFragDataLocation; extern RGLSYMGLUNIFORM1UIPROC __rglgen_glUniform1ui; extern RGLSYMGLUNIFORM2UIPROC __rglgen_glUniform2ui; extern RGLSYMGLUNIFORM3UIPROC __rglgen_glUniform3ui; extern RGLSYMGLUNIFORM4UIPROC __rglgen_glUniform4ui; extern RGLSYMGLUNIFORM1UIVPROC __rglgen_glUniform1uiv; extern RGLSYMGLUNIFORM2UIVPROC __rglgen_glUniform2uiv; extern RGLSYMGLUNIFORM3UIVPROC __rglgen_glUniform3uiv; extern RGLSYMGLUNIFORM4UIVPROC __rglgen_glUniform4uiv; extern RGLSYMGLTEXPARAMETERIIVPROC __rglgen_glTexParameterIiv; extern RGLSYMGLTEXPARAMETERIUIVPROC __rglgen_glTexParameterIuiv; extern RGLSYMGLGETTEXPARAMETERIIVPROC __rglgen_glGetTexParameterIiv; extern RGLSYMGLGETTEXPARAMETERIUIVPROC __rglgen_glGetTexParameterIuiv; extern RGLSYMGLCLEARBUFFERIVPROC __rglgen_glClearBufferiv; extern RGLSYMGLCLEARBUFFERUIVPROC __rglgen_glClearBufferuiv; extern RGLSYMGLCLEARBUFFERFVPROC __rglgen_glClearBufferfv; extern RGLSYMGLCLEARBUFFERFIPROC __rglgen_glClearBufferfi; extern RGLSYMGLGETSTRINGIPROC __rglgen_glGetStringi; extern RGLSYMGLISRENDERBUFFERPROC __rglgen_glIsRenderbuffer; extern RGLSYMGLBINDRENDERBUFFERPROC __rglgen_glBindRenderbuffer; extern RGLSYMGLDELETERENDERBUFFERSPROC __rglgen_glDeleteRenderbuffers; extern RGLSYMGLGENRENDERBUFFERSPROC __rglgen_glGenRenderbuffers; extern RGLSYMGLRENDERBUFFERSTORAGEPROC __rglgen_glRenderbufferStorage; extern RGLSYMGLGETRENDERBUFFERPARAMETERIVPROC __rglgen_glGetRenderbufferParameteriv; extern RGLSYMGLISFRAMEBUFFERPROC __rglgen_glIsFramebuffer; extern RGLSYMGLBINDFRAMEBUFFERPROC __rglgen_glBindFramebuffer; extern RGLSYMGLDELETEFRAMEBUFFERSPROC __rglgen_glDeleteFramebuffers; extern RGLSYMGLGENFRAMEBUFFERSPROC __rglgen_glGenFramebuffers; extern RGLSYMGLCHECKFRAMEBUFFERSTATUSPROC __rglgen_glCheckFramebufferStatus; extern RGLSYMGLFRAMEBUFFERTEXTURE1DPROC __rglgen_glFramebufferTexture1D; extern RGLSYMGLFRAMEBUFFERTEXTURE2DPROC __rglgen_glFramebufferTexture2D; extern RGLSYMGLFRAMEBUFFERTEXTURE3DPROC __rglgen_glFramebufferTexture3D; extern RGLSYMGLFRAMEBUFFERRENDERBUFFERPROC __rglgen_glFramebufferRenderbuffer; extern RGLSYMGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC __rglgen_glGetFramebufferAttachmentParameteriv; extern RGLSYMGLGENERATEMIPMAPPROC __rglgen_glGenerateMipmap; extern RGLSYMGLBLITFRAMEBUFFERPROC __rglgen_glBlitFramebuffer; extern RGLSYMGLRENDERBUFFERSTORAGEMULTISAMPLEPROC __rglgen_glRenderbufferStorageMultisample; extern RGLSYMGLFRAMEBUFFERTEXTURELAYERPROC __rglgen_glFramebufferTextureLayer; extern RGLSYMGLMAPBUFFERRANGEPROC __rglgen_glMapBufferRange; extern RGLSYMGLFLUSHMAPPEDBUFFERRANGEPROC __rglgen_glFlushMappedBufferRange; extern RGLSYMGLBINDVERTEXARRAYPROC __rglgen_glBindVertexArray; extern RGLSYMGLDELETEVERTEXARRAYSPROC __rglgen_glDeleteVertexArrays; extern RGLSYMGLGENVERTEXARRAYSPROC __rglgen_glGenVertexArrays; extern RGLSYMGLISVERTEXARRAYPROC __rglgen_glIsVertexArray; extern RGLSYMGLDRAWARRAYSINSTANCEDPROC __rglgen_glDrawArraysInstanced; extern RGLSYMGLDRAWELEMENTSINSTANCEDPROC __rglgen_glDrawElementsInstanced; extern RGLSYMGLTEXBUFFERPROC __rglgen_glTexBuffer; extern RGLSYMGLPRIMITIVERESTARTINDEXPROC __rglgen_glPrimitiveRestartIndex; extern RGLSYMGLCOPYBUFFERSUBDATAPROC __rglgen_glCopyBufferSubData; extern RGLSYMGLGETUNIFORMINDICESPROC __rglgen_glGetUniformIndices; extern RGLSYMGLGETACTIVEUNIFORMSIVPROC __rglgen_glGetActiveUniformsiv; extern RGLSYMGLGETACTIVEUNIFORMNAMEPROC __rglgen_glGetActiveUniformName; extern RGLSYMGLGETUNIFORMBLOCKINDEXPROC __rglgen_glGetUniformBlockIndex; extern RGLSYMGLGETACTIVEUNIFORMBLOCKIVPROC __rglgen_glGetActiveUniformBlockiv; extern RGLSYMGLGETACTIVEUNIFORMBLOCKNAMEPROC __rglgen_glGetActiveUniformBlockName; extern RGLSYMGLUNIFORMBLOCKBINDINGPROC __rglgen_glUniformBlockBinding; extern RGLSYMGLDRAWELEMENTSBASEVERTEXPROC __rglgen_glDrawElementsBaseVertex; extern RGLSYMGLDRAWRANGEELEMENTSBASEVERTEXPROC __rglgen_glDrawRangeElementsBaseVertex; extern RGLSYMGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC __rglgen_glDrawElementsInstancedBaseVertex; extern RGLSYMGLMULTIDRAWELEMENTSBASEVERTEXPROC __rglgen_glMultiDrawElementsBaseVertex; extern RGLSYMGLPROVOKINGVERTEXPROC __rglgen_glProvokingVertex; extern RGLSYMGLFENCESYNCPROC __rglgen_glFenceSync; extern RGLSYMGLISSYNCPROC __rglgen_glIsSync; extern RGLSYMGLDELETESYNCPROC __rglgen_glDeleteSync; extern RGLSYMGLCLIENTWAITSYNCPROC __rglgen_glClientWaitSync; extern RGLSYMGLWAITSYNCPROC __rglgen_glWaitSync; extern RGLSYMGLGETINTEGER64VPROC __rglgen_glGetInteger64v; extern RGLSYMGLGETSYNCIVPROC __rglgen_glGetSynciv; extern RGLSYMGLGETINTEGER64I_VPROC __rglgen_glGetInteger64i_v; extern RGLSYMGLGETBUFFERPARAMETERI64VPROC __rglgen_glGetBufferParameteri64v; extern RGLSYMGLFRAMEBUFFERTEXTUREPROC __rglgen_glFramebufferTexture; extern RGLSYMGLTEXIMAGE2DMULTISAMPLEPROC __rglgen_glTexImage2DMultisample; extern RGLSYMGLTEXIMAGE3DMULTISAMPLEPROC __rglgen_glTexImage3DMultisample; extern RGLSYMGLGETMULTISAMPLEFVPROC __rglgen_glGetMultisamplefv; extern RGLSYMGLSAMPLEMASKIPROC __rglgen_glSampleMaski; extern RGLSYMGLBINDFRAGDATALOCATIONINDEXEDPROC __rglgen_glBindFragDataLocationIndexed; extern RGLSYMGLGETFRAGDATAINDEXPROC __rglgen_glGetFragDataIndex; extern RGLSYMGLGENSAMPLERSPROC __rglgen_glGenSamplers; extern RGLSYMGLDELETESAMPLERSPROC __rglgen_glDeleteSamplers; extern RGLSYMGLISSAMPLERPROC __rglgen_glIsSampler; extern RGLSYMGLBINDSAMPLERPROC __rglgen_glBindSampler; extern RGLSYMGLSAMPLERPARAMETERIPROC __rglgen_glSamplerParameteri; extern RGLSYMGLSAMPLERPARAMETERIVPROC __rglgen_glSamplerParameteriv; extern RGLSYMGLSAMPLERPARAMETERFPROC __rglgen_glSamplerParameterf; extern RGLSYMGLSAMPLERPARAMETERFVPROC __rglgen_glSamplerParameterfv; extern RGLSYMGLSAMPLERPARAMETERIIVPROC __rglgen_glSamplerParameterIiv; extern RGLSYMGLSAMPLERPARAMETERIUIVPROC __rglgen_glSamplerParameterIuiv; extern RGLSYMGLGETSAMPLERPARAMETERIVPROC __rglgen_glGetSamplerParameteriv; extern RGLSYMGLGETSAMPLERPARAMETERIIVPROC __rglgen_glGetSamplerParameterIiv; extern RGLSYMGLGETSAMPLERPARAMETERFVPROC __rglgen_glGetSamplerParameterfv; extern RGLSYMGLGETSAMPLERPARAMETERIUIVPROC __rglgen_glGetSamplerParameterIuiv; extern RGLSYMGLQUERYCOUNTERPROC __rglgen_glQueryCounter; extern RGLSYMGLGETQUERYOBJECTI64VPROC __rglgen_glGetQueryObjecti64v; extern RGLSYMGLGETQUERYOBJECTUI64VPROC __rglgen_glGetQueryObjectui64v; extern RGLSYMGLVERTEXATTRIBDIVISORPROC __rglgen_glVertexAttribDivisor; extern RGLSYMGLVERTEXATTRIBP1UIPROC __rglgen_glVertexAttribP1ui; extern RGLSYMGLVERTEXATTRIBP1UIVPROC __rglgen_glVertexAttribP1uiv; extern RGLSYMGLVERTEXATTRIBP2UIPROC __rglgen_glVertexAttribP2ui; extern RGLSYMGLVERTEXATTRIBP2UIVPROC __rglgen_glVertexAttribP2uiv; extern RGLSYMGLVERTEXATTRIBP3UIPROC __rglgen_glVertexAttribP3ui; extern RGLSYMGLVERTEXATTRIBP3UIVPROC __rglgen_glVertexAttribP3uiv; extern RGLSYMGLVERTEXATTRIBP4UIPROC __rglgen_glVertexAttribP4ui; extern RGLSYMGLVERTEXATTRIBP4UIVPROC __rglgen_glVertexAttribP4uiv; extern RGLSYMGLVERTEXP2UIPROC __rglgen_glVertexP2ui; extern RGLSYMGLVERTEXP2UIVPROC __rglgen_glVertexP2uiv; extern RGLSYMGLVERTEXP3UIPROC __rglgen_glVertexP3ui; extern RGLSYMGLVERTEXP3UIVPROC __rglgen_glVertexP3uiv; extern RGLSYMGLVERTEXP4UIPROC __rglgen_glVertexP4ui; extern RGLSYMGLVERTEXP4UIVPROC __rglgen_glVertexP4uiv; extern RGLSYMGLTEXCOORDP1UIPROC __rglgen_glTexCoordP1ui; extern RGLSYMGLTEXCOORDP1UIVPROC __rglgen_glTexCoordP1uiv; extern RGLSYMGLTEXCOORDP2UIPROC __rglgen_glTexCoordP2ui; extern RGLSYMGLTEXCOORDP2UIVPROC __rglgen_glTexCoordP2uiv; extern RGLSYMGLTEXCOORDP3UIPROC __rglgen_glTexCoordP3ui; extern RGLSYMGLTEXCOORDP3UIVPROC __rglgen_glTexCoordP3uiv; extern RGLSYMGLTEXCOORDP4UIPROC __rglgen_glTexCoordP4ui; extern RGLSYMGLTEXCOORDP4UIVPROC __rglgen_glTexCoordP4uiv; extern RGLSYMGLMULTITEXCOORDP1UIPROC __rglgen_glMultiTexCoordP1ui; extern RGLSYMGLMULTITEXCOORDP1UIVPROC __rglgen_glMultiTexCoordP1uiv; extern RGLSYMGLMULTITEXCOORDP2UIPROC __rglgen_glMultiTexCoordP2ui; extern RGLSYMGLMULTITEXCOORDP2UIVPROC __rglgen_glMultiTexCoordP2uiv; extern RGLSYMGLMULTITEXCOORDP3UIPROC __rglgen_glMultiTexCoordP3ui; extern RGLSYMGLMULTITEXCOORDP3UIVPROC __rglgen_glMultiTexCoordP3uiv; extern RGLSYMGLMULTITEXCOORDP4UIPROC __rglgen_glMultiTexCoordP4ui; extern RGLSYMGLMULTITEXCOORDP4UIVPROC __rglgen_glMultiTexCoordP4uiv; extern RGLSYMGLNORMALP3UIPROC __rglgen_glNormalP3ui; extern RGLSYMGLNORMALP3UIVPROC __rglgen_glNormalP3uiv; extern RGLSYMGLCOLORP3UIPROC __rglgen_glColorP3ui; extern RGLSYMGLCOLORP3UIVPROC __rglgen_glColorP3uiv; extern RGLSYMGLCOLORP4UIPROC __rglgen_glColorP4ui; extern RGLSYMGLCOLORP4UIVPROC __rglgen_glColorP4uiv; extern RGLSYMGLSECONDARYCOLORP3UIPROC __rglgen_glSecondaryColorP3ui; extern RGLSYMGLSECONDARYCOLORP3UIVPROC __rglgen_glSecondaryColorP3uiv; extern RGLSYMGLMINSAMPLESHADINGPROC __rglgen_glMinSampleShading; extern RGLSYMGLBLENDEQUATIONIPROC __rglgen_glBlendEquationi; extern RGLSYMGLBLENDEQUATIONSEPARATEIPROC __rglgen_glBlendEquationSeparatei; extern RGLSYMGLBLENDFUNCIPROC __rglgen_glBlendFunci; extern RGLSYMGLBLENDFUNCSEPARATEIPROC __rglgen_glBlendFuncSeparatei; extern RGLSYMGLDRAWARRAYSINDIRECTPROC __rglgen_glDrawArraysIndirect; extern RGLSYMGLDRAWELEMENTSINDIRECTPROC __rglgen_glDrawElementsIndirect; extern RGLSYMGLUNIFORM1DPROC __rglgen_glUniform1d; extern RGLSYMGLUNIFORM2DPROC __rglgen_glUniform2d; extern RGLSYMGLUNIFORM3DPROC __rglgen_glUniform3d; extern RGLSYMGLUNIFORM4DPROC __rglgen_glUniform4d; extern RGLSYMGLUNIFORM1DVPROC __rglgen_glUniform1dv; extern RGLSYMGLUNIFORM2DVPROC __rglgen_glUniform2dv; extern RGLSYMGLUNIFORM3DVPROC __rglgen_glUniform3dv; extern RGLSYMGLUNIFORM4DVPROC __rglgen_glUniform4dv; extern RGLSYMGLUNIFORMMATRIX2DVPROC __rglgen_glUniformMatrix2dv; extern RGLSYMGLUNIFORMMATRIX3DVPROC __rglgen_glUniformMatrix3dv; extern RGLSYMGLUNIFORMMATRIX4DVPROC __rglgen_glUniformMatrix4dv; extern RGLSYMGLUNIFORMMATRIX2X3DVPROC __rglgen_glUniformMatrix2x3dv; extern RGLSYMGLUNIFORMMATRIX2X4DVPROC __rglgen_glUniformMatrix2x4dv; extern RGLSYMGLUNIFORMMATRIX3X2DVPROC __rglgen_glUniformMatrix3x2dv; extern RGLSYMGLUNIFORMMATRIX3X4DVPROC __rglgen_glUniformMatrix3x4dv; extern RGLSYMGLUNIFORMMATRIX4X2DVPROC __rglgen_glUniformMatrix4x2dv; extern RGLSYMGLUNIFORMMATRIX4X3DVPROC __rglgen_glUniformMatrix4x3dv; extern RGLSYMGLGETUNIFORMDVPROC __rglgen_glGetUniformdv; extern RGLSYMGLGETSUBROUTINEUNIFORMLOCATIONPROC __rglgen_glGetSubroutineUniformLocation; extern RGLSYMGLGETSUBROUTINEINDEXPROC __rglgen_glGetSubroutineIndex; extern RGLSYMGLGETACTIVESUBROUTINEUNIFORMIVPROC __rglgen_glGetActiveSubroutineUniformiv; extern RGLSYMGLGETACTIVESUBROUTINEUNIFORMNAMEPROC __rglgen_glGetActiveSubroutineUniformName; extern RGLSYMGLGETACTIVESUBROUTINENAMEPROC __rglgen_glGetActiveSubroutineName; extern RGLSYMGLUNIFORMSUBROUTINESUIVPROC __rglgen_glUniformSubroutinesuiv; extern RGLSYMGLGETUNIFORMSUBROUTINEUIVPROC __rglgen_glGetUniformSubroutineuiv; extern RGLSYMGLGETPROGRAMSTAGEIVPROC __rglgen_glGetProgramStageiv; extern RGLSYMGLPATCHPARAMETERIPROC __rglgen_glPatchParameteri; extern RGLSYMGLPATCHPARAMETERFVPROC __rglgen_glPatchParameterfv; extern RGLSYMGLBINDTRANSFORMFEEDBACKPROC __rglgen_glBindTransformFeedback; extern RGLSYMGLDELETETRANSFORMFEEDBACKSPROC __rglgen_glDeleteTransformFeedbacks; extern RGLSYMGLGENTRANSFORMFEEDBACKSPROC __rglgen_glGenTransformFeedbacks; extern RGLSYMGLISTRANSFORMFEEDBACKPROC __rglgen_glIsTransformFeedback; extern RGLSYMGLPAUSETRANSFORMFEEDBACKPROC __rglgen_glPauseTransformFeedback; extern RGLSYMGLRESUMETRANSFORMFEEDBACKPROC __rglgen_glResumeTransformFeedback; extern RGLSYMGLDRAWTRANSFORMFEEDBACKPROC __rglgen_glDrawTransformFeedback; extern RGLSYMGLDRAWTRANSFORMFEEDBACKSTREAMPROC __rglgen_glDrawTransformFeedbackStream; extern RGLSYMGLBEGINQUERYINDEXEDPROC __rglgen_glBeginQueryIndexed; extern RGLSYMGLENDQUERYINDEXEDPROC __rglgen_glEndQueryIndexed; extern RGLSYMGLGETQUERYINDEXEDIVPROC __rglgen_glGetQueryIndexediv; extern RGLSYMGLRELEASESHADERCOMPILERPROC __rglgen_glReleaseShaderCompiler; extern RGLSYMGLSHADERBINARYPROC __rglgen_glShaderBinary; extern RGLSYMGLGETSHADERPRECISIONFORMATPROC __rglgen_glGetShaderPrecisionFormat; extern RGLSYMGLDEPTHRANGEFPROC __rglgen_glDepthRangef; extern RGLSYMGLCLEARDEPTHFPROC __rglgen_glClearDepthf; extern RGLSYMGLGETPROGRAMBINARYPROC __rglgen_glGetProgramBinary; extern RGLSYMGLPROGRAMBINARYPROC __rglgen_glProgramBinary; extern RGLSYMGLPROGRAMPARAMETERIPROC __rglgen_glProgramParameteri; extern RGLSYMGLUSEPROGRAMSTAGESPROC __rglgen_glUseProgramStages; extern RGLSYMGLACTIVESHADERPROGRAMPROC __rglgen_glActiveShaderProgram; extern RGLSYMGLCREATESHADERPROGRAMVPROC __rglgen_glCreateShaderProgramv; extern RGLSYMGLBINDPROGRAMPIPELINEPROC __rglgen_glBindProgramPipeline; extern RGLSYMGLDELETEPROGRAMPIPELINESPROC __rglgen_glDeleteProgramPipelines; extern RGLSYMGLGENPROGRAMPIPELINESPROC __rglgen_glGenProgramPipelines; extern RGLSYMGLISPROGRAMPIPELINEPROC __rglgen_glIsProgramPipeline; extern RGLSYMGLGETPROGRAMPIPELINEIVPROC __rglgen_glGetProgramPipelineiv; extern RGLSYMGLPROGRAMUNIFORM1IPROC __rglgen_glProgramUniform1i; extern RGLSYMGLPROGRAMUNIFORM1IVPROC __rglgen_glProgramUniform1iv; extern RGLSYMGLPROGRAMUNIFORM1FPROC __rglgen_glProgramUniform1f; extern RGLSYMGLPROGRAMUNIFORM1FVPROC __rglgen_glProgramUniform1fv; extern RGLSYMGLPROGRAMUNIFORM1DPROC __rglgen_glProgramUniform1d; extern RGLSYMGLPROGRAMUNIFORM1DVPROC __rglgen_glProgramUniform1dv; extern RGLSYMGLPROGRAMUNIFORM1UIPROC __rglgen_glProgramUniform1ui; extern RGLSYMGLPROGRAMUNIFORM1UIVPROC __rglgen_glProgramUniform1uiv; extern RGLSYMGLPROGRAMUNIFORM2IPROC __rglgen_glProgramUniform2i; extern RGLSYMGLPROGRAMUNIFORM2IVPROC __rglgen_glProgramUniform2iv; extern RGLSYMGLPROGRAMUNIFORM2FPROC __rglgen_glProgramUniform2f; extern RGLSYMGLPROGRAMUNIFORM2FVPROC __rglgen_glProgramUniform2fv; extern RGLSYMGLPROGRAMUNIFORM2DPROC __rglgen_glProgramUniform2d; extern RGLSYMGLPROGRAMUNIFORM2DVPROC __rglgen_glProgramUniform2dv; extern RGLSYMGLPROGRAMUNIFORM2UIPROC __rglgen_glProgramUniform2ui; extern RGLSYMGLPROGRAMUNIFORM2UIVPROC __rglgen_glProgramUniform2uiv; extern RGLSYMGLPROGRAMUNIFORM3IPROC __rglgen_glProgramUniform3i; extern RGLSYMGLPROGRAMUNIFORM3IVPROC __rglgen_glProgramUniform3iv; extern RGLSYMGLPROGRAMUNIFORM3FPROC __rglgen_glProgramUniform3f; extern RGLSYMGLPROGRAMUNIFORM3FVPROC __rglgen_glProgramUniform3fv; extern RGLSYMGLPROGRAMUNIFORM3DPROC __rglgen_glProgramUniform3d; extern RGLSYMGLPROGRAMUNIFORM3DVPROC __rglgen_glProgramUniform3dv; extern RGLSYMGLPROGRAMUNIFORM3UIPROC __rglgen_glProgramUniform3ui; extern RGLSYMGLPROGRAMUNIFORM3UIVPROC __rglgen_glProgramUniform3uiv; extern RGLSYMGLPROGRAMUNIFORM4IPROC __rglgen_glProgramUniform4i; extern RGLSYMGLPROGRAMUNIFORM4IVPROC __rglgen_glProgramUniform4iv; extern RGLSYMGLPROGRAMUNIFORM4FPROC __rglgen_glProgramUniform4f; extern RGLSYMGLPROGRAMUNIFORM4FVPROC __rglgen_glProgramUniform4fv; extern RGLSYMGLPROGRAMUNIFORM4DPROC __rglgen_glProgramUniform4d; extern RGLSYMGLPROGRAMUNIFORM4DVPROC __rglgen_glProgramUniform4dv; extern RGLSYMGLPROGRAMUNIFORM4UIPROC __rglgen_glProgramUniform4ui; extern RGLSYMGLPROGRAMUNIFORM4UIVPROC __rglgen_glProgramUniform4uiv; extern RGLSYMGLPROGRAMUNIFORMMATRIX2FVPROC __rglgen_glProgramUniformMatrix2fv; extern RGLSYMGLPROGRAMUNIFORMMATRIX3FVPROC __rglgen_glProgramUniformMatrix3fv; extern RGLSYMGLPROGRAMUNIFORMMATRIX4FVPROC __rglgen_glProgramUniformMatrix4fv; extern RGLSYMGLPROGRAMUNIFORMMATRIX2DVPROC __rglgen_glProgramUniformMatrix2dv; extern RGLSYMGLPROGRAMUNIFORMMATRIX3DVPROC __rglgen_glProgramUniformMatrix3dv; extern RGLSYMGLPROGRAMUNIFORMMATRIX4DVPROC __rglgen_glProgramUniformMatrix4dv; extern RGLSYMGLPROGRAMUNIFORMMATRIX2X3FVPROC __rglgen_glProgramUniformMatrix2x3fv; extern RGLSYMGLPROGRAMUNIFORMMATRIX3X2FVPROC __rglgen_glProgramUniformMatrix3x2fv; extern RGLSYMGLPROGRAMUNIFORMMATRIX2X4FVPROC __rglgen_glProgramUniformMatrix2x4fv; extern RGLSYMGLPROGRAMUNIFORMMATRIX4X2FVPROC __rglgen_glProgramUniformMatrix4x2fv; extern RGLSYMGLPROGRAMUNIFORMMATRIX3X4FVPROC __rglgen_glProgramUniformMatrix3x4fv; extern RGLSYMGLPROGRAMUNIFORMMATRIX4X3FVPROC __rglgen_glProgramUniformMatrix4x3fv; extern RGLSYMGLPROGRAMUNIFORMMATRIX2X3DVPROC __rglgen_glProgramUniformMatrix2x3dv; extern RGLSYMGLPROGRAMUNIFORMMATRIX3X2DVPROC __rglgen_glProgramUniformMatrix3x2dv; extern RGLSYMGLPROGRAMUNIFORMMATRIX2X4DVPROC __rglgen_glProgramUniformMatrix2x4dv; extern RGLSYMGLPROGRAMUNIFORMMATRIX4X2DVPROC __rglgen_glProgramUniformMatrix4x2dv; extern RGLSYMGLPROGRAMUNIFORMMATRIX3X4DVPROC __rglgen_glProgramUniformMatrix3x4dv; extern RGLSYMGLPROGRAMUNIFORMMATRIX4X3DVPROC __rglgen_glProgramUniformMatrix4x3dv; extern RGLSYMGLVALIDATEPROGRAMPIPELINEPROC __rglgen_glValidateProgramPipeline; extern RGLSYMGLGETPROGRAMPIPELINEINFOLOGPROC __rglgen_glGetProgramPipelineInfoLog; extern RGLSYMGLVERTEXATTRIBL1DPROC __rglgen_glVertexAttribL1d; extern RGLSYMGLVERTEXATTRIBL2DPROC __rglgen_glVertexAttribL2d; extern RGLSYMGLVERTEXATTRIBL3DPROC __rglgen_glVertexAttribL3d; extern RGLSYMGLVERTEXATTRIBL4DPROC __rglgen_glVertexAttribL4d; extern RGLSYMGLVERTEXATTRIBL1DVPROC __rglgen_glVertexAttribL1dv; extern RGLSYMGLVERTEXATTRIBL2DVPROC __rglgen_glVertexAttribL2dv; extern RGLSYMGLVERTEXATTRIBL3DVPROC __rglgen_glVertexAttribL3dv; extern RGLSYMGLVERTEXATTRIBL4DVPROC __rglgen_glVertexAttribL4dv; extern RGLSYMGLVERTEXATTRIBLPOINTERPROC __rglgen_glVertexAttribLPointer; extern RGLSYMGLGETVERTEXATTRIBLDVPROC __rglgen_glGetVertexAttribLdv; extern RGLSYMGLVIEWPORTARRAYVPROC __rglgen_glViewportArrayv; extern RGLSYMGLVIEWPORTINDEXEDFPROC __rglgen_glViewportIndexedf; extern RGLSYMGLVIEWPORTINDEXEDFVPROC __rglgen_glViewportIndexedfv; extern RGLSYMGLSCISSORARRAYVPROC __rglgen_glScissorArrayv; extern RGLSYMGLSCISSORINDEXEDPROC __rglgen_glScissorIndexed; extern RGLSYMGLSCISSORINDEXEDVPROC __rglgen_glScissorIndexedv; extern RGLSYMGLDEPTHRANGEARRAYVPROC __rglgen_glDepthRangeArrayv; extern RGLSYMGLDEPTHRANGEINDEXEDPROC __rglgen_glDepthRangeIndexed; extern RGLSYMGLGETFLOATI_VPROC __rglgen_glGetFloati_v; extern RGLSYMGLGETDOUBLEI_VPROC __rglgen_glGetDoublei_v; extern RGLSYMGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC __rglgen_glDrawArraysInstancedBaseInstance; extern RGLSYMGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC __rglgen_glDrawElementsInstancedBaseInstance; extern RGLSYMGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC __rglgen_glDrawElementsInstancedBaseVertexBaseInstance; extern RGLSYMGLGETINTERNALFORMATIVPROC __rglgen_glGetInternalformativ; extern RGLSYMGLGETACTIVEATOMICCOUNTERBUFFERIVPROC __rglgen_glGetActiveAtomicCounterBufferiv; extern RGLSYMGLBINDIMAGETEXTUREPROC __rglgen_glBindImageTexture; extern RGLSYMGLMEMORYBARRIERPROC __rglgen_glMemoryBarrier; extern RGLSYMGLTEXSTORAGE1DPROC __rglgen_glTexStorage1D; extern RGLSYMGLTEXSTORAGE2DPROC __rglgen_glTexStorage2D; extern RGLSYMGLTEXSTORAGE3DPROC __rglgen_glTexStorage3D; extern RGLSYMGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC __rglgen_glDrawTransformFeedbackInstanced; extern RGLSYMGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC __rglgen_glDrawTransformFeedbackStreamInstanced; extern RGLSYMGLCLEARBUFFERDATAPROC __rglgen_glClearBufferData; extern RGLSYMGLCLEARBUFFERSUBDATAPROC __rglgen_glClearBufferSubData; extern RGLSYMGLDISPATCHCOMPUTEPROC __rglgen_glDispatchCompute; extern RGLSYMGLDISPATCHCOMPUTEINDIRECTPROC __rglgen_glDispatchComputeIndirect; extern RGLSYMGLCOPYIMAGESUBDATAPROC __rglgen_glCopyImageSubData; extern RGLSYMGLFRAMEBUFFERPARAMETERIPROC __rglgen_glFramebufferParameteri; extern RGLSYMGLGETFRAMEBUFFERPARAMETERIVPROC __rglgen_glGetFramebufferParameteriv; extern RGLSYMGLGETINTERNALFORMATI64VPROC __rglgen_glGetInternalformati64v; extern RGLSYMGLINVALIDATETEXSUBIMAGEPROC __rglgen_glInvalidateTexSubImage; extern RGLSYMGLINVALIDATETEXIMAGEPROC __rglgen_glInvalidateTexImage; extern RGLSYMGLINVALIDATEBUFFERSUBDATAPROC __rglgen_glInvalidateBufferSubData; extern RGLSYMGLINVALIDATEBUFFERDATAPROC __rglgen_glInvalidateBufferData; extern RGLSYMGLINVALIDATEFRAMEBUFFERPROC __rglgen_glInvalidateFramebuffer; extern RGLSYMGLINVALIDATESUBFRAMEBUFFERPROC __rglgen_glInvalidateSubFramebuffer; extern RGLSYMGLMULTIDRAWARRAYSINDIRECTPROC __rglgen_glMultiDrawArraysIndirect; extern RGLSYMGLMULTIDRAWELEMENTSINDIRECTPROC __rglgen_glMultiDrawElementsIndirect; extern RGLSYMGLGETPROGRAMINTERFACEIVPROC __rglgen_glGetProgramInterfaceiv; extern RGLSYMGLGETPROGRAMRESOURCEINDEXPROC __rglgen_glGetProgramResourceIndex; extern RGLSYMGLGETPROGRAMRESOURCENAMEPROC __rglgen_glGetProgramResourceName; extern RGLSYMGLGETPROGRAMRESOURCEIVPROC __rglgen_glGetProgramResourceiv; extern RGLSYMGLGETPROGRAMRESOURCELOCATIONPROC __rglgen_glGetProgramResourceLocation; extern RGLSYMGLGETPROGRAMRESOURCELOCATIONINDEXPROC __rglgen_glGetProgramResourceLocationIndex; extern RGLSYMGLSHADERSTORAGEBLOCKBINDINGPROC __rglgen_glShaderStorageBlockBinding; extern RGLSYMGLTEXBUFFERRANGEPROC __rglgen_glTexBufferRange; extern RGLSYMGLTEXSTORAGE2DMULTISAMPLEPROC __rglgen_glTexStorage2DMultisample; extern RGLSYMGLTEXSTORAGE3DMULTISAMPLEPROC __rglgen_glTexStorage3DMultisample; extern RGLSYMGLTEXTUREVIEWPROC __rglgen_glTextureView; extern RGLSYMGLBINDVERTEXBUFFERPROC __rglgen_glBindVertexBuffer; extern RGLSYMGLVERTEXATTRIBFORMATPROC __rglgen_glVertexAttribFormat; extern RGLSYMGLVERTEXATTRIBIFORMATPROC __rglgen_glVertexAttribIFormat; extern RGLSYMGLVERTEXATTRIBLFORMATPROC __rglgen_glVertexAttribLFormat; extern RGLSYMGLVERTEXATTRIBBINDINGPROC __rglgen_glVertexAttribBinding; extern RGLSYMGLVERTEXBINDINGDIVISORPROC __rglgen_glVertexBindingDivisor; extern RGLSYMGLDEBUGMESSAGECONTROLPROC __rglgen_glDebugMessageControl; extern RGLSYMGLDEBUGMESSAGEINSERTPROC __rglgen_glDebugMessageInsert; extern RGLSYMGLDEBUGMESSAGECALLBACKPROC __rglgen_glDebugMessageCallback; extern RGLSYMGLGETDEBUGMESSAGELOGPROC __rglgen_glGetDebugMessageLog; extern RGLSYMGLPUSHDEBUGGROUPPROC __rglgen_glPushDebugGroup; extern RGLSYMGLPOPDEBUGGROUPPROC __rglgen_glPopDebugGroup; extern RGLSYMGLOBJECTLABELPROC __rglgen_glObjectLabel; extern RGLSYMGLGETOBJECTLABELPROC __rglgen_glGetObjectLabel; extern RGLSYMGLOBJECTPTRLABELPROC __rglgen_glObjectPtrLabel; extern RGLSYMGLGETOBJECTPTRLABELPROC __rglgen_glGetObjectPtrLabel; extern RGLSYMGLBUFFERSTORAGEPROC __rglgen_glBufferStorage; extern RGLSYMGLCLEARTEXIMAGEPROC __rglgen_glClearTexImage; extern RGLSYMGLCLEARTEXSUBIMAGEPROC __rglgen_glClearTexSubImage; extern RGLSYMGLBINDBUFFERSBASEPROC __rglgen_glBindBuffersBase; extern RGLSYMGLBINDBUFFERSRANGEPROC __rglgen_glBindBuffersRange; extern RGLSYMGLBINDTEXTURESPROC __rglgen_glBindTextures; extern RGLSYMGLBINDSAMPLERSPROC __rglgen_glBindSamplers; extern RGLSYMGLBINDIMAGETEXTURESPROC __rglgen_glBindImageTextures; extern RGLSYMGLBINDVERTEXBUFFERSPROC __rglgen_glBindVertexBuffers; extern RGLSYMGLGETTEXTUREHANDLEARBPROC __rglgen_glGetTextureHandleARB; extern RGLSYMGLGETTEXTURESAMPLERHANDLEARBPROC __rglgen_glGetTextureSamplerHandleARB; extern RGLSYMGLMAKETEXTUREHANDLERESIDENTARBPROC __rglgen_glMakeTextureHandleResidentARB; extern RGLSYMGLMAKETEXTUREHANDLENONRESIDENTARBPROC __rglgen_glMakeTextureHandleNonResidentARB; extern RGLSYMGLGETIMAGEHANDLEARBPROC __rglgen_glGetImageHandleARB; extern RGLSYMGLMAKEIMAGEHANDLERESIDENTARBPROC __rglgen_glMakeImageHandleResidentARB; extern RGLSYMGLMAKEIMAGEHANDLENONRESIDENTARBPROC __rglgen_glMakeImageHandleNonResidentARB; extern RGLSYMGLUNIFORMHANDLEUI64ARBPROC __rglgen_glUniformHandleui64ARB; extern RGLSYMGLUNIFORMHANDLEUI64VARBPROC __rglgen_glUniformHandleui64vARB; extern RGLSYMGLPROGRAMUNIFORMHANDLEUI64ARBPROC __rglgen_glProgramUniformHandleui64ARB; extern RGLSYMGLPROGRAMUNIFORMHANDLEUI64VARBPROC __rglgen_glProgramUniformHandleui64vARB; extern RGLSYMGLISTEXTUREHANDLERESIDENTARBPROC __rglgen_glIsTextureHandleResidentARB; extern RGLSYMGLISIMAGEHANDLERESIDENTARBPROC __rglgen_glIsImageHandleResidentARB; extern RGLSYMGLVERTEXATTRIBL1UI64ARBPROC __rglgen_glVertexAttribL1ui64ARB; extern RGLSYMGLVERTEXATTRIBL1UI64VARBPROC __rglgen_glVertexAttribL1ui64vARB; extern RGLSYMGLGETVERTEXATTRIBLUI64VARBPROC __rglgen_glGetVertexAttribLui64vARB; extern RGLSYMGLCREATESYNCFROMCLEVENTARBPROC __rglgen_glCreateSyncFromCLeventARB; extern RGLSYMGLCLAMPCOLORARBPROC __rglgen_glClampColorARB; extern RGLSYMGLDISPATCHCOMPUTEGROUPSIZEARBPROC __rglgen_glDispatchComputeGroupSizeARB; extern RGLSYMGLDEBUGMESSAGECONTROLARBPROC __rglgen_glDebugMessageControlARB; extern RGLSYMGLDEBUGMESSAGEINSERTARBPROC __rglgen_glDebugMessageInsertARB; extern RGLSYMGLDEBUGMESSAGECALLBACKARBPROC __rglgen_glDebugMessageCallbackARB; extern RGLSYMGLGETDEBUGMESSAGELOGARBPROC __rglgen_glGetDebugMessageLogARB; extern RGLSYMGLDRAWBUFFERSARBPROC __rglgen_glDrawBuffersARB; extern RGLSYMGLBLENDEQUATIONIARBPROC __rglgen_glBlendEquationiARB; extern RGLSYMGLBLENDEQUATIONSEPARATEIARBPROC __rglgen_glBlendEquationSeparateiARB; extern RGLSYMGLBLENDFUNCIARBPROC __rglgen_glBlendFunciARB; extern RGLSYMGLBLENDFUNCSEPARATEIARBPROC __rglgen_glBlendFuncSeparateiARB; extern RGLSYMGLDRAWARRAYSINSTANCEDARBPROC __rglgen_glDrawArraysInstancedARB; extern RGLSYMGLDRAWELEMENTSINSTANCEDARBPROC __rglgen_glDrawElementsInstancedARB; extern RGLSYMGLPROGRAMSTRINGARBPROC __rglgen_glProgramStringARB; extern RGLSYMGLBINDPROGRAMARBPROC __rglgen_glBindProgramARB; extern RGLSYMGLDELETEPROGRAMSARBPROC __rglgen_glDeleteProgramsARB; extern RGLSYMGLGENPROGRAMSARBPROC __rglgen_glGenProgramsARB; extern RGLSYMGLPROGRAMENVPARAMETER4DARBPROC __rglgen_glProgramEnvParameter4dARB; extern RGLSYMGLPROGRAMENVPARAMETER4DVARBPROC __rglgen_glProgramEnvParameter4dvARB; extern RGLSYMGLPROGRAMENVPARAMETER4FARBPROC __rglgen_glProgramEnvParameter4fARB; extern RGLSYMGLPROGRAMENVPARAMETER4FVARBPROC __rglgen_glProgramEnvParameter4fvARB; extern RGLSYMGLPROGRAMLOCALPARAMETER4DARBPROC __rglgen_glProgramLocalParameter4dARB; extern RGLSYMGLPROGRAMLOCALPARAMETER4DVARBPROC __rglgen_glProgramLocalParameter4dvARB; extern RGLSYMGLPROGRAMLOCALPARAMETER4FARBPROC __rglgen_glProgramLocalParameter4fARB; extern RGLSYMGLPROGRAMLOCALPARAMETER4FVARBPROC __rglgen_glProgramLocalParameter4fvARB; extern RGLSYMGLGETPROGRAMENVPARAMETERDVARBPROC __rglgen_glGetProgramEnvParameterdvARB; extern RGLSYMGLGETPROGRAMENVPARAMETERFVARBPROC __rglgen_glGetProgramEnvParameterfvARB; extern RGLSYMGLGETPROGRAMLOCALPARAMETERDVARBPROC __rglgen_glGetProgramLocalParameterdvARB; extern RGLSYMGLGETPROGRAMLOCALPARAMETERFVARBPROC __rglgen_glGetProgramLocalParameterfvARB; extern RGLSYMGLGETPROGRAMIVARBPROC __rglgen_glGetProgramivARB; extern RGLSYMGLGETPROGRAMSTRINGARBPROC __rglgen_glGetProgramStringARB; extern RGLSYMGLISPROGRAMARBPROC __rglgen_glIsProgramARB; extern RGLSYMGLPROGRAMPARAMETERIARBPROC __rglgen_glProgramParameteriARB; extern RGLSYMGLFRAMEBUFFERTEXTUREARBPROC __rglgen_glFramebufferTextureARB; extern RGLSYMGLFRAMEBUFFERTEXTURELAYERARBPROC __rglgen_glFramebufferTextureLayerARB; extern RGLSYMGLFRAMEBUFFERTEXTUREFACEARBPROC __rglgen_glFramebufferTextureFaceARB; extern RGLSYMGLCOLORTABLEPROC __rglgen_glColorTable; extern RGLSYMGLCOLORTABLEPARAMETERFVPROC __rglgen_glColorTableParameterfv; extern RGLSYMGLCOLORTABLEPARAMETERIVPROC __rglgen_glColorTableParameteriv; extern RGLSYMGLCOPYCOLORTABLEPROC __rglgen_glCopyColorTable; extern RGLSYMGLGETCOLORTABLEPROC __rglgen_glGetColorTable; extern RGLSYMGLGETCOLORTABLEPARAMETERFVPROC __rglgen_glGetColorTableParameterfv; extern RGLSYMGLGETCOLORTABLEPARAMETERIVPROC __rglgen_glGetColorTableParameteriv; extern RGLSYMGLCOLORSUBTABLEPROC __rglgen_glColorSubTable; extern RGLSYMGLCOPYCOLORSUBTABLEPROC __rglgen_glCopyColorSubTable; extern RGLSYMGLCONVOLUTIONFILTER1DPROC __rglgen_glConvolutionFilter1D; extern RGLSYMGLCONVOLUTIONFILTER2DPROC __rglgen_glConvolutionFilter2D; extern RGLSYMGLCONVOLUTIONPARAMETERFPROC __rglgen_glConvolutionParameterf; extern RGLSYMGLCONVOLUTIONPARAMETERFVPROC __rglgen_glConvolutionParameterfv; extern RGLSYMGLCONVOLUTIONPARAMETERIPROC __rglgen_glConvolutionParameteri; extern RGLSYMGLCONVOLUTIONPARAMETERIVPROC __rglgen_glConvolutionParameteriv; extern RGLSYMGLCOPYCONVOLUTIONFILTER1DPROC __rglgen_glCopyConvolutionFilter1D; extern RGLSYMGLCOPYCONVOLUTIONFILTER2DPROC __rglgen_glCopyConvolutionFilter2D; extern RGLSYMGLGETCONVOLUTIONFILTERPROC __rglgen_glGetConvolutionFilter; extern RGLSYMGLGETCONVOLUTIONPARAMETERFVPROC __rglgen_glGetConvolutionParameterfv; extern RGLSYMGLGETCONVOLUTIONPARAMETERIVPROC __rglgen_glGetConvolutionParameteriv; extern RGLSYMGLGETSEPARABLEFILTERPROC __rglgen_glGetSeparableFilter; extern RGLSYMGLSEPARABLEFILTER2DPROC __rglgen_glSeparableFilter2D; extern RGLSYMGLGETHISTOGRAMPROC __rglgen_glGetHistogram; extern RGLSYMGLGETHISTOGRAMPARAMETERFVPROC __rglgen_glGetHistogramParameterfv; extern RGLSYMGLGETHISTOGRAMPARAMETERIVPROC __rglgen_glGetHistogramParameteriv; extern RGLSYMGLGETMINMAXPROC __rglgen_glGetMinmax; extern RGLSYMGLGETMINMAXPARAMETERFVPROC __rglgen_glGetMinmaxParameterfv; extern RGLSYMGLGETMINMAXPARAMETERIVPROC __rglgen_glGetMinmaxParameteriv; extern RGLSYMGLHISTOGRAMPROC __rglgen_glHistogram; extern RGLSYMGLMINMAXPROC __rglgen_glMinmax; extern RGLSYMGLRESETHISTOGRAMPROC __rglgen_glResetHistogram; extern RGLSYMGLRESETMINMAXPROC __rglgen_glResetMinmax; extern RGLSYMGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC __rglgen_glMultiDrawArraysIndirectCountARB; extern RGLSYMGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC __rglgen_glMultiDrawElementsIndirectCountARB; extern RGLSYMGLVERTEXATTRIBDIVISORARBPROC __rglgen_glVertexAttribDivisorARB; extern RGLSYMGLCURRENTPALETTEMATRIXARBPROC __rglgen_glCurrentPaletteMatrixARB; extern RGLSYMGLMATRIXINDEXUBVARBPROC __rglgen_glMatrixIndexubvARB; extern RGLSYMGLMATRIXINDEXUSVARBPROC __rglgen_glMatrixIndexusvARB; extern RGLSYMGLMATRIXINDEXUIVARBPROC __rglgen_glMatrixIndexuivARB; extern RGLSYMGLMATRIXINDEXPOINTERARBPROC __rglgen_glMatrixIndexPointerARB; extern RGLSYMGLSAMPLECOVERAGEARBPROC __rglgen_glSampleCoverageARB; extern RGLSYMGLACTIVETEXTUREARBPROC __rglgen_glActiveTextureARB; extern RGLSYMGLCLIENTACTIVETEXTUREARBPROC __rglgen_glClientActiveTextureARB; extern RGLSYMGLMULTITEXCOORD1DARBPROC __rglgen_glMultiTexCoord1dARB; extern RGLSYMGLMULTITEXCOORD1DVARBPROC __rglgen_glMultiTexCoord1dvARB; extern RGLSYMGLMULTITEXCOORD1FARBPROC __rglgen_glMultiTexCoord1fARB; extern RGLSYMGLMULTITEXCOORD1FVARBPROC __rglgen_glMultiTexCoord1fvARB; extern RGLSYMGLMULTITEXCOORD1IARBPROC __rglgen_glMultiTexCoord1iARB; extern RGLSYMGLMULTITEXCOORD1IVARBPROC __rglgen_glMultiTexCoord1ivARB; extern RGLSYMGLMULTITEXCOORD1SARBPROC __rglgen_glMultiTexCoord1sARB; extern RGLSYMGLMULTITEXCOORD1SVARBPROC __rglgen_glMultiTexCoord1svARB; extern RGLSYMGLMULTITEXCOORD2DARBPROC __rglgen_glMultiTexCoord2dARB; extern RGLSYMGLMULTITEXCOORD2DVARBPROC __rglgen_glMultiTexCoord2dvARB; extern RGLSYMGLMULTITEXCOORD2FARBPROC __rglgen_glMultiTexCoord2fARB; extern RGLSYMGLMULTITEXCOORD2FVARBPROC __rglgen_glMultiTexCoord2fvARB; extern RGLSYMGLMULTITEXCOORD2IARBPROC __rglgen_glMultiTexCoord2iARB; extern RGLSYMGLMULTITEXCOORD2IVARBPROC __rglgen_glMultiTexCoord2ivARB; extern RGLSYMGLMULTITEXCOORD2SARBPROC __rglgen_glMultiTexCoord2sARB; extern RGLSYMGLMULTITEXCOORD2SVARBPROC __rglgen_glMultiTexCoord2svARB; extern RGLSYMGLMULTITEXCOORD3DARBPROC __rglgen_glMultiTexCoord3dARB; extern RGLSYMGLMULTITEXCOORD3DVARBPROC __rglgen_glMultiTexCoord3dvARB; extern RGLSYMGLMULTITEXCOORD3FARBPROC __rglgen_glMultiTexCoord3fARB; extern RGLSYMGLMULTITEXCOORD3FVARBPROC __rglgen_glMultiTexCoord3fvARB; extern RGLSYMGLMULTITEXCOORD3IARBPROC __rglgen_glMultiTexCoord3iARB; extern RGLSYMGLMULTITEXCOORD3IVARBPROC __rglgen_glMultiTexCoord3ivARB; extern RGLSYMGLMULTITEXCOORD3SARBPROC __rglgen_glMultiTexCoord3sARB; extern RGLSYMGLMULTITEXCOORD3SVARBPROC __rglgen_glMultiTexCoord3svARB; extern RGLSYMGLMULTITEXCOORD4DARBPROC __rglgen_glMultiTexCoord4dARB; extern RGLSYMGLMULTITEXCOORD4DVARBPROC __rglgen_glMultiTexCoord4dvARB; extern RGLSYMGLMULTITEXCOORD4FARBPROC __rglgen_glMultiTexCoord4fARB; extern RGLSYMGLMULTITEXCOORD4FVARBPROC __rglgen_glMultiTexCoord4fvARB; extern RGLSYMGLMULTITEXCOORD4IARBPROC __rglgen_glMultiTexCoord4iARB; extern RGLSYMGLMULTITEXCOORD4IVARBPROC __rglgen_glMultiTexCoord4ivARB; extern RGLSYMGLMULTITEXCOORD4SARBPROC __rglgen_glMultiTexCoord4sARB; extern RGLSYMGLMULTITEXCOORD4SVARBPROC __rglgen_glMultiTexCoord4svARB; extern RGLSYMGLGENQUERIESARBPROC __rglgen_glGenQueriesARB; extern RGLSYMGLDELETEQUERIESARBPROC __rglgen_glDeleteQueriesARB; extern RGLSYMGLISQUERYARBPROC __rglgen_glIsQueryARB; extern RGLSYMGLBEGINQUERYARBPROC __rglgen_glBeginQueryARB; extern RGLSYMGLENDQUERYARBPROC __rglgen_glEndQueryARB; extern RGLSYMGLGETQUERYIVARBPROC __rglgen_glGetQueryivARB; extern RGLSYMGLGETQUERYOBJECTIVARBPROC __rglgen_glGetQueryObjectivARB; extern RGLSYMGLGETQUERYOBJECTUIVARBPROC __rglgen_glGetQueryObjectuivARB; extern RGLSYMGLPOINTPARAMETERFARBPROC __rglgen_glPointParameterfARB; extern RGLSYMGLPOINTPARAMETERFVARBPROC __rglgen_glPointParameterfvARB; extern RGLSYMGLGETGRAPHICSRESETSTATUSARBPROC __rglgen_glGetGraphicsResetStatusARB; extern RGLSYMGLGETNTEXIMAGEARBPROC __rglgen_glGetnTexImageARB; extern RGLSYMGLREADNPIXELSARBPROC __rglgen_glReadnPixelsARB; extern RGLSYMGLGETNCOMPRESSEDTEXIMAGEARBPROC __rglgen_glGetnCompressedTexImageARB; extern RGLSYMGLGETNUNIFORMFVARBPROC __rglgen_glGetnUniformfvARB; extern RGLSYMGLGETNUNIFORMIVARBPROC __rglgen_glGetnUniformivARB; extern RGLSYMGLGETNUNIFORMUIVARBPROC __rglgen_glGetnUniformuivARB; extern RGLSYMGLGETNUNIFORMDVARBPROC __rglgen_glGetnUniformdvARB; extern RGLSYMGLGETNMAPDVARBPROC __rglgen_glGetnMapdvARB; extern RGLSYMGLGETNMAPFVARBPROC __rglgen_glGetnMapfvARB; extern RGLSYMGLGETNMAPIVARBPROC __rglgen_glGetnMapivARB; extern RGLSYMGLGETNPIXELMAPFVARBPROC __rglgen_glGetnPixelMapfvARB; extern RGLSYMGLGETNPIXELMAPUIVARBPROC __rglgen_glGetnPixelMapuivARB; extern RGLSYMGLGETNPIXELMAPUSVARBPROC __rglgen_glGetnPixelMapusvARB; extern RGLSYMGLGETNPOLYGONSTIPPLEARBPROC __rglgen_glGetnPolygonStippleARB; extern RGLSYMGLGETNCOLORTABLEARBPROC __rglgen_glGetnColorTableARB; extern RGLSYMGLGETNCONVOLUTIONFILTERARBPROC __rglgen_glGetnConvolutionFilterARB; extern RGLSYMGLGETNSEPARABLEFILTERARBPROC __rglgen_glGetnSeparableFilterARB; extern RGLSYMGLGETNHISTOGRAMARBPROC __rglgen_glGetnHistogramARB; extern RGLSYMGLGETNMINMAXARBPROC __rglgen_glGetnMinmaxARB; extern RGLSYMGLMINSAMPLESHADINGARBPROC __rglgen_glMinSampleShadingARB; extern RGLSYMGLDELETEOBJECTARBPROC __rglgen_glDeleteObjectARB; extern RGLSYMGLGETHANDLEARBPROC __rglgen_glGetHandleARB; extern RGLSYMGLDETACHOBJECTARBPROC __rglgen_glDetachObjectARB; extern RGLSYMGLCREATESHADEROBJECTARBPROC __rglgen_glCreateShaderObjectARB; extern RGLSYMGLSHADERSOURCEARBPROC __rglgen_glShaderSourceARB; extern RGLSYMGLCOMPILESHADERARBPROC __rglgen_glCompileShaderARB; extern RGLSYMGLCREATEPROGRAMOBJECTARBPROC __rglgen_glCreateProgramObjectARB; extern RGLSYMGLATTACHOBJECTARBPROC __rglgen_glAttachObjectARB; extern RGLSYMGLLINKPROGRAMARBPROC __rglgen_glLinkProgramARB; extern RGLSYMGLUSEPROGRAMOBJECTARBPROC __rglgen_glUseProgramObjectARB; extern RGLSYMGLVALIDATEPROGRAMARBPROC __rglgen_glValidateProgramARB; extern RGLSYMGLUNIFORM1FARBPROC __rglgen_glUniform1fARB; extern RGLSYMGLUNIFORM2FARBPROC __rglgen_glUniform2fARB; extern RGLSYMGLUNIFORM3FARBPROC __rglgen_glUniform3fARB; extern RGLSYMGLUNIFORM4FARBPROC __rglgen_glUniform4fARB; extern RGLSYMGLUNIFORM1IARBPROC __rglgen_glUniform1iARB; extern RGLSYMGLUNIFORM2IARBPROC __rglgen_glUniform2iARB; extern RGLSYMGLUNIFORM3IARBPROC __rglgen_glUniform3iARB; extern RGLSYMGLUNIFORM4IARBPROC __rglgen_glUniform4iARB; extern RGLSYMGLUNIFORM1FVARBPROC __rglgen_glUniform1fvARB; extern RGLSYMGLUNIFORM2FVARBPROC __rglgen_glUniform2fvARB; extern RGLSYMGLUNIFORM3FVARBPROC __rglgen_glUniform3fvARB; extern RGLSYMGLUNIFORM4FVARBPROC __rglgen_glUniform4fvARB; extern RGLSYMGLUNIFORM1IVARBPROC __rglgen_glUniform1ivARB; extern RGLSYMGLUNIFORM2IVARBPROC __rglgen_glUniform2ivARB; extern RGLSYMGLUNIFORM3IVARBPROC __rglgen_glUniform3ivARB; extern RGLSYMGLUNIFORM4IVARBPROC __rglgen_glUniform4ivARB; extern RGLSYMGLUNIFORMMATRIX2FVARBPROC __rglgen_glUniformMatrix2fvARB; extern RGLSYMGLUNIFORMMATRIX3FVARBPROC __rglgen_glUniformMatrix3fvARB; extern RGLSYMGLUNIFORMMATRIX4FVARBPROC __rglgen_glUniformMatrix4fvARB; extern RGLSYMGLGETOBJECTPARAMETERFVARBPROC __rglgen_glGetObjectParameterfvARB; extern RGLSYMGLGETOBJECTPARAMETERIVARBPROC __rglgen_glGetObjectParameterivARB; extern RGLSYMGLGETINFOLOGARBPROC __rglgen_glGetInfoLogARB; extern RGLSYMGLGETATTACHEDOBJECTSARBPROC __rglgen_glGetAttachedObjectsARB; extern RGLSYMGLGETUNIFORMLOCATIONARBPROC __rglgen_glGetUniformLocationARB; extern RGLSYMGLGETACTIVEUNIFORMARBPROC __rglgen_glGetActiveUniformARB; extern RGLSYMGLGETUNIFORMFVARBPROC __rglgen_glGetUniformfvARB; extern RGLSYMGLGETUNIFORMIVARBPROC __rglgen_glGetUniformivARB; extern RGLSYMGLGETSHADERSOURCEARBPROC __rglgen_glGetShaderSourceARB; extern RGLSYMGLNAMEDSTRINGARBPROC __rglgen_glNamedStringARB; extern RGLSYMGLDELETENAMEDSTRINGARBPROC __rglgen_glDeleteNamedStringARB; extern RGLSYMGLCOMPILESHADERINCLUDEARBPROC __rglgen_glCompileShaderIncludeARB; extern RGLSYMGLISNAMEDSTRINGARBPROC __rglgen_glIsNamedStringARB; extern RGLSYMGLGETNAMEDSTRINGARBPROC __rglgen_glGetNamedStringARB; extern RGLSYMGLGETNAMEDSTRINGIVARBPROC __rglgen_glGetNamedStringivARB; extern RGLSYMGLTEXPAGECOMMITMENTARBPROC __rglgen_glTexPageCommitmentARB; extern RGLSYMGLTEXBUFFERARBPROC __rglgen_glTexBufferARB; extern RGLSYMGLCOMPRESSEDTEXIMAGE3DARBPROC __rglgen_glCompressedTexImage3DARB; extern RGLSYMGLCOMPRESSEDTEXIMAGE2DARBPROC __rglgen_glCompressedTexImage2DARB; extern RGLSYMGLCOMPRESSEDTEXIMAGE1DARBPROC __rglgen_glCompressedTexImage1DARB; extern RGLSYMGLCOMPRESSEDTEXSUBIMAGE3DARBPROC __rglgen_glCompressedTexSubImage3DARB; extern RGLSYMGLCOMPRESSEDTEXSUBIMAGE2DARBPROC __rglgen_glCompressedTexSubImage2DARB; extern RGLSYMGLCOMPRESSEDTEXSUBIMAGE1DARBPROC __rglgen_glCompressedTexSubImage1DARB; extern RGLSYMGLGETCOMPRESSEDTEXIMAGEARBPROC __rglgen_glGetCompressedTexImageARB; extern RGLSYMGLLOADTRANSPOSEMATRIXFARBPROC __rglgen_glLoadTransposeMatrixfARB; extern RGLSYMGLLOADTRANSPOSEMATRIXDARBPROC __rglgen_glLoadTransposeMatrixdARB; extern RGLSYMGLMULTTRANSPOSEMATRIXFARBPROC __rglgen_glMultTransposeMatrixfARB; extern RGLSYMGLMULTTRANSPOSEMATRIXDARBPROC __rglgen_glMultTransposeMatrixdARB; extern RGLSYMGLWEIGHTBVARBPROC __rglgen_glWeightbvARB; extern RGLSYMGLWEIGHTSVARBPROC __rglgen_glWeightsvARB; extern RGLSYMGLWEIGHTIVARBPROC __rglgen_glWeightivARB; extern RGLSYMGLWEIGHTFVARBPROC __rglgen_glWeightfvARB; extern RGLSYMGLWEIGHTDVARBPROC __rglgen_glWeightdvARB; extern RGLSYMGLWEIGHTUBVARBPROC __rglgen_glWeightubvARB; extern RGLSYMGLWEIGHTUSVARBPROC __rglgen_glWeightusvARB; extern RGLSYMGLWEIGHTUIVARBPROC __rglgen_glWeightuivARB; extern RGLSYMGLWEIGHTPOINTERARBPROC __rglgen_glWeightPointerARB; extern RGLSYMGLVERTEXBLENDARBPROC __rglgen_glVertexBlendARB; extern RGLSYMGLBINDBUFFERARBPROC __rglgen_glBindBufferARB; extern RGLSYMGLDELETEBUFFERSARBPROC __rglgen_glDeleteBuffersARB; extern RGLSYMGLGENBUFFERSARBPROC __rglgen_glGenBuffersARB; extern RGLSYMGLISBUFFERARBPROC __rglgen_glIsBufferARB; extern RGLSYMGLBUFFERDATAARBPROC __rglgen_glBufferDataARB; extern RGLSYMGLBUFFERSUBDATAARBPROC __rglgen_glBufferSubDataARB; extern RGLSYMGLGETBUFFERSUBDATAARBPROC __rglgen_glGetBufferSubDataARB; extern RGLSYMGLMAPBUFFERARBPROC __rglgen_glMapBufferARB; extern RGLSYMGLUNMAPBUFFERARBPROC __rglgen_glUnmapBufferARB; extern RGLSYMGLGETBUFFERPARAMETERIVARBPROC __rglgen_glGetBufferParameterivARB; extern RGLSYMGLGETBUFFERPOINTERVARBPROC __rglgen_glGetBufferPointervARB; extern RGLSYMGLVERTEXATTRIB1DARBPROC __rglgen_glVertexAttrib1dARB; extern RGLSYMGLVERTEXATTRIB1DVARBPROC __rglgen_glVertexAttrib1dvARB; extern RGLSYMGLVERTEXATTRIB1FARBPROC __rglgen_glVertexAttrib1fARB; extern RGLSYMGLVERTEXATTRIB1FVARBPROC __rglgen_glVertexAttrib1fvARB; extern RGLSYMGLVERTEXATTRIB1SARBPROC __rglgen_glVertexAttrib1sARB; extern RGLSYMGLVERTEXATTRIB1SVARBPROC __rglgen_glVertexAttrib1svARB; extern RGLSYMGLVERTEXATTRIB2DARBPROC __rglgen_glVertexAttrib2dARB; extern RGLSYMGLVERTEXATTRIB2DVARBPROC __rglgen_glVertexAttrib2dvARB; extern RGLSYMGLVERTEXATTRIB2FARBPROC __rglgen_glVertexAttrib2fARB; extern RGLSYMGLVERTEXATTRIB2FVARBPROC __rglgen_glVertexAttrib2fvARB; extern RGLSYMGLVERTEXATTRIB2SARBPROC __rglgen_glVertexAttrib2sARB; extern RGLSYMGLVERTEXATTRIB2SVARBPROC __rglgen_glVertexAttrib2svARB; extern RGLSYMGLVERTEXATTRIB3DARBPROC __rglgen_glVertexAttrib3dARB; extern RGLSYMGLVERTEXATTRIB3DVARBPROC __rglgen_glVertexAttrib3dvARB; extern RGLSYMGLVERTEXATTRIB3FARBPROC __rglgen_glVertexAttrib3fARB; extern RGLSYMGLVERTEXATTRIB3FVARBPROC __rglgen_glVertexAttrib3fvARB; extern RGLSYMGLVERTEXATTRIB3SARBPROC __rglgen_glVertexAttrib3sARB; extern RGLSYMGLVERTEXATTRIB3SVARBPROC __rglgen_glVertexAttrib3svARB; extern RGLSYMGLVERTEXATTRIB4NBVARBPROC __rglgen_glVertexAttrib4NbvARB; extern RGLSYMGLVERTEXATTRIB4NIVARBPROC __rglgen_glVertexAttrib4NivARB; extern RGLSYMGLVERTEXATTRIB4NSVARBPROC __rglgen_glVertexAttrib4NsvARB; extern RGLSYMGLVERTEXATTRIB4NUBARBPROC __rglgen_glVertexAttrib4NubARB; extern RGLSYMGLVERTEXATTRIB4NUBVARBPROC __rglgen_glVertexAttrib4NubvARB; extern RGLSYMGLVERTEXATTRIB4NUIVARBPROC __rglgen_glVertexAttrib4NuivARB; extern RGLSYMGLVERTEXATTRIB4NUSVARBPROC __rglgen_glVertexAttrib4NusvARB; extern RGLSYMGLVERTEXATTRIB4BVARBPROC __rglgen_glVertexAttrib4bvARB; extern RGLSYMGLVERTEXATTRIB4DARBPROC __rglgen_glVertexAttrib4dARB; extern RGLSYMGLVERTEXATTRIB4DVARBPROC __rglgen_glVertexAttrib4dvARB; extern RGLSYMGLVERTEXATTRIB4FARBPROC __rglgen_glVertexAttrib4fARB; extern RGLSYMGLVERTEXATTRIB4FVARBPROC __rglgen_glVertexAttrib4fvARB; extern RGLSYMGLVERTEXATTRIB4IVARBPROC __rglgen_glVertexAttrib4ivARB; extern RGLSYMGLVERTEXATTRIB4SARBPROC __rglgen_glVertexAttrib4sARB; extern RGLSYMGLVERTEXATTRIB4SVARBPROC __rglgen_glVertexAttrib4svARB; extern RGLSYMGLVERTEXATTRIB4UBVARBPROC __rglgen_glVertexAttrib4ubvARB; extern RGLSYMGLVERTEXATTRIB4UIVARBPROC __rglgen_glVertexAttrib4uivARB; extern RGLSYMGLVERTEXATTRIB4USVARBPROC __rglgen_glVertexAttrib4usvARB; extern RGLSYMGLVERTEXATTRIBPOINTERARBPROC __rglgen_glVertexAttribPointerARB; extern RGLSYMGLENABLEVERTEXATTRIBARRAYARBPROC __rglgen_glEnableVertexAttribArrayARB; extern RGLSYMGLDISABLEVERTEXATTRIBARRAYARBPROC __rglgen_glDisableVertexAttribArrayARB; extern RGLSYMGLGETVERTEXATTRIBDVARBPROC __rglgen_glGetVertexAttribdvARB; extern RGLSYMGLGETVERTEXATTRIBFVARBPROC __rglgen_glGetVertexAttribfvARB; extern RGLSYMGLGETVERTEXATTRIBIVARBPROC __rglgen_glGetVertexAttribivARB; extern RGLSYMGLGETVERTEXATTRIBPOINTERVARBPROC __rglgen_glGetVertexAttribPointervARB; extern RGLSYMGLBINDATTRIBLOCATIONARBPROC __rglgen_glBindAttribLocationARB; extern RGLSYMGLGETACTIVEATTRIBARBPROC __rglgen_glGetActiveAttribARB; extern RGLSYMGLGETATTRIBLOCATIONARBPROC __rglgen_glGetAttribLocationARB; extern RGLSYMGLWINDOWPOS2DARBPROC __rglgen_glWindowPos2dARB; extern RGLSYMGLWINDOWPOS2DVARBPROC __rglgen_glWindowPos2dvARB; extern RGLSYMGLWINDOWPOS2FARBPROC __rglgen_glWindowPos2fARB; extern RGLSYMGLWINDOWPOS2FVARBPROC __rglgen_glWindowPos2fvARB; extern RGLSYMGLWINDOWPOS2IARBPROC __rglgen_glWindowPos2iARB; extern RGLSYMGLWINDOWPOS2IVARBPROC __rglgen_glWindowPos2ivARB; extern RGLSYMGLWINDOWPOS2SARBPROC __rglgen_glWindowPos2sARB; extern RGLSYMGLWINDOWPOS2SVARBPROC __rglgen_glWindowPos2svARB; extern RGLSYMGLWINDOWPOS3DARBPROC __rglgen_glWindowPos3dARB; extern RGLSYMGLWINDOWPOS3DVARBPROC __rglgen_glWindowPos3dvARB; extern RGLSYMGLWINDOWPOS3FARBPROC __rglgen_glWindowPos3fARB; extern RGLSYMGLWINDOWPOS3FVARBPROC __rglgen_glWindowPos3fvARB; extern RGLSYMGLWINDOWPOS3IARBPROC __rglgen_glWindowPos3iARB; extern RGLSYMGLWINDOWPOS3IVARBPROC __rglgen_glWindowPos3ivARB; extern RGLSYMGLWINDOWPOS3SARBPROC __rglgen_glWindowPos3sARB; extern RGLSYMGLWINDOWPOS3SVARBPROC __rglgen_glWindowPos3svARB; extern RGLSYMGLMULTITEXCOORD1BOESPROC __rglgen_glMultiTexCoord1bOES; extern RGLSYMGLMULTITEXCOORD1BVOESPROC __rglgen_glMultiTexCoord1bvOES; extern RGLSYMGLMULTITEXCOORD2BOESPROC __rglgen_glMultiTexCoord2bOES; extern RGLSYMGLMULTITEXCOORD2BVOESPROC __rglgen_glMultiTexCoord2bvOES; extern RGLSYMGLMULTITEXCOORD3BOESPROC __rglgen_glMultiTexCoord3bOES; extern RGLSYMGLMULTITEXCOORD3BVOESPROC __rglgen_glMultiTexCoord3bvOES; extern RGLSYMGLMULTITEXCOORD4BOESPROC __rglgen_glMultiTexCoord4bOES; extern RGLSYMGLMULTITEXCOORD4BVOESPROC __rglgen_glMultiTexCoord4bvOES; extern RGLSYMGLTEXCOORD1BOESPROC __rglgen_glTexCoord1bOES; extern RGLSYMGLTEXCOORD1BVOESPROC __rglgen_glTexCoord1bvOES; extern RGLSYMGLTEXCOORD2BOESPROC __rglgen_glTexCoord2bOES; extern RGLSYMGLTEXCOORD2BVOESPROC __rglgen_glTexCoord2bvOES; extern RGLSYMGLTEXCOORD3BOESPROC __rglgen_glTexCoord3bOES; extern RGLSYMGLTEXCOORD3BVOESPROC __rglgen_glTexCoord3bvOES; extern RGLSYMGLTEXCOORD4BOESPROC __rglgen_glTexCoord4bOES; extern RGLSYMGLTEXCOORD4BVOESPROC __rglgen_glTexCoord4bvOES; extern RGLSYMGLVERTEX2BOESPROC __rglgen_glVertex2bOES; extern RGLSYMGLVERTEX2BVOESPROC __rglgen_glVertex2bvOES; extern RGLSYMGLVERTEX3BOESPROC __rglgen_glVertex3bOES; extern RGLSYMGLVERTEX3BVOESPROC __rglgen_glVertex3bvOES; extern RGLSYMGLVERTEX4BOESPROC __rglgen_glVertex4bOES; extern RGLSYMGLVERTEX4BVOESPROC __rglgen_glVertex4bvOES; extern RGLSYMGLALPHAFUNCXOESPROC __rglgen_glAlphaFuncxOES; extern RGLSYMGLCLEARCOLORXOESPROC __rglgen_glClearColorxOES; extern RGLSYMGLCLEARDEPTHXOESPROC __rglgen_glClearDepthxOES; extern RGLSYMGLCLIPPLANEXOESPROC __rglgen_glClipPlanexOES; extern RGLSYMGLCOLOR4XOESPROC __rglgen_glColor4xOES; extern RGLSYMGLDEPTHRANGEXOESPROC __rglgen_glDepthRangexOES; extern RGLSYMGLFOGXOESPROC __rglgen_glFogxOES; extern RGLSYMGLFOGXVOESPROC __rglgen_glFogxvOES; extern RGLSYMGLFRUSTUMXOESPROC __rglgen_glFrustumxOES; extern RGLSYMGLGETCLIPPLANEXOESPROC __rglgen_glGetClipPlanexOES; extern RGLSYMGLGETFIXEDVOESPROC __rglgen_glGetFixedvOES; extern RGLSYMGLGETTEXENVXVOESPROC __rglgen_glGetTexEnvxvOES; extern RGLSYMGLGETTEXPARAMETERXVOESPROC __rglgen_glGetTexParameterxvOES; extern RGLSYMGLLIGHTMODELXOESPROC __rglgen_glLightModelxOES; extern RGLSYMGLLIGHTMODELXVOESPROC __rglgen_glLightModelxvOES; extern RGLSYMGLLIGHTXOESPROC __rglgen_glLightxOES; extern RGLSYMGLLIGHTXVOESPROC __rglgen_glLightxvOES; extern RGLSYMGLLINEWIDTHXOESPROC __rglgen_glLineWidthxOES; extern RGLSYMGLLOADMATRIXXOESPROC __rglgen_glLoadMatrixxOES; extern RGLSYMGLMATERIALXOESPROC __rglgen_glMaterialxOES; extern RGLSYMGLMATERIALXVOESPROC __rglgen_glMaterialxvOES; extern RGLSYMGLMULTMATRIXXOESPROC __rglgen_glMultMatrixxOES; extern RGLSYMGLMULTITEXCOORD4XOESPROC __rglgen_glMultiTexCoord4xOES; extern RGLSYMGLNORMAL3XOESPROC __rglgen_glNormal3xOES; extern RGLSYMGLORTHOXOESPROC __rglgen_glOrthoxOES; extern RGLSYMGLPOINTPARAMETERXVOESPROC __rglgen_glPointParameterxvOES; extern RGLSYMGLPOINTSIZEXOESPROC __rglgen_glPointSizexOES; extern RGLSYMGLPOLYGONOFFSETXOESPROC __rglgen_glPolygonOffsetxOES; extern RGLSYMGLROTATEXOESPROC __rglgen_glRotatexOES; extern RGLSYMGLSAMPLECOVERAGEOESPROC __rglgen_glSampleCoverageOES; extern RGLSYMGLSCALEXOESPROC __rglgen_glScalexOES; extern RGLSYMGLTEXENVXOESPROC __rglgen_glTexEnvxOES; extern RGLSYMGLTEXENVXVOESPROC __rglgen_glTexEnvxvOES; extern RGLSYMGLTEXPARAMETERXOESPROC __rglgen_glTexParameterxOES; extern RGLSYMGLTEXPARAMETERXVOESPROC __rglgen_glTexParameterxvOES; extern RGLSYMGLTRANSLATEXOESPROC __rglgen_glTranslatexOES; extern RGLSYMGLACCUMXOESPROC __rglgen_glAccumxOES; extern RGLSYMGLBITMAPXOESPROC __rglgen_glBitmapxOES; extern RGLSYMGLBLENDCOLORXOESPROC __rglgen_glBlendColorxOES; extern RGLSYMGLCLEARACCUMXOESPROC __rglgen_glClearAccumxOES; extern RGLSYMGLCOLOR3XOESPROC __rglgen_glColor3xOES; extern RGLSYMGLCOLOR3XVOESPROC __rglgen_glColor3xvOES; extern RGLSYMGLCOLOR4XVOESPROC __rglgen_glColor4xvOES; extern RGLSYMGLCONVOLUTIONPARAMETERXOESPROC __rglgen_glConvolutionParameterxOES; extern RGLSYMGLCONVOLUTIONPARAMETERXVOESPROC __rglgen_glConvolutionParameterxvOES; extern RGLSYMGLEVALCOORD1XOESPROC __rglgen_glEvalCoord1xOES; extern RGLSYMGLEVALCOORD1XVOESPROC __rglgen_glEvalCoord1xvOES; extern RGLSYMGLEVALCOORD2XOESPROC __rglgen_glEvalCoord2xOES; extern RGLSYMGLEVALCOORD2XVOESPROC __rglgen_glEvalCoord2xvOES; extern RGLSYMGLFEEDBACKBUFFERXOESPROC __rglgen_glFeedbackBufferxOES; extern RGLSYMGLGETCONVOLUTIONPARAMETERXVOESPROC __rglgen_glGetConvolutionParameterxvOES; extern RGLSYMGLGETHISTOGRAMPARAMETERXVOESPROC __rglgen_glGetHistogramParameterxvOES; extern RGLSYMGLGETLIGHTXOESPROC __rglgen_glGetLightxOES; extern RGLSYMGLGETMAPXVOESPROC __rglgen_glGetMapxvOES; extern RGLSYMGLGETMATERIALXOESPROC __rglgen_glGetMaterialxOES; extern RGLSYMGLGETPIXELMAPXVPROC __rglgen_glGetPixelMapxv; extern RGLSYMGLGETTEXGENXVOESPROC __rglgen_glGetTexGenxvOES; extern RGLSYMGLGETTEXLEVELPARAMETERXVOESPROC __rglgen_glGetTexLevelParameterxvOES; extern RGLSYMGLINDEXXOESPROC __rglgen_glIndexxOES; extern RGLSYMGLINDEXXVOESPROC __rglgen_glIndexxvOES; extern RGLSYMGLLOADTRANSPOSEMATRIXXOESPROC __rglgen_glLoadTransposeMatrixxOES; extern RGLSYMGLMAP1XOESPROC __rglgen_glMap1xOES; extern RGLSYMGLMAP2XOESPROC __rglgen_glMap2xOES; extern RGLSYMGLMAPGRID1XOESPROC __rglgen_glMapGrid1xOES; extern RGLSYMGLMAPGRID2XOESPROC __rglgen_glMapGrid2xOES; extern RGLSYMGLMULTTRANSPOSEMATRIXXOESPROC __rglgen_glMultTransposeMatrixxOES; extern RGLSYMGLMULTITEXCOORD1XOESPROC __rglgen_glMultiTexCoord1xOES; extern RGLSYMGLMULTITEXCOORD1XVOESPROC __rglgen_glMultiTexCoord1xvOES; extern RGLSYMGLMULTITEXCOORD2XOESPROC __rglgen_glMultiTexCoord2xOES; extern RGLSYMGLMULTITEXCOORD2XVOESPROC __rglgen_glMultiTexCoord2xvOES; extern RGLSYMGLMULTITEXCOORD3XOESPROC __rglgen_glMultiTexCoord3xOES; extern RGLSYMGLMULTITEXCOORD3XVOESPROC __rglgen_glMultiTexCoord3xvOES; extern RGLSYMGLMULTITEXCOORD4XVOESPROC __rglgen_glMultiTexCoord4xvOES; extern RGLSYMGLNORMAL3XVOESPROC __rglgen_glNormal3xvOES; extern RGLSYMGLPASSTHROUGHXOESPROC __rglgen_glPassThroughxOES; extern RGLSYMGLPIXELMAPXPROC __rglgen_glPixelMapx; extern RGLSYMGLPIXELSTOREXPROC __rglgen_glPixelStorex; extern RGLSYMGLPIXELTRANSFERXOESPROC __rglgen_glPixelTransferxOES; extern RGLSYMGLPIXELZOOMXOESPROC __rglgen_glPixelZoomxOES; extern RGLSYMGLPRIORITIZETEXTURESXOESPROC __rglgen_glPrioritizeTexturesxOES; extern RGLSYMGLRASTERPOS2XOESPROC __rglgen_glRasterPos2xOES; extern RGLSYMGLRASTERPOS2XVOESPROC __rglgen_glRasterPos2xvOES; extern RGLSYMGLRASTERPOS3XOESPROC __rglgen_glRasterPos3xOES; extern RGLSYMGLRASTERPOS3XVOESPROC __rglgen_glRasterPos3xvOES; extern RGLSYMGLRASTERPOS4XOESPROC __rglgen_glRasterPos4xOES; extern RGLSYMGLRASTERPOS4XVOESPROC __rglgen_glRasterPos4xvOES; extern RGLSYMGLRECTXOESPROC __rglgen_glRectxOES; extern RGLSYMGLRECTXVOESPROC __rglgen_glRectxvOES; extern RGLSYMGLTEXCOORD1XOESPROC __rglgen_glTexCoord1xOES; extern RGLSYMGLTEXCOORD1XVOESPROC __rglgen_glTexCoord1xvOES; extern RGLSYMGLTEXCOORD2XOESPROC __rglgen_glTexCoord2xOES; extern RGLSYMGLTEXCOORD2XVOESPROC __rglgen_glTexCoord2xvOES; extern RGLSYMGLTEXCOORD3XOESPROC __rglgen_glTexCoord3xOES; extern RGLSYMGLTEXCOORD3XVOESPROC __rglgen_glTexCoord3xvOES; extern RGLSYMGLTEXCOORD4XOESPROC __rglgen_glTexCoord4xOES; extern RGLSYMGLTEXCOORD4XVOESPROC __rglgen_glTexCoord4xvOES; extern RGLSYMGLTEXGENXOESPROC __rglgen_glTexGenxOES; extern RGLSYMGLTEXGENXVOESPROC __rglgen_glTexGenxvOES; extern RGLSYMGLVERTEX2XOESPROC __rglgen_glVertex2xOES; extern RGLSYMGLVERTEX2XVOESPROC __rglgen_glVertex2xvOES; extern RGLSYMGLVERTEX3XOESPROC __rglgen_glVertex3xOES; extern RGLSYMGLVERTEX3XVOESPROC __rglgen_glVertex3xvOES; extern RGLSYMGLVERTEX4XOESPROC __rglgen_glVertex4xOES; extern RGLSYMGLVERTEX4XVOESPROC __rglgen_glVertex4xvOES; extern RGLSYMGLQUERYMATRIXXOESPROC __rglgen_glQueryMatrixxOES; extern RGLSYMGLCLEARDEPTHFOESPROC __rglgen_glClearDepthfOES; extern RGLSYMGLCLIPPLANEFOESPROC __rglgen_glClipPlanefOES; extern RGLSYMGLDEPTHRANGEFOESPROC __rglgen_glDepthRangefOES; extern RGLSYMGLFRUSTUMFOESPROC __rglgen_glFrustumfOES; extern RGLSYMGLGETCLIPPLANEFOESPROC __rglgen_glGetClipPlanefOES; extern RGLSYMGLORTHOFOESPROC __rglgen_glOrthofOES; extern RGLSYMGLIMAGETRANSFORMPARAMETERIHPPROC __rglgen_glImageTransformParameteriHP; extern RGLSYMGLIMAGETRANSFORMPARAMETERFHPPROC __rglgen_glImageTransformParameterfHP; extern RGLSYMGLIMAGETRANSFORMPARAMETERIVHPPROC __rglgen_glImageTransformParameterivHP; extern RGLSYMGLIMAGETRANSFORMPARAMETERFVHPPROC __rglgen_glImageTransformParameterfvHP; extern RGLSYMGLGETIMAGETRANSFORMPARAMETERIVHPPROC __rglgen_glGetImageTransformParameterivHP; extern RGLSYMGLGETIMAGETRANSFORMPARAMETERFVHPPROC __rglgen_glGetImageTransformParameterfvHP; struct rglgen_sym_map { const char *sym; void *ptr; }; extern const struct rglgen_sym_map rglgen_symbol_map[]; #ifdef __cplusplus } #endif #endif mupen64plus-core/src/plugin/emulate_game_controller_via_input_plugin.c000664 001750 001750 00000004631 12655644434 027630 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - emulate_game_controller_via_input_plugin.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "emulate_game_controller_via_input_plugin.h" #include "plugin.h" #include "api/m64p_plugin.h" #include "si/game_controller.h" int egcvip_is_connected(void* opaque, enum pak_type* pak) { int channel = *(int*)opaque; CONTROL* c = &Controls[channel]; switch(c->Plugin) { case PLUGIN_NONE: *pak = PAK_NONE; break; case PLUGIN_MEMPAK: *pak = PAK_MEM; break; case PLUGIN_RUMBLE_PAK: *pak = PAK_RUMBLE; break; case PLUGIN_TRANSFER_PAK: *pak = PAK_TRANSFER; break; case PLUGIN_RAW: /* historically PLUGIN_RAW has been mostly (exclusively ?) used for rumble, * so we just reproduce that behavior */ *pak = PAK_RUMBLE; break; } return c->Present; } uint32_t egcvip_get_input(void* opaque) { BUTTONS keys = { 0 }; int channel = *(int*)opaque; if (input.getKeys) input.getKeys(channel, &keys); return keys.Value; } gles2rice/src/OGLTexture.h000664 001750 001750 00000002227 12655644434 016543 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _OGL_TEXTURE_H_ #define _OGL_TEXTURE_H_ #include "osal_opengl.h" #include "TextureManager.h" class COGLTexture : public CTexture { friend class COGLRenderTexture; public: ~COGLTexture(); bool StartUpdate(DrawInfo *di); void EndUpdate(DrawInfo *di); GLuint m_dwTextureName; GLuint m_glFmt; protected: friend class OGLDeviceBuilder; COGLTexture(uint32_t dwWidth, uint32_t dwHeight, TextureUsage usage); }; #endif mupen64plus-core/doc/lgpl-license000664 001750 001750 00000063505 12655644434 020126 0ustar00sergiosergio000000 000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! mupen64plus-video-gliden64/src/GLideNHQ/TextureFilters_hq2x.cpp000664 001750 001750 00000115273 12655644434 025431 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Copyright (C) 2007 Hiroshi Morii * Modified for the Texture Filtering library */ /* 2007 Mudlord - Added hq2xS lq2xS filters */ #include "TextureFilters.h" /************************************************************************/ /* hq2x filters */ /************************************************************************/ /***************************************************************************/ /* Basic types */ /***************************************************************************/ /* interpolation */ //static unsigned interp_bits_per_pixel; #if !_16BPP_HACK #define INTERP_16_MASK_1_3(v) ((v)&0x0F0F) #define INTERP_16_MASK_SHIFT_2_4(v) (((v)&0xF0F0)>>4) #define INTERP_16_MASK_SHIFTBACK_2_4(v) ((INTERP_16_MASK_1_3(v))<<4) static uint16 hq2x_interp_16_521(uint16 p1, uint16 p2, uint16 p3) { return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*5 + INTERP_16_MASK_1_3(p2)*2 + INTERP_16_MASK_1_3(p3)*1) / 8) | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*5 + INTERP_16_MASK_SHIFT_2_4(p2)*2 + INTERP_16_MASK_SHIFT_2_4(p3)*1) / 8); } static uint16 hq2x_interp_16_332(uint16 p1, uint16 p2, uint16 p3) { return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*3 + INTERP_16_MASK_1_3(p2)*3 + INTERP_16_MASK_1_3(p3)*2) / 8) | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*3 + INTERP_16_MASK_SHIFT_2_4(p2)*3 + INTERP_16_MASK_SHIFT_2_4(p3)*2) / 8); } static uint16 hq2x_interp_16_611(uint16 p1, uint16 p2, uint16 p3) { return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*6 + INTERP_16_MASK_1_3(p2) + INTERP_16_MASK_1_3(p3)) / 8) | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*6 + INTERP_16_MASK_SHIFT_2_4(p2) + INTERP_16_MASK_SHIFT_2_4(p3)) / 8); } static uint16 hq2x_interp_16_71(uint16 p1, uint16 p2) { return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*7 + INTERP_16_MASK_1_3(p2)) / 8) | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*7 + INTERP_16_MASK_SHIFT_2_4(p2)) / 8); } static uint16 hq2x_interp_16_211(uint16 p1, uint16 p2, uint16 p3) { return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*2 + INTERP_16_MASK_1_3(p2) + INTERP_16_MASK_1_3(p3)) / 4) | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*2 + INTERP_16_MASK_SHIFT_2_4(p2) + INTERP_16_MASK_SHIFT_2_4(p3)) / 4); } static uint16 hq2x_interp_16_772(uint16 p1, uint16 p2, uint16 p3) { return INTERP_16_MASK_1_3(((INTERP_16_MASK_1_3(p1) + INTERP_16_MASK_1_3(p2))*7 + INTERP_16_MASK_1_3(p3)*2) / 16) | INTERP_16_MASK_SHIFTBACK_2_4(((INTERP_16_MASK_SHIFT_2_4(p1) + INTERP_16_MASK_SHIFT_2_4(p2))*7 + INTERP_16_MASK_SHIFT_2_4(p3)*2) / 16); } static uint16 hq2x_interp_16_11(uint16 p1, uint16 p2) { return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1) + INTERP_16_MASK_1_3(p2)) / 2) | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1) + INTERP_16_MASK_SHIFT_2_4(p2)) / 2); } static uint16 hq2x_interp_16_31(uint16 p1, uint16 p2) { return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*3 + INTERP_16_MASK_1_3(p2)) / 4) | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*3 + INTERP_16_MASK_SHIFT_2_4(p2)) / 4); } static uint16 hq2x_interp_16_1411(uint16 p1, uint16 p2, uint16 p3) { return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*14 + INTERP_16_MASK_1_3(p2) + INTERP_16_MASK_1_3(p3)) / 16) | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*14 + INTERP_16_MASK_SHIFT_2_4(p2) + INTERP_16_MASK_SHIFT_2_4(p3)) / 16); } static uint16 hq2x_interp_16_431(uint16 p1, uint16 p2, uint16 p3) { return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*4 + INTERP_16_MASK_1_3(p2)*3 + INTERP_16_MASK_1_3(p3)) / 8) | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*4 + INTERP_16_MASK_SHIFT_2_4(p2)*3 + INTERP_16_MASK_SHIFT_2_4(p3)) / 8); } static uint16 hq2x_interp_16_53(uint16 p1, uint16 p2) { return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*5 + INTERP_16_MASK_1_3(p2)*3) / 8) | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*5 + INTERP_16_MASK_SHIFT_2_4(p2)*3) / 8); } static uint16 hq2x_interp_16_151(uint16 p1, uint16 p2) { return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*15 + INTERP_16_MASK_1_3(p2)) / 16) | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*15 + INTERP_16_MASK_SHIFT_2_4(p2)) / 16); } static uint16 hq2x_interp_16_97(uint16 p1, uint16 p2) { return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*9 + INTERP_16_MASK_1_3(p2)*7) / 16) | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*9 + INTERP_16_MASK_SHIFT_2_4(p2)*7) / 16); } #endif /* !_16BPP_HACK */ #define INTERP_32_MASK_1_3(v) ((v)&0x00FF00FF) #define INTERP_32_MASK_SHIFT_2_4(v) (((v)&0xFF00FF00)>>8) #define INTERP_32_MASK_SHIFTBACK_2_4(v) (((INTERP_32_MASK_1_3(v))<<8)) static uint32 hq2x_interp_32_521(uint32 p1, uint32 p2, uint32 p3) { return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*5 + INTERP_32_MASK_1_3(p2)*2 + INTERP_32_MASK_1_3(p3)*1) / 8) | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*5 + INTERP_32_MASK_SHIFT_2_4(p2)*2 + INTERP_32_MASK_SHIFT_2_4(p3)*1) / 8); } static uint32 hq2x_interp_32_332(uint32 p1, uint32 p2, uint32 p3) { return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*3 + INTERP_32_MASK_1_3(p2)*3 + INTERP_32_MASK_1_3(p3)*2) / 8) | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*3 + INTERP_32_MASK_SHIFT_2_4(p2)*3 + INTERP_32_MASK_SHIFT_2_4(p3)*2) / 8); } static uint32 hq2x_interp_32_211(uint32 p1, uint32 p2, uint32 p3) { return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*2 + INTERP_32_MASK_1_3(p2) + INTERP_32_MASK_1_3(p3)) / 4) | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*2 + INTERP_32_MASK_SHIFT_2_4(p2) + INTERP_32_MASK_SHIFT_2_4(p3)) / 4); } static uint32 hq2x_interp_32_611(uint32 p1, uint32 p2, uint32 p3) { return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*6 + INTERP_32_MASK_1_3(p2) + INTERP_32_MASK_1_3(p3)) / 8) | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*6 + INTERP_32_MASK_SHIFT_2_4(p2) + INTERP_32_MASK_SHIFT_2_4(p3)) / 8); } static uint32 hq2x_interp_32_71(uint32 p1, uint32 p2) { return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*7 + INTERP_32_MASK_1_3(p2)) / 8) | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*7 + INTERP_32_MASK_SHIFT_2_4(p2)) / 8); } static uint32 hq2x_interp_32_772(uint32 p1, uint32 p2, uint32 p3) { return INTERP_32_MASK_1_3(((INTERP_32_MASK_1_3(p1) + INTERP_32_MASK_1_3(p2))*7 + INTERP_32_MASK_1_3(p3)*2) / 16) | INTERP_32_MASK_SHIFTBACK_2_4(((INTERP_32_MASK_SHIFT_2_4(p1) + INTERP_32_MASK_SHIFT_2_4(p2))*7 + INTERP_32_MASK_SHIFT_2_4(p3)*2) / 16); } static uint32 hq2x_interp_32_11(uint32 p1, uint32 p2) { return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1) + INTERP_32_MASK_1_3(p2)) / 2) | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1) + INTERP_32_MASK_SHIFT_2_4(p2)) / 2); } static uint32 hq2x_interp_32_31(uint32 p1, uint32 p2) { return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*3 + INTERP_32_MASK_1_3(p2)) / 4) | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*3 + INTERP_32_MASK_SHIFT_2_4(p2)) / 4); } static uint32 hq2x_interp_32_1411(uint32 p1, uint32 p2, uint32 p3) { return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*14 + INTERP_32_MASK_1_3(p2) + INTERP_32_MASK_1_3(p3)) / 16) | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*14 + INTERP_32_MASK_SHIFT_2_4(p2) + INTERP_32_MASK_SHIFT_2_4(p3)) / 16); } static uint32 hq2x_interp_32_431(uint32 p1, uint32 p2, uint32 p3) { return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*4 + INTERP_32_MASK_1_3(p2)*3 + INTERP_32_MASK_1_3(p3)) / 8) | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*4 + INTERP_32_MASK_SHIFT_2_4(p2)*3 + INTERP_32_MASK_SHIFT_2_4(p3)) / 8); } static uint32 hq2x_interp_32_53(uint32 p1, uint32 p2) { return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*5 + INTERP_32_MASK_1_3(p2)*3) / 8) | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*5 + INTERP_32_MASK_SHIFT_2_4(p2)*3) / 8); } static uint32 hq2x_interp_32_151(uint32 p1, uint32 p2) { return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*15 + INTERP_32_MASK_1_3(p2)) / 16) | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*15 + INTERP_32_MASK_SHIFT_2_4(p2)) / 16); } static uint32 hq2x_interp_32_97(uint32 p1, uint32 p2) { return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*9 + INTERP_32_MASK_1_3(p2)*7) / 16) | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*9 + INTERP_32_MASK_SHIFT_2_4(p2)*7) / 16); } /***************************************************************************/ /* diff */ #define INTERP_Y_LIMIT (0x30*4) #define INTERP_U_LIMIT (0x07*4) #define INTERP_V_LIMIT (0x06*8) #if !_16BPP_HACK static int hq2x_interp_16_diff(uint16 p1, uint16 p2) { int r, g, b; int y, u, v; if (p1 == p2) return 0; r = (int)((p1 & 0x000F) - (p2 & 0x000F)); g = (int)((p1 & 0x00F0) - (p2 & 0x00F0)) >> 4; b = (int)((p1 & 0x0F00) - (p2 & 0x0F00)) >> 8; y = r + g + b; u = r - b; v = -r + 2*g - b; if (y < -INTERP_Y_LIMIT || y > INTERP_Y_LIMIT) return 1; if (u < -INTERP_U_LIMIT || u > INTERP_U_LIMIT) return 1; if (v < -INTERP_V_LIMIT || v > INTERP_V_LIMIT) return 1; return 0; } #endif /* !_16BPP_HACK */ static int hq2x_interp_32_diff(uint32 p1, uint32 p2) { int r, g, b; int y, u, v; if ((p1 & 0xF8F8F8) == (p2 & 0xF8F8F8)) return 0; r = (int)((p1 & 0xFF) - (p2 & 0xFF)); g = (int)((p1 & 0xFF00) - (p2 & 0xFF00)) >> 8; b = (int)((p1 & 0xFF0000) - (p2 & 0xFF0000)) >> 16; y = r + g + b; u = r - b; v = -r + 2*g - b; if (y < -INTERP_Y_LIMIT || y > INTERP_Y_LIMIT) return 1; if (u < -INTERP_U_LIMIT || u > INTERP_U_LIMIT) return 1; if (v < -INTERP_V_LIMIT || v > INTERP_V_LIMIT) return 1; return 0; } /*static void interp_set(unsigned bits_per_pixel) { interp_bits_per_pixel = bits_per_pixel; }*/ #if !_16BPP_HACK static void hq2x_16_def(uint16* dst0, uint16* dst1, const uint16* src0, const uint16* src1, const uint16* src2, unsigned count) { unsigned i; for(i=0;i0) { c[0] = src0[-1]; c[3] = src1[-1]; c[6] = src2[-1]; } else { c[0] = c[1]; c[3] = c[4]; c[6] = c[7]; } if (i0) { c[0] = src0[-1]; c[3] = src1[-1]; c[6] = src2[-1]; } else { c[0] = c[1]; c[3] = c[4]; c[6] = c[7]; } if (i> 3; r = (int)((c[j] & 0xF800)) >> 8; } else { b = (int)((c[j] & 0x1F)) << 3; g = (int)((c[j] & 0x3E0)) >> 2; r = (int)((c[j] & 0x7C00)) >> 7; } const int bright = r+r+r + g+g+g + b+b; if(bright > maxBright) maxBright = bright; if(bright < minBright) minBright = bright; brightArray[j] = bright; } int diffBright = ((maxBright - minBright) * 7) >> 4; if(diffBright > 7) { #define ABS(x) ((x) < 0 ? -(x) : (x)) const int centerBright = brightArray[4]; if(ABS(brightArray[0] - centerBright) > diffBright) mask |= 1 << 0; if(ABS(brightArray[1] - centerBright) > diffBright) mask |= 1 << 1; if(ABS(brightArray[2] - centerBright) > diffBright) mask |= 1 << 2; if(ABS(brightArray[3] - centerBright) > diffBright) mask |= 1 << 3; if(ABS(brightArray[5] - centerBright) > diffBright) mask |= 1 << 4; if(ABS(brightArray[6] - centerBright) > diffBright) mask |= 1 << 5; if(ABS(brightArray[7] - centerBright) > diffBright) mask |= 1 << 6; if(ABS(brightArray[8] - centerBright) > diffBright) mask |= 1 << 7; } #define P0 dst0[0] #define P1 dst0[1] #define P2 dst1[0] #define P3 dst1[1] #define HQ2X_MUR false #define HQ2X_MDR false #define HQ2X_MDL false #define HQ2X_MUL false #define IC(p0) c[p0] #define I11(p0,p1) hq2x_interp_16_11(c[p0], c[p1]) #define I211(p0,p1,p2) hq2x_interp_16_211(c[p0], c[p1], c[p2]) #define I31(p0,p1) hq2x_interp_16_31(c[p0], c[p1]) #define I332(p0,p1,p2) hq2x_interp_16_332(c[p0], c[p1], c[p2]) #define I431(p0,p1,p2) hq2x_interp_16_431(c[p0], c[p1], c[p2]) #define I521(p0,p1,p2) hq2x_interp_16_521(c[p0], c[p1], c[p2]) #define I53(p0,p1) hq2x_interp_16_53(c[p0], c[p1]) #define I611(p0,p1,p2) hq2x_interp_16_611(c[p0], c[p1], c[p2]) #define I71(p0,p1) hq2x_interp_16_71(c[p0], c[p1]) #define I772(p0,p1,p2) hq2x_interp_16_772(c[p0], c[p1], c[p2]) #define I97(p0,p1) hq2x_interp_16_97(c[p0], c[p1]) #define I1411(p0,p1,p2) hq2x_interp_16_1411(c[p0], c[p1], c[p2]) #define I151(p0,p1) hq2x_interp_16_151(c[p0], c[p1]) switch (mask) { #include "TextureFilters_hq2x.h" } #undef P0 #undef P1 #undef P2 #undef P3 #undef HQ2X_MUR #undef HQ2X_MDR #undef HQ2X_MDL #undef HQ2X_MUL #undef IC #undef I11 #undef I211 #undef I31 #undef I332 #undef I431 #undef I521 #undef I53 #undef I611 #undef I71 #undef I772 #undef I97 #undef I1411 #undef I151 src0 += 1; src1 += 1; src2 += 1; dst0 += 2; dst1 += 2; } } #endif /* !_16BPP_HACK */ static void hq2x_32_def(uint32* dst0, uint32* dst1, const uint32* src0, const uint32* src1, const uint32* src2, unsigned count) { unsigned i; for(i=0;i0) { c[0] = src0[-1]; c[3] = src1[-1]; c[6] = src2[-1]; } else { c[0] = src0[0]; c[3] = src1[0]; c[6] = src2[0]; } if (i0) { c[0] = src0[-1]; c[3] = src1[-1]; c[6] = src2[-1]; } else { c[0] = src0[0]; c[3] = src1[0]; c[6] = src2[0]; } if (i> 8; const int r = (int)((c[j] & 0xF80000)) >> 16; const int bright = r+r+r + g+g+g + b+b; if(bright > maxBright) maxBright = bright; if(bright < minBright) minBright = bright; brightArray[j] = bright; } int diffBright = ((maxBright - minBright) * 7) >> 4; if(diffBright > 7) { #define ABS(x) ((x) < 0 ? -(x) : (x)) const int centerBright = brightArray[4]; if(ABS(brightArray[0] - centerBright) > diffBright) mask |= 1 << 0; if(ABS(brightArray[1] - centerBright) > diffBright) mask |= 1 << 1; if(ABS(brightArray[2] - centerBright) > diffBright) mask |= 1 << 2; if(ABS(brightArray[3] - centerBright) > diffBright) mask |= 1 << 3; if(ABS(brightArray[5] - centerBright) > diffBright) mask |= 1 << 4; if(ABS(brightArray[6] - centerBright) > diffBright) mask |= 1 << 5; if(ABS(brightArray[7] - centerBright) > diffBright) mask |= 1 << 6; if(ABS(brightArray[8] - centerBright) > diffBright) mask |= 1 << 7; } #define P0 dst0[0] #define P1 dst0[1] #define P2 dst1[0] #define P3 dst1[1] #define HQ2X_MUR false #define HQ2X_MDR false #define HQ2X_MDL false #define HQ2X_MUL false #define IC(p0) c[p0] #define I11(p0,p1) hq2x_interp_32_11(c[p0], c[p1]) #define I211(p0,p1,p2) hq2x_interp_32_211(c[p0], c[p1], c[p2]) #define I31(p0,p1) hq2x_interp_32_31(c[p0], c[p1]) #define I332(p0,p1,p2) hq2x_interp_32_332(c[p0], c[p1], c[p2]) #define I431(p0,p1,p2) hq2x_interp_32_431(c[p0], c[p1], c[p2]) #define I521(p0,p1,p2) hq2x_interp_32_521(c[p0], c[p1], c[p2]) #define I53(p0,p1) hq2x_interp_32_53(c[p0], c[p1]) #define I611(p0,p1,p2) hq2x_interp_32_611(c[p0], c[p1], c[p2]) #define I71(p0,p1) hq2x_interp_32_71(c[p0], c[p1]) #define I772(p0,p1,p2) hq2x_interp_32_772(c[p0], c[p1], c[p2]) #define I97(p0,p1) hq2x_interp_32_97(c[p0], c[p1]) #define I1411(p0,p1,p2) hq2x_interp_32_1411(c[p0], c[p1], c[p2]) #define I151(p0,p1) hq2x_interp_32_151(c[p0], c[p1]) switch (mask) { #include "TextureFilters_hq2x.h" } #undef P0 #undef P1 #undef P2 #undef P3 #undef HQ2X_MUR #undef HQ2X_MDR #undef HQ2X_MDL #undef HQ2X_MUL #undef IC #undef I11 #undef I211 #undef I31 #undef I332 #undef I431 #undef I521 #undef I53 #undef I611 #undef I71 #undef I772 #undef I97 #undef I1411 #undef I151 src0 += 1; src1 += 1; src2 += 1; dst0 += 2; dst1 += 2; } } /***************************************************************************/ /* LQ2x C implementation */ /* * This effect is derived from the hq2x effect made by Maxim Stepin */ #if !_16BPP_HACK static void lq2x_16_def(uint16* dst0, uint16* dst1, const uint16* src0, const uint16* src1, const uint16* src2, unsigned count) { unsigned i; for(i=0;i0) { c[0] = src0[-1]; c[3] = src1[-1]; c[6] = src2[-1]; } else { c[0] = c[1]; c[3] = c[4]; c[6] = c[7]; } if (i0) { c[0] = src0[-1]; c[3] = src1[-1]; c[6] = src2[-1]; } else { c[0] = c[1]; c[3] = c[4]; c[6] = c[7]; } if (i> 8; const int r = (int)((c[j] & 0xF80000)) >> 16; const int bright = r+r+r + g+g+g + b+b; if(bright > maxBright) maxBright = bright; if(bright < minBright) minBright = bright; brightArray[j] = bright; } int diffBright = ((maxBright - minBright) * 7) >> 4; if(diffBright > 7) { #define ABS(x) ((x) < 0 ? -(x) : (x)) const int centerBright = brightArray[4]; if(ABS(brightArray[0] - centerBright) > diffBright) mask |= 1 << 0; if(ABS(brightArray[1] - centerBright) > diffBright) mask |= 1 << 1; if(ABS(brightArray[2] - centerBright) > diffBright) mask |= 1 << 2; if(ABS(brightArray[3] - centerBright) > diffBright) mask |= 1 << 3; if(ABS(brightArray[5] - centerBright) > diffBright) mask |= 1 << 4; if(ABS(brightArray[6] - centerBright) > diffBright) mask |= 1 << 5; if(ABS(brightArray[7] - centerBright) > diffBright) mask |= 1 << 6; if(ABS(brightArray[8] - centerBright) > diffBright) mask |= 1 << 7; } #define P0 dst0[0] #define P1 dst0[1] #define P2 dst1[0] #define P3 dst1[1] #define HQ2X_MUR false #define HQ2X_MDR false #define HQ2X_MDL false #define HQ2X_MUL false #define IC(p0) c[p0] #define I11(p0,p1) hq2x_interp_16_11(c[p0], c[p1]) #define I211(p0,p1,p2) hq2x_interp_16_211(c[p0], c[p1], c[p2]) #define I31(p0,p1) hq2x_interp_16_31(c[p0], c[p1]) #define I332(p0,p1,p2) hq2x_interp_16_332(c[p0], c[p1], c[p2]) #define I431(p0,p1,p2) hq2x_interp_16_431(c[p0], c[p1], c[p2]) #define I521(p0,p1,p2) hq2x_interp_16_521(c[p0], c[p1], c[p2]) #define I53(p0,p1) hq2x_interp_16_53(c[p0], c[p1]) #define I611(p0,p1,p2) hq2x_interp_16_611(c[p0], c[p1], c[p2]) #define I71(p0,p1) hq2x_interp_16_71(c[p0], c[p1]) #define I772(p0,p1,p2) hq2x_interp_16_772(c[p0], c[p1], c[p2]) #define I97(p0,p1) hq2x_interp_16_97(c[p0], c[p1]) #define I1411(p0,p1,p2) hq2x_interp_16_1411(c[p0], c[p1], c[p2]) #define I151(p0,p1) hq2x_interp_16_151(c[p0], c[p1]) switch (mask) { #include "TextureFilters_lq2x.h" } #undef P0 #undef P1 #undef P2 #undef P3 #undef HQ2X_MUR #undef HQ2X_MDR #undef HQ2X_MDL #undef HQ2X_MUL #undef IC #undef I11 #undef I211 #undef I31 #undef I332 #undef I431 #undef I521 #undef I53 #undef I611 #undef I71 #undef I772 #undef I97 #undef I1411 #undef I151 src0 += 1; src1 += 1; src2 += 1; dst0 += 2; dst1 += 2; } } #endif /* !_16BPP_HACK */ static void lq2x_32_def(uint32* dst0, uint32* dst1, const uint32* src0, const uint32* src1, const uint32* src2, unsigned count) { unsigned i; for(i=0;i0) { c[0] = src0[-1]; c[3] = src1[-1]; c[6] = src2[-1]; } else { c[0] = c[1]; c[3] = c[4]; c[6] = c[7]; } if (i0) { c[0] = src0[-1]; c[3] = src1[-1]; c[6] = src2[-1]; } else { c[0] = c[1]; c[3] = c[4]; c[6] = c[7]; } if (i> 8; const int r = (int)((c[j] & 0xF80000)) >> 16; const int bright = r+r+r + g+g+g + b+b; if(bright > maxBright) maxBright = bright; if(bright < minBright) minBright = bright; brightArray[j] = bright; } int diffBright = ((maxBright - minBright) * 7) >> 4; if(diffBright > 7) { #define ABS(x) ((x) < 0 ? -(x) : (x)) const int centerBright = brightArray[4]; if(ABS(brightArray[0] - centerBright) > diffBright) mask |= 1 << 0; if(ABS(brightArray[1] - centerBright) > diffBright) mask |= 1 << 1; if(ABS(brightArray[2] - centerBright) > diffBright) mask |= 1 << 2; if(ABS(brightArray[3] - centerBright) > diffBright) mask |= 1 << 3; if(ABS(brightArray[5] - centerBright) > diffBright) mask |= 1 << 4; if(ABS(brightArray[6] - centerBright) > diffBright) mask |= 1 << 5; if(ABS(brightArray[7] - centerBright) > diffBright) mask |= 1 << 6; if(ABS(brightArray[8] - centerBright) > diffBright) mask |= 1 << 7; } #define P0 dst0[0] #define P1 dst0[1] #define P2 dst1[0] #define P3 dst1[1] #define HQ2X_MUR false #define HQ2X_MDR false #define HQ2X_MDL false #define HQ2X_MUL false #define IC(p0) c[p0] #define I11(p0,p1) hq2x_interp_32_11(c[p0], c[p1]) #define I211(p0,p1,p2) hq2x_interp_32_211(c[p0], c[p1], c[p2]) #define I31(p0,p1) hq2x_interp_32_31(c[p0], c[p1]) #define I332(p0,p1,p2) hq2x_interp_32_332(c[p0], c[p1], c[p2]) #define I431(p0,p1,p2) hq2x_interp_32_431(c[p0], c[p1], c[p2]) #define I521(p0,p1,p2) hq2x_interp_32_521(c[p0], c[p1], c[p2]) #define I53(p0,p1) hq2x_interp_32_53(c[p0], c[p1]) #define I611(p0,p1,p2) hq2x_interp_32_611(c[p0], c[p1], c[p2]) #define I71(p0,p1) hq2x_interp_32_71(c[p0], c[p1]) #define I772(p0,p1,p2) hq2x_interp_32_772(c[p0], c[p1], c[p2]) #define I97(p0,p1) hq2x_interp_32_97(c[p0], c[p1]) #define I1411(p0,p1,p2) hq2x_interp_32_1411(c[p0], c[p1], c[p2]) #define I151(p0,p1) hq2x_interp_32_151(c[p0], c[p1]) switch (mask) { #include "TextureFilters_lq2x.h" } #undef P0 #undef P1 #undef P2 #undef P3 #undef HQ2X_MUR #undef HQ2X_MDR #undef HQ2X_MDL #undef HQ2X_MUL #undef IC #undef I11 #undef I211 #undef I31 #undef I332 #undef I431 #undef I521 #undef I53 #undef I611 #undef I71 #undef I772 #undef I97 #undef I1411 #undef I151 src0 += 1; src1 += 1; src2 += 1; dst0 += 2; dst1 += 2; } } #if !_16BPP_HACK void hq2x_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { uint16 *dst0 = (uint16 *)dstPtr; uint16 *dst1 = dst0 + (dstPitch >> 1); uint16 *src0 = (uint16 *)srcPtr; uint16 *src1 = src0 + (srcPitch >> 1); uint16 *src2 = src1 + (srcPitch >> 1); int count; hq2x_16_def(dst0, dst1, src0, src0, src1, width); if( height == 1 ) return; count = height; count -= 2; while(count>0) { dst0 += dstPitch; dst1 += dstPitch; hq2x_16_def(dst0, dst1, src0, src1, src2, width); src0 = src1; src1 = src2; src2 += srcPitch >> 1; --count; } dst0 += dstPitch; dst1 += dstPitch; hq2x_16_def(dst0, dst1, src0, src1, src1, width); } void hq2xS_16(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */, u8 *dstPtr, u32 dstPitch, int width, int height) { u16 *dst0 = (u16 *)dstPtr; u16 *dst1 = dst0 + (dstPitch >> 1); u16 *src0 = (u16 *)srcPtr; u16 *src1 = src0 + (srcPitch >> 1); u16 *src2 = src1 + (srcPitch >> 1); hq2xS_16_def(dst0, dst1, src0, src0, src1, width); int count = height; count -= 2; while(count) { dst0 += dstPitch; dst1 += dstPitch; hq2xS_16_def(dst0, dst1, src0, src1, src2, width); src0 = src1; src1 = src2; src2 += srcPitch >> 1; --count; } dst0 += dstPitch; dst1 += dstPitch; hq2xS_16_def(dst0, dst1, src0, src1, src1, width); } #endif /* !_16BPP_HACK */ void hq2x_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { uint32 *dst0 = (uint32 *)dstPtr; uint32 *dst1 = dst0 + (dstPitch >> 2); uint32 *src0 = (uint32 *)srcPtr; uint32 *src1 = src0 + (srcPitch >> 2); uint32 *src2 = src1 + (srcPitch >> 2); int count; hq2x_32_def(dst0, dst1, src0, src0, src1, width); if( height == 1 ) return; count = height; count -= 2; while(count>0) { dst0 += dstPitch >> 1; dst1 += dstPitch >> 1; hq2x_32_def(dst0, dst1, src0, src1, src2, width); src0 = src1; src1 = src2; src2 += srcPitch >> 2; --count; } dst0 += dstPitch >> 1; dst1 += dstPitch >> 1; hq2x_32_def(dst0, dst1, src0, src1, src1, width); } void hq2xS_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { uint32 *dst0 = (uint32 *)dstPtr; uint32 *dst1 = dst0 + (dstPitch >> 2); uint32 *src0 = (uint32 *)srcPtr; uint32 *src1 = src0 + (srcPitch >> 2); uint32 *src2 = src1 + (srcPitch >> 2); hq2xS_32_def(dst0, dst1, src0, src0, src1, width); int count = height; count -= 2; while(count) { dst0 += dstPitch >> 1; dst1 += dstPitch >> 1; hq2xS_32_def(dst0, dst1, src0, src1, src2, width); src0 = src1; src1 = src2; src2 += srcPitch >> 2; --count; } dst0 += dstPitch >> 1; dst1 += dstPitch >> 1; hq2xS_32_def(dst0, dst1, src0, src1, src1, width); } #if !_16BPP_HACK void lq2x_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { uint16 *dst0 = (uint16 *)dstPtr; uint16 *dst1 = dst0 + (dstPitch >> 1); uint16 *src0 = (uint16 *)srcPtr; uint16 *src1 = src0 + (srcPitch >> 1); uint16 *src2 = src1 + (srcPitch >> 1); int count; lq2x_16_def(dst0, dst1, src0, src0, src1, width); if( height == 1 ) return; count = height; count -= 2; while(count>0) { dst0 += dstPitch; dst1 += dstPitch; hq2x_16_def(dst0, dst1, src0, src1, src2, width); src0 = src1; src1 = src2; src2 += srcPitch >> 1; --count; } dst0 += dstPitch; dst1 += dstPitch; lq2x_16_def(dst0, dst1, src0, src1, src1, width); } void lq2xS_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { uint16 *dst0 = (uint16 *)dstPtr; uint16 *dst1 = dst0 + (dstPitch >> 1); uint16 *src0 = (uint16 *)srcPtr; uint16 *src1 = src0 + (srcPitch >> 1); uint16 *src2 = src1 + (srcPitch >> 1); int count; lq2xS_16_def(dst0, dst1, src0, src0, src1, width); if( height == 1 ) return; count = height; count -= 2; while(count>0) { dst0 += dstPitch; dst1 += dstPitch; hq2x_16_def(dst0, dst1, src0, src1, src2, width); src0 = src1; src1 = src2; src2 += srcPitch >> 1; --count; } dst0 += dstPitch; dst1 += dstPitch; lq2xS_16_def(dst0, dst1, src0, src1, src1, width); } #endif /* !_16BPP_HACK */ void lq2x_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { uint32 *dst0 = (uint32 *)dstPtr; uint32 *dst1 = dst0 + (dstPitch >> 2); uint32 *src0 = (uint32 *)srcPtr; uint32 *src1 = src0 + (srcPitch >> 2); uint32 *src2 = src1 + (srcPitch >> 2); int count; lq2x_32_def(dst0, dst1, src0, src0, src1, width); if( height == 1 ) return; count = height; count -= 2; while(count>0) { dst0 += dstPitch >> 1; dst1 += dstPitch >> 1; hq2x_32_def(dst0, dst1, src0, src1, src2, width); src0 = src1; src1 = src2; src2 += srcPitch >> 2; --count; } dst0 += dstPitch >> 1; dst1 += dstPitch >> 1; lq2x_32_def(dst0, dst1, src0, src1, src1, width); } void lq2xS_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { uint32 *dst0 = (uint32 *)dstPtr; uint32 *dst1 = dst0 + (dstPitch >> 2); uint32 *src0 = (uint32 *)srcPtr; uint32 *src1 = src0 + (srcPitch >> 2); uint32 *src2 = src1 + (srcPitch >> 2); int count; lq2xS_32_def(dst0, dst1, src0, src0, src1, width); if( height == 1 ) return; count = height; count -= 2; while(count>0) { dst0 += dstPitch >> 1; dst1 += dstPitch >> 1; hq2x_32_def(dst0, dst1, src0, src1, src2, width); src0 = src1; src1 = src2; src2 += srcPitch >> 2; --count; } dst0 += dstPitch >> 1; dst1 += dstPitch >> 1; lq2xS_32_def(dst0, dst1, src0, src1, src1, width); } /************************************************************************/ /* hq3x filters */ /************************************************************************/ /************************************************************************/ /* scale2x filters */ /************************************************************************/ /************************************************************************/ /* scale3x filters */ /************************************************************************/ mupen64plus-core/src/plugin/plugin.h000664 001750 001750 00000007035 12655644434 020610 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - plugin.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * Copyright (C) 2009 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef PLUGIN_H #define PLUGIN_H #include "api/m64p_common.h" #include "api/m64p_plugin.h" enum gfx_plugin_type { GFX_GLIDE64, GFX_RICE, GFX_GLN64, GFX_ANGRYLION }; enum rsp_plugin_type { RSP_HLE, RSP_CXD4 }; extern void plugin_connect_all(enum gfx_plugin_type gfx_plugin, enum rsp_plugin_type); extern GFX_INFO gfx_info; extern CONTROL Controls[4]; /*** Version requirement information ***/ #define RSP_API_VERSION 0x20000 #define GFX_API_VERSION 0x20200 #define INPUT_API_VERSION 0x20000 /* video plugin function pointers */ typedef struct _gfx_plugin_functions { ptr_PluginGetVersion getVersion; ptr_ChangeWindow changeWindow; ptr_InitiateGFX initiateGFX; ptr_MoveScreen moveScreen; ptr_ProcessDList processDList; ptr_ProcessRDPList processRDPList; ptr_RomClosed romClosed; ptr_RomOpen romOpen; ptr_ShowCFB showCFB; ptr_UpdateScreen updateScreen; ptr_ViStatusChanged viStatusChanged; ptr_ViWidthChanged viWidthChanged; ptr_ReadScreen2 readScreen; ptr_SetRenderingCallback setRenderingCallback; /* frame buffer plugin spec extension */ ptr_FBRead fBRead; ptr_FBWrite fBWrite; ptr_FBGetFrameBufferInfo fBGetFrameBufferInfo; } gfx_plugin_functions; extern gfx_plugin_functions gfx; /* input plugin function pointers */ typedef struct _input_plugin_functions { ptr_PluginGetVersion getVersion; ptr_ControllerCommand controllerCommand; ptr_GetKeys getKeys; ptr_InitiateControllers initiateControllers; ptr_ReadController readController; ptr_RomClosed romClosed; ptr_RomOpen romOpen; } input_plugin_functions; extern input_plugin_functions input; /* RSP plugin function pointers */ typedef struct _rsp_plugin_functions { ptr_PluginGetVersion getVersion; ptr_DoRspCycles doRspCycles; ptr_InitiateRSP initiateRSP; ptr_RomClosed romClosed; } rsp_plugin_functions; extern rsp_plugin_functions rsp; #endif mupen64plus-core/src/api/libretro.h000755 001750 001750 00000257402 12655644434 020415 0ustar00sergiosergio000000 000000 /* Copyright (C) 2010-2015 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this libretro API header (libretro.h). * --------------------------------------------------------------------------------------- * * Permission is hereby granted, free of charge, * to any person obtaining a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef LIBRETRO_H__ #define LIBRETRO_H__ #include #include #include #ifdef __cplusplus extern "C" { #endif #ifndef __cplusplus #if defined(_MSC_VER) && !defined(SN_TARGET_PS3) /* Hack applied for MSVC when compiling in C89 mode * as it isn't C99-compliant. */ #define bool unsigned char #define true 1 #define false 0 #else #include #endif #endif /* Used for checking API/ABI mismatches that can break libretro * implementations. * It is not incremented for compatible changes to the API. */ #define RETRO_API_VERSION 1 /* * Libretro's fundamental device abstractions. * * Libretro's input system consists of some standardized device types, * such as a joypad (with/without analog), mouse, keyboard, lightgun * and a pointer. * * The functionality of these devices are fixed, and individual cores * map their own concept of a controller to libretro's abstractions. * This makes it possible for frontends to map the abstract types to a * real input device, and not having to worry about binding input * correctly to arbitrary controller layouts. */ #define RETRO_DEVICE_TYPE_SHIFT 8 #define RETRO_DEVICE_MASK ((1 << RETRO_DEVICE_TYPE_SHIFT) - 1) #define RETRO_DEVICE_SUBCLASS(base, id) (((id + 1) << RETRO_DEVICE_TYPE_SHIFT) | base) /* Input disabled. */ #define RETRO_DEVICE_NONE 0 /* The JOYPAD is called RetroPad. It is essentially a Super Nintendo * controller, but with additional L2/R2/L3/R3 buttons, similar to a * PS1 DualShock. */ #define RETRO_DEVICE_JOYPAD 1 /* The mouse is a simple mouse, similar to Super Nintendo's mouse. * X and Y coordinates are reported relatively to last poll (poll callback). * It is up to the libretro implementation to keep track of where the mouse * pointer is supposed to be on the screen. * The frontend must make sure not to interfere with its own hardware * mouse pointer. */ #define RETRO_DEVICE_MOUSE 2 /* KEYBOARD device lets one poll for raw key pressed. * It is poll based, so input callback will return with the current * pressed state. * For event/text based keyboard input, see * RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK. */ #define RETRO_DEVICE_KEYBOARD 3 /* Lightgun X/Y coordinates are reported relatively to last poll, * similar to mouse. */ #define RETRO_DEVICE_LIGHTGUN 4 /* The ANALOG device is an extension to JOYPAD (RetroPad). * Similar to DualShock it adds two analog sticks. * This is treated as a separate device type as it returns values in the * full analog range of [-0x8000, 0x7fff]. Positive X axis is right. * Positive Y axis is down. * Only use ANALOG type when polling for analog values of the axes. */ #define RETRO_DEVICE_ANALOG 5 /* Abstracts the concept of a pointing mechanism, e.g. touch. * This allows libretro to query in absolute coordinates where on the * screen a mouse (or something similar) is being placed. * For a touch centric device, coordinates reported are the coordinates * of the press. * * Coordinates in X and Y are reported as: * [-0x7fff, 0x7fff]: -0x7fff corresponds to the far left/top of the screen, * and 0x7fff corresponds to the far right/bottom of the screen. * The "screen" is here defined as area that is passed to the frontend and * later displayed on the monitor. * * The frontend is free to scale/resize this screen as it sees fit, however, * (X, Y) = (-0x7fff, -0x7fff) will correspond to the top-left pixel of the * game image, etc. * * To check if the pointer coordinates are valid (e.g. a touch display * actually being touched), PRESSED returns 1 or 0. * * If using a mouse on a desktop, PRESSED will usually correspond to the * left mouse button, but this is a frontend decision. * PRESSED will only return 1 if the pointer is inside the game screen. * * For multi-touch, the index variable can be used to successively query * more presses. * If index = 0 returns true for _PRESSED, coordinates can be extracted * with _X, _Y for index = 0. One can then query _PRESSED, _X, _Y with * index = 1, and so on. * Eventually _PRESSED will return false for an index. No further presses * are registered at this point. */ #define RETRO_DEVICE_POINTER 6 /* Buttons for the RetroPad (JOYPAD). * The placement of these is equivalent to placements on the * Super Nintendo controller. * L2/R2/L3/R3 buttons correspond to the PS1 DualShock. */ #define RETRO_DEVICE_ID_JOYPAD_B 0 #define RETRO_DEVICE_ID_JOYPAD_Y 1 #define RETRO_DEVICE_ID_JOYPAD_SELECT 2 #define RETRO_DEVICE_ID_JOYPAD_START 3 #define RETRO_DEVICE_ID_JOYPAD_UP 4 #define RETRO_DEVICE_ID_JOYPAD_DOWN 5 #define RETRO_DEVICE_ID_JOYPAD_LEFT 6 #define RETRO_DEVICE_ID_JOYPAD_RIGHT 7 #define RETRO_DEVICE_ID_JOYPAD_A 8 #define RETRO_DEVICE_ID_JOYPAD_X 9 #define RETRO_DEVICE_ID_JOYPAD_L 10 #define RETRO_DEVICE_ID_JOYPAD_R 11 #define RETRO_DEVICE_ID_JOYPAD_L2 12 #define RETRO_DEVICE_ID_JOYPAD_R2 13 #define RETRO_DEVICE_ID_JOYPAD_L3 14 #define RETRO_DEVICE_ID_JOYPAD_R3 15 /* Index / Id values for ANALOG device. */ #define RETRO_DEVICE_INDEX_ANALOG_LEFT 0 #define RETRO_DEVICE_INDEX_ANALOG_RIGHT 1 #define RETRO_DEVICE_ID_ANALOG_X 0 #define RETRO_DEVICE_ID_ANALOG_Y 1 /* Id values for MOUSE. */ #define RETRO_DEVICE_ID_MOUSE_X 0 #define RETRO_DEVICE_ID_MOUSE_Y 1 #define RETRO_DEVICE_ID_MOUSE_LEFT 2 #define RETRO_DEVICE_ID_MOUSE_RIGHT 3 #define RETRO_DEVICE_ID_MOUSE_WHEELUP 4 #define RETRO_DEVICE_ID_MOUSE_WHEELDOWN 5 #define RETRO_DEVICE_ID_MOUSE_MIDDLE 6 /* Id values for LIGHTGUN types. */ #define RETRO_DEVICE_ID_LIGHTGUN_X 0 #define RETRO_DEVICE_ID_LIGHTGUN_Y 1 #define RETRO_DEVICE_ID_LIGHTGUN_TRIGGER 2 #define RETRO_DEVICE_ID_LIGHTGUN_CURSOR 3 #define RETRO_DEVICE_ID_LIGHTGUN_TURBO 4 #define RETRO_DEVICE_ID_LIGHTGUN_PAUSE 5 #define RETRO_DEVICE_ID_LIGHTGUN_START 6 /* Id values for POINTER. */ #define RETRO_DEVICE_ID_POINTER_X 0 #define RETRO_DEVICE_ID_POINTER_Y 1 #define RETRO_DEVICE_ID_POINTER_PRESSED 2 /* Returned from retro_get_region(). */ #define RETRO_REGION_NTSC 0 #define RETRO_REGION_PAL 1 /* Id values for LANGUAGE */ enum retro_language { RETRO_LANGUAGE_ENGLISH = 0, RETRO_LANGUAGE_JAPANESE = 1, RETRO_LANGUAGE_FRENCH = 2, RETRO_LANGUAGE_SPANISH = 3, RETRO_LANGUAGE_GERMAN = 4, RETRO_LANGUAGE_ITALIAN = 5, RETRO_LANGUAGE_DUTCH = 6, RETRO_LANGUAGE_PORTUGUESE = 7, RETRO_LANGUAGE_RUSSIAN = 8, RETRO_LANGUAGE_KOREAN = 9, RETRO_LANGUAGE_CHINESE_TRADITIONAL = 10, RETRO_LANGUAGE_CHINESE_SIMPLIFIED = 11, RETRO_LANGUAGE_LAST, /* Ensure sizeof(enum) == sizeof(int) */ RETRO_LANGUAGE_DUMMY = INT_MAX }; /* Passed to retro_get_memory_data/size(). * If the memory type doesn't apply to the * implementation NULL/0 can be returned. */ #define RETRO_MEMORY_MASK 0xff /* Regular save RAM. This RAM is usually found on a game cartridge, * backed up by a battery. * If save game data is too complex for a single memory buffer, * the SAVE_DIRECTORY (preferably) or SYSTEM_DIRECTORY environment * callback can be used. */ #define RETRO_MEMORY_SAVE_RAM 0 /* Some games have a built-in clock to keep track of time. * This memory is usually just a couple of bytes to keep track of time. */ #define RETRO_MEMORY_RTC 1 /* System ram lets a frontend peek into a game systems main RAM. */ #define RETRO_MEMORY_SYSTEM_RAM 2 /* Video ram lets a frontend peek into a game systems video RAM (VRAM). */ #define RETRO_MEMORY_VIDEO_RAM 3 /* Keysyms used for ID in input state callback when polling RETRO_KEYBOARD. */ enum retro_key { RETROK_UNKNOWN = 0, RETROK_FIRST = 0, RETROK_BACKSPACE = 8, RETROK_TAB = 9, RETROK_CLEAR = 12, RETROK_RETURN = 13, RETROK_PAUSE = 19, RETROK_ESCAPE = 27, RETROK_SPACE = 32, RETROK_EXCLAIM = 33, RETROK_QUOTEDBL = 34, RETROK_HASH = 35, RETROK_DOLLAR = 36, RETROK_AMPERSAND = 38, RETROK_QUOTE = 39, RETROK_LEFTPAREN = 40, RETROK_RIGHTPAREN = 41, RETROK_ASTERISK = 42, RETROK_PLUS = 43, RETROK_COMMA = 44, RETROK_MINUS = 45, RETROK_PERIOD = 46, RETROK_SLASH = 47, RETROK_0 = 48, RETROK_1 = 49, RETROK_2 = 50, RETROK_3 = 51, RETROK_4 = 52, RETROK_5 = 53, RETROK_6 = 54, RETROK_7 = 55, RETROK_8 = 56, RETROK_9 = 57, RETROK_COLON = 58, RETROK_SEMICOLON = 59, RETROK_LESS = 60, RETROK_EQUALS = 61, RETROK_GREATER = 62, RETROK_QUESTION = 63, RETROK_AT = 64, RETROK_LEFTBRACKET = 91, RETROK_BACKSLASH = 92, RETROK_RIGHTBRACKET = 93, RETROK_CARET = 94, RETROK_UNDERSCORE = 95, RETROK_BACKQUOTE = 96, RETROK_a = 97, RETROK_b = 98, RETROK_c = 99, RETROK_d = 100, RETROK_e = 101, RETROK_f = 102, RETROK_g = 103, RETROK_h = 104, RETROK_i = 105, RETROK_j = 106, RETROK_k = 107, RETROK_l = 108, RETROK_m = 109, RETROK_n = 110, RETROK_o = 111, RETROK_p = 112, RETROK_q = 113, RETROK_r = 114, RETROK_s = 115, RETROK_t = 116, RETROK_u = 117, RETROK_v = 118, RETROK_w = 119, RETROK_x = 120, RETROK_y = 121, RETROK_z = 122, RETROK_DELETE = 127, RETROK_KP0 = 256, RETROK_KP1 = 257, RETROK_KP2 = 258, RETROK_KP3 = 259, RETROK_KP4 = 260, RETROK_KP5 = 261, RETROK_KP6 = 262, RETROK_KP7 = 263, RETROK_KP8 = 264, RETROK_KP9 = 265, RETROK_KP_PERIOD = 266, RETROK_KP_DIVIDE = 267, RETROK_KP_MULTIPLY = 268, RETROK_KP_MINUS = 269, RETROK_KP_PLUS = 270, RETROK_KP_ENTER = 271, RETROK_KP_EQUALS = 272, RETROK_UP = 273, RETROK_DOWN = 274, RETROK_RIGHT = 275, RETROK_LEFT = 276, RETROK_INSERT = 277, RETROK_HOME = 278, RETROK_END = 279, RETROK_PAGEUP = 280, RETROK_PAGEDOWN = 281, RETROK_F1 = 282, RETROK_F2 = 283, RETROK_F3 = 284, RETROK_F4 = 285, RETROK_F5 = 286, RETROK_F6 = 287, RETROK_F7 = 288, RETROK_F8 = 289, RETROK_F9 = 290, RETROK_F10 = 291, RETROK_F11 = 292, RETROK_F12 = 293, RETROK_F13 = 294, RETROK_F14 = 295, RETROK_F15 = 296, RETROK_NUMLOCK = 300, RETROK_CAPSLOCK = 301, RETROK_SCROLLOCK = 302, RETROK_RSHIFT = 303, RETROK_LSHIFT = 304, RETROK_RCTRL = 305, RETROK_LCTRL = 306, RETROK_RALT = 307, RETROK_LALT = 308, RETROK_RMETA = 309, RETROK_LMETA = 310, RETROK_LSUPER = 311, RETROK_RSUPER = 312, RETROK_MODE = 313, RETROK_COMPOSE = 314, RETROK_HELP = 315, RETROK_PRINT = 316, RETROK_SYSREQ = 317, RETROK_BREAK = 318, RETROK_MENU = 319, RETROK_POWER = 320, RETROK_EURO = 321, RETROK_UNDO = 322, RETROK_LAST, RETROK_DUMMY = INT_MAX /* Ensure sizeof(enum) == sizeof(int) */ }; enum retro_mod { RETROKMOD_NONE = 0x0000, RETROKMOD_SHIFT = 0x01, RETROKMOD_CTRL = 0x02, RETROKMOD_ALT = 0x04, RETROKMOD_META = 0x08, RETROKMOD_NUMLOCK = 0x10, RETROKMOD_CAPSLOCK = 0x20, RETROKMOD_SCROLLOCK = 0x40, RETROKMOD_DUMMY = INT_MAX /* Ensure sizeof(enum) == sizeof(int) */ }; /* If set, this call is not part of the public libretro API yet. It can * change or be removed at any time. */ #define RETRO_ENVIRONMENT_EXPERIMENTAL 0x10000 /* Environment callback to be used internally in frontend. */ #define RETRO_ENVIRONMENT_PRIVATE 0x20000 /* Environment commands. */ #define RETRO_ENVIRONMENT_SET_ROTATION 1 /* const unsigned * -- * Sets screen rotation of graphics. * Is only implemented if rotation can be accelerated by hardware. * Valid values are 0, 1, 2, 3, which rotates screen by 0, 90, 180, * 270 degrees counter-clockwise respectively. */ #define RETRO_ENVIRONMENT_GET_OVERSCAN 2 /* bool * -- * Boolean value whether or not the implementation should use overscan, * or crop away overscan. */ #define RETRO_ENVIRONMENT_GET_CAN_DUPE 3 /* bool * -- * Boolean value whether or not frontend supports frame duping, * passing NULL to video frame callback. */ /* Environ 4, 5 are no longer supported (GET_VARIABLE / SET_VARIABLES), * and reserved to avoid possible ABI clash. */ #define RETRO_ENVIRONMENT_SET_MESSAGE 6 /* const struct retro_message * -- * Sets a message to be displayed in implementation-specific manner * for a certain amount of 'frames'. * Should not be used for trivial messages, which should simply be * logged via RETRO_ENVIRONMENT_GET_LOG_INTERFACE (or as a * fallback, stderr). */ #define RETRO_ENVIRONMENT_SHUTDOWN 7 /* N/A (NULL) -- * Requests the frontend to shutdown. * Should only be used if game has a specific * way to shutdown the game from a menu item or similar. */ #define RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL 8 /* const unsigned * -- * Gives a hint to the frontend how demanding this implementation * is on a system. E.g. reporting a level of 2 means * this implementation should run decently on all frontends * of level 2 and up. * * It can be used by the frontend to potentially warn * about too demanding implementations. * * The levels are "floating". * * This function can be called on a per-game basis, * as certain games an implementation can play might be * particularly demanding. * If called, it should be called in retro_load_game(). */ #define RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY 9 /* const char ** -- * Returns the "system" directory of the frontend. * This directory can be used to store system specific * content such as BIOSes, configuration data, etc. * The returned value can be NULL. * If so, no such directory is defined, * and it's up to the implementation to find a suitable directory. * * NOTE: Some cores used this folder also for "save" data such as * memory cards, etc, for lack of a better place to put it. * This is now discouraged, and if possible, cores should try to * use the new GET_SAVE_DIRECTORY. */ #define RETRO_ENVIRONMENT_SET_PIXEL_FORMAT 10 /* const enum retro_pixel_format * -- * Sets the internal pixel format used by the implementation. * The default pixel format is RETRO_PIXEL_FORMAT_0RGB1555. * This pixel format however, is deprecated (see enum retro_pixel_format). * If the call returns false, the frontend does not support this pixel * format. * * This function should be called inside retro_load_game() or * retro_get_system_av_info(). */ #define RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS 11 /* const struct retro_input_descriptor * -- * Sets an array of retro_input_descriptors. * It is up to the frontend to present this in a usable way. * The array is terminated by retro_input_descriptor::description * being set to NULL. * This function can be called at any time, but it is recommended * to call it as early as possible. */ #define RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK 12 /* const struct retro_keyboard_callback * -- * Sets a callback function used to notify core about keyboard events. */ #define RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE 13 /* const struct retro_disk_control_callback * -- * Sets an interface which frontend can use to eject and insert * disk images. * This is used for games which consist of multiple images and * must be manually swapped out by the user (e.g. PSX). */ #define RETRO_ENVIRONMENT_SET_HW_RENDER 14 /* struct retro_hw_render_callback * -- * Sets an interface to let a libretro core render with * hardware acceleration. * Should be called in retro_load_game(). * If successful, libretro cores will be able to render to a * frontend-provided framebuffer. * The size of this framebuffer will be at least as large as * max_width/max_height provided in get_av_info(). * If HW rendering is used, pass only RETRO_HW_FRAME_BUFFER_VALID or * NULL to retro_video_refresh_t. */ #define RETRO_ENVIRONMENT_GET_VARIABLE 15 /* struct retro_variable * -- * Interface to acquire user-defined information from environment * that cannot feasibly be supported in a multi-system way. * 'key' should be set to a key which has already been set by * SET_VARIABLES. * 'data' will be set to a value or NULL. */ #define RETRO_ENVIRONMENT_SET_VARIABLES 16 /* const struct retro_variable * -- * Allows an implementation to signal the environment * which variables it might want to check for later using * GET_VARIABLE. * This allows the frontend to present these variables to * a user dynamically. * This should be called as early as possible (ideally in * retro_set_environment). * * 'data' points to an array of retro_variable structs * terminated by a { NULL, NULL } element. * retro_variable::key should be namespaced to not collide * with other implementations' keys. E.g. A core called * 'foo' should use keys named as 'foo_option'. * retro_variable::value should contain a human readable * description of the key as well as a '|' delimited list * of expected values. * * The number of possible options should be very limited, * i.e. it should be feasible to cycle through options * without a keyboard. * * First entry should be treated as a default. * * Example entry: * { "foo_option", "Speed hack coprocessor X; false|true" } * * Text before first ';' is description. This ';' must be * followed by a space, and followed by a list of possible * values split up with '|'. * * Only strings are operated on. The possible values will * generally be displayed and stored as-is by the frontend. */ #define RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE 17 /* bool * -- * Result is set to true if some variables are updated by * frontend since last call to RETRO_ENVIRONMENT_GET_VARIABLE. * Variables should be queried with GET_VARIABLE. */ #define RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME 18 /* const bool * -- * If true, the libretro implementation supports calls to * retro_load_game() with NULL as argument. * Used by cores which can run without particular game data. * This should be called within retro_set_environment() only. */ #define RETRO_ENVIRONMENT_GET_LIBRETRO_PATH 19 /* const char ** -- * Retrieves the absolute path from where this libretro * implementation was loaded. * NULL is returned if the libretro was loaded statically * (i.e. linked statically to frontend), or if the path cannot be * determined. * Mostly useful in cooperation with SET_SUPPORT_NO_GAME as assets can * be loaded without ugly hacks. */ /* Environment 20 was an obsolete version of SET_AUDIO_CALLBACK. * It was not used by any known core at the time, * and was removed from the API. */ #define RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK 22 /* const struct retro_audio_callback * -- * Sets an interface which is used to notify a libretro core about audio * being available for writing. * The callback can be called from any thread, so a core using this must * have a thread safe audio implementation. * It is intended for games where audio and video are completely * asynchronous and audio can be generated on the fly. * This interface is not recommended for use with emulators which have * highly synchronous audio. * * The callback only notifies about writability; the libretro core still * has to call the normal audio callbacks * to write audio. The audio callbacks must be called from within the * notification callback. * The amount of audio data to write is up to the implementation. * Generally, the audio callback will be called continously in a loop. * * Due to thread safety guarantees and lack of sync between audio and * video, a frontend can selectively disallow this interface based on * internal configuration. A core using this interface must also * implement the "normal" audio interface. * * A libretro core using SET_AUDIO_CALLBACK should also make use of * SET_FRAME_TIME_CALLBACK. */ #define RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK 21 /* const struct retro_frame_time_callback * -- * Lets the core know how much time has passed since last * invocation of retro_run(). * The frontend can tamper with the timing to fake fast-forward, * slow-motion, frame stepping, etc. * In this case the delta time will use the reference value * in frame_time_callback.. */ #define RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE 23 /* struct retro_rumble_interface * -- * Gets an interface which is used by a libretro core to set * state of rumble motors in controllers. * A strong and weak motor is supported, and they can be * controlled indepedently. */ #define RETRO_ENVIRONMENT_GET_INPUT_DEVICE_CAPABILITIES 24 /* uint64_t * -- * Gets a bitmask telling which device type are expected to be * handled properly in a call to retro_input_state_t. * Devices which are not handled or recognized always return * 0 in retro_input_state_t. * Example bitmask: caps = (1 << RETRO_DEVICE_JOYPAD) | (1 << RETRO_DEVICE_ANALOG). * Should only be called in retro_run(). */ #define RETRO_ENVIRONMENT_GET_SENSOR_INTERFACE (25 | RETRO_ENVIRONMENT_EXPERIMENTAL) /* struct retro_sensor_interface * -- * Gets access to the sensor interface. * The purpose of this interface is to allow * setting state related to sensors such as polling rate, * enabling/disable it entirely, etc. * Reading sensor state is done via the normal * input_state_callback API. */ #define RETRO_ENVIRONMENT_GET_CAMERA_INTERFACE (26 | RETRO_ENVIRONMENT_EXPERIMENTAL) /* struct retro_camera_callback * -- * Gets an interface to a video camera driver. * A libretro core can use this interface to get access to a * video camera. * New video frames are delivered in a callback in same * thread as retro_run(). * * GET_CAMERA_INTERFACE should be called in retro_load_game(). * * Depending on the camera implementation used, camera frames * will be delivered as a raw framebuffer, * or as an OpenGL texture directly. * * The core has to tell the frontend here which types of * buffers can be handled properly. * An OpenGL texture can only be handled when using a * libretro GL core (SET_HW_RENDER). * It is recommended to use a libretro GL core when * using camera interface. * * The camera is not started automatically. The retrieved start/stop * functions must be used to explicitly * start and stop the camera driver. */ #define RETRO_ENVIRONMENT_GET_LOG_INTERFACE 27 /* struct retro_log_callback * -- * Gets an interface for logging. This is useful for * logging in a cross-platform way * as certain platforms cannot use use stderr for logging. * It also allows the frontend to * show logging information in a more suitable way. * If this interface is not used, libretro cores should * log to stderr as desired. */ #define RETRO_ENVIRONMENT_GET_PERF_INTERFACE 28 /* struct retro_perf_callback * -- * Gets an interface for performance counters. This is useful * for performance logging in a cross-platform way and for detecting * architecture-specific features, such as SIMD support. */ #define RETRO_ENVIRONMENT_GET_LOCATION_INTERFACE 29 /* struct retro_location_callback * -- * Gets access to the location interface. * The purpose of this interface is to be able to retrieve * location-based information from the host device, * such as current latitude / longitude. */ #define RETRO_ENVIRONMENT_GET_CONTENT_DIRECTORY 30 /* const char ** -- * Returns the "content" directory of the frontend. * This directory can be used to store specific assets that the * core relies upon, such as art assets, * input data, etc etc. * The returned value can be NULL. * If so, no such directory is defined, * and it's up to the implementation to find a suitable directory. */ #define RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY 31 /* const char ** -- * Returns the "save" directory of the frontend. * This directory can be used to store SRAM, memory cards, * high scores, etc, if the libretro core * cannot use the regular memory interface (retro_get_memory_data()). * * NOTE: libretro cores used to check GET_SYSTEM_DIRECTORY for * similar things before. * They should still check GET_SYSTEM_DIRECTORY if they want to * be backwards compatible. * The path here can be NULL. It should only be non-NULL if the * frontend user has set a specific save path. */ #define RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO 32 /* const struct retro_system_av_info * -- * Sets a new av_info structure. This can only be called from * within retro_run(). * This should *only* be used if the core is completely altering the * internal resolutions, aspect ratios, timings, sampling rate, etc. * Calling this can require a full reinitialization of video/audio * drivers in the frontend, * * so it is important to call it very sparingly, and usually only with * the users explicit consent. * An eventual driver reinitialize will happen so that video and * audio callbacks * happening after this call within the same retro_run() call will * target the newly initialized driver. * * This callback makes it possible to support configurable resolutions * in games, which can be useful to * avoid setting the "worst case" in max_width/max_height. * * ***HIGHLY RECOMMENDED*** Do not call this callback every time * resolution changes in an emulator core if it's * expected to be a temporary change, for the reasons of possible * driver reinitialization. * This call is not a free pass for not trying to provide * correct values in retro_get_system_av_info(). If you need to change * things like aspect ratio or nominal width/height, * use RETRO_ENVIRONMENT_SET_GEOMETRY, which is a softer variant * of SET_SYSTEM_AV_INFO. * * If this returns false, the frontend does not acknowledge a * changed av_info struct. */ #define RETRO_ENVIRONMENT_SET_PROC_ADDRESS_CALLBACK 33 /* const struct retro_get_proc_address_interface * -- * Allows a libretro core to announce support for the * get_proc_address() interface. * This interface allows for a standard way to extend libretro where * use of environment calls are too indirect, * e.g. for cases where the frontend wants to call directly into the core. * * If a core wants to expose this interface, SET_PROC_ADDRESS_CALLBACK * **MUST** be called from within retro_set_environment(). */ #define RETRO_ENVIRONMENT_SET_SUBSYSTEM_INFO 34 /* const struct retro_subsystem_info * -- * This environment call introduces the concept of libretro "subsystems". * A subsystem is a variant of a libretro core which supports * different kinds of games. * The purpose of this is to support e.g. emulators which might * have special needs, e.g. Super Nintendo's Super GameBoy, Sufami Turbo. * It can also be used to pick among subsystems in an explicit way * if the libretro implementation is a multi-system emulator itself. * * Loading a game via a subsystem is done with retro_load_game_special(), * and this environment call allows a libretro core to expose which * subsystems are supported for use with retro_load_game_special(). * A core passes an array of retro_game_special_info which is terminated * with a zeroed out retro_game_special_info struct. * * If a core wants to use this functionality, SET_SUBSYSTEM_INFO * **MUST** be called from within retro_set_environment(). */ #define RETRO_ENVIRONMENT_SET_CONTROLLER_INFO 35 /* const struct retro_controller_info * -- * This environment call lets a libretro core tell the frontend * which controller types are recognized in calls to * retro_set_controller_port_device(). * * Some emulators such as Super Nintendo * support multiple lightgun types which must be specifically * selected from. * It is therefore sometimes necessary for a frontend to be able * to tell the core about a special kind of input device which is * not covered by the libretro input API. * * In order for a frontend to understand the workings of an input device, * it must be a specialized type * of the generic device types already defined in the libretro API. * * Which devices are supported can vary per input port. * The core must pass an array of const struct retro_controller_info which * is terminated with a blanked out struct. Each element of the struct * corresponds to an ascending port index to * retro_set_controller_port_device(). * Even if special device types are set in the libretro core, * libretro should only poll input based on the base input device types. */ #define RETRO_ENVIRONMENT_SET_MEMORY_MAPS (36 | RETRO_ENVIRONMENT_EXPERIMENTAL) /* const struct retro_memory_map * -- * This environment call lets a libretro core tell the frontend * about the memory maps this core emulates. * This can be used to implement, for example, cheats in a core-agnostic way. * * Should only be used by emulators; it doesn't make much sense for * anything else. * It is recommended to expose all relevant pointers through * retro_get_memory_* as well. * * Can be called from retro_init and retro_load_game. */ #define RETRO_ENVIRONMENT_SET_GEOMETRY 37 /* const struct retro_game_geometry * -- * This environment call is similar to SET_SYSTEM_AV_INFO for changing * video parameters, but provides a guarantee that drivers will not be * reinitialized. * This can only be called from within retro_run(). * * The purpose of this call is to allow a core to alter nominal * width/heights as well as aspect ratios on-the-fly, which can be * useful for some emulators to change in run-time. * * max_width/max_height arguments are ignored and cannot be changed * with this call as this could potentially require a reinitialization or a * non-constant time operation. * If max_width/max_height are to be changed, SET_SYSTEM_AV_INFO is required. * * A frontend must guarantee that this environment call completes in * constant time. */ #define RETRO_ENVIRONMENT_GET_USERNAME 38 /* const char ** * Returns the specified username of the frontend, if specified by the user. * This username can be used as a nickname for a core that has online facilities * or any other mode where personalization of the user is desirable. * The returned value can be NULL. * If this environ callback is used by a core that requires a valid username, * a default username should be specified by the core. */ #define RETRO_ENVIRONMENT_GET_LANGUAGE 39 /* unsigned * -- * Returns the specified language of the frontend, if specified by the user. * It can be used by the core for localization purposes. */ #define RETRO_MEMDESC_CONST (1 << 0) /* The frontend will never change this memory area once retro_load_game has returned. */ #define RETRO_MEMDESC_BIGENDIAN (1 << 1) /* The memory area contains big endian data. Default is little endian. */ #define RETRO_MEMDESC_ALIGN_2 (1 << 16) /* All memory access in this area is aligned to their own size, or 2, whichever is smaller. */ #define RETRO_MEMDESC_ALIGN_4 (2 << 16) #define RETRO_MEMDESC_ALIGN_8 (3 << 16) #define RETRO_MEMDESC_MINSIZE_2 (1 << 24) /* All memory in this region is accessed at least 2 bytes at the time. */ #define RETRO_MEMDESC_MINSIZE_4 (2 << 24) #define RETRO_MEMDESC_MINSIZE_8 (3 << 24) struct retro_memory_descriptor { uint64_t flags; /* Pointer to the start of the relevant ROM or RAM chip. * It's strongly recommended to use 'offset' if possible, rather than * doing math on the pointer. * * If the same byte is mapped my multiple descriptors, their descriptors * must have the same pointer. * If 'start' does not point to the first byte in the pointer, put the * difference in 'offset' instead. * * May be NULL if there's nothing usable here (e.g. hardware registers and * open bus). No flags should be set if the pointer is NULL. * It's recommended to minimize the number of descriptors if possible, * but not mandatory. */ void *ptr; size_t offset; /* This is the location in the emulated address space * where the mapping starts. */ size_t start; /* Which bits must be same as in 'start' for this mapping to apply. * The first memory descriptor to claim a certain byte is the one * that applies. * A bit which is set in 'start' must also be set in this. * Can be zero, in which case each byte is assumed mapped exactly once. * In this case, 'len' must be a power of two. */ size_t select; /* If this is nonzero, the set bits are assumed not connected to the * memory chip's address pins. */ size_t disconnect; /* This one tells the size of the current memory area. * If, after start+disconnect are applied, the address is higher than * this, the highest bit of the address is cleared. * * If the address is still too high, the next highest bit is cleared. * Can be zero, in which case it's assumed to be infinite (as limited * by 'select' and 'disconnect'). */ size_t len; /* To go from emulated address to physical address, the following * order applies: * Subtract 'start', pick off 'disconnect', apply 'len', add 'offset'. * * The address space name must consist of only a-zA-Z0-9_-, * should be as short as feasible (maximum length is 8 plus the NUL), * and may not be any other address space plus one or more 0-9A-F * at the end. * However, multiple memory descriptors for the same address space is * allowed, and the address space name can be empty. NULL is treated * as empty. * * Address space names are case sensitive, but avoid lowercase if possible. * The same pointer may exist in multiple address spaces. * * Examples: * blank+blank - valid (multiple things may be mapped in the same namespace) * 'Sp'+'Sp' - valid (multiple things may be mapped in the same namespace) * 'A'+'B' - valid (neither is a prefix of each other) * 'S'+blank - valid ('S' is not in 0-9A-F) * 'a'+blank - valid ('a' is not in 0-9A-F) * 'a'+'A' - valid (neither is a prefix of each other) * 'AR'+blank - valid ('R' is not in 0-9A-F) * 'ARB'+blank - valid (the B can't be part of the address either, because * there is no namespace 'AR') * blank+'B' - not valid, because it's ambigous which address space B1234 * would refer to. * The length can't be used for that purpose; the frontend may want * to append arbitrary data to an address, without a separator. */ const char *addrspace; }; /* The frontend may use the largest value of 'start'+'select' in a * certain namespace to infer the size of the address space. * * If the address space is larger than that, a mapping with .ptr=NULL * should be at the end of the array, with .select set to all ones for * as long as the address space is big. * * Sample descriptors (minus .ptr, and RETRO_MEMFLAG_ on the flags): * SNES WRAM: * .start=0x7E0000, .len=0x20000 * (Note that this must be mapped before the ROM in most cases; some of the * ROM mappers * try to claim $7E0000, or at least $7E8000.) * SNES SPC700 RAM: * .addrspace="S", .len=0x10000 * SNES WRAM mirrors: * .flags=MIRROR, .start=0x000000, .select=0xC0E000, .len=0x2000 * .flags=MIRROR, .start=0x800000, .select=0xC0E000, .len=0x2000 * SNES WRAM mirrors, alternate equivalent descriptor: * .flags=MIRROR, .select=0x40E000, .disconnect=~0x1FFF * (Various similar constructions can be created by combining parts of * the above two.) * SNES LoROM (512KB, mirrored a couple of times): * .flags=CONST, .start=0x008000, .select=0x408000, .disconnect=0x8000, .len=512*1024 * .flags=CONST, .start=0x400000, .select=0x400000, .disconnect=0x8000, .len=512*1024 * SNES HiROM (4MB): * .flags=CONST, .start=0x400000, .select=0x400000, .len=4*1024*1024 * .flags=CONST, .offset=0x8000, .start=0x008000, .select=0x408000, .len=4*1024*1024 * SNES ExHiROM (8MB): * .flags=CONST, .offset=0, .start=0xC00000, .select=0xC00000, .len=4*1024*1024 * .flags=CONST, .offset=4*1024*1024, .start=0x400000, .select=0xC00000, .len=4*1024*1024 * .flags=CONST, .offset=0x8000, .start=0x808000, .select=0xC08000, .len=4*1024*1024 * .flags=CONST, .offset=4*1024*1024+0x8000, .start=0x008000, .select=0xC08000, .len=4*1024*1024 * Clarify the size of the address space: * .ptr=NULL, .select=0xFFFFFF * .len can be implied by .select in many of them, but was included for clarity. */ struct retro_memory_map { const struct retro_memory_descriptor *descriptors; unsigned num_descriptors; }; struct retro_controller_description { /* Human-readable description of the controller. Even if using a generic * input device type, this can be set to the particular device type the * core uses. */ const char *desc; /* Device type passed to retro_set_controller_port_device(). If the device * type is a sub-class of a generic input device type, use the * RETRO_DEVICE_SUBCLASS macro to create an ID. * * E.g. RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 1). */ unsigned id; }; struct retro_controller_info { const struct retro_controller_description *types; unsigned num_types; }; struct retro_subsystem_memory_info { /* The extension associated with a memory type, e.g. "psram". */ const char *extension; /* The memory type for retro_get_memory(). This should be at * least 0x100 to avoid conflict with standardized * libretro memory types. */ unsigned type; }; struct retro_subsystem_rom_info { /* Describes what the content is (SGB BIOS, GB ROM, etc). */ const char *desc; /* Same definition as retro_get_system_info(). */ const char *valid_extensions; /* Same definition as retro_get_system_info(). */ bool need_fullpath; /* Same definition as retro_get_system_info(). */ bool block_extract; /* This is set if the content is required to load a game. * If this is set to false, a zeroed-out retro_game_info can be passed. */ bool required; /* Content can have multiple associated persistent * memory types (retro_get_memory()). */ const struct retro_subsystem_memory_info *memory; unsigned num_memory; }; struct retro_subsystem_info { /* Human-readable string of the subsystem type, e.g. "Super GameBoy" */ const char *desc; /* A computer friendly short string identifier for the subsystem type. * This name must be [a-z]. * E.g. if desc is "Super GameBoy", this can be "sgb". * This identifier can be used for command-line interfaces, etc. */ const char *ident; /* Infos for each content file. The first entry is assumed to be the * "most significant" content for frontend purposes. * E.g. with Super GameBoy, the first content should be the GameBoy ROM, * as it is the most "significant" content to a user. * If a frontend creates new file paths based on the content used * (e.g. savestates), it should use the path for the first ROM to do so. */ const struct retro_subsystem_rom_info *roms; /* Number of content files associated with a subsystem. */ unsigned num_roms; /* The type passed to retro_load_game_special(). */ unsigned id; }; typedef void (*retro_proc_address_t)(void); /* libretro API extension functions: * (None here so far). * * Get a symbol from a libretro core. * Cores should only return symbols which are actual * extensions to the libretro API. * * Frontends should not use this to obtain symbols to standard * libretro entry points (static linking or dlsym). * * The symbol name must be equal to the function name, * e.g. if void retro_foo(void); exists, the symbol must be called "retro_foo". * The returned function pointer must be cast to the corresponding type. */ typedef retro_proc_address_t (*retro_get_proc_address_t)(const char *sym); struct retro_get_proc_address_interface { retro_get_proc_address_t get_proc_address; }; enum retro_log_level { RETRO_LOG_DEBUG = 0, RETRO_LOG_INFO, RETRO_LOG_WARN, RETRO_LOG_ERROR, RETRO_LOG_DUMMY = INT_MAX }; /* Logging function. Takes log level argument as well. */ typedef void (*retro_log_printf_t)(enum retro_log_level level, const char *fmt, ...); struct retro_log_callback { retro_log_printf_t log; }; /* Performance related functions */ /* ID values for SIMD CPU features */ #define RETRO_SIMD_SSE (1 << 0) #define RETRO_SIMD_SSE2 (1 << 1) #define RETRO_SIMD_VMX (1 << 2) #define RETRO_SIMD_VMX128 (1 << 3) #define RETRO_SIMD_AVX (1 << 4) #define RETRO_SIMD_NEON (1 << 5) #define RETRO_SIMD_SSE3 (1 << 6) #define RETRO_SIMD_SSSE3 (1 << 7) #define RETRO_SIMD_MMX (1 << 8) #define RETRO_SIMD_MMXEXT (1 << 9) #define RETRO_SIMD_SSE4 (1 << 10) #define RETRO_SIMD_SSE42 (1 << 11) #define RETRO_SIMD_AVX2 (1 << 12) #define RETRO_SIMD_VFPU (1 << 13) #define RETRO_SIMD_PS (1 << 14) #define RETRO_SIMD_AES (1 << 15) typedef uint64_t retro_perf_tick_t; typedef int64_t retro_time_t; struct retro_perf_counter { const char *ident; retro_perf_tick_t start; retro_perf_tick_t total; retro_perf_tick_t call_cnt; bool registered; }; /* Returns current time in microseconds. * Tries to use the most accurate timer available. */ typedef retro_time_t (*retro_perf_get_time_usec_t)(void); /* A simple counter. Usually nanoseconds, but can also be CPU cycles. * Can be used directly if desired (when creating a more sophisticated * performance counter system). * */ typedef retro_perf_tick_t (*retro_perf_get_counter_t)(void); /* Returns a bit-mask of detected CPU features (RETRO_SIMD_*). */ typedef uint64_t (*retro_get_cpu_features_t)(void); /* Asks frontend to log and/or display the state of performance counters. * Performance counters can always be poked into manually as well. */ typedef void (*retro_perf_log_t)(void); /* Register a performance counter. * ident field must be set with a discrete value and other values in * retro_perf_counter must be 0. * Registering can be called multiple times. To avoid calling to * frontend redundantly, you can check registered field first. */ typedef void (*retro_perf_register_t)(struct retro_perf_counter *counter); /* Starts a registered counter. */ typedef void (*retro_perf_start_t)(struct retro_perf_counter *counter); /* Stops a registered counter. */ typedef void (*retro_perf_stop_t)(struct retro_perf_counter *counter); /* For convenience it can be useful to wrap register, start and stop in macros. * E.g.: * #ifdef LOG_PERFORMANCE * #define RETRO_PERFORMANCE_INIT(perf_cb, name) static struct retro_perf_counter name = {#name}; if (!name.registered) perf_cb.perf_register(&(name)) * #define RETRO_PERFORMANCE_START(perf_cb, name) perf_cb.perf_start(&(name)) * #define RETRO_PERFORMANCE_STOP(perf_cb, name) perf_cb.perf_stop(&(name)) * #else * ... Blank macros ... * #endif * * These can then be used mid-functions around code snippets. * * extern struct retro_perf_callback perf_cb; * Somewhere in the core. * * void do_some_heavy_work(void) * { * RETRO_PERFORMANCE_INIT(cb, work_1; * RETRO_PERFORMANCE_START(cb, work_1); * heavy_work_1(); * RETRO_PERFORMANCE_STOP(cb, work_1); * * RETRO_PERFORMANCE_INIT(cb, work_2); * RETRO_PERFORMANCE_START(cb, work_2); * heavy_work_2(); * RETRO_PERFORMANCE_STOP(cb, work_2); * } * * void retro_deinit(void) * { * perf_cb.perf_log(); * Log all perf counters here for example. * } */ struct retro_perf_callback { retro_perf_get_time_usec_t get_time_usec; retro_get_cpu_features_t get_cpu_features; retro_perf_get_counter_t get_perf_counter; retro_perf_register_t perf_register; retro_perf_start_t perf_start; retro_perf_stop_t perf_stop; retro_perf_log_t perf_log; }; /* FIXME: Document the sensor API and work out behavior. * It will be marked as experimental until then. */ enum retro_sensor_action { RETRO_SENSOR_ACCELEROMETER_ENABLE = 0, RETRO_SENSOR_ACCELEROMETER_DISABLE, RETRO_SENSOR_DUMMY = INT_MAX }; /* Id values for SENSOR types. */ #define RETRO_SENSOR_ACCELEROMETER_X 0 #define RETRO_SENSOR_ACCELEROMETER_Y 1 #define RETRO_SENSOR_ACCELEROMETER_Z 2 typedef bool (*retro_set_sensor_state_t)(unsigned port, enum retro_sensor_action action, unsigned rate); typedef float (*retro_sensor_get_input_t)(unsigned port, unsigned id); struct retro_sensor_interface { retro_set_sensor_state_t set_sensor_state; retro_sensor_get_input_t get_sensor_input; }; enum retro_camera_buffer { RETRO_CAMERA_BUFFER_OPENGL_TEXTURE = 0, RETRO_CAMERA_BUFFER_RAW_FRAMEBUFFER, RETRO_CAMERA_BUFFER_DUMMY = INT_MAX }; /* Starts the camera driver. Can only be called in retro_run(). */ typedef bool (*retro_camera_start_t)(void); /* Stops the camera driver. Can only be called in retro_run(). */ typedef void (*retro_camera_stop_t)(void); /* Callback which signals when the camera driver is initialized * and/or deinitialized. * retro_camera_start_t can be called in initialized callback. */ typedef void (*retro_camera_lifetime_status_t)(void); /* A callback for raw framebuffer data. buffer points to an XRGB8888 buffer. * Width, height and pitch are similar to retro_video_refresh_t. * First pixel is top-left origin. */ typedef void (*retro_camera_frame_raw_framebuffer_t)(const uint32_t *buffer, unsigned width, unsigned height, size_t pitch); /* A callback for when OpenGL textures are used. * * texture_id is a texture owned by camera driver. * Its state or content should be considered immutable, except for things like * texture filtering and clamping. * * texture_target is the texture target for the GL texture. * These can include e.g. GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE, and possibly * more depending on extensions. * * affine points to a packed 3x3 column-major matrix used to apply an affine * transform to texture coordinates. (affine_matrix * vec3(coord_x, coord_y, 1.0)) * After transform, normalized texture coord (0, 0) should be bottom-left * and (1, 1) should be top-right (or (width, height) for RECTANGLE). * * GL-specific typedefs are avoided here to avoid relying on gl.h in * the API definition. */ typedef void (*retro_camera_frame_opengl_texture_t)(unsigned texture_id, unsigned texture_target, const float *affine); struct retro_camera_callback { /* Set by libretro core. * Example bitmask: caps = (1 << RETRO_CAMERA_BUFFER_OPENGL_TEXTURE) | (1 << RETRO_CAMERA_BUFFER_RAW_FRAMEBUFFER). */ uint64_t caps; unsigned width; /* Desired resolution for camera. Is only used as a hint. */ unsigned height; retro_camera_start_t start; /* Set by frontend. */ retro_camera_stop_t stop; /* Set by frontend. */ /* Set by libretro core if raw framebuffer callbacks will be used. */ retro_camera_frame_raw_framebuffer_t frame_raw_framebuffer; /* Set by libretro core if OpenGL texture callbacks will be used. */ retro_camera_frame_opengl_texture_t frame_opengl_texture; /* Set by libretro core. Called after camera driver is initialized and * ready to be started. * Can be NULL, in which this callback is not called. */ retro_camera_lifetime_status_t initialized; /* Set by libretro core. Called right before camera driver is * deinitialized. * Can be NULL, in which this callback is not called. */ retro_camera_lifetime_status_t deinitialized; }; /* Sets the interval of time and/or distance at which to update/poll * location-based data. * * To ensure compatibility with all location-based implementations, * values for both interval_ms and interval_distance should be provided. * * interval_ms is the interval expressed in milliseconds. * interval_distance is the distance interval expressed in meters. */ typedef void (*retro_location_set_interval_t)(unsigned interval_ms, unsigned interval_distance); /* Start location services. The device will start listening for changes to the * current location at regular intervals (which are defined with * retro_location_set_interval_t). */ typedef bool (*retro_location_start_t)(void); /* Stop location services. The device will stop listening for changes * to the current location. */ typedef void (*retro_location_stop_t)(void); /* Get the position of the current location. Will set parameters to * 0 if no new location update has happened since the last time. */ typedef bool (*retro_location_get_position_t)(double *lat, double *lon, double *horiz_accuracy, double *vert_accuracy); /* Callback which signals when the location driver is initialized * and/or deinitialized. * retro_location_start_t can be called in initialized callback. */ typedef void (*retro_location_lifetime_status_t)(void); struct retro_location_callback { retro_location_start_t start; retro_location_stop_t stop; retro_location_get_position_t get_position; retro_location_set_interval_t set_interval; retro_location_lifetime_status_t initialized; retro_location_lifetime_status_t deinitialized; }; enum retro_rumble_effect { RETRO_RUMBLE_STRONG = 0, RETRO_RUMBLE_WEAK = 1, RETRO_RUMBLE_DUMMY = INT_MAX }; /* Sets rumble state for joypad plugged in port 'port'. * Rumble effects are controlled independently, * and setting e.g. strong rumble does not override weak rumble. * Strength has a range of [0, 0xffff]. * * Returns true if rumble state request was honored. * Calling this before first retro_run() is likely to return false. */ typedef bool (*retro_set_rumble_state_t)(unsigned port, enum retro_rumble_effect effect, uint16_t strength); struct retro_rumble_interface { retro_set_rumble_state_t set_rumble_state; }; /* Notifies libretro that audio data should be written. */ typedef void (*retro_audio_callback_t)(void); /* True: Audio driver in frontend is active, and callback is * expected to be called regularily. * False: Audio driver in frontend is paused or inactive. * Audio callback will not be called until set_state has been * called with true. * Initial state is false (inactive). */ typedef void (*retro_audio_set_state_callback_t)(bool enabled); struct retro_audio_callback { retro_audio_callback_t callback; retro_audio_set_state_callback_t set_state; }; /* Notifies a libretro core of time spent since last invocation * of retro_run() in microseconds. * * It will be called right before retro_run() every frame. * The frontend can tamper with timing to support cases like * fast-forward, slow-motion and framestepping. * * In those scenarios the reference frame time value will be used. */ typedef int64_t retro_usec_t; typedef void (*retro_frame_time_callback_t)(retro_usec_t usec); struct retro_frame_time_callback { retro_frame_time_callback_t callback; /* Represents the time of one frame. It is computed as * 1000000 / fps, but the implementation will resolve the * rounding to ensure that framestepping, etc is exact. */ retro_usec_t reference; }; /* Pass this to retro_video_refresh_t if rendering to hardware. * Passing NULL to retro_video_refresh_t is still a frame dupe as normal. * */ #define RETRO_HW_FRAME_BUFFER_VALID ((void*)-1) /* Invalidates the current HW context. * Any GL state is lost, and must not be deinitialized explicitly. * If explicit deinitialization is desired by the libretro core, * it should implement context_destroy callback. * If called, all GPU resources must be reinitialized. * Usually called when frontend reinits video driver. * Also called first time video driver is initialized, * allowing libretro core to initialize resources. */ typedef void (*retro_hw_context_reset_t)(void); /* Gets current framebuffer which is to be rendered to. * Could change every frame potentially. */ typedef uintptr_t (*retro_hw_get_current_framebuffer_t)(void); /* Get a symbol from HW context. */ typedef retro_proc_address_t (*retro_hw_get_proc_address_t)(const char *sym); enum retro_hw_context_type { RETRO_HW_CONTEXT_NONE = 0, /* OpenGL 2.x. Driver can choose to use latest compatibility context. */ RETRO_HW_CONTEXT_OPENGL = 1, /* OpenGL ES 2.0. */ RETRO_HW_CONTEXT_OPENGLES2 = 2, /* Modern desktop core GL context. Use version_major/ * version_minor fields to set GL version. */ RETRO_HW_CONTEXT_OPENGL_CORE = 3, /* OpenGL ES 3.0 */ RETRO_HW_CONTEXT_OPENGLES3 = 4, /* OpenGL ES 3.1+. Set version_major/version_minor. For GLES2 and GLES3, * use the corresponding enums directly. */ RETRO_HW_CONTEXT_OPENGLES_VERSION = 5, RETRO_HW_CONTEXT_DUMMY = INT_MAX }; struct retro_hw_render_callback { /* Which API to use. Set by libretro core. */ enum retro_hw_context_type context_type; /* Called when a context has been created or when it has been reset. * An OpenGL context is only valid after context_reset() has been called. * * When context_reset is called, OpenGL resources in the libretro * implementation are guaranteed to be invalid. * * It is possible that context_reset is called multiple times during an * application lifecycle. * If context_reset is called without any notification (context_destroy), * the OpenGL context was lost and resources should just be recreated * without any attempt to "free" old resources. */ retro_hw_context_reset_t context_reset; /* Set by frontend. */ retro_hw_get_current_framebuffer_t get_current_framebuffer; /* Set by frontend. */ retro_hw_get_proc_address_t get_proc_address; /* Set if render buffers should have depth component attached. */ bool depth; /* Set if stencil buffers should be attached. */ bool stencil; /* If depth and stencil are true, a packed 24/8 buffer will be added. * Only attaching stencil is invalid and will be ignored. */ /* Use conventional bottom-left origin convention. If false, * standard libretro top-left origin semantics are used. */ bool bottom_left_origin; /* Major version number for core GL context or GLES 3.1+. */ unsigned version_major; /* Minor version number for core GL context or GLES 3.1+. */ unsigned version_minor; /* If this is true, the frontend will go very far to avoid * resetting context in scenarios like toggling fullscreen, etc. */ bool cache_context; /* The reset callback might still be called in extreme situations * such as if the context is lost beyond recovery. * * For optimal stability, set this to false, and allow context to be * reset at any time. */ /* A callback to be called before the context is destroyed in a * controlled way by the frontend. */ retro_hw_context_reset_t context_destroy; /* OpenGL resources can be deinitialized cleanly at this step. * context_destroy can be set to NULL, in which resources will * just be destroyed without any notification. * * Even when context_destroy is non-NULL, it is possible that * context_reset is called without any destroy notification. * This happens if context is lost by external factors (such as * notified by GL_ARB_robustness). * * In this case, the context is assumed to be already dead, * and the libretro implementation must not try to free any OpenGL * resources in the subsequent context_reset. */ /* Creates a debug context. */ bool debug_context; }; /* Callback type passed in RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK. * Called by the frontend in response to keyboard events. * down is set if the key is being pressed, or false if it is being released. * keycode is the RETROK value of the char. * character is the text character of the pressed key. (UTF-32). * key_modifiers is a set of RETROKMOD values or'ed together. * * The pressed/keycode state can be indepedent of the character. * It is also possible that multiple characters are generated from a * single keypress. * Keycode events should be treated separately from character events. * However, when possible, the frontend should try to synchronize these. * If only a character is posted, keycode should be RETROK_UNKNOWN. * * Similarily if only a keycode event is generated with no corresponding * character, character should be 0. */ typedef void (*retro_keyboard_event_t)(bool down, unsigned keycode, uint32_t character, uint16_t key_modifiers); struct retro_keyboard_callback { retro_keyboard_event_t callback; }; /* Callbacks for RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE. * Should be set for implementations which can swap out multiple disk * images in runtime. * * If the implementation can do this automatically, it should strive to do so. * However, there are cases where the user must manually do so. * * Overview: To swap a disk image, eject the disk image with * set_eject_state(true). * Set the disk index with set_image_index(index). Insert the disk again * with set_eject_state(false). */ /* If ejected is true, "ejects" the virtual disk tray. * When ejected, the disk image index can be set. */ typedef bool (*retro_set_eject_state_t)(bool ejected); /* Gets current eject state. The initial state is 'not ejected'. */ typedef bool (*retro_get_eject_state_t)(void); /* Gets current disk index. First disk is index 0. * If return value is >= get_num_images(), no disk is currently inserted. */ typedef unsigned (*retro_get_image_index_t)(void); /* Sets image index. Can only be called when disk is ejected. * The implementation supports setting "no disk" by using an * index >= get_num_images(). */ typedef bool (*retro_set_image_index_t)(unsigned index); /* Gets total number of images which are available to use. */ typedef unsigned (*retro_get_num_images_t)(void); struct retro_game_info; /* Replaces the disk image associated with index. * Arguments to pass in info have same requirements as retro_load_game(). * Virtual disk tray must be ejected when calling this. * * Replacing a disk image with info = NULL will remove the disk image * from the internal list. * As a result, calls to get_image_index() can change. * * E.g. replace_image_index(1, NULL), and previous get_image_index() * returned 4 before. * Index 1 will be removed, and the new index is 3. */ typedef bool (*retro_replace_image_index_t)(unsigned index, const struct retro_game_info *info); /* Adds a new valid index (get_num_images()) to the internal disk list. * This will increment subsequent return values from get_num_images() by 1. * This image index cannot be used until a disk image has been set * with replace_image_index. */ typedef bool (*retro_add_image_index_t)(void); struct retro_disk_control_callback { retro_set_eject_state_t set_eject_state; retro_get_eject_state_t get_eject_state; retro_get_image_index_t get_image_index; retro_set_image_index_t set_image_index; retro_get_num_images_t get_num_images; retro_replace_image_index_t replace_image_index; retro_add_image_index_t add_image_index; }; enum retro_pixel_format { /* 0RGB1555, native endian. * 0 bit must be set to 0. * This pixel format is default for compatibility concerns only. * If a 15/16-bit pixel format is desired, consider using RGB565. */ RETRO_PIXEL_FORMAT_0RGB1555 = 0, /* XRGB8888, native endian. * X bits are ignored. */ RETRO_PIXEL_FORMAT_XRGB8888 = 1, /* RGB565, native endian. * This pixel format is the recommended format to use if a 15/16-bit * format is desired as it is the pixel format that is typically * available on a wide range of low-power devices. * * It is also natively supported in APIs like OpenGL ES. */ RETRO_PIXEL_FORMAT_RGB565 = 2, /* Ensure sizeof() == sizeof(int). */ RETRO_PIXEL_FORMAT_UNKNOWN = INT_MAX }; struct retro_message { const char *msg; /* Message to be displayed. */ unsigned frames; /* Duration in frames of message. */ }; /* Describes how the libretro implementation maps a libretro input bind * to its internal input system through a human readable string. * This string can be used to better let a user configure input. */ struct retro_input_descriptor { /* Associates given parameters with a description. */ unsigned port; unsigned device; unsigned index; unsigned id; /* Human readable description for parameters. * The pointer must remain valid until * retro_unload_game() is called. */ const char *description; }; struct retro_system_info { /* All pointers are owned by libretro implementation, and pointers must * remain valid until retro_deinit() is called. */ const char *library_name; /* Descriptive name of library. Should not * contain any version numbers, etc. */ const char *library_version; /* Descriptive version of core. */ const char *valid_extensions; /* A string listing probably content * extensions the core will be able to * load, separated with pipe. * I.e. "bin|rom|iso". * Typically used for a GUI to filter * out extensions. */ /* If true, retro_load_game() is guaranteed to provide a valid pathname * in retro_game_info::path. * ::data and ::size are both invalid. * * If false, ::data and ::size are guaranteed to be valid, but ::path * might not be valid. * * This is typically set to true for libretro implementations that must * load from file. * Implementations should strive for setting this to false, as it allows * the frontend to perform patching, etc. */ bool need_fullpath; /* If true, the frontend is not allowed to extract any archives before * loading the real content. * Necessary for certain libretro implementations that load games * from zipped archives. */ bool block_extract; }; struct retro_game_geometry { unsigned base_width; /* Nominal video width of game. */ unsigned base_height; /* Nominal video height of game. */ unsigned max_width; /* Maximum possible width of game. */ unsigned max_height; /* Maximum possible height of game. */ float aspect_ratio; /* Nominal aspect ratio of game. If * aspect_ratio is <= 0.0, an aspect ratio * of base_width / base_height is assumed. * A frontend could override this setting, * if desired. */ }; struct retro_system_timing { double fps; /* FPS of video content. */ double sample_rate; /* Sampling rate of audio. */ }; struct retro_system_av_info { struct retro_game_geometry geometry; struct retro_system_timing timing; }; struct retro_variable { /* Variable to query in RETRO_ENVIRONMENT_GET_VARIABLE. * If NULL, obtains the complete environment string if more * complex parsing is necessary. * The environment string is formatted as key-value pairs * delimited by semicolons as so: * "key1=value1;key2=value2;..." */ const char *key; /* Value to be obtained. If key does not exist, it is set to NULL. */ const char *value; }; struct retro_game_info { const char *path; /* Path to game, UTF-8 encoded. * Usually used as a reference. * May be NULL if rom was loaded from stdin * or similar. * retro_system_info::need_fullpath guaranteed * that this path is valid. */ const void *data; /* Memory buffer of loaded game. Will be NULL * if need_fullpath was set. */ size_t size; /* Size of memory buffer. */ const char *meta; /* String of implementation specific meta-data. */ }; /* Callbacks */ /* Environment callback. Gives implementations a way of performing * uncommon tasks. Extensible. */ typedef bool (*retro_environment_t)(unsigned cmd, void *data); /* Render a frame. Pixel format is 15-bit 0RGB1555 native endian * unless changed (see RETRO_ENVIRONMENT_SET_PIXEL_FORMAT). * * Width and height specify dimensions of buffer. * Pitch specifices length in bytes between two lines in buffer. * * For performance reasons, it is highly recommended to have a frame * that is packed in memory, i.e. pitch == width * byte_per_pixel. * Certain graphic APIs, such as OpenGL ES, do not like textures * that are not packed in memory. */ typedef void (*retro_video_refresh_t)(const void *data, unsigned width, unsigned height, size_t pitch); /* Renders a single audio frame. Should only be used if implementation * generates a single sample at a time. * Format is signed 16-bit native endian. */ typedef void (*retro_audio_sample_t)(int16_t left, int16_t right); /* Renders multiple audio frames in one go. * * One frame is defined as a sample of left and right channels, interleaved. * I.e. int16_t buf[4] = { l, r, l, r }; would be 2 frames. * Only one of the audio callbacks must ever be used. */ typedef size_t (*retro_audio_sample_batch_t)(const int16_t *data, size_t frames); /* Polls input. */ typedef void (*retro_input_poll_t)(void); /* Queries for input for player 'port'. device will be masked with * RETRO_DEVICE_MASK. * * Specialization of devices such as RETRO_DEVICE_JOYPAD_MULTITAP that * have been set with retro_set_controller_port_device() * will still use the higher level RETRO_DEVICE_JOYPAD to request input. */ typedef int16_t (*retro_input_state_t)(unsigned port, unsigned device, unsigned index, unsigned id); /* Sets callbacks. retro_set_environment() is guaranteed to be called * before retro_init(). * * The rest of the set_* functions are guaranteed to have been called * before the first call to retro_run() is made. */ void retro_set_environment(retro_environment_t); void retro_set_video_refresh(retro_video_refresh_t); void retro_set_audio_sample(retro_audio_sample_t); void retro_set_audio_sample_batch(retro_audio_sample_batch_t); void retro_set_input_poll(retro_input_poll_t); void retro_set_input_state(retro_input_state_t); /* Library global initialization/deinitialization. */ void retro_init(void); void retro_deinit(void); /* Must return RETRO_API_VERSION. Used to validate ABI compatibility * when the API is revised. */ unsigned retro_api_version(void); /* Gets statically known system info. Pointers provided in *info * must be statically allocated. * Can be called at any time, even before retro_init(). */ void retro_get_system_info(struct retro_system_info *info); /* Gets information about system audio/video timings and geometry. * Can be called only after retro_load_game() has successfully completed. * NOTE: The implementation of this function might not initialize every * variable if needed. * E.g. geom.aspect_ratio might not be initialized if core doesn't * desire a particular aspect ratio. */ void retro_get_system_av_info(struct retro_system_av_info *info); /* Sets device to be used for player 'port'. * By default, RETRO_DEVICE_JOYPAD is assumed to be plugged into all * available ports. * Setting a particular device type is not a guarantee that libretro cores * will only poll input based on that particular device type. It is only a * hint to the libretro core when a core cannot automatically detect the * appropriate input device type on its own. It is also relevant when a * core can change its behavior depending on device type. */ void retro_set_controller_port_device(unsigned port, unsigned device); /* Resets the current game. */ void retro_reset(void); /* Runs the game for one video frame. * During retro_run(), input_poll callback must be called at least once. * * If a frame is not rendered for reasons where a game "dropped" a frame, * this still counts as a frame, and retro_run() should explicitly dupe * a frame if GET_CAN_DUPE returns true. * In this case, the video callback can take a NULL argument for data. */ void retro_run(void); /* Returns the amount of data the implementation requires to serialize * internal state (save states). * Between calls to retro_load_game() and retro_unload_game(), the * returned size is never allowed to be larger than a previous returned * value, to ensure that the frontend can allocate a save state buffer once. */ size_t retro_serialize_size(void); /* Serializes internal state. If failed, or size is lower than * retro_serialize_size(), it should return false, true otherwise. */ bool retro_serialize(void *data, size_t size); bool retro_unserialize(const void *data, size_t size); void retro_cheat_reset(void); void retro_cheat_set(unsigned index, bool enabled, const char *code); /* Loads a game. */ bool retro_load_game(const struct retro_game_info *game); /* Loads a "special" kind of game. Should not be used, * except in extreme cases. */ bool retro_load_game_special( unsigned game_type, const struct retro_game_info *info, size_t num_info ); /* Unloads a currently loaded game. */ void retro_unload_game(void); /* Gets region of game. */ unsigned retro_get_region(void); /* Gets region of memory. */ void *retro_get_memory_data(unsigned id); size_t retro_get_memory_size(unsigned id); #ifdef __cplusplus } #endif #endif mupen64plus-rsp-hle/src/alist_audio.c000664 001750 001750 00000021375 12655644434 020731 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-rsp-hle - alist_audio.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * Copyright (C) 2009 Richard Goedeken * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include "common.h" #include "alist.h" #include "hle_internal.h" #include "memory.h" enum { DMEM_BASE = 0x5c0 }; /* helper functions */ #define get_address(hle, so) (alist_get_address((hle), (so), (hle)->alist_audio.segments, N_SEGMENTS)) #define set_address(hle, so) alist_set_address((hle), (so), (hle)->alist_audio.segments, N_SEGMENTS) #define clear_segments(hle) memset((hle)->alist_audio.segments, 0, N_SEGMENTS*sizeof((hle)->alist_audio.segments[0])) /* audio commands definition */ static void SPNOOP(struct hle_t* UNUSED(hle), uint32_t UNUSED(w1), uint32_t UNUSED(w2)) { } static void CLEARBUFF(struct hle_t* hle, uint32_t w1, uint32_t count) { uint16_t dmem = w1 + DMEM_BASE; if (count != 0) alist_clear(hle, dmem, align(count, 16)); } static void ENVMIXER(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint8_t flags = (w1 >> 16); uint32_t address = get_address(hle, w2); alist_envmix_exp( hle, flags & A_INIT, flags & A_AUX, hle->alist_audio.out, hle->alist_audio.dry_right, hle->alist_audio.wet_left, hle->alist_audio.wet_right, hle->alist_audio.in, hle->alist_audio.count, hle->alist_audio.dry, hle->alist_audio.wet, hle->alist_audio.vol, hle->alist_audio.target, hle->alist_audio.rate, address); } static void ENVMIXER_GE(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint8_t flags = (w1 >> 16); uint32_t address = get_address(hle, w2); alist_envmix_ge( hle, flags & A_INIT, flags & A_AUX, hle->alist_audio.out, hle->alist_audio.dry_right, hle->alist_audio.wet_left, hle->alist_audio.wet_right, hle->alist_audio.in, hle->alist_audio.count, hle->alist_audio.dry, hle->alist_audio.wet, hle->alist_audio.vol, hle->alist_audio.target, hle->alist_audio.rate, address); } static void RESAMPLE(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint8_t flags = (w1 >> 16); uint16_t pitch = w1; uint32_t address = get_address(hle, w2); alist_resample( hle, flags & 0x1, flags & 0x2, hle->alist_audio.out, hle->alist_audio.in, align(hle->alist_audio.count, 16), pitch << 1, address); } static void SETVOL(struct hle_t* hle, uint32_t w1, uint32_t w2) { unsigned lr; uint8_t flags = (w1 >> 16); if (flags & A_AUX) { hle->alist_audio.dry = w1; hle->alist_audio.wet = w2; return; } lr = (flags & A_LEFT) ? 0 : 1; if (flags & A_VOL) hle->alist_audio.vol[lr] = w1; else { hle->alist_audio.target[lr] = w1; hle->alist_audio.rate[lr] = w2; } } static void SETLOOP(struct hle_t* hle, uint32_t UNUSED(w1), uint32_t w2) { hle->alist_audio.loop = get_address(hle, w2); } static void ADPCM(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint8_t flags = (w1 >> 16); uint32_t address = get_address(hle, w2); alist_adpcm( hle, flags & 0x1, flags & 0x2, false, /* unsupported in this ucode */ hle->alist_audio.out, hle->alist_audio.in, align(hle->alist_audio.count, 32), hle->alist_audio.table, hle->alist_audio.loop, address); } static void LOADBUFF(struct hle_t* hle, uint32_t UNUSED(w1), uint32_t w2) { uint32_t address = get_address(hle, w2); if (hle->alist_audio.count != 0) alist_load(hle, hle->alist_audio.in, address, hle->alist_audio.count); } static void SAVEBUFF(struct hle_t* hle, uint32_t UNUSED(w1), uint32_t w2) { uint32_t address = get_address(hle, w2); if (hle->alist_audio.count != 0) alist_save(hle, hle->alist_audio.out, address, hle->alist_audio.count); } static void SETBUFF(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint8_t flags = (w1 >> 16); if (flags & A_AUX) { hle->alist_audio.dry_right = w1 + DMEM_BASE; hle->alist_audio.wet_left = (w2 >> 16) + DMEM_BASE; hle->alist_audio.wet_right = w2 + DMEM_BASE; } else { hle->alist_audio.in = w1 + DMEM_BASE; hle->alist_audio.out = (w2 >> 16) + DMEM_BASE; hle->alist_audio.count = w2; } } static void DMEMMOVE(struct hle_t* hle, uint32_t w1, uint32_t count) { uint16_t dmemi = w1 + DMEM_BASE; uint16_t dmemo = (count >> 16) + DMEM_BASE; if (count != 0) alist_move(hle, dmemo, dmemi, align(count, 16)); } static void LOADADPCM(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint16_t count = w1; uint32_t address = get_address(hle, w2); dram_load_u16(hle, (uint16_t*)hle->alist_audio.table, address, align(count, 8) >> 1); } static void INTERLEAVE(struct hle_t* hle, uint32_t UNUSED(w1), uint32_t w2) { uint16_t left = (w2 >> 16) + DMEM_BASE; uint16_t right = w2 + DMEM_BASE; if (hle->alist_audio.count != 0) alist_interleave(hle, hle->alist_audio.out, left, right, align(hle->alist_audio.count, 16)); } static void MIXER(struct hle_t* hle, uint32_t w1, uint32_t w2) { int16_t gain = w1; uint16_t dmemi = (w2 >> 16) + DMEM_BASE; uint16_t dmemo = w2 + DMEM_BASE; if (hle->alist_audio.count != 0) alist_mix(hle, dmemo, dmemi, align(hle->alist_audio.count, 32), gain); } static void SEGMENT(struct hle_t* hle, uint32_t UNUSED(w1), uint32_t w2) { set_address(hle, w2); } static void POLEF(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint8_t flags = (w1 >> 16); uint16_t gain = w1; uint32_t address = get_address(hle, w2); if (hle->alist_audio.count != 0) alist_polef( hle, flags & A_INIT, hle->alist_audio.out, hle->alist_audio.in, align(hle->alist_audio.count, 16), gain, hle->alist_audio.table, address); } /* global functions */ void alist_process_audio(struct hle_t* hle) { static const acmd_callback_t ABI[0x10] = { SPNOOP, ADPCM , CLEARBUFF, ENVMIXER, LOADBUFF, RESAMPLE, SAVEBUFF, SEGMENT, SETBUFF, SETVOL, DMEMMOVE, LOADADPCM, MIXER, INTERLEAVE, POLEF, SETLOOP }; clear_segments(hle); alist_process(hle, ABI, 0x10); } void alist_process_audio_ge(struct hle_t* hle) { static const acmd_callback_t ABI[0x10] = { SPNOOP, ADPCM , CLEARBUFF, ENVMIXER_GE, LOADBUFF, RESAMPLE, SAVEBUFF, SEGMENT, SETBUFF, SETVOL, DMEMMOVE, LOADADPCM, MIXER, INTERLEAVE, POLEF, SETLOOP }; clear_segments(hle); alist_process(hle, ABI, 0x10); } void alist_process_audio_bc(struct hle_t* hle) { static const acmd_callback_t ABI[0x10] = { SPNOOP, ADPCM , CLEARBUFF, ENVMIXER_GE, LOADBUFF, RESAMPLE, SAVEBUFF, SEGMENT, SETBUFF, SETVOL, DMEMMOVE, LOADADPCM, MIXER, INTERLEAVE, POLEF, SETLOOP }; clear_segments(hle); alist_process(hle, ABI, 0x10); } mupen64plus-video-gliden64/src/GLideNHQ/TextureFilters.cpp000664 001750 001750 00000044424 12655644434 024466 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Copyright (C) 2007 Hiroshi Morii * Modified for the Texture Filtering library */ #include #include "TextureFilters.h" /************************************************************************/ /* 2X filters */ /************************************************************************/ #define DWORD_MAKE(r, g, b, a) ((uint32) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))) #define WORD_MAKE(r, g, b, a) ((uint16) (((a) << 12) | ((r) << 8) | ((g) << 4) | (b))) // Basic 2x R8G8B8A8 filter with interpolation void Texture2x_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { uint32 *pDst1, *pDst2; uint32 *pSrc, *pSrc2; uint32 nWidth = width; uint32 nHeight = height; uint32 b1 = 0; uint32 g1 = 0; uint32 r1 = 0; uint32 a1 = 0; uint32 b2 = 0; uint32 g2 = 0; uint32 r2 = 0; uint32 a2 = 0; uint32 b3 = 0; uint32 g3 = 0; uint32 r3 = 0; uint32 a3 = 0; uint32 b4 = 0; uint32 g4 = 0; uint32 r4 = 0; uint32 a4 = 0; uint32 xSrc; uint32 ySrc; for (ySrc = 0; ySrc < nHeight; ySrc++) { pSrc = (uint32*)(((uint8*)srcPtr)+ySrc*srcPitch); pSrc2 = (uint32*)(((uint8*)srcPtr)+(ySrc+1)*srcPitch); pDst1 = (uint32*)(((uint8*)dstPtr)+(ySrc*2)*dstPitch); pDst2 = (uint32*)(((uint8*)dstPtr)+(ySrc*2+1)*dstPitch); for (xSrc = 0; xSrc < nWidth; xSrc++) { b1 = (pSrc[xSrc]>>0)&0xFF; g1 = (pSrc[xSrc]>>8)&0xFF; r1 = (pSrc[xSrc]>>16)&0xFF; a1 = (pSrc[xSrc]>>24)&0xFF; if( xSrc>0)&0xFF; g2 = (pSrc[xSrc+1]>>8)&0xFF; r2 = (pSrc[xSrc+1]>>16)&0xFF; a2 = (pSrc[xSrc+1]>>24)&0xFF; } if( ySrc>0)&0xFF; g3 = (pSrc2[xSrc]>>8)&0xFF; r3 = (pSrc2[xSrc]>>16)&0xFF; a3 = (pSrc2[xSrc]>>24)&0xFF; if( xSrc>0)&0xFF; g4 = (pSrc2[xSrc+1]>>8)&0xFF; r4 = (pSrc2[xSrc+1]>>16)&0xFF; a4 = (pSrc2[xSrc+1]>>24)&0xFF; } } // Pixel 1 pDst1[xSrc*2] = pSrc[xSrc]; // Pixel 2 if( xSrc> 0)&0xF; g1 = (pSrc[xSrc]>> 4)&0xF; r1 = (pSrc[xSrc]>> 8)&0xF; a1 = (pSrc[xSrc]>>12)&0xF; if( xSrc> 0)&0xF; g2 = (pSrc[xSrc+1]>> 4)&0xF; r2 = (pSrc[xSrc+1]>> 8)&0xF; a2 = (pSrc[xSrc+1]>>12)&0xF; } if( ySrc> 0)&0xF; g3 = (pSrc2[xSrc]>> 4)&0xF; r3 = (pSrc2[xSrc]>> 8)&0xF; a3 = (pSrc2[xSrc]>>12)&0xF; if( xSrc> 0)&0xF; g4 = (pSrc2[xSrc+1]>> 4)&0xF; r4 = (pSrc2[xSrc+1]>> 8)&0xF; a4 = (pSrc2[xSrc+1]>>12)&0xF; } } // Pixel 1 pDst1[xSrc*2] = pSrc[xSrc]; // Pixel 2 if( xSrc */ void SharpFilter_8888(uint32 *src, uint32 srcwidth, uint32 srcheight, uint32 *dest, uint32 filter) { // NOTE: for now we get away with copying the boundaries // filter the boundaries if we face problems uint32 mul1, mul2, mul3, shift4; uint32 x,y,z; uint32 *_src1, *_src2, *_src3, *_dest; uint32 val[4]; uint32 t1,t2,t3,t4,t5,t6,t7,t8,t9; switch( filter ) { case SHARP_FILTER_2: mul1=1; mul2=8; mul3=12; shift4=2; break; case SHARP_FILTER_1: default: mul1=1; mul2=8; mul3=16; shift4=3; break; } // setup rows _src1 = src; _src2 = _src1 + srcwidth; _src3 = _src2 + srcwidth; _dest = dest; // copy the first row memcpy(_dest, _src1, (srcwidth << 2)); _dest += srcwidth; // filter 2nd row to 1 row before the last for (y = 1; y < srcheight-1; y++) { // copy the first pixel _dest[0] = *_src2; // filter 2nd pixel to 1 pixel before last for (x = 1; x < srcwidth-1; x++) { for (z=0; z<4; z++) { t1 = *((uint8*)(_src1+x-1)+z); t2 = *((uint8*)(_src1+x )+z); t3 = *((uint8*)(_src1+x+1)+z); t4 = *((uint8*)(_src2+x-1)+z); t5 = *((uint8*)(_src2+x )+z); t6 = *((uint8*)(_src2+x+1)+z); t7 = *((uint8*)(_src3+x-1)+z); t8 = *((uint8*)(_src3+x )+z); t9 = *((uint8*)(_src3+x+1)+z); if( (t5*mul2) > (t1+t3+t7+t9+t2+t4+t6+t8)*mul1 ) { val[z]= ((t5*mul3) - (t1+t3+t7+t9+t2+t4+t6+t8)*mul1)>>shift4; if (val[z] > 0xFF) val[z] = 0xFF; } else { val[z] = t5; } } _dest[x] = val[0]|(val[1]<<8)|(val[2]<<16)|(val[3]<<24); } // copy the ending pixel _dest[srcwidth-1] = *(_src3 - 1); // next row _src1 += srcwidth; _src2 += srcwidth; _src3 += srcwidth; _dest += srcwidth; } // copy the last row memcpy(_dest, _src2, (srcwidth << 2)); } #if !_16BPP_HACK void SharpFilter_4444(uint16 *src, uint32 srcwidth, uint32 srcheight, uint16 *dest, uint32 filter) { // NOTE: for now we get away with copying the boundaries // filter the boundaries if we face problems uint16 mul1, mul2, mul3, shift4; uint32 x,y,z; uint16 *_src1, *_src2, *_src3, *_dest; uint16 val[4]; uint16 t1,t2,t3,t4,t5,t6,t7,t8,t9; switch( filter ) { case SHARP_FILTER_2: mul1=1; mul2=8; mul3=12; shift4=2; break; case SHARP_FILTER_1: default: mul1=1; mul2=8; mul3=16; shift4=3; break; } // setup rows _src1 = src; _src2 = _src1 + srcwidth; _src3 = _src2 + srcwidth; _dest = dest; // copy the first row memcpy(_dest, _src1, (srcwidth << 1)); _dest += srcwidth; // filter 2nd row to 1 row before the last for( y = 1; y < srcheight - 1; y++) { // copy the first pixel _dest[0] = *_src2; // filter 2nd pixel to 1 pixel before last for( x = 1; x < srcwidth - 1; x++) { for( z = 0; z < 4; z++ ) { /* Hiroshi Morii * Read the entire 16bit pixel and then extract the A,R,G,B components. */ uint32 shift = z << 2; t1 = ((*((uint16*)(_src1+x-1))) >> shift) & 0xF; t2 = ((*((uint16*)(_src1+x ))) >> shift) & 0xF; t3 = ((*((uint16*)(_src1+x+1))) >> shift) & 0xF; t4 = ((*((uint16*)(_src2+x-1))) >> shift) & 0xF; t5 = ((*((uint16*)(_src2+x ))) >> shift) & 0xF; t6 = ((*((uint16*)(_src2+x+1))) >> shift) & 0xF; t7 = ((*((uint16*)(_src3+x-1))) >> shift) & 0xF; t8 = ((*((uint16*)(_src3+x ))) >> shift) & 0xF; t9 = ((*((uint16*)(_src3+x+1))) >> shift) & 0xF; if( (t5*mul2) > (t1+t3+t7+t9+t2+t4+t6+t8)*mul1 ) { val[z] = ((t5*mul3) - (t1+t3+t7+t9+t2+t4+t6+t8)*mul1)>>shift4; if (val[z] > 0xF) val[z] = 0xF; } else { val[z] = t5; } } _dest[x] = val[0]|(val[1]<<4)|(val[2]<<8)|(val[3]<<12); } // copy the ending pixel _dest[srcwidth-1] = *(_src3 - 1); // next row _src1 += srcwidth; _src2 += srcwidth; _src3 += srcwidth; _dest += srcwidth; } // copy the last row memcpy(_dest, _src2, (srcwidth << 1)); } #endif /* !_16BPP_HACK */ /* * Smooth filters * Hiroshi Morii */ void SmoothFilter_8888(uint32 *src, uint32 srcwidth, uint32 srcheight, uint32 *dest, uint32 filter) { // NOTE: for now we get away with copying the boundaries // filter the boundaries if we face problems uint32 mul1, mul2, mul3, shift4; uint32 x,y,z; uint32 *_src1, *_src2, *_src3, *_dest; uint32 val[4]; uint32 t1,t2,t3,t4,t5,t6,t7,t8,t9; switch( filter ) { case SMOOTH_FILTER_4: mul1=1; mul2=2; mul3=4; shift4=4; break; case SMOOTH_FILTER_3: mul1=1; mul2=1; mul3=8; shift4=4; break; case SMOOTH_FILTER_2: mul1=1; mul2=1; mul3=2; shift4=2; break; case SMOOTH_FILTER_1: default: mul1=1; mul2=1; mul3=6; shift4=3; break; } switch (filter) { case SMOOTH_FILTER_3: case SMOOTH_FILTER_4: // setup rows _src1 = src; _src2 = _src1 + srcwidth; _src3 = _src2 + srcwidth; _dest = dest; // copy the first row memcpy(_dest, _src1, (srcwidth << 2)); _dest += srcwidth; // filter 2nd row to 1 row before the last for (y = 1; y < srcheight - 1; y++){ // copy the first pixel _dest[0] = _src2[0]; // filter 2nd pixel to 1 pixel before last for (x = 1; x < srcwidth - 1; x++) { for (z = 0; z < 4; z++ ) { t1 = *((uint8*)(_src1+x-1)+z); t2 = *((uint8*)(_src1+x )+z); t3 = *((uint8*)(_src1+x+1)+z); t4 = *((uint8*)(_src2+x-1)+z); t5 = *((uint8*)(_src2+x )+z); t6 = *((uint8*)(_src2+x+1)+z); t7 = *((uint8*)(_src3+x-1)+z); t8 = *((uint8*)(_src3+x )+z); t9 = *((uint8*)(_src3+x+1)+z); /* the component value must not overflow 0xFF */ val[z] = ((t1+t3+t7+t9)*mul1+((t2+t4+t6+t8)*mul2)+(t5*mul3))>>shift4; if (val[z] > 0xFF) val[z] = 0xFF; } _dest[x] = val[0]|(val[1]<<8)|(val[2]<<16)|(val[3]<<24); } // copy the ending pixel _dest[srcwidth-1] = *(_src3 - 1); // next row _src1 += srcwidth; _src2 += srcwidth; _src3 += srcwidth; _dest += srcwidth; } // copy the last row memcpy(_dest, _src2, (srcwidth << 2)); break; case SMOOTH_FILTER_1: case SMOOTH_FILTER_2: default: // setup rows _src1 = src; _src2 = _src1 + srcwidth; _src3 = _src2 + srcwidth; _dest = dest; // copy the first row memcpy(_dest, _src1, (srcwidth << 2)); _dest += srcwidth; // filter 2nd row to 1 row before the last for (y = 1; y < srcheight - 1; y++) { // filter 1st pixel to the last if (y & 1) { for( x = 0; x < srcwidth; x++) { for( z = 0; z < 4; z++ ) { t2 = *((uint8*)(_src1+x )+z); t5 = *((uint8*)(_src2+x )+z); t8 = *((uint8*)(_src3+x )+z); /* the component value must not overflow 0xFF */ val[z] = ((t2+t8)*mul2+(t5*mul3))>>shift4; if (val[z] > 0xFF) val[z] = 0xFF; } _dest[x] = val[0]|(val[1]<<8)|(val[2]<<16)|(val[3]<<24); } } else { memcpy(_dest, _src2, (srcwidth << 2)); } // next row _src1 += srcwidth; _src2 += srcwidth; _src3 += srcwidth; _dest += srcwidth; } // copy the last row memcpy(_dest, _src2, (srcwidth << 2)); break; } } #if !_16BPP_HACK void SmoothFilter_4444(uint16 *src, uint32 srcwidth, uint32 srcheight, uint16 *dest, uint32 filter) { // NOTE: for now we get away with copying the boundaries // filter the boundaries if we face problems uint16 mul1, mul2, mul3, shift4; uint32 x,y,z; uint16 *_src1, *_src2, *_src3, *_dest; uint16 val[4]; uint16 t1,t2,t3,t4,t5,t6,t7,t8,t9; switch( filter ) { case SMOOTH_FILTER_4: mul1=1; mul2=2; mul3=4; shift4=4; break; case SMOOTH_FILTER_3: mul1=1; mul2=1; mul3=8; shift4=4; break; case SMOOTH_FILTER_2: mul1=1; mul2=1; mul3=2; shift4=2; break; case SMOOTH_FILTER_1: default: mul1=1; mul2=1; mul3=6; shift4=3; break; } switch (filter) { case SMOOTH_FILTER_3: case SMOOTH_FILTER_4: // setup rows _src1 = src; _src2 = _src1 + srcwidth; _src3 = _src2 + srcwidth; _dest = dest; // copy the first row memcpy(_dest, _src1, (srcwidth << 1)); _dest += srcwidth; // filter 2nd row to 1 row before the last for (y = 1; y < srcheight - 1; y++) { // copy the first pixel _dest[0] = *_src2; // filter 2nd pixel to 1 pixel before last for (x = 1; x < srcwidth - 1; x++) { for (z = 0; z < 4; z++ ) { /* Read the entire 16bit pixel and then extract the A,R,G,B components. */ uint32 shift = z << 2; t1 = ((*(uint16*)(_src1+x-1)) >> shift) & 0xF; t2 = ((*(uint16*)(_src1+x )) >> shift) & 0xF; t3 = ((*(uint16*)(_src1+x+1)) >> shift) & 0xF; t4 = ((*(uint16*)(_src2+x-1)) >> shift) & 0xF; t5 = ((*(uint16*)(_src2+x )) >> shift) & 0xF; t6 = ((*(uint16*)(_src2+x+1)) >> shift) & 0xF; t7 = ((*(uint16*)(_src3+x-1)) >> shift) & 0xF; t8 = ((*(uint16*)(_src3+x )) >> shift) & 0xF; t9 = ((*(uint16*)(_src3+x+1)) >> shift) & 0xF; /* the component value must not overflow 0xF */ val[z] = ((t1+t3+t7+t9)*mul1+((t2+t4+t6+t8)*mul2)+(t5*mul3))>>shift4; if (val[z] > 0xF) val[z] = 0xF; } _dest[x] = val[0]|(val[1]<<4)|(val[2]<<8)|(val[3]<<12); } // copy the ending pixel _dest[srcwidth-1] = *(_src3 - 1); // next row _src1 += srcwidth; _src2 += srcwidth; _src3 += srcwidth; _dest += srcwidth; } // copy the last row memcpy(_dest, _src2, (srcwidth << 1)); break; case SMOOTH_FILTER_1: case SMOOTH_FILTER_2: default: // setup rows _src1 = src; _src2 = _src1 + srcwidth; _src3 = _src2 + srcwidth; _dest = dest; // copy the first row memcpy(_dest, _src1, (srcwidth << 1)); _dest += srcwidth; // filter 2nd row to 1 row before the last for( y = 1; y < srcheight - 1; y++) { if (y & 1) { for( x = 0; x < srcwidth; x++) { for( z = 0; z < 4; z++ ) { /* Read the entire 16bit pixel and then extract the A,R,G,B components. */ uint32 shift = z << 2; t2 = ((*(uint16*)(_src1+x)) >> shift) & 0xF; t5 = ((*(uint16*)(_src2+x)) >> shift) & 0xF; t8 = ((*(uint16*)(_src3+x)) >> shift) & 0xF; /* the component value must not overflow 0xF */ val[z] = ((t2+t8)*mul2+(t5*mul3))>>shift4; if (val[z] > 0xF) val[z] = 0xF; } _dest[x] = val[0]|(val[1]<<4)|(val[2]<<8)|(val[3]<<12); } } else { memcpy(_dest, _src2, (srcwidth << 1)); } // next row _src1 += srcwidth; _src2 += srcwidth; _src3 += srcwidth; _dest += srcwidth; } // copy the last row memcpy(_dest, _src2, (srcwidth << 1)); break; } } #endif /* !_16BPP_HACK */ void filter_8888(uint32 *src, uint32 srcwidth, uint32 srcheight, uint32 *dest, uint32 filter) { switch (filter & ENHANCEMENT_MASK) { case BRZ2X_ENHANCEMENT: xbrz::scale(2, (const uint32_t *)const_cast(src), (uint32_t *)dest, srcwidth, srcheight, xbrz::ColorFormat::ABGR); return; case BRZ3X_ENHANCEMENT: xbrz::scale(3, (const uint32_t *)const_cast(src), (uint32_t *)dest, srcwidth, srcheight, xbrz::ColorFormat::ABGR); return; case BRZ4X_ENHANCEMENT: xbrz::scale(4, (const uint32_t *)const_cast(src), (uint32_t *)dest, srcwidth, srcheight, xbrz::ColorFormat::ABGR); return; case BRZ5X_ENHANCEMENT: xbrz::scale(5, (const uint32_t *)const_cast(src), (uint32_t *)dest, srcwidth, srcheight, xbrz::ColorFormat::ABGR); return; case BRZ6X_ENHANCEMENT: xbrz::scale(6, (const uint32_t *)const_cast(src), (uint32_t *)dest, srcwidth, srcheight, xbrz::ColorFormat::ABGR); return; case HQ4X_ENHANCEMENT: hq4x_8888((uint8*)src, (uint8*)dest, srcwidth, srcheight, srcwidth, (srcwidth << 4)); return; case HQ2X_ENHANCEMENT: hq2x_32((uint8*)src, (srcwidth << 2), (uint8*)dest, (srcwidth << 3), srcwidth, srcheight); return; case HQ2XS_ENHANCEMENT: hq2xS_32((uint8*)src, (srcwidth << 2), (uint8*)dest, (srcwidth << 3), srcwidth, srcheight); return; case LQ2X_ENHANCEMENT: lq2x_32((uint8*)src, (srcwidth << 2), (uint8*)dest, (srcwidth << 3), srcwidth, srcheight); return; case LQ2XS_ENHANCEMENT: lq2xS_32((uint8*)src, (srcwidth << 2), (uint8*)dest, (srcwidth << 3), srcwidth, srcheight); return; case X2SAI_ENHANCEMENT: Super2xSaI_8888((uint32*)src, (uint32*)dest, srcwidth, srcheight, srcwidth); return; case X2_ENHANCEMENT: Texture2x_32((uint8*)src, (srcwidth << 2), (uint8*)dest, (srcwidth << 3), srcwidth, srcheight); return; } switch (filter & (SMOOTH_FILTER_MASK|SHARP_FILTER_MASK)) { case SMOOTH_FILTER_1: case SMOOTH_FILTER_2: case SMOOTH_FILTER_3: case SMOOTH_FILTER_4: SmoothFilter_8888((uint32*)src, srcwidth, srcheight, (uint32*)dest, (filter & SMOOTH_FILTER_MASK)); return; case SHARP_FILTER_1: case SHARP_FILTER_2: SharpFilter_8888((uint32*)src, srcwidth, srcheight, (uint32*)dest, (filter & SHARP_FILTER_MASK)); return; } } mupen64plus-core/src/plugin/plugin.c000664 001750 001750 00000023175 12655644434 020606 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - plugin.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * Copyright (C) 2009 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include "plugin.h" #include "r4300/r4300_core.h" #include "../rdp/rdp_core.h" #include "../rsp/rsp_core.h" #include "../vi/vi_controller.h" #include "api/callbacks.h" #include "api/m64p_common.h" #include "api/m64p_plugin.h" #include "api/m64p_types.h" #include "main/main.h" #include "main/rom.h" #include "main/version.h" #include "memory/memory.h" static unsigned int dummy; /* local functions */ static void EmptyFunc(void) { } static m64p_error EmptyGetVersionFunc(m64p_plugin_type *PluginType, int *PluginVersion, int *APIVersion, const char **PluginNamePtr, int *Capabilities) { return M64ERR_SUCCESS; } /* local data structures and functions */ #define DEFINE_GFX(X) \ EXPORT m64p_error CALL X##PluginGetVersion(m64p_plugin_type *, int *, int *, const char **, int *); \ EXPORT void CALL X##ChangeWindow(void); \ EXPORT int CALL X##InitiateGFX(GFX_INFO Gfx_Info); \ EXPORT void CALL X##MoveScreen(int x, int y); \ EXPORT void CALL X##ProcessDList(void); \ EXPORT void CALL X##ProcessRDPList(void); \ EXPORT void CALL X##RomClosed(void); \ EXPORT int CALL X##RomOpen(void); \ EXPORT void CALL X##ShowCFB(void); \ EXPORT void CALL X##UpdateScreen(void); \ EXPORT void CALL X##ViStatusChanged(void); \ EXPORT void CALL X##ViWidthChanged(void); \ EXPORT void CALL X##ReadScreen2(void *dest, int *width, int *height, int front); \ EXPORT void CALL X##SetRenderingCallback(void (*callback)(int)); \ EXPORT void CALL X##ResizeVideoOutput(int width, int height); \ EXPORT void CALL X##FBRead(unsigned int addr); \ EXPORT void CALL X##FBWrite(unsigned int addr, unsigned int size); \ EXPORT void CALL X##FBGetFrameBufferInfo(void *p); \ \ static const gfx_plugin_functions gfx_##X = { \ X##PluginGetVersion, \ X##ChangeWindow, \ X##InitiateGFX, \ X##MoveScreen, \ X##ProcessDList, \ X##ProcessRDPList, \ X##RomClosed, \ X##RomOpen, \ X##ShowCFB, \ X##UpdateScreen, \ X##ViStatusChanged, \ X##ViWidthChanged, \ X##ReadScreen2, \ X##SetRenderingCallback, \ X##FBRead, \ X##FBWrite, \ X##FBGetFrameBufferInfo \ } DEFINE_GFX(angrylion); DEFINE_GFX(rice); DEFINE_GFX(gln64); DEFINE_GFX(glide64); gfx_plugin_functions gfx; GFX_INFO gfx_info; static m64p_error plugin_start_gfx(void) { /* fill in the GFX_INFO data structure */ gfx_info.HEADER = (unsigned char *) g_rom; gfx_info.RDRAM = (unsigned char *) g_rdram; gfx_info.DMEM = (unsigned char *) g_sp.mem; gfx_info.IMEM = (unsigned char *) g_sp.mem + 0x1000; gfx_info.MI_INTR_REG = &(g_r4300.mi.regs[MI_INTR_REG]); gfx_info.DPC_START_REG = &(g_dp.dpc_regs[DPC_START_REG]); gfx_info.DPC_END_REG = &(g_dp.dpc_regs[DPC_END_REG]); gfx_info.DPC_CURRENT_REG = &(g_dp.dpc_regs[DPC_CURRENT_REG]); gfx_info.DPC_STATUS_REG = &(g_dp.dpc_regs[DPC_STATUS_REG]); gfx_info.DPC_CLOCK_REG = &(g_dp.dpc_regs[DPC_CLOCK_REG]); gfx_info.DPC_BUFBUSY_REG = &(g_dp.dpc_regs[DPC_BUFBUSY_REG]); gfx_info.DPC_PIPEBUSY_REG = &(g_dp.dpc_regs[DPC_PIPEBUSY_REG]); gfx_info.DPC_TMEM_REG = &(g_dp.dpc_regs[DPC_TMEM_REG]); gfx_info.VI_STATUS_REG = &(g_vi.regs[VI_STATUS_REG]); gfx_info.VI_ORIGIN_REG = &(g_vi.regs[VI_ORIGIN_REG]); gfx_info.VI_WIDTH_REG = &(g_vi.regs[VI_WIDTH_REG]); gfx_info.VI_INTR_REG = &(g_vi.regs[VI_V_INTR_REG]); gfx_info.VI_V_CURRENT_LINE_REG = &(g_vi.regs[VI_CURRENT_REG]); gfx_info.VI_TIMING_REG = &(g_vi.regs[VI_BURST_REG]); gfx_info.VI_V_SYNC_REG = &(g_vi.regs[VI_V_SYNC_REG]); gfx_info.VI_H_SYNC_REG = &(g_vi.regs[VI_H_SYNC_REG]); gfx_info.VI_LEAP_REG = &(g_vi.regs[VI_LEAP_REG]); gfx_info.VI_H_START_REG = &(g_vi.regs[VI_H_START_REG]); gfx_info.VI_V_START_REG = &(g_vi.regs[VI_V_START_REG]); gfx_info.VI_V_BURST_REG = &(g_vi.regs[VI_V_BURST_REG]); gfx_info.VI_X_SCALE_REG = &(g_vi.regs[VI_X_SCALE_REG]); gfx_info.VI_Y_SCALE_REG = &(g_vi.regs[VI_Y_SCALE_REG]); gfx_info.CheckInterrupts = EmptyFunc; /* call the audio plugin */ if (!gfx.initiateGFX(gfx_info)) { printf("plugin_start_gfx fail.\n"); return M64ERR_PLUGIN_FAIL; } printf("plugin_start_gfx success.\n"); return M64ERR_SUCCESS; } /* INPUT */ extern m64p_error inputPluginGetVersion(m64p_plugin_type *PluginType, int *PluginVersion, int *APIVersion, const char **PluginNamePtr, int *Capabilities); extern void inputInitiateControllers (CONTROL_INFO ControlInfo); extern void inputControllerCommand(int Control, unsigned char *Command); extern void inputInitiateControllers(CONTROL_INFO ControlInfo); extern void inputReadController(int Control, unsigned char *Command); extern int inputRomOpen(void); extern void inputRomClosed(void); input_plugin_functions input = { inputPluginGetVersion, inputControllerCommand, NULL, inputInitiateControllers, inputReadController, inputRomClosed, inputRomOpen, }; static CONTROL_INFO control_info; CONTROL Controls[4]; static m64p_error plugin_start_input(void) { int i; /* fill in the CONTROL_INFO data structure */ control_info.Controls = Controls; for (i=0; i<4; i++) { Controls[i].Present = 0; Controls[i].RawData = 0; Controls[i].Plugin = PLUGIN_NONE; } /* call the input plugin */ input.initiateControllers(control_info); return M64ERR_SUCCESS; } /* RSP */ #define DEFINE_RSP(X) \ EXPORT m64p_error CALL X##PluginGetVersion(m64p_plugin_type *, int *, int *, const char **, int *); \ EXPORT unsigned int CALL X##DoRspCycles(unsigned int Cycles); \ EXPORT void CALL X##InitiateRSP(RSP_INFO Rsp_Info, unsigned int *CycleCount); \ EXPORT void CALL X##RomClosed(void); \ \ static const rsp_plugin_functions rsp_##X = { \ X##PluginGetVersion, \ X##DoRspCycles, \ X##InitiateRSP, \ X##RomClosed \ } DEFINE_RSP(hle); DEFINE_RSP(cxd4); rsp_plugin_functions rsp; RSP_INFO rsp_info; static m64p_error plugin_start_rsp(void) { /* fill in the RSP_INFO data structure */ rsp_info.RDRAM = (unsigned char *) g_rdram; rsp_info.DMEM = (unsigned char *) g_sp.mem; rsp_info.IMEM = (unsigned char *) g_sp.mem + 0x1000; rsp_info.MI_INTR_REG = &g_r4300.mi.regs[MI_INTR_REG]; rsp_info.SP_MEM_ADDR_REG = &g_sp.regs[SP_MEM_ADDR_REG]; rsp_info.SP_DRAM_ADDR_REG = &g_sp.regs[SP_DRAM_ADDR_REG]; rsp_info.SP_RD_LEN_REG = &g_sp.regs[SP_RD_LEN_REG]; rsp_info.SP_WR_LEN_REG = &g_sp.regs[SP_WR_LEN_REG]; rsp_info.SP_STATUS_REG = &g_sp.regs[SP_STATUS_REG]; rsp_info.SP_DMA_FULL_REG = &g_sp.regs[SP_DMA_FULL_REG]; rsp_info.SP_DMA_BUSY_REG = &g_sp.regs[SP_DMA_BUSY_REG]; rsp_info.SP_PC_REG = &g_sp.regs2[SP_PC_REG]; rsp_info.SP_SEMAPHORE_REG = &g_sp.regs[SP_SEMAPHORE_REG]; rsp_info.DPC_START_REG = &g_dp.dpc_regs[DPC_START_REG]; rsp_info.DPC_END_REG = &g_dp.dpc_regs[DPC_END_REG]; rsp_info.DPC_CURRENT_REG = &g_dp.dpc_regs[DPC_CURRENT_REG]; rsp_info.DPC_STATUS_REG = &g_dp.dpc_regs[DPC_STATUS_REG]; rsp_info.DPC_CLOCK_REG = &g_dp.dpc_regs[DPC_CLOCK_REG]; rsp_info.DPC_BUFBUSY_REG = &g_dp.dpc_regs[DPC_BUFBUSY_REG]; rsp_info.DPC_PIPEBUSY_REG = &g_dp.dpc_regs[DPC_PIPEBUSY_REG]; rsp_info.DPC_TMEM_REG = &g_dp.dpc_regs[DPC_TMEM_REG]; rsp_info.CheckInterrupts = EmptyFunc; rsp_info.ProcessDlistList = gfx.processDList; rsp_info.ProcessAlistList = NULL; rsp_info.ProcessRdpList = gfx.processRDPList; rsp_info.ShowCFB = gfx.showCFB; /* call the RSP plugin */ rsp.initiateRSP(rsp_info, NULL); return M64ERR_SUCCESS; } /* global functions */ void plugin_connect_all(enum gfx_plugin_type gfx_plugin, enum rsp_plugin_type rsp_plugin) { switch (gfx_plugin) { case GFX_ANGRYLION: gfx = gfx_angrylion; break; case GFX_RICE: gfx = gfx_rice; break; case GFX_GLN64: gfx = gfx_gln64; break; default: gfx = gfx_glide64; break; } switch (rsp_plugin) { case RSP_CXD4: rsp = rsp_cxd4; break; default: rsp = rsp_hle; break; } plugin_start_gfx(); plugin_start_input(); plugin_start_rsp(); } mupen64plus-video-gliden64/src/GLES2/GLSLCombiner_gles2.cpp000664 001750 001750 00000040736 12655644434 024274 0ustar00sergiosergio000000 000000 #include #include #include #include #include "../N64.h" #include "../OpenGL.h" #include "../Config.h" #include "../GLSLCombiner.h" #include "../ShaderUtils.h" #include "../FrameBuffer.h" #include "../DepthBuffer.h" #include "../RSP.h" #include "../VI.h" #include "../Log.h" #include "Shaders_gles2.h" using namespace std; static GLuint g_vertex_shader_object; static GLuint g_vertex_shader_object_notex; GLuint g_monochrome_image_program = 0; static bool g_weakGLSL = false; #define GL_RED16 GL_R16UI static std::string strFragmentShader; class NoiseTexture { public: NoiseTexture() : m_pTexture(nullptr), m_pData(nullptr), m_DList(0) {} void init(); void destroy(); void update(); private: CachedTexture * m_pTexture; std::unique_ptr m_pData; u32 m_DList; } noiseTex; void NoiseTexture::init() { if (config.generalEmulation.enableNoise == 0) return; m_pTexture = textureCache().addFrameBufferTexture(); m_pTexture->format = G_IM_FMT_RGBA; m_pTexture->clampS = 1; m_pTexture->clampT = 1; m_pTexture->frameBufferTexture = CachedTexture::fbOneSample; m_pTexture->maskS = 0; m_pTexture->maskT = 0; m_pTexture->mirrorS = 0; m_pTexture->mirrorT = 0; m_pTexture->realWidth = 640; m_pTexture->realHeight = 580; m_pTexture->textureBytes = m_pTexture->realWidth * m_pTexture->realHeight; textureCache().addFrameBufferTextureSize(m_pTexture->textureBytes); glBindTexture(GL_TEXTURE_2D, m_pTexture->glName); glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, m_pTexture->realWidth, m_pTexture->realHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glBindTexture(GL_TEXTURE_2D, 0); m_pData.reset(new GLubyte[640 * 580]); } void NoiseTexture::destroy() { if (m_pTexture != nullptr) { textureCache().removeFrameBufferTexture(m_pTexture); m_pTexture = nullptr; } } void NoiseTexture::update() { if (m_DList == video().getBuffersSwapCount() || config.generalEmulation.enableNoise == 0) return; if (VI.width*VI.height == 0) return; for (u32 y = 0; y < VI.height; ++y) { for (u32 x = 0; x < VI.width; ++x) m_pData[x + y*VI.width] = rand() & 0xFF; } glActiveTexture(GL_TEXTURE0 + g_noiseTexIndex); glBindTexture(GL_TEXTURE_2D, m_pTexture->glName); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VI.width, VI.height, GL_LUMINANCE, GL_UNSIGNED_BYTE, m_pData.get()); m_DList = video().getBuffersSwapCount(); } static GLuint _createShader(GLenum _type, const char * _strShader) { GLuint shader_object = glCreateShader(_type); glShaderSource(shader_object, 1, &_strShader, NULL); glCompileShader(shader_object); assert(checkShaderCompileStatus(shader_object)); return shader_object; } void InitShaderCombiner() { if (strstr((const char*)glGetString(GL_VERSION), "OpenGL ES 2") != NULL) { const char * strRenderer = reinterpret_cast(glGetString(GL_RENDERER)); if (strstr(strRenderer, "PowerVR") != NULL || strstr(strRenderer, "Adreno") != NULL) { g_weakGLSL = true; LOG(LOG_MINIMAL, "GPU with week GLSL detected: %s\n", strRenderer); } } glActiveTexture(GL_TEXTURE0); glEnable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE1); glEnable(GL_TEXTURE_2D); g_vertex_shader_object = _createShader(GL_VERTEX_SHADER, vertex_shader); g_vertex_shader_object_notex = _createShader(GL_VERTEX_SHADER, vertex_shader_notex); strFragmentShader.reserve(1024*5); noiseTex.init(); g_monochrome_image_program = createShaderProgram(default_vertex_shader, zelda_monochrome_fragment_shader); } void DestroyShaderCombiner() { strFragmentShader.clear(); glBindFramebuffer(GL_FRAMEBUFFER, 0); glDeleteShader(g_vertex_shader_object); g_vertex_shader_object = 0; glDeleteShader(g_vertex_shader_object_notex); g_vertex_shader_object_notex = 0; glDeleteProgram(g_monochrome_image_program); g_monochrome_image_program = 0; noiseTex.destroy(); } ShaderCombiner::ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCombine & _combine) : m_combine(_combine) { char strCombiner[1024]; m_nInputs = compileCombiner(_color, _alpha, strCombiner); if (usesTexture()) { strFragmentShader.assign(fragment_shader_header_common_variables); strFragmentShader.append(fragment_shader_header_common_functions); } else { strFragmentShader.assign(fragment_shader_header_common_variables_notex); strFragmentShader.append(fragment_shader_header_common_functions_notex); } strFragmentShader.append(fragment_shader_header_main); const bool bUseLod = usesLOD(); if (bUseLod) { strFragmentShader.append(" lowp vec4 readtex0, readtex1; \n"); strFragmentShader.append(" lowp float lod_frac = mipmap(readtex0, readtex1); \n"); } else { if (usesTile(0)) { strFragmentShader.append(" nCurrentTile = 0; \n"); strFragmentShader.append(" lowp vec4 readtex0 = readTex(uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0] != 0); \n"); } if (usesTile(1)) { strFragmentShader.append(" nCurrentTile = 1; \n"); strFragmentShader.append(" lowp vec4 readtex1 = readTex(uTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1] != 0); \n"); } } const bool bUseHWLight = config.generalEmulation.enableHWLighting != 0 && GBI.isHWLSupported() && usesShadeColor(); if (bUseHWLight) strFragmentShader.append(" calc_light(vNumLights, vShadeColor.rgb, input_color); \n"); else strFragmentShader.append(" input_color = vShadeColor.rgb;\n"); strFragmentShader.append(" vec_color = vec4(input_color, vShadeColor.a); \n"); strFragmentShader.append(strCombiner); strFragmentShader.append( " if (uEnableAlphaTest != 0) { \n" " lowp float alphaTestValue = (uAlphaCompareMode == 3 && alpha2 > 0.0) ? snoise() : uAlphaTestValue; \n" " if (alpha2 < alphaTestValue) discard; \n" " } \n" ); if (!g_weakGLSL) { strFragmentShader.append( " lowp int fogUsage = uFogUsage; \n" " if (fogUsage >= 256) fogUsage -= 256; \n" " if (fogUsage == 2) fragColor = vec4(color2, uFogColor.a); \n" " else if (fogUsage == 3) fragColor = uFogColor; \n" " else if (fogUsage == 4) fragColor = vec4(color2, uFogColor.a*alpha2); \n" " else fragColor = vec4(color2, alpha2); \n" ); } else strFragmentShader.append(" fragColor = vec4(color2, alpha2); \n"); strFragmentShader.append( " if (uFogUsage == 257) \n" " fragColor.rgb = mix(fragColor.rgb, uFogColor.rgb, vFogFragCoord); \n" " gl_FragColor = fragColor; \n" ); strFragmentShader.append(fragment_shader_end); if (config.generalEmulation.enableNoise == 0) strFragmentShader.append(fragment_shader_dummy_noise); if (bUseHWLight) strFragmentShader.append(fragment_shader_calc_light); if (bUseLod) strFragmentShader.append(fragment_shader_fake_mipmap); else if (usesTexture()) { if (config.texture.bilinearMode == BILINEAR_3POINT) strFragmentShader.append(fragment_shader_readtex_3point); else strFragmentShader.append(fragment_shader_readtex); } if (config.generalEmulation.enableNoise != 0) strFragmentShader.append(fragment_shader_noise); GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); const GLchar * strShaderData = strFragmentShader.data(); glShaderSource(fragmentShader, 1, &strShaderData, NULL); glCompileShader(fragmentShader); if (!checkShaderCompileStatus(fragmentShader)) LOG(LOG_ERROR, "Error in fragment shader:\n%s\n", strFragmentShader.data()); m_program = glCreateProgram(); _locate_attributes(); if (usesTexture()) glAttachShader(m_program, g_vertex_shader_object); else glAttachShader(m_program, g_vertex_shader_object_notex); glAttachShader(m_program, fragmentShader); glLinkProgram(m_program); assert(checkProgramLinkStatus(m_program)); glDeleteShader(fragmentShader); _locateUniforms(); } ShaderCombiner::~ShaderCombiner() { glDeleteProgram(m_program); m_program = 0; } #define LocateUniform(A) \ m_uniforms.A.loc = glGetUniformLocation(m_program, #A); void ShaderCombiner::_locateUniforms() { LocateUniform(uTex0); LocateUniform(uTex1); LocateUniform(uTexNoise); LocateUniform(uTlutImage); LocateUniform(uZlutImage); LocateUniform(uDepthImage); LocateUniform(uFogMode); LocateUniform(uFogUsage); LocateUniform(uAlphaCompareMode); LocateUniform(uEnableAlphaTest); LocateUniform(uEnableDepth); LocateUniform(uEnableDepthCompare) LocateUniform(uEnableDepthUpdate); LocateUniform(uDepthMode); LocateUniform(uDepthSource); LocateUniform(uFbMonochrome); LocateUniform(uFbFixedAlpha); LocateUniform(uMaxTile) LocateUniform(uTexturePersp); LocateUniform(uTextureFilterMode); LocateUniform(uSpecialBlendMode); LocateUniform(uFogAlpha); LocateUniform(uMinLod); LocateUniform(uDeltaZ); LocateUniform(uAlphaTestValue); LocateUniform(uRenderState); LocateUniform(uScreenScale); LocateUniform(uDepthScale); LocateUniform(uFogScale); } void ShaderCombiner::_locate_attributes() const { glBindAttribLocation(m_program, SC_POSITION, "aPosition"); glBindAttribLocation(m_program, SC_COLOR, "aColor"); glBindAttribLocation(m_program, SC_TEXCOORD0, "aTexCoord0"); glBindAttribLocation(m_program, SC_TEXCOORD1, "aTexCoord1"); glBindAttribLocation(m_program, SC_NUMLIGHTS, "aNumLights"); } void ShaderCombiner::update(bool _bForce) { glUseProgram(m_program); if (_bForce) { m_uniforms.uTexNoise.set(g_noiseTexIndex, true); if (usesTexture()) { m_uniforms.uTex0.set(0, true); m_uniforms.uTex1.set(1, true); } updateFBInfo(true); updateRenderState(true); } updateFogMode(_bForce); updateDitherMode(_bForce); updateLOD(_bForce); updateTextureInfo(_bForce); updateAlphaTestInfo(_bForce); updateDepthInfo(_bForce); } void ShaderCombiner::updateRenderState(bool _bForce) { m_uniforms.uRenderState.set(video().getRender().getRenderState(), _bForce); } void ShaderCombiner::updateFogMode(bool _bForce) { const u32 blender = (gDP.otherMode.l >> 16); const int nFogBlendEnabled = config.generalEmulation.enableFog != 0 && gSP.fog.multiplier >= 0 && (gDP.otherMode.c1_m1a == 3 || gDP.otherMode.c1_m2a == 3 || gDP.otherMode.c2_m1a == 3 || gDP.otherMode.c2_m2a == 3) ? 256 : 0; int nFogUsage = ((gSP.geometryMode & G_FOG) != 0) ? 1 : 0; int nSpecialBlendMode = 0; switch (blender) { case 0x0150: case 0x0D18: nFogUsage = gDP.otherMode.cycleType == G_CYC_2CYCLE ? 2 : 0; break; case 0x0440: nFogUsage = gDP.otherMode.cycleType == G_CYC_1CYCLE ? 2 : 0; break; case 0xC912: nFogUsage = 2; break; case 0xF550: nFogUsage = 3; break; case 0x0550: nFogUsage = 4; break; case 0x0382: case 0x0091: // Mace // CLR_IN * A_IN + CLR_BL * 1MA if (gDP.otherMode.cycleType == G_CYC_2CYCLE) nSpecialBlendMode = 1; break; case 0xA500: // Bomberman 2 // CLR_BL * A_FOG + CLR_IN * 1MA if (gDP.otherMode.cycleType == G_CYC_1CYCLE) { nSpecialBlendMode = 2; nFogUsage = 5; } break; case 0x07C2: // Conker BFD shadow // CLR_IN * A_FOG + CLR_FOG * 1MA if (gDP.otherMode.cycleType == G_CYC_2CYCLE) { nSpecialBlendMode = 3; nFogUsage = 5; } break; /* Brings troubles with Roadsters sky case 0xc702: // Donald Duck // clr_fog*a_fog + clr_in*1ma nFogUsage = 5; nSpecialBlendMode = 2; break; */ } int nFogMode = 0; // Normal if (nFogUsage == 0) { switch (blender) { case 0xC410: case 0xC411: case 0xF500: nFogMode = 1; // fog blend nFogUsage = 1; break; case 0x04D1: nFogMode = 2; // inverse fog blend nFogUsage = 1; break; } } m_uniforms.uSpecialBlendMode.set(nSpecialBlendMode, _bForce); m_uniforms.uFogUsage.set(nFogUsage | nFogBlendEnabled, _bForce); m_uniforms.uFogMode.set(nFogMode, _bForce); if (nFogUsage + nFogMode != 0) { m_uniforms.uFogScale.set((float)gSP.fog.multiplier / 256.0f, (float)gSP.fog.offset / 256.0f, _bForce); m_uniforms.uFogAlpha.set(gDP.fogColor.a, _bForce); } } void ShaderCombiner::updateDitherMode(bool _bForce) { if (gDP.otherMode.cycleType < G_CYC_COPY) m_uniforms.uAlphaCompareMode.set(gDP.otherMode.alphaCompare, _bForce); else m_uniforms.uAlphaCompareMode.set(0, _bForce); const int nDither = (gDP.otherMode.cycleType < G_CYC_COPY) && (gDP.otherMode.alphaCompare == G_AC_DITHER) ? 1 : 0; if ((m_nInputs & (1 << NOISE)) + nDither != 0) { m_uniforms.uScreenScale.set(video().getScaleX(), video().getScaleY(), _bForce); noiseTex.update(); } } void ShaderCombiner::updateLOD(bool _bForce) { if (usesLOD()) { m_uniforms.uMinLod.set(gDP.primColor.m, _bForce); m_uniforms.uMaxTile.set(gSP.texture.level, _bForce); } } void ShaderCombiner::updateTextureInfo(bool _bForce) { m_uniforms.uTexturePersp.set(gDP.otherMode.texturePersp, _bForce); if (config.texture.bilinearMode == BILINEAR_3POINT) m_uniforms.uTextureFilterMode.set(gDP.otherMode.textureFilter | (gSP.objRendermode&G_OBJRM_BILERP), _bForce); } void ShaderCombiner::updateFBInfo(bool _bForce) { if (!usesTexture()) return; int nFbMonochromeMode0 = 0, nFbMonochromeMode1 = 0; int nFbFixedAlpha0 = 0, nFbFixedAlpha1 = 0; int nMSTex0Enabled = 0, nMSTex1Enabled = 0; TextureCache & cache = textureCache(); if (cache.current[0] != NULL && cache.current[0]->frameBufferTexture != CachedTexture::fbNone) { if (cache.current[0]->size == G_IM_SIZ_8b) { nFbMonochromeMode0 = 1; if (gDP.otherMode.imageRead == 0) nFbFixedAlpha0 = 1; } else if (gSP.textureTile[0]->size == G_IM_SIZ_16b && gSP.textureTile[0]->format == G_IM_FMT_IA) nFbMonochromeMode0 = 2; } if (cache.current[1] != NULL && cache.current[1]->frameBufferTexture != CachedTexture::fbNone) { if (cache.current[1]->size == G_IM_SIZ_8b) { nFbMonochromeMode1 = 1; if (gDP.otherMode.imageRead == 0) nFbFixedAlpha1 = 1; } else if (gSP.textureTile[1]->size == G_IM_SIZ_16b && gSP.textureTile[1]->format == G_IM_FMT_IA) nFbMonochromeMode1 = 2; } m_uniforms.uFbMonochrome.set(nFbMonochromeMode0, nFbMonochromeMode1, _bForce); m_uniforms.uFbFixedAlpha.set(nFbFixedAlpha0, nFbFixedAlpha1, _bForce); gDP.changed &= ~CHANGED_FB_TEXTURE; } void ShaderCombiner::updateDepthInfo(bool _bForce) { if (RSP.bLLE) m_uniforms.uDepthScale.set(0.5f, 0.5f, _bForce); else m_uniforms.uDepthScale.set(gSP.viewport.vscale[2], gSP.viewport.vtrans[2], _bForce); if (config.frameBufferEmulation.N64DepthCompare == 0 || !video().getRender().isImageTexturesSupported()) return; FrameBuffer * pBuffer = frameBufferList().getCurrent(); if (pBuffer == NULL || pBuffer->m_pDepthBuffer == NULL) return; const int nDepthEnabled = (gSP.geometryMode & G_ZBUFFER) > 0 ? 1 : 0; m_uniforms.uEnableDepth.set(nDepthEnabled, _bForce); if (nDepthEnabled == 0) { m_uniforms.uEnableDepthCompare.set(0, _bForce); m_uniforms.uEnableDepthUpdate.set(0, _bForce); } else { m_uniforms.uEnableDepthCompare.set(gDP.otherMode.depthCompare, _bForce); m_uniforms.uEnableDepthUpdate.set(gDP.otherMode.depthUpdate, _bForce); } m_uniforms.uDepthMode.set(gDP.otherMode.depthMode, _bForce); m_uniforms.uDepthSource.set(gDP.otherMode.depthSource, _bForce); if (gDP.otherMode.depthSource == G_ZS_PRIM) m_uniforms.uDeltaZ.set(gDP.primDepth.deltaZ, _bForce); } void ShaderCombiner::updateAlphaTestInfo(bool _bForce) { if (gDP.otherMode.cycleType == G_CYC_FILL) { m_uniforms.uEnableAlphaTest.set(0, _bForce); m_uniforms.uAlphaTestValue.set(0.0f, _bForce); } else if (gDP.otherMode.cycleType == G_CYC_COPY) { if (gDP.otherMode.alphaCompare & G_AC_THRESHOLD) { m_uniforms.uEnableAlphaTest.set(1, _bForce); m_uniforms.uAlphaTestValue.set(0.5f, _bForce); } else { m_uniforms.uEnableAlphaTest.set(0, _bForce); m_uniforms.uAlphaTestValue.set(0.0f, _bForce); } } else if (((gDP.otherMode.alphaCompare & G_AC_THRESHOLD) != 0) && (gDP.otherMode.alphaCvgSel == 0) && (gDP.otherMode.forceBlender == 0 || gDP.blendColor.a > 0)) { m_uniforms.uEnableAlphaTest.set(1, _bForce); m_uniforms.uAlphaTestValue.set(max(gDP.blendColor.a, 1.0f / 256.0f), _bForce); } else if ((gDP.otherMode.alphaCompare == G_AC_DITHER) && (gDP.otherMode.alphaCvgSel == 0)) { m_uniforms.uEnableAlphaTest.set(1, _bForce); m_uniforms.uAlphaTestValue.set(0.0f, _bForce); } else if (gDP.otherMode.cvgXAlpha != 0) { m_uniforms.uEnableAlphaTest.set(1, _bForce); m_uniforms.uAlphaTestValue.set(0.125f, _bForce); } else { m_uniforms.uEnableAlphaTest.set(0, _bForce); m_uniforms.uAlphaTestValue.set(0.0f, _bForce); } } void SetMonochromeCombiner() { glUseProgram(g_monochrome_image_program); static int texLoc = -1; if (texLoc < 0) { texLoc = glGetUniformLocation(g_monochrome_image_program, "uColorImage"); glUniform1i(texLoc, 0); } static int sizeLoc = -1; if (sizeLoc < 0) { glGetUniformLocation(g_monochrome_image_program, "uScreenSize"); glUniform2f(sizeLoc, (float)video().getWidth(), (float)video().getHeight()); } gDP.changed |= CHANGED_COMBINE; } gles2rice/src/ConvertImage16.cpp000664 001750 001750 00000115071 12655644434 017630 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "Config.h" #include "ConvertImage.h" #include "RenderBase.h" // Still to be swapped: // IA16 ConvertFunction gConvertFunctions_16_FullTMEM[ 8 ][ 4 ] = { // 4bpp 8bpp 16bpp 32bpp { Convert4b_16, Convert8b_16, Convert16b_16, ConvertRGBA32_16 }, // RGBA { NULL, NULL, ConvertYUV_16, NULL }, // YUV { Convert4b_16, Convert8b_16, NULL, NULL }, // CI { Convert4b_16, Convert8b_16, Convert16b_16, NULL }, // IA { Convert4b_16, Convert8b_16, Convert16b_16, NULL }, // I { NULL, NULL, NULL, NULL }, // ? { NULL, NULL, NULL, NULL }, // ? { NULL, NULL, NULL, NULL } // ? }; ConvertFunction gConvertFunctions_16[ 8 ][ 4 ] = { // 4bpp 8bpp 16bpp 32bpp { ConvertCI4_16, ConvertCI8_16, ConvertRGBA16_16, ConvertRGBA32_16 }, // RGBA { NULL, NULL, ConvertYUV_16, NULL }, // YUV { ConvertCI4_16, ConvertCI8_16, NULL, NULL }, // CI { ConvertIA4_16, ConvertIA8_16, ConvertIA16_16, NULL }, // IA { ConvertI4_16, ConvertI8_16, ConvertRGBA16_16, NULL }, // I { NULL, NULL, NULL, NULL }, // ? { NULL, NULL, NULL, NULL }, // ? { NULL, NULL, NULL, NULL } // ? }; ConvertFunction gConvertTlutFunctions_16[ 8 ][ 4 ] = { // 4bpp 8bpp 16bpp 32bpp { ConvertCI4_16, ConvertCI8_16, ConvertRGBA16_16, ConvertRGBA32_16 }, // RGBA { NULL, NULL, ConvertYUV_16, NULL }, // YUV { ConvertCI4_16, ConvertCI8_16, NULL, NULL }, // CI { ConvertCI4_16, ConvertCI8_16, ConvertIA16_16, NULL }, // IA { ConvertCI4_16, ConvertCI8_16, ConvertRGBA16_16, NULL }, // I { NULL, NULL, NULL, NULL }, // ? { NULL, NULL, NULL, NULL }, // ? { NULL, NULL, NULL, NULL } // ? }; extern bool conkerSwapHack; void ConvertRGBA16_16(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; uint32_t x, y; uint32_t nFiddle; // Copy of the base pointer uint16_t * pSrc = (uint16_t*)(tinfo.pPhysicalAddress); uint8_t * pByteSrc = (uint8_t *)pSrc; if (!pTexture->StartUpdate(&dInfo)) return; if (tinfo.bSwapped) { for (y = 0; y < tinfo.HeightToLoad; y++) { if ((y%2) == 0) nFiddle = 0x2; else nFiddle = 0x2 | 0x4; // dwDst points to start of destination row uint16_t * wDst = (uint16_t *)((uint8_t *)dInfo.lpSurface + y*dInfo.lPitch); // DWordOffset points to the current dword we're looking at // (process 2 pixels at a time). May be a problem if we don't start on even pixel uint32_t dwWordOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + (tinfo.LeftToLoad * 2); for (x = 0; x < tinfo.WidthToLoad; x++) { uint16_t w = *(uint16_t *)&pByteSrc[dwWordOffset ^ nFiddle]; wDst[x] = Convert555ToR4G4B4A4(w); // Increment word offset to point to the next two pixels dwWordOffset += 2; } } } else { for (y = 0; y < tinfo.HeightToLoad; y++) { // dwDst points to start of destination row uint16_t * wDst = (uint16_t *)((uint8_t *)dInfo.lpSurface + y*dInfo.lPitch); // DWordOffset points to the current dword we're looking at // (process 2 pixels at a time). May be a problem if we don't start on even pixel uint32_t dwWordOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + (tinfo.LeftToLoad * 2); for (x = 0; x < tinfo.WidthToLoad; x++) { uint16_t w = *(uint16_t *)&pByteSrc[dwWordOffset ^ 0x2]; wDst[x] = Convert555ToR4G4B4A4(w); // Increment word offset to point to the next two pixels dwWordOffset += 2; } } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } void ConvertRGBA32_16(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; uint32_t * pSrc = (uint32_t*)(tinfo.pPhysicalAddress); if (!pTexture->StartUpdate(&dInfo)) return; if( options.bUseFullTMEM ) { Tile &tile = gRDP.tiles[tinfo.tileNo]; uint32_t *pWordSrc; if( tinfo.tileNo >= 0 ) { pWordSrc = (uint32_t*)&g_Tmem.g_Tmem64bit[tile.dwTMem]; for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint16_t * dwDst = (uint16_t *)((uint8_t *)dInfo.lpSurface + y*dInfo.lPitch); uint32_t nFiddle = ( y&1 )? 0x2 : 0; int idx = tile.dwLine*4*y; for (uint32_t x = 0; x < tinfo.WidthToLoad; x++, idx++) { uint32_t w = pWordSrc[idx^nFiddle]; uint8_t* psw = (uint8_t*)&w; dwDst[x] = R4G4B4A4_MAKE( (psw[0]>>4), (psw[1]>>4), (psw[2]>>4), (psw[3]>>4)); } } } } else { if (tinfo.bSwapped) { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { if ((y%2) == 0) { uint16_t *pDst = (uint16_t*)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); uint8_t *pS = (uint8_t *)pSrc + (y+tinfo.TopToLoad) * tinfo.Pitch + (tinfo.LeftToLoad*4); for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { *pDst++ = R4G4B4A4_MAKE((pS[3]>>4), // Red (pS[2]>>4), // Green (pS[1]>>4), // Blue (pS[0]>>4)); // Alpha pS+=4; } } else { uint16_t *pDst = (uint16_t*)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); uint8_t *pS = (uint8_t *)pSrc + (y+tinfo.TopToLoad) * tinfo.Pitch + (tinfo.LeftToLoad*4); int n; n = 0; for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { *pDst++ = R4G4B4A4_MAKE((pS[(n^0x8) + 3]>>4), // Red (pS[(n^0x8) + 2]>>4), // Green (pS[(n^0x8) + 1]>>4), // Blue (pS[(n^0x8) + 0]>>4)); // Alpha n += 4; } } } } else { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint16_t *pDst = (uint16_t*)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); uint8_t *pS = (uint8_t *)pSrc + (y+tinfo.TopToLoad) * tinfo.Pitch + (tinfo.LeftToLoad*4); for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { *pDst++ = R4G4B4A4_MAKE((pS[3]>>4), // Red (pS[2]>>4), // Green (pS[1]>>4), // Blue (pS[0]>>4)); // Alpha pS+=4; } } } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } // E.g. Dear Mario text // Copy, Score etc void ConvertIA4_16(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; uint32_t nFiddle; uint8_t * pSrc = (uint8_t*)(tinfo.pPhysicalAddress); if (!pTexture->StartUpdate(&dInfo)) return; if (tinfo.bSwapped) { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint16_t *pDst = (uint16_t*)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); // For odd lines, swap words too if ((y%2) == 0) nFiddle = 0x3; else nFiddle = 0x7; // This may not work if X is not even? uint32_t dwByteOffset = (y+tinfo.TopToLoad) * tinfo.Pitch + (tinfo.LeftToLoad/2); // Do two pixels at a time for (uint32_t x = 0; x < tinfo.WidthToLoad; x+=2) { uint8_t b = pSrc[dwByteOffset ^ nFiddle]; // Even *pDst++ = R4G4B4A4_MAKE(ThreeToFour[(b & 0xE0) >> 5], ThreeToFour[(b & 0xE0) >> 5], ThreeToFour[(b & 0xE0) >> 5], OneToFour[(b & 0x10) >> 4]); // Odd *pDst++ = R4G4B4A4_MAKE(ThreeToFour[(b & 0x0E) >> 1], ThreeToFour[(b & 0x0E) >> 1], ThreeToFour[(b & 0x0E) >> 1], OneToFour[(b & 0x01)] ); dwByteOffset++; } } } else { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint16_t *pDst = (uint16_t*)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); // This may not work if X is not even? uint32_t dwByteOffset = (y+tinfo.TopToLoad) * tinfo.Pitch + (tinfo.LeftToLoad/2); // Do two pixels at a time for (uint32_t x = 0; x < tinfo.WidthToLoad; x+=2) { uint8_t b = pSrc[dwByteOffset ^ 0x3]; // Even *pDst++ = R4G4B4A4_MAKE(ThreeToFour[(b & 0xE0) >> 5], ThreeToFour[(b & 0xE0) >> 5], ThreeToFour[(b & 0xE0) >> 5], OneToFour[(b & 0x10) >> 4]); // Odd *pDst++ = R4G4B4A4_MAKE(ThreeToFour[(b & 0x0E) >> 1], ThreeToFour[(b & 0x0E) >> 1], ThreeToFour[(b & 0x0E) >> 1], OneToFour[(b & 0x01)] ); dwByteOffset++; } } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } // E.g Mario's head textures void ConvertIA8_16(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; uint32_t nFiddle; uint8_t * pSrc = (uint8_t*)(tinfo.pPhysicalAddress); if (!pTexture->StartUpdate(&dInfo)) return; if (tinfo.bSwapped) { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { // For odd lines, swap words too if ((y%2) == 0) nFiddle = 0x3; else nFiddle = 0x7; uint16_t *pDst = (uint16_t *)((uint8_t*)dInfo.lpSurface + y * dInfo.lPitch); // Points to current byte uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + tinfo.LeftToLoad; for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { uint8_t b = pSrc[dwByteOffset ^ nFiddle]; *pDst++ = R4G4B4A4_MAKE( ((b&0xf0)>>4),((b&0xf0)>>4),((b&0xf0)>>4),(b&0x0f)); dwByteOffset++; } } } else { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint16_t *pDst = (uint16_t*)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); // Points to current byte uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + tinfo.LeftToLoad; for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { uint8_t b = pSrc[dwByteOffset ^ 0x3]; *pDst++ = R4G4B4A4_MAKE(((b&0xf0)>>4),((b&0xf0)>>4),((b&0xf0)>>4),(b&0x0f)); dwByteOffset++; } } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } // E.g. camera's clouds, shadows void ConvertIA16_16(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; uint16_t * pSrc = (uint16_t*)(tinfo.pPhysicalAddress); uint8_t * pByteSrc = (uint8_t *)pSrc; if (!pTexture->StartUpdate(&dInfo)) return; for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint16_t *pDst = (uint16_t*)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); // Points to current word uint32_t dwWordOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + (tinfo.LeftToLoad * 2); for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { uint16_t w = *(uint16_t *)&pByteSrc[dwWordOffset^0x2]; uint8_t i = (uint8_t)(w >> 12); uint8_t a = (uint8_t)(w & 0xFF); *pDst++ = R4G4B4A4_MAKE(i, i, i, (a>>4)); dwWordOffset += 2; } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } // Used by MarioKart void ConvertI4_16(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; uint32_t nFiddle; uint8_t * pSrc = (uint8_t*)(tinfo.pPhysicalAddress); if (!pTexture->StartUpdate(&dInfo)) return; if (tinfo.bSwapped) { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint16_t *pDst = (uint16_t*)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); // Might not work with non-even starting X uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + (tinfo.LeftToLoad / 2); // For odd lines, swap words too if( !conkerSwapHack || (y&4) == 0 ) { if ((y%2) == 0) nFiddle = 0x3; else nFiddle = 0x7; } else { if ((y%2) == 1) nFiddle = 0x3; else nFiddle = 0x7; } for (uint32_t x = 0; x < tinfo.WidthToLoad; x+=2) { uint8_t b = pSrc[dwByteOffset ^ nFiddle]; // Even //*pDst++ = R4G4B4A4_MAKE(b>>4, b>>4, b>>4, b>>4); *pDst++ = FourToSixteen[(b & 0xF0)>>4]; // Odd //*pDst++ = R4G4B4A4_MAKE(b & 0x0f, b & 0x0f, b & 0x0f, b & 0x0f); *pDst++ = FourToSixteen[b & 0x0f]; dwByteOffset++; } } } else { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint8_t *pDst = (uint8_t *)dInfo.lpSurface + y * dInfo.lPitch; // Might not work with non-even starting X uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + (tinfo.LeftToLoad / 2); for (uint32_t x = 0; x < tinfo.WidthToLoad; x+=2) { uint8_t b = pSrc[dwByteOffset ^ 0x3]; // Even //*pDst++ = R4G4B4A4_MAKE(b>>4, b>>4, b>>4, b>>4); *pDst++ = FourToEight[(b & 0xF0)>>4]; // Odd //*pDst++ = R4G4B4A4_MAKE(b & 0x0f, b & 0x0f, b & 0x0f, b & 0x0f); *pDst++ = FourToEight[b & 0x0f]; dwByteOffset++; } } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } // Used by MarioKart void ConvertI8_16(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; uint32_t nFiddle; long long pSrc = (long long) (tinfo.pPhysicalAddress); if (!pTexture->StartUpdate(&dInfo)) return; if (tinfo.bSwapped) { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { if ((y%2) == 0) nFiddle = 0x3; else nFiddle = 0x7; uint16_t *pDst = (uint16_t*)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + tinfo.LeftToLoad; for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { uint8_t b = *(uint8_t*)((pSrc+dwByteOffset)^nFiddle); *pDst++ = R4G4B4A4_MAKE(b>>4, b>>4, b>>4, b>>4); dwByteOffset++; } } } else { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint16_t *pDst = (uint16_t*)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + tinfo.LeftToLoad; for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { uint8_t b = *(uint8_t*)((pSrc+dwByteOffset)^0x3); *pDst++ = R4G4B4A4_MAKE(b>>4, b>>4, b>>4, b>>4); dwByteOffset++; } } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } // Used by Starfox intro void ConvertCI4_RGBA16_16(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; uint32_t nFiddle; uint8_t * pSrc = (uint8_t*)(tinfo.pPhysicalAddress); uint16_t * pPal = (uint16_t *)tinfo.PalAddress; if (!pTexture->StartUpdate(&dInfo)) return; if (tinfo.bSwapped) { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { if ((y%2) == 0) nFiddle = 0x3; else nFiddle = 0x7; uint16_t * pDst = (uint16_t *)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + (tinfo.LeftToLoad / 2); for (uint32_t x = 0; x < tinfo.WidthToLoad; x+=2) { uint8_t b = pSrc[dwByteOffset ^ nFiddle]; uint8_t bhi = (b&0xf0)>>4; uint8_t blo = (b&0x0f); pDst[0] = Convert555ToR4G4B4A4(pPal[bhi^1]); // Remember palette is in different endian order! pDst[1] = Convert555ToR4G4B4A4(pPal[blo^1]); // Remember palette is in different endian order! pDst+=2; dwByteOffset++; } } } else { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint16_t * pDst = (uint16_t *)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + (tinfo.LeftToLoad / 2); for (uint32_t x = 0; x < tinfo.WidthToLoad; x+=2) { uint8_t b = pSrc[dwByteOffset ^ 0x3]; uint8_t bhi = (b&0xf0)>>4; uint8_t blo = (b&0x0f); pDst[0] = Convert555ToR4G4B4A4(pPal[bhi^1]); // Remember palette is in different endian order! pDst[1] = Convert555ToR4G4B4A4(pPal[blo^1]); // Remember palette is in different endian order! pDst+=2; dwByteOffset++; } } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } //***************************************************************************** // Convert CI4 images. We need to switch on the palette type //***************************************************************************** void ConvertCI4_16( CTexture * p_texture, const TxtrInfo & tinfo ) { if ( tinfo.TLutFmt == TLUT_FMT_RGBA16 ) { ConvertCI4_RGBA16_16( p_texture, tinfo ); } else if ( tinfo.TLutFmt == TLUT_FMT_IA16 ) { ConvertCI4_IA16_16( p_texture, tinfo ); } } //***************************************************************************** // Convert CI8 images. We need to switch on the palette type //***************************************************************************** void ConvertCI8_16( CTexture * p_texture, const TxtrInfo & tinfo ) { if ( tinfo.TLutFmt == TLUT_FMT_RGBA16 ) { ConvertCI8_RGBA16_16( p_texture, tinfo ); } else if ( tinfo.TLutFmt == TLUT_FMT_IA16 ) { ConvertCI8_IA16_16( p_texture, tinfo ); } } // Used by Starfox intro void ConvertCI4_IA16_16(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; uint32_t nFiddle; uint8_t * pSrc = (uint8_t*)(tinfo.pPhysicalAddress); uint16_t * pPal = (uint16_t *)tinfo.PalAddress; if (!pTexture->StartUpdate(&dInfo)) return; if (tinfo.bSwapped) { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { if ((y%2) == 0) nFiddle = 0x3; else nFiddle = 0x7; uint16_t * pDst = (uint16_t *)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + (tinfo.LeftToLoad / 2); for (uint32_t x = 0; x < tinfo.WidthToLoad; x+=2) { uint8_t b = pSrc[dwByteOffset ^ nFiddle]; uint8_t bhi = (b&0xf0)>>4; uint8_t blo = (b&0x0f); pDst[0] = ConvertIA16ToR4G4B4A4(pPal[bhi^1]); // Remember palette is in different endian order! pDst[1] = ConvertIA16ToR4G4B4A4(pPal[blo^1]); // Remember palette is in different endian order! pDst += 2; dwByteOffset++; } } } else { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint16_t * pDst = (uint16_t *)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + (tinfo.LeftToLoad / 2); for (uint32_t x = 0; x < tinfo.WidthToLoad; x+=2) { uint8_t b = pSrc[dwByteOffset ^ 0x3]; uint8_t bhi = (b&0xf0)>>4; uint8_t blo = (b&0x0f); pDst[0] = ConvertIA16ToR4G4B4A4(pPal[bhi^1]); // Remember palette is in different endian order! pDst[1] = ConvertIA16ToR4G4B4A4(pPal[blo^1]); // Remember palette is in different endian order! pDst+=2; dwByteOffset++; } } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } // Used by MarioKart for Cars etc void ConvertCI8_RGBA16_16(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; uint32_t nFiddle; uint8_t * pSrc = (uint8_t*)(tinfo.pPhysicalAddress); uint16_t * pPal = (uint16_t *)tinfo.PalAddress; if (!pTexture->StartUpdate(&dInfo)) return; if (tinfo.bSwapped) { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { if ((y%2) == 0) nFiddle = 0x3; else nFiddle = 0x7; uint16_t *pDst = (uint16_t *)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + tinfo.LeftToLoad; for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { uint8_t b = pSrc[dwByteOffset ^ nFiddle]; *pDst++ = Convert555ToR4G4B4A4(pPal[b^1]); // Remember palette is in different endian order! dwByteOffset++; } } } else { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint16_t *pDst = (uint16_t *)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + tinfo.LeftToLoad; for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { uint8_t b = pSrc[dwByteOffset ^ 0x3]; *pDst++ = Convert555ToR4G4B4A4(pPal[b^1]); // Remember palette is in different endian order! dwByteOffset++; } } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } // Used by MarioKart for Cars etc void ConvertCI8_IA16_16(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; uint32_t nFiddle; uint8_t * pSrc = (uint8_t*)(tinfo.pPhysicalAddress); uint16_t * pPal = (uint16_t *)tinfo.PalAddress; if (!pTexture->StartUpdate(&dInfo)) return; if (tinfo.bSwapped) { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { if ((y%2) == 0) nFiddle = 0x3; else nFiddle = 0x7; uint16_t *pDst = (uint16_t *)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + tinfo.LeftToLoad; for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { uint8_t b = pSrc[dwByteOffset ^ nFiddle]; *pDst++ = ConvertIA16ToR4G4B4A4(pPal[b^1]); // Remember palette is in different endian order! dwByteOffset++; } } } else { for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint16_t *pDst = (uint16_t *)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); uint32_t dwByteOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + tinfo.LeftToLoad; for (uint32_t x = 0; x < tinfo.WidthToLoad; x++) { uint8_t b = pSrc[dwByteOffset ^ 0x3]; *pDst++ = ConvertIA16ToR4G4B4A4(pPal[b^1]); // Remember palette is in different endian order! dwByteOffset++; } } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } void ConvertYUV_16(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; if (!pTexture->StartUpdate(&dInfo)) return; uint32_t x, y; uint32_t nFiddle; if( options.bUseFullTMEM ) { Tile &tile = gRDP.tiles[tinfo.tileNo]; uint16_t * pSrc; if( tinfo.tileNo >= 0 ) pSrc = (uint16_t*)&g_Tmem.g_Tmem64bit[tile.dwTMem]; else pSrc = (uint16_t*)(tinfo.pPhysicalAddress); uint8_t * pByteSrc = (uint8_t *)pSrc; for (y = 0; y < tinfo.HeightToLoad; y++) { nFiddle = ( y&1 )? 0x4 : 0; int dwWordOffset = tinfo.tileNo>=0? tile.dwLine*8*y : ((y+tinfo.TopToLoad) * tinfo.Pitch) + (tinfo.LeftToLoad * 2); uint16_t * wDst = (uint16_t *)((uint8_t *)dInfo.lpSurface + y*dInfo.lPitch); for (x = 0; x < tinfo.WidthToLoad/2; x++) { int y0 = *(uint8_t*)&pByteSrc[(dwWordOffset+1)^nFiddle]; int y1 = *(uint8_t*)&pByteSrc[(dwWordOffset+3)^nFiddle]; int u0 = *(uint8_t*)&pByteSrc[(dwWordOffset )^nFiddle]; int v0 = *(uint8_t*)&pByteSrc[(dwWordOffset+2)^nFiddle]; wDst[x*2+0] = ConvertYUV16ToR4G4B4(y0,u0,v0); wDst[x*2+1] = ConvertYUV16ToR4G4B4(y1,u0,v0); dwWordOffset += 4; } } } else { // Copy of the base pointer uint16_t * pSrc = (uint16_t*)(tinfo.pPhysicalAddress); uint8_t * pByteSrc = (uint8_t *)pSrc; if (tinfo.bSwapped) { for (y = 0; y < tinfo.HeightToLoad; y++) { if ((y%2) == 0) nFiddle = 0x2; else nFiddle = 0x2 | 0x4; // dwDst points to start of destination row uint16_t * wDst = (uint16_t *)((uint8_t *)dInfo.lpSurface + y*dInfo.lPitch); // DWordOffset points to the current dword we're looking at // (process 2 pixels at a time). May be a problem if we don't start on even pixel uint32_t dwWordOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + (tinfo.LeftToLoad * 2); for (x = 0; x < tinfo.WidthToLoad/2; x++) { uint32_t y0 = *(uint8_t*)&pByteSrc[(dwWordOffset+1)^nFiddle]; uint32_t y1 = *(uint8_t*)&pByteSrc[(dwWordOffset+3)^nFiddle]; uint32_t u0 = *(uint8_t*)&pByteSrc[(dwWordOffset )^nFiddle]; uint32_t v0 = *(uint8_t*)&pByteSrc[(dwWordOffset+2)^nFiddle]; wDst[x*2+0] = ConvertYUV16ToR4G4B4(y0,u0,v0); wDst[x*2+1] = ConvertYUV16ToR4G4B4(y1,u0,v0); dwWordOffset += 4; } } } else { for (y = 0; y < tinfo.HeightToLoad; y++) { // dwDst points to start of destination row uint16_t * wDst = (uint16_t *)((uint8_t *)dInfo.lpSurface + y*dInfo.lPitch); // DWordOffset points to the current dword we're looking at // (process 2 pixels at a time). May be a problem if we don't start on even pixel uint32_t dwWordOffset = ((y+tinfo.TopToLoad) * tinfo.Pitch) + (tinfo.LeftToLoad * 2); for (x = 0; x < tinfo.WidthToLoad/2; x++) { uint32_t y0 = *(uint8_t*)&pByteSrc[(dwWordOffset+1)^3]; uint32_t y1 = *(uint8_t*)&pByteSrc[(dwWordOffset+3)^3]; uint32_t u0 = *(uint8_t*)&pByteSrc[(dwWordOffset )^3]; uint32_t v0 = *(uint8_t*)&pByteSrc[(dwWordOffset+2)^3]; wDst[x*2+0] = ConvertYUV16ToR4G4B4(y0,u0,v0); wDst[x*2+1] = ConvertYUV16ToR4G4B4(y1,u0,v0); dwWordOffset += 4; } } } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } uint16_t ConvertYUV16ToR4G4B4(int Y, int U, int V) { uint32_t A=1; uint32_t R1 = Y + g_convk0 * V; uint32_t G1 = Y + g_convk1 * U + g_convk2 * V; uint32_t B1 = Y + g_convk3 * U; uint32_t R = (R1 - g_convk4) * g_convk5 + R1; uint32_t G = (G1 - g_convk4) * g_convk5 + G1; uint32_t B = (B1 - g_convk4) * g_convk5 + B1; return (uint16_t)R4G4B4A4_MAKE((R>>4), (G>>4), (B>>4), 0xF*A); } // Used by Starfox intro void Convert4b_16(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; if (!pTexture->StartUpdate(&dInfo)) return; uint16_t * pPal = (uint16_t *)tinfo.PalAddress; bool bIgnoreAlpha = (tinfo.TLutFmt==TLUT_FMT_UNKNOWN); if( tinfo.Format <= TXT_FMT_CI ) bIgnoreAlpha = (tinfo.TLutFmt==TLUT_FMT_NONE); Tile &tile = gRDP.tiles[tinfo.tileNo]; uint8_t *pByteSrc = tinfo.tileNo >= 0 ? (uint8_t*)&g_Tmem.g_Tmem64bit[tile.dwTMem] : (uint8_t*)(tinfo.pPhysicalAddress); for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint16_t * pDst = (uint16_t *)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); uint32_t nFiddle; if( tinfo.tileNo < 0 ) { if (tinfo.bSwapped) { if ((y%2) == 0) nFiddle = 0x3; else nFiddle = 0x7; } else { nFiddle = 3; } } else { nFiddle = ( y&1 )? 0x4 : 0; } int idx = tinfo.tileNo>=0 ? tile.dwLine*8*y : ((y+tinfo.TopToLoad) * tinfo.Pitch) + (tinfo.LeftToLoad / 2); for (uint32_t x = 0; x < tinfo.WidthToLoad; x+=2, idx++) { uint8_t b = pByteSrc[idx^nFiddle]; uint8_t bhi = (b&0xf0)>>4; uint8_t blo = (b&0x0f); if( gRDP.otherMode.text_tlut>=2 || ( tinfo.Format != TXT_FMT_IA && tinfo.Format != TXT_FMT_I) ) { if( tinfo.TLutFmt == TLUT_FMT_IA16 ) { if( tinfo.tileNo>=0 ) { pDst[0] = ConvertIA16ToR4G4B4A4(g_Tmem.g_Tmem16bit[0x400+tinfo.Palette*0x40+(bhi<<2)]); pDst[1] = ConvertIA16ToR4G4B4A4(g_Tmem.g_Tmem16bit[0x400+tinfo.Palette*0x40+(blo<<2)]); } else { pDst[0] = ConvertIA16ToR4G4B4A4(pPal[bhi^1]); pDst[1] = ConvertIA16ToR4G4B4A4(pPal[blo^1]); } } else { if( tinfo.tileNo>=0 ) { pDst[0] = Convert555ToR4G4B4A4(g_Tmem.g_Tmem16bit[0x400+tinfo.Palette*0x40+(bhi<<2)]); pDst[1] = Convert555ToR4G4B4A4(g_Tmem.g_Tmem16bit[0x400+tinfo.Palette*0x40+(blo<<2)]); } else { pDst[0] = Convert555ToR4G4B4A4(pPal[bhi^1]); pDst[1] = Convert555ToR4G4B4A4(pPal[blo^1]); } } } else if( tinfo.Format == TXT_FMT_IA ) { pDst[0] = ConvertIA4ToR4G4B4A4(b>>4); pDst[1] = ConvertIA4ToR4G4B4A4(b&0xF); } else //if( tinfo.Format == TXT_FMT_I ) { pDst[0] = ConvertI4ToR4G4B4A4(b>>4); pDst[1] = ConvertI4ToR4G4B4A4(b&0xF); } if( bIgnoreAlpha ) { pDst[0] |= 0xF000; pDst[1] |= 0xF000; } pDst+=2; } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } void Convert8b_16(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; if (!pTexture->StartUpdate(&dInfo)) return; uint16_t * pPal = (uint16_t *)tinfo.PalAddress; bool bIgnoreAlpha = (tinfo.TLutFmt==TLUT_FMT_UNKNOWN); if( tinfo.Format <= TXT_FMT_CI ) bIgnoreAlpha = (tinfo.TLutFmt==TLUT_FMT_NONE); Tile &tile = gRDP.tiles[tinfo.tileNo]; uint8_t *pByteSrc; if( tinfo.tileNo >= 0 ) pByteSrc = (uint8_t*)&g_Tmem.g_Tmem64bit[tile.dwTMem]; else pByteSrc = (uint8_t*)(tinfo.pPhysicalAddress); for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint16_t * pDst = (uint16_t *)((uint8_t *)dInfo.lpSurface + y * dInfo.lPitch); uint32_t nFiddle; if( tinfo.tileNo < 0 ) { if (tinfo.bSwapped) { if ((y%2) == 0) nFiddle = 0x3; else nFiddle = 0x7; } else { nFiddle = 3; } } else { nFiddle = ( y&1 )? 0x4 : 0; } int idx = tinfo.tileNo>=0? tile.dwLine*8*y : ((y+tinfo.TopToLoad) * tinfo.Pitch) + tinfo.LeftToLoad; for (uint32_t x = 0; x < tinfo.WidthToLoad; x++, idx++) { uint8_t b = pByteSrc[idx^nFiddle]; if( gRDP.otherMode.text_tlut>=2 || ( tinfo.Format != TXT_FMT_IA && tinfo.Format != TXT_FMT_I) ) { if( tinfo.TLutFmt == TLUT_FMT_IA16 ) { if( tinfo.tileNo>=0 ) *pDst = ConvertIA16ToR4G4B4A4(g_Tmem.g_Tmem16bit[0x400+(b<<2)]); else *pDst = ConvertIA16ToR4G4B4A4(pPal[b^1]); } else { if( tinfo.tileNo>=0 ) *pDst = Convert555ToR4G4B4A4(g_Tmem.g_Tmem16bit[0x400+(b<<2)]); else *pDst = Convert555ToR4G4B4A4(pPal[b^1]); } } else if( tinfo.Format == TXT_FMT_IA ) { *pDst = R4G4B4A4_MAKE( ((b&0xf0)>>4),((b&0xf0)>>4),((b&0xf0)>>4),(b&0x0f)); } else //if( tinfo.Format == TXT_FMT_I ) { *pDst = R4G4B4A4_MAKE(b>>4, b>>4, b>>4, b>>4); } if( bIgnoreAlpha ) { *pDst |= 0xFF000000; } pDst++; } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } void Convert16b_16(CTexture *pTexture, const TxtrInfo &tinfo) { DrawInfo dInfo; if (!pTexture->StartUpdate(&dInfo)) return; Tile &tile = gRDP.tiles[tinfo.tileNo]; uint16_t *pWordSrc; if( tinfo.tileNo >= 0 ) pWordSrc = (uint16_t*)&g_Tmem.g_Tmem64bit[tile.dwTMem]; else pWordSrc = (uint16_t*)(tinfo.pPhysicalAddress); for (uint32_t y = 0; y < tinfo.HeightToLoad; y++) { uint16_t * dwDst = (uint16_t *)((uint8_t *)dInfo.lpSurface + y*dInfo.lPitch); uint32_t nFiddle; if( tinfo.tileNo < 0 ) { if (tinfo.bSwapped) { if ((y&1) == 0) nFiddle = 0x1; else nFiddle = 0x3; } else { nFiddle = 0x1; } } else { nFiddle = ( y&1 )? 0x2 : 0; } int idx = tinfo.tileNo>=0? tile.dwLine*4*y : (((y+tinfo.TopToLoad) * tinfo.Pitch)>>1) + tinfo.LeftToLoad; for (uint32_t x = 0; x < tinfo.WidthToLoad; x++, idx++) { uint16_t w = pWordSrc[idx^nFiddle]; uint16_t w2 = tinfo.tileNo>=0? ((w>>8)|(w<<8)) : w; if( tinfo.Format == TXT_FMT_RGBA ) { dwDst[x] = Convert555ToR4G4B4A4(w2); } else if( tinfo.Format == TXT_FMT_YUV ) { } else if( tinfo.Format >= TXT_FMT_IA ) { uint8_t i = (uint8_t)(w2 >> 12); uint8_t a = (uint8_t)(w2 & 0xFF); dwDst[x] = R4G4B4A4_MAKE(i, i, i, (a>>4)); } } } pTexture->EndUpdate(&dInfo); pTexture->SetOthersVariables(); } mupen64plus-core/src/api/m64p_frontend.h000664 001750 001750 00000010444 12655644434 021250 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-core - m64p_frontend.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2009 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This header file defines typedefs for function pointers to Core functions * designed for use by the front-end user interface. */ #ifndef M64P_FRONTEND_H #define M64P_FRONTEND_H #include "m64p_types.h" #ifdef __cplusplus extern "C" { #endif /* pointer types to the callback functions in the front-end application */ typedef void (*ptr_DebugCallback)(void *Context, int level, const char *message); typedef void (*ptr_StateCallback)(void *Context, m64p_core_param param_type, int new_value); #if defined(M64P_CORE_PROTOTYPES) EXPORT void CALL DebugCallback(void *Context, int level, const char *message); EXPORT void CALL StateCallback(void *Context, m64p_core_param param_type, int new_value); #endif /* CoreStartup() * * This function initializes libmupen64plus for use by allocating memory, * creating data structures, and loading the configuration file. */ typedef m64p_error (*ptr_CoreStartup)(int, const char *, const char *, void *, ptr_DebugCallback, void *, ptr_StateCallback); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL CoreStartup(int, const char *, const char *, void *, ptr_DebugCallback, void *, ptr_StateCallback); #endif /* CoreShutdown() * * This function saves the configuration file, then destroys data structures * and releases memory allocated by the core library. */ typedef m64p_error (*ptr_CoreShutdown)(void); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL CoreShutdown(void); #endif /* CoreDoCommand() * * This function sends a command to the emulator core. */ typedef m64p_error (*ptr_CoreDoCommand)(m64p_command, int, void *); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL CoreDoCommand(m64p_command, int, void *); #endif /* CoreGetRomSettings() * * This function will retrieve the ROM settings from the mupen64plus INI file for * the ROM image corresponding to the given CRC values. */ typedef m64p_error (*ptr_CoreGetRomSettings)(m64p_rom_settings *, int, int, int); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL CoreGetRomSettings(m64p_rom_settings *, int, int, int); #endif /* CoreSetAudioInterfaceBackend() * * This function allows the frontend to specify the audio backend to be used by * the AI controller. If any of the function pointers in the structure are NULL, * a dummy backend will be used (eg no sound). */ typedef m64p_error (*ptr_CoreSetAudioInterfaceBackend)(const struct m64p_audio_backend *); #if defined(M64P_CORE_PROTOTYPES) EXPORT m64p_error CALL CoreSetAudioInterfaceBackend(const struct m64p_audio_backend *); #endif EXPORT m64p_error CALL CoreAddCheat(const char *CheatName, m64p_cheat_code *CodeList, int NumCodes); EXPORT m64p_error CALL CoreCheatEnabled(const char *CheatName, int Enabled); EXPORT m64p_error CALL CoreCheatClearAll(void); #ifdef __cplusplus } #endif #endif /* #define M64P_FRONTEND_H */ gles2rice/src/RenderBase_neon.S000664 001750 001750 00000030504 12655644434 017544 0ustar00sergiosergio000000 000000 /* * (C) Gražvydas "notaz" Ignotas, 2014 * * This work is licensed under the terms of GNU GPL version 2 or later. * See the COPYING file in the top-level directory. */ #if defined(__ARCH_ARM) || defined(__ARM_EABI__) || defined(__ARM_NEON__) #include "arm_features.h" #include "RenderBase_neon.h" .syntax unified .text .align 3 /* * ProcessVertexData register map: * * q | d | c code * ... * 12 24 gRSPworldProject _11,_12,_13,_14 * 25 * 13 26 gRSPworldProject _21,_22,_23,_24 * 27 * 14 28 gRSPworldProject _31,_32,_33,_34 * 29 * 15 30 gRSPworldProject _41,_42,_43,_44 * 31 * * r4 vtx[], 16 bytes: * short y, x, flag, z, tv, tu; * / uint8 a, b, g, r; * \ char a, z, y, x; * * outputs: * r0 - XVECTOR4 *g_vtxTransformed * r1 - XVECTOR4 *g_vecProjected * r2 - uint32 *g_dwVtxDifColor * r3 - VECTOR2 *g_fVtxTxtCoords * sp+00 - float *g_fFogCoord * r6 sp+04 - uint32 *g_clipFlag2 * inputs: * r11 sp+08 - uint32 dwNum * r10 sp+0c - int neon_flags * r4 sp+10 - FiddledVtx vtx[], (r4 [0], r5 [1]) * r7 sp+14 - Light *gRSPlights * sp+18 - float *fRSPAmbientLightRGBA * sp+1c - XMATRIX *gRSPworldProject * sp+20 - XMATRIX *gRSPmodelViewTop * sp+24 - uint32 gRSPnumLights * sp+28 - float gRSPfFogMin * sp+2c - uint32 primitiveColor * sp+30 - uint32 primitiveColor */ FUNCTION(pv_neon): ldr r12, [sp, #0x10] pld [r12] push {r4-r11,lr} vpush {q4-q7} mov r4, r12 @ vtx ldr r12, [sp, #0x64+0x1c] vld1.32 {q12,q13}, [r12, :128]! @ load gRSPworldProject vld1.32 {q14,q15}, [r12, :128] ldr r6, [sp, #0x64+0x04] @ g_clipFlag2 add r5, r4, #16 @ vtx + 1 ldr r11, [sp, #0x64+0x08] @ dwNum ldr r10, [sp, #0x64+0x0c] @ neon_flags 0: vld1.16 d12, [r4]! @ vtx[0] .z .flag .x .y (reg) vmovl.s16 q6, d12 vld1.16 d14, [r5]! @ vtx[1] .z .flag .x .y vmovl.s16 q7, d14 vcvt.f32.s32 q6, q6 @ q6 = vtx_raw0 vcvt.f32.s32 q7, q7 @ q7 = vtx_raw1 vdup.32 q0, d12[1] @ vtx_raw0.x (dup) vdup.32 q1, d12[0] @ vtx_raw0.y (dup) vdup.32 q2, d13[1] @ vtx_raw0.z (dup) vdup.32 q3, d14[1] @ vtx_raw1.x (dup) vdup.32 q4, d14[0] @ vtx_raw1.y (dup) vdup.32 q5, d15[1] @ vtx_raw1.z (dup) /* note: order of operations matters greatly, * may cause like 20 fraction bits to differ! */ vmul.f32 q0, q0, q12 vmul.f32 q3, q3, q12 vmla.f32 q0, q1, q13 vmla.f32 q3, q4, q13 vmul.f32 q2, q2, q14 @ yes, mul+add is vmul.f32 q5, q5, q14 @ faster than mla vadd.f32 q0, q2 vadd.f32 q3, q5 vadd.f32 q0, q15 @ q0 = g_vtxTransformed[i] vadd.f32 q3, q15 @ q3 = g_vtxTransformed[i + 1] vld1.16 d16[1], [r4]! @ [0].v vmov d2, d1 vld1.16 d16[0], [r4]! @ [0].u vsri.64 d2, d7, #32 vld1.16 d18[1], [r5]! @ [0].v #if 1 vrecpe.f32 d4, d2 @ inv [0][1] .w vld1.16 d18[0], [r5]! @ [0].u vrecps.f32 d5, d2, d4 @ step vmovl.s16 q8, d16 /* g_vtxTransformed[0] */ vst1.32 {q0}, [r0, :128]! vmovl.s16 q9, d18 vcvt.f32.s32 d16, d16 vcvt.f32.s32 d18, d18 vmul.f32 d4, d5, d4 @ better inv bic r9, r5, #63 pld [r9, #64] vrecps.f32 d5, d2, d4 @ step cmp r11, #1 /* u,v g_fVtxTxtCoords[0] */ vst1.32 {d16}, [r3]! beq 99f /* g_vtxTransformed[1] */ vst1.32 {q3}, [r0, :128]! /* ... [1] */ vst1.32 {d18}, [r3]! 99: vmov.f32 d20, #1.0 vmov.f32 d21, #-1.0 vmul.f32 d4, d5, d4 @ better inv [0][1] .w #if 0 vrecps.f32 d5, d2, d4 @ step vmul.f32 d4, d5, d4 @ better inv #endif #else mov r12, #0x3f800000 @ 1.0f vmov.f32 s6, r12 vdiv.f32 s8, s6, s4 vdiv.f32 s9, s6, s5 #error incomplete #endif mov r8, #X_CLIP_MAX mov r9, #Y_CLIP_MAX vmov d22, r8, r9 vmul.f32 q0, q0, d4[1] @ .x .y .z .w *= [0] .w vmul.f32 q1, q3, d4[0] vshr.u64 d5, d4, #32 @ [0] .w mov r8, #X_CLIP_MIN mov r9, #Y_CLIP_MIN vmov d23, r8, r9 vsli.64 d3, d4, #32 @ insert [1] .w vsli.64 d1, d5, #32 vsli.u64 d5, d4, #32 @ [0] [1] .w vcgt.f32 d6, d0, d20 @ .xy > 1.0? vcgt.f32 d7, d21, d0 vcgt.f32 d4, d5, #0 @ .w > 0? vst1.32 {q0}, [r1]! @ g_vecProjected[0] vcgt.f32 d8, d2, d20 vcgt.f32 d9, d21, d2 vld1.32 d0[0], [r4]! @ mem: [0] .azyx vand q3, q11 vand q4, q11 cmp r11, #1 beq 99f vst1.32 {q1}, [r1]! @ g_vecProjected[1] 99: vorr d6, d6, d7 vorr d7, d8, d9 vld1.32 d0[1], [r5]! @ mem: [1] .azyx vpadd.u32 d6, d7 vrev32.8 d0, d0 @ make 0xaazzyyxx [1][0] vsli.u64 d1, d3, #32 @ d3 = [1] [0] .z vmovl.s8 q4, d0 vand d6, d4 vmovl.s16 q1, d8 vmovl.s16 q2, d9 vst1.32 {d6}, [r6]! @ g_clipFlag2 tst r10, #PV_NEON_ENABLE_LIGHT beq pv_neon_no_light @ pv_neon_light: @ live NEON registers: @ d1 = [1][0] .z (must preserve) @ q1,q2 = azyx [1][0] @ q12+ = gRSPworldProject ldr r12, [sp, #0x64+0x20] vcvt.f32.s32 q1, q1 vcvt.f32.s32 q2, q2 vld1.32 {q8,q9}, [r12, :128]! @ load gRSPmodelViewTop vld1.32 {q10}, [r12, :128] vdup.32 q5, d4[0] @ [1] .x (dup) vdup.32 q6, d4[1] @ [1] .y (dup) vdup.32 q7, d5[0] @ [1] .z (dup) vdup.32 q2, d2[0] @ [0] .x (dup) vdup.32 q3, d2[1] @ [0] .y (dup) vdup.32 q4, d3[0] @ [0] .z (dup) vmul.f32 q2, q2, q8 vmul.f32 q5, q5, q8 vmla.f32 q2, q3, q9 vmla.f32 q5, q6, q9 vmul.f32 q4, q4, q10 vmul.f32 q7, q7, q10 vadd.f32 q4, q2 @ q4 = temp[0] .xyz0 vadd.f32 q5, q7 @ q5 = temp[1] .xyz0 vmul.f32 q2, q4, q4 @ temp .xyz0 ^2 vmul.f32 q3, q5, q5 vpadd.f32 d2, d4, d5 vpadd.f32 d3, d6, d7 movw r8, #0x0000ffff movt r8, #0x7f7f @ max normal float, ~3.4e+38 vdup.32 d4, r8 vpadd.f32 d2, d2, d3 @ d2 = [1][0] x^2 + y^2 + z^2 vcgt.f32 d5, d2, #0 vbif d2, d4, d5 @ if (d2 == 0) d2 = MAXFLOAT vrsqrte.f32 d3, d2 @ ~ 1/sqrt(d2), d2 = [1][0] .sqrsum vmul.f32 d4, d3, d2 ldr r9, [sp, #0x64+0x18] @ &fRSPAmbientLightRGBA ldr r7, [sp, #0x64+0x14] @ gRSPlights ldr r8, [sp, #0x64+0x24] @ gRSPnumLights vrsqrts.f32 d4, d3, d4 @ step vld1.32 {q6}, [r9] @ rgb vld1.32 {q7}, [r9] @ rgb vmul.f32 d3, d3, d4 @ 1/sqrt(d2) #if 0 /* not necessary? */ vmul.f32 d4, d3, d2 vrsqrts.f32 d4, d3, d4 @ step vmul.f32 d3, d3, d4 @ 1/sqrt(d2) #endif vmul.f32 q2, q4, d3[0] @ q2 = normal[0] .xyz vmul.f32 q3, q5, d3[1] @ q3 = normal[1] .xyz 1: vld1.32 {q8}, [r7] vmul.f32 q4, q8, q2 @ gRSPlights[l] * normal vmul.f32 q5, q8, q3 vpadd.f32 d8, d8, d9 vpadd.f32 d10, d10, d11 vpadd.f32 d8, d8, d10 @ d8 = [1][0] fCosT vcgt.f32 d9, d8, #0 @ if (!(fCosT > 0)) vand d8, d9 @ fCosT = 0 add r9, r7, #OFFSETOF_Light_fr vld1.32 {q8}, [r9] @ .fr .fg .fb vdup.32 q5, d8[1] @ [1] fCosT (dup) vdup.32 q4, d8[0] @ vmla.f32 q7, q8, q5 @ .rgb += frgb * fCosT vmla.f32 q6, q8, q4 add r7, #SIZEOF_Light subs r8, #1 bgt 1b movt r8, #0x437f @ float 255 vdup.32 q8, r8 vcgt.f32 q4, q6, q8 @ if (.rgb > 255) vcgt.f32 q5, q7, q8 vbit q6, q8, q4 @ .rgb = 255 vbit q7, q8, q5 vcvt.u32.f32 q6, q6 vcvt.u32.f32 q7, q7 ldrb r8, [r4, #-4] @ .a from vtx ldrb r9, [r5, #-4] vext.32 q4, q6, q6, #3 @ reg: .abgr -> .bgra vext.32 q5, q7, q7, #3 vmov.32 d8[0], r8 @ use .a from input vmov.32 d10[0], r9 vmovn.u32 d8, q4 vmovn.u32 d10, q5 vmovn.u16 d0, q4 vmovn.u16 d2, q5 vsli.u64 d0, d2, #32 vrev32.8 d0, d0 @ 0xbbggrraa -> 0xaarrggbb b pv_neon_fog_alpha pv_neon_no_light: tst r10, #PV_NEON_ENABLE_SHADE vldr d0, [sp, #0x64+0x2c] @ primitiveColor [0] [1] beq pv_neon_fog_alpha @ easier to do with ARM ldr r8, [r4, #-4] ldr r9, [r5, #-4] ror r8, #8 @ mem: .argb -> .rgba ror r9, #8 @ reg: 0xbbggrraa -> .. vmov d0, r8, r9 pv_neon_fog_alpha: tst r10, #PV_NEON_FOG_ALPHA beq pv_neon_next vmov.f32 d20, #1.0 vcgt.f32 d2, d1, d20 @ [0] [1] .z > 1.0? vcgt.f32 d3, d1, #0 @ > 0? movw r8, #0 movt r8, #0x4f7f @ r8 = (float)(255<<24) vbit d1, d20, d2 @ make 1.0 if needed vand d1, d3 vdup.32 d4, r8 vmul.f32 d1, d1, d4 vcvt.u32.f32 d1, d1 vmov.u32 d5, #0xff000000 vbit d0, d1, d5 pv_neon_next: subs r11, #2 vst1.32 {d0}, [r2]! @ g_dwVtxDifColor add r4, #16 add r5, #16 bgt 0b nop vpop {q4-q7} pop {r4-r11,pc} .size pv_neon, .-pv_neon @ (float *d, const float *m1, const float *m2, const float *s) FUNCTION(multiply_subtract2): vld1.32 {d1}, [r1] vld1.32 {d2}, [r2] vmul.f32 d0, d1, d2 vld1.32 {d3}, [r3] vsub.f32 d0, d3 vst1.32 {d0}, [r0] bx lr .size multiply_subtract2, .-multiply_subtract2 @ (const XVECTOR4 *v0, const XVECTOR4 *v1, const XVECTOR4 *v2) FUNCTION(tv_direction): vld1.32 {q0}, [r0] vld1.32 {q2}, [r2] vld1.32 {q1}, [r1] vsub.f32 d6, d4, d0 @ d6 = V2,V1 vsub.f32 d7, d4, d2 @ d7 = W2,W1 vmul.f32 d1, d5 @ d1 = v0.w * v2.w vrev64.32 d7, d7 vmul.f32 d6, d7 @ d6 = V2*W1,V1*W2 vmul.f32 d1, d3 @ d1 *= v1.w vshr.u64 d7, d6, #32 vsub.f32 d6, d7 @ d6[0] = V1*W2 - V2*W1 vshr.u64 d1, d1, #32 vmul.f32 d0, d1, d6 vmov.32 r0, d0[0] bx lr @ vim:filetype=armasm:expandtab #endif gles2rice/LICENSES000664 001750 001750 00000045600 12655644434 014733 0ustar00sergiosergio000000 000000 Mupen64Plus-video-rice LICENSE ------------------------------ Mupen64Plus-video-rice is licensed under the GNU General Public License version 2. The authors of Mupen64Plus-video-rice are: * Richard Goedeken (Richard42) * Sven Eckelmann (ecsv) * John Chadwick (NMN) * James Hood (Ebenblues) * Scott Gorman (okaygo) * Scott Knauert (Tillin9) * Jesse Dean (DarkJezter) * Louai Al-Khanji (slougi) * Bob Forder (orbitaldecay) * Jason Espinosa (hasone) * Lioncash * Littleguy77 * Metricity * HyperHacker * and others. Mupen64Plus-video-rice is based on the Rice Video plugin, which is GPL-licensed and was originally written by: * Rice1964 * Mudlord GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. mupen64plus-video-gliden64/src/L3D.cpp000664 001750 001750 00000004156 12655644434 020522 0ustar00sergiosergio000000 000000 #include "GLideN64.h" #include "Debug.h" #include "F3D.h" #include "L3D.h" #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gSP.h" #include "gDP.h" #include "GBI.h" void L3D_Line3D( u32 w0, u32 w1 ) { u32 wd = _SHIFTR( w1, 0, 8 ); if (wd == 0) gSPLine3D( _SHIFTR( w1, 16, 8 ) / 10, _SHIFTR( w1, 8, 8 ) / 10, _SHIFTR( w1, 24, 8 ) ); else gSPLineW3D( _SHIFTR( w1, 16, 8 ) / 10, _SHIFTR( w1, 8, 8 ) / 10, wd, _SHIFTR( w1, 24, 8 ) ); } void L3D_Init() { gSPSetupFunctions(); // Set GeometryMode flags GBI_InitFlags( F3D ); GBI.PCStackSize = 10; // GBI Command Command Value Command Function GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_MTX, F3D_MTX, F3D_Mtx ); GBI_SetGBI( G_RESERVED0, F3D_RESERVED0, F3D_Reserved0 ); GBI_SetGBI( G_MOVEMEM, F3D_MOVEMEM, F3D_MoveMem ); GBI_SetGBI( G_VTX, F3D_VTX, F3D_Vtx ); GBI_SetGBI( G_RESERVED1, F3D_RESERVED1, F3D_Reserved1 ); GBI_SetGBI( G_DL, F3D_DL, F3D_DList ); GBI_SetGBI( G_RESERVED2, F3D_RESERVED2, F3D_Reserved2 ); GBI_SetGBI( G_RESERVED3, F3D_RESERVED3, F3D_Reserved3 ); GBI_SetGBI( G_SPRITE2D_BASE, F3D_SPRITE2D_BASE, F3D_Sprite2D_Base ); // GBI_SetGBI( G_TRI1, F3D_TRI1, F3D_Tri1 ); GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3D_CullDL ); GBI_SetGBI( G_POPMTX, F3D_POPMTX, F3D_PopMtx ); GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3D_MoveWord ); GBI_SetGBI( G_TEXTURE, F3D_TEXTURE, F3D_Texture ); GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L ); GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL ); GBI_SetGBI( G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, F3D_SetGeometryMode ); GBI_SetGBI( G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE, F3D_ClearGeometryMode ); GBI_SetGBI( G_LINE3D, L3D_LINE3D, L3D_Line3D ); GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_RDPHALF_CONT, F3D_RDPHALF_CONT, F3D_RDPHalf_Cont ); // GBI_SetGBI( G_TRI4, F3D_TRI4, F3D_Tri4 ); } gles2rice/src/OGLRender.h000664 001750 001750 00000007530 12655644434 016324 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _OGL_RENDER_H_ #define _OGL_RENDER_H_ #include "Combiner.h" #include "Render.h" class OGLRender : public CRender { friend class COGLColorCombiner; friend class COGLBlender; friend class OGLDeviceBuilder; protected: OGLRender(); public: ~OGLRender(); void Initialize(void); bool InitDeviceObjects(); bool ClearDeviceObjects(); void ApplyTextureFilter(); void SetShadeMode(RenderShadeMode mode); void ZBufferEnable(bool bZBuffer); void ClearBuffer(bool cbuffer, bool zbuffer); void ClearZBuffer(float depth); void SetZCompare(bool bZCompare); void SetZUpdate(bool bZUpdate); void SetZBias(int bias); void ApplyZBias(int bias); void SetAlphaRef(uint32_t dwAlpha); void ForceAlphaRef(uint32_t dwAlpha); void SetFillMode(FillMode mode); void SetViewportRender(); void RenderReset(); void SetCullMode(bool bCullFront, bool bCullBack); void SetAlphaTestEnable(bool bAlphaTestEnable); void UpdateScissor(); void ApplyRDPScissor(bool force); void ApplyScissorWithClipRatio(bool force); bool SetCurrentTexture(int tile, CTexture *handler,uint32_t dwTileWidth, uint32_t dwTileHeight, TxtrCacheEntry *pTextureEntry); bool SetCurrentTexture(int tile, TxtrCacheEntry *pTextureEntry); void SetAddressUAllStages(uint32_t dwTile, TextureUVFlag dwFlag); void SetAddressVAllStages(uint32_t dwTile, TextureUVFlag dwFlag); void SetTextureUFlag(TextureUVFlag dwFlag, uint32_t tile); void SetTextureVFlag(TextureUVFlag dwFlag, uint32_t tile); virtual void BindTexture(GLuint texture, int unitno); virtual void DisBindTexture(GLuint texture, int unitno); virtual void TexCoord2f(float u, float v); virtual void TexCoord(TLITVERTEX &vtxInfo); void DrawSimple2DTexture(float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, COLOR dif, COLOR spe, float z, float rhw); void DrawSimpleRect(int nX0, int nY0, int nX1, int nY1, uint32_t dwColor, float depth, float rhw); void InitCombinerBlenderForSimpleRectDraw(uint32_t tile); void DrawSpriteR_Render(); void DrawObjBGCopy(uObjBg &info); void DrawText(const char* str, M64P_RECT *rect); void SetFogMinMax(float fMin, float fMax); void SetFogEnable(bool bEnable); void TurnFogOnOff(bool flag); void SetFogColor(uint32_t r, uint32_t g, uint32_t b, uint32_t a); void DisableMultiTexture(); void EnableMultiTexture() {m_bEnableMultiTexture=true;} void EndRendering(void); void glViewportWrapper(GLint x, GLint y, GLsizei width, GLsizei height, bool flag); virtual void EnableTexUnit(int unitno, bool flag); virtual void SetTexWrapS(int unitno,GLuint flag); virtual void SetTexWrapT(int unitno,GLuint flag); protected: COLOR PostProcessDiffuseColor(COLOR curDiffuseColor); COLOR PostProcessSpecularColor(); // Basic render drawing functions bool RenderFlushTris(); bool RenderTexRect(); bool RenderFillRect(uint32_t dwColor, float depth); bool RenderLine3D(); bool m_bSupportClampToEdge; GLuint m_curBoundTex[8]; bool m_texUnitEnabled[8]; bool m_bEnableMultiTexture; }; #endif mupen64plus-core/src/plugin/audio_libretro/drivers_resampler/cc_resampler.c000664 001750 001750 00000042266 12655644434 030504 0ustar00sergiosergio000000 000000 /* RetroArch - A frontend for libretro. * Copyright (C) 2014-2015 - Ali Bouhlel ( aliaspider@gmail.com ) * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. * * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with RetroArch. * If not, see . */ /* Convoluted Cosine Resampler */ #include "../audio_resampler_driver.h" #include #include #include #ifdef __SSE__ #include #endif #include /* Since SSE and NEON don't provide support for trigonometric functions * we approximate those with polynoms * * CC_RESAMPLER_PRECISION defines how accurate the approximation is * a setting of 5 or more means full precison. * setting 0 doesn't use a polynom * setting 1 uses P(X) = X - (3/4)*X^3 + (1/4)*X^5 * * only 0 and 1 are implemented for SSE and NEON currently * * the MIPS_ARCH_ALLEGREX target doesnt require this setting since it has * native support for the required functions so it will always use full precision. */ #ifndef CC_RESAMPLER_PRECISION #define CC_RESAMPLER_PRECISION 1 #endif #ifndef min #define min(a, b) ((a) < (b) ? (a) : (b)) #endif typedef struct rarch_CC_resampler { audio_frame_float_t buffer[4]; float distance; void (*process)(void *re, struct resampler_data *data); } rarch_CC_resampler_t; /* memalign() replacement functions * copied from sinc.c and changed signature so no conflict * happens when using griffin.c * these functions should probably be moved to a common header */ static void *memalign_alloc__(size_t boundary, size_t size) { void **place; uintptr_t addr = 0; void *ptr = malloc(boundary + size + sizeof(uintptr_t)); if (!ptr) return NULL; addr = ((uintptr_t) ptr + sizeof(uintptr_t) + boundary) & ~(boundary - 1); place = (void**)addr; place[-1] = ptr; return (void*)addr; } static void memalign_free__(void *ptr) { void **p = (void**)ptr; free(p[-1]); } #ifdef _MIPS_ARCH_ALLEGREX static void resampler_CC_process(void *re_, struct resampler_data *data) { float ratio, fraction; audio_frame_float_t *inp = (audio_frame_float_t*)data->data_in; audio_frame_float_t *inp_max = (audio_frame_float_t*) (inp + data->input_frames); audio_frame_float_t *outp = (audio_frame_float_t*)data->data_out; (void)re_; __asm__ ( ".set push\n" ".set noreorder\n" "mtv %2, s700 \n" /* 700 = data->ratio = b */ /* "vsat0.s s700, s700 \n" */ "vrcp.s s701, s700 \n" /* 701 = 1.0 / b */ "vadd.s s702, s700, s700 \n" /* 702 = 2 * b */ "vmul.s s703, s700, s710 \n" /* 703 = b * pi */ "mfv %0, s701 \n" "mfv %1, s730 \n" ".set pop\n" : "=r"(ratio), "=r"(fraction) : "r"((float)data->ratio) ); for (;;) { while (fraction < ratio) { if (inp == inp_max) goto done; __asm__ ( ".set push \n" ".set noreorder \n" "lv.s s620, 0(%1) \n" "lv.s s621, 4(%1) \n" "vsub.s s731, s701, s730 \n" "vadd.q c600, c730[-X,Y,-X,Y], c730[1/2,1/2,-1/2,-1/2]\n" "vmul.q c610, c600, c700[Z,Z,Z,Z] \n" /* *2*b */ "vmul.q c600, c600, c700[W,W,W,W] \n" /* *b*pi */ "vsin.q c610, c610 \n" "vadd.q c600, c600, c610 \n" "vmul.q c600[-1:1,-1:1,-1:1,-1:1], c600, c710[Y,Y,Y,Y] \n" "vsub.p c600, c600, c602 \n" "vmul.q c620, c620[X,Y,X,Y], c600[X,X,Y,Y] \n" "vadd.q c720, c720, c620 \n" "vadd.s s730, s730, s730[1] \n" "mfv %0, s730 \n" ".set pop \n" : "=r"(fraction) : "r"(inp)); inp++; } __asm__ ( ".set push \n" ".set noreorder \n" "vmul.p c720, c720, c720[1/2,1/2] \n" "sv.s s720, 0(%1) \n" "sv.s s721, 4(%1) \n" "vmov.q c720, c720[Z,W,0,0] \n" "vsub.s s730, s730, s701 \n" "mfv %0, s730 \n" ".set pop \n" : "=r"(fraction) : "r"(outp)); outp++; } /* The VFPU state is assumed to remain intact * in-between calls to resampler_CC_process. */ done: data->output_frames = outp - (audio_frame_float_t*)data->data_out; } static void resampler_CC_free(void *re_) { (void)re_; } static void *resampler_CC_init(const struct resampler_config *config, double bandwidth_mod, resampler_simd_mask_t mask) { (void)mask; (void)bandwidth_mod; (void)config; __asm__ ( ".set push\n" ".set noreorder\n" "vcst.s s710, VFPU_PI \n" /* 710 = pi */ "vcst.s s711, VFPU_1_PI \n" /* 711 = 1.0 / (pi) */ "vzero.q c720 \n" "vzero.q c730 \n" ".set pop\n"); return (void*)-1; } #else #if defined(__SSE__) #define CC_RESAMPLER_IDENT "SSE" static void resampler_CC_downsample(void *re_, struct resampler_data *data) { __m128 vec_previous, vec_current; float ratio, b; rarch_CC_resampler_t *re = (rarch_CC_resampler_t*)re_; audio_frame_float_t *inp = (audio_frame_float_t*)data->data_in; audio_frame_float_t *inp_max = (audio_frame_float_t*)(inp + data->input_frames); audio_frame_float_t *outp = (audio_frame_float_t*)data->data_out; ratio = 1.0 / data->ratio; b = data->ratio; /* cutoff frequency. */ vec_previous = _mm_loadu_ps((float*)&re->buffer[0]); vec_current = _mm_loadu_ps((float*)&re->buffer[2]); while (inp != inp_max) { __m128 vec_ww1, vec_ww2; __m128 vec_w_previous; __m128 vec_w_current; __m128 vec_in; __m128 vec_ratio = _mm_mul_ps(_mm_set_ps1(ratio), _mm_set_ps(3.0, 2.0, 1.0, 0.0)); __m128 vec_w = _mm_sub_ps(_mm_set_ps1(re->distance), vec_ratio); __m128 vec_w1 = _mm_add_ps(vec_w , _mm_set_ps1(0.5)); __m128 vec_w2 = _mm_sub_ps(vec_w , _mm_set_ps1(0.5)); __m128 vec_b = _mm_set_ps1(b); vec_w1 = _mm_mul_ps(vec_w1, vec_b); vec_w2 = _mm_mul_ps(vec_w2, vec_b); (void)vec_ww1; (void)vec_ww2; #if (CC_RESAMPLER_PRECISION > 0) vec_ww1 = _mm_mul_ps(vec_w1, vec_w1); vec_ww2 = _mm_mul_ps(vec_w2, vec_w2); vec_ww1 = _mm_mul_ps(vec_ww1, _mm_sub_ps(_mm_set_ps1(3.0),vec_ww1)); vec_ww2 = _mm_mul_ps(vec_ww2, _mm_sub_ps(_mm_set_ps1(3.0),vec_ww2)); vec_ww1 = _mm_mul_ps(_mm_set_ps1(1.0/4.0), vec_ww1); vec_ww2 = _mm_mul_ps(_mm_set_ps1(1.0/4.0), vec_ww2); vec_w1 = _mm_mul_ps(vec_w1, _mm_sub_ps(_mm_set_ps1(1.0), vec_ww1)); vec_w2 = _mm_mul_ps(vec_w2, _mm_sub_ps(_mm_set_ps1(1.0), vec_ww2)); #endif vec_w1 = _mm_min_ps(vec_w1, _mm_set_ps1( 0.5)); vec_w2 = _mm_min_ps(vec_w2, _mm_set_ps1( 0.5)); vec_w1 = _mm_max_ps(vec_w1, _mm_set_ps1(-0.5)); vec_w2 = _mm_max_ps(vec_w2, _mm_set_ps1(-0.5)); vec_w = _mm_sub_ps(vec_w1, vec_w2); vec_w_previous = _mm_shuffle_ps(vec_w,vec_w,_MM_SHUFFLE(1, 1, 0, 0)); vec_w_current = _mm_shuffle_ps(vec_w,vec_w,_MM_SHUFFLE(3, 3, 2, 2)); vec_in = _mm_loadl_pi(_mm_setzero_ps(),(__m64*)inp); vec_in = _mm_shuffle_ps(vec_in,vec_in,_MM_SHUFFLE(1, 0, 1, 0)); vec_previous = _mm_add_ps(vec_previous, _mm_mul_ps(vec_in, vec_w_previous)); vec_current = _mm_add_ps(vec_current, _mm_mul_ps(vec_in, vec_w_current)); re->distance++; inp++; if (re->distance > (ratio + 0.5)) { _mm_storel_pi((__m64*)outp, vec_previous); vec_previous = _mm_shuffle_ps(vec_previous,vec_current,_MM_SHUFFLE(1, 0, 3, 2)); vec_current = _mm_shuffle_ps(vec_current,_mm_setzero_ps(),_MM_SHUFFLE(1, 0, 3, 2)); re->distance -= ratio; outp++; } } _mm_storeu_ps((float*)&re->buffer[0], vec_previous); _mm_storeu_ps((float*)&re->buffer[2], vec_current); data->output_frames = outp - (audio_frame_float_t*)data->data_out; } static void resampler_CC_upsample(void *re_, struct resampler_data *data) { rarch_CC_resampler_t *re = (rarch_CC_resampler_t*)re_; audio_frame_float_t *inp = (audio_frame_float_t*)data->data_in; audio_frame_float_t *inp_max = (audio_frame_float_t*)(inp + data->input_frames); audio_frame_float_t *outp = (audio_frame_float_t*)data->data_out; float b = min(data->ratio, 1.00); /* cutoff frequency. */ float ratio = 1.0 / data->ratio; __m128 vec_previous = _mm_loadu_ps((float*)&re->buffer[0]); __m128 vec_current = _mm_loadu_ps((float*)&re->buffer[2]); while (inp != inp_max) { __m128 vec_in = _mm_loadl_pi(_mm_setzero_ps(),(__m64*)inp); vec_previous = _mm_shuffle_ps(vec_previous,vec_current,_MM_SHUFFLE(1, 0, 3, 2)); vec_current = _mm_shuffle_ps(vec_current,vec_in,_MM_SHUFFLE(1, 0, 3, 2)); while (re->distance < 1.0) { __m128 vec_w_previous, vec_w_current, vec_out; #if (CC_RESAMPLER_PRECISION > 0) __m128 vec_ww1, vec_ww2; #endif __m128 vec_w = _mm_add_ps(_mm_set_ps1(re->distance), _mm_set_ps(-2.0, -1.0, 0.0, 1.0)); __m128 vec_w1 = _mm_add_ps(vec_w , _mm_set_ps1(0.5)); __m128 vec_w2 = _mm_sub_ps(vec_w , _mm_set_ps1(0.5)); __m128 vec_b = _mm_set_ps1(b); vec_w1 = _mm_mul_ps(vec_w1, vec_b); vec_w2 = _mm_mul_ps(vec_w2, vec_b); #if (CC_RESAMPLER_PRECISION > 0) vec_ww1 = _mm_mul_ps(vec_w1, vec_w1); vec_ww2 = _mm_mul_ps(vec_w2, vec_w2); vec_ww1 = _mm_mul_ps(vec_ww1,_mm_sub_ps(_mm_set_ps1(3.0),vec_ww1)); vec_ww2 = _mm_mul_ps(vec_ww2,_mm_sub_ps(_mm_set_ps1(3.0),vec_ww2)); vec_ww1 = _mm_mul_ps(_mm_set_ps1(1.0 / 4.0), vec_ww1); vec_ww2 = _mm_mul_ps(_mm_set_ps1(1.0 / 4.0), vec_ww2); vec_w1 = _mm_mul_ps(vec_w1, _mm_sub_ps(_mm_set_ps1(1.0), vec_ww1)); vec_w2 = _mm_mul_ps(vec_w2, _mm_sub_ps(_mm_set_ps1(1.0), vec_ww2)); #endif vec_w1 = _mm_min_ps(vec_w1, _mm_set_ps1( 0.5)); vec_w2 = _mm_min_ps(vec_w2, _mm_set_ps1( 0.5)); vec_w1 = _mm_max_ps(vec_w1, _mm_set_ps1(-0.5)); vec_w2 = _mm_max_ps(vec_w2, _mm_set_ps1(-0.5)); vec_w = _mm_sub_ps(vec_w1, vec_w2); vec_w_previous = _mm_shuffle_ps(vec_w,vec_w,_MM_SHUFFLE(1, 1, 0, 0)); vec_w_current = _mm_shuffle_ps(vec_w,vec_w,_MM_SHUFFLE(3, 3, 2, 2)); vec_out = _mm_mul_ps(vec_previous, vec_w_previous); vec_out = _mm_add_ps(vec_out, _mm_mul_ps(vec_current, vec_w_current)); vec_out = _mm_add_ps(vec_out, _mm_shuffle_ps(vec_out,vec_out,_MM_SHUFFLE(3, 2, 3, 2))); _mm_storel_pi((__m64*)outp,vec_out); re->distance += ratio; outp++; } re->distance -= 1.0; inp++; } _mm_storeu_ps((float*)&re->buffer[0], vec_previous); _mm_storeu_ps((float*)&re->buffer[2], vec_current); data->output_frames = outp - (audio_frame_float_t*)data->data_out; } #elif defined (__ARM_NEON__) #define CC_RESAMPLER_IDENT "NEON" size_t resampler_CC_downsample_neon(float *outp, const float *inp, rarch_CC_resampler_t* re_, size_t input_frames, float ratio); size_t resampler_CC_upsample_neon (float *outp, const float *inp, rarch_CC_resampler_t* re_, size_t input_frames, float ratio); static void resampler_CC_downsample(void *re_, struct resampler_data *data) { data->output_frames = resampler_CC_downsample_neon( data->data_out, data->data_in, re_, data->input_frames, data->ratio); } static void resampler_CC_upsample(void *re_, struct resampler_data *data) { data->output_frames = resampler_CC_upsample_neon( data->data_out, data->data_in, re_, data->input_frames, data->ratio); } #else /* C reference version. Not optimized. */ #define CC_RESAMPLER_IDENT "C" #if (CC_RESAMPLER_PRECISION > 4) static INLINE float cc_int(float x, float b) { float val = x * b * M_PI + sinf(x * b * M_PI); return (val > M_PI) ? M_PI : (val < -M_PI) ? -M_PI : val; } #define cc_kernel(x, b) ((cc_int((x) + 0.5, (b)) - cc_int((x) - 0.5, (b))) / (2.0 * M_PI)) #else static INLINE float cc_int(float x, float b) { float val = x * b; #if (CC_RESAMPLER_PRECISION > 0) val = val*(1 - 0.25 * val * val * (3.0 - val * val)); #endif return (val > 0.5) ? 0.5 : (val < -0.5) ? -0.5 : val; } #define cc_kernel(x, b) ((cc_int((x) + 0.5, (b)) - cc_int((x) - 0.5, (b)))) #endif static INLINE void add_to(const audio_frame_float_t *source, audio_frame_float_t *target, float ratio) { target->l += source->l * ratio; target->r += source->r * ratio; } static void resampler_CC_downsample(void *re_, struct resampler_data *data) { rarch_CC_resampler_t *re = (rarch_CC_resampler_t*)re_; audio_frame_float_t *inp = (audio_frame_float_t*)data->data_in; audio_frame_float_t *inp_max = (audio_frame_float_t*) (inp + data->input_frames); audio_frame_float_t *outp = (audio_frame_float_t*)data->data_out; float ratio = 1.0 / data->ratio; float b = data->ratio; /* cutoff frequency. */ while (inp != inp_max) { add_to(inp, re->buffer + 0, cc_kernel(re->distance, b)); add_to(inp, re->buffer + 1, cc_kernel(re->distance - ratio, b)); add_to(inp, re->buffer + 2, cc_kernel(re->distance - ratio - ratio, b)); re->distance++; inp++; if (re->distance > (ratio + 0.5)) { *outp = re->buffer[0]; re->buffer[0] = re->buffer[1]; re->buffer[1] = re->buffer[2]; re->buffer[2].l = 0.0; re->buffer[2].r = 0.0; re->distance -= ratio; outp++; } } data->output_frames = outp - (audio_frame_float_t*)data->data_out; } static void resampler_CC_upsample(void *re_, struct resampler_data *data) { rarch_CC_resampler_t *re = (rarch_CC_resampler_t*)re_; audio_frame_float_t *inp = (audio_frame_float_t*)data->data_in; audio_frame_float_t *inp_max = (audio_frame_float_t*) (inp + data->input_frames); audio_frame_float_t *outp = (audio_frame_float_t*)data->data_out; float b = min(data->ratio, 1.00); /* cutoff frequency. */ float ratio = 1.0 / data->ratio; while (inp != inp_max) { re->buffer[0] = re->buffer[1]; re->buffer[1] = re->buffer[2]; re->buffer[2] = re->buffer[3]; re->buffer[3] = *inp; while (re->distance < 1.0) { int i; outp->l = 0.0; outp->r = 0.0; for (i = 0; i < 4; i++) { float temp = cc_kernel(re->distance + 1.0 - i, b); outp->l += re->buffer[i].l * temp; outp->r += re->buffer[i].r * temp; } re->distance += ratio; outp++; } re->distance -= 1.0; inp++; } data->output_frames = outp - (audio_frame_float_t*)data->data_out; } #endif static void resampler_CC_process(void *re_, struct resampler_data *data) { rarch_CC_resampler_t *re = (rarch_CC_resampler_t*)re_; if (re) re->process(re_, data); } static void resampler_CC_free(void *re_) { rarch_CC_resampler_t *re = (rarch_CC_resampler_t*)re_; if (re) memalign_free__(re); } static void *resampler_CC_init(const struct resampler_config *config, double bandwidth_mod, resampler_simd_mask_t mask) { int i; rarch_CC_resampler_t *re = (rarch_CC_resampler_t*) memalign_alloc__(32, sizeof(rarch_CC_resampler_t)); /* TODO: lookup if NEON support can be detected at * runtime and a funcptr set at runtime for either * C codepath or NEON codepath. This will help out * Android. */ (void)mask; (void)config; if (!re) return NULL; for (i = 0; i < 4; i++) { re->buffer[i].l = 0.0; re->buffer[i].r = 0.0; } /* Variations of data->ratio around 0.75 are safer * than around 1.0 for both up/downsampler. */ if (bandwidth_mod < 0.75) { re->process = resampler_CC_downsample; re->distance = 0.0; } else { re->process = resampler_CC_upsample; re->distance = 2.0; } return re; } #endif rarch_resampler_t CC_resampler = { resampler_CC_init, resampler_CC_process, resampler_CC_free, RESAMPLER_API_VERSION, "CC", "cc" }; mupen64plus-core/src/main/profile.h000664 001750 001750 00000004212 12655644434 020372 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - profile.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * Copyright (C) 2012 CasualJames * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef PROFILE_H #define PROFILE_H enum timed_section { TIMED_SECTION_ALL, TIMED_SECTION_GFX, TIMED_SECTION_AUDIO, TIMED_SECTION_COMPILER, TIMED_SECTION_IDLE, NUM_TIMED_SECTIONS }; #ifdef PROFILE void timed_section_start(enum timed_section section); void timed_section_end(enum timed_section section); void timed_sections_refresh(void); #else #define timed_section_start(a) #define timed_section_end(a) #define timed_sections_refresh() #endif #endif mupen64plus-core/src/main/profile.c000664 001750 001750 00000010231 12655644434 020363 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - profile.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * Copyright (C) 2012 CasualJames * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifdef PROFILE #include "profile.h" #include "../api/m64p_types.h" #include "../api/callbacks.h" static long long int time_in_section[NUM_TIMED_SECTIONS]; static long long int last_start[NUM_TIMED_SECTIONS]; #if defined(WIN32) && !defined(__MINGW32__) // timing #include static long long int get_time(void) { LARGE_INTEGER counter; QueryPerformanceCounter(&counter); return counter.QuadPart; } static long long int time_to_nsec(long long int time) { static LARGE_INTEGER freq = { 0 }; if (freq.QuadPart == 0) QueryPerformanceFrequency(&freq); return time * 1000000000 / freq.QuadPart; } #else /* Not WIN32 */ // timing #include static long long int get_time(void) { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); return (long long int)ts.tv_sec * 1000000000 + ts.tv_nsec; } static long long int time_to_nsec(long long int time) { return time; } #endif void timed_section_start(enum timed_section section) { last_start[section] = get_time(); } void timed_section_end(enum timed_section section) { long long int end = get_time(); time_in_section[section] += end - last_start[section]; } void timed_sections_refresh() { long long int curr_time = get_time(); if(time_to_nsec(curr_time - last_start[TIMED_SECTION_ALL]) >= 2000000000) { time_in_section[TIMED_SECTION_ALL] = curr_time - last_start[TIMED_SECTION_ALL]; DebugMessage(M64MSG_INFO, "gfx=%f%% - audio=%f%% - compiler=%f%%, idle=%f%%", 100.0 * (double)time_in_section[TIMED_SECTION_GFX] / time_in_section[TIMED_SECTION_ALL], 100.0 * (double)time_in_section[TIMED_SECTION_AUDIO] / time_in_section[TIMED_SECTION_ALL], 100.0 * (double)time_in_section[TIMED_SECTION_COMPILER] / time_in_section[TIMED_SECTION_ALL], 100.0 * (double)time_in_section[TIMED_SECTION_IDLE] / time_in_section[TIMED_SECTION_ALL]); DebugMessage(M64MSG_INFO, "gfx=%llins - audio=%llins - compiler %llins - idle=%llins", time_to_nsec(time_in_section[TIMED_SECTION_GFX]), time_to_nsec(time_in_section[TIMED_SECTION_AUDIO]), time_to_nsec(time_in_section[TIMED_SECTION_COMPILER]), time_to_nsec(time_in_section[TIMED_SECTION_IDLE])); time_in_section[TIMED_SECTION_GFX] = 0; time_in_section[TIMED_SECTION_AUDIO] = 0; time_in_section[TIMED_SECTION_COMPILER] = 0; time_in_section[TIMED_SECTION_IDLE] = 0; last_start[TIMED_SECTION_ALL] = curr_time; } } #endif gles2n64/src/DepthBuffer.h000664 001750 001750 00000001242 12655644434 016420 0ustar00sergiosergio000000 000000 #ifndef DEPTHBUFFER_H #define DEPTHBUFFER_H #include "Types.h" #ifdef __cplusplus extern "C" { #endif #ifdef __LIBRETRO__ // Prefix symbol #define depthBuffer gln64depthBuffer #endif typedef struct DepthBuffer { struct DepthBuffer *higher, *lower; u32 address, cleared; } DepthBuffer; typedef struct { DepthBuffer *top, *bottom, *current; int numBuffers; } DepthBufferInfo; extern DepthBufferInfo depthBuffer; void DepthBuffer_Init(void); void DepthBuffer_Destroy(void); void DepthBuffer_SetBuffer( u32 address ); void DepthBuffer_RemoveBuffer( u32 address ); DepthBuffer *DepthBuffer_FindBuffer( u32 address ); #ifdef __cplusplus } #endif #endif glide2gl/src/Glide64/ucode04.h000664 001750 001750 00000006102 12655644434 017010 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** //**************************************************************** // uCode 4 - RSP SW 2.0D EXT //**************************************************************** static void uc4_vertex(uint32_t w0, uint32_t w1) { pre_update(); gSPVertex_G64( RSP_SegmentToPhysical(w1), /* v - Current vertex */ _SHIFTR(w0, 4, 12) / 33 + 1, /* n - Number of vertices to copy */ 0 /* v0 */ ); } static void uc4_tri1(uint32_t w0, uint32_t w1) { VERTEX *v[3]; if (rdp.skip_drawing) return; v[0] = &rdp.vtx[_SHIFTR(w1, 16, 8) / 5]; /* v0 */ v[1] = &rdp.vtx[_SHIFTR(w1, 8, 8) / 5]; /* v1 */ v[2] = &rdp.vtx[_SHIFTR(w1, 0, 8) / 5]; /* v2 */ cull_trianglefaces(v, 1, true, true, 0); } static void uc4_quad3d(uint32_t w0, uint32_t w1) { VERTEX *v[6]; if (rdp.skip_drawing) return; v[0] = &rdp.vtx[_SHIFTR(w1, 24, 8) / 5]; /* v00 */ v[1] = &rdp.vtx[_SHIFTR(w1, 16, 8) / 5]; /* v01 */ v[2] = &rdp.vtx[_SHIFTR(w1, 8, 8) / 5]; /* v02 */ v[3] = &rdp.vtx[((w1 >> 24) & 0xFF) / 5]; /* v10 */ v[4] = &rdp.vtx[((w1 >> 8) & 0xFF) / 5]; /* v11 */ v[5] = &rdp.vtx[_SHIFTR(w1, 0, 8) / 5]; /* v12 */ cull_trianglefaces(v, 2, true, true, 0); } mupen64plus-core/src/ai/ai_controller.h000664 001750 001750 00000005246 12655644434 021243 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - ai_controller.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_AI_AI_CONTROLLER_H #define M64P_AI_AI_CONTROLLER_H #include "../api/m64p_types.h" #include #include #ifndef AI_REG #define AI_REG(a) ((a & 0xFFFF) >> 2) #endif struct r4300_core; struct ri_controller; struct vi_controller; enum ai_registers { AI_DRAM_ADDR_REG, AI_LEN_REG, AI_CONTROL_REG, AI_STATUS_REG, AI_DACRATE_REG, AI_BITRATE_REG, AI_REGS_COUNT }; struct ai_dma { uint32_t address; uint32_t length; unsigned int duration; }; struct ai_controller { uint32_t regs[AI_REGS_COUNT]; struct ai_dma fifo[2]; unsigned int samples_format_changed; struct m64p_audio_backend backend; struct r4300_core* r4300; struct ri_controller* ri; struct vi_controller* vi; }; void connect_ai(struct ai_controller* ai, struct r4300_core* r4300, struct ri_controller* ri, struct vi_controller* vi); void init_ai(struct ai_controller* ai); int read_ai_regs(void* opaque, uint32_t address, uint32_t* value); int write_ai_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask); void ai_end_of_dma_event(struct ai_controller* ai); #endif glide2gl/src/Glide64/GBI.h000664 001750 001750 00000043015 12655644434 016152 0ustar00sergiosergio000000 000000 #ifndef GBI_H #define GBI_H #ifdef __cplusplus extern "C" { #endif // Microcode Types #define F3D 0 #define F3DEX 1 #define F3DEX2 2 #define L3D 3 #define L3DEX 4 #define L3DEX2 5 #define S2DEX 6 #define S2DEX2 7 #define F3DPD 8 #define F3DDKR 9 #define F3DWRUS 10 #define F3DCBFD 11 #define NONE 12 #define F3DCBFD_MV_VIEWPORT 8 #define F3DCBFD_MV_LIGHT 10 #define F3DCBFD_MV_NORMAL 14 // Fixed point conversion factors #define FIXED2FLOATRECIP1 0.5f #define FIXED2FLOATRECIP2 0.25f #define FIXED2FLOATRECIP3 0.125f #define FIXED2FLOATRECIP4 0.0625f #define FIXED2FLOATRECIP5 0.03125f #define FIXED2FLOATRECIP6 0.015625f #define FIXED2FLOATRECIP7 0.0078125f #define FIXED2FLOATRECIP8 0.00390625f #define FIXED2FLOATRECIP9 0.001953125f #define FIXED2FLOATRECIP10 0.0009765625f #define FIXED2FLOATRECIP11 0.00048828125f #define FIXED2FLOATRECIP12 0.00024414063f #define FIXED2FLOATRECIP13 0.00012207031f #define FIXED2FLOATRECIP14 6.1035156e-05f #define FIXED2FLOATRECIP15 3.0517578e-05f #define FIXED2FLOATRECIP16 1.5258789e-05f #define _FIXED2FLOAT( v, b ) \ ((float)v * FIXED2FLOATRECIP##b) // Useful macros for decoding GBI command's parameters #define _SHIFTL( v, s, w ) \ (((uint32_t)v & ((0x01 << w) - 1)) << s) #define _SHIFTR( v, s, w ) \ (((uint32_t)v >> s) & ((0x01 << w) - 1)) // BG flags #define G_BGLT_LOADBLOCK 0x0033 #define G_BGLT_LOADTILE 0xfff4 #define G_BG_FLAG_FLIPS 0x01 #define G_BG_FLAG_FLIPT 0x10 // Sprite object render modes #define G_OBJRM_NOTXCLAMP 0x01 #define G_OBJRM_XLU 0x02 /* Ignored */ #define G_OBJRM_ANTIALIAS 0x04 /* Ignored */ #define G_OBJRM_BILERP 0x08 #define G_OBJRM_SHRINKSIZE_1 0x10 #define G_OBJRM_SHRINKSIZE_2 0x20 #define G_OBJRM_WIDEN 0x40 // Sprite texture loading types #define G_OBJLT_TXTRBLOCK 0x00001033 #define G_OBJLT_TXTRTILE 0x00fc1034 #define G_OBJLT_TLUT 0x00000030 // These are all the constant flags #define G_ZBUFFER 0x00000001 #define G_SHADE 0x00000004 #define G_FOG 0x00010000 #define G_LIGHTING 0x00020000 #define G_TEXTURE_GEN 0x00040000 #define G_TEXTURE_GEN_LINEAR 0x00080000 #define G_LOD 0x00100000 #define G_POINT_LIGHTING 0x00400000 #define G_MV_MMTX 2 #define G_MV_PMTX 6 #define G_MV_LIGHT 10 #define G_MV_POINT 12 #define G_MV_MATRIX 14 #define G_MV_NORMALES 14 #define G_MVO_LOOKATX 0 #define G_MVO_LOOKATY 24 #define G_MVO_L0 48 #define G_MVO_L1 72 #define G_MVO_L2 96 #define G_MVO_L3 120 #define G_MVO_L4 144 #define G_MVO_L5 168 #define G_MVO_L6 192 #define G_MVO_L7 216 #define G_MV_LOOKATY 0x82 #define G_MV_LOOKATX 0x84 #define G_MV_L0 0x86 #define G_MV_L1 0x88 #define G_MV_L2 0x8a #define G_MV_L3 0x8c #define G_MV_L4 0x8e #define G_MV_L5 0x90 #define G_MV_L6 0x92 #define G_MV_L7 0x94 #define G_MV_TXTATT 0x96 #define G_MV_MATRIX_1 0x9E #define G_MV_MATRIX_2 0x98 #define G_MV_MATRIX_3 0x9A #define G_MV_MATRIX_4 0x9C #define G_MW_MATRIX 0x00 #define G_MW_NUMLIGHT 0x02 #define G_MW_CLIP 0x04 #define G_MW_SEGMENT 0x06 #define G_MW_FOG 0x08 #define G_MW_LIGHTCOL 0x0A #define G_MW_FORCEMTX 0x0C #define G_MW_POINTS 0x0C #define G_MW_PERSPNORM 0x0E #define G_MV_COORDMOD 0x10 //Conker Bad Fur Day #define G_MWO_NUMLIGHT 0x00 #define G_MWO_CLIP_RNX 0x04 #define G_MWO_CLIP_RNY 0x0c #define G_MWO_CLIP_RPX 0x14 #define G_MWO_CLIP_RPY 0x1c #define G_MWO_SEGMENT_0 0x00 #define G_MWO_SEGMENT_1 0x01 #define G_MWO_SEGMENT_2 0x02 #define G_MWO_SEGMENT_3 0x03 #define G_MWO_SEGMENT_4 0x04 #define G_MWO_SEGMENT_5 0x05 #define G_MWO_SEGMENT_6 0x06 #define G_MWO_SEGMENT_7 0x07 #define G_MWO_SEGMENT_8 0x08 #define G_MWO_SEGMENT_9 0x09 #define G_MWO_SEGMENT_A 0x0a #define G_MWO_SEGMENT_B 0x0b #define G_MWO_SEGMENT_C 0x0c #define G_MWO_SEGMENT_D 0x0d #define G_MWO_SEGMENT_E 0x0e #define G_MWO_SEGMENT_F 0x0f #define G_MWO_FOG 0x00 #define G_MWO_MATRIX_XX_XY_I 0x00 #define G_MWO_MATRIX_XZ_XW_I 0x04 #define G_MWO_MATRIX_YX_YY_I 0x08 #define G_MWO_MATRIX_YZ_YW_I 0x0C #define G_MWO_MATRIX_ZX_ZY_I 0x10 #define G_MWO_MATRIX_ZZ_ZW_I 0x14 #define G_MWO_MATRIX_WX_WY_I 0x18 #define G_MWO_MATRIX_WZ_WW_I 0x1C #define G_MWO_MATRIX_XX_XY_F 0x20 #define G_MWO_MATRIX_XZ_XW_F 0x24 #define G_MWO_MATRIX_YX_YY_F 0x28 #define G_MWO_MATRIX_YZ_YW_F 0x2C #define G_MWO_MATRIX_ZX_ZY_F 0x30 #define G_MWO_MATRIX_ZZ_ZW_F 0x34 #define G_MWO_MATRIX_WX_WY_F 0x38 #define G_MWO_MATRIX_WZ_WW_F 0x3C #define G_MWO_POINT_RGBA 0x10 #define G_MWO_POINT_ST 0x14 #define G_MWO_POINT_XYSCREEN 0x18 #define G_MWO_POINT_ZSCREEN 0x1C // Image formats #define G_IM_FMT_RGBA 0 #define G_IM_FMT_YUV 1 #define G_IM_FMT_CI 2 #define G_IM_FMT_IA 3 #define G_IM_FMT_I 4 #define G_IM_FMT_CI_IA 5 //not real // Image sizes #define G_IM_SIZ_4b 0 #define G_IM_SIZ_8b 1 #define G_IM_SIZ_16b 2 #define G_IM_SIZ_32b 3 #define G_IM_SIZ_DD 5 #define G_TX_MIRROR 0x1 #define G_TX_CLAMP 0x2 #ifdef DEBUG static const char *ImageFormatText[] = { "G_IM_FMT_RGBA", "G_IM_FMT_YUV", "G_IM_FMT_CI", "G_IM_FMT_IA", "G_IM_FMT_I", "G_IM_FMT_INVALID", "G_IM_FMT_INVALID", "G_IM_FMT_INVALID" }; static const char *ImageSizeText[] = { "G_IM_SIZ_4b", "G_IM_SIZ_8b", "G_IM_SIZ_16b", "G_IM_SIZ_32b" }; static const char *SegmentText[] = { "G_MWO_SEGMENT_0", "G_MWO_SEGMENT_1", "G_MWO_SEGMENT_2", "G_MWO_SEGMENT_3", "G_MWO_SEGMENT_4", "G_MWO_SEGMENT_5", "G_MWO_SEGMENT_6", "G_MWO_SEGMENT_7", "G_MWO_SEGMENT_8", "G_MWO_SEGMENT_9", "G_MWO_SEGMENT_A", "G_MWO_SEGMENT_B", "G_MWO_SEGMENT_C", "G_MWO_SEGMENT_D", "G_MWO_SEGMENT_E", "G_MWO_SEGMENT_F" }; #endif #define G_NOOP 0x00 #define G_IMMFIRST -65 // These GBI commands are common to all ucodes #define G_SETCIMG 0xFF /* -1 */ #define G_SETZIMG 0xFE /* -2 */ #define G_SETTIMG 0xFD /* -3 */ #define G_SETCOMBINE 0xFC /* -4 */ #define G_SETENVCOLOR 0xFB /* -5 */ #define G_SETPRIMCOLOR 0xFA /* -6 */ #define G_SETBLENDCOLOR 0xF9 /* -7 */ #define G_SETFOGCOLOR 0xF8 /* -8 */ #define G_SETFILLCOLOR 0xF7 /* -9 */ #define G_FILLRECT 0xF6 /* -10 */ #define G_SETTILE 0xF5 /* -11 */ #define G_LOADTILE 0xF4 /* -12 */ #define G_LOADBLOCK 0xF3 /* -13 */ #define G_SETTILESIZE 0xF2 /* -14 */ #define G_LOADTLUT 0xF0 /* -16 */ #define G_RDPSETOTHERMODE 0xEF /* -17 */ #define G_SETPRIMDEPTH 0xEE /* -18 */ #define G_SETSCISSOR 0xED /* -19 */ #define G_SETCONVERT 0xEC /* -20 */ #define G_SETKEYR 0xEB /* -21 */ #define G_SETKEYGB 0xEA /* -22 */ #define G_RDPFULLSYNC 0xE9 /* -23 */ #define G_RDPTILESYNC 0xE8 /* -24 */ #define G_RDPPIPESYNC 0xE7 /* -25 */ #define G_RDPLOADSYNC 0xE6 /* -26 */ #define G_TEXRECTFLIP 0xE5 /* -27 */ #define G_TEXRECT 0xE4 /* -28 */ #define G_RDPNOOP 0xC0 #define G_TRI_FILL 0xC8 /* fill triangle: 11001000 */ #define G_TRI_FILL_ZBUFF 0xC9 /* fill, zbuff triangle: 11001001 */ #define G_TRI_TXTR 0xCA /* texture triangle: 11001010 */ #define G_TRI_TXTR_ZBUFF 0xCB /* texture, zbuff triangle: 11001011 */ #define G_TRI_SHADE 0xCC /* shade triangle: 11001100 */ #define G_TRI_SHADE_ZBUFF 0xCD /* shade, zbuff triangle: 11001101 */ #define G_TRI_SHADE_TXTR 0xCE /* shade, texture triangle: 11001110 */ #define G_TRI_SHADE_TXTR_ZBUFF 0xCF /* shade, txtr, zbuff trngl: 11001111 */ #define G_SETOTHERMODE_H 0xe3 #define G_SETOTHERMODE_L 0xe2 /* * G_SETOTHERMODE_L sft: shift count */ #define G_MDSFT_ALPHACOMPARE 0 #define G_MDSFT_ZSRCSEL 2 #define G_MDSFT_RENDERMODE 3 #define G_MDSFT_BLENDER 16 /* * G_SETOTHERMODE_H sft: shift count */ #define G_MDSFT_BLENDMASK 0 /* unsupported */ #define G_MDSFT_ALPHADITHER 4 #define G_MDSFT_RGBDITHER 6 #define G_MDSFT_COMBKEY 8 #define G_MDSFT_TEXTCONV 9 #define G_MDSFT_TEXTFILT 12 #define G_MDSFT_TEXTLUT 14 #define G_MDSFT_TEXTLOD 16 #define G_MDSFT_TEXTDETAIL 17 #define G_MDSFT_TEXTPERSP 19 #define G_MDSFT_CYCLETYPE 20 #define G_MDSFT_COLORDITHER 22 /* unsupported in HW 2.0 */ #define G_MDSFT_PIPELINE 23 /* G_SETOTHERMODE_H gPipelineMode */ #define G_PM_1PRIMITIVE 1 #define G_PM_NPRIMITIVE 0 /* G_SETOTHERMODE_H gSetCycleType */ #define G_CYC_1CYCLE 0 #define G_CYC_2CYCLE 1 #define G_CYC_COPY 2 #define G_CYC_FILL 3 /* G_SETOTHERMODE_H gSetTexturePersp */ #define G_TP_NONE 0 #define G_TP_PERSP 1 /* G_SETOTHERMODE_H gSetTextureDetail */ #define G_TD_CLAMP 0 #define G_TD_SHARPEN 1 #define G_TD_DETAIL 2 /* G_SETOTHERMODE_H gSetTextureLOD */ #define G_TL_TILE 0 #define G_TL_LOD 1 /* G_SETOTHERMODE_H gSetTextureLUT */ #define G_TT_NONE 0 #define G_TT_RGBA16 2 #define G_TT_IA16 3 /* G_SETOTHERMODE_H gSetTextureFilter */ #define G_TF_POINT 0 #define G_TF_AVERAGE 3 #define G_TF_BILERP 2 /* G_SETOTHERMODE_H gSetTextureConvert */ #define G_TC_CONV 0 #define G_TC_FILTCONV 5 #define G_TC_FILT 6 /* G_SETOTHERMODE_H gSetCombineKey */ #define G_CK_NONE 0 #define G_CK_KEY 1 /* G_SETOTHERMODE_H gSetColorDither */ #define G_CD_MAGICSQ 0 #define G_CD_BAYER 1 #define G_CD_NOISE 2 #define G_CD_DISABLE 3 #define G_CD_ENABLE G_CD_NOISE /* HW 1.0 compatibility mode */ /* G_SETOTHERMODE_H gSetAlphaDither */ #define G_AD_PATTERN 0 #define G_AD_NOTPATTERN 1 #define G_AD_NOISE 2 #define G_AD_DISABLE 3 /* G_SETOTHERMODE_L gSetAlphaCompare */ #define G_AC_NONE 0 #define G_AC_THRESHOLD 1 #define G_AC_DITHER 3 /* G_SETOTHERMODE_L gSetDepthSource */ #define G_ZS_PIXEL 0 #define G_ZS_PRIM 1 /* G_SETOTHERMODE_L gSetRenderMode */ #define AA_EN 1 #define Z_CMP 1 #define Z_UPD 1 #define IM_RD 1 #define CLR_ON_CVG 0x80 #define CVG_DST_CLAMP 0 #define CVG_DST_WRAP 1 #define CVG_DST_FULL 2 #define CVG_DST_SAVE 3 #define ZMODE_OPA 0 #define ZMODE_INTER 1 #define ZMODE_XLU 2 #define ZMODE_DEC 3 #define CVG_X_ALPHA 1 #define FORCE_BL 0x4000 #define ALPHA_CVG_SEL 0x2000 #define TEX_EDGE 0 // not used #define G_SC_NON_INTERLACE 0 #define G_SC_EVEN_INTERLACE 2 #define G_SC_ODD_INTERLACE 3 #ifdef DEBUG static const char *AAEnableText = "AA_EN"; static const char *DepthCompareText = "Z_CMP"; static const char *DepthUpdateText = "Z_UPD"; static const char *ClearOnCvgText = "CLR_ON_CVG"; static const char *CvgXAlphaText = "CVG_X_ALPHA"; static const char *AlphaCvgSelText = "ALPHA_CVG_SEL"; static const char *ForceBlenderText = "FORCE_BL"; static const char *AlphaCompareText[] = { "G_AC_NONE", "G_AC_THRESHOLD", "G_AC_INVALID", "G_AC_DITHER" }; static const char *DepthSourceText[] = { "G_ZS_PIXEL", "G_ZS_PRIM" }; static const char *AlphaDitherText[] = { "G_AD_PATTERN", "G_AD_NOTPATTERN", "G_AD_NOISE", "G_AD_DISABLE" }; static const char *ColorDitherText[] = { "G_CD_MAGICSQ", "G_CD_BAYER", "G_CD_NOISE", "G_CD_DISABLE" }; static const char *CombineKeyText[] = { "G_CK_NONE", "G_CK_KEY" }; static const char *TextureConvertText[] = { "G_TC_CONV", "G_TC_INVALID", "G_TC_INVALID", "G_TC_INVALID", "G_TC_INVALID", "G_TC_FILTCONV", "G_TC_FILT", "G_TC_INVALID" }; static const char *TextureFilterText[] = { "G_TF_POINT", "G_TF_INVALID", "G_TF_BILERP", "G_TF_AVERAGE" }; static const char *TextureLUTText[] = { "G_TT_NONE", "G_TT_INVALID", "G_TT_RGBA16", "G_TT_IA16" }; static const char *TextureLODText[] = { "G_TL_TILE", "G_TL_LOD" }; static const char *TextureDetailText[] = { "G_TD_CLAMP", "G_TD_SHARPEN", "G_TD_DETAIL" }; static const char *TexturePerspText[] = { "G_TP_NONE", "G_TP_PERSP" }; static const char *CycleTypeText[] = { "G_CYC_1CYCLE", "G_CYC_2CYCLE", "G_CYC_COPY", "G_CYC_FILL" }; static const char *PipelineModeText[] = { "G_PM_NPRIMITIVE", "G_PM_1PRIMITIVE" }; static const char *CvgDestText[] = { "CVG_DST_CLAMP", "CVG_DST_WRAP", "CVG_DST_FULL", "CVG_DST_SAVE" }; static const char *DepthModeText[] = { "ZMODE_OPA", "ZMODE_INTER", "ZMODE_XLU", "ZMODE_DEC" }; static const char *ScissorModeText[] = { "G_SC_NON_INTERLACE", "G_SC_INVALID", "G_SC_EVEN_INTERLACE", "G_SC_ODD_INTERLACE" }; #endif /* Color combiner constants: */ #define G_CCMUX_COMBINED 0 #define G_CCMUX_TEXEL0 1 #define G_CCMUX_TEXEL1 2 #define G_CCMUX_PRIMITIVE 3 #define G_CCMUX_SHADE 4 #define G_CCMUX_ENVIRONMENT 5 #define G_CCMUX_CENTER 6 #define G_CCMUX_SCALE 6 #define G_CCMUX_COMBINED_ALPHA 7 #define G_CCMUX_TEXEL0_ALPHA 8 #define G_CCMUX_TEXEL1_ALPHA 9 #define G_CCMUX_PRIMITIVE_ALPHA 10 #define G_CCMUX_SHADE_ALPHA 11 #define G_CCMUX_ENV_ALPHA 12 #define G_CCMUX_LOD_FRACTION 13 #define G_CCMUX_PRIM_LOD_FRAC 14 #define G_CCMUX_NOISE 7 #define G_CCMUX_K4 7 #define G_CCMUX_K5 15 #define G_CCMUX_1 6 #define G_CCMUX_0 31 /* Alpha combiner constants: */ #define G_ACMUX_COMBINED 0 #define G_ACMUX_TEXEL0 1 #define G_ACMUX_TEXEL1 2 #define G_ACMUX_PRIMITIVE 3 #define G_ACMUX_SHADE 4 #define G_ACMUX_ENVIRONMENT 5 #define G_ACMUX_LOD_FRACTION 0 #define G_ACMUX_PRIM_LOD_FRAC 6 #define G_ACMUX_1 6 #define G_ACMUX_0 7 #ifdef DEBUG static const char *saRGBText[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "NOISE", "1", "0", "0", "0", "0", "0", "0", "0", "0" }; static const char *sbRGBText[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "CENTER", "K4", "0", "0", "0", "0", "0", "0", "0", "0" }; static const char *mRGBText[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "SCALE", "COMBINED_ALPHA", "TEXEL0_ALPHA", "TEXEL1_ALPHA", "PRIMITIVE_ALPHA", "SHADE_ALPHA", "ENV_ALPHA", "LOD_FRACTION", "PRIM_LOD_FRAC", "K5", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" }; static const char *aRGBText[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "1", "0", }; static const char *saAText[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "1", "0", }; static const char *sbAText[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "1", "0", }; static const char *mAText[] = { "LOD_FRACTION", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "PRIM_LOD_FRAC", "0", }; static const char *aAText[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "1", "0", }; #endif #define LIGHT_1 1 #define LIGHT_2 2 #define LIGHT_3 3 #define LIGHT_4 4 #define LIGHT_5 5 #define LIGHT_6 6 #define LIGHT_7 7 #define LIGHT_8 8 #define G_DL_PUSH 0x00 #define G_DL_NOPUSH 0x01 //Blender #define BLEND_FOG_ASHADE 0xc800 #define BLEND_FOG_APRIME 0xc400 #define BLEND_XLU 0x0040 #define ZMODE_DECAL 0xc00 #define ZLUT_SIZE 0x40000 #define X_CLIP_MAX 0x01 #define X_CLIP_MIN 0x02 #define Y_CLIP_MAX 0x04 #define Y_CLIP_MIN 0x08 #define Z_CLIP_MAX 0x10 #define Z_CLIP_MIN 0x20 // G_MTX: parameter flags # define G_MTX_MODELVIEW 0x00 /* matrix types */ # define G_MTX_PROJECTION 0x04 # define G_MTX_MUL 0x00 /* concat or load */ # define G_MTX_LOAD 0x02 # define G_MTX_NOPUSH 0x00 /* push or not */ # define G_MTX_PUSH 0x01 #ifdef __cplusplus } #endif #endif gles2n64/src/DepthBuffer.c000664 001750 001750 00000006362 12655644434 016423 0ustar00sergiosergio000000 000000 #include #include "DepthBuffer.h" #include "Types.h" DepthBufferInfo depthBuffer; void DepthBuffer_Init(void) { depthBuffer.current = NULL; depthBuffer.top = NULL; depthBuffer.bottom = NULL; depthBuffer.numBuffers = 0; } void DepthBuffer_RemoveBottom(void) { DepthBuffer *newBottom = depthBuffer.bottom->higher; if (depthBuffer.bottom == depthBuffer.top) depthBuffer.top = NULL; free( depthBuffer.bottom ); depthBuffer.bottom = newBottom; if (depthBuffer.bottom != NULL) depthBuffer.bottom->lower = NULL; depthBuffer.numBuffers--; } void DepthBuffer_Remove( DepthBuffer *buffer ) { if ((buffer == depthBuffer.bottom) && (buffer == depthBuffer.top)) { depthBuffer.top = NULL; depthBuffer.bottom = NULL; } else if (buffer == depthBuffer.bottom) { depthBuffer.bottom = buffer->higher; if (depthBuffer.bottom) depthBuffer.bottom->lower = NULL; } else if (buffer == depthBuffer.top) { depthBuffer.top = buffer->lower; if (depthBuffer.top) depthBuffer.top->higher = NULL; } else { buffer->higher->lower = buffer->lower; buffer->lower->higher = buffer->higher; } free( buffer ); depthBuffer.numBuffers--; } void DepthBuffer_RemoveBuffer( u32 address ) { DepthBuffer *current = depthBuffer.bottom; while (current != NULL) { if (current->address == address) { DepthBuffer_Remove( current ); return; } current = current->higher; } } DepthBuffer *DepthBuffer_AddTop(void) { DepthBuffer *newtop = (DepthBuffer*)malloc( sizeof( DepthBuffer ) ); newtop->lower = depthBuffer.top; newtop->higher = NULL; if (depthBuffer.top) depthBuffer.top->higher = newtop; if (!depthBuffer.bottom) depthBuffer.bottom = newtop; depthBuffer.top = newtop; depthBuffer.numBuffers++; return newtop; } void DepthBuffer_MoveToTop( DepthBuffer *newtop ) { if (newtop == depthBuffer.top) return; if (newtop == depthBuffer.bottom) { depthBuffer.bottom = newtop->higher; depthBuffer.bottom->lower = NULL; } else { newtop->higher->lower = newtop->lower; newtop->lower->higher = newtop->higher; } newtop->higher = NULL; newtop->lower = depthBuffer.top; depthBuffer.top->higher = newtop; depthBuffer.top = newtop; } void DepthBuffer_Destroy(void) { while (depthBuffer.bottom) DepthBuffer_RemoveBottom(); depthBuffer.top = NULL; } void DepthBuffer_SetBuffer( u32 address ) { DepthBuffer *current = depthBuffer.top; // Search through saved depth buffers while (current != NULL) { if (current->address == address) { DepthBuffer_MoveToTop( current ); depthBuffer.current = current; return; } current = current->lower; } current = DepthBuffer_AddTop(); current->address = address; current->cleared = TRUE; depthBuffer.current = current; } DepthBuffer *DepthBuffer_FindBuffer( u32 address ) { DepthBuffer *current = depthBuffer.top; while (current) { if (current->address == address) return current; current = current->lower; } return NULL; } gles2rice/src/RenderTexture.cpp000664 001750 001750 00000003745 12655644434 017702 0ustar00sergiosergio000000 000000 /* Copyright (C) 2005 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "osal_opengl.h" #include "Debugger.h" #include "FrameBuffer.h" #include "OGLTexture.h" // =========================================================================== COGLRenderTexture::COGLRenderTexture(int width, int height, RenderTextureInfo* pInfo, TextureUsage usage) : CRenderTexture(width, height, pInfo, usage), m_pOGLTexture(NULL) { if( usage == AS_BACK_BUFFER_SAVE ) { m_pTexture = m_pOGLTexture = new COGLTexture(width, height, usage); if( !m_pTexture ) { TRACE0("Error to create OGL render_texture"); SAFE_DELETE(m_pTexture); } } m_width = width; m_height = height; m_beingRendered = false; } COGLRenderTexture::~COGLRenderTexture() { if( m_beingRendered ) { g_pFrameBufferManager->CloseRenderTexture(false); SetAsRenderTarget(false); } ShutdownPBuffer(); SAFE_DELETE(m_pTexture); m_pOGLTexture = NULL; m_beingRendered = false; } bool COGLRenderTexture::InitPBuffer( void ) { return true; } void COGLRenderTexture::ShutdownPBuffer(void) { } bool COGLRenderTexture::SetAsRenderTarget(bool enable) { return true; } void COGLRenderTexture::LoadTexture(TxtrCacheEntry* pEntry) { } void COGLRenderTexture::StoreToRDRAM(int infoIdx) { } mupen64plus-core/src/ai/ai_controller.c000664 001750 001750 00000014677 12655644434 021246 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - ai_controller.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "ai_controller.h" #include "api/audio_backend.h" #include "main/rom.h" #include "memory/memory.h" #include "r4300/r4300_core.h" #include "ri/ri_controller.h" #include "vi/vi_controller.h" #include void set_audio_format_via_libretro(void* user_data, unsigned int frequency, unsigned int bits); void push_audio_samples_via_libretro(void* user_data, const void* buffer, size_t size); enum { AI_STATUS_BUSY = 0x40000000, AI_STATUS_FULL = 0x80000000 }; void connect_ai(struct ai_controller* ai, struct r4300_core* r4300, struct ri_controller *ri, struct vi_controller* vi) { ai->r4300 = r4300; ai->ri = ri; ai->vi = vi; } static uint32_t get_remaining_dma_length(struct ai_controller* ai) { unsigned int next_ai_event; unsigned int remaining_dma_duration; const uint32_t* cp0_regs; if (ai->fifo[0].duration == 0) return 0; cp0_update_count(); next_ai_event = get_event(AI_INT); if (next_ai_event == 0) return 0; cp0_regs = r4300_cp0_regs(); remaining_dma_duration = next_ai_event - cp0_regs[CP0_COUNT_REG]; if (remaining_dma_duration >= 0x80000000) return 0; return (uint64_t)remaining_dma_duration * ai->fifo[0].length / ai->fifo[0].duration; } static unsigned int get_dma_duration(struct ai_controller* ai) { unsigned int samples_per_sec = ROM_PARAMS.aidacrate / (1 + ai->regs[AI_DACRATE_REG]); return ((uint64_t)ai->regs[AI_LEN_REG]*ai->vi->delay*ROM_PARAMS.vilimit) / (4 * samples_per_sec); } static void do_dma(struct ai_controller* ai, const struct ai_dma* dma) { /* lazy initialization of sample format */ if (ai->samples_format_changed) { unsigned int frequency = (ai->regs[AI_DACRATE_REG] == 0) ? 44100 : ROM_PARAMS.aidacrate / (1 + ai->regs[AI_DACRATE_REG]); unsigned int bits = (ai->regs[AI_BITRATE_REG] == 0) ? 16 : 1 + ai->regs[AI_BITRATE_REG]; set_audio_format_via_libretro(&ai->backend, frequency, bits); ai->samples_format_changed = 0; } /* push audio samples to audio backend */ push_audio_samples_via_libretro(&ai->backend, &ai->ri->rdram.dram[dma->address/4], dma->length); /* schedule end of dma event */ cp0_update_count(); add_interupt_event(AI_INT, dma->duration); } /* Fill the next FIFO entry in the DMA engine. */ static void fifo_push(struct ai_controller* ai) { unsigned int duration = get_dma_duration(ai); if (ai->regs[AI_STATUS_REG] & AI_STATUS_BUSY) { ai->fifo[1].address = ai->regs[AI_DRAM_ADDR_REG]; ai->fifo[1].length = ai->regs[AI_LEN_REG]; ai->fifo[1].duration = duration; ai->regs[AI_STATUS_REG] |= AI_STATUS_FULL; } else { /* If we're not DMA-ing already, start DMA engine. */ ai->fifo[0].address = ai->regs[AI_DRAM_ADDR_REG]; ai->fifo[0].length = ai->regs[AI_LEN_REG]; ai->fifo[0].duration = duration; ai->regs[AI_STATUS_REG] |= AI_STATUS_BUSY; do_dma(ai, &ai->fifo[0]); } } static void fifo_pop(struct ai_controller* ai) { if (ai->regs[AI_STATUS_REG] & AI_STATUS_FULL) { ai->fifo[0].address = ai->fifo[1].address; ai->fifo[0].length = ai->fifo[1].length; ai->fifo[0].duration = ai->fifo[1].duration; ai->regs[AI_STATUS_REG] &= ~AI_STATUS_FULL; do_dma(ai, &ai->fifo[0]); } else { ai->regs[AI_STATUS_REG] &= ~AI_STATUS_BUSY; } } /* Initializes the AI. */ void init_ai(struct ai_controller* ai) { memset(ai->regs, 0, AI_REGS_COUNT*sizeof(uint32_t)); memset(ai->fifo, 0, 2*sizeof(struct ai_dma)); ai->samples_format_changed = 0; } /* Reads a word from the AI MMIO register space. */ int read_ai_regs(void* opaque, uint32_t address, uint32_t* value) { struct ai_controller* ai = (struct ai_controller*)opaque; uint32_t reg = AI_REG(address); if (reg == AI_LEN_REG) *value = get_remaining_dma_length(ai); else *value = ai->regs[reg]; return 0; } /* Writes a word to the AI MMIO register space. */ int write_ai_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask) { struct ai_controller* ai = (struct ai_controller*)opaque; uint32_t reg = AI_REG(address); switch (reg) { case AI_LEN_REG: ai->regs[AI_LEN_REG] = MASKED_WRITE(&ai->regs[AI_LEN_REG], value, mask); fifo_push(ai); return 0; case AI_STATUS_REG: clear_rcp_interrupt(ai->r4300, MI_INTR_AI); return 0; case AI_BITRATE_REG: case AI_DACRATE_REG: /* lazy audio format setting */ if ((ai->regs[reg]) != (value & mask)) ai->samples_format_changed = 1; ai->regs[reg] = MASKED_WRITE(&ai->regs[reg], value, mask); return 0; } ai->regs[reg] = MASKED_WRITE(&ai->regs[reg], value, mask); return 0; } void ai_end_of_dma_event(struct ai_controller* ai) { fifo_pop(ai); raise_rcp_interrupt(ai->r4300, MI_INTR_AI); } mupen64plus-core/src/plugin/audio_libretro/drivers_resampler/nearest.c000664 001750 001750 00000004460 12655644434 027500 0ustar00sergiosergio000000 000000 /* RetroArch - A frontend for libretro. * Copyright (C) 2014-2015 - Ali Bouhlel ( aliaspider@gmail.com ) * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. * * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with RetroArch. * If not, see . */ #include "../audio_resampler_driver.h" #include #include #include #include typedef struct rarch_nearest_resampler { float fraction; } rarch_nearest_resampler_t; static void resampler_nearest_process( void *re_, struct resampler_data *data) { rarch_nearest_resampler_t *re = (rarch_nearest_resampler_t*)re_; audio_frame_float_t *inp = (audio_frame_float_t*)data->data_in; audio_frame_float_t *inp_max = (audio_frame_float_t*)inp + data->input_frames; audio_frame_float_t *outp = (audio_frame_float_t*)data->data_out; float ratio = 1.0 / data->ratio; while(inp != inp_max) { while(re->fraction > 1) { *outp++ = *inp; re->fraction -= ratio; } re->fraction++; inp++; } data->output_frames = (outp - (audio_frame_float_t*)data->data_out); } static void resampler_nearest_free(void *re_) { rarch_nearest_resampler_t *re = (rarch_nearest_resampler_t*)re_; if (re) free(re); } static void *resampler_nearest_init(const struct resampler_config *config, double bandwidth_mod, resampler_simd_mask_t mask) { rarch_nearest_resampler_t *re = (rarch_nearest_resampler_t*) calloc(1, sizeof(rarch_nearest_resampler_t)); (void)config; (void)mask; if (!re) return NULL; re->fraction = 0; return re; } rarch_resampler_t nearest_resampler = { resampler_nearest_init, resampler_nearest_process, resampler_nearest_free, RESAMPLER_API_VERSION, "nearest", "nearest" }; gles2rice/src/IColor.h000664 001750 001750 00000011410 12655644434 015722 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _ICOLOR_H_ #define _ICOLOR_H_ #ifndef min #define min(a,b) ((a) < (b) ? (a) : (b)) #endif #ifndef max #define max(a,b) ((a) > (b) ? (a) : (b)) #endif class IColor { public: uint8_t r; uint8_t g; uint8_t b; uint8_t a; IColor(COLOR rgba) { *((COLOR*)this) = rgba; } IColor() { *((COLOR*)this) = 0; } IColor(XCOLOR &rgba) { *((COLOR*)this) = (unsigned int) rgba; } inline IColor operator = (const IColor &sec) const { *((COLOR*)this) = *((COLOR*)&sec); return *this; } inline IColor operator = (COLOR col) const { *((COLOR*)this) = col; return *this; } inline IColor operator + (const IColor &sec) const { IColor newc; newc.r = (uint8_t)min((unsigned int) r + (unsigned int) sec.r, 0xFF); newc.g = (uint8_t)min((unsigned int) g + (unsigned int) sec.g, 0xFF); newc.b = (uint8_t)min((unsigned int) b + (unsigned int) sec.b, 0xFF); newc.a = (uint8_t)min((unsigned int) a + (unsigned int) sec.a, 0xFF); return newc; } inline IColor operator - (const IColor &sec) const { IColor newc; newc.r = max(int(r)-int(sec.r),0); newc.g = max(int(g)-int(sec.g),0); newc.b = max(int(b)-int(sec.b),0); newc.a = max(int(a)-int(sec.a),0); return newc; } inline IColor operator * (const IColor &sec) const { IColor newc; newc.r = (uint8_t)min((unsigned int) r * (unsigned int) sec.r / 256,255); newc.g = (uint8_t)min((unsigned int) g * (unsigned int) sec.g / 256,255); newc.b = (uint8_t)min((unsigned int) b * (unsigned int) sec.b / 256,255); newc.a = (uint8_t)min((unsigned int) a * (unsigned int) sec.a / 256,255); return newc; } inline IColor& operator += (const IColor &sec) { r = uint8_t(min((unsigned int) r + (unsigned int) sec.r, 255)); g = uint8_t(min((unsigned int) g + (unsigned int) sec.g, 255)); b = uint8_t(min((unsigned int) b + (unsigned int) sec.b, 255)); a = uint8_t(min((unsigned int) a + (unsigned int) sec.a, 255)); return *this; } inline IColor& operator -= (const IColor &sec) { r = uint8_t(max(int(r)-int(sec.r),0)); g = uint8_t(max(int(g)-int(sec.g),0)); b = uint8_t(max(int(b)-int(sec.b),0)); a = uint8_t(max(int(a)-int(sec.a),0)); return *this; } inline IColor& operator *= (const IColor &sec) { r = uint8_t(min((unsigned int) r * (unsigned int) sec.r / 256,255)); g = uint8_t(min((unsigned int) g * (unsigned int) sec.g / 256,255)); b = uint8_t(min((unsigned int) b * (unsigned int) sec.b / 256,255)); a = uint8_t(min((unsigned int) a * (unsigned int) sec.a / 256,255)); return *this; } inline IColor& operator += (XCOLOR val) { IColor newc(val); return this->operator += (newc); } inline IColor& operator -= (XCOLOR val) { IColor newc(val); return this->operator-=(newc); } inline IColor& operator *= (XCOLOR val) { IColor newc(val); return this->operator*=(newc); } inline IColor operator + (XCOLOR val) const { IColor newc(val); return this->operator+(newc); } inline IColor operator - (XCOLOR val) const { IColor newc(val); return this->operator-(newc); } inline IColor operator * (XCOLOR val) const { IColor newc(val); return this->operator*(newc); } inline operator COLOR() const { return *((COLOR*)this); } inline operator XCOLOR() const { XCOLOR rgba; rgba.r = (float)r/256.0f; rgba.g = (float)g/256.0f; rgba.b = (float)b/256.0f; rgba.a = (float)a/256.0f; return rgba; } inline void Complement() { r = 0xFF-r; g = 0xFF-g; b = 0xFF-b; a = 0xFF-a; } inline void AlphaReplicate() { r=g=b=a; } }; #undef min #undef max #endif glide2gl/src/Glide64/m64p.h000755 001750 001750 00000002424 12655644434 016337 0ustar00sergiosergio000000 000000 /****************************************************************************** * Glide64 - Glide video plugin for Nintendo 64 emulators. * http://bitbucket.org/richard42/mupen64plus-video-glide64mk2/ * * Copyright (C) 2010 Jon Ring * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *****************************************************************************/ #ifndef M64P_H #define M64P_H #include "m64p_types.h" #include "m64p_plugin.h" #include "m64p_config.h" #include "m64p_vidext.h" #include #define VIDEO_PLUGIN_API_VERSION 0x020100 void WriteLog(m64p_msg_level level, const char *msg, ...); #endif mupen64plus-core/src/r4300/recomph.h000664 001750 001750 00000020012 12655644434 020207 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - recomph.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_R4300_RECOMPH_H #define M64P_R4300_RECOMPH_H #include #include "recomp.h" extern int code_length; extern int max_code_length; extern unsigned char **inst_pointer; extern precomp_block* dst_block; extern int fast_memory; extern uint32_t src; /* opcode of r4300 instruction being recompiled */ void passe2(precomp_instr *dest, int start, int end, precomp_block* block); void init_assembler(void *block_jumps_table, int block_jumps_number, void *block_riprel_table, int block_riprel_number); void free_assembler(void **block_jumps_table, int *block_jumps_number, void **block_riprel_table, int *block_riprel_number); /* * Since "recomp.h" is included by both the 32- and 64-bit dynamic recompiler * modules in Mupen64Plus, we need to fix a particular build error on GCC * when targeting a 32-bit system and building with 32-bit dynarec. * * Preferably, we'll start off by checking only for __i386__ on GCC, as the * libretro fork of Mupen64Plus does not yet have a tested 32-bit recompiler. */ void gencallinterp(uintptr_t addr, int jump); void genupdate_system(int type); void genbnel(void); void genblezl(void); void genlw(void); void genlbu(void); void genlhu(void); void gensb(void); void gensh(void); void gensw(void); void gencache(void); void genlwc1(void); void genld(void); void gensd(void); void genbeq(void); void genbne(void); void genblez(void); void genaddi(void); void genaddiu(void); void genslti(void); void gensltiu(void); void genandi(void); void genori(void); void genxori(void); void genlui(void); void genbeql(void); void genmul_s(void); void gendiv_s(void); void gencvt_d_s(void); void genadd_d(void); void gentrunc_w_d(void); void gencvt_s_w(void); void genmfc1(void); void gencfc1(void); void genmtc1(void); void genctc1(void); void genj(void); void genjal(void); void genslt(void); void gensltu(void); void gendsll32(void); void gendsra32(void); void genbgez(void); void genbgezl(void); void genbgezal(void); void gentlbwi(void); void generet(void); void genmfc0(void); void genadd_s(void); void genmult(void); void genmultu(void); void genmflo(void); void genmtlo(void); void gendiv(void); void gendmultu(void); void genddivu(void); void genadd(void); void genaddu(void); void gensubu(void); void genand(void); void genor(void); void genxor(void); void genreserved(void); void gennop(void); void gensll(void); void gensrl(void); void gensra(void); void gensllv(void); void gensrlv(void); void genjr(void); void genni(void); void genmfhi(void); void genmthi(void); void genmtc0(void); void genbltz(void); void genlwl(void); void genswl(void); void gentlbp(void); void gentlbr(void); void genswr(void); void genlwr(void); void gensrav(void); void genbgtz(void); void genlb(void); void genswc1(void); void genldc1(void); void gencvt_d_w(void); void genmul_d(void); void gensub_d(void); void gendiv_d(void); void gencvt_s_d(void); void genmov_s(void); void genc_le_s(void); void genbc1t(void); void gentrunc_w_s(void); void genbc1tl(void); void genc_lt_s(void); void genbc1fl(void); void genneg_s(void); void genc_le_d(void); void genbgezal_idle(void); void genj_idle(void); void genbeq_idle(void); void genlh(void); void genmov_d(void); void genc_lt_d(void); void genbc1f(void); void gennor(void); void genneg_d(void); void gensub(void); void genblez_idle(void); void gendivu(void); void gencvt_w_s(void); void genbltzl(void); void gensdc1(void); void genc_eq_s(void); void genjalr(void); void gensub_s(void); void gensqrt_s(void); void genc_eq_d(void); void gencvt_w_d(void); void genfin_block(void); void genddiv(void); void gendaddiu(void); void genbgtzl(void); void gendsrav(void); void gendsllv(void); void gencvt_s_l(void); void gendmtc1(void); void gendsrlv(void); void gendsra(void); void gendmult(void); void gendsll(void); void genabs_s(void); void gensc(void); void gennotcompiled(void); void genjal_idle(void); void genjal_out(void); void genbeq_out(void); void gensyscall(void); void gensync(void); void gendadd(void); void gendaddu(void); void gendsub(void); void gendsubu(void); void genteq(void); void gendsrl(void); void gendsrl32(void); void genbltz_idle(void); void genbltz_out(void); void genbgez_idle(void); void genbgez_out(void); void genbltzl_idle(void); void genbltzl_out(void); void genbgezl_idle(void); void genbgezl_out(void); void genbltzal_idle(void); void genbltzal_out(void); void genbltzal(void); void genbgezal_out(void); void genbltzall_idle(void); void genbltzall_out(void); void genbltzall(void); void genbgezall_idle(void); void genbgezall_out(void); void genbgezall(void); void gentlbwr(void); void genbc1f_idle(void); void genbc1f_out(void); void genbc1t_idle(void); void genbc1t_out(void); void genbc1fl_idle(void); void genbc1fl_out(void); void genbc1tl_idle(void); void genbc1tl_out(void); void genround_l_s(void); void gentrunc_l_s(void); void genceil_l_s(void); void genfloor_l_s(void); void genround_w_s(void); void genceil_w_s(void); void genfloor_w_s(void); void gencvt_l_s(void); void genc_f_s(void); void genc_un_s(void); void genc_ueq_s(void); void genc_olt_s(void); void genc_ult_s(void); void genc_ole_s(void); void genc_ule_s(void); void genc_sf_s(void); void genc_ngle_s(void); void genc_seq_s(void); void genc_ngl_s(void); void genc_nge_s(void); void genc_ngt_s(void); void gensqrt_d(void); void genabs_d(void); void genround_l_d(void); void gentrunc_l_d(void); void genceil_l_d(void); void genfloor_l_d(void); void genround_w_d(void); void genceil_w_d(void); void genfloor_w_d(void); void gencvt_l_d(void); void genc_f_d(void); void genc_un_d(void); void genc_ueq_d(void); void genc_olt_d(void); void genc_ult_d(void); void genc_ole_d(void); void genc_ule_d(void); void genc_sf_d(void); void genc_ngle_d(void); void genc_seq_d(void); void genc_ngl_d(void); void genc_nge_d(void); void genc_ngt_d(void); void gencvt_d_l(void); void gendmfc1(void); void genj_out(void); void genbne_idle(void); void genbne_out(void); void genblez_out(void); void genbgtz_idle(void); void genbgtz_out(void); void genbeql_idle(void); void genbeql_out(void); void genbnel_idle(void); void genbnel_out(void); void genblezl_idle(void); void genblezl_out(void); void genbgtzl_idle(void); void genbgtzl_out(void); void gendaddi(void); void genldl(void); void genldr(void); void genlwu(void); void gensdl(void); void gensdr(void); void genlink_subblock(void); void gendelayslot(void); void gencheck_interupt_reg(void); void gentest(void); void gentest_out(void); void gentest_idle(void); void gentestl(void); void gentestl_out(void); void gencheck_cop1_unusable(void); void genll(void); #ifdef COMPARE_CORE void gendebug(void); #endif #endif /* M64P_R4300_RECOMPH_H */ mupen64plus-video-gliden64/src/GLideNHQ/test/Makefile.vc8000664 001750 001750 00000003123 12655644434 024076 0ustar00sergiosergio000000 000000 # This MUST be processed by GNU make # # Texture Filtering Test MSVC Makefile # Version: 1.0 # # Copyright (C) 2007 Hiroshi Morii All Rights Reserved. # Email koolsmoky(at)users.sourceforge.net # Web http://www.3dfxzone.it/koolsmoky # # this is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # this is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Make; see the file COPYING. If not, write to # the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. # # # Available options: # # Targets: # all: build everything # clean: remove object files # realclean: remove all generated files # .PHONY: all clean realclean .SUFFIXES: .cpp .obj CC = cl LD = _link # change this to suite your build environment UNLINK = $(RM) $(1) CFLAGS += -D__MSC__ -DWIN32 -D_CONSOLE -EHa -D_CRT_SECURE_NO_DEPRECATE CFLAGS += -I. -I../ CFLAGS += -DGHQCHK=1 #LDFLAGS += -ltcg:STATUS SOURCES = \ test.cpp \ ../Ext_TxFilter.cpp OBJECTS = $(SOURCES:.cpp=.obj) .cpp.obj: $(CC) -Fo$@ $(CFLAGS) -c $< all: test.exe test.exe: $(OBJECTS) $(LD) -out:$@ $(LDFLAGS) $(OBJECTS) $(OBJECTS): $(SOURCES) clean: -$(RM) *.obj *.pdb *.ilk realclean: clean -$(RM) test.exe mupen64plus-video-gliden64/src/GLideNHQ/TxHiResCache.h000664 001750 001750 00000003270 12655644434 023406 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __TXHIRESCACHE_H__ #define __TXHIRESCACHE_H__ /* support hires textures * 0: disable * 1: enable */ #define HIRES_TEXTURE 1 #include "TxCache.h" #include "TxQuantize.h" #include "TxImage.h" #include "TxReSample.h" class TxHiResCache : public TxCache { private: int _maxwidth; int _maxheight; int _maxbpp; boolean _haveCache; boolean _abortLoad; TxImage *_txImage; TxQuantize *_txQuantize; TxReSample *_txReSample; tx_wstring _texPackPath; boolean loadHiResTextures(const wchar_t * dir_path, boolean replace); public: ~TxHiResCache(); TxHiResCache(int maxwidth, int maxheight, int maxbpp, int options, const wchar_t *cachePath, const wchar_t *texPackPath, const wchar_t *ident, dispInfoFuncExt callback); boolean empty(); boolean load(boolean replace); }; #endif /* __TXHIRESCACHE_H__ */ mupen64plus-core/src/si/pif.h000664 001750 001750 00000005234 12655644434 017204 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - pif.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_SI_PIF_H #define M64P_SI_PIF_H #include #include "af_rtc.h" #include "cic.h" #include "eeprom.h" #include "game_controller.h" #ifndef PIF_RAM_ADDR #define PIF_RAM_ADDR(a) (((a) & 0xfffc) - 0x7c0) #endif enum { GAME_CONTROLLERS_COUNT = 4 }; enum { PIF_RAM_SIZE = 0x40 }; enum pif_commands { PIF_CMD_STATUS = 0x00, PIF_CMD_CONTROLLER_READ = 0x01, PIF_CMD_PAK_READ = 0x02, PIF_CMD_PAK_WRITE = 0x03, PIF_CMD_EEPROM_READ = 0x04, PIF_CMD_EEPROM_WRITE = 0x05, PIF_CMD_AF_RTC_STATUS = 0x06, PIF_CMD_AF_RTC_READ = 0x07, PIF_CMD_AF_RTC_WRITE = 0x08, PIF_CMD_RESET = 0xff }; struct si_controller; struct pif { uint8_t ram[PIF_RAM_SIZE]; struct game_controller controllers[GAME_CONTROLLERS_COUNT]; struct eeprom eeprom; struct af_rtc af_rtc; struct cic cic; }; void init_pif(struct pif* pif); int read_pif_ram(void* opaque, uint32_t address, uint32_t* value); int write_pif_ram(void* opaque, uint32_t address, uint32_t value, uint32_t mask); void update_pif_write(struct si_controller* si); void update_pif_read(struct si_controller* si); #endif mupen64plus-rsp-cxd4/vu/cf.h000664 001750 001750 00000013471 12655644434 016764 0ustar00sergiosergio000000 000000 /******************************************************************************\ * Authors: Iconoclast * * Release: 2013.12.04 * * License: CC0 Public Domain Dedication * * * * To the extent possible under law, the author(s) have dedicated all copyright * * and related and neighboring rights to this software to the public domain * * worldwide. This software is distributed without any warranty. * * * * You should have received a copy of the CC0 Public Domain Dedication along * * with this software. * * If not, see . * \******************************************************************************/ #ifndef _CF_H #define _CF_H /* * For a non-cycle-accurate RSP emulator using SSE2, the following * scalar definitions of the control registers are obsolete. */ #if (0) /* * Many vector units have pairs of "vector condition flags" registers. * In SGI's vector unit implementation, these are denoted as the * "vector control registers" under coprocessor 2. * * VCF-0 is the carry-out flags register: $vco. * VCF-1 is the compare code flags register: $vcc. * VCF-2 is the compare extension flags register: $vce. * There is no fourth RSP flags register. */ unsigned short VCO; unsigned short VCC; unsigned char VCE; #endif /* * These normally should have type `int` because they are Boolean T/F arrays. * However, since SSE2 uses 128-bit XMM's, and Win32 `int` storage is 32-bit, * we have the problem of 32*8 > 128 bits, so we use `short` to reduce packs. */ short ne[8]; /* $vco: high byte "NOTEQUAL" */ short co[8]; /* $vco: low byte "carry/borrow in/out" */ short clip[8]; /* $vcc: high byte (clip tests: VCL, VCH, VCR) */ short comp[8]; /* $vcc: low byte (VEQ, VNE, VLT, VGE, VCL, VCH, VCR) */ short vce[8]; /* $vce: vector compare extension register */ #ifndef ARCH_MIN_SSE2 unsigned short get_VCO(void) { register unsigned short VCO; VCO = 0x0000 | (ne[0xF % 8] << 0xF) | (ne[0xE % 8] << 0xE) | (ne[0xD % 8] << 0xD) | (ne[0xC % 8] << 0xC) | (ne[0xB % 8] << 0xB) | (ne[0xA % 8] << 0xA) | (ne[0x9 % 8] << 0x9) | (ne[0x8 % 8] << 0x8) | (co[0x7 % 8] << 0x7) | (co[0x6 % 8] << 0x6) | (co[0x5 % 8] << 0x5) | (co[0x4 % 8] << 0x4) | (co[0x3 % 8] << 0x3) | (co[0x2 % 8] << 0x2) | (co[0x1 % 8] << 0x1) | (co[0x0 % 8] << 0x0); return (VCO); /* Big endian becomes little. */ } unsigned short get_VCC(void) { register unsigned short VCC; VCC = 0x0000 | (clip[0xF % 8] << 0xF) | (clip[0xE % 8] << 0xE) | (clip[0xD % 8] << 0xD) | (clip[0xC % 8] << 0xC) | (clip[0xB % 8] << 0xB) | (clip[0xA % 8] << 0xA) | (clip[0x9 % 8] << 0x9) | (clip[0x8 % 8] << 0x8) | (comp[0x7 % 8] << 0x7) | (comp[0x6 % 8] << 0x6) | (comp[0x5 % 8] << 0x5) | (comp[0x4 % 8] << 0x4) | (comp[0x3 % 8] << 0x3) | (comp[0x2 % 8] << 0x2) | (comp[0x1 % 8] << 0x1) | (comp[0x0 % 8] << 0x0); return (VCC); /* Big endian becomes little. */ } unsigned char get_VCE(void) { register unsigned char VCE; VCE = 0x00 | (vce[07] << 0x7) | (vce[06] << 0x6) | (vce[05] << 0x5) | (vce[04] << 0x4) | (vce[03] << 0x3) | (vce[02] << 0x2) | (vce[01] << 0x1) | (vce[00] << 0x0); return (VCE); /* Big endian becomes little. */ } #else unsigned short get_VCO(void) { __m128i xmm, hi, lo; register unsigned short VCO; hi = _mm_load_si128((__m128i *)ne); lo = _mm_load_si128((__m128i *)co); /* * Rotate Boolean storage from LSB to MSB. */ hi = _mm_slli_epi16(hi, 15); lo = _mm_slli_epi16(lo, 15); xmm = _mm_packs_epi16(lo, hi); /* Decompress INT16 Booleans to INT8 ones. */ VCO = _mm_movemask_epi8(xmm) & 0x0000FFFF; /* PMOVMSKB combines each MSB. */ return (VCO); } unsigned short get_VCC(void) { __m128i xmm, hi, lo; register unsigned short VCC; hi = _mm_load_si128((__m128i *)clip); lo = _mm_load_si128((__m128i *)comp); /* * Rotate Boolean storage from LSB to MSB. */ hi = _mm_slli_epi16(hi, 15); lo = _mm_slli_epi16(lo, 15); xmm = _mm_packs_epi16(lo, hi); /* Decompress INT16 Booleans to INT8 ones. */ VCC = _mm_movemask_epi8(xmm) & 0x0000FFFF; /* PMOVMSKB combines each MSB. */ return (VCC); } unsigned char get_VCE(void) { __m128i xmm, hi, lo; register unsigned char VCE; hi = _mm_setzero_si128(); lo = _mm_load_si128((__m128i *)vce); lo = _mm_slli_epi16(lo, 15); /* Rotate Boolean storage from LSB to MSB. */ xmm = _mm_packs_epi16(lo, hi); /* Decompress INT16 Booleans to INT8 ones. */ VCE = _mm_movemask_epi8(xmm) & 0x000000FF; /* PMOVMSKB combines each MSB. */ return (VCE); } #endif /* * CTC2 resources * not sure how to vectorize going the other direction into SSE2 */ void set_VCO(unsigned short VCO) { register int i; for (i = 0; i < 8; i++) co[i] = (VCO >> (i + 0x0)) & 1; for (i = 0; i < 8; i++) ne[i] = (VCO >> (i + 0x8)) & 1; return; /* Little endian becomes big. */ } void set_VCC(unsigned short VCC) { register int i; for (i = 0; i < 8; i++) comp[i] = (VCC >> (i + 0x0)) & 1; for (i = 0; i < 8; i++) clip[i] = (VCC >> (i + 0x8)) & 1; return; /* Little endian becomes big. */ } void set_VCE(unsigned char VCE) { register int i; for (i = 0; i < 8; i++) vce[i] = (VCE >> i) & 1; return; /* Little endian becomes big. */ } #endif libretro/msvc/msvc-2010/msvc-2010.vcxproj000664 001750 001750 00000235017 12655644434 021016 0ustar00sergiosergio000000 000000  Debug Win32 Debug x64 Release Win32 Release x64 {62F97835-3567-4EF3-ACDC-46F2CDECAF40} Win32Proj msvc2010 DynamicLibrary true Unicode DynamicLibrary true Unicode DynamicLibrary false true Unicode DynamicLibrary false true Unicode true libretro true libretro false libretro false false libretro false Level3 Disabled WIN32;INLINE=_inline;__LIBRETRO__;__LIBRETRO_WIN64__;M64P_PLUGIN_API;M64P_CORE_PROTOTYPES;_ENDUSER_RELEASE;_DEBUG;_WINDOWS;_USRDLL;MSVC2010_EXPORTS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;DYNAREC $(MSBuildProjectDirectory)\..\..\..\mupen64plus-core\src\api;$(MSBuildProjectDirectory)\..\..\;$(MSBuildProjectDirectory)\..\..\..\mupen64plus-core\src;$(MSBuildProjectDirectory)\..\;$(MSBuildProjectDirectory)\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\glide2gl\src\Glitch64\inc;$(MSBuildProjectDirectory)\..\GL;$(MSBuildProjectDirectory)\..\..\..\tools\rzlib;$(MSBuildProjectDirectory)\..\..\libco;%(AdditionalIncludeDirectories) true Windows true kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;opengl32.lib;%(AdditionalDependencies) 5.00 libretro.def Level3 Disabled WIN32;INLINE=_inline;__LIBRETRO__;__LIBRETRO_WIN64__;M64P_PLUGIN_API;M64P_CORE_PROTOTYPES;_ENDUSER_RELEASE;_DEBUG;_WINDOWS;_USRDLL;MSVC2010_EXPORTS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;DYNAREC $(MSBuildProjectDirectory)\..\..\..\mupen64plus-core\src\api;$(MSBuildProjectDirectory)\..\..\;$(MSBuildProjectDirectory)\..\..\..\mupen64plus-core\src;$(MSBuildProjectDirectory)\..\;$(MSBuildProjectDirectory)\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\glide2gl\src\Glitch64\inc;$(MSBuildProjectDirectory)\..\GL;$(MSBuildProjectDirectory)\..\..\..\tools\rzlib;$(MSBuildProjectDirectory)\..\..\libco;%(AdditionalIncludeDirectories) true Windows true kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;opengl32.lib;%(AdditionalDependencies) 5.02 libretro.def Level3 MaxSpeed true WIN32;INLINE=_inline;__LIBRETRO__;__LIBRETRO_WIN64__;M64P_PLUGIN_API;M64P_CORE_PROTOTYPES;_ENDUSER_RELEASE;NDEBUG;_WINDOWS;_USRDLL;MSVC2010_EXPORTS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;DYNAREC $(MSBuildProjectDirectory)\..\..\..\mupen64plus-core\src\api;$(MSBuildProjectDirectory)\..\..\;$(MSBuildProjectDirectory)\..\..\..\mupen64plus-core\src;$(MSBuildProjectDirectory)\..\;$(MSBuildProjectDirectory)\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\glide2gl\src\Glitch64\inc;$(MSBuildProjectDirectory)\..\GL;$(MSBuildProjectDirectory)\..\..\..\tools\rzlib;$(MSBuildProjectDirectory)\..\..\libco;%(AdditionalIncludeDirectories) true false StreamingSIMDExtensions2 4996;%(DisableSpecificWarnings) Windows true true true kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;opengl32.lib;%(AdditionalDependencies) 5.00 libretro.def Level3 MaxSpeed true WIN32;INLINE=_inline;__LIBRETRO__;__LIBRETRO_WIN64__;M64P_PLUGIN_API;M64P_CORE_PROTOTYPES;_ENDUSER_RELEASE;NDEBUG;_WINDOWS;_USRDLL;MSVC2010_EXPORTS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;DYNAREC $(MSBuildProjectDirectory)\..\..\..\mupen64plus-core\src\api;$(MSBuildProjectDirectory)\..\..\;$(MSBuildProjectDirectory)\..\..\..\mupen64plus-core\src;$(MSBuildProjectDirectory)\..\;$(MSBuildProjectDirectory)\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\glide2gl\src\Glitch64\inc;$(MSBuildProjectDirectory)\..\GL;$(MSBuildProjectDirectory)\..\..\..\tools\rzlib;$(MSBuildProjectDirectory)\..\..\libco;%(AdditionalIncludeDirectories) true false 4996;%(DisableSpecificWarnings) Windows true true true kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;opengl32.lib;%(AdditionalDependencies) 5.02 libretro.def CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC CompileAsC mupen64plus-core/src/si/pif.c000664 001750 001750 00000016774 12655644434 017212 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - pif.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "pif.h" #include "n64_cic_nus_6105.h" #include "si_controller.h" #include "../api/m64p_types.h" #include "../api/callbacks.h" #include "../memory/memory.h" #include "../plugin/plugin.h" #include "r4300/r4300_core.h" #include //#define DEBUG_PIF #ifdef DEBUG_PIF void print_pif(struct pif* pif) { int i; for (i=0; i<(64/8); i++) DebugMessage(M64MSG_INFO, "%x %x %x %x | %x %x %x %x", pif->ram[i*8+0], pif->ram[i*8+1], pif->ram[i*8+2], pif->ram[i*8+3], pif->ram[i*8+4], pif->ram[i*8+5], pif->ram[i*8+6], pif->ram[i*8+7]); } #endif static void process_cart_command(struct pif* pif, uint8_t* cmd) { switch (cmd[2]) { case PIF_CMD_STATUS: eeprom_status_command(&pif->eeprom, cmd); break; case PIF_CMD_EEPROM_READ: eeprom_read_command(&pif->eeprom, cmd); break; case PIF_CMD_EEPROM_WRITE: eeprom_write_command(&pif->eeprom, cmd); break; case PIF_CMD_AF_RTC_STATUS: af_rtc_status_command(&pif->af_rtc, cmd); break; case PIF_CMD_AF_RTC_READ: af_rtc_read_command(&pif->af_rtc, cmd); break; case PIF_CMD_AF_RTC_WRITE: af_rtc_write_command(&pif->af_rtc, cmd); break; default: DebugMessage(M64MSG_ERROR, "unknown PIF command: %02x", cmd[2]); } } void init_pif(struct pif* pif) { memset(pif->ram, 0, PIF_RAM_SIZE); } int read_pif_ram(void* opaque, uint32_t address, uint32_t* value) { struct si_controller* si = (struct si_controller*)opaque; uint32_t addr = PIF_RAM_ADDR(address); if (addr >= PIF_RAM_SIZE) { DebugMessage(M64MSG_ERROR, "Invalid PIF address: %08x", address); *value = 0; return -1; } memcpy(value, si->pif.ram + addr, sizeof(*value)); *value = sl(*value); return 0; } int write_pif_ram(void* opaque, uint32_t address, uint32_t value, uint32_t mask) { struct si_controller* si = (struct si_controller*)opaque; uint32_t addr = PIF_RAM_ADDR(address); if (addr >= PIF_RAM_SIZE) { DebugMessage(M64MSG_ERROR, "Invalid PIF address: %08x", address); return -1; } si->pif.ram[addr] = MASKED_WRITE((uint32_t*)(&si->pif.ram[addr]), sl(value), sl(mask)); if ((addr == 0x3c) && (mask & 0xff)) { if (si->pif.ram[0x3f] == 0x08) { si->pif.ram[0x3f] = 0; cp0_update_count(); add_interupt_event(SI_INT, /*0x100*/0x900); } else { update_pif_write(si); } } return 0; } void update_pif_write(struct si_controller *si) { int i=0, channel=0; struct pif* pif = &si->pif; if (pif->ram[0x3F] > 1) { int8_t challenge[30], response[30]; switch (pif->ram[0x3F]) { case 0x02: #ifdef DEBUG_PIF DebugMessage(M64MSG_INFO, "update_pif_write() pif_ram[0x3f] = 2 - CIC challenge"); #endif // format the 'challenge' message into 30 nibbles for X-Scale's CIC code for (i = 0; i < 15; i++) { challenge[i*2] = (pif->ram[48+i] >> 4) & 0x0f; challenge[i*2+1] = pif->ram[48+i] & 0x0f; } // calculate the proper response for the given challenge (X-Scale's algorithm) n64_cic_nus_6105(challenge, response, CHL_LEN - 2); pif->ram[46] = 0; pif->ram[47] = 0; // re-format the 'response' into a byte stream for (i = 0; i < 15; i++) pif->ram[48+i] = (response[i*2] << 4) + response[i*2+1]; // the last byte (2 nibbles) is always 0 pif->ram[63] = 0; break; case 0x08: #ifdef DEBUG_PIF DebugMessage(M64MSG_INFO, "update_pif_write() pif_ram[0x3f] = 8"); #endif pif->ram[0x3F] = 0; break; default: DebugMessage(M64MSG_ERROR, "error in update_pif_write(): %x", pif->ram[0x3F]); } return; } while (i<0x40) { switch (pif->ram[i]) { case 0x00: channel++; if (channel > 6) i=0x40; break; case 0xFF: break; default: if (!(pif->ram[i] & 0xC0)) { if (channel < 4) { if (Controls[channel].Present && Controls[channel].RawData) input.controllerCommand(channel, &pif->ram[i]); else process_controller_command(&pif->controllers[channel], &pif->ram[i]); } else if (channel == 4) process_cart_command(pif, &pif->ram[i]); else DebugMessage(M64MSG_ERROR, "channel >= 4 in update_pif_write"); i += pif->ram[i] + (pif->ram[(i+1)] & 0x3F) + 1; channel++; } else i=0x40; } i++; } //pif->ram[0x3F] = 0; /* notify the INPUT plugin that we're at the end of PIF ram processing */ input.controllerCommand(-1, NULL); } void update_pif_read(struct si_controller *si) { struct pif* pif = &si->pif; int i=0, channel=0; while (i<0x40) { switch (pif->ram[i]) { case 0x00: channel++; if (channel > 6) i=0x40; break; case 0xFE: i = 0x40; break; case 0xFF: break; case 0xB4: case 0x56: case 0xB8: break; default: if (!(pif->ram[i] & 0xC0)) { if (channel < 4) { if (Controls[channel].Present && Controls[channel].RawData) input.readController(channel, &pif->ram[i]); else read_controller(&pif->controllers[channel], &pif->ram[i]); } i += pif->ram[i] + (pif->ram[(i+1)] & 0x3F) + 1; channel++; } else i=0x40; } i++; } /* notify the INPUT plugin that we're at the end of PIF ram processing */ input.readController(-1, NULL); } mupen64plus-video-gliden64/src/TxFilterStub.cpp000664 001750 001750 00000001642 12655644434 022534 0ustar00sergiosergio000000 000000 #include "GLideNHQ/Ext_TxFilter.h" TAPI boolean TAPIENTRY txfilter_init(int maxwidth, int maxheight, int maxbpp, int options, int cachesize, const wchar_t *path, const wchar_t * texPackPath, const wchar_t*ident, dispInfoFuncExt callback) { return 0; } TAPI void TAPIENTRY txfilter_shutdown(void) {} TAPI boolean TAPIENTRY txfilter_filter(uint8 *src, int srcwidth, int srcheight, uint16 srcformat, uint64 g64crc, GHQTexInfo *info) { return 0; } TAPI boolean TAPIENTRY txfilter_hirestex(uint64 g64crc, uint64 r_crc64, uint16 *palette, GHQTexInfo *info) { return 0; } TAPI uint64 TAPIENTRY txfilter_checksum(uint8 *src, int width, int height, int size, int rowStride, uint8 *palette) { return 0U; } TAPI boolean TAPIENTRY txfilter_dmptx(uint8 *src, int width, int height, int rowStridePixel, uint16 gfmt, uint16 n64fmt, uint64 r_crc64) { return 0; } TAPI boolean TAPIENTRY txfilter_reloadhirestex() { return 0; } mupen64plus-video-gliden64/src/Textures.cpp000664 001750 001750 00000145512 12655644434 021765 0ustar00sergiosergio000000 000000 #include #include #include #include // std::this_thread::sleep_for #include // std::chrono::seconds #include "OpenGL.h" #include "Textures.h" #include "GLSLCombiner.h" #include "GBI.h" #include "RSP.h" #include "gDP.h" #include "gSP.h" #include "N64.h" #include "convert.h" #include "FrameBuffer.h" #include "Config.h" #include "Keys.h" #include "GLideNHQ/Ext_TxFilter.h" using namespace std; const GLuint g_noiseTexIndex = 2; const GLuint g_MSTex0Index = g_noiseTexIndex + 1; inline u32 GetNone( u64 *src, u16 x, u16 i, u8 palette ) { return 0x00000000; } inline u32 GetCI4IA_RGBA4444( u64 *src, u16 x, u16 i, u8 palette ) { u8 color4B; color4B = ((u8*)src)[(x>>1)^(i<<1)]; if (x & 1) return IA88_RGBA4444( *(u16*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] ); else return IA88_RGBA4444( *(u16*)&TMEM[256 + (palette << 4) + (color4B >> 4)] ); } inline u32 GetCI4IA_RGBA8888( u64 *src, u16 x, u16 i, u8 palette ) { u8 color4B; color4B = ((u8*)src)[(x>>1)^(i<<1)]; if (x & 1) return IA88_RGBA8888( *(u16*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] ); else return IA88_RGBA8888( *(u16*)&TMEM[256 + (palette << 4) + (color4B >> 4)] ); } inline u32 GetCI4RGBA_RGBA5551( u64 *src, u16 x, u16 i, u8 palette ) { u8 color4B; color4B = ((u8*)src)[(x>>1)^(i<<1)]; if (x & 1) return RGBA5551_RGBA5551( *(u16*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] ); else return RGBA5551_RGBA5551( *(u16*)&TMEM[256 + (palette << 4) + (color4B >> 4)] ); } inline u32 GetCI4RGBA_RGBA8888( u64 *src, u16 x, u16 i, u8 palette ) { u8 color4B; color4B = ((u8*)src)[(x>>1)^(i<<1)]; if (x & 1) return RGBA5551_RGBA8888( *(u16*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] ); else return RGBA5551_RGBA8888( *(u16*)&TMEM[256 + (palette << 4) + (color4B >> 4)] ); } inline u32 GetIA31_RGBA8888( u64 *src, u16 x, u16 i, u8 palette ) { u8 color4B; color4B = ((u8*)src)[(x>>1)^(i<<1)]; return IA31_RGBA8888( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) ); } inline u32 GetIA31_RGBA4444( u64 *src, u16 x, u16 i, u8 palette ) { u8 color4B; color4B = ((u8*)src)[(x>>1)^(i<<1)]; return IA31_RGBA4444( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) ); } inline u32 GetI4_RGBA8888( u64 *src, u16 x, u16 i, u8 palette ) { u8 color4B; color4B = ((u8*)src)[(x>>1)^(i<<1)]; return I4_RGBA8888( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) ); } inline u32 GetI4_RGBA4444( u64 *src, u16 x, u16 i, u8 palette ) { u8 color4B; color4B = ((u8*)src)[(x>>1)^(i<<1)]; return I4_RGBA4444( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) ); } inline u32 GetCI8IA_RGBA4444( u64 *src, u16 x, u16 i, u8 palette ) { return IA88_RGBA4444( *(u16*)&TMEM[256 + ((u8*)src)[x^(i<<1)]] ); } inline u32 GetCI8IA_RGBA8888( u64 *src, u16 x, u16 i, u8 palette ) { return IA88_RGBA8888( *(u16*)&TMEM[256 + ((u8*)src)[x^(i<<1)]] ); } inline u32 GetCI8RGBA_RGBA5551( u64 *src, u16 x, u16 i, u8 palette ) { return RGBA5551_RGBA5551( *(u16*)&TMEM[256 + ((u8*)src)[x^(i<<1)]] ); } inline u32 GetCI8RGBA_RGBA8888( u64 *src, u16 x, u16 i, u8 palette ) { return RGBA5551_RGBA8888( *(u16*)&TMEM[256 + ((u8*)src)[x^(i<<1)]] ); } inline u32 GetIA44_RGBA8888( u64 *src, u16 x, u16 i, u8 palette ) { return IA44_RGBA8888(((u8*)src)[x^(i<<1)]); } inline u32 GetIA44_RGBA4444( u64 *src, u16 x, u16 i, u8 palette ) { return IA44_RGBA4444(((u8*)src)[x^(i<<1)]); } inline u32 GetI8_RGBA8888( u64 *src, u16 x, u16 i, u8 palette ) { return I8_RGBA8888(((u8*)src)[x^(i<<1)]); } inline u32 GetI8_RGBA4444( u64 *src, u16 x, u16 i, u8 palette ) { return I8_RGBA4444(((u8*)src)[x^(i<<1)]); } inline u32 GetCI16IA_RGBA8888(u64 *src, u16 x, u16 i, u8 palette) { const u16 tex = ((u16*)src)[x^i]; const u16 col = (*(u16*)&TMEM[256 + (tex >> 8)]); const u16 c = col >> 8; const u16 a = col & 0xFF; return (a << 24) | (c << 16) | (c << 8) | c; } inline u32 GetCI16IA_RGBA4444(u64 *src, u16 x, u16 i, u8 palette) { const u16 tex = ((u16*)src)[x^i]; const u16 col = (*(u16*)&TMEM[256 + (tex >> 8)]); const u16 c = col >> 12; const u16 a = col & 0x0F; return (a << 12) | (c << 8) | (c << 4) | c; } inline u32 GetCI16RGBA_RGBA8888(u64 *src, u16 x, u16 i, u8 palette) { const u16 tex = (((u16*)src)[x^i])&0xFF; return RGBA5551_RGBA8888(((u16*)&TMEM[256])[tex << 2]); } inline u32 GetCI16RGBA_RGBA5551(u64 *src, u16 x, u16 i, u8 palette) { const u16 tex = (((u16*)src)[x^i]) & 0xFF; return RGBA5551_RGBA5551(((u16*)&TMEM[256])[tex << 2]); } inline u32 GetRGBA5551_RGBA8888(u64 *src, u16 x, u16 i, u8 palette) { u16 tex = ((u16*)src)[x^i]; return RGBA5551_RGBA8888(tex); } inline u32 GetRGBA5551_RGBA5551( u64 *src, u16 x, u16 i, u8 palette ) { u16 tex = ((u16*)src)[x^i]; return RGBA5551_RGBA5551(tex); } inline u32 GetIA88_RGBA8888( u64 *src, u16 x, u16 i, u8 palette ) { return IA88_RGBA8888(((u16*)src)[x^i]); } inline u32 GetIA88_RGBA4444( u64 *src, u16 x, u16 i, u8 palette ) { return IA88_RGBA4444(((u16*)src)[x^i]); } inline u32 GetRGBA8888_RGBA8888( u64 *src, u16 x, u16 i, u8 palette ) { return ((u32*)src)[x^i]; } inline u32 GetRGBA8888_RGBA4444( u64 *src, u16 x, u16 i, u8 palette ) { return RGBA8888_RGBA4444(((u32*)src)[x^i]); } u32 YUV_RGBA8888(u8 y, u8 u, u8 v) { s32 r = (s32)(y + (1.370705f * (v - 128))); s32 g = (s32)((y - (0.698001f * (v - 128)) - (0.337633f * (u - 128)))); s32 b = (s32)(y + (1.732446f * (u - 128))); //clipping the result if (r > 255) r = 255; if (g > 255) g = 255; if (b > 255) b = 255; if (r < 0) r = 0; if (g < 0) g = 0; if (b < 0) b = 0; return (0xff << 24) | (b << 16) | (g << 8) | r; } u16 YUV_RGBA4444(u8 y, u8 u, u8 v) { return RGBA8888_RGBA4444(YUV_RGBA8888(y, u, v)); } inline void GetYUV_RGBA8888(u64 * src, u32 * dst, u16 x) { const u32 t = (((u32*)src)[x]); u8 y1 = (u8)t & 0xFF; u8 v = (u8)(t >> 8) & 0xFF; u8 y0 = (u8)(t >> 16) & 0xFF; u8 u = (u8)(t >> 24) & 0xFF; u32 c = YUV_RGBA8888(y0, u, v); *(dst++) = c; c = YUV_RGBA8888(y1, u, v); *(dst++) = c; } inline void GetYUV_RGBA4444(u64 * src, u16 * dst, u16 x) { const u32 t = (((u32*)src)[x]); u8 y1 = (u8)t & 0xFF; u8 v = (u8)(t >> 8) & 0xFF; u8 y0 = (u8)(t >> 16) & 0xFF; u8 u = (u8)(t >> 24) & 0xFF; u16 c = YUV_RGBA4444(y0, u, v); *(dst++) = c; c = YUV_RGBA4444(y1, u, v); *(dst++) = c; } const struct TextureLoadParameters { GetTexelFunc Get16; GLenum glType16; GLint glInternalFormat16; GetTexelFunc Get32; GLenum glType32; GLint glInternalFormat32; u32 autoFormat, lineShift, maxTexels; } imageFormat[4][4][5] = { // G_TT_NONE { // Get16 glType16 glInternalFormat16 Get32 glType32 glInternalFormat32 autoFormat { // 4-bit { GetI4_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetI4_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 4, 8192 }, // RGBA as I { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 4, 8192 }, // YUV { GetI4_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetI4_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 4, 8192 }, // CI without palette { GetIA31_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetIA31_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 4, 8192 }, // IA { GetI4_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetI4_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 4, 8192 }, // I }, { // 8-bit { GetI8_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetI8_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA, 3, 4096 }, // RGBA as I { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 4096 }, // YUV { GetI8_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetI8_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA, 3, 4096 }, // CI without palette { GetIA44_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetIA44_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 3, 4096 }, // IA { GetI8_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetI8_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA, 3, 4096 }, // I }, { // 16-bit { GetRGBA5551_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetRGBA5551_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 2, 2048 }, // RGBA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 2, 2048 }, // YUV { GetIA88_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetIA88_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA, 2, 2048 }, // CI as IA { GetIA88_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetIA88_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA, 2, 2048 }, // IA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 2048 }, // I }, { // 32-bit { GetRGBA8888_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetRGBA8888_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA, 2, 1024 }, // RGBA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // YUV { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // CI { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // IA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // I } }, // DUMMY { // Get16 glType16 glInternalFormat16 Get32 glType32 glInternalFormat32 autoFormat { // 4-bit { GetCI4RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI4RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 4, 4096 }, // CI (Banjo-Kazooie uses this, doesn't make sense, but it works...) { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 4, 8192 }, // YUV { GetCI4RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI4RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 4, 4096 }, // CI { GetCI4RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI4RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 4, 4096 }, // IA as CI { GetCI4RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI4RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 4, 4096 }, // I as CI }, { // 8-bit { GetCI8RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI8RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 3, 2048 }, // RGBA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 4096 }, // YUV { GetCI8RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI8RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 3, 2048 }, // CI { GetCI8RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI8RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 3, 2048 }, // IA as CI { GetCI8RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI8RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 3, 2048 }, // I as CI }, { // 16-bit { GetCI16RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetRGBA5551_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 2, 2048 }, // RGBA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 2, 2048 }, // YUV { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 2048 }, // CI { GetCI16RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI16RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 2, 2048 }, // IA as CI { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 2048 }, // I }, { // 32-bit { GetRGBA8888_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetRGBA8888_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA, 2, 1024 }, // RGBA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // YUV { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // CI { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // IA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // I } }, // G_TT_RGBA16 { // Get16 glType16 glInternalFormat16 Get32 glType32 glInternalFormat32 autoFormat { // 4-bit { GetCI4RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI4RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 4, 4096 }, // CI (Banjo-Kazooie uses this, doesn't make sense, but it works...) { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 4, 8192 }, // YUV { GetCI4RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI4RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 4, 4096 }, // CI { GetCI4RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI4RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 4, 4096 }, // IA as CI { GetCI4RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI4RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 4, 4096 }, // I as CI }, { // 8-bit { GetCI8RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI8RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 3, 2048 }, // RGBA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 4096 }, // YUV { GetCI8RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI8RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 3, 2048 }, // CI { GetCI8RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI8RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 3, 2048 }, // IA as CI { GetCI8RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI8RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 3, 2048 }, // I as CI }, { // 16-bit { GetCI16RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetRGBA5551_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 2, 2048 }, // RGBA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 2, 2048 }, // YUV { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 2048 }, // CI { GetCI16RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI16RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 2, 2048 }, // IA as CI { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 2048 }, // I }, { // 32-bit { GetRGBA8888_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetRGBA8888_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA, 2, 1024 }, // RGBA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // YUV { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // CI { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // IA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // I } }, // G_TT_IA16 { // Get16 glType16 glInternalFormat16 Get32 glType32 glInternalFormat32 autoFormat { // 4-bit { GetCI4IA_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetCI4IA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 4, 4096 }, // IA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 4, 8192 }, // YUV { GetCI4IA_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetCI4IA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 4, 4096 }, // CI { GetCI4IA_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetCI4IA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 4, 4096 }, // IA as CI { GetCI4IA_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetCI4IA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 4, 4096 }, // I as CI }, { // 8-bit { GetCI8IA_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetCI8IA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 3, 2048 }, // RGBA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 4096 }, // YUV { GetCI8IA_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetCI8IA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 3, 2048 }, // CI { GetCI8IA_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetCI8IA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 3, 2048 }, // IA as CI { GetCI8IA_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetCI8IA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 3, 2048 }, // I as CI }, { // 16-bit { GetCI16IA_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetCI16IA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA, 2, 2048 }, // RGBA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 2, 2048 }, // YUV { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 2048 }, // CI { GetCI16IA_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetCI16IA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA, 2, 2048 }, // IA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 2048 }, // I }, { // 32-bit { GetRGBA8888_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetRGBA8888_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA, 2, 1024 }, // RGBA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // YUV { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // CI { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // IA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // I } } }; /** cite from RiceVideo */ inline u32 CalculateDXT(u32 txl2words) { if (txl2words == 0) return 1; else return (2048 + txl2words - 1) / txl2words; } u32 sizeBytes[4] = {0, 1, 2, 4}; inline u32 Txl2Words(u32 width, u32 size) { if (size == 0) return max(1U, width / 16); else return max(1U, width*sizeBytes[size] / 8); } inline u32 ReverseDXT(u32 val, u32 lrs, u32 width, u32 size) { if (val == 0x800) return 1; int low = 2047 / val; if (CalculateDXT(low) > val) low++; int high = 2047 / (val - 1); if (low == high) return low; for (int i = low; i <= high; i++) { if (Txl2Words(width, size) == (u32)i) return i; } return (low + high) / 2; } /** end RiceVideo cite */ TextureCache & TextureCache::get() { static TextureCache cache; return cache; } void TextureCache::_initDummyTexture(CachedTexture * _pDummy) { _pDummy->address = 0; _pDummy->clampS = 1; _pDummy->clampT = 1; _pDummy->clampWidth = 2; _pDummy->clampHeight = 2; _pDummy->crc = 0; _pDummy->format = 0; _pDummy->size = 0; _pDummy->frameBufferTexture = CachedTexture::fbNone; _pDummy->width = 2; _pDummy->height = 2; _pDummy->realWidth = 2; _pDummy->realHeight = 2; _pDummy->maskS = 0; _pDummy->maskT = 0; _pDummy->scaleS = 0.5f; _pDummy->scaleT = 0.5f; _pDummy->shiftScaleS = 1.0f; _pDummy->shiftScaleT = 1.0f; _pDummy->textureBytes = 2 * 2 * 4; _pDummy->tMem = 0; } void TextureCache::init() { m_maxBytes = config.texture.maxBytes; m_curUnpackAlignment = 0; u32 dummyTexture[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; m_pDummy = addFrameBufferTexture(); // we don't want to remove dummy texture _initDummyTexture(m_pDummy); glBindTexture(GL_TEXTURE_2D, m_pDummy->glName); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, dummyTexture ); m_cachedBytes = m_pDummy->textureBytes; activateDummy( 0 ); activateDummy( 1 ); current[0] = current[1] = NULL; #ifdef GL_MULTISAMPLING_SUPPORT if (config.video.multisampling != 0) { m_pMSDummy = addFrameBufferTexture(); // we don't want to remove dummy texture _initDummyTexture(m_pMSDummy); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_pMSDummy->glName); #if defined(GLES3_1) glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, config.video.multisampling, GL_RGBA8, m_pMSDummy->realWidth, m_pMSDummy->realHeight, false); #else glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, config.video.multisampling, GL_RGBA8, m_pMSDummy->realWidth, m_pMSDummy->realHeight, false); #endif activateMSDummy(0); activateMSDummy(1); } else #endif m_pMSDummy = NULL; assert(!isGLError()); } void TextureCache::destroy() { current[0] = current[1] = NULL; for (Textures::const_iterator cur = m_textures.cbegin(); cur != m_textures.cend(); ++cur) glDeleteTextures( 1, &cur->glName ); m_textures.clear(); m_lruTextureLocations.clear(); for (FBTextures::const_iterator cur = m_fbTextures.cbegin(); cur != m_fbTextures.cend(); ++cur) glDeleteTextures( 1, &cur->second.glName ); m_fbTextures.clear(); m_cachedBytes = 0; } void TextureCache::_checkCacheSize() { if (m_cachedBytes <= m_maxBytes) return; Textures::iterator iter = m_textures.end(); do { --iter; CachedTexture& tex = *iter; m_cachedBytes -= tex.textureBytes; glDeleteTextures(1, &tex.glName); m_lruTextureLocations.erase(tex.crc); } while (m_cachedBytes > m_maxBytes && iter != m_textures.cbegin()); m_textures.erase(iter, m_textures.end()); } CachedTexture * TextureCache::_addTexture(u32 _crc32) { if (m_curUnpackAlignment == 0) glGetIntegerv(GL_UNPACK_ALIGNMENT, &m_curUnpackAlignment); _checkCacheSize(); GLuint glName; glGenTextures(1, &glName); m_textures.emplace_front(glName); Textures::iterator new_iter = m_textures.begin(); new_iter->crc = _crc32; m_lruTextureLocations.insert(std::pair(_crc32, new_iter)); return &(*new_iter); } void TextureCache::removeFrameBufferTexture(CachedTexture * _pTexture) { FBTextures::const_iterator iter = m_fbTextures.find(_pTexture->glName); assert(iter != m_fbTextures.cend()); m_cachedBytes -= iter->second.textureBytes; glDeleteTextures( 1, &iter->second.glName ); m_fbTextures.erase(iter); } CachedTexture * TextureCache::addFrameBufferTexture() { _checkCacheSize(); GLuint glName; glGenTextures(1, &glName); m_fbTextures.emplace(glName, glName); return &m_fbTextures.at(glName); } struct TileSizes { u32 maskWidth, clampWidth, width, realWidth; u32 maskHeight, clampHeight, height, realHeight; }; static void _calcTileSizes(u32 _t, TileSizes & _sizes, gDPTile * _pLoadTile) { gDPTile * pTile = _t < 2 ? gSP.textureTile[_t] : &gDP.tiles[_t]; const TextureLoadParameters & loadParams = imageFormat[gDP.otherMode.textureLUT][pTile->size][pTile->format]; const u32 maxTexels = loadParams.maxTexels; const u32 tileWidth = ((pTile->lrs - pTile->uls) & 0x03FF) + 1; const u32 tileHeight = ((pTile->lrt - pTile->ult) & 0x03FF) + 1; const bool bUseLoadSizes = _pLoadTile != NULL && _pLoadTile->loadType == LOADTYPE_TILE && (pTile->tmem == _pLoadTile->tmem); u32 loadWidth = 0, loadHeight = 0; if (bUseLoadSizes) { loadWidth = ((_pLoadTile->lrs - _pLoadTile->uls) & 0x03FF) + 1; loadHeight = ((_pLoadTile->lrt - _pLoadTile->ult) & 0x03FF) + 1; } const u32 lineWidth = pTile->line << loadParams.lineShift; const u32 lineHeight = lineWidth != 0 ? min(maxTexels / lineWidth, tileHeight) : 0; u32 maskWidth = 1 << pTile->masks; u32 maskHeight = 1 << pTile->maskt; u32 width, height; gDPLoadTileInfo &info = gDP.loadInfo[pTile->tmem]; if (info.loadType == LOADTYPE_TILE) { if (pTile->masks && ((maskWidth * maskHeight) <= maxTexels)) width = maskWidth; // Use mask width if set and valid else { width = min(info.width, info.texWidth); if (info.size > pTile->size) width <<= info.size - pTile->size; } if (pTile->maskt && ((maskWidth * maskHeight) <= maxTexels)) height = maskHeight; else height = info.height; } else { if (pTile->masks && ((maskWidth * maskHeight) <= maxTexels)) width = maskWidth; // Use mask width if set and valid else if ((tileWidth * tileHeight) <= maxTexels) width = tileWidth; // else use tile width if valid else width = lineWidth; // else use line-based width if (pTile->maskt && ((maskWidth * maskHeight) <= maxTexels)) height = maskHeight; else if ((tileWidth * tileHeight) <= maxTexels) height = tileHeight; else height = lineHeight; } _sizes.clampWidth = (pTile->clamps && gDP.otherMode.cycleType != G_CYC_COPY) ? tileWidth : width; _sizes.clampHeight = (pTile->clampt && gDP.otherMode.cycleType != G_CYC_COPY) ? tileHeight : height; if (_sizes.clampWidth > 256) pTile->clamps = 0; if (_sizes.clampHeight > 256) pTile->clampt = 0; // Make sure masking is valid if (maskWidth > width) { pTile->masks = powof(width); maskWidth = 1 << pTile->masks; } if (maskHeight > height) { pTile->maskt = powof(height); maskHeight = 1 << pTile->maskt; } _sizes.maskWidth = maskWidth; _sizes.maskHeight = maskHeight; _sizes.width = width; _sizes.height = height; if (pTile->clamps != 0) _sizes.realWidth = _sizes.clampWidth; else if (pTile->masks != 0) _sizes.realWidth = _sizes.maskWidth; else _sizes.realWidth = _sizes.width; if (pTile->clampt != 0) _sizes.realHeight = _sizes.clampHeight; else if (pTile->maskt != 0) _sizes.realHeight = _sizes.maskHeight; else _sizes.realHeight = _sizes.height; if (gSP.texture.level > gSP.texture.tile) { _sizes.realWidth = pow2(_sizes.realWidth); _sizes.realHeight = pow2(_sizes.realHeight); } } inline void _updateCachedTexture(const GHQTexInfo & _info, CachedTexture *_pTexture) { _pTexture->textureBytes = _info.width * _info.height; switch (_info.format) { case GL_RGB: case GL_RGBA4: case GL_RGB5_A1: _pTexture->textureBytes <<= 1; break; default: _pTexture->textureBytes <<= 2; } _pTexture->realWidth = _info.width; _pTexture->realHeight = _info.height; /* _pTexture->scaleS = 1.0f / (f32)(_pTexture->realWidth); _pTexture->scaleT = 1.0f / (f32)(_pTexture->realHeight); */ } bool TextureCache::_loadHiresBackground(CachedTexture *_pTexture) { if (!TFH.isInited()) return false; u8 * addr = (u8*)(RDRAM + gSP.bgImage.address); int tile_width = gSP.bgImage.width; int tile_height = gSP.bgImage.height; int bpl = tile_width << gSP.bgImage.size >> 1; u8 * paladdr = NULL; u16 * palette = NULL; if ((gSP.bgImage.size < G_IM_SIZ_16b) && (gDP.otherMode.textureLUT != G_TT_NONE || gSP.bgImage.format == G_IM_FMT_CI)) { if (gSP.bgImage.size == G_IM_SIZ_8b) paladdr = (u8*)(gDP.TexFilterPalette); else if (config.textureFilter.txHresAltCRC) paladdr = (u8*)(gDP.TexFilterPalette + (gSP.bgImage.palette << 5)); else paladdr = (u8*)(gDP.TexFilterPalette + (gSP.bgImage.palette << 4)); // TODO: fix palette load // palette = (rdp.pal_8 + (gSP.textureTile[_t]->palette << 4)); } u64 ricecrc = txfilter_checksum(addr, tile_width, tile_height, (unsigned short)(gSP.bgImage.format << 8 | gSP.bgImage.size), bpl, paladdr); GHQTexInfo ghqTexInfo; if (txfilter_hirestex(_pTexture->crc, ricecrc, palette, &ghqTexInfo)) { glTexImage2D(GL_TEXTURE_2D, 0, ghqTexInfo.format, ghqTexInfo.width, ghqTexInfo.height, 0, ghqTexInfo.texture_format, ghqTexInfo.pixel_type, ghqTexInfo.data); assert(!isGLError()); _updateCachedTexture(ghqTexInfo, _pTexture); return true; } return false; } void TextureCache::_loadBackground(CachedTexture *pTexture) { if (_loadHiresBackground(pTexture)) return; u32 *pDest; u8 *pSwapped, *pSrc; u32 numBytes, bpl; u32 x, y, j, tx, ty; u16 clampSClamp; u16 clampTClamp; GetTexelFunc GetTexel; GLuint glInternalFormat; GLenum glType; const TextureLoadParameters & loadParams = imageFormat[pTexture->format == 2 ? G_TT_RGBA16 : G_TT_NONE][pTexture->size][pTexture->format]; if (loadParams.autoFormat == GL_RGBA) { pTexture->textureBytes = (pTexture->realWidth * pTexture->realHeight) << 2; GetTexel = loadParams.Get32; glInternalFormat = loadParams.glInternalFormat32; glType = loadParams.glType32; } else { pTexture->textureBytes = (pTexture->realWidth * pTexture->realHeight) << 1; GetTexel = loadParams.Get16; glInternalFormat = loadParams.glInternalFormat16; glType = loadParams.glType16; } bpl = gSP.bgImage.width << gSP.bgImage.size >> 1; numBytes = bpl * gSP.bgImage.height; pSwapped = (u8*)malloc(numBytes); assert(pSwapped != NULL); UnswapCopyWrap(RDRAM, gSP.bgImage.address, pSwapped, 0, RDRAMSize, numBytes); pDest = (u32*)malloc(pTexture->textureBytes); assert(pDest != NULL); clampSClamp = pTexture->width - 1; clampTClamp = pTexture->height - 1; j = 0; for (y = 0; y < pTexture->realHeight; y++) { ty = min(y, (u32)clampTClamp); pSrc = &pSwapped[bpl * ty]; for (x = 0; x < pTexture->realWidth; x++) { tx = min(x, (u32)clampSClamp); if (glInternalFormat == GL_RGBA) ((u32*)pDest)[j++] = GetTexel((u64*)pSrc, tx, 0, pTexture->palette); else ((u16*)pDest)[j++] = GetTexel((u64*)pSrc, tx, 0, pTexture->palette); } } bool bLoaded = false; if ((config.textureFilter.txEnhancementMode | config.textureFilter.txFilterMode) != 0 && config.textureFilter.txFilterIgnoreBG == 0 && TFH.isInited()) { GHQTexInfo ghqTexInfo; if (txfilter_filter((u8*)pDest, pTexture->realWidth, pTexture->realHeight, glInternalFormat, (uint64)pTexture->crc, &ghqTexInfo) != 0 && ghqTexInfo.data != NULL) { if (ghqTexInfo.width % 2 != 0 && ghqTexInfo.format != GL_RGBA && m_curUnpackAlignment > 1) glPixelStorei(GL_UNPACK_ALIGNMENT, 2); glTexImage2D(GL_TEXTURE_2D, 0, ghqTexInfo.format, ghqTexInfo.width, ghqTexInfo.height, 0, ghqTexInfo.texture_format, ghqTexInfo.pixel_type, ghqTexInfo.data); _updateCachedTexture(ghqTexInfo, pTexture); bLoaded = true; } } if (!bLoaded) { if (pTexture->realWidth % 2 != 0 && glInternalFormat != GL_RGBA) glPixelStorei(GL_UNPACK_ALIGNMENT, 2); #ifdef GLES2 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pTexture->realWidth, pTexture->realHeight, 0, GL_RGBA, glType, pDest); #else glTexImage2D(GL_TEXTURE_2D, 0, glInternalFormat, pTexture->realWidth, pTexture->realHeight, 0, GL_RGBA, glType, pDest); #endif } if (m_curUnpackAlignment > 1) glPixelStorei(GL_UNPACK_ALIGNMENT, m_curUnpackAlignment); free(pDest); } bool TextureCache::_loadHiresTexture(u32 _tile, CachedTexture *_pTexture, u64 & _ricecrc) { if (config.textureFilter.txHiresEnable == 0 || !TFH.isInited()) return false; gDPLoadTileInfo & info = gDP.loadInfo[_pTexture->tMem]; int bpl; u8 * addr = (u8*)(RDRAM + info.texAddress); int tile_width = _pTexture->width; int tile_height = _pTexture->height; if (info.loadType == LOADTYPE_TILE) { bpl = info.texWidth << info.size >> 1; addr += (info.ult * bpl) + (((info.uls << info.size) + 1) >> 1); } else { if (gSP.textureTile[_tile]->size == G_IM_SIZ_32b) bpl = gSP.textureTile[_tile]->line << 4; else if (info.dxt == 0) bpl = gSP.textureTile[_tile]->line << 3; else { u32 dxt = info.dxt; if (dxt > 1) dxt = ReverseDXT(dxt, info.width, _pTexture->width, _pTexture->size); bpl = dxt << 3; } } u8 * paladdr = NULL; u16 * palette = NULL; if ((_pTexture->size < G_IM_SIZ_16b) && (gDP.otherMode.textureLUT != G_TT_NONE || _pTexture->format == G_IM_FMT_CI)) { if (_pTexture->size == G_IM_SIZ_8b) paladdr = (u8*)(gDP.TexFilterPalette); else if (config.textureFilter.txHresAltCRC) paladdr = (u8*)(gDP.TexFilterPalette + (_pTexture->palette << 5)); else paladdr = (u8*)(gDP.TexFilterPalette + (_pTexture->palette << 4)); // TODO: fix palette load // palette = (rdp.pal_8 + (gSP.textureTile[_t]->palette << 4)); } _ricecrc = txfilter_checksum(addr, tile_width, tile_height, (unsigned short)(_pTexture->format << 8 | _pTexture->size), bpl, paladdr); GHQTexInfo ghqTexInfo; if (txfilter_hirestex(_pTexture->crc, _ricecrc, palette, &ghqTexInfo)) { #ifdef GLES2 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ghqTexInfo.width, ghqTexInfo.height, 0, GL_RGBA, ghqTexInfo.pixel_type, ghqTexInfo.data); #else glTexImage2D(GL_TEXTURE_2D, 0, ghqTexInfo.format, ghqTexInfo.width, ghqTexInfo.height, 0, ghqTexInfo.texture_format, ghqTexInfo.pixel_type, ghqTexInfo.data); #endif assert(!isGLError()); _updateCachedTexture(ghqTexInfo, _pTexture); return true; } return false; } /* * Worker function for _load */ void TextureCache::_getTextureDestData(CachedTexture& tmptex, u32* pDest, GLuint glInternalFormat, GetTexelFunc GetTexel, u16* pLine) { u16 mirrorSBit, maskSMask, clampSClamp; u16 mirrorTBit, maskTMask, clampTClamp; u16 x, y, i, j, tx, ty; u64 *pSrc; if (tmptex.maskS > 0) { clampSClamp = tmptex.clampS ? tmptex.clampWidth - 1 : (tmptex.mirrorS ? (tmptex.width << 1) - 1 : tmptex.width - 1); maskSMask = (1 << tmptex.maskS) - 1; mirrorSBit = (tmptex.mirrorS != 0 || tmptex.realWidth/tmptex.width == 2) ? 1 << tmptex.maskS : 0; } else { clampSClamp = min(tmptex.clampWidth, tmptex.width) - 1; maskSMask = 0xFFFF; mirrorSBit = 0x0000; } if (tmptex.maskT > 0) { clampTClamp = tmptex.clampT ? tmptex.clampHeight - 1 : (tmptex.mirrorT ? (tmptex.height << 1) - 1 : tmptex.height - 1); maskTMask = (1 << tmptex.maskT) - 1; mirrorTBit = (tmptex.mirrorT != 0 || tmptex.realHeight/tmptex.height == 2) ? 1 << tmptex.maskT : 0; } else { clampTClamp = min(tmptex.clampHeight, tmptex.height) - 1; maskTMask = 0xFFFF; mirrorTBit = 0x0000; } if (tmptex.size == G_IM_SIZ_32b) { const u16 * tmem16 = (u16*)TMEM; const u32 tbase = tmptex.tMem << 2; int wid_64 = (tmptex.clampWidth) << 2; if (wid_64 & 15) { wid_64 += 16; } wid_64 &= 0xFFFFFFF0; wid_64 >>= 3; int line32 = tmptex.line << 1; line32 = (line32 - wid_64) << 3; if (wid_64 < 1) { wid_64 = 1; } int width = wid_64 << 1; line32 = width + (line32 >> 2); u16 gr, ab; j = 0; for (y = 0; y < tmptex.realHeight; ++y) { ty = min(y, clampTClamp) & maskTMask; if (y & mirrorTBit) { ty ^= maskTMask; } u32 tline = tbase + line32 * ty; u32 xorval = (ty & 1) ? 3 : 1; for (x = 0; x < tmptex.realWidth; ++x) { tx = min(x, clampSClamp) & maskSMask; if (x & mirrorSBit) { tx ^= maskSMask; } u32 taddr = ((tline + tx) ^ xorval) & 0x3ff; gr = swapword(tmem16[taddr]); ab = swapword(tmem16[taddr | 0x400]); pDest[j++] = (ab << 16) | gr; } } } else if (tmptex.format == G_IM_FMT_YUV) { j = 0; *pLine <<= 1; for (y = 0; y < tmptex.realHeight; ++y) { pSrc = &TMEM[tmptex.tMem] + *pLine * y; for (x = 0; x < tmptex.realWidth / 2; x++) { if (glInternalFormat == GL_RGBA) { GetYUV_RGBA8888(pSrc, pDest + j, x); } else { GetYUV_RGBA4444(pSrc, (u16*)pDest + j, x); } j += 2; } } } else { j = 0; for (y = 0; y < tmptex.realHeight; ++y) { ty = min(y, clampTClamp) & maskTMask; if (y & mirrorTBit) ty ^= maskTMask; pSrc = &TMEM[(tmptex.tMem + *pLine * ty) & 0x1FF]; i = (ty & 1) << 1; for (x = 0; x < tmptex.realWidth; ++x) { tx = min(x, clampSClamp) & maskSMask; if (x & mirrorSBit) { tx ^= maskSMask; } if (glInternalFormat == GL_RGBA) { pDest[j++] = GetTexel(pSrc, tx, i, tmptex.palette); } else { ((u16*)pDest)[j++] = GetTexel(pSrc, tx, i, tmptex.palette); } } } } } void TextureCache::_load(u32 _tile, CachedTexture *_pTexture) { u64 ricecrc = 0; if (_loadHiresTexture(_tile, _pTexture, ricecrc)) return; u32 *pDest; u16 line; GetTexelFunc GetTexel; GLuint glInternalFormat; GLenum glType; u32 sizeShift; const TextureLoadParameters & loadParams = imageFormat[gDP.otherMode.textureLUT][_pTexture->size][_pTexture->format]; if (loadParams.autoFormat == GL_RGBA) { sizeShift = 2; _pTexture->textureBytes = (_pTexture->realWidth * _pTexture->realHeight) << sizeShift; GetTexel = loadParams.Get32; glInternalFormat = loadParams.glInternalFormat32; glType = loadParams.glType32; } else { sizeShift = 1; _pTexture->textureBytes = (_pTexture->realWidth * _pTexture->realHeight) << sizeShift; GetTexel = loadParams.Get16; glInternalFormat = loadParams.glInternalFormat16; glType = loadParams.glType16; } pDest = (u32*)malloc(_pTexture->textureBytes); assert(pDest != NULL); GLint mipLevel = 0, maxLevel = 0; #ifndef GLES2 if (config.generalEmulation.enableLOD != 0 && gSP.texture.level > gSP.texture.tile + 1) maxLevel = _tile == 0 ? 0 : gSP.texture.level - gSP.texture.tile - 1; #endif _pTexture->max_level = maxLevel; CachedTexture tmptex(0); memcpy(&tmptex, _pTexture, sizeof(CachedTexture)); line = tmptex.line; while (true) { _getTextureDestData(tmptex, pDest, glInternalFormat, GetTexel, &line); bool bLoaded = false; if (m_toggleDumpTex && config.textureFilter.txHiresEnable != 0 && config.textureFilter.txDump != 0) { txfilter_dmptx((u8*)pDest, tmptex.realWidth, tmptex.realHeight, tmptex.realWidth, glInternalFormat, (unsigned short)(_pTexture->format << 8 | _pTexture->size), ricecrc); } else if ((config.textureFilter.txEnhancementMode | config.textureFilter.txFilterMode) != 0 && maxLevel == 0 && (config.textureFilter.txFilterIgnoreBG == 0 || (RSP.cmd != G_TEXRECT && RSP.cmd != G_TEXRECTFLIP)) && TFH.isInited()) { GHQTexInfo ghqTexInfo; if (txfilter_filter((u8*)pDest, tmptex.realWidth, tmptex.realHeight, glInternalFormat, (uint64)_pTexture->crc, &ghqTexInfo) != 0 && ghqTexInfo.data != NULL) { #ifdef GLES2 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ghqTexInfo.width, ghqTexInfo.height, 0, GL_RGBA, ghqTexInfo.pixel_type, ghqTexInfo.data); #else glTexImage2D(GL_TEXTURE_2D, 0, ghqTexInfo.format, ghqTexInfo.width, ghqTexInfo.height, 0, ghqTexInfo.texture_format, ghqTexInfo.pixel_type, ghqTexInfo.data); #endif _updateCachedTexture(ghqTexInfo, _pTexture); bLoaded = true; } } if (!bLoaded) { if (tmptex.realWidth % 2 != 0 && glInternalFormat != GL_RGBA && m_curUnpackAlignment > 1) glPixelStorei(GL_UNPACK_ALIGNMENT, 2); #ifdef GLES2 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tmptex.realWidth, tmptex.realHeight, 0, GL_RGBA, glType, pDest); #else glTexImage2D(GL_TEXTURE_2D, mipLevel, glInternalFormat, tmptex.realWidth, tmptex.realHeight, 0, GL_RGBA, glType, pDest); #endif } if (mipLevel == maxLevel) break; ++mipLevel; const u32 tileMipLevel = gSP.texture.tile + mipLevel + 1; gDPTile & mipTile = gDP.tiles[tileMipLevel]; line = mipTile.line; tmptex.tMem = mipTile.tmem; tmptex.palette = mipTile.palette; tmptex.maskS = mipTile.masks; tmptex.maskT = mipTile.maskt; TileSizes sizes; _calcTileSizes(tileMipLevel, sizes, NULL); tmptex.width = sizes.width; tmptex.clampWidth = sizes.clampWidth; tmptex.height = sizes.height; tmptex.clampHeight = sizes.clampHeight; // Insure mip-map levels size consistency. if (tmptex.realWidth > 1) tmptex.realWidth >>= 1; if (tmptex.realHeight > 1) tmptex.realHeight >>= 1; _pTexture->textureBytes += (tmptex.realWidth * tmptex.realHeight) << sizeShift; } if (m_curUnpackAlignment > 1) glPixelStorei(GL_UNPACK_ALIGNMENT, m_curUnpackAlignment); free(pDest); } struct TextureParams { u16 width; u16 height; u16 clampWidth; u16 clampHeight; u8 maskS; u8 maskT; u8 mirrorS; u8 mirrorT; u8 clampS; u8 clampT; u8 format; u8 size; }; static u32 _calculateCRC(u32 t, const TextureParams & _params) { const u32 line = gSP.textureTile[t]->line; const u32 lineBytes = line << 3; const u64 *src = (u64*)&TMEM[gSP.textureTile[t]->tmem]; u32 crc = 0xFFFFFFFF; crc = CRC_Calculate(crc, src, _params.height*lineBytes); if (gSP.textureTile[t]->size == G_IM_SIZ_32b) { src = (u64*)&TMEM[gSP.textureTile[t]->tmem + 256]; crc = CRC_Calculate(crc, src, _params.height*lineBytes); } if (gDP.otherMode.textureLUT != G_TT_NONE || gSP.textureTile[t]->format == G_IM_FMT_CI) { if (gSP.textureTile[t]->size == G_IM_SIZ_4b) crc = CRC_Calculate( crc, &gDP.paletteCRC16[gSP.textureTile[t]->palette], 4 ); else if (gSP.textureTile[t]->size == G_IM_SIZ_8b) crc = CRC_Calculate( crc, &gDP.paletteCRC256, 4 ); } crc = CRC_Calculate(crc, &_params, sizeof(_params)); return crc; } void TextureCache::activateTexture(u32 _t, CachedTexture *_pTexture) { #ifdef GL_MULTISAMPLING_SUPPORT if (config.video.multisampling > 0 && _pTexture->frameBufferTexture == CachedTexture::fbMultiSample) { glActiveTexture(GL_TEXTURE0 + g_MSTex0Index + _t); // Bind the cached texture glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _pTexture->glName); } else #endif { glActiveTexture(GL_TEXTURE0 + _t); // Bind the cached texture glBindTexture(GL_TEXTURE_2D, _pTexture->glName); } const bool bUseBilinear = (gDP.otherMode.textureFilter | (gSP.objRendermode&G_OBJRM_BILERP)) != 0; const bool bUseLOD = currentCombiner()->usesLOD(); const GLint texLevel = bUseLOD ? _pTexture->max_level : 0; #ifndef GLES2 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, texLevel); #endif if (config.texture.bilinearMode == BILINEAR_STANDARD) { if (bUseBilinear) { if (texLevel > 0) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); else glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } else { if (texLevel > 0) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); else glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } } else { // 3 point filter if (texLevel > 0) { // Apply standard bilinear to mipmap textures if (bUseBilinear) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } } else if (bUseBilinear && config.generalEmulation.enableLOD != 0 && bUseLOD) { // Apply standard bilinear to first tile of mipmap texture glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } else { // Don't use texture filter. Texture will be filtered by 3 point filter shader glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } } // Set clamping modes glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, _pTexture->clampS ? GL_CLAMP_TO_EDGE : _pTexture->mirrorS ? GL_MIRRORED_REPEAT : GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, _pTexture->clampT ? GL_CLAMP_TO_EDGE : _pTexture->mirrorT ? GL_MIRRORED_REPEAT : GL_REPEAT); if (video().getRender().getRenderState() == OGLRender::rsTriangle && config.texture.maxAnisotropyF > 0.0f) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, config.texture.maxAnisotropyF); _pTexture->lastDList = video().getBuffersSwapCount(); current[_t] = _pTexture; } void TextureCache::activateDummy(u32 _t) { glActiveTexture( GL_TEXTURE0 + _t ); glBindTexture( GL_TEXTURE_2D, m_pDummy->glName ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); } void TextureCache::activateMSDummy(u32 _t) { #ifdef GL_MULTISAMPLING_SUPPORT glActiveTexture(GL_TEXTURE0 + g_MSTex0Index + _t); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_pMSDummy->glName); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0); #endif } void TextureCache::_updateBackground() { u32 numBytes = gSP.bgImage.width * gSP.bgImage.height << gSP.bgImage.size >> 1; u32 crc; crc = CRC_Calculate( 0xFFFFFFFF, &RDRAM[gSP.bgImage.address], numBytes ); if (gDP.otherMode.textureLUT != G_TT_NONE || gSP.bgImage.format == G_IM_FMT_CI) { if (gSP.bgImage.size == G_IM_SIZ_4b) crc = CRC_Calculate( crc, &gDP.paletteCRC16[gSP.bgImage.palette], 4 ); else if (gSP.bgImage.size == G_IM_SIZ_8b) crc = CRC_Calculate( crc, &gDP.paletteCRC256, 4 ); } u32 params[4] = {gSP.bgImage.width, gSP.bgImage.height, gSP.bgImage.format, gSP.bgImage.size}; crc = CRC_Calculate(crc, params, sizeof(u32)*4); Texture_Locations::iterator locations_iter = m_lruTextureLocations.find(crc); if (locations_iter != m_lruTextureLocations.end()) { Textures::iterator iter = locations_iter->second; CachedTexture & current = *iter; m_textures.splice(m_textures.begin(), m_textures, iter); assert(current.width == gSP.bgImage.width); assert(current.height == gSP.bgImage.height); assert(current.format == gSP.bgImage.format); assert(current.size == gSP.bgImage.size); activateTexture(0, ¤t); m_hits++; return; } m_misses++; glActiveTexture( GL_TEXTURE0 ); CachedTexture * pCurrent = _addTexture(crc); glBindTexture( GL_TEXTURE_2D, pCurrent->glName ); pCurrent->address = gSP.bgImage.address; pCurrent->format = gSP.bgImage.format; pCurrent->size = gSP.bgImage.size; pCurrent->width = gSP.bgImage.width; pCurrent->height = gSP.bgImage.height; pCurrent->clampWidth = gSP.bgImage.width; pCurrent->clampHeight = gSP.bgImage.height; pCurrent->palette = gSP.bgImage.palette; pCurrent->maskS = 0; pCurrent->maskT = 0; pCurrent->mirrorS = 0; pCurrent->mirrorT = 0; pCurrent->clampS = 0; pCurrent->clampT = 0; pCurrent->line = 0; pCurrent->tMem = 0; pCurrent->lastDList = video().getBuffersSwapCount(); pCurrent->frameBufferTexture = CachedTexture::fbNone; pCurrent->realWidth = gSP.bgImage.width; pCurrent->realHeight = gSP.bgImage.height; pCurrent->scaleS = 1.0f / (f32)(pCurrent->realWidth); pCurrent->scaleT = 1.0f / (f32)(pCurrent->realHeight); pCurrent->shiftScaleS = 1.0f; pCurrent->shiftScaleT = 1.0f; pCurrent->offsetS = 0.5f; pCurrent->offsetT = 0.5f; _loadBackground(pCurrent); activateTexture(0, pCurrent); m_cachedBytes += pCurrent->textureBytes; current[0] = pCurrent; } void TextureCache::_clear() { current[0] = current[1] = NULL; for (Textures::const_iterator cur = m_textures.cbegin(); cur != m_textures.cend(); ++cur) { m_cachedBytes -= cur->textureBytes; glDeleteTextures(1, &cur->glName); } m_textures.clear(); m_lruTextureLocations.clear(); } void TextureCache::update(u32 _t) { if (config.textureFilter.txHiresEnable != 0 && config.textureFilter.txDump != 0) { /* Force reload hi-res textures. Useful for texture artists */ if (isKeyPressed(G64_VK_R, 0x0001)) { if (txfilter_reloadhirestex()) { _clear(); } } /* Turn on texture dump */ else if (isKeyPressed(G64_VK_D, 0x0001)) { m_toggleDumpTex = !m_toggleDumpTex; if (m_toggleDumpTex) { displayLoadProgress(L"Texture dump - ON\n"); _clear(); std::this_thread::sleep_for(std::chrono::seconds(1)); } else { displayLoadProgress(L"Texture dump - OFF\n"); std::this_thread::sleep_for(std::chrono::seconds(1)); } } } switch(gSP.textureTile[_t]->textureMode) { case TEXTUREMODE_BGIMAGE: _updateBackground(); return; case TEXTUREMODE_FRAMEBUFFER: FrameBuffer_ActivateBufferTexture( _t, gSP.textureTile[_t]->frameBuffer ); return; case TEXTUREMODE_FRAMEBUFFER_BG: FrameBuffer_ActivateBufferTextureBG( _t, gSP.textureTile[_t]->frameBuffer ); return; } if (gDP.otherMode.textureLOD == G_TL_LOD && gSP.texture.level == gSP.texture.tile && _t == 1) { current[1] = current[0]; activateTexture(_t, current[_t]); return; } if (gSP.texture.tile == 7 && _t == 0 && gSP.textureTile[0] == gDP.loadTile && gDP.loadTile->loadType == LOADTYPE_BLOCK && gSP.textureTile[0]->tmem == gSP.textureTile[1]->tmem) gSP.textureTile[0] = gSP.textureTile[1]; TileSizes sizes; _calcTileSizes(_t, sizes, gDP.loadTile); u32 crc; { TextureParams params; params.width = sizes.width; params.height = sizes.height; params.clampWidth = sizes.clampWidth; params.clampHeight = sizes.clampHeight; params.maskS = gSP.textureTile[_t]->masks; params.maskT = gSP.textureTile[_t]->maskt; params.mirrorS = gSP.textureTile[_t]->mirrors; params.mirrorT = gSP.textureTile[_t]->mirrort; params.clampS = gSP.textureTile[_t]->clamps; params.clampT = gSP.textureTile[_t]->clampt; params.format = gSP.textureTile[_t]->format; params.size = gSP.textureTile[_t]->size; crc = _calculateCRC( _t, params ); } if (current[_t] != NULL && current[_t]->crc == crc) { activateTexture(_t, current[_t]); return; } Texture_Locations::iterator locations_iter = m_lruTextureLocations.find(crc); if (locations_iter != m_lruTextureLocations.end()) { Textures::iterator iter = locations_iter->second; CachedTexture & current = *iter; m_textures.splice(m_textures.begin(), m_textures, iter); assert(current.width == sizes.width); assert(current.height == sizes.height); assert(current.clampWidth == sizes.clampWidth); assert(current.clampHeight == sizes.clampHeight); assert(current.maskS == gSP.textureTile[_t]->masks); assert(current.maskT == gSP.textureTile[_t]->maskt); assert(current.mirrorS == gSP.textureTile[_t]->mirrors); assert(current.mirrorT == gSP.textureTile[_t]->mirrort); assert(current.clampS == gSP.textureTile[_t]->clamps); assert(current.clampT == gSP.textureTile[_t]->clampt); assert(current.format == gSP.textureTile[_t]->format); assert(current.size == gSP.textureTile[_t]->size); activateTexture(_t, ¤t); m_hits++; return; } m_misses++; glActiveTexture( GL_TEXTURE0 + _t ); CachedTexture * pCurrent = _addTexture(crc); glBindTexture( GL_TEXTURE_2D, pCurrent->glName ); pCurrent->address = gDP.loadInfo[gSP.textureTile[_t]->tmem].texAddress; pCurrent->format = gSP.textureTile[_t]->format; pCurrent->size = gSP.textureTile[_t]->size; pCurrent->width = sizes.width; pCurrent->height = sizes.height; pCurrent->clampWidth = sizes.clampWidth; pCurrent->clampHeight = sizes.clampHeight; pCurrent->palette = gSP.textureTile[_t]->palette; /* pCurrent->fulS = gSP.textureTile[t]->fulS; pCurrent->fulT = gSP.textureTile[t]->fulT; pCurrent->ulS = gSP.textureTile[t]->ulS; pCurrent->ulT = gSP.textureTile[t]->ulT; pCurrent->lrS = gSP.textureTile[t]->lrS; pCurrent->lrT = gSP.textureTile[t]->lrT;*/ pCurrent->maskS = gSP.textureTile[_t]->masks; pCurrent->maskT = gSP.textureTile[_t]->maskt; pCurrent->mirrorS = gSP.textureTile[_t]->mirrors; pCurrent->mirrorT = gSP.textureTile[_t]->mirrort; pCurrent->clampS = gSP.textureTile[_t]->clamps; pCurrent->clampT = gSP.textureTile[_t]->clampt; pCurrent->line = gSP.textureTile[_t]->line; pCurrent->tMem = gSP.textureTile[_t]->tmem; pCurrent->lastDList = video().getBuffersSwapCount(); pCurrent->frameBufferTexture = CachedTexture::fbNone; pCurrent->realWidth = sizes.realWidth; pCurrent->realHeight = sizes.realHeight; pCurrent->scaleS = 1.0f / (f32)(pCurrent->realWidth); pCurrent->scaleT = 1.0f / (f32)(pCurrent->realHeight); pCurrent->offsetS = 0.5f; pCurrent->offsetT = 0.5f; _load(_t, pCurrent); activateTexture( _t, pCurrent ); m_cachedBytes += pCurrent->textureBytes; current[_t] = pCurrent; } void getTextureShiftScale(u32 t, const TextureCache & cache, f32 & shiftScaleS, f32 & shiftScaleT) { if (gSP.textureTile[t]->textureMode != TEXTUREMODE_NORMAL) { shiftScaleS = cache.current[t]->shiftScaleS; shiftScaleT = cache.current[t]->shiftScaleT; return; } if (gDP.otherMode.textureLOD == G_TL_LOD && gSP.texture.level == gSP.texture.tile) t = 0; if (gSP.textureTile[t]->shifts > 10) shiftScaleS = (f32)(1 << (16 - gSP.textureTile[t]->shifts)); else if (gSP.textureTile[t]->shifts > 0) shiftScaleS /= (f32)(1 << gSP.textureTile[t]->shifts); if (gSP.textureTile[t]->shiftt > 10) shiftScaleT = (f32)(1 << (16 - gSP.textureTile[t]->shiftt)); else if (gSP.textureTile[t]->shiftt > 0) shiftScaleT /= (f32)(1 << gSP.textureTile[t]->shiftt); } gles2rice/src/TextureManager.h000664 001750 001750 00000020566 12655644434 017502 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __TEXTUREHANDLER_H__ #define __TEXTUREHANDLER_H__ #ifndef SAFE_DELETE #define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } } #endif #ifndef SAFE_CHECK # define SAFE_CHECK(a) if( (a) == NULL ) {DebugMessage(M64MSG_ERROR, "Creater out of memory"); throw new std::exception();} #endif #include #ifndef _MSC_VER #include #endif #include "typedefs.h" #include "Texture.h" #define absi(x) ((x)>=0?(x):(-x)) #define S_FLAG 0 #define T_FLAG 1 class TxtrInfo { public: uint32_t WidthToCreate; uint32_t HeightToCreate; uint32_t Address; void *pPhysicalAddress; uint32_t Format; uint32_t Size; int LeftToLoad; int TopToLoad; uint32_t WidthToLoad; uint32_t HeightToLoad; uint32_t Pitch; uint8_t *PalAddress; uint32_t TLutFmt; uint32_t Palette; bool bSwapped; uint32_t maskS; uint32_t maskT; bool clampS; bool clampT; bool mirrorS; bool mirrorT; int tileNo; inline TxtrInfo& operator = (const TxtrInfo& src) { memcpy(this, &src, sizeof( TxtrInfo )); return *this; } inline TxtrInfo& operator = (const Tile& tile) { Format = tile.dwFormat; Size = tile.dwSize; Palette = tile.dwPalette; maskS = tile.dwMaskS; maskT = tile.dwMaskT; mirrorS = tile.bMirrorS; mirrorT = tile.bMirrorT; clampS = tile.bClampS; clampT = tile.bClampT; return *this; } inline bool operator == ( const TxtrInfo& sec) { return ( Address == sec.Address && WidthToLoad == sec.WidthToLoad && HeightToLoad == sec.HeightToLoad && WidthToCreate == sec.WidthToCreate && HeightToCreate == sec.HeightToCreate && maskS == sec.maskS && maskT == sec.maskT && TLutFmt == sec.TLutFmt && PalAddress == sec.PalAddress && Palette == sec.Palette && LeftToLoad == sec.LeftToLoad && TopToLoad == sec.TopToLoad && Format == sec.Format && Size == sec.Size && Pitch == sec.Pitch && bSwapped == sec.bSwapped && mirrorS == sec.mirrorS && mirrorT == sec.mirrorT && clampS == sec.clampS && clampT == sec.clampT ); } inline bool isEqual(const TxtrInfo& sec) { return (*this == sec); } } ; typedef struct TxtrCacheEntry { TxtrCacheEntry(): pTexture(NULL),pEnhancedTexture(NULL),txtrBufIdx(0) {} ~TxtrCacheEntry() { SAFE_DELETE(pTexture); SAFE_DELETE(pEnhancedTexture); } struct TxtrCacheEntry *pNext; // Must be first element! struct TxtrCacheEntry *pNextYoungest; struct TxtrCacheEntry *pLastYoungest; TxtrInfo ti; uint32_t dwCRC; uint32_t dwPalCRC; int maxCI; uint32_t dwUses; // Total times used (for stats) uint32_t dwTimeLastUsed; // timeGetTime of time of last usage uint32_t FrameLastUsed; // Frame # that this was last used uint32_t FrameLastUpdated; CTexture *pTexture; CTexture *pEnhancedTexture; uint32_t dwEnhancementFlag; int txtrBufIdx; bool bExternalTxtrChecked; TxtrCacheEntry *lastEntry; } TxtrCacheEntry; //***************************************************************************** // Texture cache implementation //***************************************************************************** class CTextureManager { protected: TxtrCacheEntry * CreateNewCacheEntry(uint32_t dwAddr, uint32_t dwWidth, uint32_t dwHeight); void AddTexture(TxtrCacheEntry *pEntry); void RemoveTexture(TxtrCacheEntry * pEntry); void RecycleTexture(TxtrCacheEntry *pEntry); TxtrCacheEntry * ReviveTexture( uint32_t width, uint32_t height ); TxtrCacheEntry * GetTxtrCacheEntry(TxtrInfo * pti); void ConvertTexture(TxtrCacheEntry * pEntry, bool fromTMEM); void ConvertTexture_16(TxtrCacheEntry * pEntry, bool fromTMEM); void ClampS32(uint32_t *array, uint32_t width, uint32_t towidth, uint32_t arrayWidth, uint32_t rows); void ClampS16(uint16_t *array, uint32_t width, uint32_t towidth, uint32_t arrayWidth, uint32_t rows); void ClampT32(uint32_t *array, uint32_t height, uint32_t toheight, uint32_t arrayWidth, uint32_t cols); void ClampT16(uint16_t *array, uint32_t height, uint32_t toheight, uint32_t arrayWidth, uint32_t cols); void MirrorS32(uint32_t *array, uint32_t width, uint32_t mask, uint32_t towidth, uint32_t arrayWidth, uint32_t rows); void MirrorS16(uint16_t *array, uint32_t width, uint32_t mask, uint32_t towidth, uint32_t arrayWidth, uint32_t rows); void MirrorT32(uint32_t *array, uint32_t height, uint32_t mask, uint32_t toheight, uint32_t arrayWidth, uint32_t cols); void MirrorT16(uint16_t *array, uint32_t height, uint32_t mask, uint32_t toheight, uint32_t arrayWidth, uint32_t cols); void WrapS32(uint32_t *array, uint32_t width, uint32_t mask, uint32_t towidth, uint32_t arrayWidth, uint32_t rows); void WrapS16(uint16_t *array, uint32_t width, uint32_t mask, uint32_t towidth, uint32_t arrayWidth, uint32_t rows); void WrapT32(uint32_t *array, uint32_t height, uint32_t mask, uint32_t toheight, uint32_t arrayWidth, uint32_t cols); void WrapT16(uint16_t *array, uint32_t height, uint32_t mask, uint32_t toheight, uint32_t arrayWidth, uint32_t cols); void ExpandTextureS(TxtrCacheEntry * pEntry); void ExpandTextureT(TxtrCacheEntry * pEntry); void ExpandTexture(TxtrCacheEntry * pEntry, uint32_t sizeOfLoad, uint32_t sizeToCreate, uint32_t sizeCreated, int arrayWidth, int flag, int mask, int mirror, int clamp, uint32_t otherSize); uint32_t Hash(uint32_t dwValue); bool TCacheEntryIsLoaded(TxtrCacheEntry *pEntry); void updateColorTexture(CTexture *ptexture, uint32_t color); public: void Wrap(void *array, uint32_t width, uint32_t mask, uint32_t towidth, uint32_t arrayWidth, uint32_t rows, int flag, int size ); void Clamp(void *array, uint32_t width, uint32_t towidth, uint32_t arrayWidth, uint32_t rows, int flag, int size ); void Mirror(void *array, uint32_t width, uint32_t mask, uint32_t towidth, uint32_t arrayWidth, uint32_t rows, int flag, int size ); protected: TxtrCacheEntry * m_pHead; TxtrCacheEntry ** m_pCacheTxtrList; uint32_t m_numOfCachedTxtrList; TxtrCacheEntry m_blackTextureEntry; TxtrCacheEntry m_PrimColorTextureEntry; TxtrCacheEntry m_EnvColorTextureEntry; TxtrCacheEntry m_LODFracTextureEntry; TxtrCacheEntry m_PrimLODFracTextureEntry; TxtrCacheEntry * GetPrimColorTexture(uint32_t color); TxtrCacheEntry * GetEnvColorTexture(uint32_t color); TxtrCacheEntry * GetLODFracTexture(uint8_t fac); TxtrCacheEntry * GetPrimLODFracTexture(uint8_t fac); void MakeTextureYoungest(TxtrCacheEntry *pEntry); unsigned int m_currentTextureMemUsage; TxtrCacheEntry *m_pYoungestTexture; TxtrCacheEntry *m_pOldestTexture; public: CTextureManager(); ~CTextureManager(); TxtrCacheEntry * GetBlackTexture(void); TxtrCacheEntry * GetConstantColorTexture(uint32_t constant); TxtrCacheEntry * GetTexture(TxtrInfo * pgti, bool fromTMEM, bool doCRCCheck, bool AutoExtendTexture); void PurgeOldTextures(); void RecycleAllTextures(); void RecheckHiresForAllTextures(); bool CleanUp(); #ifdef DEBUGGER TxtrCacheEntry * GetCachedTexture(uint32_t tex); uint32_t GetNumOfCachedTexture(); #endif }; extern CTextureManager gTextureManager; // The global instance of CTextureManager class extern void DumpCachedTexture(TxtrCacheEntry &entry); #endif gles2n64/src/F3DDKR.h000664 001750 001750 00000000655 12655644434 015146 0ustar00sergiosergio000000 000000 #ifndef F3DDKR_H #define F3DDKR_H #define F3DDKR_VTX_APPEND 0x00010000 #define F3DDKR_DMA_MTX 0x01 #define F3DDKR_DMA_TEX_OFFSET 0x02 #define F3DDKR_DMA_VTX 0x04 #define F3DDKR_DMA_TRI 0x05 #define F3DDKR_DMA_DL 0x07 #define F3DDKR_DMA_OFFSETS 0xBF #ifdef __cplusplus extern "C" { #endif void F3DDKR_Init(void); void F3DJFG_Init(void); #ifdef __cplusplus } #endif #endif mupen64plus-video-gliden64/src/OpenGL.cpp000664 001750 001750 00000132140 12655644434 021257 0ustar00sergiosergio000000 000000 #include #include #include #include /* time_t, struct tm, difftime, time, mktime */ #include "Types.h" #include "GLideN64.h" #include "OpenGL.h" #include "RDP.h" #include "RSP.h" #include "N64.h" #include "gSP.h" #include "gDP.h" #include "Textures.h" #include "Combiner.h" #include "GLSLCombiner.h" #include "FrameBuffer.h" #include "DepthBuffer.h" #include "GLideNHQ/Ext_TxFilter.h" #include "VI.h" #include "Config.h" #include "wst.h" #include "Log.h" #include "TextDrawer.h" #include "PluginAPI.h" #include "PostProcessor.h" using namespace std; bool checkFBO() { GLenum e = glCheckFramebufferStatus(GL_FRAMEBUFFER); switch (e) { // case GL_FRAMEBUFFER_UNDEFINED: // printf("FBO Undefined\n"); // break; case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT : LOG(LOG_ERROR, "[gles2GlideN64]: FBO Incomplete Attachment\n"); break; case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT : LOG(LOG_ERROR, "[gles2GlideN64]: FBO Missing Attachment\n"); break; // case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER : // printf("FBO Incomplete Draw Buffer\n"); // break; case GL_FRAMEBUFFER_UNSUPPORTED : LOG(LOG_ERROR, "[gles2GlideN64]: FBO Unsupported\n"); break; case GL_FRAMEBUFFER_COMPLETE: LOG(LOG_VERBOSE, "[gles2GlideN64]: FBO OK\n"); break; // case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: // printf("framebuffer FRAMEBUFFER_DIMENSIONS\n"); // break; // case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: // printf("framebuffer INCOMPLETE_FORMATS\n"); // break; default: LOG(LOG_ERROR, "[gles2GlideN64]: FBO Problem?\n"); } return e == GL_FRAMEBUFFER_COMPLETE; } const char* GLErrorString(GLenum errorCode) { static const struct { GLenum code; const char *string; } errors[]= { /* GL */ {GL_NO_ERROR, "no error"}, {GL_INVALID_ENUM, "invalid enumerant"}, {GL_INVALID_VALUE, "invalid value"}, {GL_INVALID_OPERATION, "invalid operation"}, #ifndef GLESX {GL_STACK_OVERFLOW, "stack overflow"}, {GL_STACK_UNDERFLOW, "stack underflow"}, #endif {GL_OUT_OF_MEMORY, "out of memory"}, {0, NULL } }; int i; for (i=0; errors[i].string; i++) { if (errors[i].code == errorCode) { return errors[i].string; } } return NULL; } bool isGLError() { GLenum errCode; const char* errString; if ((errCode = glGetError()) != GL_NO_ERROR) { errString = GLErrorString(errCode); if (errString != NULL) fprintf (stderr, "OpenGL Error: %s\n", errString); return true; } return false; } bool OGLVideo::isExtensionSupported(const char *extension) { GLubyte *where = (GLubyte *)strchr(extension, ' '); if (where || *extension == '\0') return false; const GLubyte *extensions = glGetString(GL_EXTENSIONS); const GLubyte *start = extensions; for (;;) { where = (GLubyte *)strstr((const char *)start, extension); if (where == NULL) break; GLubyte *terminator = where + strlen(extension); if (where == start || *(where - 1) == ' ') if (*terminator == ' ' || *terminator == '\0') return true; start = terminator; } return false; } void OGLVideo::start() { _start(); // TODO: process initialization error initGLFunctions(); m_render._initData(); m_buffersSwapCount = 0; } void OGLVideo::stop() { m_render._destroyData(); _stop(); } void OGLVideo::restart() { m_bResizeWindow = true; } void OGLVideo::swapBuffers() { _swapBuffers(); retro_return(true); gDP.otherMode.l = 0; gDPSetTextureLUT(G_TT_NONE); ++m_buffersSwapCount; } void OGLVideo::setCaptureScreen(const char * const _strDirectory) { ::mbstowcs(m_strScreenDirectory, _strDirectory, PLUGIN_PATH_SIZE-1); m_bCaptureScreen = true; } void OGLVideo::saveScreenshot() { if (!m_bCaptureScreen) return; _saveScreenshot(); m_bCaptureScreen = false; } bool OGLVideo::changeWindow() { if (!m_bToggleFullscreen) return false; m_render._destroyData(); _changeWindow(); updateScale(); m_render._initData(); m_bToggleFullscreen = false; return true; } void OGLVideo::setWindowSize(u32 _width, u32 _height) { if (m_width != _width || m_height != _height) { m_resizeWidth = _width; m_resizeHeight = _height; m_bResizeWindow = true; } } bool OGLVideo::resizeWindow() { if (!m_bResizeWindow) return false; m_render._destroyData(); if (!_resizeWindow()) _start(); updateScale(); m_render._initData(); m_bResizeWindow = false; return true; } void OGLVideo::updateScale() { if (VI.width == 0 || VI.height == 0) return; m_scaleX = m_width / (float)VI.width; m_scaleY = m_height / (float)VI.height; } void OGLVideo::_setBufferSize() { m_bAdjustScreen = false; if (config.frameBufferEmulation.enable) { switch (config.frameBufferEmulation.aspect) { case Config::aStretch: // stretch m_width = m_screenWidth; m_height = m_screenHeight; break; case Config::a43: // force 4/3 if (m_screenWidth * 3 / 4 > m_screenHeight) { m_height = m_screenHeight; m_width = m_screenHeight * 4 / 3; } else if (m_screenHeight * 4 / 3 > m_screenWidth) { m_width = m_screenWidth; m_height = m_screenWidth * 3 / 4; } else { m_width = m_screenWidth; m_height = m_screenHeight; } break; case Config::a169: // force 16/9 if (m_screenWidth * 9 / 16 > m_screenHeight) { m_height = m_screenHeight; m_width = m_screenHeight * 16 / 9; } else if (m_screenHeight * 16 / 9 > m_screenWidth) { m_width = m_screenWidth; m_height = m_screenWidth * 9 / 16; } else { m_width = m_screenWidth; m_height = m_screenHeight; } break; case Config::aAdjust: // adjust m_width = m_screenWidth; m_height = m_screenHeight; if (m_screenWidth * 3 / 4 > m_screenHeight) { f32 width43 = m_screenHeight * 4.0f / 3.0f; m_adjustScale = width43 / m_screenWidth; m_bAdjustScreen = true; } break; default: assert(false && "Unknown aspect ratio"); m_width = m_screenWidth; m_height = m_screenHeight; } } else { m_width = m_screenWidth; m_height = m_screenHeight; } } void OGLVideo::readScreen(void **_pDest, long *_pWidth, long *_pHeight ) { *_pWidth = m_width; *_pHeight = m_height; *_pDest = malloc( m_height * m_width * 3 ); if (*_pDest == NULL) return; #ifndef GLESX const GLenum format = GL_BGR_EXT; glReadBuffer( GL_FRONT ); #else const GLenum format = GL_RGB; #endif glReadPixels( 0, m_heightOffset, m_width, m_height, format, GL_UNSIGNED_BYTE, *_pDest ); } void OGLVideo::readScreen2(void * _dest, int * _width, int * _height, int _front) { if (_width == NULL || _height == NULL) return; *_width = m_screenWidth; *_height = m_screenHeight; if (_dest == NULL) return; #ifndef GLES2 GLint oldMode; glGetIntegerv(GL_READ_BUFFER, &oldMode); if (_front != 0) glReadBuffer(GL_FRONT); else glReadBuffer(GL_BACK); glReadPixels(0, m_heightOffset, m_screenWidth, m_screenHeight, GL_RGB, GL_UNSIGNED_BYTE, _dest); glReadBuffer(oldMode); #else glReadPixels(0, m_heightOffset, m_screenWidth, m_screenHeight, GL_RGB, GL_UNSIGNED_BYTE, _dest); #endif } void OGLRender::addTriangle(int _v0, int _v1, int _v2) { triangles.elements[triangles.num++] = _v0; triangles.elements[triangles.num++] = _v1; triangles.elements[triangles.num++] = _v2; if ((gSP.geometryMode & G_SHADE) == 0) { // Prim shading for (u32 i = triangles.num - 3; i < triangles.num; ++i) { SPVertex & vtx = triangles.vertices[triangles.elements[i]]; vtx.flat_r = gDP.primColor.r; vtx.flat_g = gDP.primColor.g; vtx.flat_b = gDP.primColor.b; vtx.flat_a = gDP.primColor.a; } } else if ((gSP.geometryMode & G_SHADING_SMOOTH) == 0) { // Flat shading SPVertex & vtx0 = triangles.vertices[_v0]; for (u32 i = triangles.num - 3; i < triangles.num; ++i) { SPVertex & vtx = triangles.vertices[triangles.elements[i]]; vtx.flat_r = vtx0.r; vtx.flat_g = vtx0.g; vtx.flat_b = vtx0.b; vtx.flat_a = vtx0.a; } } if (gDP.otherMode.depthSource == G_ZS_PRIM) { for (u32 i = triangles.num - 3; i < triangles.num; ++i) { SPVertex & vtx = triangles.vertices[triangles.elements[i]]; vtx.z = gDP.primDepth.z * vtx.w; } } #ifdef GLESX if (GBI.isNoN() && gDP.otherMode.depthCompare == 0 && gDP.otherMode.depthUpdate == 0) { for (u32 i = triangles.num - 3; i < triangles.num; ++i) { SPVertex & vtx = triangles.vertices[triangles.elements[i]]; vtx.z = 0.0f; } } #endif } void OGLRender::_setBlendMode() const { const u32 blendmode = gDP.otherMode.l >> 16; // 0x7000 = CVG_X_ALPHA|ALPHA_CVG_SEL|FORCE_BL if (gDP.otherMode.alphaCvgSel != 0 && (gDP.otherMode.l & 0x7000) != 0x7000) { switch (blendmode) { case 0x4055: // Mario Golf case 0x5055: // Paper Mario intro clr_mem * a_in + clr_mem * a_mem glEnable(GL_BLEND); glBlendFunc(GL_ZERO, GL_ONE); break; default: glDisable(GL_BLEND); } return; } if (gDP.otherMode.forceBlender != 0 && gDP.otherMode.cycleType < G_CYC_COPY) { glEnable( GL_BLEND ); switch (blendmode) { // Mace objects case 0x0382: // Mace special blend mode, see GLSLCombiner.cpp case 0x0091: // 1080 Sky case 0x0C08: // Used LOTS of places case 0x0F0A: //DK64 blue prints case 0x0302: // Bomberman 2 special blend mode, see GLSLCombiner.cpp case 0xA500: //Sin and Punishment case 0xCB02: // Battlezone // clr_in * a + clr_in * (1-a) case 0xC800: // Conker BFD // clr_in * a_fog + clr_fog * (1-a) // clr_in * 0 + clr_in * 1 case 0x07C2: case 0x00C0: //ISS64 case 0xC302: // Donald Duck case 0xC702: glBlendFunc(GL_ONE, GL_ZERO); break; case 0x0F1A: if (gDP.otherMode.cycleType == G_CYC_1CYCLE) glBlendFunc(GL_ONE, GL_ZERO); else glBlendFunc(GL_ZERO, GL_ONE); break; //Space Invaders case 0x0448: // Add case 0x055A: glBlendFunc( GL_ONE, GL_ONE ); break; case 0xc712: // Pokemon Stadium? case 0xAF50: // LOT in Zelda: MM case 0x0F5A: // LOT in Zelda: MM case 0x0FA5: // Seems to be doing just blend color - maybe combiner can be used for this? case 0x5055: // Used in Paper Mario intro, I'm not sure if this is right... //clr_in * 0 + clr_mem * 1 glBlendFunc( GL_ZERO, GL_ONE ); break; case 0x5F50: //clr_mem * 0 + clr_mem * (1-a) glBlendFunc( GL_ZERO, GL_ONE_MINUS_SRC_ALPHA ); break; case 0xF550: //clr_fog * a_fog + clr_mem * (1-a) case 0x0150: // spiderman case 0x0550: // bomberman 64 case 0x0D18: //clr_in * a_fog + clr_mem * (1-a) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); break; case 0xC912: //40 winks, clr_in * a_fog + clr_mem * 1 glBlendFunc(GL_SRC_ALPHA, GL_ONE); break; case 0x0040: // Fzero case 0xC810: // Blends fog case 0x0C18: // Standard interpolated blend case 0x0050: // Standard interpolated blend case 0x0051: // Standard interpolated blend case 0x0055: // Used for antialiasing glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); break; case 0x0C19: // Used for antialiasing case 0xC811: // Blends fog glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA); break; case 0x5000: // V8 explosions glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA); break; default: //LOG(LOG_VERBOSE, "Unhandled blend mode=%x", gDP.otherMode.l >> 16); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); break; } } else if ((config.generalEmulation.hacks & hack_pilotWings) != 0 && (gDP.otherMode.l & 0x80) != 0) { //CLR_ON_CVG without FORCE_BL glEnable(GL_BLEND); glBlendFunc(GL_ZERO, GL_ONE); } else if ((config.generalEmulation.hacks & hack_blastCorps) != 0 && gSP.texture.on == 0 && currentCombiner()->usesTexture()) { // Blast Corps glEnable(GL_BLEND); glBlendFunc(GL_ZERO, GL_ONE); } else { glDisable( GL_BLEND ); } } void OGLRender::_updateCullFace() const { if (gSP.geometryMode & G_CULL_BOTH) { glEnable( GL_CULL_FACE ); if (gSP.geometryMode & G_CULL_BACK) glCullFace(GL_BACK); else glCullFace(GL_FRONT); } else glDisable( GL_CULL_FACE ); } inline float _adjustViewportX(f32 _X0) { const float halfX = gDP.colorImage.width / 2.0f; const float halfVP = gSP.viewport.width / 2.0f; return (_X0 + halfVP - halfX) * video().getAdjustScale() + halfX - halfVP; } void OGLRender::_updateViewport() const { OGLVideo & ogl = video(); FrameBuffer * pCurrentBuffer = frameBufferList().getCurrent(); if (pCurrentBuffer == NULL) { const f32 scaleX = ogl.getScaleX(); const f32 scaleY = ogl.getScaleY(); float Xf = gSP.viewport.vscale[0] < 0 ? (gSP.viewport.x + gSP.viewport.vscale[0] * 2.0f) : gSP.viewport.x; if (ogl.isAdjustScreen() && gSP.viewport.width < gDP.colorImage.width && gDP.colorImage.width > VI.width * 98 / 100) Xf = _adjustViewportX(Xf); const GLint X = (GLint)(Xf * scaleX); const GLint Y = gSP.viewport.vscale[1] < 0 ? (GLint)((gSP.viewport.y + gSP.viewport.vscale[1] * 2.0f) * scaleY) : (GLint)((VI.height - (gSP.viewport.y + gSP.viewport.height)) * scaleY); glViewport(X, Y + ogl.getHeightOffset(), max((GLint)(gSP.viewport.width * scaleX), 0), max((GLint)(gSP.viewport.height * scaleY), 0)); } else { const f32 scaleX = pCurrentBuffer->m_scaleX; const f32 scaleY = pCurrentBuffer->m_scaleY; float Xf = gSP.viewport.vscale[0] < 0 ? (gSP.viewport.x + gSP.viewport.vscale[0] * 2.0f) : gSP.viewport.x; if (ogl.isAdjustScreen() && gSP.viewport.width < gDP.colorImage.width && gDP.colorImage.width > VI.width * 98 / 100) Xf = _adjustViewportX(Xf); const GLint X = (GLint)(Xf * scaleX); const GLint Y = gSP.viewport.vscale[1] < 0 ? (GLint)((gSP.viewport.y + gSP.viewport.vscale[1] * 2.0f) * scaleY) : (GLint)((pCurrentBuffer->m_height - (gSP.viewport.y + gSP.viewport.height)) * scaleY); glViewport(X, Y, max((GLint)(gSP.viewport.width * scaleX), 0), max((GLint)(gSP.viewport.height * scaleY), 0)); } gSP.changed &= ~CHANGED_VIEWPORT; } inline void _adjustScissorX(f32 & _X0, f32 & _X1, float _scale) { const float halfX = gDP.colorImage.width / 2.0f; _X0 = (_X0 - halfX) * _scale + halfX; _X1 = (_X1 - halfX) * _scale + halfX; } void OGLRender::updateScissor(FrameBuffer * _pBuffer) const { OGLVideo & ogl = video(); f32 scaleX, scaleY; u32 heightOffset, screenHeight; if (_pBuffer == NULL) { scaleX = ogl.getScaleX(); scaleY = ogl.getScaleY(); heightOffset = ogl.getHeightOffset(); screenHeight = VI.height; } else { scaleX = _pBuffer->m_scaleX; scaleY = _pBuffer->m_scaleY; heightOffset = 0; screenHeight = (_pBuffer->m_height == 0) ? VI.height : _pBuffer->m_height; } float SX0 = gDP.scissor.ulx; float SX1 = gDP.scissor.lrx; if (ogl.isAdjustScreen() && gSP.viewport.width < gDP.colorImage.width && gDP.colorImage.width > VI.width * 98 / 100) _adjustScissorX(SX0, SX1, ogl.getAdjustScale()); glScissor((GLint)(SX0 * scaleX), (GLint)((screenHeight - gDP.scissor.lry) * scaleY + heightOffset), max((GLint)((SX1 - SX0) * scaleX), 0), max((GLint)((gDP.scissor.lry - gDP.scissor.uly) * scaleY), 0)); gDP.changed &= ~CHANGED_SCISSOR; } void OGLRender::_updateDepthUpdate() const { if (gDP.otherMode.depthUpdate != 0) glDepthMask( TRUE ); else glDepthMask( FALSE ); } void OGLRender::_updateStates(RENDER_STATE _renderState) const { OGLVideo & ogl = video(); CombinerInfo & cmbInfo = CombinerInfo::get(); cmbInfo.update(); if (gSP.changed & CHANGED_GEOMETRYMODE) { _updateCullFace(); gSP.changed &= ~CHANGED_GEOMETRYMODE; } if (config.frameBufferEmulation.N64DepthCompare) { glDisable( GL_DEPTH_TEST ); glDepthMask( FALSE ); } else if ((gDP.changed & (CHANGED_RENDERMODE | CHANGED_CYCLETYPE)) != 0) { if (((gSP.geometryMode & G_ZBUFFER) || gDP.otherMode.depthSource == G_ZS_PRIM) && gDP.otherMode.cycleType <= G_CYC_2CYCLE) { if (gDP.otherMode.depthCompare != 0) { switch (gDP.otherMode.depthMode) { case ZMODE_OPA: glDisable(GL_POLYGON_OFFSET_FILL); glDepthFunc(GL_LEQUAL); break; case ZMODE_INTER: glDisable(GL_POLYGON_OFFSET_FILL); glDepthFunc(GL_LEQUAL); break; case ZMODE_XLU: // Max || Infront; glDisable(GL_POLYGON_OFFSET_FILL); if (gDP.otherMode.depthSource == G_ZS_PRIM && gDP.primDepth.z == 1.0f) // Max glDepthFunc(GL_LEQUAL); else // Infront glDepthFunc(GL_LESS); break; case ZMODE_DEC: glEnable(GL_POLYGON_OFFSET_FILL); glDepthFunc(GL_LEQUAL); break; } } else { glDisable(GL_POLYGON_OFFSET_FILL); glDepthFunc(GL_ALWAYS); } _updateDepthUpdate(); glEnable(GL_DEPTH_TEST); #ifndef GLESX if (!GBI.isNoN()) glDisable(GL_DEPTH_CLAMP); #endif } else { glDisable(GL_DEPTH_TEST); #ifndef GLESX if (!GBI.isNoN()) glEnable(GL_DEPTH_CLAMP); #endif } } if (gDP.changed & CHANGED_SCISSOR) updateScissor(frameBufferList().getCurrent()); if (gSP.changed & CHANGED_VIEWPORT) _updateViewport(); if (gSP.changed & CHANGED_LIGHT) cmbInfo.updateLightParameters(); if ((gSP.changed & CHANGED_TEXTURE) || (gDP.changed & CHANGED_TILE) || (gDP.changed & CHANGED_TMEM) || cmbInfo.isChanged()) { //For some reason updating the texture cache on the first frame of LOZ:OOT causes a NULL Pointer exception... ShaderCombiner * pCurrentCombiner = cmbInfo.getCurrent(); if (pCurrentCombiner != NULL) { for (u32 t = 0; t < 2; ++t) { if (pCurrentCombiner->usesTile(t)) textureCache().update(t); else textureCache().activateDummy(t); } pCurrentCombiner->updateFBInfo(); } if (_renderState == rsTriangle || _renderState == rsLine) cmbInfo.updateTextureParameters(); gDP.changed &= ~(CHANGED_TILE | CHANGED_TMEM); gSP.changed &= ~(CHANGED_TEXTURE); } if ((gDP.changed & (CHANGED_RENDERMODE | CHANGED_CYCLETYPE))) { _setBlendMode(); gDP.changed &= ~(CHANGED_RENDERMODE | CHANGED_CYCLETYPE); } cmbInfo.updateParameters(_renderState); } void OGLRender::_setColorArray() const { if (currentCombiner()->usesShade()) glEnableVertexAttribArray(SC_COLOR); else glDisableVertexAttribArray(SC_COLOR); } void OGLRender::_setTexCoordArrays() const { if (m_renderState == rsTriangle) { glDisableVertexAttribArray(SC_TEXCOORD1); if (currentCombiner()->usesTexture()) glEnableVertexAttribArray(SC_TEXCOORD0); else glDisableVertexAttribArray(SC_TEXCOORD0); } else { if (currentCombiner()->usesTile(0)) glEnableVertexAttribArray(SC_TEXCOORD0); else glDisableVertexAttribArray(SC_TEXCOORD0); if (currentCombiner()->usesTile(1)) glEnableVertexAttribArray(SC_TEXCOORD1); else glDisableVertexAttribArray(SC_TEXCOORD1); } } void OGLRender::_prepareDrawTriangle(bool _dma) { #ifdef GL_IMAGE_TEXTURES_SUPPORT if (m_bImageTexture && config.frameBufferEmulation.N64DepthCompare != 0) glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); #endif // GL_IMAGE_TEXTURES_SUPPORT if (gSP.changed || gDP.changed) _updateStates(rsTriangle); const bool updateArrays = m_renderState != rsTriangle; if (updateArrays || CombinerInfo::get().isChanged()) { m_renderState = rsTriangle; _setColorArray(); _setTexCoordArrays(); } currentCombiner()->updateRenderState(); const bool updateColorArrays = m_bFlatColors != (!__RSP.bLLE && (gSP.geometryMode & G_SHADING_SMOOTH) == 0); if (updateColorArrays) m_bFlatColors = !m_bFlatColors; if (updateArrays) { SPVertex * pVtx = _dma ? triangles.dmaVertices.data() : &triangles.vertices[0]; glVertexAttribPointer(SC_POSITION, 4, GL_FLOAT, GL_FALSE, sizeof(SPVertex), &pVtx->x); if (m_bFlatColors) glVertexAttribPointer(SC_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(SPVertex), &pVtx->flat_r); else glVertexAttribPointer(SC_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(SPVertex), &pVtx->r); glVertexAttribPointer(SC_TEXCOORD0, 2, GL_FLOAT, GL_FALSE, sizeof(SPVertex), &pVtx->s); if (config.generalEmulation.enableHWLighting) { glEnableVertexAttribArray(SC_NUMLIGHTS); glVertexAttribPointer(SC_NUMLIGHTS, 1, GL_BYTE, GL_FALSE, sizeof(SPVertex), &pVtx->HWLight); } } else if (updateColorArrays) { SPVertex * pVtx = _dma ? triangles.dmaVertices.data() : &triangles.vertices[0]; if (m_bFlatColors) glVertexAttribPointer(SC_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(SPVertex), &pVtx->flat_r); else glVertexAttribPointer(SC_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(SPVertex), &pVtx->r); } } bool OGLRender::_canDraw() const { return config.frameBufferEmulation.enable == 0 || frameBufferList().getCurrent() != NULL; } void OGLRender::drawLLETriangle(u32 _numVtx) { if (_numVtx == 0 || !_canDraw()) return; gSP.changed &= ~CHANGED_GEOMETRYMODE; // Don't update cull mode _prepareDrawTriangle(false); glDisable(GL_CULL_FACE); OGLVideo & ogl = video(); FrameBuffer * pCurrentBuffer = frameBufferList().getCurrent(); if (pCurrentBuffer == NULL) glViewport( 0, ogl.getHeightOffset(), ogl.getScreenWidth(), ogl.getScreenHeight()); else glViewport(0, 0, pCurrentBuffer->m_width*pCurrentBuffer->m_scaleX, pCurrentBuffer->m_height*pCurrentBuffer->m_scaleY); const float scaleX = pCurrentBuffer != NULL ? 1.0f / pCurrentBuffer->m_width : VI.rwidth; const float scaleY = pCurrentBuffer != NULL ? 1.0f / pCurrentBuffer->m_height : VI.rheight; for (u32 i = 0; i < _numVtx; ++i) { SPVertex & vtx = triangles.vertices[i]; vtx.HWLight = 0; vtx.x = vtx.x * (2.0f * scaleX) - 1.0f; vtx.x *= vtx.w; vtx.y = vtx.y * (-2.0f * scaleY) + 1.0f; vtx.y *= vtx.w; vtx.z *= vtx.w; if (gDP.otherMode.texturePersp == 0) { vtx.s *= 2.0f; vtx.t *= 2.0f; } } glDrawArrays(GL_TRIANGLE_STRIP, 0, _numVtx); triangles.num = 0; frameBufferList().setBufferChanged(); gSP.changed |= CHANGED_VIEWPORT | CHANGED_GEOMETRYMODE; } void OGLRender::drawDMATriangles(u32 _numVtx) { if (_numVtx == 0 || !_canDraw()) return; _prepareDrawTriangle(true); glDrawArrays(GL_TRIANGLES, 0, _numVtx); } void OGLRender::drawTriangles() { if (triangles.num == 0 || !_canDraw()) { triangles.num = 0; return; } _prepareDrawTriangle(false); glDrawElements(GL_TRIANGLES, triangles.num, GL_UNSIGNED_BYTE, triangles.elements); triangles.num = 0; } void OGLRender::drawLine(int _v0, int _v1, float _width) { if (!_canDraw()) return; if (gSP.changed || gDP.changed) _updateStates(rsLine); if (m_renderState != rsLine || CombinerInfo::get().isChanged()) { _setColorArray(); glDisableVertexAttribArray(SC_TEXCOORD0); glDisableVertexAttribArray(SC_TEXCOORD1); glVertexAttribPointer(SC_POSITION, 4, GL_FLOAT, GL_FALSE, sizeof(SPVertex), &triangles.vertices[0].x); glVertexAttribPointer(SC_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(SPVertex), &triangles.vertices[0].r); _updateCullFace(); _updateViewport(); m_renderState = rsLine; } currentCombiner()->updateRenderState(); unsigned short elem[2]; elem[0] = _v0; elem[1] = _v1; glLineWidth(_width * video().getScaleX()); glDrawElements(GL_LINES, 2, GL_UNSIGNED_SHORT, elem); } void OGLRender::drawRect(int _ulx, int _uly, int _lrx, int _lry, float *_pColor) { if (!_canDraw()) return; gSP.changed &= ~CHANGED_GEOMETRYMODE; // Don't update cull mode if (gSP.changed || gDP.changed) _updateStates(rsRect); const bool updateArrays = m_renderState != rsRect; if (updateArrays || CombinerInfo::get().isChanged()) { m_renderState = rsRect; glDisableVertexAttribArray(SC_COLOR); glDisableVertexAttribArray(SC_TEXCOORD0); glDisableVertexAttribArray(SC_TEXCOORD1); } if (updateArrays) glVertexAttribPointer(SC_POSITION, 4, GL_FLOAT, GL_FALSE, sizeof(GLVertex), &m_rect[0].x); currentCombiner()->updateRenderState(); FrameBuffer * pCurrentBuffer = frameBufferList().getCurrent(); OGLVideo & ogl = video(); if (pCurrentBuffer == NULL) glViewport( 0, ogl.getHeightOffset(), ogl.getScreenWidth(), ogl.getScreenHeight()); else { glViewport(0, 0, pCurrentBuffer->m_width*pCurrentBuffer->m_scaleX, pCurrentBuffer->m_height*pCurrentBuffer->m_scaleY); } glDisable(GL_CULL_FACE); const float scaleX = pCurrentBuffer != NULL ? 1.0f / pCurrentBuffer->m_width : VI.rwidth; const float scaleY = pCurrentBuffer != NULL ? 1.0f / pCurrentBuffer->m_height : VI.rheight; const float Z = (gDP.otherMode.depthSource == G_ZS_PRIM) ? gDP.primDepth.z : gSP.viewport.nearz; const float W = 1.0f; m_rect[0].x = (float)_ulx * (2.0f * scaleX) - 1.0; m_rect[0].y = (float)_uly * (-2.0f * scaleY) + 1.0; m_rect[0].z = Z; m_rect[0].w = W; m_rect[1].x = (float)_lrx * (2.0f * scaleX) - 1.0; m_rect[1].y = m_rect[0].y; m_rect[1].z = Z; m_rect[1].w = W; m_rect[2].x = m_rect[0].x; m_rect[2].y = (float)_lry * (-2.0f * scaleY) + 1.0; m_rect[2].z = Z; m_rect[2].w = W; m_rect[3].x = m_rect[1].x; m_rect[3].y = m_rect[2].y; m_rect[3].z = Z; m_rect[3].w = W; if (ogl.isAdjustScreen() && (gDP.colorImage.width > VI.width * 98 / 100) && (_lrx - _ulx < VI.width * 9 / 10)) { const float scale = ogl.getAdjustScale(); for (u32 i = 0; i < 4; ++i) m_rect[i].x *= scale; } if (gDP.otherMode.cycleType == G_CYC_FILL) glVertexAttrib4fv(SC_COLOR, _pColor); else glVertexAttrib4f(SC_COLOR, 0.0f, 0.0f, 0.0f, 0.0f); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); gSP.changed |= CHANGED_GEOMETRYMODE | CHANGED_VIEWPORT; } static bool texturedRectShadowMap(const OGLRender::TexturedRectParams &) { FrameBuffer * pCurrentBuffer = frameBufferList().getCurrent(); if (pCurrentBuffer != NULL) { if (gDP.textureImage.size == 2 && gDP.textureImage.address >= gDP.depthImageAddress && gDP.textureImage.address < (gDP.depthImageAddress + gDP.colorImage.width*gDP.colorImage.width * 6 / 4)) { #ifdef GL_IMAGE_TEXTURES_SUPPORT pCurrentBuffer->m_pDepthBuffer->activateDepthBufferTexture(pCurrentBuffer); SetDepthFogCombiner(); #else return true; #endif } } return false; } static bool texturedRectDepthBufferCopy(const OGLRender::TexturedRectParams & _params) { // Copy one line from depth buffer into auxiliary color buffer with height = 1. // Data from depth buffer loaded into TMEM and then rendered to RDRAM by texrect. // Works only with depth buffer emulation enabled. // Load of arbitrary data to that area causes weird camera rotation in CBFD. static u32 lastDList = 0xFFFFFFFF; const gDPTile * pTile = gSP.textureTile[0]; if (pTile->loadType == LOADTYPE_BLOCK && gDP.textureImage.size == 2 && gDP.textureImage.address >= gDP.depthImageAddress && gDP.textureImage.address < (gDP.depthImageAddress + gDP.colorImage.width*gDP.colorImage.width * 6 / 4)) { if (config.frameBufferEmulation.copyDepthToRDRAM == 0) return true; FrameBuffer * pBuffer = frameBufferList().getCurrent(); if (pBuffer == NULL) return true; pBuffer->m_cleared = true; if (lastDList != video().getBuffersSwapCount()) { lastDList = video().getBuffersSwapCount(); if (!FrameBuffer_CopyDepthBuffer(gDP.colorImage.address)) return true; } RDP_RepeatLastLoadBlock(); const u32 width = (u32)(_params.lrx - _params.ulx); const u32 ulx = (u32)_params.ulx; u16 * pSrc = ((u16*)TMEM) + (u32)floorf(_params.uls + 0.5f); u16 *pDst = (u16*)(gfx_info.RDRAM + gDP.colorImage.address); for (u32 x = 0; x < width; ++x) pDst[(ulx + x) ^ 1] = swapword(pSrc[x]); return true; } return false; } static bool texturedRectCopyToItself(const OGLRender::TexturedRectParams & _params) { FrameBuffer * pCurrent = frameBufferList().getCurrent(); if (pCurrent != NULL && pCurrent->m_size == G_IM_SIZ_8b && gSP.textureTile[0]->frameBuffer == pCurrent) return true; return texturedRectDepthBufferCopy(_params); } static bool texturedRectBGCopy(const OGLRender::TexturedRectParams & _params) { if (GBI.getMicrocodeType() != S2DEX) return false; float flry = _params.lry; if (flry > gDP.scissor.lry) flry = gDP.scissor.lry; const u32 width = (u32)(_params.lrx - _params.ulx); const u32 tex_width = gSP.textureTile[0]->line << 3; const u32 uly = (u32)_params.uly; const u32 lry = flry; u8 * texaddr = gfx_info.RDRAM + gDP.loadInfo[gSP.textureTile[0]->tmem].texAddress + tex_width*(u32)_params.ult + (u32)_params.uls; u8 * fbaddr = gfx_info.RDRAM + gDP.colorImage.address + (u32)_params.ulx; // LOG(LOG_VERBOSE, "memrect (%d, %d, %d, %d), ci_width: %d texaddr: 0x%08lx fbaddr: 0x%08lx\n", (u32)_params.ulx, uly, (u32)_params.lrx, lry, gDP.colorImage.width, gSP.textureTile[0]->imageAddress + tex_width*(u32)_params.ult + (u32)_params.uls, gDP.colorImage.address + (u32)_params.ulx); for (u32 y = uly; y < lry; ++y) { u8 *src = texaddr + (y - uly) * tex_width; u8 *dst = fbaddr + y * gDP.colorImage.width; memcpy(dst, src, width); } frameBufferList().removeBuffer(gDP.colorImage.address); return true; } static bool texturedRectPaletteMod(const OGLRender::TexturedRectParams & _params) { if (gDP.scissor.lrx != 16 || gDP.scissor.lry != 1 || _params.lrx != 16 || _params.lry != 1) return false; u8 envr = (u8)(gDP.envColor.r * 31.0f); u8 envg = (u8)(gDP.envColor.g * 31.0f); u8 envb = (u8)(gDP.envColor.b * 31.0f); u16 env16 = (u16)((envr << 11) | (envg << 6) | (envb << 1) | 1); u8 prmr = (u8)(gDP.primColor.r * 31.0f); u8 prmg = (u8)(gDP.primColor.g * 31.0f); u8 prmb = (u8)(gDP.primColor.b * 31.0f); u16 prim16 = (u16)((prmr << 11) | (prmg << 6) | (prmb << 1) | 1); u16 * src = (u16*)&TMEM[256]; u16 * dst = (u16*)(gfx_info.RDRAM + gDP.colorImage.address); for (u32 i = 0; i < 16; ++i) dst[i ^ 1] = (src[i<<2] & 0x100) ? prim16 : env16; return true; } static bool texturedRectMonochromeBackground(const OGLRender::TexturedRectParams & _params) { if (gDP.textureImage.address >= gDP.colorImage.address && gDP.textureImage.address <= (gDP.colorImage.address + gDP.colorImage.width*gDP.colorImage.height * 2)) { #ifdef GL_IMAGE_TEXTURES_SUPPORT FrameBuffer * pCurrentBuffer = frameBufferList().getCurrent(); if (pCurrentBuffer != NULL) { FrameBuffer_ActivateBufferTexture(0, pCurrentBuffer); SetMonochromeCombiner(); return false; } else #endif return true; } return false; } // Special processing of textured rect. // Return true if actuial rendering is not necessary bool(*texturedRectSpecial)(const OGLRender::TexturedRectParams & _params) = NULL; void OGLRender::drawTexturedRect(const TexturedRectParams & _params) { gSP.changed &= ~CHANGED_GEOMETRYMODE; // Don't update cull mode if (gSP.changed || gDP.changed) _updateStates(rsTexRect); const bool updateArrays = m_renderState != rsTexRect; if (updateArrays || CombinerInfo::get().isChanged()) { m_renderState = rsTexRect; glDisableVertexAttribArray(SC_COLOR); _setTexCoordArrays(); } if (updateArrays) { #ifdef RENDERSTATE_TEST StateChanges++; #endif glVertexAttrib4f(SC_COLOR, 0, 0, 0, 1); glVertexAttribPointer(SC_POSITION, 4, GL_FLOAT, GL_FALSE, sizeof(GLVertex), &m_rect[0].x); glVertexAttribPointer(SC_TEXCOORD0, 2, GL_FLOAT, GL_FALSE, sizeof(GLVertex), &m_rect[0].s0); glVertexAttribPointer(SC_TEXCOORD1, 2, GL_FLOAT, GL_FALSE, sizeof(GLVertex), &m_rect[0].s1); } currentCombiner()->updateRenderState(); if (__RSP.cmd == 0xE4 && texturedRectSpecial != NULL && texturedRectSpecial(_params)) { gSP.changed |= CHANGED_GEOMETRYMODE; return; } if (!_canDraw()) return; FrameBuffer * pCurrentBuffer = frameBufferList().getCurrent(); OGLVideo & ogl = video(); if (pCurrentBuffer == NULL) glViewport( 0, ogl.getHeightOffset(), ogl.getScreenWidth(), ogl.getScreenHeight()); else glViewport(0, 0, pCurrentBuffer->m_width*pCurrentBuffer->m_scaleX, pCurrentBuffer->m_height*pCurrentBuffer->m_scaleY); glDisable( GL_CULL_FACE ); const float scaleX = pCurrentBuffer != NULL ? 1.0f / pCurrentBuffer->m_width : VI.rwidth; const float scaleY = pCurrentBuffer != NULL ? 1.0f / pCurrentBuffer->m_height : VI.rheight; const float Z = (gDP.otherMode.depthSource == G_ZS_PRIM) ? gDP.primDepth.z : gSP.viewport.nearz; const float W = 1.0f; m_rect[0].x = (float)_params.ulx * (2.0f * scaleX) - 1.0f; m_rect[0].y = (float)_params.uly * (-2.0f * scaleY) + 1.0f; m_rect[0].z = Z; m_rect[0].w = W; m_rect[1].x = (float)(_params.lrx) * (2.0f * scaleX) - 1.0f; m_rect[1].y = m_rect[0].y; m_rect[1].z = Z; m_rect[1].w = W; m_rect[2].x = m_rect[0].x; m_rect[2].y = (float)(_params.lry) * (-2.0f * scaleY) + 1.0f; m_rect[2].z = Z; m_rect[2].w = W; m_rect[3].x = m_rect[1].x; m_rect[3].y = m_rect[2].y; m_rect[3].z = Z; m_rect[3].w = W; TextureCache & cache = textureCache(); struct { float s0, t0, s1, t1; } texST[2] = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; //struct for texture coordinates for (u32 t = 0; t < 2; ++t) { if (currentCombiner()->usesTile(t) && cache.current[t] && gSP.textureTile[t]) { f32 shiftScaleS = 1.0f; f32 shiftScaleT = 1.0f; getTextureShiftScale(t, cache, shiftScaleS, shiftScaleT); if (_params.uls > _params.lrs) { texST[t].s0 = (_params.uls + 1.0f) * shiftScaleS - gSP.textureTile[t]->fuls; texST[t].s1 = _params.lrs * shiftScaleS - gSP.textureTile[t]->fuls; } else { texST[t].s0 = _params.uls * shiftScaleS - gSP.textureTile[t]->fuls; texST[t].s1 = (_params.lrs + 1.0f) * shiftScaleS - gSP.textureTile[t]->fuls; } if (_params.ult > _params.lrt) { texST[t].t0 = (_params.ult + 1.0f) * shiftScaleT - gSP.textureTile[t]->fult; texST[t].t1 = _params.lrt * shiftScaleT - gSP.textureTile[t]->fult; } else { texST[t].t0 = _params.ult * shiftScaleT - gSP.textureTile[t]->fult; texST[t].t1 = (_params.lrt + 1.0f) * shiftScaleT - gSP.textureTile[t]->fult; } if (cache.current[t]->frameBufferTexture) { texST[t].s0 = cache.current[t]->offsetS + texST[t].s0; texST[t].t0 = cache.current[t]->offsetT - texST[t].t0; texST[t].s1 = cache.current[t]->offsetS + texST[t].s1; texST[t].t1 = cache.current[t]->offsetT - texST[t].t1; } glActiveTexture(GL_TEXTURE0 + t); if ((cache.current[t]->mirrorS == 0 && cache.current[t]->maskS == 0 && texST[t].s0 < texST[t].s1 && texST[t].s0 >= 0.0 && texST[t].s1 <= (float)cache.current[t]->width) || (cache.current[t]->maskS == 0 && (texST[t].s0 < -1024.0f || texST[t].s1 > 1023.99f))) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); if (cache.current[t]->mirrorT == 0 && texST[t].t0 < texST[t].t1 && texST[t].t0 >= 0.0f && texST[t].t1 <= (float)cache.current[t]->height) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); texST[t].s0 *= cache.current[t]->scaleS; texST[t].t0 *= cache.current[t]->scaleT; texST[t].s1 *= cache.current[t]->scaleS; texST[t].t1 *= cache.current[t]->scaleT; } } if (gDP.otherMode.cycleType == G_CYC_COPY) { glActiveTexture( GL_TEXTURE0 ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); } m_rect[0].s0 = texST[0].s0; m_rect[0].t0 = texST[0].t0; m_rect[0].s1 = texST[1].s0; m_rect[0].t1 = texST[1].t0; m_rect[3].s0 = texST[0].s1; m_rect[3].t0 = texST[0].t1; m_rect[3].s1 = texST[1].s1; m_rect[3].t1 = texST[1].t1; if (_params.flip) { m_rect[1].s0 = texST[0].s0; m_rect[1].t0 = texST[0].t1; m_rect[1].s1 = texST[1].s0; m_rect[1].t1 = texST[1].t1; m_rect[2].s0 = texST[0].s1; m_rect[2].t0 = texST[0].t0; m_rect[2].s1 = texST[1].s1; m_rect[2].t1 = texST[1].t0; } else { m_rect[1].s0 = texST[0].s1; m_rect[1].t0 = texST[0].t0; m_rect[1].s1 = texST[1].s1; m_rect[1].t1 = texST[1].t0; m_rect[2].s0 = texST[0].s0; m_rect[2].t0 = texST[0].t1; m_rect[2].s1 = texST[1].s0; m_rect[2].t1 = texST[1].t1; } if (ogl.isAdjustScreen() && (gDP.colorImage.width > VI.width * 98 / 100) && (_params.lrx - _params.ulx < VI.width * 9 / 10)) { const float scale = ogl.getAdjustScale(); for (u32 i = 0; i < 4; ++i) m_rect[i].x *= scale; } glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); gSP.changed |= CHANGED_GEOMETRYMODE | CHANGED_VIEWPORT; } void OGLRender::drawText(const char *_pText, float x, float y) { m_renderState = rsNone; TextDrawer::get().renderText(_pText, x, y); } void OGLRender::clearDepthBuffer(u32 _uly, u32 _lry) { if (!_canDraw()) return; depthBufferList().clearBuffer(_uly, _lry); glDisable( GL_SCISSOR_TEST ); glDepthMask( TRUE ); glClear( GL_DEPTH_BUFFER_BIT ); _updateDepthUpdate(); glEnable( GL_SCISSOR_TEST ); } void OGLRender::clearColorBuffer(float *_pColor ) { if (!_canDraw()) return; glDisable(GL_SCISSOR_TEST); glClearColor( _pColor[0], _pColor[1], _pColor[2], _pColor[3] ); glClear( GL_COLOR_BUFFER_BIT ); glEnable( GL_SCISSOR_TEST ); } FBOTextureFormats fboFormats; void FBOTextureFormats::init() { #ifdef GLES2 monochromeInternalFormat = GL_RGB; monochromeFormat = GL_RGB; monochromeType = GL_UNSIGNED_SHORT_5_6_5; monochromeFormatBytes = 2; depthInternalFormat = GL_DEPTH_COMPONENT; depthFormat = GL_DEPTH_COMPONENT; depthType = GL_UNSIGNED_INT; depthFormatBytes = 4; if (OGLVideo::isExtensionSupported("GL_OES_rgb8_rgba8")) { colorInternalFormat = GL_RGBA; colorFormat = GL_RGBA; colorType = GL_UNSIGNED_BYTE; colorFormatBytes = 4; } else { colorInternalFormat = GL_RGB; colorFormat = GL_RGB; colorType = GL_UNSIGNED_SHORT_5_6_5; colorFormatBytes = 2; } #elif defined(GLES3) || defined (GLES3_1) colorInternalFormat = GL_RGBA; colorFormat = GL_RGBA; colorType = GL_UNSIGNED_BYTE; colorFormatBytes = 4; monochromeInternalFormat = GL_RED; monochromeFormat = GL_RED; monochromeType = GL_UNSIGNED_BYTE; monochromeFormatBytes = 1; depthInternalFormat = GL_DEPTH_COMPONENT32F; depthFormat = GL_DEPTH_COMPONENT; depthType = GL_FLOAT; depthFormatBytes = 4; depthImageInternalFormat = GL_RGBA32F; depthImageFormat = GL_RGBA; depthImageType = GL_FLOAT; depthImageFormatBytes = 16; lutInternalFormat = GL_R32UI; lutFormat = GL_RED; lutType = GL_UNSIGNED_INT; lutFormatBytes = 4; #else colorInternalFormat = GL_RGBA; colorFormat = GL_RGBA; colorType = GL_UNSIGNED_BYTE; colorFormatBytes = 4; monochromeInternalFormat = GL_RED; monochromeFormat = GL_RED; monochromeType = GL_UNSIGNED_BYTE; monochromeFormatBytes = 1; depthInternalFormat = GL_DEPTH_COMPONENT; depthFormat = GL_DEPTH_COMPONENT; depthType = GL_FLOAT; depthFormatBytes = 4; depthImageInternalFormat = GL_RG32F; depthImageFormat = GL_RG; depthImageType = GL_FLOAT; depthImageFormatBytes = 8; lutInternalFormat = GL_R16; lutFormat = GL_RED; lutType = GL_UNSIGNED_SHORT; lutFormatBytes = 2; #endif } void OGLRender::_initExtensions() { LOG(LOG_VERBOSE, "OpenGL version string: %s\n", glGetString(GL_VERSION)); LOG(LOG_VERBOSE, "OpenGL vendor: %s\n", glGetString(GL_VENDOR)); const GLubyte * strRenderer = glGetString(GL_RENDERER); if (strstr((const char*)strRenderer, "Adreno") != NULL) m_oglRenderer = glrAdreno; LOG(LOG_VERBOSE, "OpenGL renderer: %s\n", strRenderer); fboFormats.init(); #ifndef GLES2 GLint majorVersion = 0; glGetIntegerv(GL_MAJOR_VERSION, &majorVersion); LOG(LOG_VERBOSE, "OpenGL major version: %d\n", majorVersion); assert(majorVersion >= 3 && "Plugin requires GL version 3 or higher."); #endif #ifdef GL_IMAGE_TEXTURES_SUPPORT GLint minorVersion = 0; glGetIntegerv(GL_MINOR_VERSION, &minorVersion); LOG(LOG_VERBOSE, "OpenGL minor version: %d\n", minorVersion); #ifndef GLESX m_bImageTexture = (majorVersion >= 4) && (minorVersion >= 3) && (glBindImageTexture != NULL); #elif defined(GLES3_1) m_bImageTexture = (majorVersion >= 3) && (minorVersion >= 1) && (glBindImageTexture != NULL); #else m_bImageTexture = false; #endif #else m_bImageTexture = false; #endif LOG(LOG_VERBOSE, "ImageTexture support: %s\n", m_bImageTexture ? "yes" : "no"); if (config.texture.maxAnisotropy != 0 && OGLVideo::isExtensionSupported("GL_EXT_texture_filter_anisotropic")) { glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &config.texture.maxAnisotropyF); config.texture.maxAnisotropyF = min(config.texture.maxAnisotropyF, (f32)config.texture.maxAnisotropy); } else config.texture.maxAnisotropyF = 0.0f; LOG(LOG_VERBOSE, "Max Anisotropy: %f\n", config.texture.maxAnisotropyF); } void OGLRender::_initStates() { glDisable(GL_CULL_FACE); glEnableVertexAttribArray(SC_POSITION); glEnable( GL_DEPTH_TEST ); glDepthFunc( GL_ALWAYS ); glDepthMask( GL_FALSE ); glEnable( GL_SCISSOR_TEST ); if (config.frameBufferEmulation.N64DepthCompare != 0) { glDisable( GL_DEPTH_TEST ); glDisable( GL_POLYGON_OFFSET_FILL ); glDepthFunc( GL_ALWAYS ); glDepthMask( FALSE ); } else { #ifdef ANDROID if(config.generalEmulation.forcePolygonOffset != 0) glPolygonOffset(config.generalEmulation.polygonOffsetFactor, config.generalEmulation.polygonOffsetUnits); else #endif glPolygonOffset(-3.0f, -3.0f); } OGLVideo & ogl = video(); glViewport(0, ogl.getHeightOffset(), ogl.getScreenWidth(), ogl.getScreenHeight()); glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); glClear( GL_COLOR_BUFFER_BIT ); srand( time(NULL) ); ogl.swapBuffers(); } void OGLRender::_initData() { glState.reset(); _initExtensions(); _initStates(); _setSpecialTexrect(); textureCache().init(); DepthBuffer_Init(); FrameBuffer_Init(); Combiner_Init(); TextDrawer::get().init(); TFH.init(); PostProcessor::get().init(); m_renderState = rsNone; gSP.changed = gDP.changed = 0xFFFFFFFF; memset(triangles.vertices, 0, VERTBUFF_SIZE * sizeof(SPVertex)); memset(triangles.elements, 0, ELEMBUFF_SIZE * sizeof(GLubyte)); for (u32 i = 0; i < VERTBUFF_SIZE; ++i) triangles.vertices[i].w = 1.0f; triangles.num = 0; } void OGLRender::_destroyData() { m_renderState = rsNone; if (config.bloomFilter.enable != 0) PostProcessor::get().destroy(); if (TFH.optionsChanged()) TFH.shutdown(); TextDrawer::get().destroy(); Combiner_Destroy(); FrameBuffer_Destroy(); DepthBuffer_Destroy(); textureCache().destroy(); } void OGLRender::_setSpecialTexrect() const { const char * name = __RSP.romname; if (strstr(name, (const char *)"Beetle") || strstr(name, (const char *)"BEETLE") || strstr(name, (const char *)"HSV") || strstr(name, (const char *)"DUCK DODGERS") || strstr(name, (const char *)"DAFFY DUCK")) texturedRectSpecial = texturedRectShadowMap; else if (strstr(name, (const char *)"Perfect Dark") || strstr(name, (const char *)"PERFECT DARK")) texturedRectSpecial = texturedRectDepthBufferCopy; // See comments to that function! else if (strstr(name, (const char *)"CONKER BFD")) texturedRectSpecial = texturedRectCopyToItself; else if (strstr(name, (const char *)"YOSHI STORY")) texturedRectSpecial = texturedRectBGCopy; else if (strstr(name, (const char *)"PAPER MARIO") || strstr(name, (const char *)"MARIO STORY")) texturedRectSpecial = texturedRectPaletteMod; else if (strstr(name, (const char *)"ZELDA")) texturedRectSpecial = texturedRectMonochromeBackground; else texturedRectSpecial = NULL; } static u32 textureFilters[] = { NO_FILTER, //"None" SMOOTH_FILTER_1, //"Smooth filtering 1" SMOOTH_FILTER_2, //"Smooth filtering 2" SMOOTH_FILTER_3, //"Smooth filtering 3" SMOOTH_FILTER_4, //"Smooth filtering 4" SHARP_FILTER_1, //"Sharp filtering 1" SHARP_FILTER_2, //"Sharp filtering 2" }; static u32 textureEnhancements[] = { NO_ENHANCEMENT, //"None" NO_ENHANCEMENT, //"Store" X2_ENHANCEMENT, //"X2" X2SAI_ENHANCEMENT, //"X2SAI" HQ2X_ENHANCEMENT, //"HQ2X" HQ2XS_ENHANCEMENT, //"HQ2XS" LQ2X_ENHANCEMENT, //"LQ2X" LQ2XS_ENHANCEMENT, //"LQ2XS" HQ4X_ENHANCEMENT, //"HQ4X" BRZ2X_ENHANCEMENT, //"2XBRZ" BRZ3X_ENHANCEMENT, //"3XBRZ" BRZ4X_ENHANCEMENT, //"4XBRZ" BRZ5X_ENHANCEMENT, //"5XBRZ" BRZ6X_ENHANCEMENT //"6XBRZ" }; void displayLoadProgress(const wchar_t *format, ...) { va_list args; wchar_t wbuf[INFO_BUF]; char buf[INFO_BUF]; // process input #ifdef ANDROID const u32 bufSize = 2048; char cbuf[bufSize]; char fmt[bufSize]; wcstombs(fmt, format, bufSize); va_start(args, format); vsprintf(cbuf, fmt, args); va_end(args); mbstowcs(wbuf, cbuf, INFO_BUF); #else va_start(args, format); vswprintf(wbuf, INFO_BUF, format, args); va_end(args); #endif // XXX: convert to multibyte wcstombs(buf, wbuf, INFO_BUF); FrameBuffer* pBuffer = frameBufferList().getCurrent(); if (pBuffer != NULL) glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); OGLRender & render = video().getRender(); float black[4] = {0, 0, 0, 0}; render.clearColorBuffer(black); render.drawText(buf, -0.9f, 0); video().swapBuffers(); if (pBuffer != NULL) glBindFramebuffer(GL_DRAW_FRAMEBUFFER, pBuffer->m_FBO); } u32 TextureFilterHandler::_getConfigOptions() const { u32 options = textureFilters[config.textureFilter.txFilterMode] | textureEnhancements[config.textureFilter.txEnhancementMode]; if (config.textureFilter.txHiresEnable) options |= RICE_HIRESTEXTURES; if (config.textureFilter.txForce16bpp) options |= FORCE16BPP_TEX | FORCE16BPP_HIRESTEX; if (config.textureFilter.txCacheCompression) options |= GZ_TEXCACHE | GZ_HIRESTEXCACHE; if (config.textureFilter.txSaveCache) options |= (DUMP_TEXCACHE | DUMP_HIRESTEXCACHE); if (config.textureFilter.txHiresFullAlphaChannel) options |= LET_TEXARTISTS_FLY; if (config.textureFilter.txDump) options |= DUMP_TEX; return options; } void TextureFilterHandler::init() { if (isInited()) return; m_inited = config.textureFilter.txFilterMode | config.textureFilter.txEnhancementMode | config.textureFilter.txHiresEnable; if (m_inited == 0) return; m_options = _getConfigOptions(); GLint maxTextureSize; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); wchar_t wRomName[32]; ::mbstowcs(wRomName, __RSP.romname, 32); wchar_t txPath[PLUGIN_PATH_SIZE + 16]; wchar_t * pTexPackPath = config.textureFilter.txPath; if (::wcslen(config.textureFilter.txPath) == 0) { api().GetUserDataPath(txPath); gln_wcscat(txPath, wst("/hires_texture")); pTexPackPath = txPath; } wchar_t txCachePath[PLUGIN_PATH_SIZE]; api().GetUserCachePath(txCachePath); m_inited = txfilter_init(maxTextureSize, // max texture width supported by hardware maxTextureSize, // max texture height supported by hardware 32, // max texture bpp supported by hardware m_options, config.textureFilter.txCacheSize, // cache texture to system memory txCachePath, // path to store cache files pTexPackPath, // path to texture packs folder wRomName, // name of ROM. must be no longer than 256 characters displayLoadProgress); } void TextureFilterHandler::shutdown() { if (isInited()) { txfilter_shutdown(); m_inited = m_options = 0; } } TextureFilterHandler TFH; mupen64plus-core/src/api/debugger.h000664 001750 001750 00000004163 12655644434 020350 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-core - api/debugger.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2009 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file contains the definitions for debugger functions which will be * called from the other Core modules */ #ifndef API_DEBUGGER_H #define API_DEBUGGER_H #include "m64p_types.h" /* Debugger Definitions */ typedef enum { DEBUG_UI_INIT = 1, DEBUG_UI_UPDATE, DEBUG_UI_VI, DEBUG_CORE_COMPARE } eDbgCallbackType; /* Functions for use by the Core, to send information back to the front-end app */ extern void DebuggerCallback(eDbgCallbackType type, unsigned int param); extern void CoreCompareCallback(void); extern void CoreCompareDataSync(int length, void *ptr); #endif /* API_DEBUGGER_H */ mupen64plus-core/src/r4300/hacktarux_dynarec/interpret.h000664 001750 001750 00000016400 12655644434 024273 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - interpret.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2007 Richard Goedeken (Richard42) * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef __INTERPRET_H__ #define __INTERPRET_H__ //#define INTERPRET_J //#define INTERPRET_J_OUT //#define INTERPRET_J_IDLE //#define INTERPRET_JAL //#define INTERPRET_JAL_OUT //#define INTERPRET_JAL_IDLE //#define INTERPRET_BEQ //#define INTERPRET_BEQ_OUT //#define INTERPRET_BEQ_IDLE //#define INTERPRET_BNE //#define INTERPRET_BNE_OUT //#define INTERPRET_BNE_IDLE //#define INTERPRET_BLEZ //#define INTERPRET_BLEZ_OUT //#define INTERPRET_BLEZ_IDLE //#define INTERPRET_BGTZ //#define INTERPRET_BGTZ_OUT //#define INTERPRET_BGTZ_IDLE //#define INTERPRET_ADDI //#define INTERPRET_ADDIU //#define INTERPRET_SLTI //#define INTERPRET_SLTIU //#define INTERPRET_ANDI //#define INTERPRET_ORI //#define INTERPRET_XORI //#define INTERPRET_LUI //#define INTERPRET_BEQL //#define INTERPRET_BEQL_OUT //#define INTERPRET_BEQL_IDLE //#define INTERPRET_BNEL //#define INTERPRET_BNEL_OUT //#define INTERPRET_BNEL_IDLE //#define INTERPRET_BLEZL //#define INTERPRET_BLEZL_OUT //#define INTERPRET_BLEZL_IDLE //#define INTERPRET_BGTZL //#define INTERPRET_BGTZL_OUT //#define INTERPRET_BGTZL_IDLE //#define INTERPRET_DADDI //#define INTERPRET_DADDIU //#define INTERPRET_LB //#define INTERPRET_LH //#define INTERPRET_LW //#define INTERPRET_LBU //#define INTERPRET_LHU //#define INTERPRET_LWU //#define INTERPRET_SB //#define INTERPRET_SH //#define INTERPRET_SW //#define INTERPRET_LWC1 //#define INTERPRET_LDC1 //#define INTERPRET_LD //#define INTERPRET_SWC1 //#define INTERPRET_SDC1 //#define INTERPRET_SD //#define INTERPRET_SLL //#define INTERPRET_SRL //#define INTERPRET_SRA //#define INTERPRET_SLLV //#define INTERPRET_SRLV //#define INTERPRET_SRAV //#define INTERPRET_JR //#define INTERPRET_JALR //#define INTERPRET_SYSCALL //#define INTERPRET_MFHI //#define INTERPRET_MTHI //#define INTERPRET_MFLO //#define INTERPRET_MTLO //#define INTERPRET_DSLLV //#define INTERPRET_DSRLV //#define INTERPRET_DSRAV //#define INTERPRET_MULT //#define INTERPRET_MULTU //#define INTERPRET_DIV //#define INTERPRET_DIVU //#define INTERPRET_DMULTU //#define INTERPRET_ADD //#define INTERPRET_ADDU //#define INTERPRET_SUB //#define INTERPRET_SUBU //#define INTERPRET_AND //#define INTERPRET_OR //#define INTERPRET_XOR //#define INTERPRET_NOR //#define INTERPRET_SLT //#define INTERPRET_SLTU //#define INTERPRET_DADD //#define INTERPRET_DADDU //#define INTERPRET_DSUB //#define INTERPRET_DSUBU //#define INTERPRET_DSLL //#define INTERPRET_DSRL //#define INTERPRET_DSRA //#define INTERPRET_DSLL32 //#define INTERPRET_DSRL32 //#define INTERPRET_DSRA32 //#define INTERPRET_BLTZ //#define INTERPRET_BLTZ_OUT //#define INTERPRET_BLTZ_IDLE //#define INTERPRET_BGEZ //#define INTERPRET_BGEZ_OUT //#define INTERPRET_BGEZ_IDLE //#define INTERPRET_BLTZL //#define INTERPRET_BLTZL_OUT //#define INTERPRET_BLTZL_IDLE //#define INTERPRET_BGEZL //#define INTERPRET_BGEZL_OUT //#define INTERPRET_BGEZL_IDLE //#define INTERPRET_BLTZAL //#define INTERPRET_BLTZAL_OUT //#define INTERPRET_BLTZAL_IDLE //#define INTERPRET_BGEZAL //#define INTERPRET_BGEZAL_OUT //#define INTERPRET_BGEZAL_IDLE //#define INTERPRET_BLTZALL //#define INTERPRET_BLTZALL_OUT //#define INTERPRET_BLTZALL_IDLE //#define INTERPRET_BGEZALL //#define INTERPRET_BGEZALL_OUT //#define INTERPRET_BGEZALL_IDLE //#define INTERPRET_BC1F //#define INTERPRET_BC1F_OUT //#define INTERPRET_BC1F_IDLE //#define INTERPRET_BC1T //#define INTERPRET_BC1T_OUT //#define INTERPRET_BC1T_IDLE //#define INTERPRET_BC1FL //#define INTERPRET_BC1FL_OUT //#define INTERPRET_BC1FL_IDLE //#define INTERPRET_BC1TL //#define INTERPRET_BC1TL_OUT //#define INTERPRET_BC1TL_IDLE //#define INTERPRET_MFC1 //#define INTERPRET_DMFC1 //#define INTERPRET_CFC1 //#define INTERPRET_MTC1 //#define INTERPRET_DMTC1 //#define INTERPRET_CTC1 //#define INTERPRET_ADD_D //#define INTERPRET_SUB_D //#define INTERPRET_MUL_D //#define INTERPRET_DIV_D //#define INTERPRET_SQRT_D //#define INTERPRET_ABS_D //#define INTERPRET_MOV_D //#define INTERPRET_NEG_D //#define INTERPRET_ROUND_L_D //#define INTERPRET_TRUNC_L_D //#define INTERPRET_CEIL_L_D //#define INTERPRET_FLOOR_L_D //#define INTERPRET_ROUND_W_D //#define INTERPRET_TRUNC_W_D //#define INTERPRET_CEIL_W_D //#define INTERPRET_FLOOR_W_D //#define INTERPRET_CVT_S_D //#define INTERPRET_CVT_W_D //#define INTERPRET_CVT_L_D //#define INTERPRET_C_F_D //#define INTERPRET_C_UN_D //#define INTERPRET_C_EQ_D //#define INTERPRET_C_UEQ_D //#define INTERPRET_C_OLT_D //#define INTERPRET_C_ULT_D //#define INTERPRET_C_OLE_D //#define INTERPRET_C_ULE_D //#define INTERPRET_C_SF_D //#define INTERPRET_C_NGLE_D //#define INTERPRET_C_SEQ_D //#define INTERPRET_C_NGL_D //#define INTERPRET_C_LT_D //#define INTERPRET_C_NGE_D //#define INTERPRET_C_LE_D //#define INTERPRET_C_NGT_D //#define INTERPRET_CVT_S_L //#define INTERPRET_CVT_D_L //#define INTERPRET_CVT_S_W //#define INTERPRET_CVT_D_W //#define INTERPRET_ADD_S //#define INTERPRET_SUB_S //#define INTERPRET_MUL_S //#define INTERPRET_DIV_S //#define INTERPRET_SQRT_S //#define INTERPRET_ABS_S //#define INTERPRET_MOV_S //#define INTERPRET_NEG_S //#define INTERPRET_ROUND_L_S //#define INTERPRET_TRUNC_L_S //#define INTERPRET_CEIL_L_S //#define INTERPRET_FLOOR_L_S //#define INTERPRET_ROUND_W_S //#define INTERPRET_TRUNC_W_S //#define INTERPRET_CEIL_W_S //#define INTERPRET_FLOOR_W_S //#define INTERPRET_CVT_D_S //#define INTERPRET_CVT_W_S //#define INTERPRET_CVT_L_S //#define INTERPRET_C_F_S //#define INTERPRET_C_UN_S //#define INTERPRET_C_EQ_S //#define INTERPRET_C_UEQ_S //#define INTERPRET_C_OLT_S //#define INTERPRET_C_ULT_S //#define INTERPRET_C_OLE_S //#define INTERPRET_C_ULE_S //#define INTERPRET_C_SF_S //#define INTERPRET_C_NGLE_S //#define INTERPRET_C_SEQ_S //#define INTERPRET_C_NGL_S //#define INTERPRET_C_LT_S //#define INTERPRET_C_NGE_S //#define INTERPRET_C_LE_S //#define INTERPRET_C_NGT_S #endif /* __INTERPRET_H__ */ gles2n64/src/F3DDKR.c000664 001750 001750 00000010111 12655644434 015125 0ustar00sergiosergio000000 000000 #include "gles2N64.h" #include "Debug.h" #include "F3D.h" #include "F3DDKR.h" #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gSP.h" #include "gDP.h" #include "GBI.h" #include "OpenGL.h" void F3DDKR_DMA_Mtx( u32 w0, u32 w1 ) { u32 index, multiply; if (_SHIFTR( w0, 0, 16 ) != 64) { #ifdef DEBUG DebugMsg( DEBUG_MEDIUM | DEBUG_HIGH | DEBUG_ERROR, "G_MTX: address = 0x%08X length = %i params = 0x%02X\n", w1, _SHIFTR( w0, 0, 16 ), _SHIFTR( w0, 16, 8 ) ); #endif return; } index = _SHIFTR( w0, 16, 4 ); if (index == 0) // DKR { index = _SHIFTR( w0, 22, 2 ); multiply = 0; } else // Gemini { multiply = _SHIFTR( w0, 23, 1 ); } gSPDMAMatrix( w1, index, multiply ); } void F3DDKR_DMA_Vtx( u32 w0, u32 w1 ) { u32 n; if ((w0 & F3DDKR_VTX_APPEND)) { if (gSP.matrix.billboard) gSP.vertexi = 1; } else gSP.vertexi = 0; n = _SHIFTR( w0, 19, 5 ) + 1; gSPDMAVertex( w1, n, gSP.vertexi + _SHIFTR( w0, 9, 5 ) ); gSP.vertexi += n; } void F3DJFG_DMA_Vtx(u32 w0, u32 w1) { u32 n; if ((w0 & F3DDKR_VTX_APPEND)) { if (gSP.matrix.billboard) gSP.vertexi = 1; } else gSP.vertexi = 0; n = _SHIFTR(w0, 19, 5); gSPDMAVertex(w1, n, gSP.vertexi + _SHIFTR(w0, 9, 5)); gSP.vertexi += n; } void F3DDKR_DMA_Tri( u32 w0, u32 w1 ) { gSPDMATriangles( w1, _SHIFTR( w0, 4, 12 ) ); gSP.vertexi = 0; } void F3DDKR_DMA_DList( u32 w0, u32 w1 ) { gSPDlistCount(_SHIFTR(w0, 16, 8), w1); } void F3DDKR_DMA_Offsets( u32 w0, u32 w1 ) { gSPSetDMAOffsets( _SHIFTR( w0, 0, 24 ), _SHIFTR( w1, 0, 24 ) ); } void F3DDKR_DMA_Tex_Offset(u32 w0, u32 w1) { gSPSetDMATexOffset(w1); } void F3DDKR_MoveWord( u32 w0, u32 w1 ) { switch (_SHIFTR( w0, 0, 8 )) { case 0x02: gSP.matrix.billboard = w1 & 1; break; case 0x0A: gSP.matrix.modelViewi = _SHIFTR( w1, 6, 2 ); gSP.changed |= CHANGED_MATRIX; break; default: F3D_MoveWord( w0, w1 ); break; } } void F3DDKR_Init(void) { gSPSetupFunctions(); // Set GeometryMode flags GBI_InitFlags( F3D ); GBI.PCStackSize = 10; // GBI Command Command Value Command Function GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_DMA_MTX, F3DDKR_DMA_MTX, F3DDKR_DMA_Mtx ); GBI_SetGBI( G_DMA_TEX_OFFSET, F3DDKR_DMA_TEX_OFFSET, F3DDKR_DMA_Tex_Offset ); GBI_SetGBI( G_MOVEMEM, F3D_MOVEMEM, F3D_MoveMem ); GBI_SetGBI( G_DMA_VTX, F3DDKR_DMA_VTX, F3DDKR_DMA_Vtx ); GBI_SetGBI( G_DL, F3D_DL, F3D_DList ); GBI_SetGBI( G_DMA_DL, F3DDKR_DMA_DL, F3DDKR_DMA_DList ); GBI_SetGBI( G_DMA_TRI, F3DDKR_DMA_TRI, F3DDKR_DMA_Tri ); GBI_SetGBI( G_DMA_OFFSETS, F3DDKR_DMA_OFFSETS, F3DDKR_DMA_Offsets ); GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3D_CullDL ); GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3DDKR_MoveWord ); GBI_SetGBI( G_TEXTURE, F3D_TEXTURE, F3D_Texture ); GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L ); GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL ); GBI_SetGBI( G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, F3D_SetGeometryMode ); GBI_SetGBI( G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE, F3D_ClearGeometryMode ); GBI_SetGBI( G_QUAD, F3D_QUAD, F3D_Quad ); GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_RDPHALF_CONT, F3D_RDPHALF_CONT, F3D_RDPHalf_Cont ); GBI_SetGBI( G_TRI4, F3D_TRI4, F3D_Tri4 ); gSPSetDMAOffsets( 0, 0 ); } void F3DJFG_Init(void) { F3DDKR_Init(); GBI_SetGBI(G_DMA_VTX, F3DDKR_DMA_VTX, F3DJFG_DMA_Vtx); } mupen64plus-core/src/api/debugger.c000664 001750 001750 00000030162 12655644434 020341 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-core - api/debugger.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2009 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file contains the Core debugger functions which will be exported * outside of the core library. */ #include #define M64P_CORE_PROTOTYPES 1 #include "m64p_types.h" #include "m64p_debugger.h" #include "callbacks.h" #include "debugger.h" #include "../ai/ai_controller.h" #include "debugger/dbg_types.h" #include "debugger/dbg_breakpoints.h" #include "debugger/dbg_decoder.h" #include "debugger/dbg_memory.h" #include "debugger/debugger.h" #include "main/main.h" #include "memory/memory.h" #include "../pi/pi_controller.h" #include "r4300/r4300_core.h" #include "../ri/ri_controller.h" #include "../vi/vi_controller.h" extern unsigned int op_R4300; /* this is in r4300/pure_interp.c */ /* local variables */ static void (*callback_ui_init)(void) = NULL; static void (*callback_ui_update)(unsigned int) = NULL; static void (*callback_ui_vi)(void) = NULL; static void (*callback_core_compare)(unsigned int) = NULL; static void (*callback_core_data_sync)(int, void *) = NULL; /* global Functions for use by the Core */ void DebuggerCallback(eDbgCallbackType type, unsigned int param) { if (type == DEBUG_UI_INIT) { if (callback_ui_init != NULL) (*callback_ui_init)(); } else if (type == DEBUG_UI_UPDATE) { if (callback_ui_update != NULL) (*callback_ui_update)(param); } else if (type == DEBUG_UI_VI) { if (callback_ui_vi != NULL) (*callback_ui_vi)(); } } void CoreCompareCallback(void) { if (callback_core_compare != NULL) (*callback_core_compare)(op_R4300); } void CoreCompareDataSync(int length, void *ptr) { if (callback_core_data_sync != NULL) (*callback_core_data_sync)(length, ptr); } /* exported functions for use by the front-end User Interface */ EXPORT m64p_error CALL DebugSetCoreCompare(void (*dbg_core_compare)(unsigned int), void (*dbg_core_data_sync)(int, void *)) { callback_core_compare = dbg_core_compare; callback_core_data_sync = dbg_core_data_sync; return M64ERR_SUCCESS; } EXPORT m64p_error CALL DebugSetCallbacks(void (*dbg_frontend_init)(void), void (*dbg_frontend_update)(unsigned int pc), void (*dbg_frontend_vi)(void)) { #ifdef DBG callback_ui_init = dbg_frontend_init; callback_ui_update = dbg_frontend_update; callback_ui_vi = dbg_frontend_vi; return M64ERR_SUCCESS; #else return M64ERR_UNSUPPORTED; #endif } EXPORT m64p_error CALL DebugSetRunState(int runstate) { #ifdef DBG run = runstate; /* in debugger/debugger.c */ return M64ERR_SUCCESS; #else return M64ERR_UNSUPPORTED; #endif } EXPORT int CALL DebugGetState(m64p_dbg_state statenum) { #ifdef DBG switch (statenum) { case M64P_DBG_RUN_STATE: return run; case M64P_DBG_PREVIOUS_PC: return previousPC; case M64P_DBG_NUM_BREAKPOINTS: return g_NumBreakpoints; case M64P_DBG_CPU_DYNACORE: return get_r4300_emumode(); case M64P_DBG_CPU_NEXT_INTERRUPT: return *r4300_next_interrupt(); default: DebugMessage(M64MSG_WARNING, "Bug: invalid m64p_dbg_state input in DebugGetState()"); return 0; } return 0; #else DebugMessage(M64MSG_ERROR, "Bug: DebugGetState() called, but Debugger not supported in Core library"); return 0; #endif } EXPORT m64p_error CALL DebugStep(void) { #ifdef DBG if (!g_DebuggerActive) return M64ERR_INVALID_STATE; debugger_step(); /* in debugger/debugger.c */ return M64ERR_SUCCESS; #else return M64ERR_UNSUPPORTED; #endif } EXPORT void CALL DebugDecodeOp(unsigned int instruction, char *op, char *args, int pc) { #ifdef DBG r4300_decode_op(instruction, op, args, pc); #else DebugMessage(M64MSG_ERROR, "Bug: DebugDecodeOp() called, but Debugger not supported in Core library"); #endif } EXPORT void * CALL DebugMemGetRecompInfo(m64p_dbg_mem_info recomp_type, unsigned int address, int index) { #ifdef DBG switch (recomp_type) { case M64P_DBG_RECOMP_OPCODE: return get_recompiled_opcode(address, index); case M64P_DBG_RECOMP_ARGS: return get_recompiled_args(address, index); case M64P_DBG_RECOMP_ADDR: return get_recompiled_addr(address, index); default: DebugMessage(M64MSG_ERROR, "Bug: DebugMemGetRecompInfo() called with invalid m64p_dbg_mem_info"); return NULL; } #else DebugMessage(M64MSG_ERROR, "Bug: DebugMemGetRecompInfo() called, but Debugger not supported in Core library"); return NULL; #endif } EXPORT int CALL DebugMemGetMemInfo(m64p_dbg_mem_info mem_info_type, unsigned int address) { #ifdef DBG switch (mem_info_type) { case M64P_DBG_MEM_TYPE: return get_memory_type(address); case M64P_DBG_MEM_FLAGS: return get_memory_flags(address); case M64P_DBG_MEM_HAS_RECOMPILED: return get_has_recompiled(address); case M64P_DBG_MEM_NUM_RECOMPILED: return get_num_recompiled(address); default: DebugMessage(M64MSG_ERROR, "Bug: DebugMemGetMemInfo() called with invalid m64p_dbg_mem_info"); return 0; } #else DebugMessage(M64MSG_ERROR, "Bug: DebugMemGetMemInfo() called, but Debugger not supported in Core library"); return 0; #endif } EXPORT void * CALL DebugMemGetPointer(m64p_dbg_memptr_type mem_ptr_type) { switch (mem_ptr_type) { case M64P_DBG_PTR_RDRAM: return g_rdram; case M64P_DBG_PTR_PI_REG: return g_pi.regs; case M64P_DBG_PTR_SI_REG: return g_si.regs; case M64P_DBG_PTR_VI_REG: return g_vi.regs; case M64P_DBG_PTR_RI_REG: return g_ri.regs; case M64P_DBG_PTR_AI_REG: return g_ai.regs; default: DebugMessage(M64MSG_ERROR, "Bug: DebugMemGetPointer() called with invalid m64p_dbg_memptr_type"); return NULL; } } EXPORT unsigned long long CALL DebugMemRead64(unsigned int address) { #ifdef DBG if ((address & 3) == 0) return read_memory_64(address); else return read_memory_64_unaligned(address); #else DebugMessage(M64MSG_ERROR, "Bug: DebugMemRead64() called, but Debugger not supported in Core library"); return 0LL; #endif } EXPORT unsigned int CALL DebugMemRead32(unsigned int address) { #ifdef DBG if ((address & 3) == 0) return read_memory_32(address); else return read_memory_32_unaligned(address); #else DebugMessage(M64MSG_ERROR, "Bug: DebugMemRead32() called, but Debugger not supported in Core library"); return 0; #endif } EXPORT unsigned short CALL DebugMemRead16(unsigned int address) { #ifdef DBG return read_memory_16(address); #else DebugMessage(M64MSG_ERROR, "Bug: DebugMemRead16() called, but Debugger not supported in Core library"); return 0; #endif } EXPORT unsigned char CALL DebugMemRead8(unsigned int address) { #ifdef DBG return read_memory_8(address); #else DebugMessage(M64MSG_ERROR, "Bug: DebugMemRead8() called, but Debugger not supported in Core library"); return 0; #endif } EXPORT void CALL DebugMemWrite64(unsigned int address, unsigned long long value) { #ifdef DBG if ((address & 3) == 0) write_memory_64(address, value); else write_memory_64_unaligned(address, value); #else DebugMessage(M64MSG_ERROR, "Bug: DebugMemWrite64() called, but Debugger not supported in Core library"); #endif } EXPORT void CALL DebugMemWrite32(unsigned int address, unsigned int value) { #ifdef DBG if ((address & 3) == 0) write_memory_32(address, value); else write_memory_32_unaligned(address, value); #else DebugMessage(M64MSG_ERROR, "Bug: DebugMemWrite32() called, but Debugger not supported in Core library"); #endif } EXPORT void CALL DebugMemWrite16(unsigned int address, unsigned short value) { #ifdef DBG write_memory_16(address, value); #else DebugMessage(M64MSG_ERROR, "Bug: DebugMemWrite16() called, but Debugger not supported in Core library"); #endif } EXPORT void CALL DebugMemWrite8(unsigned int address, unsigned char value) { #ifdef DBG write_memory_8(address, value); #else DebugMessage(M64MSG_ERROR, "Bug: DebugMemWrite8() called, but Debugger not supported in Core library"); #endif } EXPORT void * CALL DebugGetCPUDataPtr(m64p_dbg_cpu_data cpu_data_type) { switch (cpu_data_type) { case M64P_CPU_PC: return r4300_pc(); case M64P_CPU_REG_REG: return r4300_regs(); case M64P_CPU_REG_HI: return r4300_mult_hi(); case M64P_CPU_REG_LO: return r4300_mult_lo(); case M64P_CPU_REG_COP0: return r4300_cp0_regs(); case M64P_CPU_REG_COP1_DOUBLE_PTR: return r4300_cp1_regs_double(); case M64P_CPU_REG_COP1_SIMPLE_PTR: return r4300_cp1_regs_simple(); case M64P_CPU_REG_COP1_FGR_64: return r4300_cp1_regs(); case M64P_CPU_TLB: return tlb_e; default: DebugMessage(M64MSG_ERROR, "Bug: DebugGetCPUDataPtr() called with invalid input m64p_dbg_cpu_data"); return NULL; } } EXPORT int CALL DebugBreakpointLookup(unsigned int address, unsigned int size, unsigned int flags) { #ifdef DBG return lookup_breakpoint(address, size, flags); #else DebugMessage(M64MSG_ERROR, "Bug: DebugBreakpointLookup() called, but Debugger not supported in Core library"); return -1; #endif } EXPORT int CALL DebugBreakpointCommand(m64p_dbg_bkp_command command, unsigned int index, void *ptr) { #ifdef DBG switch (command) { case M64P_BKP_CMD_ADD_ADDR: return add_breakpoint(index); case M64P_BKP_CMD_ADD_STRUCT: return add_breakpoint_struct((breakpoint *) ptr); case M64P_BKP_CMD_REPLACE: replace_breakpoint_num(index, (breakpoint *) ptr); return 0; case M64P_BKP_CMD_REMOVE_ADDR: remove_breakpoint_by_address(index); return 0; case M64P_BKP_CMD_REMOVE_IDX: remove_breakpoint_by_num(index); return 0; case M64P_BKP_CMD_ENABLE: enable_breakpoint(index); return 0; case M64P_BKP_CMD_DISABLE: disable_breakpoint(index); return 0; case M64P_BKP_CMD_CHECK: return check_breakpoints(index); default: DebugMessage(M64MSG_ERROR, "Bug: DebugBreakpointCommand() called with invalid input m64p_dbg_bkp_command"); return -1; } #else DebugMessage(M64MSG_ERROR, "Bug: DebugBreakpointCommand() called, but Debugger not supported in Core library"); return -1; #endif } mupen64plus-core/src/api/m64p_plugin.h000664 001750 001750 00000021606 12655644434 020731 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-core - m64p_plugin.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * Copyright (C) 2009 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_PLUGIN_H #define M64P_PLUGIN_H #include #include "m64p_types.h" #ifdef __cplusplus extern "C" { #endif /*** Controller plugin's ****/ #define PLUGIN_NONE 1 #define PLUGIN_MEMPAK 2 #define PLUGIN_RUMBLE_PAK 3 /* not implemented for non raw data */ #define PLUGIN_TRANSFER_PAK 4 /* not implemented for non raw data */ #define PLUGIN_RAW 5 /* the controller plugin is passed in raw data */ /***** Structures *****/ typedef struct { uint8_t * RDRAM; uint8_t * DMEM; uint8_t * IMEM; uint32_t * MI_INTR_REG; uint32_t * SP_MEM_ADDR_REG; uint32_t * SP_DRAM_ADDR_REG; uint32_t * SP_RD_LEN_REG; uint32_t * SP_WR_LEN_REG; uint32_t * SP_STATUS_REG; uint32_t * SP_DMA_FULL_REG; uint32_t * SP_DMA_BUSY_REG; uint32_t * SP_PC_REG; uint32_t * SP_SEMAPHORE_REG; uint32_t * DPC_START_REG; uint32_t * DPC_END_REG; uint32_t * DPC_CURRENT_REG; uint32_t * DPC_STATUS_REG; uint32_t * DPC_CLOCK_REG; uint32_t * DPC_BUFBUSY_REG; uint32_t * DPC_PIPEBUSY_REG; uint32_t * DPC_TMEM_REG; void (*CheckInterrupts)(void); void (*ProcessDlistList)(void); void (*ProcessAlistList)(void); void (*ProcessRdpList)(void); void (*ShowCFB)(void); } RSP_INFO; typedef struct { uint8_t * HEADER; /* This is the rom header (first 40h bytes of the rom) */ uint8_t * RDRAM; uint8_t * DMEM; uint8_t * IMEM; uint32_t * MI_INTR_REG; uint32_t * DPC_START_REG; uint32_t * DPC_END_REG; uint32_t * DPC_CURRENT_REG; uint32_t * DPC_STATUS_REG; uint32_t * DPC_CLOCK_REG; uint32_t * DPC_BUFBUSY_REG; uint32_t * DPC_PIPEBUSY_REG; uint32_t * DPC_TMEM_REG; uint32_t * VI_STATUS_REG; uint32_t * VI_ORIGIN_REG; uint32_t * VI_WIDTH_REG; uint32_t * VI_INTR_REG; uint32_t * VI_V_CURRENT_LINE_REG; uint32_t * VI_TIMING_REG; uint32_t * VI_V_SYNC_REG; uint32_t * VI_H_SYNC_REG; uint32_t * VI_LEAP_REG; uint32_t * VI_H_START_REG; uint32_t * VI_V_START_REG; uint32_t * VI_V_BURST_REG; uint32_t * VI_X_SCALE_REG; uint32_t * VI_Y_SCALE_REG; void (*CheckInterrupts)(void); } GFX_INFO; typedef struct { uint8_t * RDRAM; uint8_t * DMEM; uint8_t * IMEM; uint32_t * MI_INTR_REG; uint32_t * AI_DRAM_ADDR_REG; uint32_t * AI_LEN_REG; uint32_t * AI_CONTROL_REG; uint32_t * AI_STATUS_REG; uint32_t * AI_DACRATE_REG; uint32_t * AI_BITRATE_REG; void (*CheckInterrupts)(void); } AUDIO_INFO; typedef struct { int Present; int RawData; int Plugin; } CONTROL; typedef union { uint32_t Value; struct { unsigned R_DPAD : 1; unsigned L_DPAD : 1; unsigned D_DPAD : 1; unsigned U_DPAD : 1; unsigned START_BUTTON : 1; unsigned Z_TRIG : 1; unsigned B_BUTTON : 1; unsigned A_BUTTON : 1; unsigned R_CBUTTON : 1; unsigned L_CBUTTON : 1; unsigned D_CBUTTON : 1; unsigned U_CBUTTON : 1; unsigned R_TRIG : 1; unsigned L_TRIG : 1; unsigned Reserved1 : 1; unsigned Reserved2 : 1; signed X_AXIS : 8; signed Y_AXIS : 8; }; } BUTTONS; typedef struct { CONTROL *Controls; /* A pointer to an array of 4 controllers .. eg: CONTROL Controls[4]; */ } CONTROL_INFO; /* common plugin function pointer types */ typedef void (*ptr_RomClosed)(void); typedef int (*ptr_RomOpen)(void); #if defined(M64P_PLUGIN_PROTOTYPES) EXPORT int CALL RomOpen(void); EXPORT void CALL RomClosed(void); #endif /* video plugin function pointer types */ typedef void (*ptr_ChangeWindow)(void); typedef int (*ptr_InitiateGFX)(GFX_INFO Gfx_Info); typedef void (*ptr_MoveScreen)(int x, int y); typedef void (*ptr_ProcessDList)(void); typedef void (*ptr_ProcessRDPList)(void); typedef void (*ptr_ShowCFB)(void); typedef void (*ptr_UpdateScreen)(void); typedef void (*ptr_ViStatusChanged)(void); typedef void (*ptr_ViWidthChanged)(void); typedef void (*ptr_ReadScreen2)(void *dest, int *width, int *height, int front); typedef void (*ptr_SetRenderingCallback)(void (*callback)(int)); typedef void (*ptr_ResizeVideoOutput)(int width, int height); #if defined(M64P_PLUGIN_PROTOTYPES) EXPORT void CALL ChangeWindow(void); EXPORT int CALL InitiateGFX(GFX_INFO Gfx_Info); EXPORT void CALL MoveScreen(int x, int y); EXPORT void CALL ProcessDList(void); EXPORT void CALL ProcessRDPList(void); EXPORT void CALL ShowCFB(void); EXPORT void CALL UpdateScreen(void); EXPORT void CALL ViStatusChanged(void); EXPORT void CALL ViWidthChanged(void); EXPORT void CALL ReadScreen2(void *dest, int *width, int *height, int front); EXPORT void CALL SetRenderingCallback(void (*callback)(int)); EXPORT void CALL ResizeVideoOutput(int width, int height); #endif /* frame buffer plugin spec extension */ typedef struct { uint32_t addr; uint32_t size; uint32_t width; uint32_t height; } FrameBufferInfo; typedef void (*ptr_FBRead)(uint32_t addr); typedef void (*ptr_FBWrite)(uint32_t addr, uint32_t size); typedef void (*ptr_FBGetFrameBufferInfo)(void *p); #if defined(M64P_PLUGIN_PROTOTYPES) EXPORT void CALL FBRead(uint32_t addr); EXPORT void CALL FBWrite(uint32_t addr, uint32_t size); EXPORT void CALL FBGetFrameBufferInfo(void *p); #endif /* audio plugin function pointers */ typedef void (*ptr_AiDacrateChanged)(int SystemType); typedef void (*ptr_AiLenChanged)(void); typedef int (*ptr_InitiateAudio)(AUDIO_INFO Audio_Info); typedef void (*ptr_ProcessAList)(void); typedef void (*ptr_SetSpeedFactor)(int percent); typedef void (*ptr_VolumeUp)(void); typedef void (*ptr_VolumeDown)(void); typedef int (*ptr_VolumeGetLevel)(void); typedef void (*ptr_VolumeSetLevel)(int level); typedef void (*ptr_VolumeMute)(void); typedef const char * (*ptr_VolumeGetString)(void); #if defined(M64P_PLUGIN_PROTOTYPES) EXPORT void CALL AiDacrateChanged(int SystemType); EXPORT void CALL AiLenChanged(void); EXPORT int CALL InitiateAudio(AUDIO_INFO Audio_Info); EXPORT void CALL ProcessAList(void); EXPORT void CALL SetSpeedFactor(int percent); EXPORT void CALL VolumeUp(void); EXPORT void CALL VolumeDown(void); EXPORT int CALL VolumeGetLevel(void); EXPORT void CALL VolumeSetLevel(int level); EXPORT void CALL VolumeMute(void); EXPORT const char * CALL VolumeGetString(void); #endif /* input plugin function pointers */ typedef void (*ptr_ControllerCommand)(int Control, uint8_t *Command); typedef void (*ptr_GetKeys)(int Control, BUTTONS *Keys); typedef void (*ptr_InitiateControllers)(CONTROL_INFO ControlInfo); typedef void (*ptr_ReadController)(int Control, uint8_t *Command); #if defined(M64P_PLUGIN_PROTOTYPES) EXPORT void CALL ControllerCommand(int Control, uint8_t *Command); EXPORT void CALL GetKeys(int Control, BUTTONS *Keys); EXPORT void CALL InitiateControllers(CONTROL_INFO ControlInfo); EXPORT void CALL ReadController(int Control, uint8_t *Command); #endif /* RSP plugin function pointers */ typedef uint32_t (*ptr_DoRspCycles)(uint32_t Cycles); typedef void (*ptr_InitiateRSP)(RSP_INFO Rsp_Info, uint32_t *CycleCount); #if defined(M64P_PLUGIN_PROTOTYPES) EXPORT uint32_t CALL DoRspCycles(uint32_t Cycles); EXPORT void CALL InitiateRSP(RSP_INFO Rsp_Info, uint32_t *CycleCount); #endif #ifdef __cplusplus } #endif #endif /* M64P_PLUGIN_H */ mupen64plus-video-gliden64/src/F3DPD.h000664 001750 001750 00000000136 12655644434 020377 0ustar00sergiosergio000000 000000 #ifndef F3DPD_H #define F3DPD_H #define F3DPD_VTXCOLORBASE 0x07 void F3DPD_Init(); #endif glide2gl/src/Glide64/Help/000700 001750 001750 00000000000 12656647145 016254 5ustar00sergiosergio000000 000000 gles2rice/src/version.h000664 001750 001750 00000003720 12655644434 016225 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-video-rice - version.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2009-2011 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This header file is for versioning information * */ #if !defined(VERSION_H) #define VERSION_H #define PLUGIN_NAME "Mupen64Plus OpenGL Video Plugin by Rice" #define PLUGIN_VERSION 0x020000 #define VIDEO_PLUGIN_API_VERSION 0x020200 #define CONFIG_API_VERSION 0x020000 #define VIDEXT_API_VERSION 0x030000 #define VERSION_PRINTF_SPLIT(x) (((x) >> 16) & 0xffff), (((x) >> 8) & 0xff), ((x) & 0xff) #endif /* #define VERSION_H */ libretro/msvc/msvc-2010/000700 001750 001750 00000000000 12656647145 016030 5ustar00sergiosergio000000 000000 mupen64plus-core/src/rsp/000700 001750 001750 00000000000 12656647145 016431 5ustar00sergiosergio000000 000000 mupen64plus-video-gliden64/src/ShaderUtils.h000664 001750 001750 00000000546 12655644434 022033 0ustar00sergiosergio000000 000000 #ifndef SHADER_UTILS_H #define SHADER_UTILS_H #include "OpenGL.h" #include "Combiner.h" GLuint createShaderProgram(const char * _strVertex, const char * _strFragment); bool checkShaderCompileStatus(GLuint obj); bool checkProgramLinkStatus(GLuint obj); int compileCombiner(Combiner & _color, Combiner & _alpha, char * _strShader); #endif // SHADER_UTILS_H mupen64plus-core/src/r4300/hacktarux_dynarec/grspecial.c000664 001750 001750 00000136642 12655644434 024236 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - gspecial.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2007 Richard Goedeken (Richard42) * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include "assemble.h" #include "interpret.h" #include "r4300/cached_interp.h" #include "r4300/cp0_private.h" #include "r4300/exception.h" #include "r4300/ops.h" #include "r4300/r4300.h" #include "r4300/recomp.h" #include "r4300/recomph.h" #include "regcache.h" #if !defined(offsetof) # define offsetof(TYPE,MEMBER) ((unsigned int) &((TYPE*)0)->MEMBER) #endif void gensll(void) { #ifdef INTERPRET_SLL gencallinterp((native_type)cached_interpreter_table.SLL, 0); #else #ifdef __x86_64__ int rt = allocate_register_32((unsigned int *)dst->f.r.rt); int rd = allocate_register_32_w((unsigned int *)dst->f.r.rd); #else int rt = allocate_register((unsigned int *)dst->f.r.rt); int rd = allocate_register_w((unsigned int *)dst->f.r.rd); #endif mov_reg32_reg32(rd, rt); shl_reg32_imm8(rd, dst->f.r.sa); #endif } void gensrl(void) { #ifdef INTERPRET_SRL gencallinterp((native_type)cached_interpreter_table.SRL, 0); #else #ifdef __x86_64__ int rt = allocate_register_32((unsigned int *)dst->f.r.rt); int rd = allocate_register_32_w((unsigned int *)dst->f.r.rd); #else int rt = allocate_register((unsigned int *)dst->f.r.rt); int rd = allocate_register_w((unsigned int *)dst->f.r.rd); #endif mov_reg32_reg32(rd, rt); shr_reg32_imm8(rd, dst->f.r.sa); #endif } void gensra(void) { #ifdef INTERPRET_SRA gencallinterp((native_type)cached_interpreter_table.SRA, 0); #else #ifdef __x86_64__ int rt = allocate_register_32((unsigned int *)dst->f.r.rt); int rd = allocate_register_32_w((unsigned int *)dst->f.r.rd); #else int rt = allocate_register((unsigned int *)dst->f.r.rt); int rd = allocate_register_w((unsigned int *)dst->f.r.rd); #endif mov_reg32_reg32(rd, rt); sar_reg32_imm8(rd, dst->f.r.sa); #endif } void gensllv(void) { #ifdef INTERPRET_SLLV gencallinterp((native_type)cached_interpreter_table.SLLV, 0); #else int rt, rd; #ifdef __x86_64__ allocate_register_32_manually(ECX, (unsigned int *)dst->f.r.rs); rt = allocate_register_32((unsigned int *)dst->f.r.rt); rd = allocate_register_32_w((unsigned int *)dst->f.r.rd); #else allocate_register_manually(ECX, (unsigned int *)dst->f.r.rs); rt = allocate_register((unsigned int *)dst->f.r.rt); rd = allocate_register_w((unsigned int *)dst->f.r.rd); #endif if (rd != ECX) { mov_reg32_reg32(rd, rt); shl_reg32_cl(rd); } else { int temp = lru_register(); free_register(temp); mov_reg32_reg32(temp, rt); shl_reg32_cl(temp); mov_reg32_reg32(rd, temp); } #endif } void gensrlv(void) { #ifdef INTERPRET_SRLV gencallinterp((native_type)cached_interpreter_table.SRLV, 0); #else int rt, rd; #ifdef __x86_64__ allocate_register_32_manually(ECX, (unsigned int *)dst->f.r.rs); rt = allocate_register_32((unsigned int *)dst->f.r.rt); rd = allocate_register_32_w((unsigned int *)dst->f.r.rd); #else allocate_register_manually(ECX, (unsigned int *)dst->f.r.rs); rt = allocate_register((unsigned int *)dst->f.r.rt); rd = allocate_register_w((unsigned int *)dst->f.r.rd); #endif if (rd != ECX) { mov_reg32_reg32(rd, rt); shr_reg32_cl(rd); } else { int temp = lru_register(); free_register(temp); mov_reg32_reg32(temp, rt); shr_reg32_cl(temp); mov_reg32_reg32(rd, temp); } #endif } void gensrav(void) { #ifdef INTERPRET_SRAV gencallinterp((native_type)cached_interpreter_table.SRAV, 0); #else int rt, rd; #ifdef __x86_64__ allocate_register_32_manually(ECX, (unsigned int *)dst->f.r.rs); rt = allocate_register_32((unsigned int *)dst->f.r.rt); rd = allocate_register_32_w((unsigned int *)dst->f.r.rd); #else allocate_register_manually(ECX, (unsigned int *)dst->f.r.rs); rt = allocate_register((unsigned int *)dst->f.r.rt); rd = allocate_register_w((unsigned int *)dst->f.r.rd); #endif if (rd != ECX) { mov_reg32_reg32(rd, rt); sar_reg32_cl(rd); } else { int temp = lru_register(); free_register(temp); mov_reg32_reg32(temp, rt); sar_reg32_cl(temp); mov_reg32_reg32(rd, temp); } #endif } void genjr(void) { #ifdef INTERPRET_JR gencallinterp((native_type)cached_interpreter_table.JR, 1); #else #ifdef __x86_64__ static unsigned int precomp_instr_size = sizeof(precomp_instr); unsigned int diff = (unsigned int) offsetof(precomp_instr, local_addr); unsigned int diff_need = (unsigned int) offsetof(precomp_instr, reg_cache_infos.need_map); unsigned int diff_wrap = (unsigned int) offsetof(precomp_instr, reg_cache_infos.jump_wrapper); if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.JR, 1); return; } free_registers_move_start(); mov_xreg32_m32rel(EAX, (unsigned int *)dst->f.i.rs); mov_m32rel_xreg32((unsigned int *)&local_rs, EAX); gendelayslot(); mov_xreg32_m32rel(EAX, (unsigned int *)&local_rs); mov_m32rel_xreg32((unsigned int *)&last_addr, EAX); gencheck_interupt_reg(); mov_xreg32_m32rel(EAX, (unsigned int *)&local_rs); mov_reg32_reg32(EBX, EAX); and_eax_imm32(0xFFFFF000); cmp_eax_imm32(dst_block->start & 0xFFFFF000); je_near_rj(0); jump_start_rel32(); mov_m32rel_xreg32(&jump_to_address, EBX); mov_reg64_imm64(RAX, (uint64_t) (dst+1)); mov_m64rel_xreg64((uint64_t *)(&PC), RAX); mov_reg64_imm64(RAX, (uint64_t) jump_to_func); call_reg64(RAX); /* will never return from call */ jump_end_rel32(); mov_reg64_imm64(RSI, (uint64_t) dst_block->block); mov_reg32_reg32(EAX, EBX); sub_eax_imm32(dst_block->start); shr_reg32_imm8(EAX, 2); mul_m32rel((unsigned int *)(&precomp_instr_size)); mov_reg32_preg64preg64pimm32(EBX, RAX, RSI, diff_need); cmp_reg32_imm32(EBX, 1); jne_rj(11); add_reg32_imm32(EAX, diff_wrap); // 6 add_reg64_reg64(RAX, RSI); // 3 jmp_reg64(RAX); // 2 mov_reg32_preg64preg64pimm32(EBX, RAX, RSI, diff); mov_rax_memoffs64((uint64_t *) &dst_block->code); add_reg64_reg64(RAX, RBX); jmp_reg64(RAX); #else static unsigned int precomp_instr_size = sizeof(precomp_instr); unsigned int diff = (unsigned int)(&dst->local_addr) - (unsigned int)(dst); unsigned int diff_need = (unsigned int)(&dst->reg_cache_infos.need_map) - (unsigned int)(dst); unsigned int diff_wrap = (unsigned int)(&dst->reg_cache_infos.jump_wrapper) - (unsigned int)(dst); if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((unsigned int)cached_interpreter_table.JR, 1); return; } free_all_registers(); simplify_access(); mov_eax_memoffs32((unsigned int *)dst->f.i.rs); mov_memoffs32_eax((unsigned int *)&local_rs); gendelayslot(); mov_eax_memoffs32((unsigned int *)&local_rs); mov_memoffs32_eax((unsigned int *)&last_addr); gencheck_interupt_reg(); mov_eax_memoffs32((unsigned int *)&local_rs); mov_reg32_reg32(EBX, EAX); and_eax_imm32(0xFFFFF000); cmp_eax_imm32(dst_block->start & 0xFFFFF000); je_near_rj(0); jump_start_rel32(); mov_m32_reg32(&jump_to_address, EBX); mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(dst+1)); mov_reg32_imm32(EAX, (unsigned int)jump_to_func); call_reg32(EAX); jump_end_rel32(); mov_reg32_reg32(EAX, EBX); sub_eax_imm32(dst_block->start); shr_reg32_imm8(EAX, 2); mul_m32((unsigned int *)(&precomp_instr_size)); mov_reg32_preg32pimm32(EBX, EAX, (unsigned int)(dst_block->block)+diff_need); cmp_reg32_imm32(EBX, 1); jne_rj(7); add_eax_imm32((unsigned int)(dst_block->block)+diff_wrap); // 5 jmp_reg32(EAX); // 2 mov_reg32_preg32pimm32(EAX, EAX, (unsigned int)(dst_block->block)+diff); add_reg32_m32(EAX, (unsigned int *)(&dst_block->code)); jmp_reg32(EAX); #endif #endif } void genjalr(void) { #ifdef INTERPRET_JALR gencallinterp((native_type)cached_interpreter_table.JALR, 0); #else #ifdef __x86_64__ static unsigned int precomp_instr_size = sizeof(precomp_instr); unsigned int diff = (unsigned int) offsetof(precomp_instr, local_addr); unsigned int diff_need = (unsigned int) offsetof(precomp_instr, reg_cache_infos.need_map); unsigned int diff_wrap = (unsigned int) offsetof(precomp_instr, reg_cache_infos.jump_wrapper); if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.JALR, 1); return; } free_registers_move_start(); mov_xreg32_m32rel(EAX, (unsigned int *)dst->f.r.rs); mov_m32rel_xreg32((unsigned int *)&local_rs, EAX); gendelayslot(); mov_m32rel_imm32((unsigned int *)(dst-1)->f.r.rd, dst->addr+4); if ((dst->addr+4) & 0x80000000) mov_m32rel_imm32(((unsigned int *)(dst-1)->f.r.rd)+1, 0xFFFFFFFF); else mov_m32rel_imm32(((unsigned int *)(dst-1)->f.r.rd)+1, 0); mov_xreg32_m32rel(EAX, (unsigned int *)&local_rs); mov_m32rel_xreg32((unsigned int *)&last_addr, EAX); gencheck_interupt_reg(); mov_xreg32_m32rel(EAX, (unsigned int *)&local_rs); mov_reg32_reg32(EBX, EAX); and_eax_imm32(0xFFFFF000); cmp_eax_imm32(dst_block->start & 0xFFFFF000); je_near_rj(0); jump_start_rel32(); mov_m32rel_xreg32(&jump_to_address, EBX); mov_reg64_imm64(RAX, (uint64_t) (dst+1)); mov_m64rel_xreg64((uint64_t *)(&PC), RAX); mov_reg64_imm64(RAX, (uint64_t) jump_to_func); call_reg64(RAX); /* will never return from call */ jump_end_rel32(); mov_reg64_imm64(RSI, (uint64_t) dst_block->block); mov_reg32_reg32(EAX, EBX); sub_eax_imm32(dst_block->start); shr_reg32_imm8(EAX, 2); mul_m32rel((unsigned int *)(&precomp_instr_size)); mov_reg32_preg64preg64pimm32(EBX, RAX, RSI, diff_need); cmp_reg32_imm32(EBX, 1); jne_rj(11); add_reg32_imm32(EAX, diff_wrap); // 6 add_reg64_reg64(RAX, RSI); // 3 jmp_reg64(RAX); // 2 mov_reg32_preg64preg64pimm32(EBX, RAX, RSI, diff); mov_rax_memoffs64((uint64_t *) &dst_block->code); add_reg64_reg64(RAX, RBX); jmp_reg64(RAX); #else static unsigned int precomp_instr_size = sizeof(precomp_instr); unsigned int diff = (unsigned int)(&dst->local_addr) - (unsigned int)(dst); unsigned int diff_need = (unsigned int)(&dst->reg_cache_infos.need_map) - (unsigned int)(dst); unsigned int diff_wrap = (unsigned int)(&dst->reg_cache_infos.jump_wrapper) - (unsigned int)(dst); if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((unsigned int)cached_interpreter_table.JALR, 1); return; } free_all_registers(); simplify_access(); mov_eax_memoffs32((unsigned int *)dst->f.r.rs); mov_memoffs32_eax((unsigned int *)&local_rs); gendelayslot(); mov_m32_imm32((unsigned int *)(dst-1)->f.r.rd, dst->addr+4); if ((dst->addr+4) & 0x80000000) mov_m32_imm32(((unsigned int *)(dst-1)->f.r.rd)+1, 0xFFFFFFFF); else mov_m32_imm32(((unsigned int *)(dst-1)->f.r.rd)+1, 0); mov_eax_memoffs32((unsigned int *)&local_rs); mov_memoffs32_eax((unsigned int *)&last_addr); gencheck_interupt_reg(); mov_eax_memoffs32((unsigned int *)&local_rs); mov_reg32_reg32(EBX, EAX); and_eax_imm32(0xFFFFF000); cmp_eax_imm32(dst_block->start & 0xFFFFF000); je_near_rj(0); jump_start_rel32(); mov_m32_reg32(&jump_to_address, EBX); mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(dst+1)); mov_reg32_imm32(EAX, (unsigned int)jump_to_func); call_reg32(EAX); jump_end_rel32(); mov_reg32_reg32(EAX, EBX); sub_eax_imm32(dst_block->start); shr_reg32_imm8(EAX, 2); mul_m32((unsigned int *)(&precomp_instr_size)); mov_reg32_preg32pimm32(EBX, EAX, (unsigned int)(dst_block->block)+diff_need); cmp_reg32_imm32(EBX, 1); jne_rj(7); add_eax_imm32((unsigned int)(dst_block->block)+diff_wrap); // 5 jmp_reg32(EAX); // 2 mov_reg32_preg32pimm32(EAX, EAX, (unsigned int)(dst_block->block)+diff); add_reg32_m32(EAX, (unsigned int *)(&dst_block->code)); jmp_reg32(EAX); #endif #endif } void gensyscall(void) { #ifdef INTERPRET_SYSCALL gencallinterp((native_type)cached_interpreter_table.SYSCALL, 0); #else #ifdef __x86_64__ free_registers_move_start(); mov_m32rel_imm32(&g_cp0_regs[CP0_CAUSE_REG], 8 << 2); #else free_all_registers(); simplify_access(); mov_m32_imm32(&g_cp0_regs[CP0_CAUSE_REG], 8 << 2); #endif gencallinterp((native_type)exception_general, 0); #endif } void gensync(void) { } void genmfhi(void) { #ifdef INTERPRET_MFHI gencallinterp((native_type)cached_interpreter_table.MFHI, 0); #else #ifdef __x86_64__ int rd = allocate_register_64_w((uint64_t *) dst->f.r.rd); int _hi = allocate_register_64((uint64_t *) &hi); mov_reg64_reg64(rd, _hi); #else int rd1 = allocate_64_register1_w((unsigned int*)dst->f.r.rd); int rd2 = allocate_64_register2_w((unsigned int*)dst->f.r.rd); int hi1 = allocate_64_register1((unsigned int*)&hi); int hi2 = allocate_64_register2((unsigned int*)&hi); mov_reg32_reg32(rd1, hi1); mov_reg32_reg32(rd2, hi2); #endif #endif } void genmthi(void) { #ifdef INTERPRET_MTHI gencallinterp((native_type)cached_interpreter_table.MTHI, 0); #else #ifdef __x86_64__ int _hi = allocate_register_64_w((uint64_t *) &hi); int rs = allocate_register_64((uint64_t *) dst->f.r.rs); mov_reg64_reg64(_hi, rs); #else int hi1 = allocate_64_register1_w((unsigned int*)&hi); int hi2 = allocate_64_register2_w((unsigned int*)&hi); int rs1 = allocate_64_register1((unsigned int*)dst->f.r.rs); int rs2 = allocate_64_register2((unsigned int*)dst->f.r.rs); mov_reg32_reg32(hi1, rs1); mov_reg32_reg32(hi2, rs2); #endif #endif } void genmflo(void) { #ifdef INTERPRET_MFLO gencallinterp((native_type)cached_interpreter_table.MFLO, 0); #else #ifdef __x86_64__ int rd = allocate_register_64_w((uint64_t *) dst->f.r.rd); int _lo = allocate_register_64((uint64_t *) &lo); mov_reg64_reg64(rd, _lo); #else int rd1 = allocate_64_register1_w((unsigned int*)dst->f.r.rd); int rd2 = allocate_64_register2_w((unsigned int*)dst->f.r.rd); int lo1 = allocate_64_register1((unsigned int*)&lo); int lo2 = allocate_64_register2((unsigned int*)&lo); mov_reg32_reg32(rd1, lo1); mov_reg32_reg32(rd2, lo2); #endif #endif } void genmtlo(void) { #ifdef INTERPRET_MTLO gencallinterp((native_type)cached_interpreter_table.MTLO, 0); #else #ifdef __x86_64__ int _lo = allocate_register_64_w((uint64_t *)&lo); int rs = allocate_register_64((uint64_t *)dst->f.r.rs); mov_reg64_reg64(_lo, rs); #else int lo1 = allocate_64_register1_w((unsigned int*)&lo); int lo2 = allocate_64_register2_w((unsigned int*)&lo); int rs1 = allocate_64_register1((unsigned int*)dst->f.r.rs); int rs2 = allocate_64_register2((unsigned int*)dst->f.r.rs); mov_reg32_reg32(lo1, rs1); mov_reg32_reg32(lo2, rs2); #endif #endif } void gendsllv(void) { #ifdef INTERPRET_DSLLV gencallinterp((native_type)cached_interpreter_table.DSLLV, 0); #else #ifdef __x86_64__ int rt, rd; allocate_register_32_manually(ECX, (unsigned int *)dst->f.r.rs); rt = allocate_register_64((uint64_t *)dst->f.r.rt); rd = allocate_register_64_w((uint64_t *)dst->f.r.rd); if (rd != ECX) { mov_reg64_reg64(rd, rt); shl_reg64_cl(rd); } else { int temp; temp = lru_register(); free_register(temp); mov_reg64_reg64(temp, rt); shl_reg64_cl(temp); mov_reg64_reg64(rd, temp); } #else int rt1, rt2, rd1, rd2; allocate_register_manually(ECX, (unsigned int *)dst->f.r.rs); rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt); rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt); rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd); rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd); if (rd1 != ECX && rd2 != ECX) { mov_reg32_reg32(rd1, rt1); mov_reg32_reg32(rd2, rt2); shld_reg32_reg32_cl(rd2,rd1); shl_reg32_cl(rd1); test_reg32_imm32(ECX, 0x20); je_rj(4); mov_reg32_reg32(rd2, rd1); // 2 xor_reg32_reg32(rd1, rd1); // 2 } else { int temp1, temp2; force_32(ECX); temp1 = lru_register(); temp2 = lru_register_exc1(temp1); free_register(temp1); free_register(temp2); mov_reg32_reg32(temp1, rt1); mov_reg32_reg32(temp2, rt2); shld_reg32_reg32_cl(temp2, temp1); shl_reg32_cl(temp1); test_reg32_imm32(ECX, 0x20); je_rj(4); mov_reg32_reg32(temp2, temp1); // 2 xor_reg32_reg32(temp1, temp1); // 2 mov_reg32_reg32(rd1, temp1); mov_reg32_reg32(rd2, temp2); } #endif #endif } void gendsrlv(void) { #ifdef INTERPRET_DSRLV gencallinterp((native_type)cached_interpreter_table.DSRLV, 0); #else #ifdef __x86_64__ int rt, rd; allocate_register_32_manually(ECX, (unsigned int *)dst->f.r.rs); rt = allocate_register_64((uint64_t *)dst->f.r.rt); rd = allocate_register_64_w((uint64_t *)dst->f.r.rd); if (rd != ECX) { mov_reg64_reg64(rd, rt); shr_reg64_cl(rd); } else { int temp; temp = lru_register(); free_register(temp); mov_reg64_reg64(temp, rt); shr_reg64_cl(temp); mov_reg64_reg64(rd, temp); } #else int rt1, rt2, rd1, rd2; allocate_register_manually(ECX, (unsigned int *)dst->f.r.rs); rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt); rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt); rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd); rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd); if (rd1 != ECX && rd2 != ECX) { mov_reg32_reg32(rd1, rt1); mov_reg32_reg32(rd2, rt2); shrd_reg32_reg32_cl(rd1,rd2); shr_reg32_cl(rd2); test_reg32_imm32(ECX, 0x20); je_rj(4); mov_reg32_reg32(rd1, rd2); // 2 xor_reg32_reg32(rd2, rd2); // 2 } else { int temp1, temp2; force_32(ECX); temp1 = lru_register(); temp2 = lru_register_exc1(temp1); free_register(temp1); free_register(temp2); mov_reg32_reg32(temp1, rt1); mov_reg32_reg32(temp2, rt2); shrd_reg32_reg32_cl(temp1, temp2); shr_reg32_cl(temp2); test_reg32_imm32(ECX, 0x20); je_rj(4); mov_reg32_reg32(temp1, temp2); // 2 xor_reg32_reg32(temp2, temp2); // 2 mov_reg32_reg32(rd1, temp1); mov_reg32_reg32(rd2, temp2); } #endif #endif } void gendsrav(void) { #ifdef INTERPRET_DSRAV gencallinterp((native_type)cached_interpreter_table.DSRAV, 0); #else #ifdef __x86_64__ int rt, rd; allocate_register_32_manually(ECX, (unsigned int *)dst->f.r.rs); rt = allocate_register_64((uint64_t *)dst->f.r.rt); rd = allocate_register_64_w((uint64_t *)dst->f.r.rd); if (rd != ECX) { mov_reg64_reg64(rd, rt); sar_reg64_cl(rd); } else { int temp; temp = lru_register(); free_register(temp); mov_reg64_reg64(temp, rt); sar_reg64_cl(temp); mov_reg64_reg64(rd, temp); } #else int rt1, rt2, rd1, rd2; allocate_register_manually(ECX, (unsigned int *)dst->f.r.rs); rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt); rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt); rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd); rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd); if (rd1 != ECX && rd2 != ECX) { mov_reg32_reg32(rd1, rt1); mov_reg32_reg32(rd2, rt2); shrd_reg32_reg32_cl(rd1,rd2); sar_reg32_cl(rd2); test_reg32_imm32(ECX, 0x20); je_rj(5); mov_reg32_reg32(rd1, rd2); // 2 sar_reg32_imm8(rd2, 31); // 3 } else { int temp1, temp2; force_32(ECX); temp1 = lru_register(); temp2 = lru_register_exc1(temp1); free_register(temp1); free_register(temp2); mov_reg32_reg32(temp1, rt1); mov_reg32_reg32(temp2, rt2); shrd_reg32_reg32_cl(temp1, temp2); sar_reg32_cl(temp2); test_reg32_imm32(ECX, 0x20); je_rj(5); mov_reg32_reg32(temp1, temp2); // 2 sar_reg32_imm8(temp2, 31); // 3 mov_reg32_reg32(rd1, temp1); mov_reg32_reg32(rd2, temp2); } #endif #endif } void genmult(void) { #ifdef INTERPRET_MULT gencallinterp((native_type)cached_interpreter_table.MULT, 0); #else int rs, rt; #ifdef __x86_64__ allocate_register_32_manually_w(EAX, (unsigned int *)&lo); /* these must be done first so they are not assigned by allocate_register() */ allocate_register_32_manually_w(EDX, (unsigned int *)&hi); rs = allocate_register_32((unsigned int*)dst->f.r.rs); rt = allocate_register_32((unsigned int*)dst->f.r.rt); #else allocate_register_manually_w(EAX, (unsigned int *)&lo, 0); allocate_register_manually_w(EDX, (unsigned int *)&hi, 0); rs = allocate_register((unsigned int*)dst->f.r.rs); rt = allocate_register((unsigned int*)dst->f.r.rt); #endif mov_reg32_reg32(EAX, rs); imul_reg32(rt); #endif } void genmultu(void) { #ifdef INTERPRET_MULTU gencallinterp((native_type)cached_interpreter_table.MULTU, 0); #else int rs, rt; #ifdef __x86_64__ allocate_register_32_manually_w(EAX, (unsigned int *)&lo); allocate_register_32_manually_w(EDX, (unsigned int *)&hi); rs = allocate_register_32((unsigned int*)dst->f.r.rs); rt = allocate_register_32((unsigned int*)dst->f.r.rt); #else allocate_register_manually_w(EAX, (unsigned int *)&lo, 0); allocate_register_manually_w(EDX, (unsigned int *)&hi, 0); rs = allocate_register((unsigned int*)dst->f.r.rs); rt = allocate_register((unsigned int*)dst->f.r.rt); #endif mov_reg32_reg32(EAX, rs); mul_reg32(rt); #endif } void gendiv(void) { #ifdef INTERPRET_DIV gencallinterp((native_type)cached_interpreter_table.DIV, 0); #else int rs, rt; #ifdef __x86_64__ allocate_register_32_manually_w(EAX, (unsigned int *)&lo); allocate_register_32_manually_w(EDX, (unsigned int *)&hi); rs = allocate_register_32((unsigned int*)dst->f.r.rs); rt = allocate_register_32((unsigned int*)dst->f.r.rt); #else allocate_register_manually_w(EAX, (unsigned int *)&lo, 0); allocate_register_manually_w(EDX, (unsigned int *)&hi, 0); rs = allocate_register((unsigned int*)dst->f.r.rs); rt = allocate_register((unsigned int*)dst->f.r.rt); #endif cmp_reg32_imm32(rt, 0); je_rj((rs == EAX ? 0 : 2) + 1 + 2); mov_reg32_reg32(EAX, rs); // 0 or 2 cdq(); // 1 idiv_reg32(rt); // 2 #endif } void gendivu(void) { #ifdef INTERPRET_DIVU gencallinterp((native_type)cached_interpreter_table.DIVU, 0); #else int rs, rt; #ifdef __x86_64__ allocate_register_32_manually_w(EAX, (unsigned int *)&lo); allocate_register_32_manually_w(EDX, (unsigned int *)&hi); rs = allocate_register_32((unsigned int*)dst->f.r.rs); rt = allocate_register_32((unsigned int*)dst->f.r.rt); #else allocate_register_manually_w(EAX, (unsigned int *)&lo, 0); allocate_register_manually_w(EDX, (unsigned int *)&hi, 0); rs = allocate_register((unsigned int*)dst->f.r.rs); rt = allocate_register((unsigned int*)dst->f.r.rt); #endif cmp_reg32_imm32(rt, 0); je_rj((rs == EAX ? 0 : 2) + 2 + 2); mov_reg32_reg32(EAX, rs); // 0 or 2 xor_reg32_reg32(EDX, EDX); // 2 div_reg32(rt); // 2 #endif } void gendmult(void) { gencallinterp((native_type)cached_interpreter_table.DMULT, 0); } void gendmultu(void) { #ifdef INTERPRET_DMULTU gencallinterp((native_type)cached_interpreter_table.DMULTU, 0); #else #ifdef __x86_64__ free_registers_move_start(); mov_xreg64_m64rel(RAX, (uint64_t *) dst->f.r.rs); mov_xreg64_m64rel(RDX, (uint64_t *) dst->f.r.rt); mul_reg64(RDX); mov_m64rel_xreg64((uint64_t *) &lo, RAX); mov_m64rel_xreg64((uint64_t *) &hi, RDX); #else free_all_registers(); simplify_access(); mov_eax_memoffs32((unsigned int *)dst->f.r.rs); mul_m32((unsigned int *)dst->f.r.rt); // EDX:EAX = temp1 mov_memoffs32_eax((unsigned int *)(&lo)); mov_reg32_reg32(EBX, EDX); // EBX = temp1>>32 mov_eax_memoffs32((unsigned int *)dst->f.r.rs); mul_m32((unsigned int *)(dst->f.r.rt)+1); add_reg32_reg32(EBX, EAX); adc_reg32_imm32(EDX, 0); mov_reg32_reg32(ECX, EDX); // ECX:EBX = temp2 mov_eax_memoffs32((unsigned int *)(dst->f.r.rs)+1); mul_m32((unsigned int *)dst->f.r.rt); // EDX:EAX = temp3 add_reg32_reg32(EBX, EAX); adc_reg32_imm32(ECX, 0); // ECX:EBX = result2 mov_m32_reg32((unsigned int*)(&lo)+1, EBX); mov_reg32_reg32(ESI, EDX); // ESI = temp3>>32 mov_eax_memoffs32((unsigned int *)(dst->f.r.rs)+1); mul_m32((unsigned int *)(dst->f.r.rt)+1); add_reg32_reg32(EAX, ESI); adc_reg32_imm32(EDX, 0); // EDX:EAX = temp4 add_reg32_reg32(EAX, ECX); adc_reg32_imm32(EDX, 0); // EDX:EAX = result3 mov_memoffs32_eax((unsigned int *)(&hi)); mov_m32_reg32((unsigned int *)(&hi)+1, EDX); #endif #endif } void genddiv(void) { gencallinterp((native_type)cached_interpreter_table.DDIV, 0); } void genddivu(void) { gencallinterp((native_type)cached_interpreter_table.DDIVU, 0); } void genadd(void) { #ifdef INTERPRET_ADD gencallinterp((native_type)cached_interpreter_table.ADD, 0); #else #ifdef __x86_64__ int rs = allocate_register_32((unsigned int *)dst->f.r.rs); int rt = allocate_register_32((unsigned int *)dst->f.r.rt); int rd = allocate_register_32_w((unsigned int *)dst->f.r.rd); if (rs == rd) add_reg32_reg32(rd, rt); else if (rt == rd) add_reg32_reg32(rd, rs); else { mov_reg32_reg32(rd, rs); add_reg32_reg32(rd, rt); } #else int rs = allocate_register((unsigned int *)dst->f.r.rs); int rt = allocate_register((unsigned int *)dst->f.r.rt); int rd = allocate_register_w((unsigned int *)dst->f.r.rd); if (rt != rd && rs != rd) { mov_reg32_reg32(rd, rs); add_reg32_reg32(rd, rt); } else { int temp = lru_register(); free_register(temp); mov_reg32_reg32(temp, rs); add_reg32_reg32(temp, rt); mov_reg32_reg32(rd, temp); } #endif #endif } void genaddu(void) { #ifdef INTERPRET_ADDU gencallinterp((native_type)cached_interpreter_table.ADDU, 0); #else #ifdef __x86_64__ int rs = allocate_register_32((unsigned int *)dst->f.r.rs); int rt = allocate_register_32((unsigned int *)dst->f.r.rt); int rd = allocate_register_32_w((unsigned int *)dst->f.r.rd); if (rs == rd) add_reg32_reg32(rd, rt); else if (rt == rd) add_reg32_reg32(rd, rs); else { mov_reg32_reg32(rd, rs); add_reg32_reg32(rd, rt); } #else int rs = allocate_register((unsigned int *)dst->f.r.rs); int rt = allocate_register((unsigned int *)dst->f.r.rt); int rd = allocate_register_w((unsigned int *)dst->f.r.rd); if (rt != rd && rs != rd) { mov_reg32_reg32(rd, rs); add_reg32_reg32(rd, rt); } else { int temp = lru_register(); free_register(temp); mov_reg32_reg32(temp, rs); add_reg32_reg32(temp, rt); mov_reg32_reg32(rd, temp); } #endif #endif } void gensub(void) { #ifdef INTERPRET_SUB gencallinterp((native_type)cached_interpreter_table.SUB, 0); #else #ifdef __x86_64__ int rs = allocate_register_32((unsigned int *)dst->f.r.rs); int rt = allocate_register_32((unsigned int *)dst->f.r.rt); int rd = allocate_register_32_w((unsigned int *)dst->f.r.rd); if (rs == rd) sub_reg32_reg32(rd, rt); else if (rt == rd) { neg_reg32(rd); add_reg32_reg32(rd, rs); } else { mov_reg32_reg32(rd, rs); sub_reg32_reg32(rd, rt); } #else int rs = allocate_register((unsigned int *)dst->f.r.rs); int rt = allocate_register((unsigned int *)dst->f.r.rt); int rd = allocate_register_w((unsigned int *)dst->f.r.rd); if (rt != rd && rs != rd) { mov_reg32_reg32(rd, rs); sub_reg32_reg32(rd, rt); } else { int temp = lru_register(); free_register(temp); mov_reg32_reg32(temp, rs); sub_reg32_reg32(temp, rt); mov_reg32_reg32(rd, temp); } #endif #endif } void gensubu(void) { #ifdef INTERPRET_SUBU gencallinterp((native_type)cached_interpreter_table.SUBU, 0); #else #ifdef __x86_64__ int rs = allocate_register_32((unsigned int *)dst->f.r.rs); int rt = allocate_register_32((unsigned int *)dst->f.r.rt); int rd = allocate_register_32_w((unsigned int *)dst->f.r.rd); if (rs == rd) sub_reg32_reg32(rd, rt); else if (rt == rd) { neg_reg32(rd); add_reg32_reg32(rd, rs); } else { mov_reg32_reg32(rd, rs); sub_reg32_reg32(rd, rt); } #else int rs = allocate_register((unsigned int *)dst->f.r.rs); int rt = allocate_register((unsigned int *)dst->f.r.rt); int rd = allocate_register_w((unsigned int *)dst->f.r.rd); if (rt != rd && rs != rd) { mov_reg32_reg32(rd, rs); sub_reg32_reg32(rd, rt); } else { int temp = lru_register(); free_register(temp); mov_reg32_reg32(temp, rs); sub_reg32_reg32(temp, rt); mov_reg32_reg32(rd, temp); } #endif #endif } void genand(void) { #ifdef INTERPRET_AND gencallinterp((native_type)cached_interpreter_table.AND, 0); #else #ifdef __x86_64__ int rs = allocate_register_64((uint64_t *)dst->f.r.rs); int rt = allocate_register_64((uint64_t *)dst->f.r.rt); int rd = allocate_register_64_w((uint64_t *)dst->f.r.rd); if (rs == rd) and_reg64_reg64(rd, rt); else if (rt == rd) and_reg64_reg64(rd, rs); else { mov_reg64_reg64(rd, rs); and_reg64_reg64(rd, rt); } #else int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs); int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs); int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt); int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt); int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd); int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd); if (rt1 != rd1 && rs1 != rd1) { mov_reg32_reg32(rd1, rs1); mov_reg32_reg32(rd2, rs2); and_reg32_reg32(rd1, rt1); and_reg32_reg32(rd2, rt2); } else { int temp = lru_register(); free_register(temp); mov_reg32_reg32(temp, rs1); and_reg32_reg32(temp, rt1); mov_reg32_reg32(rd1, temp); mov_reg32_reg32(temp, rs2); and_reg32_reg32(temp, rt2); mov_reg32_reg32(rd2, temp); } #endif #endif } void genor(void) { #ifdef INTERPRET_OR gencallinterp((native_type)cached_interpreter_table.OR, 0); #else #ifdef __x86_64__ int rs = allocate_register_64((uint64_t *)dst->f.r.rs); int rt = allocate_register_64((uint64_t *)dst->f.r.rt); int rd = allocate_register_64_w((uint64_t *)dst->f.r.rd); if (rs == rd) or_reg64_reg64(rd, rt); else if (rt == rd) or_reg64_reg64(rd, rs); else { mov_reg64_reg64(rd, rs); or_reg64_reg64(rd, rt); } #else int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs); int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs); int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt); int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt); int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd); int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd); if (rt1 != rd1 && rs1 != rd1) { mov_reg32_reg32(rd1, rs1); mov_reg32_reg32(rd2, rs2); or_reg32_reg32(rd1, rt1); or_reg32_reg32(rd2, rt2); } else { int temp = lru_register(); free_register(temp); mov_reg32_reg32(temp, rs1); or_reg32_reg32(temp, rt1); mov_reg32_reg32(rd1, temp); mov_reg32_reg32(temp, rs2); or_reg32_reg32(temp, rt2); mov_reg32_reg32(rd2, temp); } #endif #endif } void genxor(void) { #ifdef INTERPRET_XOR gencallinterp((native_type)cached_interpreter_table.XOR, 0); #else #ifdef __x86_64__ int rs = allocate_register_64((uint64_t *)dst->f.r.rs); int rt = allocate_register_64((uint64_t *)dst->f.r.rt); int rd = allocate_register_64_w((uint64_t *)dst->f.r.rd); if (rs == rd) xor_reg64_reg64(rd, rt); else if (rt == rd) xor_reg64_reg64(rd, rs); else { mov_reg64_reg64(rd, rs); xor_reg64_reg64(rd, rt); } #else int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs); int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs); int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt); int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt); int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd); int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd); if (rt1 != rd1 && rs1 != rd1) { mov_reg32_reg32(rd1, rs1); mov_reg32_reg32(rd2, rs2); xor_reg32_reg32(rd1, rt1); xor_reg32_reg32(rd2, rt2); } else { int temp = lru_register(); free_register(temp); mov_reg32_reg32(temp, rs1); xor_reg32_reg32(temp, rt1); mov_reg32_reg32(rd1, temp); mov_reg32_reg32(temp, rs2); xor_reg32_reg32(temp, rt2); mov_reg32_reg32(rd2, temp); } #endif #endif } void gennor(void) { #ifdef INTERPRET_NOR gencallinterp((native_type)cached_interpreter_table.NOR, 0); #else #ifdef __x86_64__ int rs = allocate_register_64((uint64_t *)dst->f.r.rs); int rt = allocate_register_64((uint64_t *)dst->f.r.rt); int rd = allocate_register_64_w((uint64_t *)dst->f.r.rd); if (rs == rd) { or_reg64_reg64(rd, rt); not_reg64(rd); } else if (rt == rd) { or_reg64_reg64(rd, rs); not_reg64(rd); } else { mov_reg64_reg64(rd, rs); or_reg64_reg64(rd, rt); not_reg64(rd); } #else int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs); int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs); int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt); int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt); int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd); int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd); if (rt1 != rd1 && rs1 != rd1) { mov_reg32_reg32(rd1, rs1); mov_reg32_reg32(rd2, rs2); or_reg32_reg32(rd1, rt1); or_reg32_reg32(rd2, rt2); not_reg32(rd1); not_reg32(rd2); } else { int temp = lru_register(); free_register(temp); mov_reg32_reg32(temp, rs1); or_reg32_reg32(temp, rt1); mov_reg32_reg32(rd1, temp); mov_reg32_reg32(temp, rs2); or_reg32_reg32(temp, rt2); mov_reg32_reg32(rd2, temp); not_reg32(rd1); not_reg32(rd2); } #endif #endif } void genslt(void) { #ifdef INTERPRET_SLT gencallinterp((native_type)cached_interpreter_table.SLT, 0); #else #ifdef __x86_64__ int rs = allocate_register_64((uint64_t *)dst->f.r.rs); int rt = allocate_register_64((uint64_t *)dst->f.r.rt); int rd = allocate_register_64_w((uint64_t *)dst->f.r.rd); cmp_reg64_reg64(rs, rt); setl_reg8(rd); and_reg64_imm8(rd, 1); #else int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs); int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs); int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt); int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt); int rd = allocate_register_w((unsigned int *)dst->f.r.rd); cmp_reg32_reg32(rs2, rt2); jl_rj(13); jne_rj(4); // 2 cmp_reg32_reg32(rs1, rt1); // 2 jl_rj(7); // 2 mov_reg32_imm32(rd, 0); // 5 jmp_imm_short(5); // 2 mov_reg32_imm32(rd, 1); // 5 #endif #endif } void gensltu(void) { #ifdef INTERPRET_SLTU gencallinterp((native_type)cached_interpreter_table.SLTU, 0); #else #ifdef __x86_64__ int rs = allocate_register_64((uint64_t *)dst->f.r.rs); int rt = allocate_register_64((uint64_t *)dst->f.r.rt); int rd = allocate_register_64_w((uint64_t *)dst->f.r.rd); cmp_reg64_reg64(rs, rt); setb_reg8(rd); and_reg64_imm8(rd, 1); #else int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs); int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs); int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt); int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt); int rd = allocate_register_w((unsigned int *)dst->f.r.rd); cmp_reg32_reg32(rs2, rt2); jb_rj(13); jne_rj(4); // 2 cmp_reg32_reg32(rs1, rt1); // 2 jb_rj(7); // 2 mov_reg32_imm32(rd, 0); // 5 jmp_imm_short(5); // 2 mov_reg32_imm32(rd, 1); // 5 #endif #endif } void gendadd(void) { #ifdef INTERPRET_DADD gencallinterp((native_type)cached_interpreter_table.DADD, 0); #else #ifdef __x86_64__ int rs = allocate_register_64((uint64_t *)dst->f.r.rs); int rt = allocate_register_64((uint64_t *)dst->f.r.rt); int rd = allocate_register_64_w((uint64_t *)dst->f.r.rd); if (rs == rd) add_reg64_reg64(rd, rt); else if (rt == rd) add_reg64_reg64(rd, rs); else { mov_reg64_reg64(rd, rs); add_reg64_reg64(rd, rt); } #else int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs); int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs); int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt); int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt); int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd); int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd); if (rt1 != rd1 && rs1 != rd1) { mov_reg32_reg32(rd1, rs1); mov_reg32_reg32(rd2, rs2); add_reg32_reg32(rd1, rt1); adc_reg32_reg32(rd2, rt2); } else { int temp = lru_register(); free_register(temp); mov_reg32_reg32(temp, rs1); add_reg32_reg32(temp, rt1); mov_reg32_reg32(rd1, temp); mov_reg32_reg32(temp, rs2); adc_reg32_reg32(temp, rt2); mov_reg32_reg32(rd2, temp); } #endif #endif } void gendaddu(void) { #ifdef INTERPRET_DADDU gencallinterp((native_type)cached_interpreter_table.DADDU, 0); #else #ifdef __x86_64__ int rs = allocate_register_64((uint64_t *)dst->f.r.rs); int rt = allocate_register_64((uint64_t *)dst->f.r.rt); int rd = allocate_register_64_w((uint64_t *)dst->f.r.rd); if (rs == rd) add_reg64_reg64(rd, rt); else if (rt == rd) add_reg64_reg64(rd, rs); else { mov_reg64_reg64(rd, rs); add_reg64_reg64(rd, rt); } #else int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs); int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs); int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt); int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt); int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd); int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd); if (rt1 != rd1 && rs1 != rd1) { mov_reg32_reg32(rd1, rs1); mov_reg32_reg32(rd2, rs2); add_reg32_reg32(rd1, rt1); adc_reg32_reg32(rd2, rt2); } else { int temp = lru_register(); free_register(temp); mov_reg32_reg32(temp, rs1); add_reg32_reg32(temp, rt1); mov_reg32_reg32(rd1, temp); mov_reg32_reg32(temp, rs2); adc_reg32_reg32(temp, rt2); mov_reg32_reg32(rd2, temp); } #endif #endif } void gendsub(void) { #ifdef INTERPRET_DSUB gencallinterp((native_type)cached_interpreter_table.DSUB, 0); #else #ifdef __x86_64__ int rs = allocate_register_64((uint64_t *)dst->f.r.rs); int rt = allocate_register_64((uint64_t *)dst->f.r.rt); int rd = allocate_register_64_w((uint64_t *)dst->f.r.rd); if (rs == rd) sub_reg64_reg64(rd, rt); else if (rt == rd) { neg_reg64(rd); add_reg64_reg64(rd, rs); } else { mov_reg64_reg64(rd, rs); sub_reg64_reg64(rd, rt); } #else int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs); int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs); int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt); int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt); int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd); int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd); if (rt1 != rd1 && rs1 != rd1) { mov_reg32_reg32(rd1, rs1); mov_reg32_reg32(rd2, rs2); sub_reg32_reg32(rd1, rt1); sbb_reg32_reg32(rd2, rt2); } else { int temp = lru_register(); free_register(temp); mov_reg32_reg32(temp, rs1); sub_reg32_reg32(temp, rt1); mov_reg32_reg32(rd1, temp); mov_reg32_reg32(temp, rs2); sbb_reg32_reg32(temp, rt2); mov_reg32_reg32(rd2, temp); } #endif #endif } void gendsubu(void) { #ifdef INTERPRET_DSUBU gencallinterp((native_type)cached_interpreter_table.DSUBU, 0); #else #ifdef __x86_64__ int rs = allocate_register_64((uint64_t *)dst->f.r.rs); int rt = allocate_register_64((uint64_t *)dst->f.r.rt); int rd = allocate_register_64_w((uint64_t *)dst->f.r.rd); if (rs == rd) sub_reg64_reg64(rd, rt); else if (rt == rd) { neg_reg64(rd); add_reg64_reg64(rd, rs); } else { mov_reg64_reg64(rd, rs); sub_reg64_reg64(rd, rt); } #else int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs); int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs); int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt); int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt); int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd); int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd); if (rt1 != rd1 && rs1 != rd1) { mov_reg32_reg32(rd1, rs1); mov_reg32_reg32(rd2, rs2); sub_reg32_reg32(rd1, rt1); sbb_reg32_reg32(rd2, rt2); } else { int temp = lru_register(); free_register(temp); mov_reg32_reg32(temp, rs1); sub_reg32_reg32(temp, rt1); mov_reg32_reg32(rd1, temp); mov_reg32_reg32(temp, rs2); sbb_reg32_reg32(temp, rt2); mov_reg32_reg32(rd2, temp); } #endif #endif } void genteq(void) { gencallinterp((native_type)cached_interpreter_table.TEQ, 0); } void gendsll(void) { #ifdef INTERPRET_DSLL gencallinterp((native_type)cached_interpreter_table.DSLL, 0); #else #ifdef __x86_64__ int rt = allocate_register_64((uint64_t *)dst->f.r.rt); int rd = allocate_register_64_w((uint64_t *)dst->f.r.rd); mov_reg64_reg64(rd, rt); shl_reg64_imm8(rd, dst->f.r.sa); #else int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt); int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt); int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd); int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd); mov_reg32_reg32(rd1, rt1); mov_reg32_reg32(rd2, rt2); shld_reg32_reg32_imm8(rd2, rd1, dst->f.r.sa); shl_reg32_imm8(rd1, dst->f.r.sa); if (dst->f.r.sa & 0x20) { mov_reg32_reg32(rd2, rd1); xor_reg32_reg32(rd1, rd1); } #endif #endif } void gendsrl(void) { #ifdef INTERPRET_DSRL gencallinterp((native_type)cached_interpreter_table.DSRL, 0); #else #ifdef __x86_64__ int rt = allocate_register_64((uint64_t *)dst->f.r.rt); int rd = allocate_register_64_w((uint64_t *)dst->f.r.rd); mov_reg64_reg64(rd, rt); shr_reg64_imm8(rd, dst->f.r.sa); #else int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt); int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt); int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd); int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd); mov_reg32_reg32(rd1, rt1); mov_reg32_reg32(rd2, rt2); shrd_reg32_reg32_imm8(rd1, rd2, dst->f.r.sa); shr_reg32_imm8(rd2, dst->f.r.sa); if (dst->f.r.sa & 0x20) { mov_reg32_reg32(rd1, rd2); xor_reg32_reg32(rd2, rd2); } #endif #endif } void gendsra(void) { #ifdef INTERPRET_DSRA gencallinterp((native_type)cached_interpreter_table.DSRA, 0); #else #ifdef __x86_64__ int rt = allocate_register_64((uint64_t *)dst->f.r.rt); int rd = allocate_register_64_w((uint64_t *)dst->f.r.rd); mov_reg64_reg64(rd, rt); sar_reg64_imm8(rd, dst->f.r.sa); #else int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt); int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt); int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd); int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd); mov_reg32_reg32(rd1, rt1); mov_reg32_reg32(rd2, rt2); shrd_reg32_reg32_imm8(rd1, rd2, dst->f.r.sa); sar_reg32_imm8(rd2, dst->f.r.sa); if (dst->f.r.sa & 0x20) { mov_reg32_reg32(rd1, rd2); sar_reg32_imm8(rd2, 31); } #endif #endif } void gendsll32(void) { #ifdef INTERPRET_DSLL32 gencallinterp((native_type)cached_interpreter_table.DSLL32, 0); #else #ifdef __x86_64__ int rt = allocate_register_64((uint64_t *)dst->f.r.rt); int rd = allocate_register_64_w((uint64_t *)dst->f.r.rd); mov_reg64_reg64(rd, rt); shl_reg64_imm8(rd, dst->f.r.sa + 32); #else int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt); int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd); int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd); mov_reg32_reg32(rd2, rt1); shl_reg32_imm8(rd2, dst->f.r.sa); xor_reg32_reg32(rd1, rd1); #endif #endif } void gendsrl32(void) { #ifdef INTERPRET_DSRL32 gencallinterp((native_type)cached_interpreter_table.DSRL32, 0); #else #ifdef __x86_64__ int rt = allocate_register_64((uint64_t *)dst->f.r.rt); int rd = allocate_register_64_w((uint64_t *)dst->f.r.rd); mov_reg64_reg64(rd, rt); shr_reg64_imm8(rd, dst->f.r.sa + 32); #else int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt); int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd); int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd); mov_reg32_reg32(rd1, rt2); shr_reg32_imm8(rd1, dst->f.r.sa); xor_reg32_reg32(rd2, rd2); #endif #endif } void gendsra32(void) { #ifdef INTERPRET_DSRA32 gencallinterp((native_type)cached_interpreter_table.DSRA32, 0); #else #ifdef __x86_64__ int rt = allocate_register_64((uint64_t *)dst->f.r.rt); int rd = allocate_register_64_w((uint64_t *)dst->f.r.rd); mov_reg64_reg64(rd, rt); sar_reg64_imm8(rd, dst->f.r.sa + 32); #else int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt); int rd = allocate_register_w((unsigned int *)dst->f.r.rd); mov_reg32_reg32(rd, rt2); sar_reg32_imm8(rd, dst->f.r.sa); #endif #endif } mupen64plus-core/doc/emuwiki-api-doc/Mupen64Plus_v2.0_Core_Video_Extension.txt000664 001750 001750 00000020445 12655644434 030347 0ustar00sergiosergio000000 000000 [[Mupen64Plus v2.0 Core API v1.0|Mupen64Plus v2.0 API]] = Mupen64Plus v2.0 Video Extension API = Most libmupen64plus functions return an m64p_error return code, which is an enumerated type defined in [[Mupen64Plus v2.0 headers#m64p_types.h|m64p_types.h]]. Plugin code should check the return value of each call to a libmupen64plus function. All of these functions should only be called from within the video plugin; they should not be called from the front-end. == Startup/Shutdown Functions == {| border="1" |Prototype |'''m64p_error VidExt_Init(void)''' |- |Input Parameters |N/A |- |Requirements |This function should be called before any other Video Extension functions. |- |Usage |This function should be called from within the RomOpen() video plugin function call. The default SDL implementation of this function simply calls SDL_InitSubSystem(SDL_INIT_VIDEO). It does not open a rendering window or switch video modes. |}
{| border="1" |Prototype |'''m64p_error VidExt_Quit(void)''' |- |Input Parameters |N/A |- |Usage |This function closes any open rendering window and shuts down the video system. The default SDL implementation of this function calls SDL_QuitSubSystem(SDL_INIT_VIDEO). This function should be called from within the RomClosed() video plugin function. |}
== Screen Handling Functions == {| border="1" |Prototype |'''m64p_error VidExt_ListFullscreenModes(m64p_2d_size *SizeArray, int *NumSizes)''' |- |Input Parameters |'''SizeArray''' Pointer to an array of m64p_2d_size objects, defined in [[Mupen64Plus v2.0 headers#m64p_types.h|m64p_types.h]]
'''NumSizes''' Pointer to an integer which contains the size of '''SizeArray''' for input, and the number of size objects stored for output. |- |Requirements |The video extension must be initialized before calling this function. |- |Usage |This function is used to enumerate the available resolutions for fullscreen video modes. An array '''SizeArray''' is passed into the function, which is then filled (up to *'''NumSizes''' objects) with resolution sizes. The number of sizes actually written is stored in the integer which is pointed to by '''NumSizes'''. |}
{| border="1" |Prototype |'''m64p_error VidExt_SetVideoMode(int Width, int Height, int BitsPerPixel, m64p_video_mode ScreenMode, m64p_video_flags Flags)''' |- |Input Parameters |'''Width''' Horizontal resolution in pixels of desired video window
'''Height''' Vertical resolution in pixels of desired video window
'''BitsPerPixel''' Pixel color resolution of desired video window. This value must be 16, 24, or 32
'''ScreenMode''' Either M64VIDEO_WINDOWED or M64VIDEO_FULLSCREEN
'''Flags''' Logical-OR combination of flags which describes the video plugin's capabilities. |- |Requirements |The video extension must be initialized before calling this function. |- |Usage |This function creates a rendering window or switches into a fullscreen video mode. Any desired OpenGL attributes should be set before calling this function. |}
{| border="1" |Prototype |'''m64p_error VidExt_SetCaption(const char *Title)''' |- |Input Parameters |'''Title''' Pointer to a NULL-terminated string containing the desired title text of the emulator rendering window |- |Requirements |The video extension must be initialized before calling this function. |- |Usage |This function sets the caption text of the emulator rendering window. |}
{| border="1" |Prototype |'''m64p_error VidExt_ToggleFullScreen(void)''' |- |Input Parameters |N/A |- |Requirements |The video extension must be initialized before calling this function. The rendering window should already be created. |- |Usage |This function toggles between fullscreen and windowed rendering modes. |}
{| border="1" |Prototype |'''m64p_error VidExt_ResizeWindow(int Width, int Height)''' |- |Input Parameters |'''Width''' Horizontal resolution of resized window in pixels
'''Height''' Vertical resolution of resized window in pixels |- |Requirements |The video extension must be initialized before calling this function. The rendering window should already be created. |- |Usage |This function is called when the video plugin has resized its OpenGL output viewport in response to a ResizeVideoOutput() call, and requests that the window manager update the OpenGL rendering window size to match. If a front-end application does not support resizable windows and never sets the M64CORE_VIDEO_SIZE core variable with the M64CMD_CORE_STATE_SET command, then this function should not be called. |}
===Window Resizing=== The window resizing functionality is particularly complicated, so here is a high-level description of the events which make it happen: ====Without video extension:==== # In VidExt_SetVideoMode(), check if M64VIDEOFLAG_SUPPORT_RESIZING is set #* if True, create SDL window with RESIZABLE attribute # Core receives SDL_RESIZE messages in SDL event loop # If present, Core calls ResizeVideoOutput function in video plugin # Video Plugin calls ResizeWindow function in Video Extension #* Core calls SDL_SetVideoMode() # Core emits M64CORE_VIDEO_SIZE state changed callback ====With video extension:==== # in Front-end SetVideoMode() callback #* if M64VIDEOFLAG_SUPPORT_RESIZING is set, create resizable window frame # Front-end GUI gets window resize notification # Front-end calls CoreDoCommand w/ M64CMD_CORE_STATE_SET, w/ M64CORE_VIDEO_SIZE # If present, Core calls ResizeVideoOutput function in video plugin # Video Plugin calls ResizeWindow function in Video Extension # Core emits M64CORE_VIDEO_SIZE state changed callback In the Core Video Extension function ResizeWindow, the SDL function SetVideoMode() is called. This function will destroy the current OpenGL context and create a new one. For this reason, any video plugin which supports resizable windows must completely reset its OpenGL state including uploading any textures, FBOs, programs, etc after calling the VidExt_ResizeWindow function. == OpenGL Functions == {| border="1" |Prototype |'''void * VidExt_GL_GetProcAddress(const char* Proc)''' |- |Input Parameters |'''Proc''' Pointer to a NULL-terminated string containing the name of the desired OpenGL extension function. |- |Requirements |The video extension must be initialized before calling this function. |- |Usage |This function is used to get a pointer to an OpenGL extension function. This is only necessary on the Windows platform, because the OpenGL implementation shipped with Windows only supports OpenGL version 1.1. |}
{| border="1" |Prototype |'''m64p_error VidExt_GL_SetAttribute(m64p_GLattr Attr, int Value)''' |- |Input Parameters |'''Attr''' Enumerated type (defined in [[Mupen64Plus v2.0 headers#m64p_types.h|m64p_types.h]]) specifying which OpenGL attribute to set
'''Value''' Value to set for the attribute |- |Requirements |The video extension must be initialized before calling this function. The desired attributes should be set before calling '''VidExt_SetVideoMode''' |- |Usage |This function is used to set certain OpenGL attributes which must be specified before creating the rendering window with '''VidExt_SetVideoMode'''. |}
{| border="1" |Prototype |'''m64p_error VidExt_GL_GetAttribute(m64p_GLattr Attr, int *pValue)''' |- |Input Parameters |'''Attr''' Enumerated type (defined in [[Mupen64Plus v2.0 headers#m64p_types.h|m64p_types.h]]) specifying OpenGL attribute of which to get value
'''pValue''' Pointer to integer Value which will be set to attribute's value |- |Requirements |The video extension must be initialized before calling this function. |- |Usage |This function may be used to check that OpenGL attributes where successfully set to the rendering window after the '''VidExt_SetVideoMode''' function call. |}
{| border="1" |Prototype |'''m64p_error VidExt_GL_SwapBuffers(void)''' |- |Input Parameters |N/A |- |Requirements |The video extension must be initialized before calling this function. The rendering window should already be created. |- |Usage |This function is used to swap the front/back buffers after rendering an output video frame. |}
gles2rice/src/OGLDebug.h000664 001750 001750 00000002065 12655644434 016131 0ustar00sergiosergio000000 000000 /* OGLDebug.h Copyright (C) 2009 Richard Goedeken This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #if !defined(OPENGL_DEBUG_H) #define OPENGL_DEBUG_H #if defined(OPENGL_DEBUG) #define OPENGL_CHECK_ERRORS { const GLenum errcode = glGetError(); if (errcode != GL_NO_ERROR) fprintf(stderr, "OpenGL Error code %i in '%s' line %i\n", errcode, __FILE__, __LINE__-1); } #else #define OPENGL_CHECK_ERRORS #endif #endif /* OPENGL_DEBUG_H */ libretro/libretro_memory.h000664 001750 001750 00000000452 12655644434 017125 0ustar00sergiosergio000000 000000 #ifndef M64P_LIBRETRO_MEMORY_H #define M64P_LIBRETRO_MEMORY_H #include typedef struct _save_memory_data { uint8_t eeprom[0x800]; uint8_t mempack[4][0x8000]; uint8_t sram[0x8000]; uint8_t flashram[0x20000]; } save_memory_data; extern save_memory_data saved_memory; #endif mupen64plus-core/src/plugin/audio_libretro/audio_utils.h000664 001750 001750 00000012675 12655644434 024644 0ustar00sergiosergio000000 000000 /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. * * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with RetroArch. * If not, see . */ #ifndef AUDIO_UTILS_H #define AUDIO_UTILS_H #ifdef __cplusplus extern "C" { #endif #include #include #ifdef HAVE_CONFIG_H #include "../config.h" #endif #if defined(__SSE2__) #define audio_convert_s16_to_float audio_convert_s16_to_float_SSE2 #define audio_convert_float_to_s16 audio_convert_float_to_s16_SSE2 /** * audio_convert_s16_to_float_SSE2: * @out : output buffer * @in : input buffer * @samples : size of samples to be converted * @gain : gain applied to the audio volume * * Converts audio samples from signed integer 16-bit * to floating point. * * SSE2 implementation callback function. **/ void audio_convert_s16_to_float_SSE2(float *out, const int16_t *in, size_t samples, float gain); /** * audio_convert_float_to_s16_SSE2: * @out : output buffer * @in : input buffer * @samples : size of samples to be converted * * Converts audio samples from floating point * to signed integer 16-bit. * * SSE2 implementation callback function. **/ void audio_convert_float_to_s16_SSE2(int16_t *out, const float *in, size_t samples); #elif defined(__ALTIVEC__) #define audio_convert_s16_to_float audio_convert_s16_to_float_altivec #define audio_convert_float_to_s16 audio_convert_float_to_s16_altivec /** * audio_convert_s16_to_float_altivec: * @out : output buffer * @in : input buffer * @samples : size of samples to be converted * @gain : gain applied to the audio volume * * Converts audio samples from signed integer 16-bit * to floating point. * * AltiVec implementation callback function. **/ void audio_convert_s16_to_float_altivec(float *out, const int16_t *in, size_t samples, float gain); /** * audio_convert_float_to_s16_altivec: * @out : output buffer * @in : input buffer * @samples : size of samples to be converted * * Converts audio samples from floating point * to signed integer 16-bit. * * AltiVec implementation callback function. **/ void audio_convert_float_to_s16_altivec(int16_t *out, const float *in, size_t samples); #elif defined(__ARM_NEON__) #define audio_convert_s16_to_float audio_convert_s16_to_float_arm #define audio_convert_float_to_s16 audio_convert_float_to_s16_arm void (*audio_convert_s16_to_float_arm)(float *out, const int16_t *in, size_t samples, float gain); void (*audio_convert_float_to_s16_arm)(int16_t *out, const float *in, size_t samples); #elif defined(_MIPS_ARCH_ALLEGREX) #define audio_convert_s16_to_float audio_convert_s16_to_float_ALLEGREX #define audio_convert_float_to_s16 audio_convert_float_to_s16_ALLEGREX /** * audio_convert_s16_to_float_ALLEGREX: * @out : output buffer * @in : input buffer * @samples : size of samples to be converted * @gain : gain applied to the audio volume * * Converts audio samples from signed integer 16-bit * to floating point. * * MIPS ALLEGREX implementation callback function. **/ void audio_convert_s16_to_float_ALLEGREX(float *out, const int16_t *in, size_t samples, float gain); /** * audio_convert_float_to_s16_ALLEGREX: * @out : output buffer * @in : input buffer * @samples : size of samples to be converted * * Converts audio samples from floating point * to signed integer 16-bit. * * MIPS ALLEGREX implementation callback function. **/ void audio_convert_float_to_s16_ALLEGREX(int16_t *out, const float *in, size_t samples); #else #define audio_convert_s16_to_float audio_convert_s16_to_float_C #define audio_convert_float_to_s16 audio_convert_float_to_s16_C #endif /** * audio_convert_s16_to_float_C: * @out : output buffer * @in : input buffer * @samples : size of samples to be converted * @gain : gain applied to the audio volume * * Converts audio samples from signed integer 16-bit * to floating point. * * C implementation callback function. **/ void audio_convert_s16_to_float_C(float *out, const int16_t *in, size_t samples, float gain); /** * audio_convert_float_to_s16_C: * @out : output buffer * @in : input buffer * @samples : size of samples to be converted * * Converts audio samples from floating point * to signed integer 16-bit. * * C implementation callback function. **/ void audio_convert_float_to_s16_C(int16_t *out, const float *in, size_t samples); /** * audio_convert_init_simd: * * Sets up function pointers for audio conversion * functions based on CPU features. **/ void audio_convert_init_simd(void); #ifdef __cplusplus } #endif #endif mupen64plus-video-gliden64/src/GLideNHQ/TextureFilters_hq4x.cpp000664 001750 001750 00000062324 12655644434 025431 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Based on Maxim Stepin and Rice1964 hq4x code */ #include #include #include "TextureFilters.h" #if !_16BPP_HACK static uint32 RGB444toYUV[4096]; #define RGB444toYUV(val) RGB444toYUV[val & 0x0FFF] /* val = ARGB4444 */ static uint32 RGB555toYUV(uint32 val) { uint32 r, g, b, Y, u, v; b = (val & 0x7C00) >> 7; g = (val & 0x03E0) >> 2; r = (val & 0x001F) << 3; r |= r >> 5; g |= g >> 5; b |= b >> 5; Y = (r + g + b) >> 2; u = 128 + ((r - b) >> 2); v = 128 + ((2*g - r - b)>>3); return ((Y << 16) | (u << 8) | v); } static uint32 RGB565toYUV(uint32 val) { uint32 r, g, b, Y, u, v; b = (val & 0xF800) >> 8; g = (val & 0x07E0) >> 3; r = (val & 0x001F) << 3; r |= r >> 5; g |= g >> 6; b |= b >> 5; Y = (r + g + b) >> 2; u = 128 + ((r - b) >> 2); v = 128 + ((2*g - r - b)>>3); return ((Y << 16) | (u << 8) | v); } #endif /* !_16BPP_HACK */ static uint32 RGB888toYUV(uint32 val) { uint32 r, g, b, Y, u, v; b = (val & 0x00ff0000) >> 16; g = (val & 0x0000ff00) >> 8; r = val & 0x000000ff; Y = (r + g + b) >> 2; u = (0x00000200 + r - b) >> 2; v = (0x00000400 + (g << 1) - r - b) >> 3; return ((Y << 16) | (u << 8) | v); } #define Ymask 0x00FF0000 #define Umask 0x0000FF00 #define Vmask 0x000000FF #define trY 0x00300000 // ? #define trU 0x00000700 // ?? #define trV 0x00000006 // ??? #define HQ4X_INTERP1(n, b) \ static void hq4x_Interp1_##n (uint8 * pc, uint##b p1, uint##b p2) \ { \ /* *((uint##b*)pc) = (p1*3+p2) >> 2; */ \ *((uint##b*)pc) = INTERP_##n##_MASK_1_3((INTERP_##n##_MASK_1_3(p1)*3 + INTERP_##n##_MASK_1_3(p2)) / 4) \ | INTERP_##n##_MASK_SHIFTBACK_2_4((INTERP_##n##_MASK_SHIFT_2_4(p1)*3 + INTERP_##n##_MASK_SHIFT_2_4(p2)) / 4 ); \ } #define HQ4X_INTERP2(n, b) \ static void hq4x_Interp2_##n (uint8 * pc, uint##b p1, uint##b p2, uint##b p3) \ { \ /**((uint##b*)pc) = (p1*2+p2+p3) >> 2;*/ \ *((uint##b*)pc) = INTERP_##n##_MASK_1_3((INTERP_##n##_MASK_1_3(p1)*2 + INTERP_##n##_MASK_1_3(p2) + INTERP_##n##_MASK_1_3(p3)) / 4) \ | INTERP_##n##_MASK_SHIFTBACK_2_4((INTERP_##n##_MASK_SHIFT_2_4(p1)*2 + INTERP_##n##_MASK_SHIFT_2_4(p2) + INTERP_##n##_MASK_SHIFT_2_4(p3)) / 4); \ } #define HQ4X_INTERP3(n, b) \ static void hq4x_Interp3_##n (uint8 * pc, uint##b p1, uint##b p2) \ { \ /**((uint##b*)pc) = (p1*7+p2)/8;*/ \ *((uint##b*)pc) = INTERP_##n##_MASK_1_3((INTERP_##n##_MASK_1_3(p1)*7 + INTERP_##n##_MASK_1_3(p2)) / 8) \ | INTERP_##n##_MASK_SHIFTBACK_2_4((INTERP_##n##_MASK_SHIFT_2_4(p1)*7 + INTERP_##n##_MASK_SHIFT_2_4(p2)) / 8); \ } #define HQ4X_INTERP5(n, b) \ static void hq4x_Interp5_##n (uint8 * pc, uint##b p1, uint##b p2) \ { \ /**((uint##b*)pc) = (p1+p2) >> 1;*/ \ *((uint##b*)pc) = INTERP_##n##_MASK_1_3((INTERP_##n##_MASK_1_3(p1) + INTERP_##n##_MASK_1_3(p2)) / 2) \ | INTERP_##n##_MASK_SHIFTBACK_2_4((INTERP_##n##_MASK_SHIFT_2_4(p1) + INTERP_##n##_MASK_SHIFT_2_4(p2)) / 2); \ } #define HQ4X_INTERP6(n, b) \ static void hq4x_Interp6_##n (uint8 * pc, uint##b p1, uint##b p2, uint##b p3) \ { \ /**((uint##b*)pc) = (p1*5+p2*2+p3)/8;*/ \ *((uint##b*)pc) = INTERP_##n##_MASK_1_3((INTERP_##n##_MASK_1_3(p1)*5 + INTERP_##n##_MASK_1_3(p2)*2 + INTERP_##n##_MASK_1_3(p3)) / 8) \ | INTERP_##n##_MASK_SHIFTBACK_2_4((INTERP_##n##_MASK_SHIFT_2_4(p1)*5 + INTERP_##n##_MASK_SHIFT_2_4(p2)*2 + INTERP_##n##_MASK_SHIFT_2_4(p3)) / 8); \ } #define HQ4X_INTERP7(n, b) \ static void hq4x_Interp7_##n (uint8 * pc, uint##b p1, uint##b p2, uint##b p3) \ { \ /**((uint##b*)pc) = (p1*6+p2+p3)/8;*/ \ *((uint##b*)pc) = INTERP_##n##_MASK_1_3((INTERP_##n##_MASK_1_3(p1)*6 + INTERP_##n##_MASK_1_3(p2) + INTERP_##n##_MASK_1_3(p3)) / 8) \ | INTERP_##n##_MASK_SHIFTBACK_2_4((INTERP_##n##_MASK_SHIFT_2_4(p1)*6 + INTERP_##n##_MASK_SHIFT_2_4(p2) + INTERP_##n##_MASK_SHIFT_2_4(p3)) / 8); \ } #define HQ4X_INTERP8(n, b) \ static void hq4x_Interp8_##n (uint8 * pc, uint##b p1, uint##b p2) \ { \ /**((uint##b*)pc) = (p1*5+p2*3)/8;*/ \ *((uint##b*)pc) = INTERP_##n##_MASK_1_3((INTERP_##n##_MASK_1_3(p1)*5 + INTERP_##n##_MASK_1_3(p2)*3) / 8) \ | INTERP_##n##_MASK_SHIFTBACK_2_4((INTERP_##n##_MASK_SHIFT_2_4(p1)*5 + INTERP_##n##_MASK_SHIFT_2_4(p2)*3) / 8); \ } #if !_16BPP_HACK #define INTERP_4444_MASK_1_3(v) (v & 0x0F0F) #define INTERP_4444_MASK_SHIFT_2_4(v) ((v & 0xF0F0) >> 4) #define INTERP_4444_MASK_SHIFTBACK_2_4(v) (INTERP_4444_MASK_1_3(v) << 4) HQ4X_INTERP1(4444, 16) HQ4X_INTERP2(4444, 16) HQ4X_INTERP3(4444, 16) HQ4X_INTERP5(4444, 16) HQ4X_INTERP6(4444, 16) HQ4X_INTERP7(4444, 16) HQ4X_INTERP8(4444, 16) #define INTERP_1555_MASK_1_3(v) (v & 0x7C1F) #define INTERP_1555_MASK_SHIFT_2_4(v) ((v & 0x83E0) >> 5) #define INTERP_1555_MASK_SHIFTBACK_2_4(v) (INTERP_1555_MASK_1_3(v) << 5) HQ4X_INTERP1(1555, 16) HQ4X_INTERP2(1555, 16) HQ4X_INTERP3(1555, 16) HQ4X_INTERP5(1555, 16) HQ4X_INTERP6(1555, 16) HQ4X_INTERP7(1555, 16) HQ4X_INTERP8(1555, 16) #define INTERP_565_MASK_1_3(v) (v & 0xF81F) #define INTERP_565_MASK_SHIFT_2_4(v) ((v & 0x7E0) >> 5) #define INTERP_565_MASK_SHIFTBACK_2_4(v) (INTERP_565_MASK_1_3(v) << 5) HQ4X_INTERP1(565, 16) HQ4X_INTERP2(565, 16) HQ4X_INTERP3(565, 16) HQ4X_INTERP5(565, 16) HQ4X_INTERP6(565, 16) HQ4X_INTERP7(565, 16) HQ4X_INTERP8(565, 16) #endif /* !_16BPP_HACK */ #define INTERP_8888_MASK_1_3(v) (v & 0x00FF00FF) #define INTERP_8888_MASK_SHIFT_2_4(v) ((v & 0xFF00FF00) >> 8) #define INTERP_8888_MASK_SHIFTBACK_2_4(v) (INTERP_8888_MASK_1_3(v) << 8) HQ4X_INTERP1(8888, 32) HQ4X_INTERP2(8888, 32) HQ4X_INTERP3(8888, 32) HQ4X_INTERP5(8888, 32) HQ4X_INTERP6(8888, 32) HQ4X_INTERP7(8888, 32) HQ4X_INTERP8(8888, 32) #define PIXEL00_0 *((int*)(pOut)) = c[5]; #define PIXEL00_11 hq4x_Interp1(pOut, c[5], c[4]); #define PIXEL00_12 hq4x_Interp1(pOut, c[5], c[2]); #define PIXEL00_20 hq4x_Interp2(pOut, c[5], c[2], c[4]); #define PIXEL00_50 hq4x_Interp5(pOut, c[2], c[4]); #define PIXEL00_80 hq4x_Interp8(pOut, c[5], c[1]); #define PIXEL00_81 hq4x_Interp8(pOut, c[5], c[4]); #define PIXEL00_82 hq4x_Interp8(pOut, c[5], c[2]); #define PIXEL01_0 *((int*)(pOut+BPP)) = c[5]; #define PIXEL01_10 hq4x_Interp1(pOut+BPP, c[5], c[1]); #define PIXEL01_12 hq4x_Interp1(pOut+BPP, c[5], c[2]); #define PIXEL01_14 hq4x_Interp1(pOut+BPP, c[2], c[5]); #define PIXEL01_21 hq4x_Interp2(pOut+BPP, c[2], c[5], c[4]); #define PIXEL01_31 hq4x_Interp3(pOut+BPP, c[5], c[4]); #define PIXEL01_50 hq4x_Interp5(pOut+BPP, c[2], c[5]); #define PIXEL01_60 hq4x_Interp6(pOut+BPP, c[5], c[2], c[4]); #define PIXEL01_61 hq4x_Interp6(pOut+BPP, c[5], c[2], c[1]); #define PIXEL01_82 hq4x_Interp8(pOut+BPP, c[5], c[2]); #define PIXEL01_83 hq4x_Interp8(pOut+BPP, c[2], c[4]); #define PIXEL02_0 *((int*)(pOut+BPP2)) = c[5]; #define PIXEL02_10 hq4x_Interp1(pOut+BPP2, c[5], c[3]); #define PIXEL02_11 hq4x_Interp1(pOut+BPP2, c[5], c[2]); #define PIXEL02_13 hq4x_Interp1(pOut+BPP2, c[2], c[5]); #define PIXEL02_21 hq4x_Interp2(pOut+BPP2, c[2], c[5], c[6]); #define PIXEL02_32 hq4x_Interp3(pOut+BPP2, c[5], c[6]); #define PIXEL02_50 hq4x_Interp5(pOut+BPP2, c[2], c[5]); #define PIXEL02_60 hq4x_Interp6(pOut+BPP2, c[5], c[2], c[6]); #define PIXEL02_61 hq4x_Interp6(pOut+BPP2, c[5], c[2], c[3]); #define PIXEL02_81 hq4x_Interp8(pOut+BPP2, c[5], c[2]); #define PIXEL02_83 hq4x_Interp8(pOut+BPP2, c[2], c[6]); #define PIXEL03_0 *((int*)(pOut+BPP3)) = c[5]; #define PIXEL03_11 hq4x_Interp1(pOut+BPP3, c[5], c[2]); #define PIXEL03_12 hq4x_Interp1(pOut+BPP3, c[5], c[6]); #define PIXEL03_20 hq4x_Interp2(pOut+BPP3, c[5], c[2], c[6]); #define PIXEL03_50 hq4x_Interp5(pOut+BPP3, c[2], c[6]); #define PIXEL03_80 hq4x_Interp8(pOut+BPP3, c[5], c[3]); #define PIXEL03_81 hq4x_Interp8(pOut+BPP3, c[5], c[2]); #define PIXEL03_82 hq4x_Interp8(pOut+BPP3, c[5], c[6]); #define PIXEL10_0 *((int*)(pOut+BpL)) = c[5]; #define PIXEL10_10 hq4x_Interp1(pOut+BpL, c[5], c[1]); #define PIXEL10_11 hq4x_Interp1(pOut+BpL, c[5], c[4]); #define PIXEL10_13 hq4x_Interp1(pOut+BpL, c[4], c[5]); #define PIXEL10_21 hq4x_Interp2(pOut+BpL, c[4], c[5], c[2]); #define PIXEL10_32 hq4x_Interp3(pOut+BpL, c[5], c[2]); #define PIXEL10_50 hq4x_Interp5(pOut+BpL, c[4], c[5]); #define PIXEL10_60 hq4x_Interp6(pOut+BpL, c[5], c[4], c[2]); #define PIXEL10_61 hq4x_Interp6(pOut+BpL, c[5], c[4], c[1]); #define PIXEL10_81 hq4x_Interp8(pOut+BpL, c[5], c[4]); #define PIXEL10_83 hq4x_Interp8(pOut+BpL, c[4], c[2]); #define PIXEL11_0 *((int*)(pOut+BpL+BPP)) = c[5]; #define PIXEL11_30 hq4x_Interp3(pOut+BpL+BPP, c[5], c[1]); #define PIXEL11_31 hq4x_Interp3(pOut+BpL+BPP, c[5], c[4]); #define PIXEL11_32 hq4x_Interp3(pOut+BpL+BPP, c[5], c[2]); #define PIXEL11_70 hq4x_Interp7(pOut+BpL+BPP, c[5], c[4], c[2]); #define PIXEL12_0 *((int*)(pOut+BpL+BPP2)) = c[5]; #define PIXEL12_30 hq4x_Interp3(pOut+BpL+BPP2, c[5], c[3]); #define PIXEL12_31 hq4x_Interp3(pOut+BpL+BPP2, c[5], c[2]); #define PIXEL12_32 hq4x_Interp3(pOut+BpL+BPP2, c[5], c[6]); #define PIXEL12_70 hq4x_Interp7(pOut+BpL+BPP2, c[5], c[6], c[2]); #define PIXEL13_0 *((int*)(pOut+BpL+BPP3)) = c[5]; #define PIXEL13_10 hq4x_Interp1(pOut+BpL+BPP3, c[5], c[3]); #define PIXEL13_12 hq4x_Interp1(pOut+BpL+BPP3, c[5], c[6]); #define PIXEL13_14 hq4x_Interp1(pOut+BpL+BPP3, c[6], c[5]); #define PIXEL13_21 hq4x_Interp2(pOut+BpL+BPP3, c[6], c[5], c[2]); #define PIXEL13_31 hq4x_Interp3(pOut+BpL+BPP3, c[5], c[2]); #define PIXEL13_50 hq4x_Interp5(pOut+BpL+BPP3, c[6], c[5]); #define PIXEL13_60 hq4x_Interp6(pOut+BpL+BPP3, c[5], c[6], c[2]); #define PIXEL13_61 hq4x_Interp6(pOut+BpL+BPP3, c[5], c[6], c[3]); #define PIXEL13_82 hq4x_Interp8(pOut+BpL+BPP3, c[5], c[6]); #define PIXEL13_83 hq4x_Interp8(pOut+BpL+BPP3, c[6], c[2]); #define PIXEL20_0 *((int*)(pOut+BpL+BpL)) = c[5]; #define PIXEL20_10 hq4x_Interp1(pOut+BpL+BpL, c[5], c[7]); #define PIXEL20_12 hq4x_Interp1(pOut+BpL+BpL, c[5], c[4]); #define PIXEL20_14 hq4x_Interp1(pOut+BpL+BpL, c[4], c[5]); #define PIXEL20_21 hq4x_Interp2(pOut+BpL+BpL, c[4], c[5], c[8]); #define PIXEL20_31 hq4x_Interp3(pOut+BpL+BpL, c[5], c[8]); #define PIXEL20_50 hq4x_Interp5(pOut+BpL+BpL, c[4], c[5]); #define PIXEL20_60 hq4x_Interp6(pOut+BpL+BpL, c[5], c[4], c[8]); #define PIXEL20_61 hq4x_Interp6(pOut+BpL+BpL, c[5], c[4], c[7]); #define PIXEL20_82 hq4x_Interp8(pOut+BpL+BpL, c[5], c[4]); #define PIXEL20_83 hq4x_Interp8(pOut+BpL+BpL, c[4], c[8]); #define PIXEL21_0 *((int*)(pOut+BpL+BpL+BPP)) = c[5]; #define PIXEL21_30 hq4x_Interp3(pOut+BpL+BpL+BPP, c[5], c[7]); #define PIXEL21_31 hq4x_Interp3(pOut+BpL+BpL+BPP, c[5], c[8]); #define PIXEL21_32 hq4x_Interp3(pOut+BpL+BpL+BPP, c[5], c[4]); #define PIXEL21_70 hq4x_Interp7(pOut+BpL+BpL+BPP, c[5], c[4], c[8]); #define PIXEL22_0 *((int*)(pOut+BpL+BpL+BPP2)) = c[5]; #define PIXEL22_30 hq4x_Interp3(pOut+BpL+BpL+BPP2, c[5], c[9]); #define PIXEL22_31 hq4x_Interp3(pOut+BpL+BpL+BPP2, c[5], c[6]); #define PIXEL22_32 hq4x_Interp3(pOut+BpL+BpL+BPP2, c[5], c[8]); #define PIXEL22_70 hq4x_Interp7(pOut+BpL+BpL+BPP2, c[5], c[6], c[8]); #define PIXEL23_0 *((int*)(pOut+BpL+BpL+BPP3)) = c[5]; #define PIXEL23_10 hq4x_Interp1(pOut+BpL+BpL+BPP3, c[5], c[9]); #define PIXEL23_11 hq4x_Interp1(pOut+BpL+BpL+BPP3, c[5], c[6]); #define PIXEL23_13 hq4x_Interp1(pOut+BpL+BpL+BPP3, c[6], c[5]); #define PIXEL23_21 hq4x_Interp2(pOut+BpL+BpL+BPP3, c[6], c[5], c[8]); #define PIXEL23_32 hq4x_Interp3(pOut+BpL+BpL+BPP3, c[5], c[8]); #define PIXEL23_50 hq4x_Interp5(pOut+BpL+BpL+BPP3, c[6], c[5]); #define PIXEL23_60 hq4x_Interp6(pOut+BpL+BpL+BPP3, c[5], c[6], c[8]); #define PIXEL23_61 hq4x_Interp6(pOut+BpL+BpL+BPP3, c[5], c[6], c[9]); #define PIXEL23_81 hq4x_Interp8(pOut+BpL+BpL+BPP3, c[5], c[6]); #define PIXEL23_83 hq4x_Interp8(pOut+BpL+BpL+BPP3, c[6], c[8]); #define PIXEL30_0 *((int*)(pOut+BpL+BpL+BpL)) = c[5]; #define PIXEL30_11 hq4x_Interp1(pOut+BpL+BpL+BpL, c[5], c[8]); #define PIXEL30_12 hq4x_Interp1(pOut+BpL+BpL+BpL, c[5], c[4]); #define PIXEL30_20 hq4x_Interp2(pOut+BpL+BpL+BpL, c[5], c[8], c[4]); #define PIXEL30_50 hq4x_Interp5(pOut+BpL+BpL+BpL, c[8], c[4]); #define PIXEL30_80 hq4x_Interp8(pOut+BpL+BpL+BpL, c[5], c[7]); #define PIXEL30_81 hq4x_Interp8(pOut+BpL+BpL+BpL, c[5], c[8]); #define PIXEL30_82 hq4x_Interp8(pOut+BpL+BpL+BpL, c[5], c[4]); #define PIXEL31_0 *((int*)(pOut+BpL+BpL+BpL+BPP)) = c[5]; #define PIXEL31_10 hq4x_Interp1(pOut+BpL+BpL+BpL+BPP, c[5], c[7]); #define PIXEL31_11 hq4x_Interp1(pOut+BpL+BpL+BpL+BPP, c[5], c[8]); #define PIXEL31_13 hq4x_Interp1(pOut+BpL+BpL+BpL+BPP, c[8], c[5]); #define PIXEL31_21 hq4x_Interp2(pOut+BpL+BpL+BpL+BPP, c[8], c[5], c[4]); #define PIXEL31_32 hq4x_Interp3(pOut+BpL+BpL+BpL+BPP, c[5], c[4]); #define PIXEL31_50 hq4x_Interp5(pOut+BpL+BpL+BpL+BPP, c[8], c[5]); #define PIXEL31_60 hq4x_Interp6(pOut+BpL+BpL+BpL+BPP, c[5], c[8], c[4]); #define PIXEL31_61 hq4x_Interp6(pOut+BpL+BpL+BpL+BPP, c[5], c[8], c[7]); #define PIXEL31_81 hq4x_Interp8(pOut+BpL+BpL+BpL+BPP, c[5], c[8]); #define PIXEL31_83 hq4x_Interp8(pOut+BpL+BpL+BpL+BPP, c[8], c[4]); #define PIXEL32_0 *((int*)(pOut+BpL+BpL+BpL+BPP2)) = c[5]; #define PIXEL32_10 hq4x_Interp1(pOut+BpL+BpL+BpL+BPP2, c[5], c[9]); #define PIXEL32_12 hq4x_Interp1(pOut+BpL+BpL+BpL+BPP2, c[5], c[8]); #define PIXEL32_14 hq4x_Interp1(pOut+BpL+BpL+BpL+BPP2, c[8], c[5]); #define PIXEL32_21 hq4x_Interp2(pOut+BpL+BpL+BpL+BPP2, c[8], c[5], c[6]); #define PIXEL32_31 hq4x_Interp3(pOut+BpL+BpL+BpL+BPP2, c[5], c[6]); #define PIXEL32_50 hq4x_Interp5(pOut+BpL+BpL+BpL+BPP2, c[8], c[5]); #define PIXEL32_60 hq4x_Interp6(pOut+BpL+BpL+BpL+BPP2, c[5], c[8], c[6]); #define PIXEL32_61 hq4x_Interp6(pOut+BpL+BpL+BpL+BPP2, c[5], c[8], c[9]); #define PIXEL32_82 hq4x_Interp8(pOut+BpL+BpL+BpL+BPP2, c[5], c[8]); #define PIXEL32_83 hq4x_Interp8(pOut+BpL+BpL+BpL+BPP2, c[8], c[6]); #define PIXEL33_0 *((int*)(pOut+BpL+BpL+BpL+BPP3)) = c[5]; #define PIXEL33_11 hq4x_Interp1(pOut+BpL+BpL+BpL+BPP3, c[5], c[6]); #define PIXEL33_12 hq4x_Interp1(pOut+BpL+BpL+BpL+BPP3, c[5], c[8]); #define PIXEL33_20 hq4x_Interp2(pOut+BpL+BpL+BpL+BPP3, c[5], c[8], c[6]); #define PIXEL33_50 hq4x_Interp5(pOut+BpL+BpL+BpL+BPP3, c[8], c[6]); #define PIXEL33_80 hq4x_Interp8(pOut+BpL+BpL+BpL+BPP3, c[5], c[9]); #define PIXEL33_81 hq4x_Interp8(pOut+BpL+BpL+BpL+BPP3, c[5], c[6]); #define PIXEL33_82 hq4x_Interp8(pOut+BpL+BpL+BpL+BPP3, c[5], c[8]); #define HQ4X_DIFF(n, b) \ static int Diff_##n (uint##b w1, uint##b w2) \ { \ int YUV1, YUV2; \ YUV1 = RGB##n##toYUV(w1); \ YUV2 = RGB##n##toYUV(w2); \ return ( ( abs((YUV1 & Ymask) - (YUV2 & Ymask)) > trY ) || \ ( abs((YUV1 & Umask) - (YUV2 & Umask)) > trU ) || \ ( abs((YUV1 & Vmask) - (YUV2 & Vmask)) > trV ) ); \ } HQ4X_DIFF(888, 32) #if !_16BPP_HACK HQ4X_DIFF(444, 16) HQ4X_DIFF(555, 16) HQ4X_DIFF(565, 16) void hq4x_4444(unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int SrcPPL, int BpL) { #define hq4x_Interp1 hq4x_Interp1_4444 #define hq4x_Interp2 hq4x_Interp2_4444 #define hq4x_Interp3 hq4x_Interp3_4444 #define hq4x_Interp4 hq4x_Interp4_4444 #define hq4x_Interp5 hq4x_Interp5_4444 #define hq4x_Interp6 hq4x_Interp6_4444 #define hq4x_Interp7 hq4x_Interp7_4444 #define hq4x_Interp8 hq4x_Interp8_4444 #define Diff Diff_444 #define BPP 2 #define BPP2 4 #define BPP3 6 int i, j, k; int prevline, nextline; uint16 w[10]; uint16 c[10]; int pattern; int flag; int YUV1, YUV2; // +----+----+----+ // | | | | // | w1 | w2 | w3 | // +----+----+----+ // | | | | // | w4 | w5 | w6 | // +----+----+----+ // | | | | // | w7 | w8 | w9 | // +----+----+----+ for (j = 0; j < Yres; j++) { if (j>0) prevline = -SrcPPL*2; else prevline = 0; if (j0) { w[1] = *((uint16*)(pIn + prevline - 2)); w[4] = *((uint16*)(pIn - 2)); w[7] = *((uint16*)(pIn + nextline - 2)); } else { w[1] = w[2]; w[4] = w[5]; w[7] = w[8]; } if (i trY ) || ( abs((YUV1 & Umask) - (YUV2 & Umask)) > trU ) || ( abs((YUV1 & Vmask) - (YUV2 & Vmask)) > trV ) ) pattern |= flag; } flag <<= 1; } for (k=1; k<=9; k++) c[k] = w[k]; #include "TextureFilters_hq4x.h" pIn+=2; pOut+=8; } pIn += 2*(SrcPPL-Xres); pOut+= 8*(SrcPPL-Xres); pOut+=BpL; pOut+=BpL; pOut+=BpL; } #undef BPP #undef BPP2 #undef BPP3 #undef Diff #undef hq4x_Interp1 #undef hq4x_Interp2 #undef hq4x_Interp3 #undef hq4x_Interp4 #undef hq4x_Interp5 #undef hq4x_Interp6 #undef hq4x_Interp7 #undef hq4x_Interp8 } void hq4x_1555(unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int SrcPPL, int BpL) { #define hq4x_Interp1 hq4x_Interp1_1555 #define hq4x_Interp2 hq4x_Interp2_1555 #define hq4x_Interp3 hq4x_Interp3_1555 #define hq4x_Interp4 hq4x_Interp4_1555 #define hq4x_Interp5 hq4x_Interp5_1555 #define hq4x_Interp6 hq4x_Interp6_1555 #define hq4x_Interp7 hq4x_Interp7_1555 #define hq4x_Interp8 hq4x_Interp8_1555 #define Diff Diff_555 #define BPP 2 #define BPP2 4 #define BPP3 6 int i, j, k; int prevline, nextline; uint16 w[10]; uint16 c[10]; int pattern; int flag; int YUV1, YUV2; // +----+----+----+ // | | | | // | w1 | w2 | w3 | // +----+----+----+ // | | | | // | w4 | w5 | w6 | // +----+----+----+ // | | | | // | w7 | w8 | w9 | // +----+----+----+ for (j = 0; j < Yres; j++) { if (j>0) prevline = -SrcPPL*2; else prevline = 0; if (j0) { w[1] = *((uint16*)(pIn + prevline - 2)); w[4] = *((uint16*)(pIn - 2)); w[7] = *((uint16*)(pIn + nextline - 2)); } else { w[1] = w[2]; w[4] = w[5]; w[7] = w[8]; } if (i trY ) || ( abs((YUV1 & Umask) - (YUV2 & Umask)) > trU ) || ( abs((YUV1 & Vmask) - (YUV2 & Vmask)) > trV ) ) pattern |= flag; } flag <<= 1; } for (k=1; k<=9; k++) c[k] = w[k]; #include "TextureFilters_hq4x.h" pIn+=2; pOut+=8; } pIn += 2*(SrcPPL-Xres); pOut+= 8*(SrcPPL-Xres); pOut+=BpL; pOut+=BpL; pOut+=BpL; } #undef BPP #undef BPP2 #undef BPP3 #undef Diff #undef hq4x_Interp1 #undef hq4x_Interp2 #undef hq4x_Interp3 #undef hq4x_Interp4 #undef hq4x_Interp5 #undef hq4x_Interp6 #undef hq4x_Interp7 #undef hq4x_Interp8 } void hq4x_565(unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int SrcPPL, int BpL) { #define hq4x_Interp1 hq4x_Interp1_565 #define hq4x_Interp2 hq4x_Interp2_565 #define hq4x_Interp3 hq4x_Interp3_565 #define hq4x_Interp4 hq4x_Interp4_565 #define hq4x_Interp5 hq4x_Interp5_565 #define hq4x_Interp6 hq4x_Interp6_565 #define hq4x_Interp7 hq4x_Interp7_565 #define hq4x_Interp8 hq4x_Interp8_565 #define Diff Diff_565 #define BPP 2 #define BPP2 4 #define BPP3 6 int i, j, k; int prevline, nextline; uint16 w[10]; uint16 c[10]; int pattern; int flag; int YUV1, YUV2; // +----+----+----+ // | | | | // | w1 | w2 | w3 | // +----+----+----+ // | | | | // | w4 | w5 | w6 | // +----+----+----+ // | | | | // | w7 | w8 | w9 | // +----+----+----+ for (j = 0; j < Yres; j++) { if (j>0) prevline = -SrcPPL*2; else prevline = 0; if (j0) { w[1] = *((uint16*)(pIn + prevline - 2)); w[4] = *((uint16*)(pIn - 2)); w[7] = *((uint16*)(pIn + nextline - 2)); } else { w[1] = w[2]; w[4] = w[5]; w[7] = w[8]; } if (i trY ) || ( abs((YUV1 & Umask) - (YUV2 & Umask)) > trU ) || ( abs((YUV1 & Vmask) - (YUV2 & Vmask)) > trV ) ) pattern |= flag; } flag <<= 1; } for (k=1; k<=9; k++) c[k] = w[k]; #include "TextureFilters_hq4x.h" pIn+=2; pOut+=8; } pIn += 2*(SrcPPL-Xres); pOut+= 8*(SrcPPL-Xres); pOut+=BpL; pOut+=BpL; pOut+=BpL; } #undef BPP #undef BPP2 #undef BPP3 #undef Diff #undef hq4x_Interp1 #undef hq4x_Interp2 #undef hq4x_Interp3 #undef hq4x_Interp4 #undef hq4x_Interp5 #undef hq4x_Interp6 #undef hq4x_Interp7 #undef hq4x_Interp8 } #endif /* !_16BPP_HACK */ void hq4x_8888(unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int SrcPPL, int BpL) { #define hq4x_Interp1 hq4x_Interp1_8888 #define hq4x_Interp2 hq4x_Interp2_8888 #define hq4x_Interp3 hq4x_Interp3_8888 #define hq4x_Interp4 hq4x_Interp4_8888 #define hq4x_Interp5 hq4x_Interp5_8888 #define hq4x_Interp6 hq4x_Interp6_8888 #define hq4x_Interp7 hq4x_Interp7_8888 #define hq4x_Interp8 hq4x_Interp8_8888 #define Diff Diff_888 #define BPP 4 #define BPP2 8 #define BPP3 12 int i, j, k; int prevline, nextline; uint32 w[10]; uint32 c[10]; int pattern; int flag; int YUV1, YUV2; // +----+----+----+ // | | | | // | w1 | w2 | w3 | // +----+----+----+ // | | | | // | w4 | w5 | w6 | // +----+----+----+ // | | | | // | w7 | w8 | w9 | // +----+----+----+ for (j = 0; j < Yres; j++) { if (j>0) prevline = -SrcPPL*4; else prevline = 0; if (j0) { w[1] = *((uint32*)(pIn + prevline - 4)); w[4] = *((uint32*)(pIn - 4)); w[7] = *((uint32*)(pIn + nextline - 4)); } else { w[1] = w[2]; w[4] = w[5]; w[7] = w[8]; } if (i trY ) || ( abs((YUV1 & Umask) - (YUV2 & Umask)) > trU ) || ( abs((YUV1 & Vmask) - (YUV2 & Vmask)) > trV ) ) pattern |= flag; } flag <<= 1; } for (k=1; k<=9; k++) c[k] = w[k]; #include "TextureFilters_hq4x.h" pIn+=4; pOut+=16; } pIn += 4*(SrcPPL-Xres); pOut+= 16*(SrcPPL-Xres); pOut+=BpL; pOut+=BpL; pOut+=BpL; } #undef BPP #undef BPP2 #undef BPP3 #undef Diff #undef hq4x_Interp1 #undef hq4x_Interp2 #undef hq4x_Interp3 #undef hq4x_Interp4 #undef hq4x_Interp5 #undef hq4x_Interp6 #undef hq4x_Interp7 #undef hq4x_Interp8 } #if !_16BPP_HACK void hq4x_init(void) { static int done = 0; int r, g, b, Y, u, v, i, j, k; if (done ) return; for (i = 0; i < 16; i++) { for (j = 0; j < 16; j++) { for (k = 0; k < 16; k++) { r = (i << 4) | i; g = (j << 4) | j; b = (k << 4) | k; /* Microsoft's RGB888->YUV conversion */ /*Y = ((( 66 * r + 129 * g + 25 * b + 128) >> 8) + 16) & 0xFF; u = ((( -38 * r - 74 * g + 112 * b + 128) >> 8) + 128) & 0xFF; v = ((( 112 * r - 94 * g - 18 * b + 128) >> 8) + 128) & 0xFF;*/ Y = (r + g + b) >> 2; u = 128 + ((r - b) >> 2); v = 128 + ((-r + 2*g -b)>>3); RGB444toYUV[(i << 8) | (j << 4) | k] = (Y << 16) | (u << 8) | v; } } } done = 1; } #endif /* !_16BPP_HACK */ gles2n64/src/F3DEX2.h000664 001750 001750 00000005626 12655644434 015127 0ustar00sergiosergio000000 000000 #ifndef F3DEX2_H #define F3DEX2_H #ifdef __cplusplus extern "C" { #endif #define F3DEX2_MTX_STACKSIZE 18 #define F3DEX2_MTX_MODELVIEW 0x00 #define F3DEX2_MTX_PROJECTION 0x04 #define F3DEX2_MTX_MUL 0x00 #define F3DEX2_MTX_LOAD 0x02 #define F3DEX2_MTX_NOPUSH 0x00 #define F3DEX2_MTX_PUSH 0x01 #define F3DEX2_TEXTURE_ENABLE 0x00000000 #define F3DEX2_SHADING_SMOOTH 0x00200000 #define F3DEX2_CULL_FRONT 0x00000200 #define F3DEX2_CULL_BACK 0x00000400 #define F3DEX2_CULL_BOTH 0x00000600 #define F3DEX2_CLIPPING 0x00800000 #define F3DEX2_MV_VIEWPORT 8 #define F3DEX2_MWO_aLIGHT_1 0x00 #define F3DEX2_MWO_bLIGHT_1 0x04 #define F3DEX2_MWO_aLIGHT_2 0x18 #define F3DEX2_MWO_bLIGHT_2 0x1c #define F3DEX2_MWO_aLIGHT_3 0x30 #define F3DEX2_MWO_bLIGHT_3 0x34 #define F3DEX2_MWO_aLIGHT_4 0x48 #define F3DEX2_MWO_bLIGHT_4 0x4c #define F3DEX2_MWO_aLIGHT_5 0x60 #define F3DEX2_MWO_bLIGHT_5 0x64 #define F3DEX2_MWO_aLIGHT_6 0x78 #define F3DEX2_MWO_bLIGHT_6 0x7c #define F3DEX2_MWO_aLIGHT_7 0x90 #define F3DEX2_MWO_bLIGHT_7 0x94 #define F3DEX2_MWO_aLIGHT_8 0xa8 #define F3DEX2_MWO_bLIGHT_8 0xac #define F3DEX2_RDPHALF_2 0xF1 #define F3DEX2_SETOTHERMODE_H 0xE3 #define F3DEX2_SETOTHERMODE_L 0xE2 #define F3DEX2_RDPHALF_1 0xE1 #define F3DEX2_SPNOOP 0xE0 #define F3DEX2_ENDDL 0xDF #define F3DEX2_DL 0xDE #define F3DEX2_LOAD_UCODE 0xDD #define F3DEX2_MOVEMEM 0xDC #define F3DEX2_MOVEWORD 0xDB #define F3DEX2_MTX 0xDA #define F3DEX2_GEOMETRYMODE 0xD9 #define F3DEX2_POPMTX 0xD8 #define F3DEX2_TEXTURE 0xD7 #define F3DEX2_DMA_IO 0xD6 #define F3DEX2_SPECIAL_1 0xD5 #define F3DEX2_SPECIAL_2 0xD4 #define F3DEX2_SPECIAL_3 0xD3 #define F3DEX2_VTX 0x01 #define F3DEX2_MODIFYVTX 0x02 #define F3DEX2_CULLDL 0x03 #define F3DEX2_BRANCH_Z 0x04 #define F3DEX2_TRI1 0x05 #define F3DEX2_TRI2 0x06 #define F3DEX2_QUAD 0x07 #define F3DEX2_LINE3D 0x08 void F3DEX2_Mtx( u32 w0, u32 w1 ); void F3DEX2_MoveMem( u32 w0, u32 w1 ); void F3DEX2_Vtx( u32 w0, u32 w1 ); void F3DEX2_Reserved1( u32 w0, u32 w1 ); void F3DEX2_Tri1( u32 w0, u32 w1 ); void F3DEX2_PopMtx( u32 w0, u32 w1 ); void F3DEX2_MoveWord( u32 w0, u32 w1 ); void F3DEX2_Texture( u32 w0, u32 w1 ); void F3DEX2_SetOtherMode_H( u32 w0, u32 w1 ); void F3DEX2_SetOtherMode_L( u32 w0, u32 w1 ); void F3DEX2_GeometryMode( u32 w0, u32 w1 ); void F3DEX2_Line3D( u32 w0, u32 w1 ); void F3DEX2_DMAIO( u32 w0, u32 w1 ); void F3DEX2_Special_1( u32 w0, u32 w1 ); void F3DEX2_Special_2( u32 w0, u32 w1 ); void F3DEX2_Special_3( u32 w0, u32 w1 ); void F3DEX2_Quad( u32 w0, u32 w1 ); void F3DEX2_Init(); #ifdef __cplusplus } #endif #endif glide2gl/src/Glide64/ucode03.h000664 001750 001750 00000007161 12655644434 017015 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** // // vertex - loads vertices // static void uc3_vertex(uint32_t w0, uint32_t w1) { int v0 = _SHIFTR(w0, 16, 8) / 5; // Current vertex int n = (uint16_t)((w0 & 0xFFFF) + 1) / 0x210; // Number to copy if (v0 >= 32) v0 = 31; if ((v0 + n) > 32) n = 32 - v0; pre_update(); gSPVertex_G64( RSP_SegmentToPhysical(w1), /* v - Current vertex */ n, /* n - Number of vertices to copy */ v0 /* v0 */ ); } static void uc3_tri1(uint32_t w0, uint32_t w1) { VERTEX *v[3]; if (rdp.skip_drawing) return; v[0] = &rdp.vtx[_SHIFTR( w1, 16, 8) / 5]; /* v0 */ v[1] = &rdp.vtx[_SHIFTR( w1, 8, 8) / 5]; /* v1 */ v[2] = &rdp.vtx[_SHIFTR( w1, 0, 8) / 5]; /* v2 */ cull_trianglefaces(v, 1, true, true, 0); } static void uc3_tri2(uint32_t w0, uint32_t w1) { VERTEX *v[6]; if (rdp.skip_drawing) return; v[0] = &rdp.vtx[_SHIFTR(w0, 16, 8) / 5]; /* v00 */ v[1] = &rdp.vtx[_SHIFTR(w0, 8, 8) / 5]; /* v01 */ v[2] = &rdp.vtx[_SHIFTR(w0, 0, 8) / 5]; /* v02 */ v[3] = &rdp.vtx[_SHIFTR(w1, 16, 8) / 5]; /* v10 */ v[4] = &rdp.vtx[_SHIFTR(w1, 8, 8) / 5]; /* v11 */ v[5] = &rdp.vtx[_SHIFTR(w1, 0, 8) / 5]; /* v12 */ cull_trianglefaces(v, 2, true, true, 0); } static void uc3_quad3d(uint32_t w0, uint32_t w1) { VERTEX *v[6]; if (rdp.skip_drawing) return; v[0] = &rdp.vtx[((w1 >> 24) & 0xFF) / 5]; /* v00 */ v[1] = &rdp.vtx[((w1 >> 16) & 0xFF) / 5]; /* v01 */ v[2] = &rdp.vtx[((w1 >> 8) & 0xFF) / 5]; /* v02 */ v[3] = &rdp.vtx[(w1 & 0xFF) / 5]; /* v10 */ v[4] = &rdp.vtx[((w1 >> 24) & 0xFF) / 5]; /* v11 */ v[5] = &rdp.vtx[((w1 >> 8) & 0xFF) / 5]; /* v12 */ cull_trianglefaces(v, 2, true, true, 0); } mupen64plus-core/src/plugin/audio_libretro/audio_utils.c000664 001750 001750 00000031405 12655644434 024627 0ustar00sergiosergio000000 000000 /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2014-2015 - Ali Bouhlel ( aliaspider@gmail.com ) * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. * * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with RetroArch. * If not, see . */ #include #include "audio_utils.h" #if defined(__SSE2__) #include #elif defined(__ALTIVEC__) #include #endif #include "api/libretro.h" /** * audio_convert_s16_to_float_C: * @out : output buffer * @in : input buffer * @samples : size of samples to be converted * @gain : gain applied to the audio volume * * Converts audio samples from signed integer 16-bit * to floating point. * * C implementation callback function. **/ void audio_convert_s16_to_float_C(float *out, const int16_t *in, size_t samples, float gain) { size_t i; gain = gain / 0x8000; for (i = 0; i < samples; i++) out[i] = (float)in[i] * gain; } /** * audio_convert_float_to_s16_C: * @out : output buffer * @in : input buffer * @samples : size of samples to be converted * * Converts audio samples from floating point * to signed integer 16-bit. * * C implementation callback function. **/ void audio_convert_float_to_s16_C(int16_t *out, const float *in, size_t samples) { size_t i; for (i = 0; i < samples; i++) { int32_t val = (int32_t)(in[i] * 0x8000); out[i] = (val > 0x7FFF) ? 0x7FFF : (val < -0x8000 ? -0x8000 : (int16_t)val); } } #if defined(__SSE2__) /** * audio_convert_s16_to_float_SSE2: * @out : output buffer * @in : input buffer * @samples : size of samples to be converted * @gain : gain applied to the audio volume * * Converts audio samples from signed integer 16-bit * to floating point. * * SSE2 implementation callback function. **/ void audio_convert_s16_to_float_SSE2(float *out, const int16_t *in, size_t samples, float gain) { float fgain = gain / UINT32_C(0x80000000); __m128 factor = _mm_set1_ps(fgain); size_t i; for (i = 0; i + 8 <= samples; i += 8, in += 8, out += 8) { __m128i input = _mm_loadu_si128((const __m128i *)in); __m128i regs[2] = { _mm_unpacklo_epi16(_mm_setzero_si128(), input), _mm_unpackhi_epi16(_mm_setzero_si128(), input), }; __m128 output[2] = { _mm_mul_ps(_mm_cvtepi32_ps(regs[0]), factor), _mm_mul_ps(_mm_cvtepi32_ps(regs[1]), factor), }; _mm_storeu_ps(out + 0, output[0]); _mm_storeu_ps(out + 4, output[1]); } audio_convert_s16_to_float_C(out, in, samples - i, gain); } /** * audio_convert_float_to_s16_SSE2: * @out : output buffer * @in : input buffer * @samples : size of samples to be converted * * Converts audio samples from floating point * to signed integer 16-bit. * * SSE2 implementation callback function. **/ void audio_convert_float_to_s16_SSE2(int16_t *out, const float *in, size_t samples) { size_t i; __m128 factor = _mm_set1_ps((float)0x8000); for (i = 0; i + 8 <= samples; i += 8, in += 8, out += 8) { __m128 input[2] = { _mm_loadu_ps(in + 0), _mm_loadu_ps(in + 4) }; __m128 res[2] = { _mm_mul_ps(input[0], factor), _mm_mul_ps(input[1], factor) }; __m128i ints[2] = { _mm_cvtps_epi32(res[0]), _mm_cvtps_epi32(res[1]) }; __m128i packed = _mm_packs_epi32(ints[0], ints[1]); _mm_storeu_si128((__m128i *)out, packed); } audio_convert_float_to_s16_C(out, in, samples - i); } #elif defined(__ALTIVEC__) /** * audio_convert_s16_to_float_altivec: * @out : output buffer * @in : input buffer * @samples : size of samples to be converted * @gain : gain applied to the audio volume * * Converts audio samples from signed integer 16-bit * to floating point. * * AltiVec implementation callback function. **/ void audio_convert_s16_to_float_altivec(float *out, const int16_t *in, size_t samples, float gain) { size_t samples_in = samples; const vector float gain_vec = { gain, gain , gain, gain }; const vector float zero_vec = { 0.0f, 0.0f, 0.0f, 0.0f}; /* Unaligned loads/store is a bit expensive, so we * optimize for the good path (very likely). */ if (((uintptr_t)out & 15) + ((uintptr_t)in & 15) == 0) { size_t i; for (i = 0; i + 8 <= samples; i += 8, in += 8, out += 8) { vector signed short input = vec_ld(0, in); vector signed int hi = vec_unpackh(input); vector signed int lo = vec_unpackl(input); vector float out_hi = vec_madd(vec_ctf(hi, 15), gain_vec, zero_vec); vector float out_lo = vec_madd(vec_ctf(lo, 15), gain_vec, zero_vec); vec_st(out_hi, 0, out); vec_st(out_lo, 16, out); } samples_in -= i; } audio_convert_s16_to_float_C(out, in, samples_in, gain); } /** * audio_convert_float_to_s16_altivec: * @out : output buffer * @in : input buffer * @samples : size of samples to be converted * * Converts audio samples from floating point * to signed integer 16-bit. * * AltiVec implementation callback function. **/ void audio_convert_float_to_s16_altivec(int16_t *out, const float *in, size_t samples) { int samples_in = samples; /* Unaligned loads/store is a bit expensive, * so we optimize for the good path (very likely). */ if (((uintptr_t)out & 15) + ((uintptr_t)in & 15) == 0) { size_t i; for (i = 0; i + 8 <= samples; i += 8, in += 8, out += 8) { vector float input0 = vec_ld( 0, in); vector float input1 = vec_ld(16, in); vector signed int result0 = vec_cts(input0, 15); vector signed int result1 = vec_cts(input1, 15); vec_st(vec_packs(result0, result1), 0, out); } samples_in -= i; } audio_convert_float_to_s16_C(out, in, samples_in); } #elif defined(__ARM_NEON__) /* Avoid potential hard-float/soft-float ABI issues. */ void audio_convert_s16_float_asm(float *out, const int16_t *in, size_t samples, const float *gain); /** * audio_convert_s16_to_float_neon: * @out : output buffer * @in : input buffer * @samples : size of samples to be converted * @gain : gain applied to the audio volume * * Converts audio samples from signed integer 16-bit * to floating point. * * ARM NEON implementation callback function. **/ static void audio_convert_s16_to_float_neon(float *out, const int16_t *in, size_t samples, float gain) { size_t aligned_samples = samples & ~7; if (aligned_samples) audio_convert_s16_float_asm(out, in, aligned_samples, &gain); /* Could do all conversion in ASM, but keep it simple for now. */ audio_convert_s16_to_float_C(out + aligned_samples, in + aligned_samples, samples - aligned_samples, gain); } void audio_convert_float_s16_asm(int16_t *out, const float *in, size_t samples); /** * audio_convert_float_to_s16_neon: * @out : output buffer * @in : input buffer * @samples : size of samples to be converted * * Converts audio samples from floating point * to signed integer 16-bit. * * ARM NEON implementation callback function. **/ static void audio_convert_float_to_s16_neon(int16_t *out, const float *in, size_t samples) { size_t aligned_samples = samples & ~7; if (aligned_samples) audio_convert_float_s16_asm(out, in, aligned_samples); audio_convert_float_to_s16_C(out + aligned_samples, in + aligned_samples, samples - aligned_samples); } #elif defined(_MIPS_ARCH_ALLEGREX) /** * audio_convert_s16_to_float_ALLEGREX: * @out : output buffer * @in : input buffer * @samples : size of samples to be converted * @gain : gain applied to the audio volume * * Converts audio samples from signed integer 16-bit * to floating point. * * MIPS ALLEGREX implementation callback function. **/ void audio_convert_s16_to_float_ALLEGREX(float *out, const int16_t *in, size_t samples, float gain) { #ifdef DEBUG /* Make sure the buffer is 16 byte aligned, this should be the * default behaviour of malloc in the PSPSDK. * Only the output buffer can be assumed to be 16-byte aligned. */ rarch_assert(((uintptr_t)out & 0xf) == 0); #endif size_t i; gain = gain / 0x8000; __asm__ ( ".set push \n" ".set noreorder \n" "mtv %0, s200 \n" ".set pop \n" ::"r"(gain)); for (i = 0; i + 16 <= samples; i += 16) { __asm__ ( ".set push \n" ".set noreorder \n" "lv.s s100, 0(%0) \n" "lv.s s101, 4(%0) \n" "lv.s s110, 8(%0) \n" "lv.s s111, 12(%0) \n" "lv.s s120, 16(%0) \n" "lv.s s121, 20(%0) \n" "lv.s s130, 24(%0) \n" "lv.s s131, 28(%0) \n" "vs2i.p c100, c100 \n" "vs2i.p c110, c110 \n" "vs2i.p c120, c120 \n" "vs2i.p c130, c130 \n" "vi2f.q c100, c100, 16 \n" "vi2f.q c110, c110, 16 \n" "vi2f.q c120, c120, 16 \n" "vi2f.q c130, c130, 16 \n" "vmscl.q e100, e100, s200 \n" "sv.q c100, 0(%1) \n" "sv.q c110, 16(%1) \n" "sv.q c120, 32(%1) \n" "sv.q c130, 48(%1) \n" ".set pop \n" :: "r"(in + i), "r"(out + i)); } for (; i < samples; i++) out[i] = (float)in[i] * gain; } /** * audio_convert_float_to_s16_ALLEGREX: * @out : output buffer * @in : input buffer * @samples : size of samples to be converted * * Converts audio samples from floating point * to signed integer 16-bit. * * MIPS ALLEGREX implementation callback function. **/ void audio_convert_float_to_s16_ALLEGREX(int16_t *out, const float *in, size_t samples) { size_t i; #ifdef DEBUG /* Make sure the buffers are 16 byte aligned, this should be * the default behaviour of malloc in the PSPSDK. * Both buffers are allocated by RetroArch, so can assume alignment. */ rarch_assert(((uintptr_t)in & 0xf) == 0); rarch_assert(((uintptr_t)out & 0xf) == 0); #endif for (i = 0; i + 8 <= samples; i += 8) { __asm__ ( ".set push \n" ".set noreorder \n" "lv.q c100, 0(%0) \n" "lv.q c110, 16(%0) \n" "vf2in.q c100, c100, 31 \n" "vf2in.q c110, c110, 31 \n" "vi2s.q c100, c100 \n" "vi2s.q c102, c110 \n" "sv.q c100, 0(%1) \n" ".set pop \n" :: "r"(in + i), "r"(out + i)); } for (; i < samples; i++) { int32_t val = (int32_t)(in[i] * 0x8000); out[i] = (val > 0x7FFF) ? 0x7FFF : (val < -0x8000 ? -0x8000 : (int16_t)val); } } #endif #ifndef RARCH_INTERNAL #ifdef __cplusplus extern "C" { #endif retro_get_cpu_features_t perf_get_cpu_features_cb; #ifdef __cplusplus } #endif #endif static unsigned audio_convert_get_cpu_features(void) { #ifdef RARCH_INTERNAL return rarch_get_cpu_features(); #else return perf_get_cpu_features_cb ? (unsigned)perf_get_cpu_features_cb() : 0; #endif } /** * audio_convert_init_simd: * * Sets up function pointers for audio conversion * functions based on CPU features. **/ void audio_convert_init_simd(void) { unsigned cpu = audio_convert_get_cpu_features(); (void)cpu; #if defined(__ARM_NEON__) audio_convert_s16_to_float_arm = (cpu & RETRO_SIMD_NEON) ? audio_convert_s16_to_float_neon : audio_convert_s16_to_float_C; audio_convert_float_to_s16_arm = (cpu & RETRO_SIMD_NEON) ? audio_convert_float_to_s16_neon : audio_convert_float_to_s16_C; #endif } mupen64plus-video-gliden64/licenses/GlideHQ/gpl-2.0.txt000664 001750 001750 00000043103 12655644434 023542 0ustar00sergiosergio000000 000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. mupen64plus-core/src/plugin/audio_libretro/drivers_resampler/sinc.c000664 001750 001750 00000035635 12655644434 027003 0ustar00sergiosergio000000 000000 /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. * * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with RetroArch. * If not, see . */ /* Bog-standard windowed SINC implementation. */ #include "../audio_resampler_driver.h" #include #include #include #include #ifdef __SSE__ #include #endif #include /* Rough SNR values for upsampling: * LOWEST: 40 dB * LOWER: 55 dB * NORMAL: 70 dB * HIGHER: 110 dB * HIGHEST: 140 dB */ /* TODO, make all this more configurable. */ #if defined(SINC_LOWEST_QUALITY) #define SINC_WINDOW_LANCZOS #define CUTOFF 0.98 #define PHASE_BITS 12 #define SINC_COEFF_LERP 0 #define SUBPHASE_BITS 10 #define SIDELOBES 2 #define ENABLE_AVX 0 #elif defined(SINC_LOWER_QUALITY) #define SINC_WINDOW_LANCZOS #define CUTOFF 0.98 #define PHASE_BITS 12 #define SUBPHASE_BITS 10 #define SINC_COEFF_LERP 0 #define SIDELOBES 4 #define ENABLE_AVX 0 #elif defined(SINC_HIGHER_QUALITY) #define SINC_WINDOW_KAISER #define SINC_WINDOW_KAISER_BETA 10.5 #define CUTOFF 0.90 #define PHASE_BITS 10 #define SUBPHASE_BITS 14 #define SINC_COEFF_LERP 1 #define SIDELOBES 32 #define ENABLE_AVX 1 #elif defined(SINC_HIGHEST_QUALITY) #define SINC_WINDOW_KAISER #define SINC_WINDOW_KAISER_BETA 14.5 #define CUTOFF 0.962 #define PHASE_BITS 10 #define SUBPHASE_BITS 14 #define SINC_COEFF_LERP 1 #define SIDELOBES 128 #define ENABLE_AVX 1 #else #define SINC_WINDOW_KAISER #define SINC_WINDOW_KAISER_BETA 5.5 #define CUTOFF 0.825 #define PHASE_BITS 8 #define SUBPHASE_BITS 16 #define SINC_COEFF_LERP 1 #define SIDELOBES 8 #define ENABLE_AVX 0 #endif /* For the little amount of taps we're using, * SSE1 is faster than AVX for some reason. * AVX code is kept here though as by increasing number * of sinc taps, the AVX code is clearly faster than SSE1. */ #if defined(__AVX__) && ENABLE_AVX #include #endif #define PHASES (1 << (PHASE_BITS + SUBPHASE_BITS)) #define TAPS (SIDELOBES * 2) #define SUBPHASE_MASK ((1 << SUBPHASE_BITS) - 1) #define SUBPHASE_MOD (1.0f / (1 << SUBPHASE_BITS)) typedef struct rarch_sinc_resampler { float *phase_table; float *buffer_l; float *buffer_r; unsigned taps; unsigned ptr; uint32_t time; /* A buffer for phase_table, buffer_l and buffer_r * are created in a single calloc(). * Ensure that we get as good cache locality as we can hope for. */ float *main_buffer; } rarch_sinc_resampler_t; static INLINE double sinc(double val) { if (fabs(val) < 0.00001) return 1.0; return sin(val) / val; } #if defined(SINC_WINDOW_LANCZOS) #define window_function(idx) (sinc(M_PI * (idx))) #elif defined(SINC_WINDOW_KAISER) /* Modified Bessel function of first order. * Check Wiki for mathematical definition ... */ static INLINE double besseli0(double x) { unsigned i; double sum = 0.0; double factorial = 1.0; double factorial_mult = 0.0; double x_pow = 1.0; double two_div_pow = 1.0; double x_sqr = x * x; /* Approximate. This is an infinite sum. * Luckily, it converges rather fast. */ for (i = 0; i < 18; i++) { sum += x_pow * two_div_pow / (factorial * factorial); factorial_mult += 1.0; x_pow *= x_sqr; two_div_pow *= 0.25; factorial *= factorial_mult; } return sum; } #define window_function(idx) (besseli0(SINC_WINDOW_KAISER_BETA * sqrt(1 - (idx) * (idx)))) #else #error "No SINC window function defined." #endif static void init_sinc_table(rarch_sinc_resampler_t *resamp, double cutoff, float *phase_table, int phases, int taps, bool calculate_delta) { int i, j; double window_mod = window_function(0.0); /* Need to normalize w(0) to 1.0. */ int stride = calculate_delta ? 2 : 1; double sidelobes = taps / 2.0; for (i = 0; i < phases; i++) { for (j = 0; j < taps; j++) { double sinc_phase; float val; int n = j * phases + i; double window_phase = (double)n / (phases * taps); /* [0, 1). */ window_phase = 2.0 * window_phase - 1.0; /* [-1, 1) */ sinc_phase = sidelobes * window_phase; val = cutoff * sinc(M_PI * sinc_phase * cutoff) * window_function(window_phase) / window_mod; phase_table[i * stride * taps + j] = val; } } if (calculate_delta) { int p; int phase; for (p = 0; p < phases - 1; p++) { for (j = 0; j < taps; j++) { float delta = phase_table[(p + 1) * stride * taps + j] - phase_table[p * stride * taps + j]; phase_table[(p * stride + 1) * taps + j] = delta; } } phase = phases - 1; for (j = 0; j < taps; j++) { float val, delta; double sinc_phase; int n = j * phases + (phase + 1); double window_phase = (double)n / (phases * taps); /* (0, 1]. */ window_phase = 2.0 * window_phase - 1.0; /* (-1, 1] */ sinc_phase = sidelobes * window_phase; val = cutoff * sinc(M_PI * sinc_phase * cutoff) * window_function(window_phase) / window_mod; delta = (val - phase_table[phase * stride * taps + j]); phase_table[(phase * stride + 1) * taps + j] = delta; } } } /* No memalign() for us on Win32 ... */ static void *aligned_alloc__(size_t boundary, size_t size) { void **place; uintptr_t addr = 0; void *ptr = malloc(boundary + size + sizeof(uintptr_t)); if (!ptr) return NULL; addr = ((uintptr_t)ptr + sizeof(uintptr_t) + boundary) & ~(boundary - 1); place = (void**)addr; place[-1] = ptr; return (void*)addr; } static void aligned_free__(void *ptr) { void **p = (void**)ptr; free(p[-1]); } #if !(defined(__AVX__) && ENABLE_AVX) && !defined(__SSE__) static INLINE void process_sinc_C(rarch_sinc_resampler_t *resamp, float *out_buffer) { unsigned i; float sum_l = 0.0f; float sum_r = 0.0f; const float *buffer_l = resamp->buffer_l + resamp->ptr; const float *buffer_r = resamp->buffer_r + resamp->ptr; unsigned taps = resamp->taps; unsigned phase = resamp->time >> SUBPHASE_BITS; #if SINC_COEFF_LERP const float *phase_table = resamp->phase_table + phase * taps * 2; const float *delta_table = phase_table + taps; float delta = (float)(resamp->time & SUBPHASE_MASK) * SUBPHASE_MOD; #else const float *phase_table = resamp->phase_table + phase * taps; #endif for (i = 0; i < taps; i++) { #if SINC_COEFF_LERP float sinc_val = phase_table[i] + delta_table[i] * delta; #else float sinc_val = phase_table[i]; #endif sum_l += buffer_l[i] * sinc_val; sum_r += buffer_r[i] * sinc_val; } out_buffer[0] = sum_l; out_buffer[1] = sum_r; } #endif #if defined(__AVX__) && ENABLE_AVX #define process_sinc_func process_sinc static void process_sinc(rarch_sinc_resampler_t *resamp, float *out_buffer) { unsigned i; __m256 sum_l = _mm256_setzero_ps(); __m256 sum_r = _mm256_setzero_ps(); const float *buffer_l = resamp->buffer_l + resamp->ptr; const float *buffer_r = resamp->buffer_r + resamp->ptr; unsigned taps = resamp->taps; unsigned phase = resamp->time >> SUBPHASE_BITS; #if SINC_COEFF_LERP const float *phase_table = resamp->phase_table + phase * taps * 2; const float *delta_table = phase_table + taps; __m256 delta = _mm256_set1_ps((float) (resamp->time & SUBPHASE_MASK) * SUBPHASE_MOD); #else const float *phase_table = resamp->phase_table + phase * taps; #endif for (i = 0; i < taps; i += 8) { __m256 buf_l = _mm256_loadu_ps(buffer_l + i); __m256 buf_r = _mm256_loadu_ps(buffer_r + i); #if SINC_COEFF_LERP __m256 deltas = _mm256_load_ps(delta_table + i); __m256 sinc = _mm256_add_ps(_mm256_load_ps(phase_table + i), _mm256_mul_ps(deltas, delta)); #else __m256 sinc = _mm256_load_ps(phase_table + i); #endif sum_l = _mm256_add_ps(sum_l, _mm256_mul_ps(buf_l, sinc)); sum_r = _mm256_add_ps(sum_r, _mm256_mul_ps(buf_r, sinc)); } /* hadd on AVX is weird, and acts on low-lanes * and high-lanes separately. */ __m256 res_l = _mm256_hadd_ps(sum_l, sum_l); __m256 res_r = _mm256_hadd_ps(sum_r, sum_r); res_l = _mm256_hadd_ps(res_l, res_l); res_r = _mm256_hadd_ps(res_r, res_r); res_l = _mm256_add_ps(_mm256_permute2f128_ps(res_l, res_l, 1), res_l); res_r = _mm256_add_ps(_mm256_permute2f128_ps(res_r, res_r, 1), res_r); /* This is optimized to mov %xmmN, [mem]. * There doesn't seem to be any _mm256_store_ss intrinsic. */ _mm_store_ss(out_buffer + 0, _mm256_extractf128_ps(res_l, 0)); _mm_store_ss(out_buffer + 1, _mm256_extractf128_ps(res_r, 0)); } #elif defined(__SSE__) #define process_sinc_func process_sinc static void process_sinc(rarch_sinc_resampler_t *resamp, float *out_buffer) { unsigned i; __m128 sum_l = _mm_setzero_ps(); __m128 sum_r = _mm_setzero_ps(); const float *buffer_l = resamp->buffer_l + resamp->ptr; const float *buffer_r = resamp->buffer_r + resamp->ptr; unsigned taps = resamp->taps; unsigned phase = resamp->time >> SUBPHASE_BITS; #if SINC_COEFF_LERP const float *phase_table = resamp->phase_table + phase * taps * 2; const float *delta_table = phase_table + taps; __m128 delta = _mm_set1_ps((float) (resamp->time & SUBPHASE_MASK) * SUBPHASE_MOD); #else const float *phase_table = resamp->phase_table + phase * taps; #endif __m128 sum; for (i = 0; i < taps; i += 4) { __m128 buf_l = _mm_loadu_ps(buffer_l + i); __m128 buf_r = _mm_loadu_ps(buffer_r + i); #if SINC_COEFF_LERP __m128 deltas = _mm_load_ps(delta_table + i); __m128 _sinc = _mm_add_ps(_mm_load_ps(phase_table + i), _mm_mul_ps(deltas, delta)); #else __m128 _sinc = _mm_load_ps(phase_table + i); #endif sum_l = _mm_add_ps(sum_l, _mm_mul_ps(buf_l, _sinc)); sum_r = _mm_add_ps(sum_r, _mm_mul_ps(buf_r, _sinc)); } /* Them annoying shuffles. * sum_l = { l3, l2, l1, l0 } * sum_r = { r3, r2, r1, r0 } */ sum = _mm_add_ps(_mm_shuffle_ps(sum_l, sum_r, _MM_SHUFFLE(1, 0, 1, 0)), _mm_shuffle_ps(sum_l, sum_r, _MM_SHUFFLE(3, 2, 3, 2))); /* sum = { r1, r0, l1, l0 } + { r3, r2, l3, l2 } * sum = { R1, R0, L1, L0 } */ sum = _mm_add_ps(_mm_shuffle_ps(sum, sum, _MM_SHUFFLE(3, 3, 1, 1)), sum); /* sum = {R1, R1, L1, L1 } + { R1, R0, L1, L0 } * sum = { X, R, X, L } */ /* Store L */ _mm_store_ss(out_buffer + 0, sum); /* movehl { X, R, X, L } == { X, R, X, R } */ _mm_store_ss(out_buffer + 1, _mm_movehl_ps(sum, sum)); } #elif defined(__ARM_NEON__) #if SINC_COEFF_LERP #error "NEON asm does not support SINC lerp." #endif /* Need to make this function pointer as Android doesn't * have built-in targets for NEON and plain ARMv7a. */ static void (*process_sinc_func)(rarch_sinc_resampler_t *resamp, float *out_buffer); /* Assumes that taps >= 8, and that taps is a multiple of 8. */ void process_sinc_neon_asm(float *out, const float *left, const float *right, const float *coeff, unsigned taps); static void process_sinc_neon(rarch_sinc_resampler_t *resamp, float *out_buffer) { const float *buffer_l = resamp->buffer_l + resamp->ptr; const float *buffer_r = resamp->buffer_r + resamp->ptr; unsigned phase = resamp->time >> SUBPHASE_BITS; unsigned taps = resamp->taps; const float *phase_table = resamp->phase_table + phase * taps; process_sinc_neon_asm(out_buffer, buffer_l, buffer_r, phase_table, taps); } #else /* Plain ol' C99 */ #define process_sinc_func process_sinc_C #endif static void resampler_sinc_process(void *re_, struct resampler_data *data) { rarch_sinc_resampler_t *re = (rarch_sinc_resampler_t*)re_; uint32_t ratio = PHASES / data->ratio; const float *input = data->data_in; float *output = data->data_out; size_t frames = data->input_frames; size_t out_frames = 0; while (frames) { while (frames && re->time >= PHASES) { /* Push in reverse to make filter more obvious. */ if (!re->ptr) re->ptr = re->taps; re->ptr--; re->buffer_l[re->ptr + re->taps] = re->buffer_l[re->ptr] = *input++; re->buffer_r[re->ptr + re->taps] = re->buffer_r[re->ptr] = *input++; re->time -= PHASES; frames--; } while (re->time < PHASES) { process_sinc_func(re, output); output += 2; out_frames++; re->time += ratio; } } data->output_frames = out_frames; } static void resampler_sinc_free(void *re) { rarch_sinc_resampler_t *resampler = (rarch_sinc_resampler_t*)re; if (resampler) aligned_free__(resampler->main_buffer); free(resampler); } static void *resampler_sinc_new(const struct resampler_config *config, double bandwidth_mod, resampler_simd_mask_t mask) { size_t phase_elems, elems; double cutoff; rarch_sinc_resampler_t *re = (rarch_sinc_resampler_t*) calloc(1, sizeof(*re)); if (!re) return NULL; (void)config; re->taps = TAPS; cutoff = CUTOFF; /* Downsampling, must lower cutoff, and extend number of * taps accordingly to keep same stopband attenuation. */ if (bandwidth_mod < 1.0) { cutoff *= bandwidth_mod; re->taps = (unsigned)ceil(re->taps / bandwidth_mod); } /* Be SIMD-friendly. */ #if (defined(__AVX__) && ENABLE_AVX) || defined(__ARM_NEON__) re->taps = (re->taps + 7) & ~7; #else re->taps = (re->taps + 3) & ~3; #endif phase_elems = (1 << PHASE_BITS) * re->taps; #if SINC_COEFF_LERP phase_elems *= 2; #endif elems = phase_elems + 4 * re->taps; re->main_buffer = (float*) aligned_alloc__(128, sizeof(float) * elems); if (!re->main_buffer) goto error; re->phase_table = re->main_buffer; re->buffer_l = re->main_buffer + phase_elems; re->buffer_r = re->buffer_l + 2 * re->taps; init_sinc_table(re, cutoff, re->phase_table, 1 << PHASE_BITS, re->taps, SINC_COEFF_LERP); #if defined(__ARM_NEON__) process_sinc_func = mask & RESAMPLER_SIMD_NEON ? process_sinc_neon : process_sinc_C; #endif return re; error: resampler_sinc_free(re); return NULL; } rarch_resampler_t sinc_resampler = { resampler_sinc_new, resampler_sinc_process, resampler_sinc_free, RESAMPLER_API_VERSION, "sinc", "sinc" }; gles2n64/src/F3DEX2.c000664 001750 001750 00000013735 12655644434 015122 0ustar00sergiosergio000000 000000 #include #include "gles2N64.h" #include "Debug.h" #include "F3D.h" #include "F3DEX.h" #include "F3DEX2.h" #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gSP.h" #include "gDP.h" #include "GBI.h" #include "OpenGL.h" #include "Config.h" void F3DEX2_Mtx( u32 w0, u32 w1 ) { gSPMatrix( w1, _SHIFTR( w0, 0, 8 ) ^ G_MTX_PUSH ); } void F3DEX2_MoveMem( u32 w0, u32 w1 ) { switch (_SHIFTR( w0, 0, 8 )) { case F3DEX2_MV_VIEWPORT: gSPViewport( w1 ); break; case G_MV_MATRIX: gSPForceMatrix( w1 ); /* force matrix takes two commands */ __RSP.PC[__RSP.PCi] += 8; break; case G_MV_LIGHT: { const uint32_t offset = (_SHIFTR( w0, 5, 11)) & 0x7F8; const u32 n = offset / 24; if (n < 2) gSPLookAt(w1, n); else gSPLight(w1, n - 1); } break; } } void F3DEX2_Vtx( u32 w0, u32 w1 ) { u32 n = _SHIFTR( w0, 12, 8 ); gSPVertex( w1, n, _SHIFTR( w0, 1, 7 ) - n ); } void F3DEX2_Reserved1( u32 w0, u32 w1 ) { } void F3DEX2_Tri1( u32 w0, u32 w1 ) { gSP1Triangle( _SHIFTR( w0, 17, 7 ), _SHIFTR( w0, 9, 7 ), _SHIFTR( w0, 1, 7 )); } void F3DEX2_Line3D( u32 w0, u32 w1 ) { } void F3DEX2_PopMtx( u32 w0, u32 w1 ) { gSPPopMatrixN( 0, w1 >> 6 ); } void F3DEX2_MoveWord( u32 w0, u32 w1 ) { switch (_SHIFTR( w0, 16, 8 )) { case G_MW_FORCEMTX: /* Handled in movemem */ break; case G_MW_MATRIX: gSPInsertMatrix( _SHIFTR( w0, 0, 16 ), w1 ); break; case G_MW_NUMLIGHT: gSPNumLights( w1 / 24 ); break; case G_MW_CLIP: gSPClipRatio( w1 ); break; case G_MW_SEGMENT: gSPSegment( _SHIFTR( w0, 0, 16 ) >> 2, w1 & 0x00FFFFFF ); break; case G_MW_FOG: gSPFogFactor( (s16)_SHIFTR( w1, 16, 16 ), (s16)_SHIFTR( w1, 0, 16 ) ); //offset must be 0 for move_fog, but it can be non zero in Nushi Zuri 64 - Shiokaze ni Notte //low-level display list has setothermode commands in this place, so this is obviously not move_fog. if (_SHIFTR(w0, 0, 16) == 0x04) gDPSetTextureLUT((w1 == 0xffffffff) ? G_TT_NONE : G_TT_RGBA16); break; case G_MW_LIGHTCOL: gSPLightColor((_SHIFTR( w0, 0, 16 ) / 24) + 1, w1 ); break; case G_MW_PERSPNORM: gSPPerspNormalize( w1 ); break; } } void F3DEX2_Texture( u32 w0, u32 w1 ) { gSPTexture( _FIXED2FLOAT( _SHIFTR( w1, 16, 16 ), 16 ), _FIXED2FLOAT( _SHIFTR( w1, 0, 16 ), 16 ), _SHIFTR( w0, 11, 3 ), _SHIFTR( w0, 8, 3 ), _SHIFTR( w0, 1, 7 ) ); } void F3DEX2_SetOtherMode_H( u32 w0, u32 w1 ) { const u32 length = _SHIFTR(w0, 0, 8) + 1; const u32 shift = MAX(0, (s32)(32 - _SHIFTR(w0, 8, 8) - length)); gSPSetOtherMode_H(length, shift, w1); } void F3DEX2_SetOtherMode_L( u32 w0, u32 w1 ) { const u32 length = _SHIFTR(w0, 0, 8) + 1; const u32 shift = MAX(0, (s32)(32 - _SHIFTR(w0, 8, 8) - length)); gSPSetOtherMode_L(length, shift, w1); } void F3DEX2_GeometryMode( u32 w0, u32 w1 ) { gSPGeometryMode( ~_SHIFTR( w0, 0, 24 ), w1 ); } void F3DEX2_DMAIO( u32 w0, u32 w1 ) { } void F3DEX2_Special_1( u32 w0, u32 w1 ) { gSPDlistCount(_SHIFTR( w0, 0, 8 ), w1); } void F3DEX2_Special_2( u32 w0, u32 w1 ) { } void F3DEX2_Special_3( u32 w0, u32 w1 ) { } void F3DEX2_Quad( u32 w0, u32 w1 ) { gSP2Triangles( _SHIFTR( w0, 17, 7 ), _SHIFTR( w0, 9, 7 ), _SHIFTR( w0, 1, 7 ), 0, _SHIFTR( w1, 17, 7 ), _SHIFTR( w1, 9, 7 ), _SHIFTR( w1, 1, 7 ), 0 ); } void F3DEX2_Init(void) { gSPSetupFunctions(); // Set GeometryMode flags GBI_InitFlags( F3DEX2 ); GBI.PCStackSize = 18; // GBI Command Command Value Command Function GBI_SetGBI( G_RDPHALF_2, F3DEX2_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_SETOTHERMODE_H, F3DEX2_SETOTHERMODE_H, F3DEX2_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3DEX2_SETOTHERMODE_L, F3DEX2_SetOtherMode_L ); GBI_SetGBI( G_RDPHALF_1, F3DEX2_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_SPNOOP, F3DEX2_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_ENDDL, F3DEX2_ENDDL, F3D_EndDL ); GBI_SetGBI( G_DL, F3DEX2_DL, F3D_DList ); GBI_SetGBI( G_LOAD_UCODE, F3DEX2_LOAD_UCODE, F3DEX_Load_uCode ); GBI_SetGBI( G_MOVEMEM, F3DEX2_MOVEMEM, F3DEX2_MoveMem ); GBI_SetGBI( G_MOVEWORD, F3DEX2_MOVEWORD, F3DEX2_MoveWord ); GBI_SetGBI( G_MTX, F3DEX2_MTX, F3DEX2_Mtx ); GBI_SetGBI( G_GEOMETRYMODE, F3DEX2_GEOMETRYMODE, F3DEX2_GeometryMode ); GBI_SetGBI( G_POPMTX, F3DEX2_POPMTX, F3DEX2_PopMtx ); GBI_SetGBI( G_TEXTURE, F3DEX2_TEXTURE, F3DEX2_Texture ); GBI_SetGBI( G_DMA_IO, F3DEX2_DMA_IO, F3DEX2_DMAIO ); GBI_SetGBI( G_SPECIAL_1, F3DEX2_SPECIAL_1, F3DEX2_Special_1 ); GBI_SetGBI( G_SPECIAL_2, F3DEX2_SPECIAL_2, F3DEX2_Special_2 ); GBI_SetGBI( G_SPECIAL_3, F3DEX2_SPECIAL_3, F3DEX2_Special_3 ); GBI_SetGBI( G_VTX, F3DEX2_VTX, F3DEX2_Vtx ); GBI_SetGBI( G_MODIFYVTX, F3DEX2_MODIFYVTX, F3DEX_ModifyVtx ); GBI_SetGBI( G_CULLDL, F3DEX2_CULLDL, F3DEX_CullDL ); GBI_SetGBI( G_BRANCH_Z, F3DEX2_BRANCH_Z, F3DEX_Branch_Z ); GBI_SetGBI( G_TRI1, F3DEX2_TRI1, F3DEX2_Tri1 ); GBI_SetGBI( G_TRI2, F3DEX2_TRI2, F3DEX_Tri2 ); GBI_SetGBI( G_QUAD, F3DEX2_QUAD, F3DEX2_Quad ); GBI_SetGBI( G_LINE3D, F3DEX2_LINE3D, F3DEX2_Line3D ); } mupen64plus-core/tools/m64p_helper_scripts.tar.gz000664 001750 001750 00000003135 12655644434 023234 0ustar00sergiosergio000000 000000 ‹í[ÿOÛ8çWòW¼Ëøa›š¦iKÑ !](-TW êMètBiâ6>;r›øßï9-4ë`ÀX'~H$ŽãçççíϳӸQONÇ‚r®­F*([››ùeùÚ¨ÔëkNÕqjU§Þ¨á{N¥ºY]ƒÊÚ/,•žX{¥òæ{L™†Æû=ü´?ã þ8ÌÂaQ–‚qkðpYÒv¬´…<&‰7% ”2ù`Û>HyÊù4"eŸÇvbÇ‹Êí[´5yr)è4”ð¶ùª•ʟЧ~è‰ö9 Èa°íçȵ¶aHSHŸ /¼B åyá ² —<ßc H@S)è8“¨6ó€N.Ú0'c C’ˆ8>Éû½ìF„Áq6ލ]ê–ðÐõ$ Iã‚6U®­ìÌí6Gõž¤œm¡˜/àœˆÓP½®i®¶h_±¥o=©š#€'JÁ;lÃ%Dž\è(?›^X8;Êòf…g)pËÊ­4ˆpÀ&™ÌïDšX!æÓ€pK Hæ·Ó/z|V5•F|PVe[’TÚ†²ñ´Ó ÝnwÇ<îŽö;½½Nn¿•ßíΟº³k·³›_;½¦ºz …î^ó¨×îìïH‘0 c’;)N8#Lª™eãËRã®¶!àÆzîsãËÍËW&ì@Þð‚cÖo²OåeBvÌˆŽ…'.McD¨âVè·¢ â‡Ì÷ØU :ÅA¥|ý£C¬gýסU ®`™ðIqa¶°^;çêµSL•Ïõb)Î$eùží‹þþž&UY„¹RrË+hÑ”2ÌW½ÿC>(ÚVLä\¡ækÜ[ÍÛ¼Q,nãÔôñejgŒ~?"¸âoüõ.OOR@’å\‰‚ha0\Á^k0T77Þ&Á»Yÿ!¶¿ABÀ}ô/"oÖ»f«7h  ßr÷[xé¶ÜAkøâ-%÷ºñõ]û_îÁÅÌ…uógÖ]e¼ë&g-I³ñ¼1Ó$²¢›…ávˆŠ9ÈϲˆX8XsŽ“–å'ùØ&ÏlUþø–/•.´¿Ø¾üßš–+ùÜ;%ruÑÿ½ñ½^mÜÄÿ›õ-|¾µUkèøÿEÆÿ3¬éè_Gÿ:ú×Ñ¿Žþ_Uôÿˆª):{ ÃŒ@¸ $5 ƒ%&ó°e ÏÏdÓàóË*ÌçLïñ qïañt8ÅÈeùÁ ׬`Lå8óÏqp1µÅl}¯Wï ŠTtüÊ"žœ“ÍãúUÅ÷ñÿšS[ðÿ†£ÎÿN]óÿÉÿXÓ€Žt #èó¿¥ó?Íåïæò¿ÃyXg¶È¯öDlq¥)žÆÿÕÑÏ îáÿ5ÇÙBþ_©ÖjÕÆ–ÓPüß©iþÿ2ùÿk O4ÿ×ü_óÍÿŸ=ÿ÷ƒüÛ.£\œR¡üíw[†æ`¿%ÿC:½ÊàÇíÿªß8N£¦ùß‹äE¬iþ§ùŸæšÿiþ§÷õþï Úÿ퓘Ÿ¯v÷÷†Gèýß§óÿ§-²²à{ùekñûïjþûïºÞÿ}©üÿkzÿWóÍÿ5ÿ×üÿ•òMìã´Gù2þ ï³“ §ÅâçÙwRüüõAxXÍýµhÑ¢E‹–‘ÿ Y®Pmupen64plus-core/src/plugin/audio_libretro/audio_utils_neon.S000664 001750 001750 00000004553 12655644434 025632 0ustar00sergiosergio000000 000000 /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. * * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with RetroArch. * If not, see . */ #if defined(__ARM_NEON__) #ifndef __MACH__ .arm #endif .align 4 .globl audio_convert_s16_float_asm .globl _audio_convert_s16_float_asm # audio_convert_s16_float_asm(float *out, const int16_t *in, size_t samples, const float *gain) audio_convert_s16_float_asm: _audio_convert_s16_float_asm: # Hacky way to get a constant of 2^-15. # Might be faster to just load a constant from memory. # It's just done once however ... vmov.f32 q8, #0.25 vmul.f32 q8, q8, q8 vmul.f32 q8, q8, q8 vmul.f32 q8, q8, q8 vadd.f32 q8, q8, q8 # Apply gain vld1.f32 {d6[0]}, [r3] vmul.f32 q8, q8, d6[0] 1: # Preload here? vld1.s16 {q0}, [r1]! # Widen to 32-bit vmovl.s16 q1, d0 vmovl.s16 q2, d1 # Convert to float vcvt.f32.s32 q1, q1 vcvt.f32.s32 q2, q2 vmul.f32 q1, q1, q8 vmul.f32 q2, q2, q8 vst1.f32 {q1-q2}, [r0]! # Guaranteed to get samples in multiples of 8. subs r2, r2, #8 bne 1b bx lr .align 4 .globl audio_convert_float_s16_asm .globl _audio_convert_float_s16_asm # audio_convert_float_s16_asm(int16_t *out, const float *in, size_t samples) audio_convert_float_s16_asm: _audio_convert_float_s16_asm: # Hacky way to get a constant of 2^15. # ((2^4)^2)^2 * 0.5 = 2^15 vmov.f32 q8, #16.0 vmov.f32 q9, #0.5 vmul.f32 q8, q8, q8 vmul.f32 q8, q8, q8 vmul.f32 q8, q8, q9 1: # Preload here? vld1.f32 {q0-q1}, [r1]! vmul.f32 q0, q0, q8 vmul.f32 q1, q1, q8 vcvt.s32.f32 q0, q0 vcvt.s32.f32 q1, q1 vqmovn.s32 d4, q0 vqmovn.s32 d5, q1 vst1.f32 {d4-d5}, [r0]! # Guaranteed to get samples in multiples of 8. subs r2, r2, #8 bne 1b bx lr #endif gles2rice/src/Debugger.h000664 001750 001750 00000017037 12655644434 016272 0ustar00sergiosergio000000 000000 /* Copyright (C) 2002 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #if !defined(DEBUGGER_H) #define DEBUGGER_H #include "typedefs.h" #if defined(DEBUGGER) // Debugger.h : header file // ///////////////////////////////////////////////////////////////////////////// // CDebugger dialog extern bool debuggerWinOpened; extern bool logCombiners; extern bool logTriangles; extern bool logVertex; extern bool logWarning; extern bool logTextures; extern bool logTextureBuffer; extern bool logMatrix; extern bool logToScreen; extern bool logToFile; extern bool logUcodes; extern bool logMicrocode; extern bool logFog; extern bool logDetails; extern bool debuggerEnableTexture; extern bool debuggerEnableZBuffer; extern bool debuggerEnableCullFace; extern bool debuggerEnableTestTris; extern bool debuggerEnableAlphaTest; extern bool debuggerContinueWithUnknown; extern bool debuggerPause; extern bool pauseAtNext; extern int eventToPause; extern int debuggerPauseCount; extern int countToPause; extern bool debuggerDropCombiners; extern bool debuggerDropGeneralCombiners; extern bool debuggerDropDecodedMux; extern bool debuggerDropCombinerInfos; enum { NEXT_FRAME, NEXT_FLUSH_TRI, NEXT_TEXTRECT, NEXT_TRIANGLE, NEXT_SET_CIMG, NEXT_OBJ_TXT_CMD, NEXT_OBJ_BG, NEXT_SPRITE_2D, NEXT_FILLRECT, NEXT_DLIST, NEXT_UCODE, NEXT_RENDER_TEXTURE, NEXT_MATRIX_CMD, NEXT_VERTEX_CMD, NEXT_NEW_TEXTURE, NEXT_SET_TEXTURE, NEXT_MUX, NEXT_SET_LIGHT, NEXT_SET_MODE_CMD, NEXT_SET_PRIM_COLOR, NEXT_TEXTURE_CMD, NEXT_UNKNOWN_OP, NEXT_SCALE_IMG, NEXT_LOADTLUT, NEXT_SWITCH_UCODE, }; void DebuggerPause(); void DebuggerAppendMsg(const char * Message, ...); void DumpHex(uint32 rdramAddr, int count); void DumpMatrix(const Matrix &mtx, const char* prompt); //Some common used macros #define DEBUG_DUMP_VERTEXES(str, v0, v1, v2) \ if( (pauseAtNext && (eventToPause == NEXT_TRIANGLE || eventToPause == NEXT_FLUSH_TRI)) && logTriangles ) \ { \ DebuggerAppendMsg("%s:%d(%08X),%d(%08X),%d(%08X)\n", (str),\ (v0), GetVertexDiffuseColor((v0)), \ (v1), GetVertexDiffuseColor((v1)), \ (v2), GetVertexDiffuseColor((v2))); \ } #define DEBUGGER_IF(op) if(op) #define DEBUGGER_PAUSE(op) if(pauseAtNext && eventToPause == op){pauseAtNext = false;CGraphicsContext::Get()->UpdateFrame(false); debuggerPause = true;} extern void DEBUGGER_PAUSE_COUNT_N(uint32 event); extern void DEBUGGER_PAUSE_COUNT_N_WITHOUT_UPDATE(uint32 val); #define DebuggerPauseCountN DEBUGGER_PAUSE_COUNT_N #define DEBUGGER_PAUSE_AND_DUMP(op,dumpfuc) \ if(pauseAtNext && eventToPause == op) \ { pauseAtNext = false;debuggerPause = true; CGraphicsContext::Get()->UpdateFrame(false); dumpfuc;} #define DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(op,dumpfuc) \ if(pauseAtNext && eventToPause == op) \ { pauseAtNext = false;debuggerPause = true; dumpfuc;} #define DEBUGGER_PAUSE_AND_DUMP_COUNT_N(op,dumpfuc) \ if(pauseAtNext && eventToPause == op) \ { if( debuggerPauseCount > 0 ) debuggerPauseCount--; if( debuggerPauseCount == 0 ){pauseAtNext = false;debuggerPause = true; CGraphicsContext::Get()->UpdateFrame(false); dumpfuc;}} #define DEBUGGER_PAUSE_AT_COND_AND_DUMP_COUNT_N(cond,dumpfuc) \ if(pauseAtNext && (cond) ) \ { if( debuggerPauseCount > 0 ) debuggerPauseCount--; if( debuggerPauseCount == 0 ){pauseAtNext = false;debuggerPause = true; CGraphicsContext::Get()->UpdateFrame(false); dumpfuc;}} void RDP_NOIMPL_Real(const char* op,uint32,uint32) ; #define RSP_RDP_NOIMPL RDP_NOIMPL_Real #define DEBUGGER_IF_DUMP(cond, dumpfunc) {if(cond) {dumpfunc}} #define TXTRBUF_DUMP(dumpfunc) DEBUGGER_IF_DUMP((logTextureBuffer), dumpfunc) #define TXTRBUF_DETAIL_DUMP(dumpfunc) DEBUGGER_IF_DUMP((logTextureBuffer&&logDetails), dumpfunc) #define TXTRBUF_OR_CI_DUMP(dumpfunc) DEBUGGER_IF_DUMP((logTextureBuffer || (pauseAtNext && eventToPause == NEXT_SET_CIMG)), dumpfunc) #define TXTRBUF_OR_CI_DETAIL_DUMP(dumpfunc) DEBUGGER_IF_DUMP(((logTextureBuffer || (pauseAtNext && eventToPause == NEXT_SET_CIMG))&&logDetails), dumpfunc) #define VTX_DUMP(dumpfunc) DEBUGGER_IF_DUMP((logVertex && pauseAtNext), dumpfunc) #define TRI_DUMP(dumpfunc) DEBUGGER_IF_DUMP((logTriangles && pauseAtNext), dumpfunc) #define LIGHT_DUMP(dumpfunc) DEBUGGER_IF_DUMP((eventToPause == NEXT_SET_LIGHT && pauseAtNext), dumpfunc) #define WARNING(dumpfunc) DEBUGGER_IF_DUMP(logWarning, dumpfunc) #define FOG_DUMP(dumpfunc) DEBUGGER_IF_DUMP(logFog, dumpfunc) #define LOG_TEXTURE(dumpfunc) DEBUGGER_IF_DUMP((logTextures || (pauseAtNext && eventToPause==NEXT_TEXTURE_CMD) ), dumpfunc) #define DEBUGGER_ONLY_IF DEBUGGER_IF_DUMP #define DEBUGGER_ONLY(func) {func} #define TRACE0(arg0) {DebuggerAppendMsg(arg0);} #define TRACE1(arg0,arg1) {DebuggerAppendMsg(arg0,arg1);} #define TRACE2(arg0,arg1,arg2) {DebuggerAppendMsg(arg0,arg1,arg2);} #define TRACE3(arg0,arg1,arg2,arg3) {DebuggerAppendMsg(arg0,arg1,arg2,arg3);} #define TRACE4(arg0,arg1,arg2,arg3,arg4) {DebuggerAppendMsg(arg0,arg1,arg2,arg3,arg4);} #define TRACE5(arg0,arg1,arg2,arg3,arg4,arg5) {DebuggerAppendMsg(arg0,arg1,arg2,arg3,arg4,arg5);} #define DEBUG_TRIANGLE(dumpfunc) { if(pauseAtNext && eventToPause==NEXT_TRIANGLE ) { eventToPause = NEXT_FLUSH_TRI; debuggerPause = true; DEBUGGER_PAUSE(NEXT_FLUSH_TRI); dumpfunc} } #else #define DEBUG_DUMP_VERTEXES(str, v0, v1, v2) #define DEBUGGER_IF(op) #define DEBUGGER_PAUSE(op) #define DEBUGGER_PAUSE_COUNT_N(op) #define DEBUGGER_PAUSE_AND_DUMP(op,dumpfuc) #define DebuggerPauseCountN DEBUGGER_PAUSE_COUNT_N #define DEBUGGER_PAUSE_AT_COND_AND_DUMP_COUNT_N(cond,dumpfuc) #define DEBUGGER_PAUSE_AND_DUMP_COUNT_N(op,dumpfuc) #define DEBUGGER_PAUSE_COUNT_N_WITHOUT_UPDATE(op) #define DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(op,dumpfuc) #define RSP_RDP_NOIMPL(a,b,c) void DebuggerAppendMsg(const char * Message, ...); #define DumpHex(rdramAddr, count) #define DEBUGGER_IF_DUMP(cond, dumpfunc) #define TXTRBUF_DUMP(dumpfunc) #define TXTRBUF_DETAIL_DUMP(dumpfunc) #define TXTRBUF_OR_CI_DUMP(dumpfunc) #define TXTRBUF_OR_CI_DETAIL_DUMP(dumpfunc) #define VTX_DUMP(dumpfunc) #define TRI_DUMP(dumpfunc) #define LIGHT_DUMP(dumpfunc) #define WARNING(dumpfunc) #define FOG_DUMP(dumpfunc) #define LOG_TEXTURE(dumpfunc) #define DEBUGGER_ONLY_IF DEBUGGER_IF_DUMP #define DEBUGGER_ONLY(func) #define DumpMatrix(a,b) #define TRACE0(arg0) {} #define TRACE1(arg0,arg1) {} #define TRACE2(arg0,arg1,arg2) {} #define TRACE3(arg0,arg1,arg2,arg3) {} #define TRACE4(arg0,arg1,arg2,arg3,arg4) {} #define TRACE5(arg0,arg1,arg2,arg3,arg4,arg5) {} #define DEBUG_TRIANGLE(arg0) {} #endif #endif // !defined(DEBUGGER_H) mupen64plus-rsp-hle/src/alist_naudio.c000664 001750 001750 00000023237 12655644434 021106 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-rsp-hle - alist_naudio.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * Copyright (C) 2009 Richard Goedeken * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include "common.h" #include "alist.h" #include "hle_external.h" #include "hle_internal.h" #include "memory.h" #include "ucodes.h" enum { NAUDIO_COUNT = 0x170 }; /* ie 184 samples */ enum { NAUDIO_MAIN = 0x4f0, NAUDIO_MAIN2 = 0x660, NAUDIO_DRY_LEFT = 0x9d0, NAUDIO_DRY_RIGHT = 0xb40, NAUDIO_WET_LEFT = 0xcb0, NAUDIO_WET_RIGHT = 0xe20 }; /* audio commands definition */ static void UNKNOWN(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint8_t acmd = (w1 >> 24); HleWarnMessage(hle->user_defined, "Unknown audio command %d: %08x %08x", acmd, w1, w2); } static void SPNOOP(struct hle_t* UNUSED(hle), uint32_t UNUSED(w1), uint32_t UNUSED(w2)) { } static void NAUDIO_0000(struct hle_t* hle, uint32_t w1, uint32_t w2) { /* ??? */ UNKNOWN(hle, w1, w2); } static void NAUDIO_02B0(struct hle_t* hle, uint32_t UNUSED(w1), uint32_t w2) { /* emulate code at 0x12b0 (inside SETVOL), because PC always execute in IMEM */ hle->alist_naudio.rate[1] &= ~0xffff; hle->alist_naudio.rate[1] |= (w2 & 0xffff); } static void NAUDIO_14(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint8_t flags = (w1 >> 16); uint16_t gain = w1; uint8_t select_main = (w2 >> 24); uint32_t address = (w2 & 0xffffff); uint16_t dmem = (select_main == 0) ? NAUDIO_MAIN : NAUDIO_MAIN2; if (hle->alist_naudio.table[0] == 0 && hle->alist_naudio.table[1] == 0) { alist_polef( hle, flags & A_INIT, dmem, dmem, NAUDIO_COUNT, gain, hle->alist_naudio.table, address); return; } alist_iirf( hle, flags & A_INIT, dmem, dmem, NAUDIO_COUNT, hle->alist_naudio.table, address); } static void SETVOL(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint8_t flags = (w1 >> 16); if (flags & 0x4) { if (flags & 0x2) { hle->alist_naudio.vol[0] = w1; hle->alist_naudio.dry = (w2 >> 16); hle->alist_naudio.wet = w2; } else { hle->alist_naudio.target[1] = w1; hle->alist_naudio.rate[1] = w2; } return; } hle->alist_naudio.target[0] = w1; hle->alist_naudio.rate[0] = w2; } static void ENVMIXER(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint8_t flags = (w1 >> 16); uint32_t address = (w2 & 0xffffff); hle->alist_naudio.vol[1] = w1; alist_envmix_lin( hle, flags & 0x1, NAUDIO_DRY_LEFT, NAUDIO_DRY_RIGHT, NAUDIO_WET_LEFT, NAUDIO_WET_RIGHT, NAUDIO_MAIN, NAUDIO_COUNT, hle->alist_naudio.dry, hle->alist_naudio.wet, hle->alist_naudio.vol, hle->alist_naudio.target, hle->alist_naudio.rate, address); } static void CLEARBUFF(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint16_t dmem = w1 + NAUDIO_MAIN; uint16_t count = w2; alist_clear(hle, dmem, count); } static void MIXER(struct hle_t* hle, uint32_t w1, uint32_t w2) { int16_t gain = w1; uint16_t dmemi = (w2 >> 16) + NAUDIO_MAIN; uint16_t dmemo = w2 + NAUDIO_MAIN; alist_mix(hle, dmemo, dmemi, NAUDIO_COUNT, gain); } static void LOADBUFF(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint16_t count = (w1 >> 12) & 0xfff; uint16_t dmem = (w1 & 0xfff) + NAUDIO_MAIN; uint32_t address = (w2 & 0xffffff); alist_load(hle, dmem, address, count); } static void SAVEBUFF(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint16_t count = (w1 >> 12) & 0xfff; uint16_t dmem = (w1 & 0xfff) + NAUDIO_MAIN; uint32_t address = (w2 & 0xffffff); alist_save(hle, dmem, address, count); } static void LOADADPCM(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint16_t count = w1; uint32_t address = (w2 & 0xffffff); dram_load_u16(hle, (uint16_t*)hle->alist_naudio.table, address, count >> 1); } static void DMEMMOVE(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint16_t dmemi = w1 + NAUDIO_MAIN; uint16_t dmemo = (w2 >> 16) + NAUDIO_MAIN; uint16_t count = w2; alist_move(hle, dmemo, dmemi, (count + 3) & ~3); } static void SETLOOP(struct hle_t* hle, uint32_t UNUSED(w1), uint32_t w2) { hle->alist_naudio.loop = (w2 & 0xffffff); } static void ADPCM(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint32_t address = (w1 & 0xffffff); uint8_t flags = (w2 >> 28); uint16_t count = (w2 >> 16) & 0xfff; uint16_t dmemi = ((w2 >> 12) & 0xf) + NAUDIO_MAIN; uint16_t dmemo = (w2 & 0xfff) + NAUDIO_MAIN; alist_adpcm( hle, flags & 0x1, flags & 0x2, false, /* unsuported by this ucode */ dmemo, dmemi, (count + 0x1f) & ~0x1f, hle->alist_naudio.table, hle->alist_naudio.loop, address); } static void RESAMPLE(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint32_t address = (w1 & 0xffffff); uint8_t flags = (w2 >> 30); uint16_t pitch = (w2 >> 14); uint16_t dmemi = ((w2 >> 2) & 0xfff) + NAUDIO_MAIN; uint16_t dmemo = (w2 & 0x3) ? NAUDIO_MAIN2 : NAUDIO_MAIN; alist_resample( hle, flags & 0x1, false, /* TODO: check which ABI supports it */ dmemo, dmemi, NAUDIO_COUNT, pitch << 1, address); } static void INTERLEAVE(struct hle_t* hle, uint32_t UNUSED(w1), uint32_t UNUSED(w2)) { alist_interleave(hle, NAUDIO_MAIN, NAUDIO_DRY_LEFT, NAUDIO_DRY_RIGHT, NAUDIO_COUNT); } static void MP3ADDY(struct hle_t* UNUSED(hle), uint32_t UNUSED(w1), uint32_t UNUSED(w2)) { } static void MP3(struct hle_t* hle, uint32_t w1, uint32_t w2) { unsigned index = (w1 & 0x1e); uint32_t address = (w2 & 0xffffff); mp3_task(hle, index, address); } /* global functions */ void alist_process_naudio(struct hle_t* hle) { static const acmd_callback_t ABI[0x10] = { SPNOOP, ADPCM, CLEARBUFF, ENVMIXER, LOADBUFF, RESAMPLE, SAVEBUFF, NAUDIO_0000, NAUDIO_0000, SETVOL, DMEMMOVE, LOADADPCM, MIXER, INTERLEAVE, NAUDIO_02B0, SETLOOP }; alist_process(hle, ABI, 0x10); } void alist_process_naudio_bk(struct hle_t* hle) { /* TODO: see what differs from alist_process_naudio */ static const acmd_callback_t ABI[0x10] = { SPNOOP, ADPCM, CLEARBUFF, ENVMIXER, LOADBUFF, RESAMPLE, SAVEBUFF, NAUDIO_0000, NAUDIO_0000, SETVOL, DMEMMOVE, LOADADPCM, MIXER, INTERLEAVE, NAUDIO_02B0, SETLOOP }; alist_process(hle, ABI, 0x10); } void alist_process_naudio_dk(struct hle_t* hle) { /* TODO: see what differs from alist_process_naudio */ static const acmd_callback_t ABI[0x10] = { SPNOOP, ADPCM, CLEARBUFF, ENVMIXER, LOADBUFF, RESAMPLE, SAVEBUFF, MIXER, MIXER, SETVOL, DMEMMOVE, LOADADPCM, MIXER, INTERLEAVE, NAUDIO_02B0, SETLOOP }; alist_process(hle, ABI, 0x10); } void alist_process_naudio_mp3(struct hle_t* hle) { static const acmd_callback_t ABI[0x10] = { UNKNOWN, ADPCM, CLEARBUFF, ENVMIXER, LOADBUFF, RESAMPLE, SAVEBUFF, MP3, MP3ADDY, SETVOL, DMEMMOVE, LOADADPCM, MIXER, INTERLEAVE, NAUDIO_14, SETLOOP }; alist_process(hle, ABI, 0x10); } void alist_process_naudio_cbfd(struct hle_t* hle) { /* TODO: see what differs from alist_process_naudio_mp3 */ static const acmd_callback_t ABI[0x10] = { UNKNOWN, ADPCM, CLEARBUFF, ENVMIXER, LOADBUFF, RESAMPLE, SAVEBUFF, MP3, MP3ADDY, SETVOL, DMEMMOVE, LOADADPCM, MIXER, INTERLEAVE, NAUDIO_14, SETLOOP }; alist_process(hle, ABI, 0x10); } mupen64plus-core/README000664 001750 001750 00000012723 12655644434 015734 0ustar00sergiosergio000000 000000 Mupen64Plus-Core README ----------------------- The most current version of this README and more documentation can be found on the Mupen64Plus wiki: http://code.google.com/p/mupen64plus/wiki/README Mupen64Plus is based off of mupen64, originally created by Hacktarux. This package contains the only the Mupen64Plus core library. For a fully functional emulator, the user must also install graphics, sound, input, and RSP plugins, as well as a user interface program (called a front-end). README Sections 1. Requirements for building or running Mupen64Plus 2. Building From Source 3. Installation 4. Key Commands In Emulator 1. Requirements and Pre-requisites ---------------------------------- *Binary Package Requirements* - SDL 1.2 - libpng - freetype 2 - zlib *Source Build Requirements* In addition to the binary libraries, the following packages are required if you build Mupen64Plus from source: - GNU C and C++ compiler, libraries, and headers - GNU make - Development packages for all the libraries above 2. Building From Source ----------------------- If you downloaded the binary distribution of Mupen64Plus, skip to the Installation section. To build the source distribution, unzip and cd into the projects/unix directory, then build using make: $ unzip mupen64plus-core-x-y-z-src.zip $ cd mupen64plus-core-x-y-z-src/projects/unix $ make all Type 'make' by itself to view all available build options: $ make Mupen64Plus makefile. Targets: all == Build Mupen64Plus and all plugins clean == remove object files install == Install Mupen64Plus and all plugins uninstall == Uninstall Mupen64Plus and all plugins Options: BITS=32 == build 32-bit binaries on 64-bit machine LIRC=1 == enable LIRC support NO_ASM=1 == build without assembly (no dynamic recompiler or MMX/SSE code) SHAREDIR=path == extra path to search for shared data files OPTFLAGS=flag == compiler optimization (default: -O3) PIC=(1|0) == Force enable/disable of position independent code Install Options: PREFIX=path == install/uninstall prefix (default: /usr/local/) SHAREDIR=path == path to install shared data (default: PREFIX/share/mupen64plus/) LIBDIR=path == path to install plugin libs (default: PREFIX/lib) INCDIR=path == path to install core header files (default: PREFIX/include/mupen64plus) DESTDIR=path == path to prepend to all installation paths (only for packagers) Debugging Options: PROFILE=1 == build gprof instrumentation into binaries for profiling DEBUG=1 == add debugging symbols to binaries DEBUGGER=1 == build graphical debugger DBG_CORE=1 == print debugging info in r4300 core DBG_COUNT=1 == print R4300 instruction count totals (64-bit dynarec only) DBG_COMPARE=1 == enable core-synchronized r4300 debugging DBG_PROFILE=1 == dump profiling data for r4300 dynarec to data file V=1 == show verbose compiler output 3. Installation --------------- *Binary Distribution* To install the binary distribution of Mupen64Plus, su to root and run the provided install.sh script: $ su # ./install.sh # exit $ The install script will copy the executable to /usr/local/bin and a directory called /usr/local/share/mupen64plus will be created to hold plugins and other files used by mupen64plus. NOTE: By default, install.sh uses /usr/local for the install prefix. Although the user can specify an alternate prefix to install.sh at the commandline, the mupen64plus binary was compiled to look for the install directory in /usr/local, so specifying an alternate prefix to install.sh will cause problems (mupen64plus will not find the install directory). If you want to use a prefix other than /usr/local, you will have to download the source package and build with the PREFIX option (see below). *Source Distribution* After building mupen64plus and all plugins, su to root and type 'make install' to install Mupen64Plus. The install process will copy the executable to $PREFIX/bin and a directory called $PREFIX/share/mupen64plus will be created to hold plugins and other files used by mupen64plus. By default, PREFIX is set to /usr/local. This can be changed by passing the PREFIX option to make. NOTE: you must pass the prefix, when building AND installing. For example, to install mupen64plus to /usr, do this: $ make all $ sudo make PREFIX=/usr install $ 4. Key Commands In Emulator --------------------------- The keys or joystick/mouse inputs which will be mapped to the N64 controller for playing the games are determined by the input plugin. The emulator core also supports several key commands during emulation, which may be configured by editing the ~/.config/mupen64plus/mupen64plus.cfg file. They are: Escape == Quit the emulator 0-9 == Select virtual 'slot' for save/load state (F5 and F7) commands F5 == Save emulator state F7 == Load emulator state F9 == Reset emulator F10 == slow down emulator by 5% F11 == speed up emulator by 5% F12 == take screenshot Alt-Enter == Toggle between windowed and fullscreen (may not be supported by all video plugins) p or P == Pause on/off m or M == Mute/unmute sound g or G == Press "Game Shark" button (only if cheats are enabled) / or ? == single frame advance while paused F == Fast Forward (playback at 250% normal speed while F key is pressed) [ == Decrease volume ] == Increase volume mupen64plus-core/src/si/rumblepak.h000664 001750 001750 00000003737 12655644434 020416 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - rumblepak.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_SI_RUMBLEPAK_H #define M64P_SI_RUMBLEPAK_H #include enum rumble_action { RUMBLE_STOP, RUMBLE_START }; struct rumblepak { /* external rumble sink */ void* user_data; void (*rumble)(void*,enum rumble_action); }; void rumblepak_rumble(struct rumblepak* rpk, enum rumble_action action); void rumblepak_read_command(struct rumblepak* rpk, uint8_t* cmd); void rumblepak_write_command(struct rumblepak* rpk, uint8_t* cmd); #endif mupen64plus-video-gliden64/src/GLideNHQ/TxUtil.cpp000664 001750 001750 00000027202 12655644434 022721 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "TxUtil.h" #include "TxDbg.h" #include #include #if defined (OS_MAC_OS_X) #include #include #elif defined OS_LINUX #include #endif /* * Utilities ******************************************************************************/ uint32 TxUtil::checksumTx(uint8 *src, int width, int height, uint16 format) { int dataSize = sizeofTx(width, height, format); /* for now we use adler32 if something else is better * we can simply swtich later */ /* return (dataSize ? Adler32(src, dataSize, 1) : 0); */ /* zlib crc32 */ return (dataSize ? crc32(crc32(0L, Z_NULL, 0), src, dataSize) : 0); } int TxUtil::sizeofTx(int width, int height, uint16 format) { int dataSize = 0; /* a lookup table for the shifts would be better */ switch (format) { case GL_COLOR_INDEX8_EXT: dataSize = width * height; break; case GL_RGBA4: case GL_RGB5_A1: case GL_RGB: dataSize = (width * height) << 1; break; case GL_RGBA8: dataSize = (width * height) << 2; break; default: /* unsupported format */ DBG_INFO(80, wst("Error: cannot get size. unsupported gfmt:%x\n"), format); ; } return dataSize; } uint32 TxUtil::checksum(uint8 *src, int width, int height, int size, int rowStride) { /* Rice CRC32 for now. We can switch this to Jabo MD5 or * any other custom checksum. * TODO: use *_HIRESTEXTURE option. */ if (!src) return 0; return RiceCRC32(src, width, height, size, rowStride); } uint64 TxUtil::checksum64(uint8 *src, int width, int height, int size, int rowStride, uint8 *palette) { /* Rice CRC32 for now. We can switch this to Jabo MD5 or * any other custom checksum. * TODO: use *_HIRESTEXTURE option. */ /* Returned value is 64bits: hi=palette crc32 low=texture crc32 */ if (!src) return 0; uint64 crc64Ret = 0; if (palette) { uint32 crc32 = 0, cimax = 0; switch (size & 0xff) { case 1: if (RiceCRC32_CI8(src, width, height, rowStride, &crc32, &cimax)) { crc64Ret = (uint64)RiceCRC32(palette, cimax + 1, 1, 2, 512); crc64Ret <<= 32; crc64Ret |= (uint64)crc32; } break; case 0: if (RiceCRC32_CI4(src, width, height, rowStride, &crc32, &cimax)) { crc64Ret = (uint64)RiceCRC32(palette, cimax + 1, 1, 2, 32); crc64Ret <<= 32; crc64Ret |= (uint64)crc32; } } } if (!crc64Ret) { crc64Ret = (uint64)RiceCRC32(src, width, height, size, rowStride); } return crc64Ret; } /* Rice CRC32 for hires texture packs */ /* NOTE: The following is used in Glide64 to calculate the CRC32 * for Rice hires texture packs. * * BYTE* addr = (BYTE*)(gfx.RDRAM + * rdp.addr[rdp.tiles[tile].t_mem] + * (rdp.tiles[tile].ul_t * bpl) + * (((rdp.tiles[tile].ul_s<>1)); * RiceCRC32(addr, * rdp.tiles[tile].width, * rdp.tiles[tile].height, * (unsigned short)(rdp.tiles[tile].format << 8 | rdp.tiles[tile].size), * bpl); */ uint32 TxUtil::RiceCRC32(const uint8* src, int width, int height, int size, int rowStride) { /* NOTE: bytes_per_width must be equal or larger than 4 */ uint32 crc32Ret = 0; const uint32 bytesPerLine = width << size >> 1; try { #ifdef __MSC__ __asm { push ebx; push esi; push edi; mov ecx, dword ptr [src]; mov eax, dword ptr [height]; mov edx, 0; dec eax; loop2: mov ebx, dword ptr[bytesPerLine]; sub ebx, 4; loop1: mov esi, dword ptr [ecx+ebx]; xor esi, ebx; rol edx, 4; add edx, esi; sub ebx, 4; jge loop1; xor esi, eax; add edx, esi; add ecx, dword ptr [rowStride]; dec eax; jge loop2; mov dword ptr [crc32Ret], edx; pop edi; pop esi; pop ebx; } #else int y = height - 1; while (y >= 0) { uint32 esi = 0; int x = bytesPerLine - 4; while (x >= 0) { esi = *(uint32*)(src + x); esi ^= x; crc32Ret = (crc32Ret << 4) + ((crc32Ret >> 28) & 15); crc32Ret += esi; x -= 4; } esi ^= y; crc32Ret += esi; src += rowStride; --y; } #endif } catch(...) { DBG_INFO(80, wst("Error: RiceCRC32 exception!\n")); } return crc32Ret; } static uint8 CalculateMaxCI8b(const uint8* src, uint32 width, uint32 height, uint32 rowStride) { uint8 val = 0; for (uint32 y = 0; y < height; ++y) { const uint8 * buf = src + rowStride * y; for (uint32 x = 0; x val) val = buf[x]; if (val == 0xFF) return 0xFF; } } return val; } static uint8 CalculateMaxCI4b(const uint8* src, uint32 width, uint32 height, uint32 rowStride) { uint8 val = 0; uint8 val1, val2; width >>= 1; for (uint32 y = 0; y < height; ++y) { const uint8 * buf = src + rowStride * y; for (uint32 x = 0; x> 4; val2 = buf[x] & 0xF; if (val1 > val) val = val1; if (val2 > val) val = val2; if (val == 0xF) return 0xF; } } return val; } boolean TxUtil::RiceCRC32_CI4(const uint8* src, int width, int height, int rowStride, uint32* crc32, uint32* cimax) { /* NOTE: bytes_per_width must be equal or larger than 4 */ uint32 crc32Ret = 0; uint32 cimaxRet = 0; const uint32 bytes_per_width = width >> 1; /*if (bytes_per_width < 4) return 0;*/ /* 4bit CI */ try { #ifdef __MSC__ __asm { push ebx; push esi; push edi; mov ecx, dword ptr [src]; mov eax, dword ptr [height]; mov edx, 0; mov edi, 0; dec eax; loop2: mov ebx, dword ptr [bytes_per_width]; sub ebx, 4; loop1: mov esi, dword ptr [ecx+ebx]; cmp edi, 0x0000000f; je findmax0; push ecx; mov ecx, esi; and ecx, 0x0000000f; cmp ecx, edi; jb findmax8; mov edi, ecx; findmax8: mov ecx, esi; shr ecx, 4; and ecx, 0x0000000f; cmp ecx, edi; jb findmax7; mov edi, ecx; findmax7: mov ecx, esi; shr ecx, 8; and ecx, 0x0000000f; cmp ecx, edi; jb findmax6; mov edi, ecx; findmax6: mov ecx, esi; shr ecx, 12; and ecx, 0x0000000f; cmp ecx, edi; jb findmax5; mov edi, ecx; findmax5: mov ecx, esi; shr ecx, 16; and ecx, 0x0000000f; cmp ecx, edi; jb findmax4; mov edi, ecx; findmax4: mov ecx, esi; shr ecx, 20; and ecx, 0x0000000f; cmp ecx, edi; jb findmax3; mov edi, ecx; findmax3: mov ecx, esi; shr ecx, 24; and ecx, 0x0000000f; cmp ecx, edi; jb findmax2; mov edi, ecx; findmax2: mov ecx, esi; shr ecx, 28; and ecx, 0x0000000f; cmp ecx, edi; jb findmax1; mov edi, ecx; findmax1: pop ecx; findmax0: xor esi, ebx; rol edx, 4; add edx, esi; sub ebx, 4; jge loop1; xor esi, eax; add edx, esi; add ecx, dword ptr [rowStride]; dec eax; jge loop2; mov dword ptr [crc32Ret], edx; mov dword ptr [cimaxRet], edi; pop edi; pop esi; pop ebx; } #else crc32Ret = RiceCRC32(src, width, height, 0, rowStride); cimaxRet = CalculateMaxCI4b(src, width, height, rowStride); #endif } catch(...) { DBG_INFO(80, wst("Error: RiceCRC32 exception!\n")); } *crc32 = crc32Ret; *cimax = cimaxRet; return 1; } boolean TxUtil::RiceCRC32_CI8(const uint8* src, int width, int height, int rowStride, uint32* crc32, uint32* cimax) { /* NOTE: bytes_per_width must be equal or larger than 4 */ uint32 crc32Ret = 0; uint32 cimaxRet = 0; /* 8bit CI */ try { #ifdef __MSC__ const uint32 bytes_per_width = width; __asm { push ebx; push esi; push edi; mov ecx, dword ptr [src]; mov eax, dword ptr [height]; mov edx, 0; mov edi, 0; dec eax; loop2: mov ebx, dword ptr [bytes_per_width]; sub ebx, 4; loop1: mov esi, dword ptr [ecx+ebx]; cmp edi, 0x000000ff; je findmax0; push ecx; mov ecx, esi; and ecx, 0x000000ff; cmp ecx, edi; jb findmax4; mov edi, ecx; findmax4: mov ecx, esi; shr ecx, 8; and ecx, 0x000000ff; cmp ecx, edi; jb findmax3; mov edi, ecx; findmax3: mov ecx, esi; shr ecx, 16; and ecx, 0x000000ff; cmp ecx, edi; jb findmax2; mov edi, ecx; findmax2: mov ecx, esi; shr ecx, 24; and ecx, 0x000000ff; cmp ecx, edi; jb findmax1; mov edi, ecx; findmax1: pop ecx; findmax0: xor esi, ebx; rol edx, 4; add edx, esi; sub ebx, 4; jge loop1; xor esi, eax; add edx, esi; add ecx, dword ptr [rowStride]; dec eax; jge loop2; mov dword ptr [crc32Ret], edx; mov dword ptr [cimaxRet], edi; pop edi; pop esi; pop ebx; } #else crc32Ret = RiceCRC32(src, width, height, 1, rowStride); cimaxRet = CalculateMaxCI8b(src, width, height, rowStride); #endif } catch(...) { DBG_INFO(80, wst("Error: RiceCRC32 exception!\n")); } *crc32 = crc32Ret; *cimax = cimaxRet; return 1; } int TxUtil::getNumberofProcessors() { int numcore = 1; #ifndef ANDROID try { #if defined (OS_WINDOWS) SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); numcore = sysinfo.dwNumberOfProcessors; #elif defined (OS_MAC_OS_X) int nm[2]; size_t len = 4; uint32_t count; nm[0] = CTL_HW; nm[1] = HW_AVAILCPU; sysctl(nm, 2, &count, &len, NULL, 0); if (count < 1) { nm[1] = HW_NCPU; sysctl(nm, 2, &count, &len, NULL, 0); if (count < 1) { count = 1; } } numcore = count; #elif defined (OS_LINUX) numcore = sysconf(_SC_NPROCESSORS_ONLN); #endif } catch (...) { DBG_INFO(80, wst("Error: number of processor detection failed!\n")); } if (numcore > MAX_NUMCORE) numcore = MAX_NUMCORE; #endif // ANDROID DBG_INFO(80, wst("Number of processors : %d\n"), numcore); return numcore; } /* * Memory buffers for texture manipulations ******************************************************************************/ TxMemBuf::TxMemBuf() { int i; for (i = 0; i < 2; i++) { _tex[i] = NULL; _size[i] = 0; } } TxMemBuf::~TxMemBuf() { shutdown(); } boolean TxMemBuf::init(int maxwidth, int maxheight) { int i; for (i = 0; i < 2; i++) { if (!_tex[i]) { _tex[i] = (uint8 *)malloc(maxwidth * maxheight * 4); _size[i] = maxwidth * maxheight * 4; } if (!_tex[i]) { shutdown(); return 0; } } return 1; } void TxMemBuf::shutdown() { int i; for (i = 0; i < 2; i++) { if (_tex[i]) free(_tex[i]); _tex[i] = NULL; _size[i] = 0; } } uint8* TxMemBuf::get(unsigned int num) { return ((num < 2) ? _tex[num] : NULL); } uint32 TxMemBuf::size_of(unsigned int num) { return ((num < 2) ? _size[num] : 0); } void setTextureFormat(uint16 internalFormat, GHQTexInfo * info) { info->format = internalFormat; switch (internalFormat) { case GL_RGBA8: info->texture_format = GL_RGBA; info->pixel_type = GL_UNSIGNED_BYTE; break; case GL_RGB: info->texture_format = GL_RGB; info->pixel_type = GL_UNSIGNED_SHORT_5_6_5; break; case GL_RGBA4: info->texture_format = GL_RGBA; info->pixel_type = GL_UNSIGNED_SHORT_4_4_4_4; break; case GL_RGB5_A1: info->texture_format = GL_RGBA; info->pixel_type = GL_UNSIGNED_SHORT_5_5_5_1; break; default: info->texture_format = GL_RGBA; info->pixel_type = GL_UNSIGNED_BYTE; break; } } mupen64plus-core/src/si/rumblepak.c000664 001750 001750 00000004316 12655644434 020403 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - rumblepak.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "rumblepak.h" #include void rumblepak_rumble(struct rumblepak* rpk, enum rumble_action action) { rpk->rumble(rpk->user_data, action); } void rumblepak_read_command(struct rumblepak* rpk, uint8_t* cmd) { uint8_t data; uint16_t address = (cmd[3] << 8) | (cmd[4] & 0xe0); if ((address >= 0x8000) && (address < 0x9000)) data = 0x80; else data = 0x00; memset(&cmd[5], data, 0x20); } void rumblepak_write_command(struct rumblepak* rpk, uint8_t* cmd) { uint16_t address = (cmd[3] << 8) | (cmd[4] & 0xe0); if (address == 0xc000) { enum rumble_action action = (cmd[5] == 0) ? RUMBLE_STOP : RUMBLE_START; rumblepak_rumble(rpk, action); } } mupen64plus-core/tools/build_bundle_bin.sh000755 001750 001750 00000006123 12655644434 022026 0ustar00sergiosergio000000 000000 #!/bin/sh #/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # * Mupen64plus - build_bundle_bin.sh * # * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * # * Copyright (C) 2009-2013 Richard Goedeken * # * * # * This program is free software; you can redistribute it and/or modify * # * it under the terms of the GNU General Public License as published by * # * the Free Software Foundation; either version 2 of the License, or * # * (at your option) any later version. * # * * # * This program is distributed in the hope that it will be useful, * # * but WITHOUT ANY WARRANTY; without even the implied warranty of * # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * # * GNU General Public License for more details. * # * * # * You should have received a copy of the GNU General Public License * # * along with this program; if not, write to the * # * Free Software Foundation, Inc., * # * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ # terminate the script if any commands return a non-zero error code set -e if [ $# -lt 2 ]; then echo "Usage: build_bundle_bin.sh [ ...]" exit 1 fi TEMPDIR="mupen64plus-temp-build" rm -rf ${TEMPDIR} mkdir -p ${TEMPDIR}/source cd ${TEMPDIR}/source echo "************************************ Downloading Mupen64Plus module source code" hg clone -r $1 http://bitbucket.org/richard42/mupen64plus-core hg clone -r $1 http://bitbucket.org/richard42/mupen64plus-rom hg clone -r $1 http://bitbucket.org/richard42/mupen64plus-ui-console hg clone -r $1 http://bitbucket.org/richard42/mupen64plus-audio-sdl hg clone -r $1 http://bitbucket.org/richard42/mupen64plus-input-sdl hg clone -r $1 http://bitbucket.org/richard42/mupen64plus-rsp-hle hg clone -r $1 http://bitbucket.org/richard42/mupen64plus-video-rice hg clone -r $1 http://bitbucket.org/richard42/mupen64plus-video-glide64mk2 shift for dirname in ./mupen64plus-*; do rm -rf ${dirname}/.hg*; done OUTPUTDIR="mupen64plus-bundle-$1" shift echo "************************************ Building Mupen64Plus modules" cd .. tar xzvf source/mupen64plus-core/tools/m64p_helper_scripts.tar.gz ./m64p_build.sh $@ mv "test" "${OUTPUTDIR}" echo "************************************ Creating archive" cp source/mupen64plus-core/tools/install_binary_bundle.sh "${OUTPUTDIR}/install.sh" cp source/mupen64plus-core/tools/uninstall_binary_bundle.sh "${OUTPUTDIR}/uninstall.sh" tar c "${OUTPUTDIR}" --owner 0 --group 0 --numeric-owner | gzip -n > "../${OUTPUTDIR}.tar.gz" cd .. rm -rf "${TEMPDIR}" mupen64plus-video-gliden64/licenses/Glow/000700 001750 001750 00000000000 12656647145 021343 5ustar00sergiosergio000000 000000 libretro/SDL_config.h000664 001750 001750 00000000000 12655644434 015647 0ustar00sergiosergio000000 000000 mupen64plus-video-gliden64/src/ZilmarGFX_1_3.h000664 001750 001750 00000024616 12655644434 022055 0ustar00sergiosergio000000 000000 /********************************************************************************** Common gfx plugin spec, version #1.3 maintained by zilmar (zilmar@emulation64.com) All questions or suggestions should go through the mailing list. http://www.egroups.com/group/Plugin64-Dev *********************************************************************************** Notes: ------ Setting the approprate bits in the MI_INTR_REG and calling CheckInterrupts which are both passed to the DLL in InitiateGFX will generate an Interrupt from with in the plugin. The Setting of the RSP flags and generating an SP interrupt should not be done in the plugin **********************************************************************************/ #ifndef _GFX_H_INCLUDED__ #define _GFX_H_INCLUDED__ #if defined(__cplusplus) extern "C" { #endif /* Plugin types */ #define PLUGIN_TYPE_GFX 2 #ifdef OS_WINDOWS #define EXPORT __declspec(dllexport) #define CALL __cdecl #else #define EXPORT __attribute__((visibility("default"))) #define CALL _cdecl #endif /***** Structures *****/ typedef struct { WORD Version; /* Set to 0x0103 */ WORD Type; /* Set to PLUGIN_TYPE_GFX */ char Name[100]; /* Name of the DLL */ /* If DLL supports memory these memory options then set them to TRUE or FALSE if it does not support it */ BOOL NormalMemory; /* a normal BYTE array */ BOOL MemoryBswaped; /* a normal BYTE array where the memory has been pre bswap on a dword (32 bits) boundry */ } PLUGIN_INFO; typedef struct { HWND hWnd; /* Render window */ HWND hStatusBar; /* if render window does not have a status bar then this is NULL */ BOOL MemoryBswaped; // If this is set to TRUE, then the memory has been pre // bswap on a dword (32 bits) boundry // eg. the first 8 bytes are stored like this: // 4 3 2 1 8 7 6 5 unsigned char * HEADER; /* This is the rom header (first 40h bytes of the rom) */ unsigned char * RDRAM; unsigned char * DMEM; unsigned char * IMEM; unsigned int * MI_INTR_REG; unsigned int * DPC_START_REG; unsigned int * DPC_END_REG; unsigned int * DPC_CURRENT_REG; unsigned int * DPC_STATUS_REG; unsigned int * DPC_CLOCK_REG; unsigned int * DPC_BUFBUSY_REG; unsigned int * DPC_PIPEBUSY_REG; unsigned int * DPC_TMEM_REG; unsigned int * VI_STATUS_REG; unsigned int * VI_ORIGIN_REG; unsigned int * VI_WIDTH_REG; unsigned int * VI_INTR_REG; unsigned int * VI_V_CURRENT_LINE_REG; unsigned int * VI_TIMING_REG; unsigned int * VI_V_SYNC_REG; unsigned int * VI_H_SYNC_REG; unsigned int * VI_LEAP_REG; unsigned int * VI_H_START_REG; unsigned int * VI_V_START_REG; unsigned int * VI_V_BURST_REG; unsigned int * VI_X_SCALE_REG; unsigned int * VI_Y_SCALE_REG; void (*CheckInterrupts)( void ); } GFX_INFO; /****************************************************************** Function: CaptureScreen Purpose: This function dumps the current frame to a file input: pointer to the directory to save the file to output: none *******************************************************************/ EXPORT void CALL CaptureScreen ( char * Directory ); /****************************************************************** Function: ChangeWindow Purpose: to change the window between fullscreen and window mode. If the window was in fullscreen this should change the screen to window mode and vice vesa. input: none output: none *******************************************************************/ EXPORT void CALL ChangeWindow (void); /****************************************************************** Function: CloseDLL Purpose: This function is called when the emulator is closing down allowing the dll to de-initialise. input: none output: none *******************************************************************/ EXPORT void CALL CloseDLL (void); /****************************************************************** Function: DllAbout Purpose: This function is optional function that is provided to give further information about the DLL. input: a handle to the window that calls this function output: none *******************************************************************/ EXPORT void CALL DllAbout ( HWND hParent ); /****************************************************************** Function: DllConfig Purpose: This function is optional function that is provided to allow the user to configure the dll input: a handle to the window that calls this function output: none *******************************************************************/ EXPORT void CALL DllConfig ( HWND hParent ); /****************************************************************** Function: DllTest Purpose: This function is optional function that is provided to allow the user to test the dll input: a handle to the window that calls this function output: none *******************************************************************/ EXPORT void CALL DllTest ( HWND hParent ); /****************************************************************** Function: DrawScreen Purpose: This function is called when the emulator receives a WM_PAINT message. This allows the gfx to fit in when it is being used in the desktop. input: none output: none *******************************************************************/ EXPORT void CALL DrawScreen (void); /****************************************************************** Function: GetDllInfo Purpose: This function allows the emulator to gather information about the dll by filling in the PluginInfo structure. input: a pointer to a PLUGIN_INFO stucture that needs to be filled by the function. (see def above) output: none *******************************************************************/ EXPORT void CALL GetDllInfo ( PLUGIN_INFO * PluginInfo ); /****************************************************************** Function: InitiateGFX Purpose: This function is called when the DLL is started to give information from the emulator that the n64 graphics uses. This is not called from the emulation thread. Input: Gfx_Info is passed to this function which is defined above. Output: TRUE on success FALSE on failure to initialise ** note on interrupts **: To generate an interrupt set the appropriate bit in MI_INTR_REG and then call the function CheckInterrupts to tell the emulator that there is a waiting interrupt. *******************************************************************/ EXPORT BOOL CALL InitiateGFX (GFX_INFO Gfx_Info); /****************************************************************** Function: MoveScreen Purpose: This function is called in response to the emulator receiving a WM_MOVE passing the xpos and ypos passed from that message. input: xpos - the x-coordinate of the upper-left corner of the client area of the window. ypos - y-coordinate of the upper-left corner of the client area of the window. output: none *******************************************************************/ EXPORT void CALL MoveScreen (int xpos, int ypos); /****************************************************************** Function: ProcessDList Purpose: This function is called when there is a Dlist to be processed. (High level GFX list) input: none output: none *******************************************************************/ EXPORT void CALL ProcessDList(void); /****************************************************************** Function: ProcessRDPList Purpose: This function is called when there is a Dlist to be processed. (Low level GFX list) input: none output: none *******************************************************************/ EXPORT void CALL ProcessRDPList(void); /****************************************************************** Function: RomClosed Purpose: This function is called when a rom is closed. input: none output: none *******************************************************************/ EXPORT void CALL RomClosed (void); /****************************************************************** Function: RomOpen Purpose: This function is called when a rom is open. (from the emulation thread) input: none output: none *******************************************************************/ EXPORT void CALL RomOpen (void); /****************************************************************** Function: ShowCFB Purpose: Useally once Dlists are started being displayed, cfb is ignored. This function tells the dll to start displaying them again. input: none output: none *******************************************************************/ EXPORT void CALL ShowCFB (void); /****************************************************************** Function: UpdateScreen Purpose: This function is called in response to a vsync of the screen were the VI bit in MI_INTR_REG has already been set input: none output: none *******************************************************************/ EXPORT void CALL UpdateScreen (void); /****************************************************************** Function: ViStatusChanged Purpose: This function is called to notify the dll that the ViStatus registers value has been changed. input: none output: none *******************************************************************/ EXPORT void CALL ViStatusChanged (void); /****************************************************************** Function: ViWidthChanged Purpose: This function is called to notify the dll that the ViWidth registers value has been changed. input: none output: none *******************************************************************/ EXPORT void CALL ViWidthChanged (void); /****************************************************************** Function: ReadScreen Purpose: Capture the current screen Input: none Output: dest - 24-bit RGB data (flipped horizontally) width - width of image height - height of image ******************************************************************/ EXPORT void CALL ReadScreen (void **dest, long *width, long *height); #if defined(__cplusplus) } #endif #endif mupen64plus-core/src/r4300/cp1_private.h000664 001750 001750 00000000470 12655644434 020775 0ustar00sergiosergio000000 000000 #ifndef M64P_R4300_CP1_PRIVATE_H #define M64P_R4300_CP1_PRIVATE_H #include "cp1.h" #include extern float *reg_cop1_simple[32]; extern double *reg_cop1_double[32]; extern uint32_t FCR0, FCR31; extern int64_t reg_cop1_fgr_64[32]; extern uint32_t rounding_mode; #endif /* M64P_R4300_CP1_PRIVATE_H */ mupen64plus-rsp-hle/src/hle_memory.c000664 001750 001750 00000004223 12655644434 020565 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-rsp-hle - memory.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include "memory.h" /* Global functions */ void load_u8(uint8_t* dst, const unsigned char* buffer, unsigned address, size_t count) { while (count) { *(dst++) = *u8(buffer, address); address += 1; --count; } } void load_u16(uint16_t* dst, const unsigned char* buffer, unsigned address, size_t count) { while (count) { *(dst++) = *u16(buffer, address); address += 2; --count; } } void store_u16(unsigned char* buffer, unsigned address, const uint16_t* src, size_t count) { while (count) { *u16(buffer, address) = *(src++); address += 2; --count; } } glide2gl/src/Glide64/glide64_gDP.h000664 001750 001750 00000006510 12655644434 017540 0ustar00sergiosergio000000 000000 #include "Util.h" #include #include "TexLoad.h" //forward decls extern void RestoreScale(void); extern uint32_t ucode5_texshiftaddr; extern uint32_t ucode5_texshiftcount; extern uint16_t ucode5_texshift; extern int CI_SET; extern uint32_t swapped_addr; static void gDPSetScissor_G64( uint32_t mode, float ulx, float uly, float lrx, float lry ) { g_gdp.__clip.xh = (uint32_t)ulx; g_gdp.__clip.yh = (uint32_t)ulx; g_gdp.__clip.xl = (uint32_t)lrx; g_gdp.__clip.yl = (uint32_t)lry; if (rdp.ci_count) { COLOR_IMAGE *cur_fb = (COLOR_IMAGE*)&rdp.frame_buffers[rdp.ci_count-1]; if (g_gdp.__clip.xl - g_gdp.__clip.xh > (uint32_t)(cur_fb->width >> 1)) { if (cur_fb->height == 0 || (cur_fb->width >= g_gdp.__clip.xl - 1 && cur_fb->width <= g_gdp.__clip.xl + 1)) cur_fb->height = g_gdp.__clip.yl; } } } /* * Loads a texture from DRAM into texture memory (TMEM). * The texture image is loaded into memory in a single transfer. * * tile - Tile descriptor index 93-bit precision, 0~7). * ul_s - texture tile's upper-left s coordinate (10.2, 0.0~1023.75) * ul_t - texture tile's upper-left t coordinate (10.2, 0.0~1023.75) * lr_s - texture tile's lower-right s coordinate (10.2, 0.0~1023.75) * dxt - amount of change in value of t per scan line (12-bit precision, 0~4095) */ static void gDPLoadBlock( uint32_t tile, uint32_t ul_s, uint32_t ul_t, uint32_t lr_s, uint32_t dxt ) { uint32_t _dxt, addr, off, cnt; uint8_t *dst; if (rdp.skip_drawing) return; if (ucode5_texshiftaddr) { if (ucode5_texshift % ((lr_s+1)<<3)) { g_gdp.ti_address -= ucode5_texshift; ucode5_texshiftaddr = 0; ucode5_texshift = 0; ucode5_texshiftcount = 0; } else ucode5_texshiftcount++; } rdp.addr[g_gdp.tile[tile].tmem] = g_gdp.ti_address; // ** DXT is used for swapping every other line /* double fdxt = (double)0x8000000F/(double)((uint32_t)(2047/(dxt-1))); // F for error uint32_t _dxt = (uint32_t)fdxt;*/ // 0x00000800 -> 0x80000000 (so we can check the sign bit instead of the 11th bit) _dxt = dxt << 20; addr = RSP_SegmentToPhysical(g_gdp.ti_address); g_gdp.tile[tile].sh = ul_s; g_gdp.tile[tile].th = ul_t; g_gdp.tile[tile].sl = lr_s; rdp.timg.set_by = 0; // load block // do a quick boundary check before copying to eliminate the possibility for exception if (ul_s >= 512) { lr_s = 1; // 1 so that it doesn't die on memcpy ul_s = 511; } if (ul_s+lr_s > 512) lr_s = 512-ul_s; if (addr+(lr_s<<3) > BMASK+1) lr_s = (uint16_t)((BMASK-addr)>>3); //angrylion's advice to use ul_s in texture image offset and cnt calculations. //Helps to fix Vigilante 8 jpeg backgrounds and logos off = g_gdp.ti_address + (ul_s << g_gdp.tile[tile].size >> 1); dst = ((uint8_t*)g_gdp.tmem) + (g_gdp.tile[tile].tmem<<3); cnt = lr_s-ul_s+1; if (g_gdp.tile[tile].size == 3) cnt <<= 1; if (g_gdp.ti_size == G_IM_SIZ_32b) LoadBlock32b(tile, ul_s, ul_t, lr_s, dxt); else loadBlock((uint32_t *)gfx_info.RDRAM, (uint32_t *)dst, off, _dxt, cnt); g_gdp.ti_address += cnt << 3; g_gdp.tile[tile].tl = ul_t + ((dxt*cnt)>>11); g_gdp.flags |= UPDATE_TEXTURE; #ifdef HAVE_HWFBE if (fb_hwfbe_enabled) setTBufTex(rdp.tiles[tile].t_mem, cnt); #endif } gles2n64/src/OpenGL.h000664 001750 001750 00000006656 12655644434 015364 0ustar00sergiosergio000000 000000 #ifndef OPENGL_H #define OPENGL_H #ifdef __cplusplus extern "C" { #endif #include "boolean.h" #include #include "gSP.h" #define RS_NONE 0 #define RS_TRIANGLE 1 #define RS_RECT 2 #define RS_TEXTUREDRECT 3 #define RS_LINE 4 #define SCREEN_UPDATE_AT_VI_UPDATE 1 #define SCREEN_UPDATE_AT_VI_CHANGE 2 #define SCREEN_UPDATE_AT_CI_CHANGE 3 #define SCREEN_UPDATE_AT_1ST_CI_CHANGE 4 #define SCREEN_UPDATE_BEFORE_SCREEN_CLEAR 6 #define SCREEN_UPDATE_AT_VI_UPDATE_AND_DRAWN 7 #define BLEND_NOOP 0x0000 #define BLEND_NOOP5 0xcc48 // Fog * 0 + Mem * 1 #define BLEND_NOOP4 0xcc08 // Fog * 0 + In * 1 #define BLEND_FOG_ASHADE 0xc800 #define BLEND_FOG_3 0xc000 // Fog * AIn + In * 1-A #define BLEND_FOG_MEM 0xc440 // Fog * AFog + Mem * 1-A #define BLEND_FOG_APRIM 0xc400 // Fog * AFog + In * 1-A #define BLEND_BLENDCOLOR 0x8c88 #define BLEND_BI_AFOG 0x8400 // Bl * AFog + In * 1-A #define BLEND_BI_AIN 0x8040 // Bl * AIn + Mem * 1-A #define BLEND_MEM 0x4c40 // Mem*0 + Mem*(1-0)?! #define BLEND_FOG_MEM_3 0x44c0 // Mem * AFog + Fog * 1-A #define BLEND_NOOP3 0x0c48 // In * 0 + Mem * 1 #define BLEND_PASS 0x0c08 // In * 0 + In * 1 #define BLEND_FOG_MEM_IN_MEM 0x0440 // In * AFog + Mem * 1-A #define BLEND_FOG_MEM_FOG_MEM 0x04c0 // In * AFog + Fog * 1-A #define BLEND_OPA 0x0044 // In * AIn + Mem * AMem #define BLEND_XLU 0x0040 #define BLEND_MEM_ALPHA_IN 0x4044 // Mem * AIn + Mem * AMem #define INDEXMAP_SIZE 64 #define VERTBUFF_SIZE 256 #define ELEMBUFF_SIZE 1024 typedef struct { float x, y, z, w; struct { float r, g, b, a; } color, secondaryColor; float s0, t0, s1, t1; } GLVertex; typedef struct triangles_t { SPVertex vertices[VERTBUFF_SIZE]; GLubyte elements[ELEMBUFF_SIZE]; int num; } triangles_t; typedef struct { bool screenUpdate; int frame_dl; int frame_prevdl; int mustRenderDlist; int renderingToTexture; uint32_t heightOffset; float scaleX, scaleY; struct triangles_t triangles; unsigned int renderState; GLVertex rect[4]; } GLInfo; struct TexturedRectParams { float ulx, uly, lrx, lry; float uls, ult, lrs, lrt; bool flip; }; extern GLInfo OGL; bool OGL_Start(); void OGL_Stop(); void OGL_AddTriangle(int v0, int v1, int v2); void OGL_DrawTriangles(void); void OGL_DrawDMATriangles(u32 _numVtx); void OGL_DrawTriangle(SPVertex *vertices, int v0, int v1, int v2); void OGL_DrawLLETriangle(u32 _numVtx); void OGL_DrawLine(int v0, int v1, float width); void OGL_DrawRect(int ulx, int uly, int lrx, int lry, float *color); void OGL_DrawTexturedRect(const struct TexturedRectParams *_params); void OGL_UpdateFrameTime(); void OGL_UpdateScale(); void OGL_ClearDepthBuffer(bool _fullsize); void OGL_ClearColorBuffer(float *color); void OGL_ResizeWindow(int x, int y, int width, int height); void OGL_SwapBuffers(); void OGL_ReadScreen( void *dest, int *width, int *height ); int OGL_CheckError(); int OGL_IsExtSupported( const char *extension ); float OGL_GetScaleX(void); float OGL_GetScaleY(void); uint32_t OGL_GetHeightOffset(void); uint32_t OGL_GetScreenWidth(void); uint32_t OGL_GetScreenHeight(void); #ifdef __cplusplus } #endif #endif mupen64plus-core/src/r4300/tlb.h000664 001750 001750 00000004416 12655644434 017345 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - tlb.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef TLB_H #define TLB_H #include typedef struct _tlb { int16_t mask; int32_t vpn2; int8_t g; uint8_t asid; int32_t pfn_even; int8_t c_even; int8_t d_even; int8_t v_even; int32_t pfn_odd; int8_t c_odd; int8_t d_odd; int8_t v_odd; int8_t r; //int32_t check_parity_mask; uint32_t start_even; uint32_t end_even; uint32_t phys_even; uint32_t start_odd; uint32_t end_odd; uint32_t phys_odd; } tlb; #define TLB_READ 0 #define TLB_WRITE 1 #define TLB_FAST_READ 2 extern tlb tlb_e[32]; extern uint32_t tlb_LUT_r[0x100000]; extern uint32_t tlb_LUT_w[0x100000]; void tlb_unmap(tlb *entry); void tlb_map(tlb *entry); uint32_t virtual_to_physical_address(uint32_t addresse, int w); #endif gles2n64/src/OpenGL.c000664 001750 001750 00000106210 12655644434 015342 0ustar00sergiosergio000000 000000 #include #include #include #include #include #ifdef _WIN32 #include #else #include #endif #include #include "Common.h" #include "gles2N64.h" #include "OpenGL.h" #include "Types.h" #include "N64.h" #include "gSP.h" #include "gDP.h" #include "Textures.h" #include "FrameBuffer.h" #include "ShaderCombiner.h" #include "VI.h" #include "RSP.h" #include "Config.h" GLInfo OGL; static bool m_bFlatColors; int OGL_IsExtSupported( const char *extension ) { const GLubyte *extensions = NULL; const GLubyte *start; GLubyte *where, *terminator; where = (GLubyte *) strchr(extension, ' '); if (where || *extension == '\0') return 0; extensions = glGetString(GL_EXTENSIONS); if (!extensions) return 0; start = extensions; for (;;) { where = (GLubyte *) strstr((const char *) start, extension); if (!where) break; terminator = where + strlen(extension); if (where == start || *(where - 1) == ' ') if (*terminator == ' ' || *terminator == '\0') return 1; start = terminator; } return 0; } static void _initStates(void) { glDisable( GL_CULL_FACE ); glEnableVertexAttribArray( SC_POSITION ); glEnable( GL_DEPTH_TEST ); glDepthFunc( GL_ALWAYS ); glDepthMask( GL_FALSE ); glEnable( GL_SCISSOR_TEST ); glDepthRange(0.0f, 1.0f); glPolygonOffset(-0.2f, -0.2f); glViewport(0, OGL_GetHeightOffset(), OGL_GetScreenWidth(), OGL_GetScreenHeight()); glClearColor( 0.0f, 0.0f, 0.0f, 0.0f); glClear( GL_COLOR_BUFFER_BIT); srand( time(NULL) ); } void OGL_UpdateScale(void) { if (VI.width == 0 || VI.height == 0) return; OGL.scaleX = OGL_GetScreenWidth() / (float)VI.width; OGL.scaleY = OGL_GetScreenHeight() / (float)VI.height; } uint32_t OGL_GetScreenWidth(void) { return config.screen.width; } uint32_t OGL_GetScreenHeight(void) { return config.screen.height; } float OGL_GetScaleX(void) { return OGL.scaleX; } float OGL_GetScaleY(void) { return OGL.scaleY; } uint32_t OGL_GetHeightOffset(void) { return OGL.heightOffset; } void OGL_Stop(void) { LOG(LOG_MINIMAL, "Stopping OpenGL\n"); Combiner_Destroy(); TextureCache_Destroy(); } static void _updateCullFace(void) { if (gSP.geometryMode & G_CULL_BOTH) { glEnable( GL_CULL_FACE ); if (gSP.geometryMode & G_CULL_BACK) glCullFace(GL_BACK); else glCullFace(GL_FRONT); } else glDisable(GL_CULL_FACE); } /* TODO/FIXME - not complete yet */ static void _updateViewport(void) { const u32 VI_height = VI.height; const f32 scaleX = OGL_GetScaleX(); const f32 scaleY = OGL_GetScaleY(); float Xf = gSP.viewport.vscale[0] < 0 ? (gSP.viewport.x + gSP.viewport.vscale[0] * 2.0f) : gSP.viewport.x; const GLint X = (GLint)(Xf * scaleX); const GLint Y = gSP.viewport.vscale[1] < 0 ? (GLint)((gSP.viewport.y + gSP.viewport.vscale[1] * 2.0f) * scaleY) : (GLint)((VI_height - (gSP.viewport.y + gSP.viewport.height)) * scaleY); glViewport(X, Y + OGL_GetHeightOffset(), max((GLint)(gSP.viewport.width * scaleX), 0), max((GLint)(gSP.viewport.height * scaleY), 0)); gSP.changed &= ~CHANGED_VIEWPORT; } static void _updateDepthUpdate(void) { if (gDP.otherMode.depthUpdate) glDepthMask(GL_TRUE); else glDepthMask(GL_FALSE); } static void _updateScissor(struct FrameBuffer *_pBuffer) { u32 heightOffset, screenHeight; f32 scaleX, scaleY; float SX0 = gDP.scissor.ulx; float SX1 = gDP.scissor.lrx; if (_pBuffer == NULL) { scaleX = OGL_GetScaleX(); scaleY = OGL_GetScaleY(); heightOffset = OGL_GetHeightOffset(); screenHeight = VI.height; } else { scaleX = _pBuffer->m_scaleX; scaleY = _pBuffer->m_scaleY; heightOffset = 0; screenHeight = (_pBuffer->m_height == 0) ? VI.height : _pBuffer->m_height; } #if 0 if (ogl.isAdjustScreen() && gSP.viewport.width < gDP.colorImage.width && gDP.colorImage.width > VI.width * 98 / 100) _adjustScissorX(SX0, SX1, ogl.getAdjustScale()); #endif glScissor( (GLint)(SX0 * scaleX), (GLint)((screenHeight - gDP.scissor.lry) * scaleY + heightOffset), max((GLint)((SX1 - gDP.scissor.ulx) * scaleX), 0), max((GLint)((gDP.scissor.lry - gDP.scissor.uly) * scaleY), 0) ); gDP.changed &= ~CHANGED_SCISSOR; } static void _setBlendMode(void) { const u32 blendmode = gDP.otherMode.l >> 16; // 0x7000 = CVG_X_ALPHA|ALPHA_CVG_SEL|FORCE_BL if (gDP.otherMode.alphaCvgSel != 0 && (gDP.otherMode.l & 0x7000) != 0x7000) { switch (blendmode) { case 0x4055: // Mario Golf case 0x5055: // Paper Mario intro clr_mem * a_in + clr_mem * a_mem glEnable(GL_BLEND); glBlendFunc(GL_ZERO, GL_ONE); break; default: glDisable(GL_BLEND); } return; } if (gDP.otherMode.forceBlender != 0 && gDP.otherMode.cycleType < G_CYC_COPY) { glEnable( GL_BLEND ); switch (blendmode) { // Mace objects case 0x0382: // Mace special blend mode, see GLSLCombiner.cpp case 0x0091: // 1080 Sky case 0x0C08: // Used LOTS of places case 0x0F0A: //DK64 blue prints case 0x0302: // Bomberman 2 special blend mode, see GLSLCombiner.cpp case 0xA500: //Sin and Punishment case 0xCB02: // Battlezone // clr_in * a + clr_in * (1-a) case 0xC800: // Conker BFD // clr_in * a_fog + clr_fog * (1-a) // clr_in * 0 + clr_in * 1 case 0x07C2: case 0x00C0: //ISS64 case 0xC302: // Donald Duck case 0xC702: glBlendFunc(GL_ONE, GL_ZERO); break; case 0x0F1A: if (gDP.otherMode.cycleType == G_CYC_1CYCLE) glBlendFunc(GL_ONE, GL_ZERO); else glBlendFunc(GL_ZERO, GL_ONE); break; //Space Invaders case 0x0448: // Add case 0x055A: glBlendFunc( GL_ONE, GL_ONE ); break; case 0xc712: // Pokemon Stadium? case 0xAF50: // LOT in Zelda: MM case 0x0F5A: // LOT in Zelda: MM case 0x0FA5: // Seems to be doing just blend color - maybe combiner can be used for this? case 0x5055: // Used in Paper Mario intro, I'm not sure if this is right... //clr_in * 0 + clr_mem * 1 glBlendFunc( GL_ZERO, GL_ONE ); break; case 0x5F50: //clr_mem * 0 + clr_mem * (1-a) glBlendFunc( GL_ZERO, GL_ONE_MINUS_SRC_ALPHA ); break; case 0xF550: //clr_fog * a_fog + clr_mem * (1-a) case 0x0150: // spiderman case 0x0550: // bomberman 64 case 0x0D18: //clr_in * a_fog + clr_mem * (1-a) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); break; case 0xC912: //40 winks, clr_in * a_fog + clr_mem * 1 glBlendFunc(GL_SRC_ALPHA, GL_ONE); break; case 0x0040: // Fzero case 0xC810: // Blends fog case 0xC811: // Blends fog case 0x0C18: // Standard interpolated blend case 0x0C19: // Used for antialiasing case 0x0050: // Standard interpolated blend case 0x0051: // Standard interpolated blend case 0x0055: // Used for antialiasing glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); break; case 0x5000: // V8 explosions glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA); break; default: LOG(LOG_VERBOSE, "Unhandled blend mode=%x", gDP.otherMode.l >> 16); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); break; } } else if ((config.generalEmulation.hacks & hack_pilotWings) != 0 && (gDP.otherMode.l & 0x80) != 0) { //CLR_ON_CVG without FORCE_BL glEnable(GL_BLEND); glBlendFunc(GL_ZERO, GL_ONE); } /* TODO/FIXME: update */ else if ((config.generalEmulation.hacks & hack_blastCorps) != 0 && gSP.texture.on == 0 /* && currentCombiner()->usesTex() */) { // Blast Corps glEnable(GL_BLEND); glBlendFunc(GL_ZERO, GL_ONE); } else { glDisable( GL_BLEND ); } } static void _updateStates(void) { if (gDP.otherMode.cycleType == G_CYC_COPY) Combiner_Set(EncodeCombineMode(0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0), -1); else if (gDP.otherMode.cycleType == G_CYC_FILL) Combiner_Set(EncodeCombineMode(0, 0, 0, SHADE, 0, 0, 0, 1, 0, 0, 0, SHADE, 0, 0, 0, 1), -1); else Combiner_Set(gDP.combine.mux, -1); if (gSP.changed & CHANGED_GEOMETRYMODE) { _updateCullFace(); gSP.changed &= ~CHANGED_GEOMETRYMODE; } if (gDP.changed & CHANGED_RENDERMODE || gDP.changed & CHANGED_CYCLETYPE) { if (((gSP.geometryMode & G_ZBUFFER) || gDP.otherMode.depthSource == G_ZS_PRIM) && gDP.otherMode.cycleType <= G_CYC_2CYCLE) { if (gDP.otherMode.depthCompare != 0) { switch (gDP.otherMode.depthMode) { case ZMODE_OPA: glDisable(GL_POLYGON_OFFSET_FILL); glDepthFunc(GL_LEQUAL); break; case ZMODE_INTER: glDisable(GL_POLYGON_OFFSET_FILL); glDepthFunc(GL_LEQUAL); break; case ZMODE_XLU: // Max || Infront; glDisable(GL_POLYGON_OFFSET_FILL); if (gDP.otherMode.depthSource == G_ZS_PRIM && gDP.primDepth.z == 1.0f) // Max glDepthFunc(GL_LEQUAL); else // Infront glDepthFunc(GL_LESS); break; case ZMODE_DEC: glEnable(GL_POLYGON_OFFSET_FILL); glDepthFunc(GL_LEQUAL); break; } } else { glDisable(GL_POLYGON_OFFSET_FILL); glDepthFunc(GL_ALWAYS); } _updateDepthUpdate(); glEnable(GL_DEPTH_TEST); #ifdef NEW if (!GBI.isNoN()) glDisable(GL_DEPTH_CLAMP); #endif } else { glDisable(GL_DEPTH_TEST); #ifdef NEW if (!GBI.isNoN()) glEnable(GL_DEPTH_CLAMP); #endif } } if ((gDP.changed & CHANGED_RENDERMODE)) SC_SetUniform1f(uAlphaRef, (gDP.otherMode.cvgXAlpha) ? 0.5f : gDP.blendColor.a); if (gDP.changed & CHANGED_SCISSOR) _updateScissor(FrameBuffer_GetCurrent()); if (gSP.changed & CHANGED_VIEWPORT) _updateViewport(); if (gSP.changed & CHANGED_LIGHT) ShaderCombiner_UpdateLightParameters(); if (gSP.changed & CHANGED_FOGPOSITION) { SC_SetUniform1f(uFogScale, (float) gSP.fog.multiplier / 255.0f); SC_SetUniform1f(uFogOffset, (float) gSP.fog.offset / 255.0f); } if ((gSP.changed & CHANGED_TEXTURE) || (gDP.changed & CHANGED_TILE) || (gDP.changed & CHANGED_TMEM)) { //For some reason updating the texture cache on the first frame of LOZ:OOT causes a NULL Pointer exception... if (scProgramCurrent) { if (scProgramCurrent->usesT0) { TextureCache_Update(0); SC_ForceUniform2f(uTexOffset[0], gSP.textureTile[0]->fuls, gSP.textureTile[0]->fult); SC_ForceUniform2f(uCacheShiftScale[0], cache.current[0]->shiftScaleS, cache.current[0]->shiftScaleT); SC_ForceUniform2f(uCacheScale[0], cache.current[0]->scaleS, cache.current[0]->scaleT); SC_ForceUniform2f(uCacheOffset[0], cache.current[0]->offsetS, cache.current[0]->offsetT); } //else TextureCache_ActivateDummy(0); //Note: enabling dummies makes some F-zero X textures flicker.... strange. if (scProgramCurrent->usesT1) { TextureCache_Update(1); SC_ForceUniform2f(uTexOffset[1], gSP.textureTile[1]->fuls, gSP.textureTile[1]->fult); SC_ForceUniform2f(uCacheShiftScale[1], cache.current[1]->shiftScaleS, cache.current[1]->shiftScaleT); SC_ForceUniform2f(uCacheScale[1], cache.current[1]->scaleS, cache.current[1]->scaleT); SC_ForceUniform2f(uCacheOffset[1], cache.current[1]->offsetS, cache.current[1]->offsetT); } //else TextureCache_ActivateDummy(1); } } if ((gDP.changed & (CHANGED_RENDERMODE | CHANGED_CYCLETYPE))) { _setBlendMode(); gDP.changed &= ~(CHANGED_RENDERMODE | CHANGED_CYCLETYPE); } gDP.changed &= CHANGED_TILE | CHANGED_TMEM; gSP.changed &= CHANGED_TEXTURE | CHANGED_MATRIX; } void OGL_DrawTriangle(SPVertex *vertices, int v0, int v1, int v2) { } static void OGL_SetColorArray(void) { if (scProgramCurrent->usesCol) glEnableVertexAttribArray(SC_COLOR); else glDisableVertexAttribArray(SC_COLOR); } static void OGL_SetTexCoordArrays(void) { if (OGL.renderState == RS_TRIANGLE) { glDisableVertexAttribArray(SC_TEXCOORD1); if (scProgramCurrent->usesT0 || scProgramCurrent->usesT1) glEnableVertexAttribArray(SC_TEXCOORD0); else glDisableVertexAttribArray(SC_TEXCOORD0); } else { if (scProgramCurrent->usesT0) glEnableVertexAttribArray(SC_TEXCOORD0); else glDisableVertexAttribArray(SC_TEXCOORD0); if (scProgramCurrent->usesT1) glEnableVertexAttribArray(SC_TEXCOORD1); else glDisableVertexAttribArray(SC_TEXCOORD1); } } static void OGL_prepareDrawTriangle(bool _dma) { bool updateColorArrays, updateArrays; if (gSP.changed || gDP.changed) _updateStates(); updateArrays = OGL.renderState != RS_TRIANGLE; if (updateArrays || scProgramChanged) { OGL.renderState = RS_TRIANGLE; OGL_SetColorArray(); OGL_SetTexCoordArrays(); glDisableVertexAttribArray(SC_TEXCOORD1); SC_ForceUniform1f(uRenderState, RS_TRIANGLE); } updateColorArrays = m_bFlatColors != (!__RSP.bLLE && (gSP.geometryMode & G_SHADING_SMOOTH) == 0); if (updateColorArrays) m_bFlatColors = !m_bFlatColors; if (updateArrays) { SPVertex *pVtx = (SPVertex*)&OGL.triangles.vertices[0]; glVertexAttribPointer(SC_POSITION, 4, GL_FLOAT, GL_FALSE, sizeof(SPVertex), &pVtx->x); if (m_bFlatColors) glVertexAttribPointer(SC_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(SPVertex), &pVtx->flat_r); else glVertexAttribPointer(SC_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(SPVertex), &pVtx->r); glVertexAttribPointer(SC_TEXCOORD0, 2, GL_FLOAT, GL_FALSE, sizeof(SPVertex), &pVtx->s); } else if (updateColorArrays) { SPVertex *pVtx = (SPVertex*)&OGL.triangles.vertices[0]; if (m_bFlatColors) glVertexAttribPointer(SC_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(SPVertex), &pVtx->flat_r); else glVertexAttribPointer(SC_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(SPVertex), &pVtx->r); } } void OGL_DrawLLETriangle(u32 _numVtx) { struct FrameBuffer * pCurrentBuffer; float scaleX, scaleY; u32 i; if (_numVtx == 0) return; gSP.changed &= ~CHANGED_GEOMETRYMODE; // Don't update cull mode OGL_prepareDrawTriangle(false); glDisable(GL_CULL_FACE); pCurrentBuffer = FrameBuffer_GetCurrent(); if (pCurrentBuffer == NULL) { glViewport( 0, OGL_GetHeightOffset(), OGL_GetScreenWidth(), OGL_GetScreenHeight()); } else glViewport(0, 0, pCurrentBuffer->m_width * pCurrentBuffer->m_scaleX, pCurrentBuffer->m_height * pCurrentBuffer->m_scaleY); scaleX = pCurrentBuffer != NULL ? 1.0f / pCurrentBuffer->m_width : VI.rwidth; scaleY = pCurrentBuffer != NULL ? 1.0f / pCurrentBuffer->m_height : VI.rheight; for (i = 0; i < _numVtx; ++i) { SPVertex *vtx = (SPVertex*)&OGL.triangles.vertices[i]; vtx->HWLight = 0; vtx->x = vtx->x * (2.0f * scaleX) - 1.0f; vtx->x *= vtx->w; vtx->y = vtx->y * (-2.0f * scaleY) + 1.0f; vtx->y *= vtx->w; vtx->z *= vtx->w; if (gDP.otherMode.texturePersp == 0) { vtx->s *= 2.0f; vtx->t *= 2.0f; } } glDrawArrays(GL_TRIANGLE_STRIP, 0, _numVtx); OGL.triangles.num = 0; #if 0 frameBufferList().setBufferChanged(); #endif gSP.changed |= CHANGED_VIEWPORT | CHANGED_GEOMETRYMODE; } void OGL_AddTriangle(int v0, int v1, int v2) { u32 i; SPVertex *vtx = NULL; OGL.triangles.elements[OGL.triangles.num++] = v0; OGL.triangles.elements[OGL.triangles.num++] = v1; OGL.triangles.elements[OGL.triangles.num++] = v2; if ((gSP.geometryMode & G_SHADE) == 0) { /* Prim shading */ for (i = OGL.triangles.num - 3; i < OGL.triangles.num; ++i) { vtx = (SPVertex*)&OGL.triangles.vertices[OGL.triangles.elements[i]]; vtx->flat_r = gDP.primColor.r; vtx->flat_g = gDP.primColor.g; vtx->flat_b = gDP.primColor.b; vtx->flat_a = gDP.primColor.a; } } else if ((gSP.geometryMode & G_SHADING_SMOOTH) == 0) { /* Flat shading */ SPVertex *vtx0 = (SPVertex*)&OGL.triangles.vertices[v0]; for (i = OGL.triangles.num - 3; i < OGL.triangles.num; ++i) { vtx = (SPVertex*)&OGL.triangles.vertices[OGL.triangles.elements[i]]; vtx->flat_r = vtx0->r; vtx->flat_g = vtx0->g; vtx->flat_b = vtx0->b; vtx->flat_a = vtx0->a; } } if (gDP.otherMode.depthSource == G_ZS_PRIM) { for (i = OGL.triangles.num - 3; i < OGL.triangles.num; ++i) { vtx = (SPVertex*)&OGL.triangles.vertices[OGL.triangles.elements[i]]; vtx->z = gDP.primDepth.z * vtx->w; } } } void OGL_DrawDMATriangles(u32 _numVtx) { if (_numVtx == 0) return; OGL_prepareDrawTriangle(true); glDrawArrays(GL_TRIANGLES, 0, _numVtx); } void OGL_DrawTriangles(void) { if (OGL.triangles.num == 0) return; OGL_prepareDrawTriangle(false); glDrawElements(GL_TRIANGLES, OGL.triangles.num, GL_UNSIGNED_BYTE, OGL.triangles.elements); OGL.triangles.num = 0; } void OGL_DrawLine(int v0, int v1, float width ) { unsigned short elem[2]; if (gSP.changed || gDP.changed) _updateStates(); if (OGL.renderState != RS_LINE || scProgramChanged) { OGL_SetColorArray(); glDisableVertexAttribArray(SC_TEXCOORD0); glDisableVertexAttribArray(SC_TEXCOORD1); glVertexAttribPointer(SC_POSITION, 4, GL_FLOAT, GL_FALSE, sizeof(SPVertex), &OGL.triangles.vertices[0].x); glVertexAttribPointer(SC_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(SPVertex), &OGL.triangles.vertices[0].r); SC_ForceUniform1f(uRenderState, RS_LINE); _updateCullFace(); _updateViewport(); OGL.renderState = RS_LINE; } elem[0] = v0; elem[1] = v1; glLineWidth( width * OGL.scaleX ); glDrawElements(GL_LINES, 2, GL_UNSIGNED_SHORT, elem); } void OGL_DrawRect( int ulx, int uly, int lrx, int lry, float *color) { struct FrameBuffer *pCurrentBuffer; float scaleX, scaleY, Z, W; bool updateArrays; gSP.changed &= ~CHANGED_GEOMETRYMODE; // Don't update cull mode if (gSP.changed || gDP.changed) _updateStates(); updateArrays = OGL.renderState != RS_RECT; if (updateArrays || scProgramChanged) { glDisableVertexAttribArray(SC_COLOR); glDisableVertexAttribArray(SC_TEXCOORD0); glDisableVertexAttribArray(SC_TEXCOORD1); SC_ForceUniform1f(uRenderState, RS_RECT); } if (updateArrays) { glVertexAttrib4f(SC_POSITION, 0, 0, gSP.viewport.nearz, 1.0); glVertexAttribPointer(SC_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(GLVertex), &OGL.rect[0].x); OGL.renderState = RS_RECT; } pCurrentBuffer = FrameBuffer_GetCurrent(); if (pCurrentBuffer == NULL) glViewport(0, OGL_GetHeightOffset(), OGL_GetScreenWidth(), OGL_GetScreenHeight()); else glViewport(0, 0, pCurrentBuffer->m_width * pCurrentBuffer->m_scaleX, pCurrentBuffer->m_height * pCurrentBuffer->m_scaleY); glDisable(GL_CULL_FACE); scaleX = pCurrentBuffer != NULL ? 1.0f / pCurrentBuffer->m_width : VI.rwidth; scaleY = pCurrentBuffer != NULL ? 1.0f / pCurrentBuffer->m_height : VI.rheight; Z = (gDP.otherMode.depthSource == G_ZS_PRIM) ? gDP.primDepth.z : gSP.viewport.nearz; W = 1.0f; OGL.rect[0].x = (float)ulx * (2.0f * scaleX) - 1.0f; OGL.rect[0].y = (float)uly * (-2.0f * scaleY) + 1.0f; OGL.rect[0].z = Z; OGL.rect[0].w = W; OGL.rect[1].x = (float)lrx * (2.0f * scaleX) - 1.0f; OGL.rect[1].y = OGL.rect[0].y; OGL.rect[1].z = Z; OGL.rect[1].w = W; OGL.rect[2].x = OGL.rect[0].x; OGL.rect[2].y = (float)lry * (-2.0f * scaleY) + 1.0f; OGL.rect[2].z = Z; OGL.rect[2].w = W; OGL.rect[3].x = OGL.rect[1].x; OGL.rect[3].y = OGL.rect[2].y; OGL.rect[3].z = Z; OGL.rect[3].w = W; #if 0 if (ogl.isAdjustScreen() && (gDP.colorImage.width > VI.width * 98 / 100) && (_lrx - _ulx < VI.width * 9 / 10)) { const float scale = ogl.getAdjustScale(); for (u32 i = 0; i < 4; ++i) m_rect[i].x *= scale; } #endif if (gDP.otherMode.cycleType == G_CYC_FILL) glVertexAttrib4fv(SC_COLOR, color); else glVertexAttrib4f(SC_COLOR, 0.0f, 0.0f, 0.0f, 0.0f); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); gSP.changed |= CHANGED_GEOMETRYMODE | CHANGED_VIEWPORT; } static bool texturedRectShadowMap(const struct TexturedRectParams *a) { struct FrameBuffer *pCurrentBuffer = FrameBuffer_GetCurrent(); if (pCurrentBuffer != NULL) { if (gDP.textureImage.size == 2 && gDP.textureImage.address >= gDP.depthImageAddress && gDP.textureImage.address < (gDP.depthImageAddress + gDP.colorImage.width*gDP.colorImage.width * 6 / 4)) { #ifdef NEW pCurrentBuffer->m_pDepthBuffer->activateDepthBufferTexture(pCurrentBuffer); SetDepthFogCombiner(); #endif } } return false; } static bool texturedRectDepthBufferCopy(const struct TexturedRectParams *_params) { // Copy one line from depth buffer into auxiliary color buffer with height = 1. // Data from depth buffer loaded into TMEM and then rendered to RDRAM by texrect. // Works only with depth buffer emulation enabled. // Load of arbitrary data to that area causes weird camera rotation in CBFD. const gDPTile *pTile = (const gDPTile*)gSP.textureTile[0]; if (pTile->loadType == LOADTYPE_BLOCK && gDP.textureImage.size == 2 && gDP.textureImage.address >= gDP.depthImageAddress && gDP.textureImage.address < (gDP.depthImageAddress + gDP.colorImage.width*gDP.colorImage.width * 6 / 4)) { u32 x; struct FrameBuffer *pBuffer = FrameBuffer_GetCurrent(); if (config.frameBufferEmulation.enable == 0 || !pBuffer) return true; /* TODO/FIXMES */ #ifdef NEW pBuffer->m_cleared = true; #endif if (config.frameBufferEmulation.copyDepthToRDRAM == 0) return true; #ifdef NEW if (FrameBuffer_CopyDepthBuffer(gDP.colorImage.address)) RDP_RepeatLastLoadBlock(); #endif const u32 width = (u32)(_params->lrx - _params->ulx); const u32 ulx = (u32)_params->ulx; u16 * pSrc = ((u16*)TMEM) + (u32)floorf(_params->uls + 0.5f); u16 *pDst = (u16*)(gfx_info.RDRAM + gDP.colorImage.address); for (x = 0; x < width; ++x) pDst[(ulx + x) ^ 1] = swapword(pSrc[x]); return true; } return false; } static bool texturedRectCopyToItself(const struct TexturedRectParams * _params) { struct FrameBuffer *pCurrent = FrameBuffer_GetCurrent(); if (gSP.textureTile[0]->frameBuffer == pCurrent) return true; return texturedRectDepthBufferCopy(_params); } static bool texturedRectBGCopy(const struct TexturedRectParams *_params) { u8 *texaddr, *fbaddr; u32 y, width, tex_width, uly, lry; float flry; if (GBI_GetCurrentMicrocodeType() != S2DEX) return false; flry = _params->lry; if (flry > gDP.scissor.lry) flry = gDP.scissor.lry; width = (u32)(_params->lrx - _params->ulx); tex_width = gSP.textureTile[0]->line << 3; uly = (u32)_params->uly; lry = flry; texaddr = gfx_info.RDRAM + gDP.loadInfo[gSP.textureTile[0]->tmem].texAddress + tex_width*(u32)_params->ult + (u32)_params->uls; fbaddr = gfx_info.RDRAM + gDP.colorImage.address + (u32)_params->ulx; for (y = uly; y < lry; ++y) { u8 *src = texaddr + (y - uly) * tex_width; u8 *dst = fbaddr + y * gDP.colorImage.width; memcpy(dst, src, width); } FrameBuffer_RemoveBuffer(gDP.colorImage.address); return true; } static bool texturedRectPaletteMod(const struct TexturedRectParams *_params) { u32 i; if (gDP.scissor.lrx != 16 || gDP.scissor.lry != 1 || _params->lrx != 16 || _params->lry != 1) return false; u8 envr = (u8)(gDP.envColor.r * 31.0f); u8 envg = (u8)(gDP.envColor.g * 31.0f); u8 envb = (u8)(gDP.envColor.b * 31.0f); u16 env16 = (u16)((envr << 11) | (envg << 6) | (envb << 1) | 1); u8 prmr = (u8)(gDP.primColor.r * 31.0f); u8 prmg = (u8)(gDP.primColor.g * 31.0f); u8 prmb = (u8)(gDP.primColor.b * 31.0f); u16 prim16 = (u16)((prmr << 11) | (prmg << 6) | (prmb << 1) | 1); u16 * src = (u16*)&TMEM[256]; u16 * dst = (u16*)(gfx_info.RDRAM + gDP.colorImage.address); for (i = 0; i < 16; ++i) dst[i ^ 1] = (src[i<<2] & 0x100) ? prim16 : env16; return true; } static bool texturedRectMonochromeBackground(const struct TexturedRectParams * _params) { if (gDP.textureImage.address >= gDP.colorImage.address && gDP.textureImage.address <= (gDP.colorImage.address + gDP.colorImage.width*gDP.colorImage.height * 2)) { #ifdef GL_IMAGE_TEXTURES_SUPPORT FrameBuffer * pCurrentBuffer = frameBufferList().getCurrent(); if (pCurrentBuffer != NULL) { FrameBuffer_ActivateBufferTexture(0, pCurrentBuffer); SetMonochromeCombiner(); return false; } else #endif return true; } return false; } // Special processing of textured rect. // Return true if actuial rendering is not necessary bool(*texturedRectSpecial)(const struct TexturedRectParams * _params) = NULL; void OGL_DrawTexturedRect(const struct TexturedRectParams *_params) { struct FrameBuffer *pCurrentBuffer; float scaleX, scaleY, Z, W; bool updateArrays; if (gSP.changed || gDP.changed) _updateStates(); updateArrays = OGL.renderState != RS_TEXTUREDRECT; if (updateArrays || scProgramChanged) { OGL.renderState = RS_TEXTUREDRECT; glDisableVertexAttribArray(SC_COLOR); OGL_SetTexCoordArrays(); SC_ForceUniform1f(uRenderState, RS_TEXTUREDRECT); } if (updateArrays) { glVertexAttrib4f(SC_COLOR, 0, 0, 0, 0); glVertexAttribPointer(SC_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(GLVertex), &OGL.rect[0].x); glVertexAttribPointer(SC_TEXCOORD0, 2, GL_FLOAT, GL_FALSE, sizeof(GLVertex), &OGL.rect[0].s0); glVertexAttribPointer(SC_TEXCOORD1, 2, GL_FLOAT, GL_FALSE, sizeof(GLVertex), &OGL.rect[0].s1); } if (__RSP.cmd == 0xE4 && texturedRectSpecial != NULL && texturedRectSpecial(_params)) { gSP.changed |= CHANGED_GEOMETRYMODE; return; } pCurrentBuffer = FrameBuffer_GetCurrent(); if (pCurrentBuffer == NULL) glViewport(0, OGL_GetHeightOffset(), OGL_GetScreenWidth(), OGL_GetScreenHeight()); else glViewport(0, 0, pCurrentBuffer->m_width * pCurrentBuffer->m_scaleX, pCurrentBuffer->m_height * pCurrentBuffer->m_scaleY); glDisable(GL_CULL_FACE); scaleX = pCurrentBuffer != NULL ? 1.0f / pCurrentBuffer->m_width : VI.rwidth; scaleY = pCurrentBuffer != NULL ? 1.0f / pCurrentBuffer->m_height : VI.rheight; Z = (gDP.otherMode.depthSource == G_ZS_PRIM) ? gDP.primDepth.z : gSP.viewport.nearz; W = 1.0f; OGL.rect[0].x = (float) _params->ulx * (2.0f * scaleX) - 1.0f; OGL.rect[0].y = (float) _params->uly * (-2.0f * scaleY) + 1.0f; OGL.rect[0].z = Z; OGL.rect[0].w = W; OGL.rect[1].x = (float) (_params->lrx) * (2.0f * scaleX) - 1.0f; OGL.rect[1].y = OGL.rect[0].y; OGL.rect[1].z = Z; OGL.rect[1].w = W; OGL.rect[2].x = OGL.rect[0].x; OGL.rect[2].y = (float) (_params->lry) * (-2.0f * scaleY) + 1.0f; OGL.rect[2].z = Z; OGL.rect[2].w = W; OGL.rect[3].x = OGL.rect[1].x; OGL.rect[3].y = OGL.rect[2].y; OGL.rect[3].z = Z; OGL.rect[3].w = W; if (scProgramCurrent->usesT0 && cache.current[0] && gSP.textureTile[0]) { OGL.rect[0].s0 = _params->uls * cache.current[0]->shiftScaleS - gSP.textureTile[0]->fuls; OGL.rect[0].t0 = _params->ult * cache.current[0]->shiftScaleT - gSP.textureTile[0]->fult; OGL.rect[3].s0 = (_params->lrs + 1.0f) * cache.current[0]->shiftScaleS - gSP.textureTile[0]->fuls; OGL.rect[3].t0 = (_params->lrt + 1.0f) * cache.current[0]->shiftScaleT - gSP.textureTile[0]->fult; if ((cache.current[0]->maskS) && !(cache.current[0]->mirrorS) && (fmod( OGL.rect[0].s0, cache.current[0]->width ) == 0.0f)) { OGL.rect[3].s0 -= OGL.rect[0].s0; OGL.rect[0].s0 = 0.0f; } if ((cache.current[0]->maskT) && !(cache.current[0]->mirrorT) && (fmod( OGL.rect[0].t0, cache.current[0]->height ) == 0.0f)) { OGL.rect[3].t0 -= OGL.rect[0].t0; OGL.rect[0].t0 = 0.0f; } glActiveTexture( GL_TEXTURE0); if ((OGL.rect[0].s0 >= 0.0f) && (OGL.rect[3].s0 <= cache.current[0]->width)) glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); if ((OGL.rect[0].t0 >= 0.0f) && (OGL.rect[3].t0 <= cache.current[0]->height)) glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); OGL.rect[0].s0 *= cache.current[0]->scaleS; OGL.rect[0].t0 *= cache.current[0]->scaleT; OGL.rect[3].s0 *= cache.current[0]->scaleS; OGL.rect[3].t0 *= cache.current[0]->scaleT; } if (scProgramCurrent->usesT1 && cache.current[1] && gSP.textureTile[1]) { OGL.rect[0].s1 = _params->uls * cache.current[1]->shiftScaleS - gSP.textureTile[1]->fuls; OGL.rect[0].t1 = _params->ult * cache.current[1]->shiftScaleT - gSP.textureTile[1]->fult; OGL.rect[3].s1 = (_params->lrs + 1.0f) * cache.current[1]->shiftScaleS - gSP.textureTile[1]->fuls; OGL.rect[3].t1 = (_params->lrt + 1.0f) * cache.current[1]->shiftScaleT - gSP.textureTile[1]->fult; if ((cache.current[1]->maskS) && (fmod( OGL.rect[0].s1, cache.current[1]->width ) == 0.0f) && !(cache.current[1]->mirrorS)) { OGL.rect[3].s1 -= OGL.rect[0].s1; OGL.rect[0].s1 = 0.0f; } if ((cache.current[1]->maskT) && (fmod( OGL.rect[0].t1, cache.current[1]->height ) == 0.0f) && !(cache.current[1]->mirrorT)) { OGL.rect[3].t1 -= OGL.rect[0].t1; OGL.rect[0].t1 = 0.0f; } glActiveTexture( GL_TEXTURE1); if ((OGL.rect[0].s1 == 0.0f) && (OGL.rect[3].s1 <= cache.current[1]->width)) glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); if ((OGL.rect[0].t1 == 0.0f) && (OGL.rect[3].t1 <= cache.current[1]->height)) glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); OGL.rect[0].s1 *= cache.current[1]->scaleS; OGL.rect[0].t1 *= cache.current[1]->scaleT; OGL.rect[3].s1 *= cache.current[1]->scaleS; OGL.rect[3].t1 *= cache.current[1]->scaleT; } if (gDP.otherMode.cycleType == G_CYC_COPY) { glActiveTexture(GL_TEXTURE0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); } if (_params->flip) { OGL.rect[1].s0 = OGL.rect[0].s0; OGL.rect[1].t0 = OGL.rect[3].t0; OGL.rect[1].s1 = OGL.rect[0].s1; OGL.rect[1].t1 = OGL.rect[3].t1; OGL.rect[2].s0 = OGL.rect[3].s0; OGL.rect[2].t0 = OGL.rect[0].t0; OGL.rect[2].s1 = OGL.rect[3].s1; OGL.rect[2].t1 = OGL.rect[0].t1; } else { OGL.rect[1].s0 = OGL.rect[3].s0; OGL.rect[1].t0 = OGL.rect[0].t0; OGL.rect[1].s1 = OGL.rect[3].s1; OGL.rect[1].t1 = OGL.rect[0].t1; OGL.rect[2].s0 = OGL.rect[0].s0; OGL.rect[2].t0 = OGL.rect[3].t0; OGL.rect[2].s1 = OGL.rect[0].s1; OGL.rect[2].t1 = OGL.rect[3].t1; } #ifdef NEW if (ogl.isAdjustScreen() && (gDP.colorImage.width > VI.width * 98 / 100) && (_params.lrx - _params.ulx < VI.width * 9 / 10)) { const float scale = ogl.getAdjustScale(); for (u32 i = 0; i < 4; ++i) m_rect[i].x *= scale; } #endif glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); gSP.changed |= CHANGED_GEOMETRYMODE | CHANGED_VIEWPORT; } void OGL_ClearDepthBuffer(bool _fullsize) { if (config.frameBufferEmulation.enable && FrameBuffer_GetCurrent() == NULL) return; #ifdef NEW depthBufferList().clearBuffer(_uly, _lry); #endif glDisable( GL_SCISSOR_TEST ); glDepthMask( GL_TRUE ); glClear( GL_DEPTH_BUFFER_BIT ); _updateDepthUpdate(); glEnable( GL_SCISSOR_TEST ); } void OGL_ClearColorBuffer(float *color) { glDisable( GL_SCISSOR_TEST ); glClearColor( color[0], color[1], color[2], color[3] ); glClear( GL_COLOR_BUFFER_BIT ); glEnable( GL_SCISSOR_TEST ); } int OGL_CheckError(void) { GLenum e = glGetError(); if (e != GL_NO_ERROR) { printf("GL Error: "); switch(e) { case GL_INVALID_ENUM: printf("INVALID ENUM"); break; case GL_INVALID_VALUE: printf("INVALID VALUE"); break; case GL_INVALID_OPERATION: printf("INVALID OPERATION"); break; case GL_OUT_OF_MEMORY: printf("OUT OF MEMORY"); break; } printf("\n"); return 1; } return 0; } void OGL_SwapBuffers(void) { // if emulator defined a render callback function, call it before // buffer swap if (renderCallback) (*renderCallback)(); retro_return(true); scProgramChanged = 0; gDP.otherMode.l = 0; gDPSetTextureLUT(G_TT_NONE); ++__RSP.DList; } void OGL_ReadScreen( void *dest, int *width, int *height ) { *width = OGL_GetScreenWidth(); *height = OGL_GetScreenHeight(); dest = malloc(OGL_GetScreenHeight() * OGL_GetScreenWidth() * 3); if (dest == NULL) return; glReadPixels(0, OGL_GetHeightOffset(), OGL_GetScreenWidth(), OGL_GetScreenHeight(), GL_RGBA, GL_UNSIGNED_BYTE, dest ); } void _setSpecialTexrect(void) { const char * name = __RSP.romname; if (strstr(name, (const char *)"Beetle") || strstr(name, (const char *)"BEETLE") || strstr(name, (const char *)"HSV") || strstr(name, (const char *)"DUCK DODGERS") || strstr(name, (const char *)"DAFFY DUCK")) texturedRectSpecial = texturedRectShadowMap; else if (strstr(name, (const char *)"Perfect Dark") || strstr(name, (const char *)"PERFECT DARK")) texturedRectSpecial = texturedRectDepthBufferCopy; // See comments to that function! else if (strstr(name, (const char *)"CONKER BFD")) texturedRectSpecial = texturedRectCopyToItself; else if (strstr(name, (const char *)"YOSHI STORY")) texturedRectSpecial = texturedRectBGCopy; else if (strstr(name, (const char *)"PAPER MARIO") || strstr(name, (const char *)"MARIO STORY")) texturedRectSpecial = texturedRectPaletteMod; else if (strstr(name, (const char *)"ZELDA")) texturedRectSpecial = texturedRectMonochromeBackground; else texturedRectSpecial = NULL; } bool OGL_Start(void) { float f; _initStates(); _setSpecialTexrect(); //check extensions if ((config.texture.maxAnisotropy>0) && !OGL_IsExtSupported("GL_EXT_texture_filter_anistropic")) { LOG(LOG_WARNING, "Anistropic Filtering is not supported.\n"); config.texture.maxAnisotropy = 0; } f = 0; glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &f); if (config.texture.maxAnisotropy > ((int)f)) { LOG(LOG_WARNING, "Clamping max anistropy to %ix.\n", (int)f); config.texture.maxAnisotropy = (int)f; } //Print some info LOG(LOG_VERBOSE, "[gles2n64]: Enable Runfast... \n"); //We must have a shader bound before binding any textures: Combiner_Init(); Combiner_Set(EncodeCombineMode(0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0), -1); Combiner_Set(EncodeCombineMode(0, 0, 0, SHADE, 0, 0, 0, 1, 0, 0, 0, SHADE, 0, 0, 0, 1), -1); TextureCache_Init(); OGL.renderState = RS_NONE; gSP.changed = gDP.changed = 0xFFFFFFFF; memset(OGL.triangles.vertices, 0, VERTBUFF_SIZE * sizeof(SPVertex)); memset(OGL.triangles.elements, 0, ELEMBUFF_SIZE * sizeof(GLubyte)); OGL.triangles.num = 0; return TRUE; } mupen64plus-core/src/si/cic.h000664 001750 001750 00000003450 12655644434 017162 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - cic.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_SI_CIC_H #define M64P_SI_CIC_H enum cic_version { CIC_X101, CIC_X102, CIC_X103, CIC_X105, CIC_X106, CIC_5167 }; struct cic { enum cic_version version; unsigned int seed; }; void init_cic_using_ipl3(struct cic* cic, const void* ipl3); #endif mupen64plus-core/src/dd/dd_controller.h000664 001750 001750 00000005421 12655644434 021232 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - dd_controller.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2015 LuigiBlood * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef DD_CONTROLLER_H #define DD_CONTROLLER_H struct r4300_core; #include #include "dd_disk.h" enum dd_registers { ASIC_DATA, ASIC_MISC_REG, ASIC_CMD_STATUS, ASIC_CUR_TK, ASIC_BM_STATUS_CTL, ASIC_ERR_SECTOR, ASIC_SEQ_STATUS_CTL, ASIC_CUR_SECTOR, ASIC_HARD_RESET, ASIC_C1_S0, ASIC_HOST_SECBYTE, ASIC_C1_S2, ASIC_SEC_BYTE, ASIC_C1_S4, ASIC_C1_S6, ASIC_CUR_ADDR, ASIC_ID_REG, ASIC_TEST_REG, ASIC_TEST_PIN_SEL, ASIC_REGS_COUNT }; struct dd_controller { uint32_t regs[ASIC_REGS_COUNT]; uint32_t c2_buf[0x400/4]; uint32_t sec_buf[0x100/4]; uint32_t mseq_buf[0x40/4]; struct r4300_core* r4300; struct dd_disk disk; }; static uint32_t dd_reg(uint32_t address) { uint32_t temp = address & 0xffff; if (temp >= 0x0500 && temp < 0x054c) temp -= 0x0500; return temp >> 2; } void connect_dd(struct dd_controller* dd, struct r4300_core* r4300, uint8_t *dd_disk, size_t dd_disk_size); void init_dd(struct dd_controller* dd); int read_dd_regs(void* opaque, uint32_t address, uint32_t* value); int write_dd_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask); int dd_end_of_dma_event(struct dd_controller* dd); #endif mupen64plus-core/src/r4300/tlb.c000664 001750 001750 00000011502 12655644434 017332 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - tlb.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "tlb.h" #include "exception.h" #include "main/rom.h" tlb tlb_e[32]; uint32_t tlb_LUT_r[0x100000]; uint32_t tlb_LUT_w[0x100000]; void tlb_unmap(tlb *entry) { unsigned int i; if (entry->v_even) { for (i=entry->start_even; iend_even; i += 0x1000) tlb_LUT_r[i>>12] = 0; if (entry->d_even) for (i=entry->start_even; iend_even; i += 0x1000) tlb_LUT_w[i>>12] = 0; } if (entry->v_odd) { for (i=entry->start_odd; iend_odd; i += 0x1000) tlb_LUT_r[i>>12] = 0; if (entry->d_odd) for (i=entry->start_odd; iend_odd; i += 0x1000) tlb_LUT_w[i>>12] = 0; } } void tlb_map(tlb *entry) { unsigned int i; if (entry->v_even) { if (entry->start_even < entry->end_even && !(entry->start_even >= 0x80000000 && entry->end_even < 0xC0000000) && entry->phys_even < 0x20000000) { for (i=entry->start_even;iend_even;i+=0x1000) tlb_LUT_r[i>>12] = UINT32_C(0x80000000) | (entry->phys_even + (i - entry->start_even) + 0xFFF); if (entry->d_even) for (i=entry->start_even;iend_even;i+=0x1000) tlb_LUT_w[i>>12] = UINT32_C(0x80000000) | (entry->phys_even + (i - entry->start_even) + 0xFFF); } } if (entry->v_odd) { if (entry->start_odd < entry->end_odd && !(entry->start_odd >= 0x80000000 && entry->end_odd < 0xC0000000) && entry->phys_odd < 0x20000000) { for (i=entry->start_odd;iend_odd;i+=0x1000) tlb_LUT_r[i>>12] = UINT32_C(0x80000000) | (entry->phys_odd + (i - entry->start_odd) + 0xFFF); if (entry->d_odd) for (i=entry->start_odd;iend_odd;i+=0x1000) tlb_LUT_w[i>>12] = UINT32_C(0x80000000) | (entry->phys_odd + (i - entry->start_odd) + 0xFFF); } } } uint32_t virtual_to_physical_address(uint32_t address, int mode) { if (address >= UINT32_C(0x7f000000) && address < UINT32_C(0x80000000) && isGoldeneyeRom) { /************************************************** GoldenEye 007 hack allows for use of TLB. Recoded by okaygo to support all US, J, and E ROMS. **************************************************/ switch (ROM_HEADER.destination_code) { case 'E': /* North American */ return UINT32_C(0xb0034b30) + (address & UINT32_C(0xFFFFFF)); case 'J': /* Japanese */ return UINT32_C(0xb0034b70) + (address & UINT32_C(0xFFFFFF)); case 'P': /* European (PAL spec.) */ return UINT32_C(0xb00329f0) + (address & UINT32_C(0xFFFFFF)); default: // UNKNOWN COUNTRY CODE FOR GOLDENEYE USING AMERICAN VERSION HACK return UINT32_C(0xb0034b30) + (address & UINT32_C(0xFFFFFF)); } } if (mode == TLB_WRITE) { if (tlb_LUT_w[address>>12]) return (tlb_LUT_w[address>>12] & UINT32_C(0xFFFFF000))|(address & UINT32_C(0xFFF)); } else { if (tlb_LUT_r[address>>12]) return (tlb_LUT_r[address>>12] & UINT32_C(0xFFFFF000))|(address & UINT32_C(0xFFF)); } TLB_refill_exception(address, mode); return 0x00000000; } mupen64plus-core/src/si/cic.c000664 001750 001750 00000005376 12655644434 017166 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - cic.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "cic.h" #include "api/m64p_types.h" #include "api/callbacks.h" #include #include #include void init_cic_using_ipl3(struct cic* cic, const void* ipl3) { size_t i; uint64_t crc = 0; static const struct cic cics[] = { { CIC_X101, 0x3f }, { CIC_X102, 0x3f }, { CIC_X103, 0x78 }, { CIC_X105, 0x91 }, { CIC_X106, 0x85 }, { CIC_5167, 0xdd } }; for (i = 0; i < 0xfc0/4; i++) crc += ((uint32_t*)ipl3)[i]; switch(crc) { default: DebugMessage(M64MSG_WARNING, "Unknown CIC type (%08x)! using CIC 6102.", crc); case 0x000000D057C85244LL: /* CIC_X102 */ i = 1; break; case 0x000000D0027FDF31LL: /* CIC_X101 */ case 0x000000CFFB631223LL: /* CIC_X101 */ i = 0; break; case 0x000000D6497E414BLL: /* CIC_X103 */ i = 2; break; case 0x0000011A49F60E96LL: /* CIC_X105 */ i = 3; break; case 0x000000D6D5BE5580LL: /* CIC_X106 */ i = 4; break; case UINT64_C(0x000001053BC19870): /* CIC_5167 */ i = 5; break; } memcpy(cic, &cics[i], sizeof(*cic)); } mupen64plus-core/src/dd/dd_controller.c000664 001750 001750 00000017753 12655644434 021240 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - dd_controller.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2015 LuigiBlood * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "dd_controller.h" #include "dd_rom.h" #include "dd_disk.h" #include #include #define M64P_CORE_PROTOTYPES 1 #include "api/m64p_config.h" #include "api/m64p_types.h" #include "main/main.h" #include "memory/memory.h" #include "r4300/r4300_core.h" #include "si/pif.h" #include "si/si_controller.h" int dd_bm_mode_read; int CUR_BLOCK; int dd_sector55; struct tm* timeinfo; static unsigned char byte2bcd(int n) { n %= 100; return ((n / 10) << 4) | (n % 10); } void connect_dd(struct dd_controller* dd, struct r4300_core* r4300, uint8_t* dd_disk, size_t dd_disk_size) { dd->r4300 = r4300; connect_dd_disk(&dd->disk, dd_disk, dd_disk_size); } void init_dd(struct dd_controller* dd) { memset(dd->regs, 0, ASIC_REGS_COUNT*sizeof(uint32_t)); memset(dd->c2_buf, 0, 0x400); memset(dd->sec_buf, 0, 0x100); memset(dd->mseq_buf, 0, 0x40); dd->regs[ASIC_CMD_STATUS] = (ConfigGetParamBool(g_CoreConfig, "64DD") == 1) ? 0x01000000 : 0xffffffff; dd->regs[ASIC_ID_REG] = 0x00030000; } int read_dd_regs(void* opaque, uint32_t address, uint32_t* value) { struct dd_controller* dd = (struct dd_controller*)opaque; uint32_t reg = dd_reg(address); uint32_t offset = address & 0x00000fff; *value = 0x00000000; if (reg < ASIC_REGS_COUNT) *value = dd->regs[reg]; int Cur_Sector = dd->regs[ASIC_CUR_SECTOR]; if (Cur_Sector >= 0x5A) Cur_Sector -= 0x5A; if ((dd->regs[ASIC_CMD_STATUS] & 0x04000000) && (85 < dd->regs[ASIC_CUR_SECTOR])) { dd->regs[ASIC_CMD_STATUS] &= ~0x04000000; dd_update_bm(dd); } /* //BUFFERS switch (address & 0x00000c00) { case 0x000: //C2 BUFFER *value = dd->c2_buf[offset/4]; break; case 0x400: //SECTOR BUFFER offset -= 0x400; *value = dd->sec_buf[offset/4]; break; } if ((address & 0x00000f00) == 0x500) { //REGS if (reg < ASIC_REGS_COUNT) *value = dd->regs[reg]; if (((address & 0x00000FFF) >= 0x580) || ((address & 0x00000FFF) < 0x5C0)) { //MSEQ offset -= 0x580; *value = dd->mseq_buf[offset/4]; } } */ return 0; } int write_dd_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask) { struct dd_controller* dd = (struct dd_controller*)opaque; uint32_t reg = dd_reg(address); value &= 0xffff0000; if (!ConfigGetParamBool(g_CoreConfig, "64DD")) return 0; switch (reg) { case ASIC_DATA: dd->regs[ASIC_DATA] = value; break; case ASIC_BM_STATUS_CTL: if (value & 0x01000000) { //MECHA INT RESET dd->regs[ASIC_CMD_STATUS] &= ~0x02000000; } if (value & 0x02000000) { //BLOCK TRANSFER dd->regs[ASIC_BM_STATUS_CTL] |= 0x01000000; } else dd->regs[ASIC_BM_STATUS_CTL] &= ~0x01000000; if (value & 0x10000000) { //BM RESET dd->regs[ASIC_CMD_STATUS] &= ~0x5C000000; dd->regs[ASIC_BM_STATUS_CTL] = 0x00000000; } //SET SECTOR dd->regs[ASIC_CUR_SECTOR] = value & 0x00FF0000; CUR_BLOCK = ((dd->regs[ASIC_CUR_SECTOR] >> 16) < 0x5A) ? 0 : 1; if (value & 0x80000000) { //BM START dd->regs[ASIC_BM_STATUS_CTL] |= 0x80000000; dd_sector55 = 0; dd_update_bm(dd); } break; case ASIC_CMD_STATUS: //ASIC Commands timeinfo = (struct tm*)af_rtc_get_time(&g_si.pif.af_rtc); uint8_t year, month, hour, day, min, sec; switch (value >> 16) { case 0x01: //SEEK READ TRACK dd->regs[ASIC_CUR_TK] = dd->regs[ASIC_DATA] | 0x60000000; dd->regs[ASIC_CMD_STATUS] &= ~0x00180000; dd_bm_mode_read = 1; dd_set_zone_and_track_offset(dd); break; case 0x02: //SEEK WRITE TRACK dd->regs[ASIC_CUR_TK] = dd->regs[ASIC_DATA] | 0x60000000; dd->regs[ASIC_CMD_STATUS] &= ~0x00180000; dd_bm_mode_read = 0; dd_set_zone_and_track_offset(dd); break; case 0x08: //CLEAR DISK CHANGE FLAG dd->regs[ASIC_CMD_STATUS] &= ~0x00010000; break; case 0x09: //CLEAR RESET FLAG dd->regs[ASIC_CMD_STATUS] &= ~0x00400000; break; case 0x12: //Get Year/Month //Put time in DATA as BCD year = (uint8_t)byte2bcd(timeinfo->tm_year); month = (uint8_t)byte2bcd((timeinfo->tm_mon + 1)); dd->regs[ASIC_DATA] = (year << 24) | (month << 16); break; case 0x13: //Get Day/Hour //Put time in DATA as BCD hour = (uint8_t)byte2bcd(timeinfo->tm_hour); day = (uint8_t)byte2bcd(timeinfo->tm_mday); dd->regs[ASIC_DATA] = (day << 24) | (hour << 16); break; case 0x14: //Get Min/Sec //Put time in DATA as BCD min = (uint8_t)byte2bcd(timeinfo->tm_min); sec = (uint8_t)byte2bcd(timeinfo->tm_sec); dd->regs[ASIC_DATA] = (min << 24) | (sec << 16); break; case 0x1b: //Feature Inquiry dd->regs[ASIC_DATA] = 0x00010000; break; } dd->regs[ASIC_CMD_STATUS] |= 0x02000000; cp0_update_count(); add_interupt_event(CART_INT, 100); break; case ASIC_HARD_RESET: dd->regs[ASIC_CMD_STATUS] |= 0x00400000; break; } return 0; } int dd_end_of_dma_event(struct dd_controller* dd) { //Insert clear CART INT here or something dd_update_bm(dd); if ((dd->regs[ASIC_CMD_STATUS] & 0x06000000) == 0) return 1; return 0; } mupen64plus-video-gliden64/src/F3DEX.cpp000664 001750 001750 00000005725 12655644434 020754 0ustar00sergiosergio000000 000000 #include "GLideN64.h" #include "Debug.h" #include "F3D.h" #include "F3DEX.h" #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gSP.h" #include "gDP.h" #include "GBI.h" void F3DEX_Vtx( u32 w0, u32 w1 ) { gSPVertex( w1, _SHIFTR( w0, 10, 6 ), _SHIFTR( w0, 17, 7 ) ); } void F3DEX_Tri1( u32 w0, u32 w1 ) { gSP1Triangle( _SHIFTR( w1, 17, 7 ), _SHIFTR( w1, 9, 7 ), _SHIFTR( w1, 1, 7 )); } void F3DEX_CullDL( u32 w0, u32 w1 ) { gSPCullDisplayList( _SHIFTR( w0, 1, 15 ), _SHIFTR( w1, 1, 15 ) ); } void F3DEX_ModifyVtx( u32 w0, u32 w1 ) { gSPModifyVertex( _SHIFTR( w0, 1, 15 ), _SHIFTR( w0, 16, 8 ), w1 ); } void F3DEX_Tri2( u32 w0, u32 w1 ) { gSP2Triangles( _SHIFTR( w0, 17, 7 ), _SHIFTR( w0, 9, 7 ), _SHIFTR( w0, 1, 7 ), 0, _SHIFTR( w1, 17, 7 ), _SHIFTR( w1, 9, 7 ), _SHIFTR( w1, 1, 7 ), 0); } void F3DEX_Quad( u32 w0, u32 w1 ) { gSP1Quadrangle( _SHIFTR( w1, 25, 7 ), _SHIFTR( w1, 17, 7 ), _SHIFTR( w1, 9, 7 ), _SHIFTR( w1, 1, 7 ) ); } void F3DEX_Branch_Z( u32 w0, u32 w1 ) { gSPBranchLessZ( gDP.half_1, _SHIFTR( w0, 1, 11 ), (s32)w1 / 65535.0f / 1023.0f ); } void F3DEX_Load_uCode( u32 w0, u32 w1 ) { gSPLoadUcodeEx( w1, gDP.half_1, _SHIFTR( w0, 0, 16 ) + 1 ); } void F3DEX_Init() { gSPSetupFunctions(); // Set GeometryMode flags GBI_InitFlags( F3DEX ); GBI.PCStackSize = 18; // GBI Command Command Value Command Function GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_MTX, F3D_MTX, F3D_Mtx ); GBI_SetGBI( G_RESERVED0, F3D_RESERVED0, F3D_Reserved0 ); GBI_SetGBI( G_MOVEMEM, F3D_MOVEMEM, F3D_MoveMem ); GBI_SetGBI( G_VTX, F3D_VTX, F3DEX_Vtx ); GBI_SetGBI( G_RESERVED1, F3D_RESERVED1, F3D_Reserved1 ); GBI_SetGBI( G_DL, F3D_DL, F3D_DList ); GBI_SetGBI( G_RESERVED2, F3D_RESERVED2, F3D_Reserved2 ); GBI_SetGBI( G_RESERVED3, F3D_RESERVED3, F3D_Reserved3 ); GBI_SetGBI( G_SPRITE2D_BASE, F3D_SPRITE2D_BASE, F3D_Sprite2D_Base ); GBI_SetGBI( G_TRI1, F3D_TRI1, F3DEX_Tri1 ); GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3DEX_CullDL ); GBI_SetGBI( G_POPMTX, F3D_POPMTX, F3D_PopMtx ); GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3D_MoveWord ); GBI_SetGBI( G_TEXTURE, F3D_TEXTURE, F3D_Texture ); GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L ); GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL ); GBI_SetGBI( G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, F3D_SetGeometryMode ); GBI_SetGBI( G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE, F3D_ClearGeometryMode ); GBI_SetGBI( G_QUAD, F3D_QUAD, F3DEX_Quad ); GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_MODIFYVTX, F3DEX_MODIFYVTX, F3DEX_ModifyVtx ); GBI_SetGBI( G_TRI2, F3DEX_TRI2, F3DEX_Tri2 ); GBI_SetGBI( G_BRANCH_Z, F3DEX_BRANCH_Z, F3DEX_Branch_Z ); GBI_SetGBI( G_LOAD_UCODE, F3DEX_LOAD_UCODE, F3DEX_Load_uCode ); } mupen64plus-rsp-cxd4/vu/select.h000664 001750 001750 00000024116 12655644434 017651 0ustar00sergiosergio000000 000000 /******************************************************************************\ * Authors: Iconoclast * * Release: 2013.11.26 * * License: CC0 Public Domain Dedication * * * * To the extent possible under law, the author(s) have dedicated all copyright * * and related and neighboring rights to this software to the public domain * * worldwide. This software is distributed without any warranty. * * * * You should have received a copy of the CC0 Public Domain Dedication along * * with this software. * * If not, see . * \******************************************************************************/ /* * vector select merge (`VMRG`) formula * * This is really just a vectorizer for ternary conditional storage. * I've named it so because it directly maps to the VMRG op-code. * -- example -- * for (i = 0; i < N; i++) * if (c_pass) * dest = element_a; * else * dest = element_b; */ static INLINE void merge(short* VD, short* cmp, short* pass, short* fail) { register int i; short diff[N]; for (i = 0; i < N; i++) diff[i] = pass[i] - fail[i]; for (i = 0; i < N; i++) VD[i] = fail[i] + cmp[i]*diff[i]; /* actually `(cmp[i] != 0)*diff[i]` */ } INLINE static void do_lt(short* VD, short* VS, short* VT) { short cn[N]; short eq[N]; register int i; for (i = 0; i < N; i++) eq[i] = (VS[i] == VT[i]); for (i = 0; i < N; i++) cn[i] = ne[i] & co[i]; for (i = 0; i < N; i++) eq[i] = eq[i] & cn[i]; for (i = 0; i < N; i++) clip[i] = 0; for (i = 0; i < N; i++) comp[i] = (VS[i] < VT[i]); /* less than */ for (i = 0; i < N; i++) comp[i] = comp[i] | eq[i]; /* ... or equal (uncommonly) */ merge(VACC_L, comp, VS, VT); vector_copy(VD, VACC_L); for (i = 0; i < N; i++) ne[i] = 0; for (i = 0; i < N; i++) co[i] = 0; } INLINE static void do_ne(short* VD, short* VS, short* VT) { register int i; for (i = 0; i < N; i++) clip[i] = 0; for (i = 0; i < N; i++) comp[i] = (VS[i] != VT[i]); for (i = 0; i < N; i++) comp[i] = comp[i] | ne[i]; #if (0) merge(VACC_L, comp, VS, VT); /* correct but redundant */ #else vector_copy(VACC_L, VS); #endif vector_copy(VD, VACC_L); for (i = 0; i < N; i++) ne[i] = 0; for (i = 0; i < N; i++) co[i] = 0; return; } INLINE static void do_ge(short* VD, short* VS, short* VT) { short ce[N]; short eq[N]; register int i; for (i = 0; i < N; i++) eq[i] = (VS[i] == VT[i]); for (i = 0; i < N; i++) ce[i] = (ne[i] & co[i]) ^ 1; for (i = 0; i < N; i++) eq[i] = eq[i] & ce[i]; for (i = 0; i < N; i++) clip[i] = 0; for (i = 0; i < N; i++) comp[i] = (VS[i] > VT[i]); /* greater than */ for (i = 0; i < N; i++) comp[i] = comp[i] | eq[i]; /* ... or equal (commonly) */ merge(VACC_L, comp, VS, VT); vector_copy(VD, VACC_L); for (i = 0; i < N; i++) ne[i] = 0; for (i = 0; i < N; i++) co[i] = 0; } INLINE static void do_cl(short* VD, short* VS, short* VT) { ALIGNED unsigned short VB[N], VC[N]; ALIGNED short eq[N], ge[N], le[N]; ALIGNED short gen[N], len[N], lz[N], uz[N], sn[N]; short diff[N]; short cmp[N]; register int i; vector_copy((short *)VB, VS); vector_copy((short *)VC, VT); /* for (i = 0; i < N; i++) ge[i] = clip[i]; for (i = 0; i < N; i++) le[i] = comp[i]; */ for (i = 0; i < N; i++) eq[i] = ne[i] ^ 1; vector_copy(sn, co); /* * Now that we have extracted all the flags, we will essentially be masking * them back in where they came from redundantly, unless the corresponding * NOTEQUAL bit from VCO upper was not set.... */ for (i = 0; i < N; i++) VC[i] = VC[i] ^ -sn[i]; for (i = 0; i < N; i++) VC[i] = VC[i] + sn[i]; /* conditional negation, if sn */ for (i = 0; i < N; i++) diff[i] = VB[i] - VC[i]; for (i = 0; i < N; i++) uz[i] = (VB[i] + (unsigned short)VT[i] - 65536) >> 31; for (i = 0; i < N; i++) lz[i] = (diff[i] == 0x0000); for (i = 0; i < N; i++) gen[i] = lz[i] | uz[i]; for (i = 0; i < N; i++) len[i] = lz[i] & uz[i]; for (i = 0; i < N; i++) gen[i] = gen[i] & vce[i]; for (i = 0; i < N; i++) len[i] = len[i] & (vce[i] ^ 1); for (i = 0; i < N; i++) len[i] = len[i] | gen[i]; for (i = 0; i < N; i++) gen[i] = (VB[i] >= VC[i]); for (i = 0; i < N; i++) cmp[i] = eq[i] & sn[i]; merge(le, cmp, len, comp); for (i = 0; i < N; i++) cmp[i] = eq[i] & (sn[i] ^ 1); merge(ge, cmp, gen, clip); merge(cmp, sn, le, ge); merge(VACC_L, cmp, (short *)VC, VS); vector_copy(VD, VACC_L); vector_copy(clip, ge); vector_copy(comp, le); for (i = 0; i < N; i++) ne[i] = 0; for (i = 0; i < N; i++) co[i] = 0; for (i = 0; i < N; i++) vce[i] = 0; } INLINE static void do_ch(short* VD, short* VS, short* VT) { ALIGNED short VC[N]; ALIGNED short eq[N], ge[N], le[N]; ALIGNED short sn[N]; #ifndef _DEBUG short diff[N]; #endif short cch[N]; /* corner case hack: -(-32768) with undefined sign */ register int i; for (i = 0; i < N; i++) cch[i] = (VT[i] == -32768) ? ~0 : 0; /* -(-32768) might not be >= 0. */ vector_copy(VC, VT); for (i = 0; i < N; i++) sn[i] = VS[i] ^ VT[i]; for (i = 0; i < N; i++) sn[i] = (sn[i] < 0) ? ~0 : 0; /* signed SRA (sn), 15 */ for (i = 0; i < N; i++) VC[i] ^= sn[i]; /* if (sn == ~0) {VT = ~VT;} else {VT = VT;} */ for (i = 0; i < N; i++) vce[i] = (VS[i] == VC[i]); /* 2's complement: VC = -VT - 1, or ~VT. */ for (i = 0; i < N; i++) vce[i] &= sn[i]; for (i = 0; i < N; i++) VC[i] -= sn[i] & cch[i]; /* converts ~(VT) into -(VT) if (sign) */ for (i = 0; i < N; i++) eq[i] = (VS[i] == VC[i]) & ~cch[i]; /* (VS == +32768) is never true. */ for (i = 0; i < N; i++) eq[i] |= vce[i]; #ifdef _DEBUG for (i = 0; i < N; i++) le[i] = sn[i] ? (VS[i] <= VC[i]) : (VC[i] < 0); for (i = 0; i < N; i++) ge[i] = sn[i] ? (VC[i] > 0x0000) : (VS[i] >= VC[i]); #elif (0) for (i = 0; i < N; i++) le[i] = sn[i] ? (VT[i] <= -VS[i]) : (VT[i] <= ~0x0000); for (i = 0; i < N; i++) ge[i] = sn[i] ? (~0x0000 >= VT[i]) : (VS[i] >= VT[i]); #else for (i = 0; i < N; i++) diff[i] = sn[i] | VS[i]; for (i = 0; i < N; i++) ge[i] = (diff[i] >= VT[i]); for (i = 0; i < N; i++) sn[i] = (unsigned short)(sn[i]) >> 15; /* ~0 to 1, 0 to 0 */ for (i = 0; i < N; i++) diff[i] = VC[i] - VS[i]; for (i = 0; i < N; i++) diff[i] = (diff[i] >= 0); for (i = 0; i < N; i++) le[i] = (VT[i] < 0); merge(le, sn, diff, le); #endif merge(comp, sn, le, ge); merge(VACC_L, comp, VC, VS); vector_copy(VD, VACC_L); vector_copy(clip, ge); vector_copy(comp, le); for (i = 0; i < N; i++) ne[i] = eq[i] ^ 1; vector_copy(co, sn); } INLINE static void do_cr(short* VD, short* VS, short* VT) { short ge[N], le[N], sn[N]; short VC[N]; short cmp[N]; register int i; for (i = 0; i < N; i++) VC[i] = VT[i]; for (i = 0; i < N; i++) sn[i] = VS[i] ^ VT[i]; for (i = 0; i < N; i++) sn[i] = (sn[i] < 0) ? ~0 : 0; #ifdef _DEBUG for (i = 0; i < N; i++) le[i] = sn[i] ? (VT[i] <= ~VS[i]) : (VT[i] <= ~0x0000); for (i = 0; i < N; i++) ge[i] = sn[i] ? (~0x0000 >= VT[i]) : (VS[i] >= VT[i]); #else for (i = 0; i < N; i++) cmp[i] = ~(VS[i] & sn[i]); for (i = 0; i < N; i++) le[i] = (VT[i] <= cmp[i]); for (i = 0; i < N; i++) cmp[i] = (VS[i] | sn[i]); for (i = 0; i < N; i++) ge[i] = (cmp[i] >= VT[i]); #endif for (i = 0; i < N; i++) VC[i] ^= sn[i]; /* if (sn == ~0) {VT = ~VT;} else {VT = VT;} */ merge(cmp, sn, le, ge); merge(VACC_L, cmp, VC, VS); vector_copy(VD, VACC_L); for (i = 0; i < N; i++) clip[i] = ge[i]; for (i = 0; i < N; i++) comp[i] = le[i]; for (i = 0; i < N; i++) ne[i] = 0; for (i = 0; i < N; i++) co[i] = 0; for (i = 0; i < N; i++) vce[i] = 0; } static INLINE void do_mrg(short* VD, short* VS, short* VT) { merge(VACC_L, comp, VS, VT); vector_copy(VD, VACC_L); } static INLINE void do_eq(short* VD, short* VS, short* VT) { register int i; for (i = 0; i < N; i++) clip[i] = 0; for (i = 0; i < N; i++) comp[i] = (VS[i] == VT[i]); for (i = 0; i < N; i++) comp[i] = comp[i] & (ne[i] ^ 1); #if (0) merge(VACC_L, comp, VS, VT); /* correct but redundant */ #else vector_copy(VACC_L, VT); #endif vector_copy(VD, VACC_L); for (i = 0; i < N; i++) ne[i] = 0; for (i = 0; i < N; i++) co[i] = 0; } static INLINE void VEQ(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_eq(VR[vd], VR[vs], ST); } static void VMRG(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_mrg(VR[vd], VR[vs], ST); } static void VCR(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_cr(VR[vd], VR[vs], ST); } static void VCH(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_ch(VR[vd], VR[vs], ST); } static void VCL(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_cl(VR[vd], VR[vs], ST); } static void VGE(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_ge(VR[vd], VR[vs], ST); } static void VNE(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_ne(VR[vd], VR[vs], ST); } static void VLT(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_lt(VR[vd], VR[vs], ST); } gles2rice/src/Video.h000664 001750 001750 00000011714 12655644434 015610 0ustar00sergiosergio000000 000000 /* Copyright (C) 2002 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _DLLINTERFACE_H_ #define _DLLINTERFACE_H_ #define M64P_PLUGIN_PROTOTYPES 1 #include "typedefs.h" #include "m64p_config.h" #include "m64p_plugin.h" #include "m64p_vidext.h" typedef struct { float fViWidth, fViHeight; unsigned short uViWidth, uViHeight; unsigned short uDisplayWidth, uDisplayHeight; bool bVerticalSync; float fMultX, fMultY; int vpLeftW, vpTopW, vpRightW, vpBottomW, vpWidthW, vpHeightW; struct { uint32_t left; uint32_t top; uint32_t right; uint32_t bottom; uint32_t width; uint32_t height; bool needToClip; } clipping; int timer; float fps; // frame per second float dps; // dlist per second uint32_t lastSecFrameCount; uint32_t lastSecDlistCount; }WindowSettingStruct; typedef enum { PRIM_TRI1, PRIM_TRI2, PRIM_TRI3, PRIM_DMA_TRI, PRIM_LINE3D, PRIM_TEXTRECT, PRIM_TEXTRECTFLIP, PRIM_FILLRECT, } PrimitiveType; typedef enum { RSP_SCISSOR, RDP_SCISSOR, UNKNOWN_SCISSOR, } CurScissorType; typedef struct { bool bGameIsRunning; uint32_t dwTvSystem; float fRatio; bool frameReadByCPU; bool frameWriteByCPU; uint32_t SPCycleCount; // Count how many CPU cycles SP used in this DLIST uint32_t DPCycleCount; // Count how many CPU cycles DP used in this DLIST uint32_t dwNumTrisRendered; uint32_t dwNumDListsCulled; uint32_t dwNumTrisClipped; uint32_t dwNumVertices; uint32_t dwBiggestVertexIndex; uint32_t gDlistCount; uint32_t gFrameCount; uint32_t gUcodeCount; uint32_t gRDPTime; bool ToResize; uint32_t gNewResizeWidth, gNewResizeHeight; bool bDisableFPS; bool bUseModifiedUcodeMap; bool ucodeHasBeenSet; bool bUcodeIsKnown; uint32_t curRenderBuffer; uint32_t curDisplayBuffer; uint32_t curVIOriginReg; CurScissorType curScissor; PrimitiveType primitiveType; uint32_t lastPurgeTimeTime; // Time textures were last purged bool UseLargerTile[2]; // This is a speed up for large tile loading, uint32_t LargerTileRealLeft[2]; // works only for TexRect, LoadTile, large width, large pitch bool bVIOriginIsUpdated; bool bCIBufferIsRendered; int leftRendered,topRendered,rightRendered,bottomRendered; bool isMMXSupported; bool isMMXEnabled; bool toShowCFB; bool bAllowLoadFromTMEM; // Frame buffer simulation related status variables bool bN64FrameBufferIsUsed; // Frame buffer is used in the frame bool bN64IsDrawingTextureBuffer; // The current N64 game is rendering into render_texture, to create self-rendering texture bool bHandleN64RenderTexture; // Do we need to handle of the N64 render_texture stuff? bool bDirectWriteIntoRDRAM; // When drawing into render_texture, this value = // = true don't render, but write real N64 graphic value into RDRAM // = false rendering into render_texture of DX or OGL, the render_texture // will be copied into RDRAM at the end bool bFrameBufferIsDrawn; // flag to mark if the frame buffer is ever drawn bool bFrameBufferDrawnByTriangles; // flag to tell if the buffer is even drawn by Triangle cmds bool bScreenIsDrawn; } PluginStatus; #define MI_INTR_DP 0x00000020 #define MI_INTR_SP 0x00000001 extern PluginStatus status; #ifdef __cplusplus extern "C" { #endif extern GFX_INFO gfx_info; #ifdef __cplusplus } #endif extern WindowSettingStruct windowSetting; extern uint32_t g_dwRamSize; #ifdef __LIBRETRO__ // Prefix symbol #define renderCallback ricerenderCallback #endif /* global functions provided by Video.cpp */ extern char generalText[]; extern void (*renderCallback)(int); void DebugMessage(int level, const char *message, ...); void SetVIScales(); extern void _VIDEO_DisplayTemporaryMessage2(const char *msg, ...); extern void _VIDEO_DisplayTemporaryMessage(const char *msg); extern void XBOX_Debugger_Log(const char *Message, ...); #endif gles2rice/src/OGLExtRender.cpp000664 001750 001750 00000020240 12655644434 017331 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "osal_opengl.h" #include "OGLDebug.h" #include "OGLExtRender.h" #include "OGLTexture.h" void COGLExtRender::Initialize(void) { OGLRender::Initialize(); // Initialize multitexture glGetIntegerv(GL_MAX_TEXTURE_UNITS,&m_maxTexUnits); OPENGL_CHECK_ERRORS; for( int i=0; i<8; i++ ) m_textureUnitMap[i] = -1; m_textureUnitMap[0] = 0; // T0 is usually using texture unit 0 m_textureUnitMap[1] = 1; // T1 is usually using texture unit 1 } void COGLExtRender::BindTexture(GLuint texture, int unitno) { if( m_bEnableMultiTexture ) { if( unitno < m_maxTexUnits ) { if( m_curBoundTex[unitno] != texture ) { pglActiveTexture(GL_TEXTURE0 + unitno); OPENGL_CHECK_ERRORS; glBindTexture(GL_TEXTURE_2D,texture); OPENGL_CHECK_ERRORS; m_curBoundTex[unitno] = texture; } } } else { OGLRender::BindTexture(texture, unitno); } } void COGLExtRender::DisBindTexture(GLuint texture, int unitno) { if( m_bEnableMultiTexture ) { pglActiveTexture(GL_TEXTURE0 + unitno); OPENGL_CHECK_ERRORS; glBindTexture(GL_TEXTURE_2D, 0); //Not to bind any texture OPENGL_CHECK_ERRORS; } else OGLRender::DisBindTexture(texture, unitno); } void COGLExtRender::TexCoord2f(float u, float v) { } void COGLExtRender::TexCoord(TLITVERTEX &vtxInfo) { } void COGLExtRender::SetTexWrapS(int unitno,GLuint flag) { static GLuint mflag[8]; static GLuint mtex[8]; if( m_curBoundTex[unitno] != mtex[unitno] || mflag[unitno] != flag ) { pglActiveTexture(GL_TEXTURE0+unitno); OPENGL_CHECK_ERRORS; mtex[unitno] = m_curBoundTex[0]; mflag[unitno] = flag; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, flag); OPENGL_CHECK_ERRORS; } } void COGLExtRender::SetTexWrapT(int unitno,GLuint flag) { static GLuint mflag[8]; static GLuint mtex[8]; if( m_curBoundTex[unitno] != mtex[unitno] || mflag[unitno] != flag ) { mtex[unitno] = m_curBoundTex[0]; mflag[unitno] = flag; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, flag); OPENGL_CHECK_ERRORS; } } extern UVFlagMap OGLXUVFlagMaps[]; void COGLExtRender::SetTextureUFlag(TextureUVFlag dwFlag, uint32_t dwTile) { TileUFlags[dwTile] = dwFlag; if( !m_bEnableMultiTexture ) { OGLRender::SetTextureUFlag(dwFlag, dwTile); return; } int tex; if( dwTile == gRSP.curTile ) tex=0; else if( dwTile == ((gRSP.curTile+1)&7) ) tex=1; else { if( dwTile == ((gRSP.curTile+2)&7) ) tex=2; else if( dwTile == ((gRSP.curTile+3)&7) ) tex=3; else { TRACE2("Incorrect tile number for OGL SetTextureUFlag: cur=%d, tile=%d", gRSP.curTile, dwTile); return; } } for( int textureNo=0; textureNo<8; textureNo++) { if( m_textureUnitMap[textureNo] == tex ) { COGLTexture* pTexture = g_textures[(gRSP.curTile+tex)&7].m_pCOGLTexture; if( pTexture ) { EnableTexUnit(textureNo, true); BindTexture(pTexture->m_dwTextureName, textureNo); } SetTexWrapS(textureNo, OGLXUVFlagMaps[dwFlag].realFlag); } } } void COGLExtRender::SetTextureVFlag(TextureUVFlag dwFlag, uint32_t dwTile) { TileVFlags[dwTile] = dwFlag; if( !m_bEnableMultiTexture ) { OGLRender::SetTextureVFlag(dwFlag, dwTile); return; } int tex; if( dwTile == gRSP.curTile ) tex=0; else if( dwTile == ((gRSP.curTile+1)&7) ) tex=1; else { if( dwTile == ((gRSP.curTile+2)&7) ) tex=2; else if( dwTile == ((gRSP.curTile+3)&7) ) tex=3; else { TRACE2("Incorrect tile number for OGL SetTextureVFlag: cur=%d, tile=%d", gRSP.curTile, dwTile); return; } } for( int textureNo=0; textureNo<8; textureNo++) { if( m_textureUnitMap[textureNo] == tex ) { COGLTexture* pTexture = g_textures[(gRSP.curTile+tex)&7].m_pCOGLTexture; if( pTexture ) { EnableTexUnit(textureNo, true); BindTexture(pTexture->m_dwTextureName, textureNo); } SetTexWrapT(textureNo, OGLXUVFlagMaps[dwFlag].realFlag); } } } void COGLExtRender::EnableTexUnit(int unitno, bool flag) { if( m_texUnitEnabled[unitno] != flag ) { m_texUnitEnabled[unitno] = flag; pglActiveTexture(GL_TEXTURE0 + unitno); OPENGL_CHECK_ERRORS; } } void COGLExtRender::ApplyTextureFilter() { static uint32_t minflag[32], magflag[32]; static uint32_t mtex[32]; int iMinFilter, iMagFilter; for( int i=0; i #include #include #include "osal_preproc.h" #include "float.h" #include "DeviceBuilder.h" #include "Render.h" #include "Timing.h" #ifndef min #define min(a,b) ((a) < (b) ? (a) : (b)) #endif #ifndef max #define max(a,b) ((a) > (b) ? (a) : (b)) #endif extern FiddledVtx * g_pVtxBase; #define ENABLE_CLIP_TRI #define X_CLIP_MAX 0x1 #define X_CLIP_MIN 0x2 #define Y_CLIP_MAX 0x4 #define Y_CLIP_MIN 0x8 #define Z_CLIP_MAX 0x10 #define Z_CLIP_MIN 0x20 #ifdef ENABLE_CLIP_TRI inline void RSP_Vtx_Clipping(int i) { g_clipFlag[i] = 0; g_clipFlag2[i] = 0; if( g_vecProjected[i].w > 0 ) { /* if( gRSP.bRejectVtx ) { if( g_vecProjected[i].x > 1 ) { g_clipFlag2[i] |= X_CLIP_MAX; if( g_vecProjected[i].x > gRSP.real_clip_ratio_posx ) g_clipFlag[i] |= X_CLIP_MAX; } if( g_vecProjected[i].x < -1 ) { g_clipFlag2[i] |= X_CLIP_MIN; if( g_vecProjected[i].x < gRSP.real_clip_ratio_negx ) g_clipFlag[i] |= X_CLIP_MIN; } if( g_vecProjected[i].y > 1 ) { g_clipFlag2[i] |= Y_CLIP_MAX; if( g_vecProjected[i].y > gRSP.real_clip_ratio_posy ) g_clipFlag[i] |= Y_CLIP_MAX; } if( g_vecProjected[i].y < -1 ) { g_clipFlag2[i] |= Y_CLIP_MIN; if( g_vecProjected[i].y < gRSP.real_clip_ratio_negy ) g_clipFlag[i] |= Y_CLIP_MIN; } //if( g_vecProjected[i].z > 1.0f ) //{ // g_clipFlag2[i] |= Z_CLIP_MAX; // g_clipFlag[i] |= Z_CLIP_MAX; //} //if( gRSP.bNearClip && g_vecProjected[i].z < -1.0f ) //{ // g_clipFlag2[i] |= Z_CLIP_MIN; // g_clipFlag[i] |= Z_CLIP_MIN; //} } else */ { if( g_vecProjected[i].x > 1 ) g_clipFlag2[i] |= X_CLIP_MAX; if( g_vecProjected[i].x < -1 ) g_clipFlag2[i] |= X_CLIP_MIN; if( g_vecProjected[i].y > 1 ) g_clipFlag2[i] |= Y_CLIP_MAX; if( g_vecProjected[i].y < -1 ) g_clipFlag2[i] |= Y_CLIP_MIN; //if( g_vecProjected[i].z > 1.0f ) g_clipFlag2[i] |= Z_CLIP_MAX; //if( gRSP.bNearClip && g_vecProjected[i].z < -1.0f ) g_clipFlag2[i] |= Z_CLIP_MIN; } } } #else inline void RSP_Vtx_Clipping(int i) {} #endif /* * Global variables */ ALIGN(16,RSP_Options gRSP); ALIGN(16,RDP_Options gRDP); static ALIGN(16,XVECTOR4 g_normal); //static int norms[3]; ALIGN(16,XVECTOR4 g_vtxNonTransformed[MAX_VERTS]); ALIGN(16,XVECTOR4 g_vecProjected[MAX_VERTS]); ALIGN(16,XVECTOR4 g_vtxTransformed[MAX_VERTS]); float g_vtxProjected5[1000][5]; float g_vtxProjected5Clipped[2000][5]; //uint32_t g_dwVtxFlags[MAX_VERTS]; // Z_POS Z_NEG etc VECTOR2 g_fVtxTxtCoords[MAX_VERTS]; uint32_t g_dwVtxDifColor[MAX_VERTS]; uint32_t g_clipFlag[MAX_VERTS]; uint32_t g_clipFlag2[MAX_VERTS]; RenderTexture g_textures[MAX_TEXTURES]; float g_fFogCoord[MAX_VERTS]; EXTERNAL_VERTEX g_vtxForExternal[MAX_VERTS]; TLITVERTEX g_vtxBuffer[1000]; TLITVERTEX g_clippedVtxBuffer[2000]; uint8_t g_oglVtxColors[1000][4]; int g_clippedVtxCount=0; TLITVERTEX g_texRectTVtx[4]; unsigned short g_vtxIndex[1000]; unsigned int g_minIndex, g_maxIndex; float gRSPfFogMin; float gRSPfFogMax; float gRSPfFogDivider; uint32_t gRSPnumLights; Light gRSPlights[16]; ALIGN(16,Matrix gRSPworldProjectTransported); ALIGN(16,Matrix gRSPworldProject); ALIGN(16,Matrix gRSPmodelViewTop); ALIGN(16,Matrix gRSPmodelViewTopTranspose); ALIGN(16,Matrix dkrMatrixTransposed); N64Light gRSPn64lights[16]; void (*ProcessVertexData)(uint32_t dwAddr, uint32_t dwV0, uint32_t dwNum)=NULL; /* * */ /*n.x = (g_normal.x * matWorld.m00) + (g_normal.y * matWorld.m10) + (g_normal.z * matWorld.m20); n.y = (g_normal.x * matWorld.m01) + (g_normal.y * matWorld.m11) + (g_normal.z * matWorld.m21); n.z = (g_normal.x * matWorld.m02) + (g_normal.y * matWorld.m12) + (g_normal.z * matWorld.m22);*/ // Multiply (x,y,z,0) by matrix m, then normalize #if defined(__INTEL_COMPILER) && !defined(NO_ASM) #define Vec3TransformNormal(vec, m) __asm \ { \ __asm fld dword ptr [vec + 0] \ __asm fmul dword ptr [m + 0] \ /* x m00*/ __asm fld dword ptr [vec + 0] \ __asm fmul dword ptr [m + 4] \ /* x m01 x m00*/ __asm fld dword ptr [vec + 0] \ __asm fmul dword ptr [m + 8] \ /* x m02 x m01 x m00*/ \ __asm fld dword ptr [vec + 4] \ __asm fmul dword ptr [m + 16] \ /* y m10 x m02 x m01 x m00*/ __asm fld dword ptr [vec + 4] \ __asm fmul dword ptr [m + 20] \ /* y m11 y m10 x m02 x m01 x m00*/ __asm fld dword ptr [vec + 4] \ __asm fmul dword ptr [m + 24] \ /* y m12 y m11 y m10 x m02 x m01 x m00*/ \ __asm fxch st(2) \ /* y m10 y m11 y m12 x m02 x m01 x m00*/ __asm faddp st(5), st(0) \ /* y m11 y m12 x m02 x m01 (x m00 + y m10)*/ __asm faddp st(3), st(0) \ /* y m12 x m02 (x m01 + ym11) (x m00 + y m10)*/ __asm faddp st(1), st(0) \ /* (x m02 + y m12) (x m01 + ym11) (x m00 + y m10)*/ \ __asm fld dword ptr [vec + 8] \ __asm fmul dword ptr [m + 32] \ /* z m20 (x m02 + y m12) (x m01 + ym11) (x m00 + y m10)*/ __asm fld dword ptr [vec + 8] \ __asm fmul dword ptr [m + 36] \ /* z m21 z m20 (x m02 + y m12) (x m01 + ym11) (x m00 + y m10)*/ __asm fld dword ptr [vec + 8] \ __asm fmul dword ptr [m + 40] \ /* z m22 z m21 z m20 (x m02 + y m12) (x m01 + ym11) (x m00 + y m10)*/ \ __asm fxch st(2) \ /* z m20 z m21 z m22 (x m02 + y m12) (x m01 + ym11) (x m00 + y m10)*/ __asm faddp st(5), st(0) \ /* z m21 z m22 (x m02 + y m12) (x m01 + ym11) (x m00 + y m10 + z m20)*/ __asm faddp st(3), st(0) \ /* z m22 (x m02 + y m12) (x m01 + ym11 + z m21) (x m00 + y m10 + z m20)*/ __asm faddp st(1), st(0) \ /* (x m02 + y m12 + z m 22) (x m01 + ym11 + z m21) (x m00 + y m10 + z m20)*/ \ __asm fxch st(2) \ /* (x m00 + y m10 + z m20) (x m01 + ym11 + z m21) (x m02 + y m12 + z m 22) */ \ __asm fld1 \ /* 1 x y z */ __asm fld st(1) \ /* x 1 x y z */ __asm fmul st(0),st(0) \ /* xx 1 x y z */ __asm fld st(3) \ /* y xx 1 x y z */ __asm fmul st(0),st(0) \ /* yy xx 1 x y z */ __asm fld st(5) \ /* z yy xx 1 x y z */ __asm fmul st(0),st(0) \ /* zz yy xx 1 x y z */ \ __asm fxch st(2) \ /* xx yy zz 1 x y z */ \ __asm faddp st(1),st(0) \ /* (xx+yy) zz 1 x y z */ __asm faddp st(1),st(0) \ /* (xx+yy+zz) 1 x y z */ \ __asm ftst \ /* Compare ST to 0 */ __asm fstsw ax \ /* Store FPU status word in a */ __asm sahf \ /* Transfer ax to flags register */ __asm jz l2 \ /* Skip if length is zero */ \ __asm fsqrt \ /* l 1 x y z */ \ __asm fdivp st(1),st(0) \ /* (1/l) x y z */ \ __asm fmul st(3),st(0) \ /* f x y fz */ __asm fmul st(2),st(0) \ /* f x fy fz */ __asm fmulp st(1),st(0) \ /* fx fy fz */ \ __asm fstp dword ptr [vec + 0] \ /* fy fz*/ __asm fstp dword ptr [vec + 4] \ /* fz */ __asm fstp dword ptr [vec + 8] \ /* done */ __asm jmp l3 \ __asm l2: \ __asm mov dword ptr [vec + 0], 0 \ __asm mov dword ptr [vec + 4], 0 \ __asm mov dword ptr [vec + 8], 0 \ __asm l3: \ } \ #else // use C code in other cases, this is probably faster anyway #define Vec3TransformNormal(vec, m) \ VECTOR3 temp; \ temp.x = (vec.x * m._11) + (vec.y * m._21) + (vec.z * m._31); \ temp.y = (vec.x * m._12) + (vec.y * m._22) + (vec.z * m._32); \ temp.z = (vec.x * m._13) + (vec.y * m._23) + (vec.z * m._33); \ float norm = sqrt(temp.x*temp.x+temp.y*temp.y+temp.z*temp.z); \ if (norm == 0.0) { vec.x = 0.0; vec.y = 0.0; vec.z = 0.0;} else \ { vec.x = temp.x/norm; vec.y = temp.y/norm; vec.z = temp.z/norm; } #endif float real255 = 255.0f; float real128 = 128.0f; void NormalizeNormalVec() { float w = 1/sqrtf(g_normal.x*g_normal.x + g_normal.y*g_normal.y + g_normal.z*g_normal.z); g_normal.x *= w; g_normal.y *= w; g_normal.z *= w; } void InitRenderBase() { #if defined(__ARM_NEON__) if( !g_curRomInfo.bPrimaryDepthHack && options.enableHackForGames != HACK_FOR_NASCAR && options.enableHackForGames != HACK_FOR_ZELDA_MM && !options.bWinFrameMode) { ProcessVertexData = ProcessVertexDataNEON; } else #endif { ProcessVertexData = ProcessVertexDataNoSSE; } gRSPfFogMin = gRSPfFogMax = 0.0f; windowSetting.fMultX = windowSetting.fMultY = 2.0f; windowSetting.vpLeftW = windowSetting.vpTopW = 0; windowSetting.vpRightW = windowSetting.vpWidthW = 640; windowSetting.vpBottomW = windowSetting.vpHeightW = 480; gRSP.maxZ = 0; gRSP.nVPLeftN = gRSP.nVPTopN = 0; gRSP.nVPRightN = 640; gRSP.nVPBottomN = 640; gRSP.nVPWidthN = 640; gRSP.nVPHeightN = 640; gRDP.scissor.left=gRDP.scissor.top=0; gRDP.scissor.right=gRDP.scissor.bottom=640; gRSP.bLightingEnable = gRSP.bTextureGen = false; gRSP.curTile=gRSPnumLights=gRSP.ambientLightColor=gRSP.ambientLightIndex= 0; gRSP.fAmbientLightR=gRSP.fAmbientLightG=gRSP.fAmbientLightB=0; gRSP.projectionMtxTop = gRSP.modelViewMtxTop = 0; gRDP.fogColor = gRDP.primitiveColor = gRDP.envColor = gRDP.primitiveDepth = gRDP.primLODMin = gRDP.primLODFrac = gRDP.LODFrac = 0; gRDP.fPrimitiveDepth = 0; gRSP.numVertices = 0; gRSP.maxVertexID = 0; gRSP.bCullFront=false; gRSP.bCullBack=true; gRSP.bFogEnabled=gRDP.bFogEnableInBlender=false; gRSP.bZBufferEnabled=true; gRSP.shadeMode=SHADE_SMOOTH; gRDP.keyR=gRDP.keyG=gRDP.keyB=gRDP.keyA=gRDP.keyRGB=gRDP.keyRGBA = 0; gRDP.fKeyA = 0; gRSP.DKRCMatrixIndex = gRSP.dwDKRVtxAddr = gRSP.dwDKRMatrixAddr = 0; gRSP.DKRBillBoard = false; gRSP.fTexScaleX = 1/32.0f; gRSP.fTexScaleY = 1/32.0f; gRSP.bTextureEnabled = FALSE; gRSP.clip_ratio_left = 0; gRSP.clip_ratio_top = 0; gRSP.clip_ratio_right = 640; gRSP.clip_ratio_bottom = 480; gRSP.clip_ratio_negx = 1; gRSP.clip_ratio_negy = 1; gRSP.clip_ratio_posx = 1; gRSP.clip_ratio_posy = 1; gRSP.real_clip_scissor_left = 0; gRSP.real_clip_scissor_top = 0; gRSP.real_clip_scissor_right = 640; gRSP.real_clip_scissor_bottom = 480; windowSetting.clipping.left = 0; windowSetting.clipping.top = 0; windowSetting.clipping.right = 640; windowSetting.clipping.bottom = 480; windowSetting.clipping.width = 640; windowSetting.clipping.height = 480; windowSetting.clipping.needToClip = false; gRSP.real_clip_ratio_negx = 1; gRSP.real_clip_ratio_negy = 1; gRSP.real_clip_ratio_posx = 1; gRSP.real_clip_ratio_posy = 1; gRSP.DKRCMatrixIndex=0; gRSP.DKRVtxCount=0; gRSP.DKRBillBoard = false; gRSP.dwDKRVtxAddr=0; gRSP.dwDKRMatrixAddr=0; gRDP.geometryMode = 0; gRDP.otherModeL = 0; gRDP.otherModeH = 0; gRDP.fillColor = 0xFFFFFFFF; gRDP.originalFillColor =0; gRSP.ucode = 1; gRSP.vertexMult = 10; gRSP.bNearClip = false; gRSP.bRejectVtx = false; gRDP.texturesAreReloaded = false; gRDP.textureIsChanged = false; gRDP.colorsAreReloaded = false; memset(&gRDP.otherMode,0,sizeof(RDP_OtherMode)); memset(&gRDP.tiles,0,sizeof(Tile)*8); for (int i=0; i fMax) { float temp = fMin; fMin = fMax; fMax = temp; } { gRSPfFogMin = max(0,fMin/500-1); gRSPfFogMax = fMax/500-1; } gRSPfFogDivider = 255/(gRSPfFogMax-gRSPfFogMin); CRender::g_pRender->SetFogMinMax(fMin, fMax); } void InitVertexTextureConstants() { RenderTexture &tex0 = g_textures[gRSP.curTile]; //CTexture *surf = tex0.m_pCTexture; Tile &tile0 = gRDP.tiles[gRSP.curTile]; float scaleX = gRSP.fTexScaleX; float scaleY = gRSP.fTexScaleY; gRSP.tex0scaleX = scaleX * tile0.fShiftScaleS/tex0.m_fTexWidth; gRSP.tex0scaleY = scaleY * tile0.fShiftScaleT/tex0.m_fTexHeight; gRSP.tex0OffsetX = tile0.fhilite_sl/tex0.m_fTexWidth; gRSP.tex0OffsetY = tile0.fhilite_tl/tex0.m_fTexHeight; if( CRender::g_pRender->IsTexel1Enable() ) { RenderTexture &tex1 = g_textures[(gRSP.curTile+1)&7]; //CTexture *surf = tex1.m_pCTexture; Tile &tile1 = gRDP.tiles[(gRSP.curTile+1)&7]; gRSP.tex1scaleX = scaleX * tile1.fShiftScaleS/tex1.m_fTexWidth; gRSP.tex1scaleY = scaleY * tile1.fShiftScaleT/tex1.m_fTexHeight; gRSP.tex1OffsetX = tile1.fhilite_sl/tex1.m_fTexWidth; gRSP.tex1OffsetY = tile1.fhilite_tl/tex1.m_fTexHeight; } gRSP.texGenXRatio = tile0.fShiftScaleS; gRSP.texGenYRatio = gRSP.fTexScaleX/gRSP.fTexScaleY*tex0.m_fTexWidth/tex0.m_fTexHeight*tile0.fShiftScaleT; } void TexGen(float &s, float &t) { if (gRDP.geometryMode & G_TEXTURE_GEN_LINEAR) { s = acosf(g_normal.x) / 3.14159f; t = acosf(g_normal.y) / 3.14159f; } else { s = 0.5f * ( 1.0f + g_normal.x); t = 0.5f * ( 1.0f - g_normal.y); } } void ComputeLOD(void) { TLITVERTEX &v0 = g_vtxBuffer[0]; TLITVERTEX &v1 = g_vtxBuffer[1]; RenderTexture &tex0 = g_textures[gRSP.curTile]; float d,dt; float x = g_vtxProjected5[0][0] / g_vtxProjected5[0][4] - g_vtxProjected5[1][0] / g_vtxProjected5[1][4]; float y = g_vtxProjected5[0][1] / g_vtxProjected5[0][4] - g_vtxProjected5[1][1] / g_vtxProjected5[1][4]; x = windowSetting.vpWidthW*x/windowSetting.fMultX/2; y = windowSetting.vpHeightW*y/windowSetting.fMultY/2; d = sqrtf(x*x+y*y); float s0 = v0.tcord[0].u * tex0.m_fTexWidth; float t0 = v0.tcord[0].v * tex0.m_fTexHeight; float s1 = v1.tcord[0].u * tex0.m_fTexWidth; float t1 = v1.tcord[0].v * tex0.m_fTexHeight; dt = sqrtf((s0-s1)*(s0-s1)+(t0-t1)*(t0-t1)); float lod = dt/d; float frac = log10f(lod)/log10f(2.0f); //DEBUGGER_IF_DUMP(pauseAtNext,{DebuggerAppendMsg("LOD frac = %f", frac);}); frac = (lod / powf(2.0f,floorf(frac))); frac = frac - floorf(frac); //DEBUGGER_IF_DUMP(pauseAtNext,{DebuggerAppendMsg("LOD = %f, frac = %f", lod, frac);}); gRDP.LODFrac = (uint32_t)(frac*255); CRender::g_pRender->SetCombinerAndBlender(); } bool bHalfTxtScale=false; extern uint32_t lastSetTile; #ifdef _MSC_VER #define noinline __declspec(noinline) #else #define noinline __attribute__((noinline)) #endif static noinline void InitVertex_scale_hack_check(uint32_t dwV) { // Check for txt scale hack if( gRDP.tiles[lastSetTile].dwSize == TXT_SIZE_32b || gRDP.tiles[lastSetTile].dwSize == TXT_SIZE_4b ) { int width = ((gRDP.tiles[lastSetTile].sh-gRDP.tiles[lastSetTile].sl+1)<<1); int height = ((gRDP.tiles[lastSetTile].th-gRDP.tiles[lastSetTile].tl+1)<<1); if( g_fVtxTxtCoords[dwV].x*gRSP.fTexScaleX == width || g_fVtxTxtCoords[dwV].y*gRSP.fTexScaleY == height ) { bHalfTxtScale=true; } } } static noinline void InitVertex_notopengl_or_clipper_adjust(TLITVERTEX &v, uint32_t dwV) { v.x = g_vecProjected[dwV].x*gRSP.vtxXMul+gRSP.vtxXAdd; v.y = g_vecProjected[dwV].y*gRSP.vtxYMul+gRSP.vtxYAdd; v.z = (g_vecProjected[dwV].z + 1.0f) * 0.5f; // DirectX minZ=0, maxZ=1 //v.z = g_vecProjected[dwV].z; // DirectX minZ=0, maxZ=1 v.rhw = g_vecProjected[dwV].w; VTX_DUMP(TRACE4(" Proj : x=%f, y=%f, z=%f, rhw=%f", v.x,v.y,v.z,v.rhw)); if( gRSP.bProcessSpecularColor ) { v.dcSpecular = CRender::g_pRender->PostProcessSpecularColor(); if( gRSP.bFogEnabled ) { v.dcSpecular &= 0x00FFFFFF; uint32_t fogFct = 0xFF-(uint8_t)((g_fFogCoord[dwV]-gRSPfFogMin)*gRSPfFogDivider); v.dcSpecular |= (fogFct<<24); } } else if( gRSP.bFogEnabled ) { uint32_t fogFct = 0xFF-(uint8_t)((g_fFogCoord[dwV]-gRSPfFogMin)*gRSPfFogDivider); v.dcSpecular = (fogFct<<24); } } static noinline void InitVertex_texgen_correct(TLITVERTEX &v, uint32_t dwV) { // Correction for texGen result float u0,u1,v0,v1; RenderTexture &tex0 = g_textures[gRSP.curTile]; u0 = g_fVtxTxtCoords[dwV].x * 32 * 1024 * gRSP.fTexScaleX / tex0.m_fTexWidth; v0 = g_fVtxTxtCoords[dwV].y * 32 * 1024 * gRSP.fTexScaleY / tex0.m_fTexHeight; u0 *= (gRDP.tiles[gRSP.curTile].fShiftScaleS); v0 *= (gRDP.tiles[gRSP.curTile].fShiftScaleT); if( CRender::g_pRender->IsTexel1Enable() ) { RenderTexture &tex1 = g_textures[(gRSP.curTile+1)&7]; u1 = g_fVtxTxtCoords[dwV].x * 32 * 1024 * gRSP.fTexScaleX / tex1.m_fTexWidth; v1 = g_fVtxTxtCoords[dwV].y * 32 * 1024 * gRSP.fTexScaleY / tex1.m_fTexHeight; u1 *= gRDP.tiles[(gRSP.curTile+1)&7].fShiftScaleS; v1 *= gRDP.tiles[(gRSP.curTile+1)&7].fShiftScaleT; CRender::g_pRender->SetVertexTextureUVCoord(v, u0, v0, u1, v1); } else { CRender::g_pRender->SetVertexTextureUVCoord(v, u0, v0); } } #include "RenderBase_neon.h" #ifndef __ARM_NEON__ static void multiply_subtract2(float *d, const float *m1, const float *m2, const float *s) { int i; for (i = 0; i < 2; i++) d[i] = m1[i] * m2[i] - s[i]; } #else extern "C" void multiply_subtract2(float *d, const float *m1, const float *m2, const float *s); #endif void InitVertex(uint32_t dwV, uint32_t vtxIndex, bool bTexture) { VTX_DUMP(TRACE2("Initialize vertex (%d) to vertex buffer[%d]:", dwV, vtxIndex)); TLITVERTEX &v = g_vtxBuffer[vtxIndex]; VTX_DUMP(TRACE4(" Trans: x=%f, y=%f, z=%f, w=%f", g_vtxTransformed[dwV].x,g_vtxTransformed[dwV].y,g_vtxTransformed[dwV].z,g_vtxTransformed[dwV].w)); g_vtxProjected5[vtxIndex][0] = g_vtxTransformed[dwV].x; g_vtxProjected5[vtxIndex][1] = g_vtxTransformed[dwV].y; g_vtxProjected5[vtxIndex][2] = g_vtxTransformed[dwV].z; g_vtxProjected5[vtxIndex][3] = g_vtxTransformed[dwV].w; g_vtxProjected5[vtxIndex][4] = g_fFogCoord[dwV]; g_vtxIndex[vtxIndex] = vtxIndex; if( options.bOGLVertexClipper == TRUE ) { InitVertex_notopengl_or_clipper_adjust(v, dwV); } VTX_DUMP(TRACE2(" (U,V): %f, %f", g_fVtxTxtCoords[dwV].x,g_fVtxTxtCoords[dwV].y)); v.dcDiffuse = g_dwVtxDifColor[dwV]; if( gRDP.otherMode.key_en ) { v.dcDiffuse &= 0x00FFFFFF; v.dcDiffuse |= (gRDP.keyA<<24); } else if( gRDP.otherMode.aa_en && gRDP.otherMode.clr_on_cvg==0 ) { v.dcDiffuse |= 0xFF000000; } if( gRSP.bProcessDiffuseColor ) { v.dcDiffuse = CRender::g_pRender->PostProcessDiffuseColor(v.dcDiffuse); } if( options.bWinFrameMode ) { v.dcDiffuse = g_dwVtxDifColor[dwV]; } g_oglVtxColors[vtxIndex][0] = v.r; g_oglVtxColors[vtxIndex][1] = v.g; g_oglVtxColors[vtxIndex][2] = v.b; g_oglVtxColors[vtxIndex][3] = v.a; if( bTexture ) { // If the vert is already lit, then there is no normal (and hence we can't generate tex coord) // Only scale if not generated automatically if (gRSP.bTextureGen && gRSP.bLightingEnable) { InitVertex_texgen_correct(v, dwV); } else { TexCord tex0; multiply_subtract2(&tex0.u, &g_fVtxTxtCoords[dwV].x, &gRSP.tex0scaleX, &gRSP.tex0OffsetX); if( CRender::g_pRender->IsTexel1Enable() ) { TexCord tex1; multiply_subtract2(&tex1.u, &g_fVtxTxtCoords[dwV].x, &gRSP.tex1scaleX, &gRSP.tex1OffsetX); CRender::g_pRender->SetVertexTextureUVCoord(v, tex0, tex1); VTX_DUMP(TRACE2(" (tex0): %f, %f", tex0.u,tex0.v)); VTX_DUMP(TRACE2(" (tex1): %f, %f", tex1.u,tex1.v)); } else { CRender::g_pRender->SetVertexTextureUVCoord(v, tex0); VTX_DUMP(TRACE2(" (tex0): %f, %f", tex0.u,tex0.v)); } } if(g_curRomInfo.bTextureScaleHack && !bHalfTxtScale) InitVertex_scale_hack_check(dwV); } VTX_DUMP(TRACE2(" DIF(%08X), SPE(%08X)", v.dcDiffuse, v.dcSpecular)); VTX_DUMP(TRACE0("")); } uint32_t LightVert(XVECTOR4 & norm, int vidx) { float fCosT; // Do ambient register float r = gRSP.fAmbientLightR; register float g = gRSP.fAmbientLightG; register float b = gRSP.fAmbientLightB; if( options.enableHackForGames != HACK_FOR_ZELDA_MM ) { for (register unsigned int l=0; l < gRSPnumLights; l++) { fCosT = norm.x*gRSPlights[l].x + norm.y*gRSPlights[l].y + norm.z*gRSPlights[l].z; if (fCosT > 0 ) { r += gRSPlights[l].fr * fCosT; g += gRSPlights[l].fg * fCosT; b += gRSPlights[l].fb * fCosT; } } } else { XVECTOR4 v; bool transformed = false; for (register unsigned int l=0; l < gRSPnumLights; l++) { if( gRSPlights[l].range == 0 ) { // Regular directional light fCosT = norm.x*gRSPlights[l].x + norm.y*gRSPlights[l].y + norm.z*gRSPlights[l].z; if (fCosT > 0 ) { r += gRSPlights[l].fr * fCosT; g += gRSPlights[l].fg * fCosT; b += gRSPlights[l].fb * fCosT; } } else //if( (gRSPlights[l].col&0x00FFFFFF) != 0x00FFFFFF ) { // Point light if( !transformed ) { Vec3Transform(&v, (XVECTOR3*)&g_vtxNonTransformed[vidx], &gRSPmodelViewTop); // Convert to w=1 transformed = true; } XVECTOR3 dir(gRSPlights[l].x - v.x, gRSPlights[l].y - v.y, gRSPlights[l].z - v.z); //XVECTOR3 dir(v.x-gRSPlights[l].x, v.y-gRSPlights[l].y, v.z-gRSPlights[l].z); float d2 = sqrtf(dir.x*dir.x+dir.y*dir.y+dir.z*dir.z); dir.x /= d2; dir.y /= d2; dir.z /= d2; fCosT = norm.x*dir.x + norm.y*dir.y + norm.z*dir.z; if (fCosT > 0 ) { //float f = d2/gRSPlights[l].range*50; float f = d2/15000*50; f = 1 - min(f,1); fCosT *= f*f; r += gRSPlights[l].fr * fCosT; g += gRSPlights[l].fg * fCosT; b += gRSPlights[l].fb * fCosT; } } } } if (r > 255) r = 255; if (g > 255) g = 255; if (b > 255) b = 255; return ((0xff000000)|(((uint32_t)r)<<16)|(((uint32_t)g)<<8)|((uint32_t)b)); } uint32_t LightVertNew(XVECTOR4 & norm) { // Do ambient register float r = gRSP.fAmbientLightR; register float g = gRSP.fAmbientLightG; register float b = gRSP.fAmbientLightB; for (register unsigned int l=0; l < gRSPnumLights; l++) { float fCosT = norm.x*gRSPlights[l].tx + norm.y*gRSPlights[l].ty + norm.z*gRSPlights[l].tz; if (fCosT > 0 ) { r += gRSPlights[l].fr * fCosT; g += gRSPlights[l].fg * fCosT; b += gRSPlights[l].fb * fCosT; } } if (r > 255) r = 255; if (g > 255) g = 255; if (b > 255) b = 255; return ((0xff000000)|(((uint32_t)r)<<16)|(((uint32_t)g)<<8)|((uint32_t)b)); } float zero = 0.0f; float onef = 1.0f; float fcosT; inline void ReplaceAlphaWithFogFactor(int i) { if( gRDP.geometryMode & G_FOG ) { // Use fog factor to replace vertex alpha if( g_vecProjected[i].z > 1 ) *(((uint8_t*)&(g_dwVtxDifColor[i]))+3) = 0xFF; if( g_vecProjected[i].z < 0 ) *(((uint8_t*)&(g_dwVtxDifColor[i]))+3) = 0; else *(((uint8_t*)&(g_dwVtxDifColor[i]))+3) = (uint8_t)(g_vecProjected[i].z*255); } } // Bits // +-+-+- // xxyyzz #define Z_NEG 0x01 #define Z_POS 0x02 #define Y_NEG 0x04 #define Y_POS 0x08 #define X_NEG 0x10 #define X_POS 0x20 // Assumes dwAddr has already been checked! // Don't inline - it's too big with the transform macros void ProcessVertexDataNoSSE(uint32_t dwAddr, uint32_t dwV0, uint32_t dwNum) { UpdateCombinedMatrix(); // This function is called upon SPvertex // - do vertex matrix transform // - do vertex lighting // - do texture coordinate transform if needed // - calculate normal vector // Output: - g_vecProjected[i] -> transformed vertex x,y,z // - g_vecProjected[i].w -> saved vertex 1/w // - g_dwVtxFlags[i] -> flags // - g_dwVtxDifColor[i] -> vertex color // - g_fVtxTxtCoords[i] -> vertex texture coordinates uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; FiddledVtx * pVtxBase = (FiddledVtx*)(rdram_u8 + dwAddr); g_pVtxBase = pVtxBase; for (uint32_t i = dwV0; i < dwV0 + dwNum; i++) { SP_Timing(RSP_GBI0_Vtx); FiddledVtx & vert = pVtxBase[i - dwV0]; g_vtxNonTransformed[i].x = (float)vert.x; g_vtxNonTransformed[i].y = (float)vert.y; g_vtxNonTransformed[i].z = (float)vert.z; Vec3Transform(&g_vtxTransformed[i], (XVECTOR3*)&g_vtxNonTransformed[i], &gRSPworldProject); // Convert to w=1 g_vecProjected[i].w = 1.0f / g_vtxTransformed[i].w; g_vecProjected[i].x = g_vtxTransformed[i].x * g_vecProjected[i].w; g_vecProjected[i].y = g_vtxTransformed[i].y * g_vecProjected[i].w; if ((g_curRomInfo.bPrimaryDepthHack || options.enableHackForGames == HACK_FOR_NASCAR ) && gRDP.otherMode.depth_source ) { g_vecProjected[i].z = gRDP.fPrimitiveDepth; g_vtxTransformed[i].z = gRDP.fPrimitiveDepth*g_vtxTransformed[i].w; } else { g_vecProjected[i].z = g_vtxTransformed[i].z * g_vecProjected[i].w; } if( gRSP.bFogEnabled ) { g_fFogCoord[i] = g_vecProjected[i].z; if( g_vecProjected[i].w < 0 || g_vecProjected[i].z < 0 || g_fFogCoord[i] < gRSPfFogMin ) g_fFogCoord[i] = gRSPfFogMin; } VTX_DUMP( { uint32_t *dat = (uint32_t*)(&vert); DebuggerAppendMsg("Vertex %d: %08X %08X %08X %08X", i, dat[0],dat[1],dat[2],dat[3]); DebuggerAppendMsg(" : %f, %f, %f, %f", g_vtxTransformed[i].x,g_vtxTransformed[i].y,g_vtxTransformed[i].z,g_vtxTransformed[i].w); DebuggerAppendMsg(" : %f, %f, %f, %f", g_vecProjected[i].x,g_vecProjected[i].y,g_vecProjected[i].z,g_vecProjected[i].w); }); RSP_Vtx_Clipping(i); if( gRSP.bLightingEnable ) { g_normal.x = (float)vert.norma.nx; g_normal.y = (float)vert.norma.ny; g_normal.z = (float)vert.norma.nz; Vec3TransformNormal(g_normal, gRSPmodelViewTop); g_dwVtxDifColor[i] = LightVert(g_normal, i); *(((uint8_t*)&(g_dwVtxDifColor[i]))+3) = vert.rgba.a; // still use alpha from the vertex } else { if( (gRDP.geometryMode & G_SHADE) == 0 && gRSP.ucode < 5 ) //Shade is disabled { //FLAT shade g_dwVtxDifColor[i] = gRDP.primitiveColor; } else { register IColor &color = *(IColor*)&g_dwVtxDifColor[i]; color.b = vert.rgba.r; color.g = vert.rgba.g; color.r = vert.rgba.b; color.a = vert.rgba.a; } } if( options.bWinFrameMode ) { g_dwVtxDifColor[i] = COLOR_RGBA(vert.rgba.r, vert.rgba.g, vert.rgba.b, vert.rgba.a); } ReplaceAlphaWithFogFactor(i); // Update texture coords n.b. need to divide tu/tv by bogus scale on addition to buffer // If the vertex is already lit, then there is no normal (and hence we // can't generate tex coord) if (gRSP.bTextureGen && gRSP.bLightingEnable ) { TexGen(g_fVtxTxtCoords[i].x, g_fVtxTxtCoords[i].y); } else { g_fVtxTxtCoords[i].x = (float)vert.tu; g_fVtxTxtCoords[i].y = (float)vert.tv; } } VTX_DUMP(TRACE2("Setting Vertexes: %d - %d\n", dwV0, dwV0+dwNum-1)); DEBUGGER_PAUSE_AND_DUMP(NEXT_VERTEX_CMD,{TRACE0("Paused at Vertex Command");}); } #ifdef __ARM_NEON__ /* NEON code */ #include "RenderBase_neon.h" extern "C" void pv_neon(XVECTOR4 *g_vtxTransformed, XVECTOR4 *g_vecProjected, uint32_t *g_dwVtxDifColor, VECTOR2 *g_fVtxTxtCoords, float *g_fFogCoord, uint32_t *g_clipFlag2, uint32_t dwNum, int neon_state, const FiddledVtx *vtx, const Light *gRSPlights, const float *fRSPAmbientLightRGBA, const XMATRIX *gRSPworldProject, const XMATRIX *gRSPmodelViewTop, uint32_t gRSPnumLights, float gRSPfFogMin, uint32_t primitiveColor, uint32_t primitiveColor_); extern "C" int tv_direction(const XVECTOR4 *v0, const XVECTOR4 *v1, const XVECTOR4 *v2); void ProcessVertexDataNEON(uint32_t dwAddr, uint32_t dwV0, uint32_t dwNum) { if (gRSP.bTextureGen && gRSP.bLightingEnable) { ProcessVertexDataNoSSE(dwAddr, dwV0,dwNum); return; } // assumtions: // - g_clipFlag is not used at all // - g_fFogCoord is not used at all // - g_vtxNonTransformed is not used after ProcessVertexData*() returns // - g_normal - same int neon_state = 0; if ( gRSP.bLightingEnable ) neon_state |= PV_NEON_ENABLE_LIGHT; if ( (gRDP.geometryMode & G_SHADE) || gRSP.ucode >= 5 ) neon_state |= PV_NEON_ENABLE_SHADE; if ( gRSP.bFogEnabled ) neon_state |= PV_NEON_ENABLE_FOG; if ( gRDP.geometryMode & G_FOG ) neon_state |= PV_NEON_FOG_ALPHA; uint32_t i; UpdateCombinedMatrix(); // This function is called upon SPvertex // - do vertex matrix transform // - do vertex lighting // - do texture cooridinate transform if needed // - calculate normal vector // Output: - g_vecProjected[i] -> transformed vertex x,y,z // - g_vecProjected[i].w -> saved vertex 1/w // - g_vtxTransformed[i] // - g_dwVtxDifColor[i] -> vertex color // - g_fVtxTxtCoords[i] -> vertex texture cooridinates // - g_fFogCoord[i] -> unused // - g_clipFlag2[i] uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; const FiddledVtx * pVtxBase = (const FiddledVtx*)(rdram_u8 + dwAddr); g_pVtxBase = (FiddledVtx *)pVtxBase; gRSPmodelViewTop._14 = gRSPmodelViewTop._24 = gRSPmodelViewTop._34 = 0; // SP_Timing(RSP_GBI0_Vtx); status.SPCycleCount += Timing_RSP_GBI0_Vtx * dwNum; #if 1 i = dwV0; pv_neon(&g_vtxTransformed[i], &g_vecProjected[i], &g_dwVtxDifColor[i], &g_fVtxTxtCoords[i], &g_fFogCoord[i], &g_clipFlag2[i], dwNum, neon_state, &pVtxBase[i - dwV0], gRSPlights, gRSP.fAmbientColors, &gRSPworldProject, &gRSPmodelViewTop, gRSPnumLights, gRSPfFogMin, gRDP.primitiveColor, gRDP.primitiveColor); #else for (i = dwV0; i < dwV0 + dwNum; i++) { const FiddledVtx & vert = pVtxBase[i - dwV0]; XVECTOR3 vtx_raw; // was g_vtxNonTransformed vtx_raw.x = (float)vert.x; vtx_raw.y = (float)vert.y; vtx_raw.z = (float)vert.z; Vec3Transform(&g_vtxTransformed[i], &vtx_raw, &gRSPworldProject); // Convert to w=1 g_vecProjected[i].w = 1.0f / g_vtxTransformed[i].w; g_vecProjected[i].x = g_vtxTransformed[i].x * g_vecProjected[i].w; g_vecProjected[i].y = g_vtxTransformed[i].y * g_vecProjected[i].w; g_vecProjected[i].z = g_vtxTransformed[i].z * g_vecProjected[i].w; // RSP_Vtx_Clipping(i); g_clipFlag2[i] = 0; if( g_vecProjected[i].w > 0 ) { if( g_vecProjected[i].x > 1 ) g_clipFlag2[i] |= X_CLIP_MAX; if( g_vecProjected[i].x < -1 ) g_clipFlag2[i] |= X_CLIP_MIN; if( g_vecProjected[i].y > 1 ) g_clipFlag2[i] |= Y_CLIP_MAX; if( g_vecProjected[i].y < -1 ) g_clipFlag2[i] |= Y_CLIP_MIN; } if( neon_state & PV_NEON_ENABLE_LIGHT ) { XVECTOR3 normal; // was g_normal float r, g, b; normal.x = (float)vert.norma.nx; normal.y = (float)vert.norma.ny; normal.z = (float)vert.norma.nz; Vec3TransformNormal(normal, gRSPmodelViewTop); r = gRSP.fAmbientLightR; g = gRSP.fAmbientLightG; b = gRSP.fAmbientLightB; for (unsigned int l=0; l < gRSPnumLights; l++) { float fCosT = normal.x * gRSPlights[l].x + normal.y * gRSPlights[l].y + normal.z * gRSPlights[l].z; if (fCosT > 0 ) { r += gRSPlights[l].fr * fCosT; g += gRSPlights[l].fg * fCosT; b += gRSPlights[l].fb * fCosT; } } if (r > 255) r = 255; if (g > 255) g = 255; if (b > 255) b = 255; g_dwVtxDifColor[i] = ((vert.rgba.a<<24)|(((uint32_t)r)<<16)|(((uint32_t)g)<<8)|((uint32_t)b)); } else if( neon_state & PV_NEON_ENABLE_SHADE ) { IColor &color = *(IColor*)&g_dwVtxDifColor[i]; color.b = vert.rgba.r; color.g = vert.rgba.g; color.r = vert.rgba.b; color.a = vert.rgba.a; } else g_dwVtxDifColor[i] = gRDP.primitiveColor; // FLAT shade // ReplaceAlphaWithFogFactor(i); if( neon_state & PV_NEON_FOG_ALPHA ) { // Use fog factor to replace vertex alpha if( g_vecProjected[i].z > 1 ) *(((uint8*)&(g_dwVtxDifColor[i]))+3) = 0xFF; // missing 'else' in original code?? else if( g_vecProjected[i].z < 0 ) *(((uint8*)&(g_dwVtxDifColor[i]))+3) = 0; else *(((uint8*)&(g_dwVtxDifColor[i]))+3) = (uint8)(g_vecProjected[i].z*255); } g_fVtxTxtCoords[i].x = (float)vert.tu; g_fVtxTxtCoords[i].y = (float)vert.tv; } #endif } #endif bool PrepareTriangle(uint32_t dwV0, uint32_t dwV1, uint32_t dwV2) { SP_Timing(SP_Each_Triangle); bool textureFlag = (CRender::g_pRender->IsTextureEnabled() || gRSP.ucode == 6 ); InitVertex(dwV0, gRSP.numVertices, textureFlag); InitVertex(dwV1, gRSP.numVertices+1, textureFlag); InitVertex(dwV2, gRSP.numVertices+2, textureFlag); if(gRSP.numVertices == 0 && g_curRomInfo.bEnableTxtLOD && gRDP.otherMode.text_lod) { if( CRender::g_pRender->IsTexel1Enable() && CRender::g_pRender->m_pColorCombiner->m_pDecodedMux->IsUsed(MUX_LODFRAC, MUX_MASK) ) { ComputeLOD(); } else { gRDP.LODFrac = 0; } } gRSP.numVertices += 3; status.dwNumTrisRendered++; return true; } // Returns TRUE if it thinks the triangle is visible // Returns FALSE if it is clipped bool IsTriangleVisible(uint32_t dwV0, uint32_t dwV1, uint32_t dwV2) { //return true; //fix me DEBUGGER_ONLY_IF( (!debuggerEnableTestTris || !debuggerEnableCullFace), {return TRUE;}); #ifdef DEBUGGER // Check vertices are valid! if (dwV0 >= MAX_VERTS || dwV1 >= MAX_VERTS || dwV2 >= MAX_VERTS) return false; #endif // Here we AND all the flags. If any of the bits is set for all // 3 vertices, it means that all three x, y or z lie outside of // the current viewing volume. // Currently disabled - still seems a bit dodgy if ((gRSP.bCullFront || gRSP.bCullBack) && gRDP.otherMode.zmode != 3) { XVECTOR4 & v0 = g_vecProjected[dwV0]; XVECTOR4 & v1 = g_vecProjected[dwV1]; XVECTOR4 & v2 = g_vecProjected[dwV2]; // Only try to clip if the tri is onscreen. For some reason, this // method doesn't work well when the z value is outside of screenspace //if (v0.z < 1 && v1.z < 1 && v2.z < 1) { #ifndef __ARM_NEON__ float V1 = v2.x - v0.x; float V2 = v2.y - v0.y; float W1 = v2.x - v1.x; float W2 = v2.y - v1.y; float fDirection = (V1 * W2) - (V2 * W1); fDirection = fDirection * v1.w * v2.w * v0.w; //float fDirection = v0.x*v1.y-v1.x*v0.y+v1.x*v2.y-v2.x*v1.y+v2.x*v0.y-v0.x*v2.y; #else // really returns float, but we only need sign int fDirection = tv_direction(&v0, &v1, &v2); #endif if (fDirection < 0 && gRSP.bCullBack) { status.dwNumTrisClipped++; return false; } else if (fDirection > 0 && gRSP.bCullFront) { status.dwNumTrisClipped++; return false; } } } #ifdef ENABLE_CLIP_TRI //if( gRSP.bRejectVtx && (g_clipFlag[dwV0]|g_clipFlag[dwV1]|g_clipFlag[dwV2]) ) // return; if( g_clipFlag2[dwV0]&g_clipFlag2[dwV1]&g_clipFlag2[dwV2] ) { //DebuggerAppendMsg("Clipped"); return false; } #endif return true; } void SetPrimitiveColor(uint32_t dwCol, uint32_t LODMin, uint32_t LODFrac) { gRDP.colorsAreReloaded = true; gRDP.primitiveColor = dwCol; gRDP.primLODMin = LODMin; gRDP.primLODFrac = LODFrac; if( gRDP.primLODFrac < gRDP.primLODMin ) { gRDP.primLODFrac = gRDP.primLODMin; } gRDP.fvPrimitiveColor[0] = ((dwCol>>16)&0xFF)/255.0f; // R gRDP.fvPrimitiveColor[1] = ((dwCol>>8)&0xFF)/255.0f; // G gRDP.fvPrimitiveColor[2] = ((dwCol)&0xFF)/255.0f; // B gRDP.fvPrimitiveColor[3] = ((dwCol>>24)&0xFF)/255.0f; // A } void SetPrimitiveDepth(uint32_t z, uint32_t dwDZ) { gRDP.primitiveDepth = z & 0x7FFF; gRDP.fPrimitiveDepth = (float)(gRDP.primitiveDepth)/(float)0x8000; //gRDP.fPrimitiveDepth = gRDP.fPrimitiveDepth*2-1; /* z=0xFFFF -> 1 the farthest z=0 -> -1 the nearest */ // TODO: How to use dwDZ? #ifdef DEBUGGER if( (pauseAtNext && (eventToPause == NEXT_VERTEX_CMD || eventToPause == NEXT_FLUSH_TRI )) )//&& logTriangles ) { DebuggerAppendMsg("Set prim Depth: %f, (%08X, %08X)", gRDP.fPrimitiveDepth, z, dwDZ); } #endif } void SetVertexXYZ(uint32_t vertex, float x, float y, float z) { g_vecProjected[vertex].x = x; g_vecProjected[vertex].y = y; g_vecProjected[vertex].z = z; g_vtxTransformed[vertex].x = x*g_vtxTransformed[vertex].w; g_vtxTransformed[vertex].y = y*g_vtxTransformed[vertex].w; g_vtxTransformed[vertex].z = z*g_vtxTransformed[vertex].w; } void ModifyVertexInfo(uint32_t where, uint32_t vertex, uint32_t val) { switch (where) { case RSP_MV_WORD_OFFSET_POINT_RGBA: // Modify RGBA { uint32_t r = (val>>24)&0xFF; uint32_t g = (val>>16)&0xFF; uint32_t b = (val>>8)&0xFF; uint32_t a = val&0xFF; g_dwVtxDifColor[vertex] = COLOR_RGBA(r, g, b, a); LOG_UCODE("Modify vertex %d color, 0x%08x", vertex, g_dwVtxDifColor[vertex]); } break; case RSP_MV_WORD_OFFSET_POINT_XYSCREEN: // Modify X,Y { uint16_t nX = (uint16_t)(val>>16); short x = *((short*)&nX); x /= 4; uint16_t nY = (uint16_t)(val&0xFFFF); short y = *((short*)&nY); y /= 4; // Should do viewport transform. x -= windowSetting.uViWidth/2; y = windowSetting.uViHeight/2-y; if( options.bEnableHacks && ((*gfx_info.VI_X_SCALE_REG)&0xF) != 0 ) { // Tarzan // I don't know why Tarzan is different SetVertexXYZ(vertex, x/windowSetting.fViWidth, y/windowSetting.fViHeight, g_vecProjected[vertex].z); } else { // Toy Story 2 and other games SetVertexXYZ(vertex, x*2/windowSetting.fViWidth, y*2/windowSetting.fViHeight, g_vecProjected[vertex].z); } LOG_UCODE("Modify vertex %d: x=%d, y=%d", vertex, x, y); VTX_DUMP(TRACE3("Modify vertex %d: (%d,%d)", vertex, x, y)); } break; case RSP_MV_WORD_OFFSET_POINT_ZSCREEN: // Modify C { int z = val>>16; SetVertexXYZ(vertex, g_vecProjected[vertex].x, g_vecProjected[vertex].y, (((float)z/0x03FF)+0.5f)/2.0f ); LOG_UCODE("Modify vertex %d: z=%d", vertex, z); VTX_DUMP(TRACE2("Modify vertex %d: z=%d", vertex, z)); } break; case RSP_MV_WORD_OFFSET_POINT_ST: // Texture { short tu = short(val>>16); short tv = short(val & 0xFFFF); float ftu = tu / 32.0f; float ftv = tv / 32.0f; LOG_UCODE(" Setting vertex %d tu/tv to %f, %f", vertex, (float)tu, (float)tv); CRender::g_pRender->SetVtxTextureCoord(vertex, ftu/gRSP.fTexScaleX, ftv/gRSP.fTexScaleY); } break; } DEBUGGER_PAUSE_AND_DUMP(NEXT_VERTEX_CMD,{TRACE0("Paused at ModVertex Command");}); } void ProcessVertexDataDKR(uint32_t dwAddr, uint32_t dwV0, uint32_t dwNum) { UpdateCombinedMatrix(); uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; long long pVtxBase = (long long) (rdram_u8 + dwAddr); g_pVtxBase = (FiddledVtx*)pVtxBase; Matrix &matWorldProject = gRSP.DKRMatrixes[gRSP.DKRCMatrixIndex]; bool addbase=false; if ((!gRSP.DKRBillBoard) || (gRSP.DKRCMatrixIndex != 2) ) addbase = false; else addbase = true; if( addbase && gRSP.DKRVtxCount == 0 && dwNum > 1 ) { gRSP.DKRVtxCount++; } LOG_UCODE(" ProcessVertexDataDKR, CMatrix = %d, Add base=%s", gRSP.DKRCMatrixIndex, gRSP.DKRBillBoard?"true":"false"); VTX_DUMP(TRACE2("DKR Setting Vertexes\nCMatrix = %d, Add base=%s", gRSP.DKRCMatrixIndex, gRSP.DKRBillBoard?"true":"false")); int nOff = 0; uint32_t end = dwV0 + dwNum; for (uint32_t i = dwV0; i < end; i++) { XVECTOR3 w; g_vtxNonTransformed[i].x = (float)*(short*)((pVtxBase+nOff + 0) ^ 2); g_vtxNonTransformed[i].y = (float)*(short*)((pVtxBase+nOff + 2) ^ 2); g_vtxNonTransformed[i].z = (float)*(short*)((pVtxBase+nOff + 4) ^ 2); Vec3Transform(&g_vtxTransformed[i], (XVECTOR3*)&g_vtxNonTransformed[i], &matWorldProject); // Convert to w=1 if( gRSP.DKRVtxCount == 0 && dwNum==1 ) { gRSP.DKRBaseVec.x = g_vtxTransformed[i].x; gRSP.DKRBaseVec.y = g_vtxTransformed[i].y; gRSP.DKRBaseVec.z = g_vtxTransformed[i].z; gRSP.DKRBaseVec.w = g_vtxTransformed[i].w; } else if( addbase ) { g_vtxTransformed[i].x += gRSP.DKRBaseVec.x; g_vtxTransformed[i].y += gRSP.DKRBaseVec.y; g_vtxTransformed[i].z += gRSP.DKRBaseVec.z; g_vtxTransformed[i].w = gRSP.DKRBaseVec.w; } g_vecProjected[i].w = 1.0f / g_vtxTransformed[i].w; g_vecProjected[i].x = g_vtxTransformed[i].x * g_vecProjected[i].w; g_vecProjected[i].y = g_vtxTransformed[i].y * g_vecProjected[i].w; g_vecProjected[i].z = g_vtxTransformed[i].z * g_vecProjected[i].w; gRSP.DKRVtxCount++; VTX_DUMP(TRACE5("Vertex %d: %f, %f, %f, %f", i, g_vtxTransformed[i].x,g_vtxTransformed[i].y,g_vtxTransformed[i].z,g_vtxTransformed[i].w)); if( gRSP.bFogEnabled ) { g_fFogCoord[i] = g_vecProjected[i].z; if( g_vecProjected[i].w < 0 || g_vecProjected[i].z < 0 || g_fFogCoord[i] < gRSPfFogMin ) g_fFogCoord[i] = gRSPfFogMin; } RSP_Vtx_Clipping(i); short wA = *(short*)((pVtxBase+nOff + 6) ^ 2); short wB = *(short*)((pVtxBase+nOff + 8) ^ 2); int8_t r = (int8_t)(wA >> 8); int8_t g = (int8_t)(wA); int8_t b = (int8_t)(wB >> 8); int8_t a = (int8_t)(wB); if (gRSP.bLightingEnable) { g_normal.x = (char)r; //norma.nx; g_normal.y = (char)g; //norma.ny; g_normal.z = (char)b; //norma.nz; Vec3TransformNormal(g_normal, matWorldProject) g_dwVtxDifColor[i] = LightVert(g_normal, i); } else { int nR = r; int nG = g; int nB = b; int nA = a; // Assign true vert colour after lighting/fogging g_dwVtxDifColor[i] = COLOR_RGBA(nR, nG, nB, nA); } ReplaceAlphaWithFogFactor(i); g_fVtxTxtCoords[i].x = g_fVtxTxtCoords[i].y = 1; nOff += 10; } DEBUGGER_PAUSE_AND_DUMP(NEXT_VERTEX_CMD,{DebuggerAppendMsg("Paused at DKR Vertex Command, v0=%d, vn=%d, addr=%08X", dwV0, dwNum, dwAddr);}); } extern uint32_t dwPDCIAddr; void ProcessVertexDataPD(uint32_t dwAddr, uint32_t dwV0, uint32_t dwNum) { UpdateCombinedMatrix(); uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; N64VtxPD * pVtxBase = (N64VtxPD*)(rdram_u8 + dwAddr); g_pVtxBase = (FiddledVtx*)pVtxBase; // Fix me for (uint32_t i = dwV0; i < dwV0 + dwNum; i++) { N64VtxPD &vert = pVtxBase[i - dwV0]; g_vtxNonTransformed[i].x = (float)vert.x; g_vtxNonTransformed[i].y = (float)vert.y; g_vtxNonTransformed[i].z = (float)vert.z; { Vec3Transform(&g_vtxTransformed[i], (XVECTOR3*)&g_vtxNonTransformed[i], &gRSPworldProject); // Convert to w=1 g_vecProjected[i].w = 1.0f / g_vtxTransformed[i].w; g_vecProjected[i].x = g_vtxTransformed[i].x * g_vecProjected[i].w; g_vecProjected[i].y = g_vtxTransformed[i].y * g_vecProjected[i].w; g_vecProjected[i].z = g_vtxTransformed[i].z * g_vecProjected[i].w; } g_fFogCoord[i] = g_vecProjected[i].z; if( g_vecProjected[i].w < 0 || g_vecProjected[i].z < 0 || g_fFogCoord[i] < gRSPfFogMin ) g_fFogCoord[i] = gRSPfFogMin; RSP_Vtx_Clipping(i); uint8_t *addr = rdram_u8 + dwPDCIAddr + (vert.cidx&0xFF); uint32_t a = addr[0]; uint32_t r = addr[3]; uint32_t g = addr[2]; uint32_t b = addr[1]; if( gRSP.bLightingEnable ) { g_normal.x = (char)r; g_normal.y = (char)g; g_normal.z = (char)b; { Vec3TransformNormal(g_normal, gRSPmodelViewTop); g_dwVtxDifColor[i] = LightVert(g_normal, i); } *(((uint8_t*)&(g_dwVtxDifColor[i]))+3) = (uint8_t)a; // still use alpha from the vertex } else { if( (gRDP.geometryMode & G_SHADE) == 0 && gRSP.ucode < 5 ) //Shade is disabled { g_dwVtxDifColor[i] = gRDP.primitiveColor; } else //FLAT shade { g_dwVtxDifColor[i] = COLOR_RGBA(r, g, b, a); } } if( options.bWinFrameMode ) { g_dwVtxDifColor[i] = COLOR_RGBA(r, g, b, a); } ReplaceAlphaWithFogFactor(i); VECTOR2 & t = g_fVtxTxtCoords[i]; if (gRSP.bTextureGen && gRSP.bLightingEnable ) { // Not sure if we should transform the normal here //Matrix & matWV = gRSP.projectionMtxs[gRSP.projectionMtxTop]; //Vec3TransformNormal(g_normal, matWV); TexGen(g_fVtxTxtCoords[i].x, g_fVtxTxtCoords[i].y); } else { t.x = vert.s; t.y = vert.t; } VTX_DUMP( { DebuggerAppendMsg("Vertex %d: %d %d %d", i, vert.x,vert.y,vert.z); DebuggerAppendMsg(" : %f, %f, %f, %f", g_vtxTransformed[i].x,g_vtxTransformed[i].y,g_vtxTransformed[i].z,g_vtxTransformed[i].w); DebuggerAppendMsg(" : %X, %X, %X, %X", r,g,b,a); DebuggerAppendMsg(" : u=%f, v=%f", t.x, t.y); }); } VTX_DUMP(TRACE2("Setting Vertexes: %d - %d\n", dwV0, dwV0+dwNum-1)); DEBUGGER_PAUSE_AND_DUMP(NEXT_VERTEX_CMD,{TRACE0("Paused at Vertex Command");}); } extern uint32_t dwConkerVtxZAddr; void ProcessVertexDataConker(uint32_t dwAddr, uint32_t dwV0, uint32_t dwNum) { UpdateCombinedMatrix(); uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; FiddledVtx * pVtxBase = (FiddledVtx*)(rdram_u8 + dwAddr); g_pVtxBase = pVtxBase; for (uint32_t i = dwV0; i < dwV0 + dwNum; i++) { SP_Timing(RSP_GBI0_Vtx); FiddledVtx & vert = pVtxBase[i - dwV0]; g_vtxNonTransformed[i].x = (float)vert.x; g_vtxNonTransformed[i].y = (float)vert.y; g_vtxNonTransformed[i].z = (float)vert.z; { Vec3Transform(&g_vtxTransformed[i], (XVECTOR3*)&g_vtxNonTransformed[i], &gRSPworldProject); // Convert to w=1 g_vecProjected[i].w = 1.0f / g_vtxTransformed[i].w; g_vecProjected[i].x = g_vtxTransformed[i].x * g_vecProjected[i].w; g_vecProjected[i].y = g_vtxTransformed[i].y * g_vecProjected[i].w; g_vecProjected[i].z = g_vtxTransformed[i].z * g_vecProjected[i].w; } g_fFogCoord[i] = g_vecProjected[i].z; if( g_vecProjected[i].w < 0 || g_vecProjected[i].z < 0 || g_fFogCoord[i] < gRSPfFogMin ) g_fFogCoord[i] = gRSPfFogMin; VTX_DUMP( { uint32_t *dat = (uint32_t*)(&vert); DebuggerAppendMsg("Vertex %d: %08X %08X %08X %08X", i, dat[0],dat[1],dat[2],dat[3]); DebuggerAppendMsg(" : %f, %f, %f, %f", g_vtxTransformed[i].x,g_vtxTransformed[i].y,g_vtxTransformed[i].z,g_vtxTransformed[i].w); DebuggerAppendMsg(" : %f, %f, %f, %f", g_vecProjected[i].x,g_vecProjected[i].y,g_vecProjected[i].z,g_vecProjected[i].w); }); RSP_Vtx_Clipping(i); if( gRSP.bLightingEnable ) { { uint32_t r= ((gRSP.ambientLightColor>>16)&0xFF); uint32_t g= ((gRSP.ambientLightColor>> 8)&0xFF); uint32_t b= ((gRSP.ambientLightColor )&0xFF); for( uint32_t k=1; k<=gRSPnumLights; k++) { r += gRSPlights[k].r; g += gRSPlights[k].g; b += gRSPlights[k].b; } if( r>255 ) r=255; if( g>255 ) g=255; if( b>255 ) b=255; r *= vert.rgba.r ; g *= vert.rgba.g ; b *= vert.rgba.b ; r >>= 8; g >>= 8; b >>= 8; g_dwVtxDifColor[i] = 0xFF000000; g_dwVtxDifColor[i] |= (r<<16); g_dwVtxDifColor[i] |= (g<< 8); g_dwVtxDifColor[i] |= (b ); } *(((uint8_t*)&(g_dwVtxDifColor[i]))+3) = vert.rgba.a; // still use alpha from the vertex } else { if( (gRDP.geometryMode & G_SHADE) == 0 && gRSP.ucode < 5 ) //Shade is disabled { g_dwVtxDifColor[i] = gRDP.primitiveColor; } else //FLAT shade { g_dwVtxDifColor[i] = COLOR_RGBA(vert.rgba.r, vert.rgba.g, vert.rgba.b, vert.rgba.a); } } if( options.bWinFrameMode ) { //g_vecProjected[i].z = 0; g_dwVtxDifColor[i] = COLOR_RGBA(vert.rgba.r, vert.rgba.g, vert.rgba.b, vert.rgba.a); } ReplaceAlphaWithFogFactor(i); // Update texture coords n.b. need to divide tu/tv by bogus scale on addition to buffer //VECTOR2 & t = g_fVtxTxtCoords[i]; // If the vert is already lit, then there is no normal (and hence we // can't generate tex coord) if (gRSP.bTextureGen && gRSP.bLightingEnable ) { g_normal.x = (float)*(int8_t*)(rdram_u8 + (((i<<1)+0)^3)+dwConkerVtxZAddr); g_normal.y = (float)*(int8_t*)(rdram_u8 + (((i<<1)+1)^3)+dwConkerVtxZAddr); g_normal.z = (float)*(int8_t*)(rdram_u8 + (((i<<1)+2)^3)+dwConkerVtxZAddr); Vec3TransformNormal(g_normal, gRSPmodelViewTop); TexGen(g_fVtxTxtCoords[i].x, g_fVtxTxtCoords[i].y); } else { g_fVtxTxtCoords[i].x = (float)vert.tu; g_fVtxTxtCoords[i].y = (float)vert.tv; } } VTX_DUMP(TRACE2("Setting Vertexes: %d - %d\n", dwV0, dwV0+dwNum-1)); DEBUGGER_PAUSE_AND_DUMP(NEXT_VERTEX_CMD,{DebuggerAppendMsg("Paused at Vertex Command");}); } typedef struct { short y; short x; short flag; short z; } RS_Vtx_XYZ; typedef union { struct { uint8_t a; uint8_t b; uint8_t g; uint8_t r; }; struct { char na; // A char nz; // B char ny; // G char nx; // R }; } RS_Vtx_Color; void ProcessVertexData_Rogue_Squadron(uint32_t dwXYZAddr, uint32_t dwColorAddr, uint32_t dwXYZCmd, uint32_t dwColorCmd) { UpdateCombinedMatrix(); uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; uint32_t dwV0 = 0; uint32_t dwNum = (dwXYZCmd&0xFF00)>>10; RS_Vtx_XYZ * pVtxXYZBase = (RS_Vtx_XYZ*)(rdram_u8 + dwXYZAddr); RS_Vtx_Color * pVtxColorBase = (RS_Vtx_Color*)(rdram_u8 + dwColorAddr); for (uint32_t i = dwV0; i < dwV0 + dwNum; i++) { RS_Vtx_XYZ & vertxyz = pVtxXYZBase[i - dwV0]; RS_Vtx_Color & vertcolors = pVtxColorBase[i - dwV0]; g_vtxNonTransformed[i].x = (float)vertxyz.x; g_vtxNonTransformed[i].y = (float)vertxyz.y; g_vtxNonTransformed[i].z = (float)vertxyz.z; { Vec3Transform(&g_vtxTransformed[i], (XVECTOR3*)&g_vtxNonTransformed[i], &gRSPworldProject); // Convert to w=1 g_vecProjected[i].w = 1.0f / g_vtxTransformed[i].w; g_vecProjected[i].x = g_vtxTransformed[i].x * g_vecProjected[i].w; g_vecProjected[i].y = g_vtxTransformed[i].y * g_vecProjected[i].w; g_vecProjected[i].z = g_vtxTransformed[i].z * g_vecProjected[i].w; } VTX_DUMP( { DebuggerAppendMsg(" : %f, %f, %f, %f", g_vtxTransformed[i].x,g_vtxTransformed[i].y,g_vtxTransformed[i].z,g_vtxTransformed[i].w); DebuggerAppendMsg(" : %f, %f, %f, %f", g_vecProjected[i].x,g_vecProjected[i].y,g_vecProjected[i].z,g_vecProjected[i].w); }); g_fFogCoord[i] = g_vecProjected[i].z; if( g_vecProjected[i].w < 0 || g_vecProjected[i].z < 0 || g_fFogCoord[i] < gRSPfFogMin ) g_fFogCoord[i] = gRSPfFogMin; RSP_Vtx_Clipping(i); if( gRSP.bLightingEnable ) { g_normal.x = (float)vertcolors.nx; g_normal.y = (float)vertcolors.ny; g_normal.z = (float)vertcolors.nz; { Vec3TransformNormal(g_normal, gRSPmodelViewTop); g_dwVtxDifColor[i] = LightVert(g_normal, i); } *(((uint8_t*)&(g_dwVtxDifColor[i]))+3) = vertcolors.a; // still use alpha from the vertex } else { if( (gRDP.geometryMode & G_SHADE) == 0 && gRSP.ucode < 5 ) //Shade is disabled { g_dwVtxDifColor[i] = gRDP.primitiveColor; } else //FLAT shade { g_dwVtxDifColor[i] = COLOR_RGBA(vertcolors.r, vertcolors.g, vertcolors.b, vertcolors.a); } } if( options.bWinFrameMode ) { g_dwVtxDifColor[i] = COLOR_RGBA(vertcolors.r, vertcolors.g, vertcolors.b, vertcolors.a); } ReplaceAlphaWithFogFactor(i); /* // Update texture coords n.b. need to divide tu/tv by bogus scale on addition to buffer VECTOR2 & t = g_fVtxTxtCoords[i]; // If the vert is already lit, then there is no normal (and hence we // can't generate tex coord) if (gRSP.bTextureGen && gRSP.bLightingEnable && g_textures[gRSP.curTile].m_bTextureEnable ) { TexGen(g_fVtxTxtCoords[i].x, g_fVtxTxtCoords[i].y); } else { t.x = (float)vert.tu; t.y = (float)vert.tv; } */ } VTX_DUMP(TRACE2("Setting Vertexes: %d - %d\n", dwV0, dwV0+dwNum-1)); DEBUGGER_PAUSE_AND_DUMP(NEXT_VERTEX_CMD,{TRACE0("Paused at Vertex Cmd");}); } void SetLightCol(uint32_t dwLight, uint32_t dwCol) { gRSPlights[dwLight].r = (uint8_t)((dwCol >> 24)&0xFF); gRSPlights[dwLight].g = (uint8_t)((dwCol >> 16)&0xFF); gRSPlights[dwLight].b = (uint8_t)((dwCol >> 8)&0xFF); gRSPlights[dwLight].a = 255; // Ignore light alpha gRSPlights[dwLight].fr = (float)gRSPlights[dwLight].r; gRSPlights[dwLight].fg = (float)gRSPlights[dwLight].g; gRSPlights[dwLight].fb = (float)gRSPlights[dwLight].b; gRSPlights[dwLight].fa = 255; // Ignore light alpha //TRACE1("Set light %d color", dwLight); LIGHT_DUMP(TRACE2("Set Light %d color: %08X", dwLight, dwCol)); } void SetLightDirection(uint32_t dwLight, float x, float y, float z, float range) { //gRSP.bLightIsUpdated = true; //gRSPlights[dwLight].ox = x; //gRSPlights[dwLight].oy = y; //gRSPlights[dwLight].oz = z; register float w = range == 0 ? (float)sqrt(x*x+y*y+z*z) : 1; gRSPlights[dwLight].x = x/w; gRSPlights[dwLight].y = y/w; gRSPlights[dwLight].z = z/w; gRSPlights[dwLight].range = range; DEBUGGER_PAUSE_AND_DUMP(NEXT_SET_LIGHT,TRACE5("Set Light %d dir: %.4f, %.4f, %.4f, %.4f", dwLight, x, y, z, range)); } static float maxS0, maxT0; static float maxS1, maxT1; static bool validS0, validT0; static bool validS1, validT1; void LogTextureCoords(float fTex0S, float fTex0T, float fTex1S, float fTex1T) { if( validS0 ) { if( fTex0S<0 || fTex0S>maxS0 ) validS0 = false; } if( validT0 ) { if( fTex0T<0 || fTex0T>maxT0 ) validT0 = false; } if( validS1 ) { if( fTex1S<0 || fTex1S>maxS1 ) validS1 = false; } if( validT1 ) { if( fTex1T<0 || fTex1T>maxT1 ) validT1 = false; } } bool CheckTextureCoords(int tex) { if( tex==0 ) { return validS0&&validT0; } else { return validS1&&validT1; } } void ResetTextureCoordsLog(float maxs0, float maxt0, float maxs1, float maxt1) { maxS0 = maxs0; maxT0 = maxt0; maxS1 = maxs1; maxT1 = maxt1; validS0 = validT0 = true; validS1 = validT1 = true; } void ForceMainTextureIndex(int dwTile) { if( dwTile == 1 && !(CRender::g_pRender->IsTexel0Enable()) && CRender::g_pRender->IsTexel1Enable() ) { // Hack gRSP.curTile = 0; } else { gRSP.curTile = dwTile; } } float HackZ2(float z) { z = (z+9)/10; return z; } float HackZ(float z) { /* TODO - investigate * should we just do this instead? * z = HackZ2(z); */ return HackZ2(z); if( z < 0.1 && z >= 0 ) z = (.1f+z)/2; else if( z < 0 ) //return (10+z)/100; z = (expf(z)/20); return z; } void HackZ(std::vector& points) { int size = points.size(); for( int i=0; i #include #include #ifdef __cplusplus extern "C" { #endif static thread_local ucontext_t co_primary; static thread_local ucontext_t *co_running = 0; cothread_t co_active(void) { if (!co_running) co_running = &co_primary; return (cothread_t)co_running; } cothread_t co_create(unsigned int heapsize, void (*coentry)(void)) { if (!co_running) co_running = &co_primary; ucontext_t *thread = (ucontext_t*)malloc(sizeof(ucontext_t)); if(thread) { if((!getcontext(thread) && !(thread->uc_stack.ss_sp = 0)) && (thread->uc_stack.ss_sp = malloc(heapsize))) { thread->uc_link = co_running; thread->uc_stack.ss_size = heapsize; makecontext(thread, coentry, 0); } else { co_delete((cothread_t)thread); thread = 0; } } return (cothread_t)thread; } void co_delete(cothread_t cothread) { if (!cothread) return; if(((ucontext_t*)cothread)->uc_stack.ss_sp) free(((ucontext_t*)cothread)->uc_stack.ss_sp); free(cothread); } void co_switch(cothread_t cothread) { ucontext_t *old_thread = co_running; co_running = (ucontext_t*)cothread; swapcontext(old_thread, co_running); } #ifdef __cplusplus } #endif gles2rice/src/RSP_S2DEX.cpp000664 001750 001750 00000036715 12655644434 016456 0ustar00sergiosergio000000 000000 /* Copyright (C) 2002 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // This file implements the S2DEX microcode. Yoshi's Story is using this microcode. #include #include "UcodeDefs.h" #include "Render.h" #include "Timing.h" uObjTxtr *gObjTxtr = NULL; uObjTxtrTLUT *gObjTlut = NULL; uint32_t gObjTlutAddr = 0; uObjMtx *gObjMtx = NULL; uObjSubMtx *gSubObjMtx = NULL; uObjMtxReal gObjMtxReal = {1, 0, 0, 1, 0, 0, 0, 0}; Matrix g_MtxReal(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1); uint32_t g_TxtLoadBy = CMD_LOAD_OBJ_TXTR; // Yoshi's Story uses this - 0x02 void RSP_S2DEX_BG_COPY(Gfx *gfx) { SP_Timing(DP_Minimal16); DP_Timing(DP_Minimal16); uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; uint32_t dwAddr = RSPSegmentAddr((gfx->words.w1)); uObjBg *sbgPtr = (uObjBg*)(rdram_u8 + dwAddr); CRender::g_pRender->LoadObjBGCopy(*sbgPtr); CRender::g_pRender->DrawObjBGCopy(*sbgPtr); } // Yoshi's Story uses this - 0x03 void RSP_S2DEX_OBJ_RECTANGLE(Gfx *gfx) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; uint32_t dwAddr = RSPSegmentAddr((gfx->words.w1)); uObjSprite *ptr = (uObjSprite*)(rdram_u8 + dwAddr); uObjTxSprite objtx; memcpy(&objtx.sprite,ptr,sizeof(uObjSprite)); if( g_TxtLoadBy == CMD_LOAD_OBJ_TXTR ) { memcpy(&(objtx.txtr.block),&(gObjTxtr->block),sizeof(uObjTxtr)); CRender::g_pRender->LoadObjSprite(objtx, true); } else { PrepareTextures(); } CRender::g_pRender->DrawSprite(objtx, false); #ifdef DEBUGGER if( (pauseAtNext && (eventToPause == NEXT_OBJ_TXT_CMD||eventToPause == NEXT_FLUSH_TRI)) || logTextures ) { if( debuggerPauseCount > 0 ) debuggerPauseCount--; if( debuggerPauseCount == 0 ) { eventToPause = false; debuggerPause = true; TRACE3("Paused at RSP_S2DEX_OBJ_RECTANGLE\nptr=%08X, img=%08X, TMEM=%08X", dwAddr,objtx.txtr.block.image, ptr->imageAdrs); CGraphicsContext::g_pGraphicsContext->UpdateFrame(false); } } #endif } // Yoshi's Story uses this - 0x04 void RSP_S2DEX_OBJ_SPRITE(Gfx *gfx) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; uint32_t dwAddr = RSPSegmentAddr((gfx->words.w1)); uObjSprite *info = (uObjSprite*)(rdram_u8 + dwAddr); uint32_t dwTile = gRSP.curTile; status.bAllowLoadFromTMEM = false; // Because we need to use TLUT loaded by the ObjTlut command PrepareTextures(); status.bAllowLoadFromTMEM = true; uObjTxSprite drawinfo; memcpy( &(drawinfo.sprite), info, sizeof(uObjSprite)); CRender::g_pRender->DrawSpriteR(drawinfo, false, dwTile, 0, 0, drawinfo.sprite.imageW/32, drawinfo.sprite.imageH/32); #ifdef DEBUGGER if( (pauseAtNext && (eventToPause == NEXT_OBJ_TXT_CMD||eventToPause == NEXT_FLUSH_TRI)) || logTextures ) { eventToPause = false; debuggerPause = true; TRACE0("Paused at RSP_S2DEX_OBJ_SPRITE"); CGraphicsContext::g_pGraphicsContext->UpdateFrame(false); } #endif } // Yoshi's Story uses this - 0xb0 void RSP_S2DEX_SELECT_DL(Gfx *gfx) { //static BOOL bWarned = FALSE; //if (!bWarned) { RSP_RDP_NOIMPL("RDP: RSP_S2DEX_SELECT_DL (0x%08x 0x%08x)", (gfx->words.w0), (gfx->words.w1)); //bWarned = TRUE; } DEBUGGER_PAUSE_AND_DUMP_COUNT_N(NEXT_OBJ_TXT_CMD, {DebuggerAppendMsg("Paused at RSP_S2DEX_SELECT_DL");}); } void RSP_S2DEX_OBJ_RENDERMODE(Gfx *gfx) { /* static BOOL bWarned = FALSE; //if (!bWarned) { RSP_RDP_NOIMPL("RDP: RSP_S2DEX_OBJ_RENDERMODE (0x%08x 0x%08x)", (gfx->words.w0), (gfx->words.w1)); bWarned = TRUE; } */ } // Yoshi's Story uses this - 0xb1 void RSP_GBI1_Tri2(Gfx *gfx); void RSP_S2DEX_OBJ_RENDERMODE_2(Gfx *gfx) { if( ((gfx->words.w0)&0xFFFFFF) != 0 || ((gfx->words.w1)&0xFFFFFF00) != 0 ) { // This is a TRI2 cmd RSP_GBI1_Tri2(gfx); return; } RSP_S2DEX_OBJ_RENDERMODE(gfx); } #ifdef DEBUGGER void DumpBlockParameters(uObjTxtrBlock &ptr) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; DebuggerAppendMsg("uObjTxtrBlock Header in RDRAM: 0x%08X", (uint32_t) ((char *) &ptr - (int8_t*)rdram_u8)); DebuggerAppendMsg("ImgAddr=0x%08X(0x%08X), tsize=0x%X, \nTMEM=0x%X, sid=%d, tline=%d, flag=0x%X, mask=0x%X\n\n", RSPSegmentAddr(ptr.image), ptr.image, ptr.tsize, ptr.tmem, ptr.sid/4, ptr.tline, ptr.flag, ptr.mask); } void DumpSpriteParameters(uObjSprite &ptr) { if( logTextures || (pauseAtNext && eventToPause == NEXT_OBJ_TXT_CMD) ) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; DebuggerAppendMsg("uObjSprite Header in RDRAM: 0x%08X", (uint32_t) ((char *) &ptr - (int8_t*)rdram_u8)); DebuggerAppendMsg("X=%d, Y=%d, W=%d, H=%d, scaleW=%f, scaleH=%f\n" "TAddr=0x%X, Stride=%d, Flag=0x%X, Pal=%d, Fmt=%s-%db\n\n", ptr.objX/4, ptr.objY/4, ptr.imageW/32, ptr.imageH/32, ptr.scaleW/1024.0f, ptr.scaleH/1024.0f, ptr.imageAdrs, ptr.imageStride, ptr.imageFlags, ptr.imagePal, pszImgFormat[ptr.imageFmt], pnImgSize[ptr.imageSiz]); } } void DumpTileParameters(uObjTxtrTile &tile) { } void DumpTlutParameters(uObjTxtrTLUT &tlut) { DebuggerAppendMsg("ImgAddr=0x%08X(0x%08X), pnum=%d, phead=%d, sid=%d, flag=0x%X, mask=0x%X\n\n", RSPSegmentAddr(tlut.image), tlut.image, tlut.pnum+1, tlut.phead, tlut.sid/4, tlut.flag, tlut.mask); } void DumpTxtrInfo(uObjTxtr *ptr) { if( logTextures || (pauseAtNext && eventToPause == NEXT_OBJ_TXT_CMD) ) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; DebuggerAppendMsg("uObjTxtr Header in RDRAM: 0x%08X", (uint32_t) ((char *) ptr - (char *) rdram_u8)); switch( ptr->block.type ) { case S2DEX_OBJLT_TXTRBLOCK: TRACE0("Loading ObjTxtr: type=BLOCK"); DumpBlockParameters(ptr->block); break; case S2DEX_OBJLT_TXTRTILE: TRACE0("Loading ObjTxtr: type=TILE"); DumpTileParameters(ptr->tile); break; case S2DEX_OBJLT_TLUT: TRACE0("Loading ObjTxtr: type=TLUT"); DumpTlutParameters(ptr->tlut); break; } } } void DumpObjMtx(bool fullmtx = true) { if( logTextures || (pauseAtNext && eventToPause == NEXT_OBJ_TXT_CMD) ) { if( fullmtx ) DebuggerAppendMsg("A=%X, B=%X, C=%X, D=%X, X=%X, Y=%X, BaseX=%X, BaseY=%X", gObjMtx->A, gObjMtx->B, gObjMtx->C, gObjMtx->D, gObjMtx->X, gObjMtx->Y, gObjMtx->BaseScaleX, gObjMtx->BaseScaleY); else DebuggerAppendMsg("SubMatrix: X=%X, Y=%X, BaseX=%X, BaseY=%X", gSubObjMtx->X, gSubObjMtx->Y, gSubObjMtx->BaseScaleX, gSubObjMtx->BaseScaleY); DebuggerAppendMsg("A=%f, B=%f, C=%f, D=%f, X=%f, Y=%f, BaseX=%f, BaseY=%f", gObjMtxReal.A, gObjMtxReal.B, gObjMtxReal.C, gObjMtxReal.D, gObjMtxReal.X, gObjMtxReal.Y, gObjMtxReal.BaseScaleX, gObjMtxReal.BaseScaleY); } } #endif void ObjMtxTranslate(float &x, float &y) { float x1 = gObjMtxReal.A*x + gObjMtxReal.B*y + gObjMtxReal.X; float y1 = gObjMtxReal.C*x + gObjMtxReal.D*y + gObjMtxReal.Y; x = x1; y = y1; } void RSP_S2DEX_SPObjLoadTxtr(Gfx *gfx) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; gObjTxtr = (uObjTxtr*)(rdram_u8 + (RSPSegmentAddr((gfx->words.w1))&(g_dwRamSize-1))); if( gObjTxtr->block.type == S2DEX_OBJLT_TLUT ) { gObjTlut = (uObjTxtrTLUT*)gObjTxtr; gObjTlutAddr = (uint32_t)(RSPSegmentAddr(gObjTlut->image)); // Copy tlut int size = gObjTlut->pnum+1; int offset = gObjTlut->phead-0x100; if( offset+size>0x100) { size = 0x100 - offset; } uint32_t addr = (gObjTlutAddr); for( int i=offset; iwords.w1))&(g_dwRamSize-1))); gObjTxtr = (uObjTxtr*)ptr; //Now draw the sprite CRender::g_pRender->LoadObjSprite(*ptr, false); CRender::g_pRender->DrawSpriteR(*ptr, true, 0, 0, 0, 0, 0); DEBUGGER_PAUSE_AT_COND_AND_DUMP_COUNT_N((eventToPause == NEXT_OBJ_TXT_CMD||eventToPause == NEXT_FLUSH_TRI), { DumpTxtrInfo(gObjTxtr); DumpSpriteParameters(ptr->sprite); TRACE0("Paused at RSP_S2DEX_SPObjLoadTxSprite"); } ); } // Yoshi's Story uses this - 0xc3 void RSP_S2DEX_SPObjLoadTxRect(Gfx *gfx) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; uObjTxSprite* ptr = (uObjTxSprite*)(rdram_u8 + (RSPSegmentAddr((gfx->words.w1))&(g_dwRamSize-1))); gObjTxtr = (uObjTxtr*)ptr; //Now draw the sprite CRender::g_pRender->LoadObjSprite(*ptr, false); CRender::g_pRender->DrawSprite(*ptr, false); DEBUGGER_PAUSE_AT_COND_AND_DUMP_COUNT_N((eventToPause == NEXT_OBJ_TXT_CMD||eventToPause == NEXT_FLUSH_TRI), { DumpTxtrInfo(gObjTxtr); DumpSpriteParameters(ptr->sprite); TRACE0("Paused at RSP_S2DEX_SPObjLoadTxRect"); } ); } // Yoshi's Story uses this - 0xc4 void RSP_S2DEX_SPObjLoadTxRectR(Gfx *gfx) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; uObjTxSprite* ptr = (uObjTxSprite*)(rdram_u8 + (RSPSegmentAddr((gfx->words.w1))&(g_dwRamSize-1))); gObjTxtr = (uObjTxtr*)ptr; //Now draw the sprite CRender::g_pRender->LoadObjSprite(*ptr, false); CRender::g_pRender->DrawSprite(*ptr, true); DEBUGGER_PAUSE_AT_COND_AND_DUMP_COUNT_N((eventToPause == NEXT_OBJ_TXT_CMD||eventToPause == NEXT_FLUSH_TRI), { DumpTxtrInfo(gObjTxtr); DumpSpriteParameters(ptr->sprite); TRACE0("Paused at RSP_S2DEX_SPObjLoadTxRect"); } ); } void DLParser_TexRect(Gfx *gfx); // Yoshi's Story uses this - 0xe4 void RSP_S2DEX_RDPHALF_0(Gfx *gfx) { //RDP: RSP_S2DEX_RDPHALF_0 (0xe449c0a8 0x003b40a4) //0x001d3c88: e449c0a8 003b40a4 RDP_TEXRECT //0x001d3c90: b4000000 00000000 RSP_RDPHALF_1 //0x001d3c98: b3000000 04000400 RSP_RDPHALF_2 uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; uint32_t dwPC = gDlistStack[gDlistStackPointer].pc; // This points to the next instruction uint32_t dwNextUcode = *(uint32_t *)(rdram_u8 + dwPC); if( (dwNextUcode>>24) != S2DEX_SELECT_DL ) { // Pokemom Puzzle League if( (dwNextUcode>>24) == 0xB4 ) { DLParser_TexRect(gfx); } else { RSP_RDP_NOIMPL("RDP: RSP_S2DEX_RDPHALF_0 (0x%08x 0x%08x)", (gfx->words.w0), (gfx->words.w1)); } } else { RSP_RDP_NOIMPL("RDP: RSP_S2DEX_RDPHALF_0 (0x%08x 0x%08x)", (gfx->words.w0), (gfx->words.w1)); DEBUGGER_PAUSE_COUNT_N(NEXT_OBJ_TXT_CMD); } } // Yoshi's Story uses this - 0x05 void RSP_S2DEX_OBJ_MOVEMEM(Gfx *gfx) { uint32_t dwCommand = ((gfx->words.w0)>>16)&0xFF; uint32_t dwLength = ((gfx->words.w0)) &0xFFFF; uint32_t dwAddr = RSPSegmentAddr((gfx->words.w1)); if( dwAddr >= g_dwRamSize ) { TRACE0("ObjMtx: memory ptr is invalid"); } if( dwLength == 0 && dwCommand == 23 ) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; gObjMtx = (uObjMtx *)(rdram_u8 + dwAddr); gObjMtxReal.A = gObjMtx->A/65536.0f; gObjMtxReal.B = gObjMtx->B/65536.0f; gObjMtxReal.C = gObjMtx->C/65536.0f; gObjMtxReal.D = gObjMtx->D/65536.0f; gObjMtxReal.X = float(gObjMtx->X>>2); gObjMtxReal.Y = float(gObjMtx->Y>>2); gObjMtxReal.BaseScaleX = gObjMtx->BaseScaleX/1024.0f; gObjMtxReal.BaseScaleY = gObjMtx->BaseScaleY/1024.0f; #ifdef DEBUGGER DumpObjMtx(); #endif } else if( dwLength == 2 && dwCommand == 7 ) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; gSubObjMtx = (uObjSubMtx*)(rdram_u8 + dwAddr); gObjMtxReal.X = float(gSubObjMtx->X>>2); gObjMtxReal.Y = float(gSubObjMtx->Y>>2); gObjMtxReal.BaseScaleX = gSubObjMtx->BaseScaleX/1024.0f; gObjMtxReal.BaseScaleY = gSubObjMtx->BaseScaleY/1024.0f; #ifdef DEBUGGER DumpObjMtx(false); #endif } g_MtxReal._11 = gObjMtxReal.A; g_MtxReal._12 = gObjMtxReal.C; g_MtxReal._13 = 0; g_MtxReal._14 = 0;//gObjMtxReal.X; g_MtxReal._21 = gObjMtxReal.B; g_MtxReal._22 = gObjMtxReal.D; g_MtxReal._23 = 0; g_MtxReal._24 = 0;//gObjMtxReal.Y; g_MtxReal._31 = 0; g_MtxReal._32 = 0; g_MtxReal._33 = 1.0; g_MtxReal._34 = 0; g_MtxReal._41 = gObjMtxReal.X; g_MtxReal._42 = gObjMtxReal.Y; g_MtxReal._43 = 0; g_MtxReal._44 = 1.0; DEBUGGER_PAUSE_COUNT_N(NEXT_OBJ_TXT_CMD); } // Yoshi's Story uses this - 0x01 extern void RSP_GBI0_Mtx(Gfx *gfx); void RSP_S2DEX_BG_1CYC(Gfx *gfx) { SP_Timing(DP_Minimal16); DP_Timing(DP_Minimal16); uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; uint32_t dwAddr = RSPSegmentAddr((gfx->words.w1)); uObjScaleBg *sbgPtr = (uObjScaleBg *)(rdram_u8 + dwAddr); CRender::g_pRender->LoadObjBG1CYC(*sbgPtr); CRender::g_pRender->DrawObjBG1CYC(*sbgPtr, true); DEBUGGER_PAUSE_AT_COND_AND_DUMP_COUNT_N((eventToPause == NEXT_OBJ_TXT_CMD||eventToPause == NEXT_FLUSH_TRI||eventToPause == NEXT_OBJ_BG), { DebuggerAppendMsg("S2DEX BG 1CYC: %08X-%08X\n", (gfx->words.w0), (gfx->words.w1) ); TRACE0("Paused at RSP_S2DEX_BG_1CYC"); } ); } void RSP_S2DEX_BG_1CYC_2(Gfx *gfx) { if( ((gfx->words.w0)&0x00FFFFFF) != 0 ) { RSP_GBI0_Mtx(gfx); return; } RSP_S2DEX_BG_1CYC(gfx); } // Yoshi's Story uses this - 0xb2 void RSP_S2DEX_OBJ_RECTANGLE_R(Gfx *gfx) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; uint32_t dwAddr = RSPSegmentAddr((gfx->words.w1)); uObjSprite *ptr = (uObjSprite*)(rdram_u8 + dwAddr); uObjTxSprite objtx; memcpy(&objtx.sprite, ptr, sizeof(uObjSprite)); //Now draw the sprite if( g_TxtLoadBy == CMD_LOAD_OBJ_TXTR ) { memcpy(&(objtx.txtr.block), &(gObjTxtr->block), sizeof(uObjTxtr)); //CRender::g_pRender->LoadObjSprite(*ptr, true); CRender::g_pRender->LoadObjSprite(objtx, true); } else { PrepareTextures(); } //CRender::g_pRender->DrawSprite(*ptr, true); CRender::g_pRender->DrawSprite(objtx, true); DEBUGGER_PAUSE_AT_COND_AND_DUMP_COUNT_N((eventToPause == NEXT_OBJ_TXT_CMD||eventToPause == NEXT_FLUSH_TRI), { DumpTxtrInfo(gObjTxtr); DumpSpriteParameters(*ptr); TRACE0("Paused at RSP_S2DEX_OBJ_RECTANGLE_R"); } ); } mupen64plus-rsp-hle/src/hle_internal.h000664 001750 001750 00000005237 12655644434 021104 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-rsp-hle - hle_internal.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef HLE_INTERNAL_H #define HLE_INTERNAL_H #include #include "ucodes.h" /* rsp hle internal state - internal usage only */ struct hle_t { unsigned char* dram; unsigned char* dmem; unsigned char* imem; unsigned int* mi_intr; unsigned int* sp_mem_addr; unsigned int* sp_dram_addr; unsigned int* sp_rd_length; unsigned int* sp_wr_length; unsigned int* sp_status; unsigned int* sp_dma_full; unsigned int* sp_dma_busy; unsigned int* sp_pc; unsigned int* sp_semaphore; unsigned int* dpc_start; unsigned int* dpc_end; unsigned int* dpc_current; unsigned int* dpc_status; unsigned int* dpc_clock; unsigned int* dpc_bufbusy; unsigned int* dpc_pipebusy; unsigned int* dpc_tmem; /* for user convenience, this will be passed to "external" functions */ void* user_defined; /* alist.c */ uint8_t alist_buffer[0x1000]; /* alist_audio.c */ struct alist_audio_t alist_audio; /* alist_naudio.c */ struct alist_naudio_t alist_naudio; /* alist_nead.c */ struct alist_nead_t alist_nead; /* mp3.c */ uint8_t mp3_buffer[0x1000]; }; #endif gles2rice/src/000700 001750 001750 00000000000 12656647145 014354 5ustar00sergiosergio000000 000000 mupen64plus-core/doc/emuwiki-api-doc/Mupen64Plus_Plugin_Parameters.txt000664 001750 001750 00000030150 12655644434 027143 0ustar00sergiosergio000000 000000 [[Mupen64Plus v2.0 Core API v1.0|Mupen64Plus v2.0 API]] = Plugin Parameters = These are standard parameters which are used by the Mupen64Plus plugins. The behavior of the plugin library when these parameters are changed while the emulator is running is not defined here. Some plugins will load the parameters when starting and store internal copies of the parameters for use during emulation. Other plugins may read the value of the parameters while running. === Audio-SDL === {| border="1" !Parameter Name!!Type!!Usage |- |Version |M64TYPE_FLOAT |Mupen64Plus Audio SDL config parameter set version number. Please don't change. |- |DEFAULT_FREQUENCY |M64TYPE_INT |Frequency which is used if rom doesn't want to change it |- |SWAP_CHANNELS |M64TYPE_BOOL |Swaps left and right channels |- |PRIMARY_BUFFER_SIZE |M64TYPE_INT |Size of primary buffer in output samples. This is where audio is loaded after it's extracted from n64's memory. |- |PRIMARY_BUFFER_TARGET |M64TYPE_INT |Fullness level target for Primary audio buffer, in equivalent output samples. |- |SECONDARY_BUFFER_SIZE |M64TYPE_INT |Size of secondary buffer in samples. This is SDL's hardware buffer. |- |RESAMPLE |M64TYPE_STRING |Audio resampling algorithm. "trivial" for fastest, lowest-quality algorithm. If compiled with SPEEX support, this can be "speex-fixed-0" to "speex-fixed-10". If compiled with libsrc support, this can be "src-sinc-best-quality", "src-sinc-medium-quality", "src-sinc-fastest", "src-zero-order-hold", or "src-linear". |- |VOLUME_CONTROL_TYPE |M64TYPE_INT |Volume control type: 1 = SDL (only affects Mupen64Plus output) 2 = OSS mixer (adjusts master PC volume) |- |VOLUME_ADJUST |M64TYPE_INT |Percentage change each time the volume is increased or decreased |- |VOLUME_DEFAULT |M64TYPE_INT |Default volume when a game is started. Only used if VOLUME_CONTROL_TYPE is 1 |- |} === Video-General === {| border="1" !Parameter Name!!Type!!Usage |- |Fullscreen |M64TYPE_BOOL |Use fullscreen mode if True, or windowed mode if False |- |ScreenWidth |M64TYPE_INT |Width of output window or fullscreen width |- |ScreenHeight |M64TYPE_INT |Height of output window or fullscreen height |- |} === Video-Rice === {| border="1" !Parameter Name!!Type!!Usage |- |FrameBufferSetting |M64TYPE_INT |Frame Buffer Emulation (0=ROM default, 1=disable) |- |FrameBufferWriteBackControl |M64TYPE_INT |Frequency to write back the frame buffer (0=every frame, 1=every other frame, etc) |- |RenderToTexture |M64TYPE_INT |Render-to-texture emulation (0=none, 1=ignore, 2=normal, 3=write back, 4=write back and reload) |- |ScreenUpdateSetting |M64TYPE_INT |Control when the screen will be updated (0=ROM default, 1=VI origin update, 2=VI origin change, 3=CI change, 4=first CI change, 5=first primitive draw, 6=before screen clear, 7=after screen drawn) |- |NormalAlphaBlender |M64TYPE_BOOL |Force to use normal alpha blender |- |FastTextureLoading |M64TYPE_BOOL |Use a faster algorithm to speed up texture loading and CRC computation (may break hi-res texture loading) |- |AccurateTextureMapping |M64TYPE_BOOL |Use different texture coordinate clamping code |- |InN64Resolution |M64TYPE_BOOL |Force emulated frame buffers to be in N64 native resolution |- |SaveVRAM |M64TYPE_BOOL |Try to reduce Video RAM usage (should never be used) |- |DoubleSizeForSmallTxtrBuf |M64TYPE_BOOL |Enable this option to have better render-to-texture quality |- |DefaultCombinerDisable |M64TYPE_BOOL |Force to use normal color combiner |- |EnableHacks |M64TYPE_BOOL |Enable game-specific settings from INI file |- |EnableFog |M64TYPE_BOOL |Enable or disable fog generation |- |WinFrameMode |M64TYPE_BOOL |If enabled, graphics will be drawn in WinFrame mode instead of solid and texture mode |- |FullTMEMEmulation |M64TYPE_BOOL |N64 Texture Memory Full Emulation (may fix some games, may break others) |- |OpenGLVertexClipper |M64TYPE_BOOL |Enable vertex clipper for fog operations |- |EnableSSE |M64TYPE_BOOL |Enable SSE optimizations for capable CPUs |- |EnableVertexShader |M64TYPE_BOOL |Use GPU vertex shader |- |SkipFrame |M64TYPE_BOOL |If this option is enabled, the plugin will skip every other frame |- |TexRectOnly |M64TYPE_BOOL |If enabled, texture enhancement will be done only for TxtRect ucode |- |SmallTextureOnly |M64TYPE_BOOL |If enabled, texture enhancement will be done only for textures width+height<=128 |- |LoadHiResTextures |M64TYPE_BOOL |Enable hi-resolution texture file loading |- |LoadHiResCRCOnly |M64TYPE_BOOL |Filter hi-resolution texture filenames based only on the CRC and ignore format+size tags (Glide64 compatibility) |- |DumpTexturesToFiles |M64TYPE_BOOL |Enable texture dumping |- |ShowFPS |M64TYPE_BOOL |Display On-screen FPS |- |FogMethod |M64TYPE_INT |Enable, Disable or Force fog generation (0=Disable, 1=Enable n64 choose, 2=Force Fog) |- |Mipmapping |M64TYPE_INT |Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear |- |MultiSampling |M64TYPE_INT |Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) |- |TextureEnhancement |M64TYPE_INT |Primary texture filter (0=None, 1=2X, 2=2XSAI, 3=HQ2X, 4=LQ2X, 5=HQ4X, 6=Sharpen, 7=Sharpen More, 8=External, 9=Mirrored) |- |TextureEnhancementControl |M64TYPE_INT |Secondary texture filter (0 = none, 1-4 = filtered) |- |ForceTextureFilter |M64TYPE_INT |Force to use texture filtering or not (0=auto: n64 choose, 1=force no filtering, 2=force filtering) |- |TextureQuality |M64TYPE_INT |Color bit depth to use for textures (0=default, 1=32 bits, 2=16 bits |- |OpenGLDepthBufferSetting |M64TYPE_INT |Z-buffer depth (only 16 or 32) |- |ColorQuality |M64TYPE_INT |Color bit depth for rendering window (0=32 bits, 1=16 bits) |- |OpenGLRenderSetting |M64TYPE_INT |OpenGL rendering level to support (0=auto, 1=OGL_1.1, 2=OGL_1.2, 3=OGL_1.3, 4=OGL_1.4, 5=OGL_1.4_V2, 6=OGL_TNT2, 7=NVIDIA_OGL, 8=OGL_FRAGMENT_PROGRAM) |- |AnisotropicFiltering |M64TYPE_INT |Enable/Disable Anisotropic Filtering for Mipmapping (0=no filtering, 2-16=quality). This is uneffective if EnableMipmapping is false. If the given value is to high to be supported by your graphic card, the value will be the highest value your graphic card can support. Better result with Trilinear filtering |} === Input-SDL === The Mupen64Plus-Input-SDL plugin uses a separate config section for each simulated N64 controller. The sections are named: Input-SDL-Control1, Input-SDL-Control2, Input-SDL-Control3, and Input-SDL-Control4. The 4 sections all contain the same parameters. General-purpose Controller Configuration Parameters {| border="1" !Parameter Name!!Type!!Usage |- |version |M64TYPE_FLOAT |Mupen64Plus Input-SDL config parameter set version number. Please don't change. |- |mode |M64TYPE_INT |Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic |- |device |M64TYPE_INT |Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number |- |name |M64TYPE_STRING |SDL joystick name (or Keyboard) |- |plugged |M64TYPE_BOOL |Specifies whether this controller is 'plugged in' to the simulated N64 |- |plugin |M64TYPE_INT |Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 5=Rumble pak |- |mouse |M64TYPE_BOOL |If True, then mouse buttons may be used with this controller, and mouse movement will map to X/Y analog stick |- |MouseSensitivity |M64TYPE_STRING |The sensitivity coefficients for the mouse to move the N64 controller axis value from 0. For X, Y axes. Values must be positive. |- |AnalogDeadzone |M64TYPE_STRING |The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. |- |AnalogPeak |M64TYPE_STRING |An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value |- |} Digital Controller Configuration These parameters are used to bind input events with N64 Controller button presses. There are 14 simulated buttons and 2 special buttons for switching between the Mem Pak and Rumble Pak expansion units. Each configuration parameter is a string which specifies input events which will map to the given N64 button. The configuration strings consist of zero or more input event words. A list of available input event words is given here: {| border="1" !Input Event Word!!Usage |- |key(<keysym>) |<keysym> = SDLK_* key symbol enumerated type |- |button(<num>) |<num> = SDL Joystick Button Number (0 or greater) |- |axis(<num><dir>) |<num> = SDL Joystick Axis Number, <dir> = axis direction (+ = positive, - = negative) |- |axis(<num><dir>,<deadzone>) |<num> = SDL Joystick Axis Number, <dir> = axis direction (+ = positive, - = negative), <deadzone> = minimum axis value (max 32767) to activate button; default 6000 |- |hat(<num> <dir>) |<num> = SDL Joystick Hat Number, <dir> = hat direction (Up, Down, Left, or Right) |- |mouse(<num>) |<num> = mouse button number (1 = left button, 2 = middle, 3 = right, etc) |- |}
{| border="1" !Parameter Name!!Type!!Usage |- |DPad R |M64TYPE_STRING |Input event string for mapping the Right button on the D-pad |- |DPad L |M64TYPE_STRING |Input event string for mapping the Left button on the D-pad |- |DPad D |M64TYPE_STRING |Input event string for mapping the Down button on the D-pad |- |DPad U |M64TYPE_STRING |Input event string for mapping the Up button on the D-pad |- |Start |M64TYPE_STRING |Input event string for mapping the Start button |- |Z Trig |M64TYPE_STRING |Input event string for mapping the Z trigger |- |B Button |M64TYPE_STRING |Input event string for mapping the "B" button |- |A Button |M64TYPE_STRING |Input event string for mapping the "A" button |- |C Button R |M64TYPE_STRING |Input event string for mapping the Right "C" button |- |C Button L |M64TYPE_STRING |Input event string for mapping the Left "C" button |- |C Button D |M64TYPE_STRING |Input event string for mapping the Down "C" button |- |C Button U |M64TYPE_STRING |Input event string for mapping the Up "C" button |- |R Trig |M64TYPE_STRING |Input event string for mapping the Right trigger |- |L Trig |M64TYPE_STRING |Input event string for mapping the Left trigger |- |Mempak switch |M64TYPE_STRING |Input event string for toggling the Memory Pak unit |- |Rumblepak switch |M64TYPE_STRING |Input event string for toggling the Rumble Pak unit |- |} Analog Controller Configuration These parameters are used to bind input events with N64 Controller analog stick movements. There are only 2 analog stick axes, X and Y. Each configuration parameter is a string which specifies input events which will map to the given N64 controller axis movement. The configuration strings consist of zero or more input event words. A list of available input event words is given here: {| border="1" !Input Event Word!!Usage |- |key(<key_a>,<key_b>) |<key_a> = SDLK_* key symbol for up/left movement. <key_b> = SDLK_* key symbol for down/right movement. The strength of these movements can be modulated with the Left-Shift and Left-Control keys. |- |button(<num_a>,<num_b>) |<num_a> = SDL Joystick Button Number for up/left movement. <num_b> = SDL Joystick Button Number for down/right movement. |- |axis(<num_a><dir_a>,<num_b><dir_b>) |<num_a> = SDL Joystick Axis Number for up/left movement, <dir_a> = axis direction for up/left movement (+ = positive, - = negative). <num_b> = SDL Joystick Axis Number for down/right movement, <dir_b> = axis direction for down/right movement. |- |hat(<num> <dir_a> <dir_b>) |<num> = SDL Joystick Hat Number, <dir_a> = hat direction for up/left movement (Up, Down, Left, or Right), <dir_b> = hat direction for right/down movement |- |}
{| border="1" !Parameter Name!!Type!!Usage |- |Y Axis |M64TYPE_STRING |Input event string for mapping the Y axis (up/down) of the analog stick |- |X Axis |M64TYPE_STRING |Input event string for mapping the X axis (left/right) of the analog stick |- |} mupen64plus-video-gliden64/src/F3D.h000664 001750 001750 00000005342 12655644434 020157 0ustar00sergiosergio000000 000000 #ifndef F3D_H #define F3D_H #include "Types.h" #define F3D_MTX_STACKSIZE 10 #define F3D_MTX_MODELVIEW 0x00 #define F3D_MTX_PROJECTION 0x01 #define F3D_MTX_MUL 0x00 #define F3D_MTX_LOAD 0x02 #define F3D_MTX_NOPUSH 0x00 #define F3D_MTX_PUSH 0x04 #define F3D_TEXTURE_ENABLE 0x00000002 #define F3D_SHADING_SMOOTH 0x00000200 #define F3D_CULL_FRONT 0x00001000 #define F3D_CULL_BACK 0x00002000 #define F3D_CULL_BOTH 0x00003000 #define F3D_CLIPPING 0x00000000 #define F3D_MV_VIEWPORT 0x80 #define F3D_MWO_aLIGHT_1 0x00 #define F3D_MWO_bLIGHT_1 0x04 #define F3D_MWO_aLIGHT_2 0x20 #define F3D_MWO_bLIGHT_2 0x24 #define F3D_MWO_aLIGHT_3 0x40 #define F3D_MWO_bLIGHT_3 0x44 #define F3D_MWO_aLIGHT_4 0x60 #define F3D_MWO_bLIGHT_4 0x64 #define F3D_MWO_aLIGHT_5 0x80 #define F3D_MWO_bLIGHT_5 0x84 #define F3D_MWO_aLIGHT_6 0xa0 #define F3D_MWO_bLIGHT_6 0xa4 #define F3D_MWO_aLIGHT_7 0xc0 #define F3D_MWO_bLIGHT_7 0xc4 #define F3D_MWO_aLIGHT_8 0xe0 #define F3D_MWO_bLIGHT_8 0xe4 // FAST3D commands #define F3D_SPNOOP 0x00 #define F3D_MTX 0x01 #define F3D_RESERVED0 0x02 #define F3D_MOVEMEM 0x03 #define F3D_VTX 0x04 #define F3D_RESERVED1 0x05 #define F3D_DL 0x06 #define F3D_RESERVED2 0x07 #define F3D_RESERVED3 0x08 #define F3D_SPRITE2D_BASE 0x09 #define F3D_TRI1 0xBF #define F3D_CULLDL 0xBE #define F3D_POPMTX 0xBD #define F3D_MOVEWORD 0xBC #define F3D_TEXTURE 0xBB #define F3D_SETOTHERMODE_H 0xBA #define F3D_SETOTHERMODE_L 0xB9 #define F3D_ENDDL 0xB8 #define F3D_SETGEOMETRYMODE 0xB7 #define F3D_CLEARGEOMETRYMODE 0xB6 //#define F3D_LINE3D 0xB5 // Only used in Line3D #define F3D_QUAD 0xB5 #define F3D_RDPHALF_1 0xB4 #define F3D_RDPHALF_2 0xB3 #define F3D_RDPHALF_CONT 0xB2 #define F3D_TRI4 0xB1 void F3D_SPNoOp( u32 w0, u32 w1 ); void F3D_Mtx( u32 w0, u32 w1 ); void F3D_Reserved0( u32 w0, u32 w1 ); void F3D_MoveMem( u32 w0, u32 w1 ); void F3D_Vtx( u32 w0, u32 w1 ); void F3D_Reserved1( u32 w0, u32 w1 ); void F3D_DList( u32 w0, u32 w1 ); void F3D_Reserved2( u32 w0, u32 w1 ); void F3D_Reserved3( u32 w0, u32 w1 ); void F3D_Sprite2D_Base( u32 w0, u32 w1 ); void F3D_Tri1( u32 w0, u32 w1 ); void F3D_CullDL( u32 w0, u32 w1 ); void F3D_PopMtx( u32 w0, u32 w1 ); void F3D_MoveWord( u32 w0, u32 w1 ); void F3D_Texture( u32 w0, u32 w1 ); void F3D_SetOtherMode_H( u32 w0, u32 w1 ); void F3D_SetOtherMode_L( u32 w0, u32 w1 ); void F3D_EndDL( u32 w0, u32 w1 ); void F3D_SetGeometryMode( u32 w0, u32 w1 ); void F3D_ClearGeometryMode( u32 w0, u32 w1 ); //void F3D_Line3D( u32 w0, u32 w1 ); void F3D_Quad( u32 w0, u32 w1 ); void F3D_RDPHalf_1( u32 w0, u32 w1 ); void F3D_RDPHalf_2( u32 w0, u32 w1 ); void F3D_RDPHalf_Cont( u32 w0, u32 w1 ); void F3D_Tri4( u32 w0, u32 w1 ); void F3D_Init(); #endif gles2rice/src/OGLGraphicsContext.cpp000664 001750 001750 00000013210 12655644434 020535 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "osal_opengl.h" #define M64P_PLUGIN_PROTOTYPES 1 #include "m64p_plugin.h" #include "Config.h" #include "Debugger.h" #include "OGLDebug.h" #include "OGLGraphicsContext.h" #include "TextureManager.h" #include "Video.h" #include "version.h" COGLGraphicsContext::COGLGraphicsContext() : m_bSupportLODBias(false), m_bSupportTextureLOD(false), m_pVendorStr(NULL), m_pRenderStr(NULL), m_pExtensionStr(NULL), m_pVersionStr(NULL) { } COGLGraphicsContext::~COGLGraphicsContext() { } bool COGLGraphicsContext::Initialize(uint32_t dwWidth, uint32_t dwHeight) { DebugMessage(M64MSG_INFO, "Initializing OpenGL Device Context."); CGraphicsContext::Initialize(dwWidth, dwHeight); int depthBufferDepth = options.OpenglDepthBufferSetting; int colorBufferDepth = 32; int bVerticalSync = windowSetting.bVerticalSync; if (options.colorQuality == TEXTURE_FMT_A4R4G4B4) colorBufferDepth = 16; InitState(); InitOGLExtension(); sprintf(m_strDeviceStats, "%.60s - %.128s : %.60s", m_pVendorStr, m_pRenderStr, m_pVersionStr); TRACE0(m_strDeviceStats); DebugMessage(M64MSG_INFO, "Using OpenGL: %s", m_strDeviceStats); Clear(CLEAR_COLOR_AND_DEPTH_BUFFER, 0xFF000000, 1.0f); // Clear buffers UpdateFrame(false); Clear(CLEAR_COLOR_AND_DEPTH_BUFFER, 0xFF000000, 1.0f); UpdateFrame(false); return true; } bool COGLGraphicsContext::ResizeInitialize(uint32_t dwWidth, uint32_t dwHeight) { CGraphicsContext::Initialize(dwWidth, dwHeight); int depthBufferDepth = options.OpenglDepthBufferSetting; int colorBufferDepth = 32; int bVerticalSync = windowSetting.bVerticalSync; if (options.colorQuality == TEXTURE_FMT_A4R4G4B4) colorBufferDepth = 16; /* Hard-coded attribute values */ const int iDOUBLEBUFFER = 1; InitState(); Clear(CLEAR_COLOR_AND_DEPTH_BUFFER, 0xFF000000, 1.0f); // Clear buffers UpdateFrame(false); Clear(CLEAR_COLOR_AND_DEPTH_BUFFER, 0xFF000000, 1.0f); UpdateFrame(false); return true; } void COGLGraphicsContext::InitState(void) { m_pRenderStr = glGetString(GL_RENDERER); m_pExtensionStr = glGetString(GL_EXTENSIONS); m_pVersionStr = glGetString(GL_VERSION); m_pVendorStr = glGetString(GL_VENDOR); glMatrixMode(GL_PROJECTION); OPENGL_CHECK_ERRORS; glLoadIdentity(); OPENGL_CHECK_ERRORS; glClearColor(0.0f, 0.0f, 0.0f, 0.0f); OPENGL_CHECK_ERRORS; glClearDepth(1.0f); OPENGL_CHECK_ERRORS; glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); OPENGL_CHECK_ERRORS; glDisable(GL_BLEND); OPENGL_CHECK_ERRORS; glFrontFace(GL_CCW); OPENGL_CHECK_ERRORS; glDisable(GL_CULL_FACE); OPENGL_CHECK_ERRORS; glDepthFunc(GL_LEQUAL); OPENGL_CHECK_ERRORS; glEnable(GL_DEPTH_TEST); OPENGL_CHECK_ERRORS; glEnable(GL_BLEND); OPENGL_CHECK_ERRORS; glDepthRange(-1.0f, 1.0f); OPENGL_CHECK_ERRORS; } void COGLGraphicsContext::InitOGLExtension(void) { } bool COGLGraphicsContext::IsExtensionSupported(const char* pExtName) { if (strstr((const char*)m_pExtensionStr, pExtName) != NULL) { DebugMessage(M64MSG_VERBOSE, "OpenGL Extension '%s' is supported.", pExtName); return true; } else { DebugMessage(M64MSG_VERBOSE, "OpenGL Extension '%s' is NOT supported.", pExtName); return false; } } bool COGLGraphicsContext::IsWglExtensionSupported(const char* pExtName) { if (m_pWglExtensionStr == NULL) return false; if (strstr((const char*)m_pWglExtensionStr, pExtName) != NULL) return true; else return false; } void COGLGraphicsContext::CleanUp() { } void COGLGraphicsContext::Clear(ClearFlag dwFlags, uint32_t color, float depth) { uint32_t flag=0; if (dwFlags & CLEAR_COLOR_BUFFER) flag |= GL_COLOR_BUFFER_BIT; if (dwFlags & CLEAR_DEPTH_BUFFER) flag |= GL_DEPTH_BUFFER_BIT; float r = ((color>>16)&0xFF)/255.0f; float g = ((color>> 8)&0xFF)/255.0f; float b = ((color )&0xFF)/255.0f; float a = ((color>>24)&0xFF)/255.0f; glClearColor(r, g, b, a); OPENGL_CHECK_ERRORS; glClearDepth(depth); OPENGL_CHECK_ERRORS; glClear(flag); //Clear color buffer and depth buffer OPENGL_CHECK_ERRORS; } void COGLGraphicsContext::UpdateFrame(bool swapOnly) { status.gFrameCount++; glFlush(); OPENGL_CHECK_ERRORS; // if emulator defined a render callback function, call it before buffer swap if (renderCallback) (*renderCallback)(status.bScreenIsDrawn); retro_return(true); glDepthMask(GL_TRUE); OPENGL_CHECK_ERRORS; glClearDepth(1.0f); OPENGL_CHECK_ERRORS; if (!g_curRomInfo.bForceScreenClear) { glClear(GL_DEPTH_BUFFER_BIT); OPENGL_CHECK_ERRORS; } else { needCleanScene = true; } status.bScreenIsDrawn = false; } // This is a static function, will be called when the plugin DLL is initialized void COGLGraphicsContext::InitDeviceParameters() { } libretro-common/include/glsym/glsym_es2.h000664 001750 001750 00000023511 12655644434 021664 0ustar00sergiosergio000000 000000 /* Copyright (C) 2010-2015 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this libretro SDK code part (glsym). * --------------------------------------------------------------------------------------- * * Permission is hereby granted, free of charge, * to any person obtaining a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef RGLGEN_DECL_H__ #define RGLGEN_DECL_H__ #ifdef __cplusplus extern "C" { #endif #ifdef GL_APIENTRY typedef void (GL_APIENTRY *RGLGENGLDEBUGPROC)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*); typedef void (GL_APIENTRY *RGLGENGLDEBUGPROCKHR)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*); #else #ifndef APIENTRY #define APIENTRY #endif #ifndef APIENTRYP #define APIENTRYP APIENTRY * #endif typedef void (APIENTRY *RGLGENGLDEBUGPROCARB)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*); typedef void (APIENTRY *RGLGENGLDEBUGPROC)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*); #endif #ifndef GL_OES_EGL_image typedef void *GLeglImageOES; #endif #if !defined(GL_OES_fixed_point) && !defined(HAVE_OPENGLES2) typedef GLint GLfixed; #endif #if defined(OSX) && !defined(MAC_OS_X_VERSION_10_7) typedef long long int GLint64; typedef unsigned long long int GLuint64; typedef unsigned long long int GLuint64EXT; typedef struct __GLsync *GLsync; #endif typedef void (GL_APIENTRYP RGLSYMGLDEBUGMESSAGECONTROLKHRPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); typedef void (GL_APIENTRYP RGLSYMGLDEBUGMESSAGEINSERTKHRPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); typedef void (GL_APIENTRYP RGLSYMGLDEBUGMESSAGECALLBACKKHRPROC) (RGLGENGLDEBUGPROCKHR callback, const void *userParam); typedef GLuint (GL_APIENTRYP RGLSYMGLGETDEBUGMESSAGELOGKHRPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); typedef void (GL_APIENTRYP RGLSYMGLPUSHDEBUGGROUPKHRPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message); typedef void (GL_APIENTRYP RGLSYMGLPOPDEBUGGROUPKHRPROC) (void); typedef void (GL_APIENTRYP RGLSYMGLOBJECTLABELKHRPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); typedef void (GL_APIENTRYP RGLSYMGLGETOBJECTLABELKHRPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); typedef void (GL_APIENTRYP RGLSYMGLOBJECTPTRLABELKHRPROC) (const void *ptr, GLsizei length, const GLchar *label); typedef void (GL_APIENTRYP RGLSYMGLGETOBJECTPTRLABELKHRPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); typedef void (GL_APIENTRYP RGLSYMGLGETPOINTERVKHRPROC) (GLenum pname, void **params); typedef void (GL_APIENTRYP RGLSYMGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image); typedef void (GL_APIENTRYP RGLSYMGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image); typedef void (GL_APIENTRYP RGLSYMGLGETPROGRAMBINARYOESPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); typedef void (GL_APIENTRYP RGLSYMGLPROGRAMBINARYOESPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLint length); typedef void *(GL_APIENTRYP RGLSYMGLMAPBUFFEROESPROC) (GLenum target, GLenum access); typedef GLboolean (GL_APIENTRYP RGLSYMGLUNMAPBUFFEROESPROC) (GLenum target); typedef void (GL_APIENTRYP RGLSYMGLGETBUFFERPOINTERVOESPROC) (GLenum target, GLenum pname, void **params); typedef void (GL_APIENTRYP RGLSYMGLTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); typedef void (GL_APIENTRYP RGLSYMGLTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); typedef void (GL_APIENTRYP RGLSYMGLCOPYTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (GL_APIENTRYP RGLSYMGLCOMPRESSEDTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); typedef void (GL_APIENTRYP RGLSYMGLCOMPRESSEDTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); typedef void (GL_APIENTRYP RGLSYMGLFRAMEBUFFERTEXTURE3DOESPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); typedef void (GL_APIENTRYP RGLSYMGLBINDVERTEXARRAYOESPROC) (GLuint array); typedef void (GL_APIENTRYP RGLSYMGLDELETEVERTEXARRAYSOESPROC) (GLsizei n, const GLuint *arrays); typedef void (GL_APIENTRYP RGLSYMGLGENVERTEXARRAYSOESPROC) (GLsizei n, GLuint *arrays); typedef GLboolean (GL_APIENTRYP RGLSYMGLISVERTEXARRAYOESPROC) (GLuint array); #define glDebugMessageControlKHR __rglgen_glDebugMessageControlKHR #define glDebugMessageInsertKHR __rglgen_glDebugMessageInsertKHR #define glDebugMessageCallbackKHR __rglgen_glDebugMessageCallbackKHR #define glGetDebugMessageLogKHR __rglgen_glGetDebugMessageLogKHR #define glPushDebugGroupKHR __rglgen_glPushDebugGroupKHR #define glPopDebugGroupKHR __rglgen_glPopDebugGroupKHR #define glObjectLabelKHR __rglgen_glObjectLabelKHR #define glGetObjectLabelKHR __rglgen_glGetObjectLabelKHR #define glObjectPtrLabelKHR __rglgen_glObjectPtrLabelKHR #define glGetObjectPtrLabelKHR __rglgen_glGetObjectPtrLabelKHR #define glGetPointervKHR __rglgen_glGetPointervKHR #define glEGLImageTargetTexture2DOES __rglgen_glEGLImageTargetTexture2DOES #define glEGLImageTargetRenderbufferStorageOES __rglgen_glEGLImageTargetRenderbufferStorageOES #define glGetProgramBinaryOES __rglgen_glGetProgramBinaryOES #define glProgramBinaryOES __rglgen_glProgramBinaryOES #define glMapBufferOES __rglgen_glMapBufferOES #define glUnmapBufferOES __rglgen_glUnmapBufferOES #define glGetBufferPointervOES __rglgen_glGetBufferPointervOES #define glTexImage3DOES __rglgen_glTexImage3DOES #define glTexSubImage3DOES __rglgen_glTexSubImage3DOES #define glCopyTexSubImage3DOES __rglgen_glCopyTexSubImage3DOES #define glCompressedTexImage3DOES __rglgen_glCompressedTexImage3DOES #define glCompressedTexSubImage3DOES __rglgen_glCompressedTexSubImage3DOES #define glFramebufferTexture3DOES __rglgen_glFramebufferTexture3DOES #define glBindVertexArrayOES __rglgen_glBindVertexArrayOES #define glDeleteVertexArraysOES __rglgen_glDeleteVertexArraysOES #define glGenVertexArraysOES __rglgen_glGenVertexArraysOES #define glIsVertexArrayOES __rglgen_glIsVertexArrayOES extern RGLSYMGLDEBUGMESSAGECONTROLKHRPROC __rglgen_glDebugMessageControlKHR; extern RGLSYMGLDEBUGMESSAGEINSERTKHRPROC __rglgen_glDebugMessageInsertKHR; extern RGLSYMGLDEBUGMESSAGECALLBACKKHRPROC __rglgen_glDebugMessageCallbackKHR; extern RGLSYMGLGETDEBUGMESSAGELOGKHRPROC __rglgen_glGetDebugMessageLogKHR; extern RGLSYMGLPUSHDEBUGGROUPKHRPROC __rglgen_glPushDebugGroupKHR; extern RGLSYMGLPOPDEBUGGROUPKHRPROC __rglgen_glPopDebugGroupKHR; extern RGLSYMGLOBJECTLABELKHRPROC __rglgen_glObjectLabelKHR; extern RGLSYMGLGETOBJECTLABELKHRPROC __rglgen_glGetObjectLabelKHR; extern RGLSYMGLOBJECTPTRLABELKHRPROC __rglgen_glObjectPtrLabelKHR; extern RGLSYMGLGETOBJECTPTRLABELKHRPROC __rglgen_glGetObjectPtrLabelKHR; extern RGLSYMGLGETPOINTERVKHRPROC __rglgen_glGetPointervKHR; extern RGLSYMGLEGLIMAGETARGETTEXTURE2DOESPROC __rglgen_glEGLImageTargetTexture2DOES; extern RGLSYMGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC __rglgen_glEGLImageTargetRenderbufferStorageOES; extern RGLSYMGLGETPROGRAMBINARYOESPROC __rglgen_glGetProgramBinaryOES; extern RGLSYMGLPROGRAMBINARYOESPROC __rglgen_glProgramBinaryOES; extern RGLSYMGLMAPBUFFEROESPROC __rglgen_glMapBufferOES; extern RGLSYMGLUNMAPBUFFEROESPROC __rglgen_glUnmapBufferOES; extern RGLSYMGLGETBUFFERPOINTERVOESPROC __rglgen_glGetBufferPointervOES; extern RGLSYMGLTEXIMAGE3DOESPROC __rglgen_glTexImage3DOES; extern RGLSYMGLTEXSUBIMAGE3DOESPROC __rglgen_glTexSubImage3DOES; extern RGLSYMGLCOPYTEXSUBIMAGE3DOESPROC __rglgen_glCopyTexSubImage3DOES; extern RGLSYMGLCOMPRESSEDTEXIMAGE3DOESPROC __rglgen_glCompressedTexImage3DOES; extern RGLSYMGLCOMPRESSEDTEXSUBIMAGE3DOESPROC __rglgen_glCompressedTexSubImage3DOES; extern RGLSYMGLFRAMEBUFFERTEXTURE3DOESPROC __rglgen_glFramebufferTexture3DOES; extern RGLSYMGLBINDVERTEXARRAYOESPROC __rglgen_glBindVertexArrayOES; extern RGLSYMGLDELETEVERTEXARRAYSOESPROC __rglgen_glDeleteVertexArraysOES; extern RGLSYMGLGENVERTEXARRAYSOESPROC __rglgen_glGenVertexArraysOES; extern RGLSYMGLISVERTEXARRAYOESPROC __rglgen_glIsVertexArrayOES; struct rglgen_sym_map { const char *sym; void *ptr; }; extern const struct rglgen_sym_map rglgen_symbol_map[]; #ifdef __cplusplus } #endif #endif mupen64plus-video-gliden64/src/GLideNHQ/TextureFilters_hq4x.h000664 001750 001750 00000274740 12655644434 025105 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Based on Maxim Stepin and Rice1964 hq4x code */ switch (pattern) { case 0: case 1: case 4: case 32: case 128: case 5: case 132: case 160: case 33: case 129: case 36: case 133: case 164: case 161: case 37: case 165: { PIXEL00_20 PIXEL01_60 PIXEL02_60 PIXEL03_20 PIXEL10_60 PIXEL11_70 PIXEL12_70 PIXEL13_60 PIXEL20_60 PIXEL21_70 PIXEL22_70 PIXEL23_60 PIXEL30_20 PIXEL31_60 PIXEL32_60 PIXEL33_20 break; } case 2: case 34: case 130: case 162: { PIXEL00_80 PIXEL01_10 PIXEL02_10 PIXEL03_80 PIXEL10_61 PIXEL11_30 PIXEL12_30 PIXEL13_61 PIXEL20_60 PIXEL21_70 PIXEL22_70 PIXEL23_60 PIXEL30_20 PIXEL31_60 PIXEL32_60 PIXEL33_20 break; } case 16: case 17: case 48: case 49: { PIXEL00_20 PIXEL01_60 PIXEL02_61 PIXEL03_80 PIXEL10_60 PIXEL11_70 PIXEL12_30 PIXEL13_10 PIXEL20_60 PIXEL21_70 PIXEL22_30 PIXEL23_10 PIXEL30_20 PIXEL31_60 PIXEL32_61 PIXEL33_80 break; } case 64: case 65: case 68: case 69: { PIXEL00_20 PIXEL01_60 PIXEL02_60 PIXEL03_20 PIXEL10_60 PIXEL11_70 PIXEL12_70 PIXEL13_60 PIXEL20_61 PIXEL21_30 PIXEL22_30 PIXEL23_61 PIXEL30_80 PIXEL31_10 PIXEL32_10 PIXEL33_80 break; } case 8: case 12: case 136: case 140: { PIXEL00_80 PIXEL01_61 PIXEL02_60 PIXEL03_20 PIXEL10_10 PIXEL11_30 PIXEL12_70 PIXEL13_60 PIXEL20_10 PIXEL21_30 PIXEL22_70 PIXEL23_60 PIXEL30_80 PIXEL31_61 PIXEL32_60 PIXEL33_20 break; } case 3: case 35: case 131: case 163: { PIXEL00_81 PIXEL01_31 PIXEL02_10 PIXEL03_80 PIXEL10_81 PIXEL11_31 PIXEL12_30 PIXEL13_61 PIXEL20_60 PIXEL21_70 PIXEL22_70 PIXEL23_60 PIXEL30_20 PIXEL31_60 PIXEL32_60 PIXEL33_20 break; } case 6: case 38: case 134: case 166: { PIXEL00_80 PIXEL01_10 PIXEL02_32 PIXEL03_82 PIXEL10_61 PIXEL11_30 PIXEL12_32 PIXEL13_82 PIXEL20_60 PIXEL21_70 PIXEL22_70 PIXEL23_60 PIXEL30_20 PIXEL31_60 PIXEL32_60 PIXEL33_20 break; } case 20: case 21: case 52: case 53: { PIXEL00_20 PIXEL01_60 PIXEL02_81 PIXEL03_81 PIXEL10_60 PIXEL11_70 PIXEL12_31 PIXEL13_31 PIXEL20_60 PIXEL21_70 PIXEL22_30 PIXEL23_10 PIXEL30_20 PIXEL31_60 PIXEL32_61 PIXEL33_80 break; } case 144: case 145: case 176: case 177: { PIXEL00_20 PIXEL01_60 PIXEL02_61 PIXEL03_80 PIXEL10_60 PIXEL11_70 PIXEL12_30 PIXEL13_10 PIXEL20_60 PIXEL21_70 PIXEL22_32 PIXEL23_32 PIXEL30_20 PIXEL31_60 PIXEL32_82 PIXEL33_82 break; } case 192: case 193: case 196: case 197: { PIXEL00_20 PIXEL01_60 PIXEL02_60 PIXEL03_20 PIXEL10_60 PIXEL11_70 PIXEL12_70 PIXEL13_60 PIXEL20_61 PIXEL21_30 PIXEL22_31 PIXEL23_81 PIXEL30_80 PIXEL31_10 PIXEL32_31 PIXEL33_81 break; } case 96: case 97: case 100: case 101: { PIXEL00_20 PIXEL01_60 PIXEL02_60 PIXEL03_20 PIXEL10_60 PIXEL11_70 PIXEL12_70 PIXEL13_60 PIXEL20_82 PIXEL21_32 PIXEL22_30 PIXEL23_61 PIXEL30_82 PIXEL31_32 PIXEL32_10 PIXEL33_80 break; } case 40: case 44: case 168: case 172: { PIXEL00_80 PIXEL01_61 PIXEL02_60 PIXEL03_20 PIXEL10_10 PIXEL11_30 PIXEL12_70 PIXEL13_60 PIXEL20_31 PIXEL21_31 PIXEL22_70 PIXEL23_60 PIXEL30_81 PIXEL31_81 PIXEL32_60 PIXEL33_20 break; } case 9: case 13: case 137: case 141: { PIXEL00_82 PIXEL01_82 PIXEL02_60 PIXEL03_20 PIXEL10_32 PIXEL11_32 PIXEL12_70 PIXEL13_60 PIXEL20_10 PIXEL21_30 PIXEL22_70 PIXEL23_60 PIXEL30_80 PIXEL31_61 PIXEL32_60 PIXEL33_20 break; } case 18: case 50: { PIXEL00_80 PIXEL01_10 if (Diff(w[2], w[6])) { PIXEL02_10 PIXEL03_80 PIXEL12_30 PIXEL13_10 } else { PIXEL02_50 PIXEL03_50 PIXEL12_0 PIXEL13_50 } PIXEL10_61 PIXEL11_30 PIXEL20_60 PIXEL21_70 PIXEL22_30 PIXEL23_10 PIXEL30_20 PIXEL31_60 PIXEL32_61 PIXEL33_80 break; } case 80: case 81: { PIXEL00_20 PIXEL01_60 PIXEL02_61 PIXEL03_80 PIXEL10_60 PIXEL11_70 PIXEL12_30 PIXEL13_10 PIXEL20_61 PIXEL21_30 if (Diff(w[6], w[8])) { PIXEL22_30 PIXEL23_10 PIXEL32_10 PIXEL33_80 } else { PIXEL22_0 PIXEL23_50 PIXEL32_50 PIXEL33_50 } PIXEL30_80 PIXEL31_10 break; } case 72: case 76: { PIXEL00_80 PIXEL01_61 PIXEL02_60 PIXEL03_20 PIXEL10_10 PIXEL11_30 PIXEL12_70 PIXEL13_60 if (Diff(w[8], w[4])) { PIXEL20_10 PIXEL21_30 PIXEL30_80 PIXEL31_10 } else { PIXEL20_50 PIXEL21_0 PIXEL30_50 PIXEL31_50 } PIXEL22_30 PIXEL23_61 PIXEL32_10 PIXEL33_80 break; } case 10: case 138: { if (Diff(w[4], w[2])) { PIXEL00_80 PIXEL01_10 PIXEL10_10 PIXEL11_30 } else { PIXEL00_50 PIXEL01_50 PIXEL10_50 PIXEL11_0 } PIXEL02_10 PIXEL03_80 PIXEL12_30 PIXEL13_61 PIXEL20_10 PIXEL21_30 PIXEL22_70 PIXEL23_60 PIXEL30_80 PIXEL31_61 PIXEL32_60 PIXEL33_20 break; } case 66: { PIXEL00_80 PIXEL01_10 PIXEL02_10 PIXEL03_80 PIXEL10_61 PIXEL11_30 PIXEL12_30 PIXEL13_61 PIXEL20_61 PIXEL21_30 PIXEL22_30 PIXEL23_61 PIXEL30_80 PIXEL31_10 PIXEL32_10 PIXEL33_80 break; } case 24: { PIXEL00_80 PIXEL01_61 PIXEL02_61 PIXEL03_80 PIXEL10_10 PIXEL11_30 PIXEL12_30 PIXEL13_10 PIXEL20_10 PIXEL21_30 PIXEL22_30 PIXEL23_10 PIXEL30_80 PIXEL31_61 PIXEL32_61 PIXEL33_80 break; } case 7: case 39: case 135: { PIXEL00_81 PIXEL01_31 PIXEL02_32 PIXEL03_82 PIXEL10_81 PIXEL11_31 PIXEL12_32 PIXEL13_82 PIXEL20_60 PIXEL21_70 PIXEL22_70 PIXEL23_60 PIXEL30_20 PIXEL31_60 PIXEL32_60 PIXEL33_20 break; } case 148: case 149: case 180: { PIXEL00_20 PIXEL01_60 PIXEL02_81 PIXEL03_81 PIXEL10_60 PIXEL11_70 PIXEL12_31 PIXEL13_31 PIXEL20_60 PIXEL21_70 PIXEL22_32 PIXEL23_32 PIXEL30_20 PIXEL31_60 PIXEL32_82 PIXEL33_82 break; } case 224: case 228: case 225: { PIXEL00_20 PIXEL01_60 PIXEL02_60 PIXEL03_20 PIXEL10_60 PIXEL11_70 PIXEL12_70 PIXEL13_60 PIXEL20_82 PIXEL21_32 PIXEL22_31 PIXEL23_81 PIXEL30_82 PIXEL31_32 PIXEL32_31 PIXEL33_81 break; } case 41: case 169: case 45: { PIXEL00_82 PIXEL01_82 PIXEL02_60 PIXEL03_20 PIXEL10_32 PIXEL11_32 PIXEL12_70 PIXEL13_60 PIXEL20_31 PIXEL21_31 PIXEL22_70 PIXEL23_60 PIXEL30_81 PIXEL31_81 PIXEL32_60 PIXEL33_20 break; } case 22: case 54: { PIXEL00_80 PIXEL01_10 if (Diff(w[2], w[6])) { PIXEL02_0 PIXEL03_0 PIXEL13_0 } else { PIXEL02_50 PIXEL03_50 PIXEL13_50 } PIXEL10_61 PIXEL11_30 PIXEL12_0 PIXEL20_60 PIXEL21_70 PIXEL22_30 PIXEL23_10 PIXEL30_20 PIXEL31_60 PIXEL32_61 PIXEL33_80 break; } case 208: case 209: { PIXEL00_20 PIXEL01_60 PIXEL02_61 PIXEL03_80 PIXEL10_60 PIXEL11_70 PIXEL12_30 PIXEL13_10 PIXEL20_61 PIXEL21_30 PIXEL22_0 if (Diff(w[6], w[8])) { PIXEL23_0 PIXEL32_0 PIXEL33_0 } else { PIXEL23_50 PIXEL32_50 PIXEL33_50 } PIXEL30_80 PIXEL31_10 break; } case 104: case 108: { PIXEL00_80 PIXEL01_61 PIXEL02_60 PIXEL03_20 PIXEL10_10 PIXEL11_30 PIXEL12_70 PIXEL13_60 if (Diff(w[8], w[4])) { PIXEL20_0 PIXEL30_0 PIXEL31_0 } else { PIXEL20_50 PIXEL30_50 PIXEL31_50 } PIXEL21_0 PIXEL22_30 PIXEL23_61 PIXEL32_10 PIXEL33_80 break; } case 11: case 139: { if (Diff(w[4], w[2])) { PIXEL00_0 PIXEL01_0 PIXEL10_0 } else { PIXEL00_50 PIXEL01_50 PIXEL10_50 } PIXEL02_10 PIXEL03_80 PIXEL11_0 PIXEL12_30 PIXEL13_61 PIXEL20_10 PIXEL21_30 PIXEL22_70 PIXEL23_60 PIXEL30_80 PIXEL31_61 PIXEL32_60 PIXEL33_20 break; } case 19: case 51: { if (Diff(w[2], w[6])) { PIXEL00_81 PIXEL01_31 PIXEL02_10 PIXEL03_80 PIXEL12_30 PIXEL13_10 } else { PIXEL00_12 PIXEL01_14 PIXEL02_83 PIXEL03_50 PIXEL12_70 PIXEL13_21 } PIXEL10_81 PIXEL11_31 PIXEL20_60 PIXEL21_70 PIXEL22_30 PIXEL23_10 PIXEL30_20 PIXEL31_60 PIXEL32_61 PIXEL33_80 break; } case 146: case 178: { PIXEL00_80 PIXEL01_10 if (Diff(w[2], w[6])) { PIXEL02_10 PIXEL03_80 PIXEL12_30 PIXEL13_10 PIXEL23_32 PIXEL33_82 } else { PIXEL02_21 PIXEL03_50 PIXEL12_70 PIXEL13_83 PIXEL23_13 PIXEL33_11 } PIXEL10_61 PIXEL11_30 PIXEL20_60 PIXEL21_70 PIXEL22_32 PIXEL30_20 PIXEL31_60 PIXEL32_82 break; } case 84: case 85: { PIXEL00_20 PIXEL01_60 PIXEL02_81 if (Diff(w[6], w[8])) { PIXEL03_81 PIXEL13_31 PIXEL22_30 PIXEL23_10 PIXEL32_10 PIXEL33_80 } else { PIXEL03_12 PIXEL13_14 PIXEL22_70 PIXEL23_83 PIXEL32_21 PIXEL33_50 } PIXEL10_60 PIXEL11_70 PIXEL12_31 PIXEL20_61 PIXEL21_30 PIXEL30_80 PIXEL31_10 break; } case 112: case 113: { PIXEL00_20 PIXEL01_60 PIXEL02_61 PIXEL03_80 PIXEL10_60 PIXEL11_70 PIXEL12_30 PIXEL13_10 PIXEL20_82 PIXEL21_32 if (Diff(w[6], w[8])) { PIXEL22_30 PIXEL23_10 PIXEL30_82 PIXEL31_32 PIXEL32_10 PIXEL33_80 } else { PIXEL22_70 PIXEL23_21 PIXEL30_11 PIXEL31_13 PIXEL32_83 PIXEL33_50 } break; } case 200: case 204: { PIXEL00_80 PIXEL01_61 PIXEL02_60 PIXEL03_20 PIXEL10_10 PIXEL11_30 PIXEL12_70 PIXEL13_60 if (Diff(w[8], w[4])) { PIXEL20_10 PIXEL21_30 PIXEL30_80 PIXEL31_10 PIXEL32_31 PIXEL33_81 } else { PIXEL20_21 PIXEL21_70 PIXEL30_50 PIXEL31_83 PIXEL32_14 PIXEL33_12 } PIXEL22_31 PIXEL23_81 break; } case 73: case 77: { if (Diff(w[8], w[4])) { PIXEL00_82 PIXEL10_32 PIXEL20_10 PIXEL21_30 PIXEL30_80 PIXEL31_10 } else { PIXEL00_11 PIXEL10_13 PIXEL20_83 PIXEL21_70 PIXEL30_50 PIXEL31_21 } PIXEL01_82 PIXEL02_60 PIXEL03_20 PIXEL11_32 PIXEL12_70 PIXEL13_60 PIXEL22_30 PIXEL23_61 PIXEL32_10 PIXEL33_80 break; } case 42: case 170: { if (Diff(w[4], w[2])) { PIXEL00_80 PIXEL01_10 PIXEL10_10 PIXEL11_30 PIXEL20_31 PIXEL30_81 } else { PIXEL00_50 PIXEL01_21 PIXEL10_83 PIXEL11_70 PIXEL20_14 PIXEL30_12 } PIXEL02_10 PIXEL03_80 PIXEL12_30 PIXEL13_61 PIXEL21_31 PIXEL22_70 PIXEL23_60 PIXEL31_81 PIXEL32_60 PIXEL33_20 break; } case 14: case 142: { if (Diff(w[4], w[2])) { PIXEL00_80 PIXEL01_10 PIXEL02_32 PIXEL03_82 PIXEL10_10 PIXEL11_30 } else { PIXEL00_50 PIXEL01_83 PIXEL02_13 PIXEL03_11 PIXEL10_21 PIXEL11_70 } PIXEL12_32 PIXEL13_82 PIXEL20_10 PIXEL21_30 PIXEL22_70 PIXEL23_60 PIXEL30_80 PIXEL31_61 PIXEL32_60 PIXEL33_20 break; } case 67: { PIXEL00_81 PIXEL01_31 PIXEL02_10 PIXEL03_80 PIXEL10_81 PIXEL11_31 PIXEL12_30 PIXEL13_61 PIXEL20_61 PIXEL21_30 PIXEL22_30 PIXEL23_61 PIXEL30_80 PIXEL31_10 PIXEL32_10 PIXEL33_80 break; } case 70: { PIXEL00_80 PIXEL01_10 PIXEL02_32 PIXEL03_82 PIXEL10_61 PIXEL11_30 PIXEL12_32 PIXEL13_82 PIXEL20_61 PIXEL21_30 PIXEL22_30 PIXEL23_61 PIXEL30_80 PIXEL31_10 PIXEL32_10 PIXEL33_80 break; } case 28: { PIXEL00_80 PIXEL01_61 PIXEL02_81 PIXEL03_81 PIXEL10_10 PIXEL11_30 PIXEL12_31 PIXEL13_31 PIXEL20_10 PIXEL21_30 PIXEL22_30 PIXEL23_10 PIXEL30_80 PIXEL31_61 PIXEL32_61 PIXEL33_80 break; } case 152: { PIXEL00_80 PIXEL01_61 PIXEL02_61 PIXEL03_80 PIXEL10_10 PIXEL11_30 PIXEL12_30 PIXEL13_10 PIXEL20_10 PIXEL21_30 PIXEL22_32 PIXEL23_32 PIXEL30_80 PIXEL31_61 PIXEL32_82 PIXEL33_82 break; } case 194: { PIXEL00_80 PIXEL01_10 PIXEL02_10 PIXEL03_80 PIXEL10_61 PIXEL11_30 PIXEL12_30 PIXEL13_61 PIXEL20_61 PIXEL21_30 PIXEL22_31 PIXEL23_81 PIXEL30_80 PIXEL31_10 PIXEL32_31 PIXEL33_81 break; } case 98: { PIXEL00_80 PIXEL01_10 PIXEL02_10 PIXEL03_80 PIXEL10_61 PIXEL11_30 PIXEL12_30 PIXEL13_61 PIXEL20_82 PIXEL21_32 PIXEL22_30 PIXEL23_61 PIXEL30_82 PIXEL31_32 PIXEL32_10 PIXEL33_80 break; } case 56: { PIXEL00_80 PIXEL01_61 PIXEL02_61 PIXEL03_80 PIXEL10_10 PIXEL11_30 PIXEL12_30 PIXEL13_10 PIXEL20_31 PIXEL21_31 PIXEL22_30 PIXEL23_10 PIXEL30_81 PIXEL31_81 PIXEL32_61 PIXEL33_80 break; } case 25: { PIXEL00_82 PIXEL01_82 PIXEL02_61 PIXEL03_80 PIXEL10_32 PIXEL11_32 PIXEL12_30 PIXEL13_10 PIXEL20_10 PIXEL21_30 PIXEL22_30 PIXEL23_10 PIXEL30_80 PIXEL31_61 PIXEL32_61 PIXEL33_80 break; } case 26: case 31: { if (Diff(w[4], w[2])) { PIXEL00_0 PIXEL01_0 PIXEL10_0 } else { PIXEL00_50 PIXEL01_50 PIXEL10_50 } if (Diff(w[2], w[6])) { PIXEL02_0 PIXEL03_0 PIXEL13_0 } else { PIXEL02_50 PIXEL03_50 PIXEL13_50 } PIXEL11_0 PIXEL12_0 PIXEL20_10 PIXEL21_30 PIXEL22_30 PIXEL23_10 PIXEL30_80 PIXEL31_61 PIXEL32_61 PIXEL33_80 break; } case 82: case 214: { PIXEL00_80 PIXEL01_10 if (Diff(w[2], w[6])) { PIXEL02_0 PIXEL03_0 PIXEL13_0 } else { PIXEL02_50 PIXEL03_50 PIXEL13_50 } PIXEL10_61 PIXEL11_30 PIXEL12_0 PIXEL20_61 PIXEL21_30 PIXEL22_0 if (Diff(w[6], w[8])) { PIXEL23_0 PIXEL32_0 PIXEL33_0 } else { PIXEL23_50 PIXEL32_50 PIXEL33_50 } PIXEL30_80 PIXEL31_10 break; } case 88: case 248: { PIXEL00_80 PIXEL01_61 PIXEL02_61 PIXEL03_80 PIXEL10_10 PIXEL11_30 PIXEL12_30 PIXEL13_10 if (Diff(w[8], w[4])) { PIXEL20_0 PIXEL30_0 PIXEL31_0 } else { PIXEL20_50 PIXEL30_50 PIXEL31_50 } PIXEL21_0 PIXEL22_0 if (Diff(w[6], w[8])) { PIXEL23_0 PIXEL32_0 PIXEL33_0 } else { PIXEL23_50 PIXEL32_50 PIXEL33_50 } break; } case 74: case 107: { if (Diff(w[4], w[2])) { PIXEL00_0 PIXEL01_0 PIXEL10_0 } else { PIXEL00_50 PIXEL01_50 PIXEL10_50 } PIXEL02_10 PIXEL03_80 PIXEL11_0 PIXEL12_30 PIXEL13_61 if (Diff(w[8], w[4])) { PIXEL20_0 PIXEL30_0 PIXEL31_0 } else { PIXEL20_50 PIXEL30_50 PIXEL31_50 } PIXEL21_0 PIXEL22_30 PIXEL23_61 PIXEL32_10 PIXEL33_80 break; } case 27: { if (Diff(w[4], w[2])) { PIXEL00_0 PIXEL01_0 PIXEL10_0 } else { PIXEL00_50 PIXEL01_50 PIXEL10_50 } PIXEL02_10 PIXEL03_80 PIXEL11_0 PIXEL12_30 PIXEL13_10 PIXEL20_10 PIXEL21_30 PIXEL22_30 PIXEL23_10 PIXEL30_80 PIXEL31_61 PIXEL32_61 PIXEL33_80 break; } case 86: { PIXEL00_80 PIXEL01_10 if (Diff(w[2], w[6])) { PIXEL02_0 PIXEL03_0 PIXEL13_0 } else { PIXEL02_50 PIXEL03_50 PIXEL13_50 } PIXEL10_61 PIXEL11_30 PIXEL12_0 PIXEL20_61 PIXEL21_30 PIXEL22_30 PIXEL23_10 PIXEL30_80 PIXEL31_10 PIXEL32_10 PIXEL33_80 break; } case 216: { PIXEL00_80 PIXEL01_61 PIXEL02_61 PIXEL03_80 PIXEL10_10 PIXEL11_30 PIXEL12_30 PIXEL13_10 PIXEL20_10 PIXEL21_30 PIXEL22_0 if (Diff(w[6], w[8])) { PIXEL23_0 PIXEL32_0 PIXEL33_0 } else { PIXEL23_50 PIXEL32_50 PIXEL33_50 } PIXEL30_80 PIXEL31_10 break; } case 106: { PIXEL00_80 PIXEL01_10 PIXEL02_10 PIXEL03_80 PIXEL10_10 PIXEL11_30 PIXEL12_30 PIXEL13_61 if (Diff(w[8], w[4])) { PIXEL20_0 PIXEL30_0 PIXEL31_0 } else { PIXEL20_50 PIXEL30_50 PIXEL31_50 } PIXEL21_0 PIXEL22_30 PIXEL23_61 PIXEL32_10 PIXEL33_80 break; } case 30: { PIXEL00_80 PIXEL01_10 if (Diff(w[2], w[6])) { PIXEL02_0 PIXEL03_0 PIXEL13_0 } else { PIXEL02_50 PIXEL03_50 PIXEL13_50 } PIXEL10_10 PIXEL11_30 PIXEL12_0 PIXEL20_10 PIXEL21_30 PIXEL22_30 PIXEL23_10 PIXEL30_80 PIXEL31_61 PIXEL32_61 PIXEL33_80 break; } case 210: { PIXEL00_80 PIXEL01_10 PIXEL02_10 PIXEL03_80 PIXEL10_61 PIXEL11_30 PIXEL12_30 PIXEL13_10 PIXEL20_61 PIXEL21_30 PIXEL22_0 if (Diff(w[6], w[8])) { PIXEL23_0 PIXEL32_0 PIXEL33_0 } else { PIXEL23_50 PIXEL32_50 PIXEL33_50 } PIXEL30_80 PIXEL31_10 break; } case 120: { PIXEL00_80 PIXEL01_61 PIXEL02_61 PIXEL03_80 PIXEL10_10 PIXEL11_30 PIXEL12_30 PIXEL13_10 if (Diff(w[8], w[4])) { PIXEL20_0 PIXEL30_0 PIXEL31_0 } else { PIXEL20_50 PIXEL30_50 PIXEL31_50 } PIXEL21_0 PIXEL22_30 PIXEL23_10 PIXEL32_10 PIXEL33_80 break; } case 75: { if (Diff(w[4], w[2])) { PIXEL00_0 PIXEL01_0 PIXEL10_0 } else { PIXEL00_50 PIXEL01_50 PIXEL10_50 } PIXEL02_10 PIXEL03_80 PIXEL11_0 PIXEL12_30 PIXEL13_61 PIXEL20_10 PIXEL21_30 PIXEL22_30 PIXEL23_61 PIXEL30_80 PIXEL31_10 PIXEL32_10 PIXEL33_80 break; } case 29: { PIXEL00_82 PIXEL01_82 PIXEL02_81 PIXEL03_81 PIXEL10_32 PIXEL11_32 PIXEL12_31 PIXEL13_31 PIXEL20_10 PIXEL21_30 PIXEL22_30 PIXEL23_10 PIXEL30_80 PIXEL31_61 PIXEL32_61 PIXEL33_80 break; } case 198: { PIXEL00_80 PIXEL01_10 PIXEL02_32 PIXEL03_82 PIXEL10_61 PIXEL11_30 PIXEL12_32 PIXEL13_82 PIXEL20_61 PIXEL21_30 PIXEL22_31 PIXEL23_81 PIXEL30_80 PIXEL31_10 PIXEL32_31 PIXEL33_81 break; } case 184: { PIXEL00_80 PIXEL01_61 PIXEL02_61 PIXEL03_80 PIXEL10_10 PIXEL11_30 PIXEL12_30 PIXEL13_10 PIXEL20_31 PIXEL21_31 PIXEL22_32 PIXEL23_32 PIXEL30_81 PIXEL31_81 PIXEL32_82 PIXEL33_82 break; } case 99: { PIXEL00_81 PIXEL01_31 PIXEL02_10 PIXEL03_80 PIXEL10_81 PIXEL11_31 PIXEL12_30 PIXEL13_61 PIXEL20_82 PIXEL21_32 PIXEL22_30 PIXEL23_61 PIXEL30_82 PIXEL31_32 PIXEL32_10 PIXEL33_80 break; } case 57: { PIXEL00_82 PIXEL01_82 PIXEL02_61 PIXEL03_80 PIXEL10_32 PIXEL11_32 PIXEL12_30 PIXEL13_10 PIXEL20_31 PIXEL21_31 PIXEL22_30 PIXEL23_10 PIXEL30_81 PIXEL31_81 PIXEL32_61 PIXEL33_80 break; } case 71: { PIXEL00_81 PIXEL01_31 PIXEL02_32 PIXEL03_82 PIXEL10_81 PIXEL11_31 PIXEL12_32 PIXEL13_82 PIXEL20_61 PIXEL21_30 PIXEL22_30 PIXEL23_61 PIXEL30_80 PIXEL31_10 PIXEL32_10 PIXEL33_80 break; } case 156: { PIXEL00_80 PIXEL01_61 PIXEL02_81 PIXEL03_81 PIXEL10_10 PIXEL11_30 PIXEL12_31 PIXEL13_31 PIXEL20_10 PIXEL21_30 PIXEL22_32 PIXEL23_32 PIXEL30_80 PIXEL31_61 PIXEL32_82 PIXEL33_82 break; } case 226: { PIXEL00_80 PIXEL01_10 PIXEL02_10 PIXEL03_80 PIXEL10_61 PIXEL11_30 PIXEL12_30 PIXEL13_61 PIXEL20_82 PIXEL21_32 PIXEL22_31 PIXEL23_81 PIXEL30_82 PIXEL31_32 PIXEL32_31 PIXEL33_81 break; } case 60: { PIXEL00_80 PIXEL01_61 PIXEL02_81 PIXEL03_81 PIXEL10_10 PIXEL11_30 PIXEL12_31 PIXEL13_31 PIXEL20_31 PIXEL21_31 PIXEL22_30 PIXEL23_10 PIXEL30_81 PIXEL31_81 PIXEL32_61 PIXEL33_80 break; } case 195: { PIXEL00_81 PIXEL01_31 PIXEL02_10 PIXEL03_80 PIXEL10_81 PIXEL11_31 PIXEL12_30 PIXEL13_61 PIXEL20_61 PIXEL21_30 PIXEL22_31 PIXEL23_81 PIXEL30_80 PIXEL31_10 PIXEL32_31 PIXEL33_81 break; } case 102: { PIXEL00_80 PIXEL01_10 PIXEL02_32 PIXEL03_82 PIXEL10_61 PIXEL11_30 PIXEL12_32 PIXEL13_82 PIXEL20_82 PIXEL21_32 PIXEL22_30 PIXEL23_61 PIXEL30_82 PIXEL31_32 PIXEL32_10 PIXEL33_80 break; } case 153: { PIXEL00_82 PIXEL01_82 PIXEL02_61 PIXEL03_80 PIXEL10_32 PIXEL11_32 PIXEL12_30 PIXEL13_10 PIXEL20_10 PIXEL21_30 PIXEL22_32 PIXEL23_32 PIXEL30_80 PIXEL31_61 PIXEL32_82 PIXEL33_82 break; } case 58: { if (Diff(w[4], w[2])) { PIXEL00_80 PIXEL01_10 PIXEL10_10 PIXEL11_30 } else { PIXEL00_20 PIXEL01_12 PIXEL10_11 PIXEL11_0 } if (Diff(w[2], w[6])) { PIXEL02_10 PIXEL03_80 PIXEL12_30 PIXEL13_10 } else { PIXEL02_11 PIXEL03_20 PIXEL12_0 PIXEL13_12 } PIXEL20_31 PIXEL21_31 PIXEL22_30 PIXEL23_10 PIXEL30_81 PIXEL31_81 PIXEL32_61 PIXEL33_80 break; } case 83: { PIXEL00_81 PIXEL01_31 if (Diff(w[2], w[6])) { PIXEL02_10 PIXEL03_80 PIXEL12_30 PIXEL13_10 } else { PIXEL02_11 PIXEL03_20 PIXEL12_0 PIXEL13_12 } PIXEL10_81 PIXEL11_31 PIXEL20_61 PIXEL21_30 if (Diff(w[6], w[8])) { PIXEL22_30 PIXEL23_10 PIXEL32_10 PIXEL33_80 } else { PIXEL22_0 PIXEL23_11 PIXEL32_12 PIXEL33_20 } PIXEL30_80 PIXEL31_10 break; } case 92: { PIXEL00_80 PIXEL01_61 PIXEL02_81 PIXEL03_81 PIXEL10_10 PIXEL11_30 PIXEL12_31 PIXEL13_31 if (Diff(w[8], w[4])) { PIXEL20_10 PIXEL21_30 PIXEL30_80 PIXEL31_10 } else { PIXEL20_12 PIXEL21_0 PIXEL30_20 PIXEL31_11 } if (Diff(w[6], w[8])) { PIXEL22_30 PIXEL23_10 PIXEL32_10 PIXEL33_80 } else { PIXEL22_0 PIXEL23_11 PIXEL32_12 PIXEL33_20 } break; } case 202: { if (Diff(w[4], w[2])) { PIXEL00_80 PIXEL01_10 PIXEL10_10 PIXEL11_30 } else { PIXEL00_20 PIXEL01_12 PIXEL10_11 PIXEL11_0 } PIXEL02_10 PIXEL03_80 PIXEL12_30 PIXEL13_61 if (Diff(w[8], w[4])) { PIXEL20_10 PIXEL21_30 PIXEL30_80 PIXEL31_10 } else { PIXEL20_12 PIXEL21_0 PIXEL30_20 PIXEL31_11 } PIXEL22_31 PIXEL23_81 PIXEL32_31 PIXEL33_81 break; } case 78: { if (Diff(w[4], w[2])) { PIXEL00_80 PIXEL01_10 PIXEL10_10 PIXEL11_30 } else { PIXEL00_20 PIXEL01_12 PIXEL10_11 PIXEL11_0 } PIXEL02_32 PIXEL03_82 PIXEL12_32 PIXEL13_82 if (Diff(w[8], w[4])) { PIXEL20_10 PIXEL21_30 PIXEL30_80 PIXEL31_10 } else { PIXEL20_12 PIXEL21_0 PIXEL30_20 PIXEL31_11 } PIXEL22_30 PIXEL23_61 PIXEL32_10 PIXEL33_80 break; } case 154: { if (Diff(w[4], w[2])) { PIXEL00_80 PIXEL01_10 PIXEL10_10 PIXEL11_30 } else { PIXEL00_20 PIXEL01_12 PIXEL10_11 PIXEL11_0 } if (Diff(w[2], w[6])) { PIXEL02_10 PIXEL03_80 PIXEL12_30 PIXEL13_10 } else { PIXEL02_11 PIXEL03_20 PIXEL12_0 PIXEL13_12 } PIXEL20_10 PIXEL21_30 PIXEL22_32 PIXEL23_32 PIXEL30_80 PIXEL31_61 PIXEL32_82 PIXEL33_82 break; } case 114: { PIXEL00_80 PIXEL01_10 if (Diff(w[2], w[6])) { PIXEL02_10 PIXEL03_80 PIXEL12_30 PIXEL13_10 } else { PIXEL02_11 PIXEL03_20 PIXEL12_0 PIXEL13_12 } PIXEL10_61 PIXEL11_30 PIXEL20_82 PIXEL21_32 if (Diff(w[6], w[8])) { PIXEL22_30 PIXEL23_10 PIXEL32_10 PIXEL33_80 } else { PIXEL22_0 PIXEL23_11 PIXEL32_12 PIXEL33_20 } PIXEL30_82 PIXEL31_32 break; } case 89: { PIXEL00_82 PIXEL01_82 PIXEL02_61 PIXEL03_80 PIXEL10_32 PIXEL11_32 PIXEL12_30 PIXEL13_10 if (Diff(w[8], w[4])) { PIXEL20_10 PIXEL21_30 PIXEL30_80 PIXEL31_10 } else { PIXEL20_12 PIXEL21_0 PIXEL30_20 PIXEL31_11 } if (Diff(w[6], w[8])) { PIXEL22_30 PIXEL23_10 PIXEL32_10 PIXEL33_80 } else { PIXEL22_0 PIXEL23_11 PIXEL32_12 PIXEL33_20 } break; } case 90: { if (Diff(w[4], w[2])) { PIXEL00_80 PIXEL01_10 PIXEL10_10 PIXEL11_30 } else { PIXEL00_20 PIXEL01_12 PIXEL10_11 PIXEL11_0 } if (Diff(w[2], w[6])) { PIXEL02_10 PIXEL03_80 PIXEL12_30 PIXEL13_10 } else { PIXEL02_11 PIXEL03_20 PIXEL12_0 PIXEL13_12 } if (Diff(w[8], w[4])) { PIXEL20_10 PIXEL21_30 PIXEL30_80 PIXEL31_10 } else { PIXEL20_12 PIXEL21_0 PIXEL30_20 PIXEL31_11 } if (Diff(w[6], w[8])) { PIXEL22_30 PIXEL23_10 PIXEL32_10 PIXEL33_80 } else { PIXEL22_0 PIXEL23_11 PIXEL32_12 PIXEL33_20 } break; } case 55: case 23: { if (Diff(w[2], w[6])) { PIXEL00_81 PIXEL01_31 PIXEL02_0 PIXEL03_0 PIXEL12_0 PIXEL13_0 } else { PIXEL00_12 PIXEL01_14 PIXEL02_83 PIXEL03_50 PIXEL12_70 PIXEL13_21 } PIXEL10_81 PIXEL11_31 PIXEL20_60 PIXEL21_70 PIXEL22_30 PIXEL23_10 PIXEL30_20 PIXEL31_60 PIXEL32_61 PIXEL33_80 break; } case 182: case 150: { PIXEL00_80 PIXEL01_10 if (Diff(w[2], w[6])) { PIXEL02_0 PIXEL03_0 PIXEL12_0 PIXEL13_0 PIXEL23_32 PIXEL33_82 } else { PIXEL02_21 PIXEL03_50 PIXEL12_70 PIXEL13_83 PIXEL23_13 PIXEL33_11 } PIXEL10_61 PIXEL11_30 PIXEL20_60 PIXEL21_70 PIXEL22_32 PIXEL30_20 PIXEL31_60 PIXEL32_82 break; } case 213: case 212: { PIXEL00_20 PIXEL01_60 PIXEL02_81 if (Diff(w[6], w[8])) { PIXEL03_81 PIXEL13_31 PIXEL22_0 PIXEL23_0 PIXEL32_0 PIXEL33_0 } else { PIXEL03_12 PIXEL13_14 PIXEL22_70 PIXEL23_83 PIXEL32_21 PIXEL33_50 } PIXEL10_60 PIXEL11_70 PIXEL12_31 PIXEL20_61 PIXEL21_30 PIXEL30_80 PIXEL31_10 break; } case 241: case 240: { PIXEL00_20 PIXEL01_60 PIXEL02_61 PIXEL03_80 PIXEL10_60 PIXEL11_70 PIXEL12_30 PIXEL13_10 PIXEL20_82 PIXEL21_32 if (Diff(w[6], w[8])) { PIXEL22_0 PIXEL23_0 PIXEL30_82 PIXEL31_32 PIXEL32_0 PIXEL33_0 } else { PIXEL22_70 PIXEL23_21 PIXEL30_11 PIXEL31_13 PIXEL32_83 PIXEL33_50 } break; } case 236: case 232: { PIXEL00_80 PIXEL01_61 PIXEL02_60 PIXEL03_20 PIXEL10_10 PIXEL11_30 PIXEL12_70 PIXEL13_60 if (Diff(w[8], w[4])) { PIXEL20_0 PIXEL21_0 PIXEL30_0 PIXEL31_0 PIXEL32_31 PIXEL33_81 } else { PIXEL20_21 PIXEL21_70 PIXEL30_50 PIXEL31_83 PIXEL32_14 PIXEL33_12 } PIXEL22_31 PIXEL23_81 break; } case 109: case 105: { if (Diff(w[8], w[4])) { PIXEL00_82 PIXEL10_32 PIXEL20_0 PIXEL21_0 PIXEL30_0 PIXEL31_0 } else { PIXEL00_11 PIXEL10_13 PIXEL20_83 PIXEL21_70 PIXEL30_50 PIXEL31_21 } PIXEL01_82 PIXEL02_60 PIXEL03_20 PIXEL11_32 PIXEL12_70 PIXEL13_60 PIXEL22_30 PIXEL23_61 PIXEL32_10 PIXEL33_80 break; } case 171: case 43: { if (Diff(w[4], w[2])) { PIXEL00_0 PIXEL01_0 PIXEL10_0 PIXEL11_0 PIXEL20_31 PIXEL30_81 } else { PIXEL00_50 PIXEL01_21 PIXEL10_83 PIXEL11_70 PIXEL20_14 PIXEL30_12 } PIXEL02_10 PIXEL03_80 PIXEL12_30 PIXEL13_61 PIXEL21_31 PIXEL22_70 PIXEL23_60 PIXEL31_81 PIXEL32_60 PIXEL33_20 break; } case 143: case 15: { if (Diff(w[4], w[2])) { PIXEL00_0 PIXEL01_0 PIXEL02_32 PIXEL03_82 PIXEL10_0 PIXEL11_0 } else { PIXEL00_50 PIXEL01_83 PIXEL02_13 PIXEL03_11 PIXEL10_21 PIXEL11_70 } PIXEL12_32 PIXEL13_82 PIXEL20_10 PIXEL21_30 PIXEL22_70 PIXEL23_60 PIXEL30_80 PIXEL31_61 PIXEL32_60 PIXEL33_20 break; } case 124: { PIXEL00_80 PIXEL01_61 PIXEL02_81 PIXEL03_81 PIXEL10_10 PIXEL11_30 PIXEL12_31 PIXEL13_31 if (Diff(w[8], w[4])) { PIXEL20_0 PIXEL30_0 PIXEL31_0 } else { PIXEL20_50 PIXEL30_50 PIXEL31_50 } PIXEL21_0 PIXEL22_30 PIXEL23_10 PIXEL32_10 PIXEL33_80 break; } case 203: { if (Diff(w[4], w[2])) { PIXEL00_0 PIXEL01_0 PIXEL10_0 } else { PIXEL00_50 PIXEL01_50 PIXEL10_50 } PIXEL02_10 PIXEL03_80 PIXEL11_0 PIXEL12_30 PIXEL13_61 PIXEL20_10 PIXEL21_30 PIXEL22_31 PIXEL23_81 PIXEL30_80 PIXEL31_10 PIXEL32_31 PIXEL33_81 break; } case 62: { PIXEL00_80 PIXEL01_10 if (Diff(w[2], w[6])) { PIXEL02_0 PIXEL03_0 PIXEL13_0 } else { PIXEL02_50 PIXEL03_50 PIXEL13_50 } PIXEL10_10 PIXEL11_30 PIXEL12_0 PIXEL20_31 PIXEL21_31 PIXEL22_30 PIXEL23_10 PIXEL30_81 PIXEL31_81 PIXEL32_61 PIXEL33_80 break; } case 211: { PIXEL00_81 PIXEL01_31 PIXEL02_10 PIXEL03_80 PIXEL10_81 PIXEL11_31 PIXEL12_30 PIXEL13_10 PIXEL20_61 PIXEL21_30 PIXEL22_0 if (Diff(w[6], w[8])) { PIXEL23_0 PIXEL32_0 PIXEL33_0 } else { PIXEL23_50 PIXEL32_50 PIXEL33_50 } PIXEL30_80 PIXEL31_10 break; } case 118: { PIXEL00_80 PIXEL01_10 if (Diff(w[2], w[6])) { PIXEL02_0 PIXEL03_0 PIXEL13_0 } else { PIXEL02_50 PIXEL03_50 PIXEL13_50 } PIXEL10_61 PIXEL11_30 PIXEL12_0 PIXEL20_82 PIXEL21_32 PIXEL22_30 PIXEL23_10 PIXEL30_82 PIXEL31_32 PIXEL32_10 PIXEL33_80 break; } case 217: { PIXEL00_82 PIXEL01_82 PIXEL02_61 PIXEL03_80 PIXEL10_32 PIXEL11_32 PIXEL12_30 PIXEL13_10 PIXEL20_10 PIXEL21_30 PIXEL22_0 if (Diff(w[6], w[8])) { PIXEL23_0 PIXEL32_0 PIXEL33_0 } else { PIXEL23_50 PIXEL32_50 PIXEL33_50 } PIXEL30_80 PIXEL31_10 break; } case 110: { PIXEL00_80 PIXEL01_10 PIXEL02_32 PIXEL03_82 PIXEL10_10 PIXEL11_30 PIXEL12_32 PIXEL13_82 if (Diff(w[8], w[4])) { PIXEL20_0 PIXEL30_0 PIXEL31_0 } else { PIXEL20_50 PIXEL30_50 PIXEL31_50 } PIXEL21_0 PIXEL22_30 PIXEL23_61 PIXEL32_10 PIXEL33_80 break; } case 155: { if (Diff(w[4], w[2])) { PIXEL00_0 PIXEL01_0 PIXEL10_0 } else { PIXEL00_50 PIXEL01_50 PIXEL10_50 } PIXEL02_10 PIXEL03_80 PIXEL11_0 PIXEL12_30 PIXEL13_10 PIXEL20_10 PIXEL21_30 PIXEL22_32 PIXEL23_32 PIXEL30_80 PIXEL31_61 PIXEL32_82 PIXEL33_82 break; } case 188: { PIXEL00_80 PIXEL01_61 PIXEL02_81 PIXEL03_81 PIXEL10_10 PIXEL11_30 PIXEL12_31 PIXEL13_31 PIXEL20_31 PIXEL21_31 PIXEL22_32 PIXEL23_32 PIXEL30_81 PIXEL31_81 PIXEL32_82 PIXEL33_82 break; } case 185: { PIXEL00_82 PIXEL01_82 PIXEL02_61 PIXEL03_80 PIXEL10_32 PIXEL11_32 PIXEL12_30 PIXEL13_10 PIXEL20_31 PIXEL21_31 PIXEL22_32 PIXEL23_32 PIXEL30_81 PIXEL31_81 PIXEL32_82 PIXEL33_82 break; } case 61: { PIXEL00_82 PIXEL01_82 PIXEL02_81 PIXEL03_81 PIXEL10_32 PIXEL11_32 PIXEL12_31 PIXEL13_31 PIXEL20_31 PIXEL21_31 PIXEL22_30 PIXEL23_10 PIXEL30_81 PIXEL31_81 PIXEL32_61 PIXEL33_80 break; } case 157: { PIXEL00_82 PIXEL01_82 PIXEL02_81 PIXEL03_81 PIXEL10_32 PIXEL11_32 PIXEL12_31 PIXEL13_31 PIXEL20_10 PIXEL21_30 PIXEL22_32 PIXEL23_32 PIXEL30_80 PIXEL31_61 PIXEL32_82 PIXEL33_82 break; } case 103: { PIXEL00_81 PIXEL01_31 PIXEL02_32 PIXEL03_82 PIXEL10_81 PIXEL11_31 PIXEL12_32 PIXEL13_82 PIXEL20_82 PIXEL21_32 PIXEL22_30 PIXEL23_61 PIXEL30_82 PIXEL31_32 PIXEL32_10 PIXEL33_80 break; } case 227: { PIXEL00_81 PIXEL01_31 PIXEL02_10 PIXEL03_80 PIXEL10_81 PIXEL11_31 PIXEL12_30 PIXEL13_61 PIXEL20_82 PIXEL21_32 PIXEL22_31 PIXEL23_81 PIXEL30_82 PIXEL31_32 PIXEL32_31 PIXEL33_81 break; } case 230: { PIXEL00_80 PIXEL01_10 PIXEL02_32 PIXEL03_82 PIXEL10_61 PIXEL11_30 PIXEL12_32 PIXEL13_82 PIXEL20_82 PIXEL21_32 PIXEL22_31 PIXEL23_81 PIXEL30_82 PIXEL31_32 PIXEL32_31 PIXEL33_81 break; } case 199: { PIXEL00_81 PIXEL01_31 PIXEL02_32 PIXEL03_82 PIXEL10_81 PIXEL11_31 PIXEL12_32 PIXEL13_82 PIXEL20_61 PIXEL21_30 PIXEL22_31 PIXEL23_81 PIXEL30_80 PIXEL31_10 PIXEL32_31 PIXEL33_81 break; } case 220: { PIXEL00_80 PIXEL01_61 PIXEL02_81 PIXEL03_81 PIXEL10_10 PIXEL11_30 PIXEL12_31 PIXEL13_31 if (Diff(w[8], w[4])) { PIXEL20_10 PIXEL21_30 PIXEL30_80 PIXEL31_10 } else { PIXEL20_12 PIXEL21_0 PIXEL30_20 PIXEL31_11 } PIXEL22_0 if (Diff(w[6], w[8])) { PIXEL23_0 PIXEL32_0 PIXEL33_0 } else { PIXEL23_50 PIXEL32_50 PIXEL33_50 } break; } case 158: { if (Diff(w[4], w[2])) { PIXEL00_80 PIXEL01_10 PIXEL10_10 PIXEL11_30 } else { PIXEL00_20 PIXEL01_12 PIXEL10_11 PIXEL11_0 } if (Diff(w[2], w[6])) { PIXEL02_0 PIXEL03_0 PIXEL13_0 } else { PIXEL02_50 PIXEL03_50 PIXEL13_50 } PIXEL12_0 PIXEL20_10 PIXEL21_30 PIXEL22_32 PIXEL23_32 PIXEL30_80 PIXEL31_61 PIXEL32_82 PIXEL33_82 break; } case 234: { if (Diff(w[4], w[2])) { PIXEL00_80 PIXEL01_10 PIXEL10_10 PIXEL11_30 } else { PIXEL00_20 PIXEL01_12 PIXEL10_11 PIXEL11_0 } PIXEL02_10 PIXEL03_80 PIXEL12_30 PIXEL13_61 if (Diff(w[8], w[4])) { PIXEL20_0 PIXEL30_0 PIXEL31_0 } else { PIXEL20_50 PIXEL30_50 PIXEL31_50 } PIXEL21_0 PIXEL22_31 PIXEL23_81 PIXEL32_31 PIXEL33_81 break; } case 242: { PIXEL00_80 PIXEL01_10 if (Diff(w[2], w[6])) { PIXEL02_10 PIXEL03_80 PIXEL12_30 PIXEL13_10 } else { PIXEL02_11 PIXEL03_20 PIXEL12_0 PIXEL13_12 } PIXEL10_61 PIXEL11_30 PIXEL20_82 PIXEL21_32 PIXEL22_0 if (Diff(w[6], w[8])) { PIXEL23_0 PIXEL32_0 PIXEL33_0 } else { PIXEL23_50 PIXEL32_50 PIXEL33_50 } PIXEL30_82 PIXEL31_32 break; } case 59: { if (Diff(w[4], w[2])) { PIXEL00_0 PIXEL01_0 PIXEL10_0 } else { PIXEL00_50 PIXEL01_50 PIXEL10_50 } if (Diff(w[2], w[6])) { PIXEL02_10 PIXEL03_80 PIXEL12_30 PIXEL13_10 } else { PIXEL02_11 PIXEL03_20 PIXEL12_0 PIXEL13_12 } PIXEL11_0 PIXEL20_31 PIXEL21_31 PIXEL22_30 PIXEL23_10 PIXEL30_81 PIXEL31_81 PIXEL32_61 PIXEL33_80 break; } case 121: { PIXEL00_82 PIXEL01_82 PIXEL02_61 PIXEL03_80 PIXEL10_32 PIXEL11_32 PIXEL12_30 PIXEL13_10 if (Diff(w[8], w[4])) { PIXEL20_0 PIXEL30_0 PIXEL31_0 } else { PIXEL20_50 PIXEL30_50 PIXEL31_50 } PIXEL21_0 if (Diff(w[6], w[8])) { PIXEL22_30 PIXEL23_10 PIXEL32_10 PIXEL33_80 } else { PIXEL22_0 PIXEL23_11 PIXEL32_12 PIXEL33_20 } break; } case 87: { PIXEL00_81 PIXEL01_31 if (Diff(w[2], w[6])) { PIXEL02_0 PIXEL03_0 PIXEL13_0 } else { PIXEL02_50 PIXEL03_50 PIXEL13_50 } PIXEL10_81 PIXEL11_31 PIXEL12_0 PIXEL20_61 PIXEL21_30 if (Diff(w[6], w[8])) { PIXEL22_30 PIXEL23_10 PIXEL32_10 PIXEL33_80 } else { PIXEL22_0 PIXEL23_11 PIXEL32_12 PIXEL33_20 } PIXEL30_80 PIXEL31_10 break; } case 79: { if (Diff(w[4], w[2])) { PIXEL00_0 PIXEL01_0 PIXEL10_0 } else { PIXEL00_50 PIXEL01_50 PIXEL10_50 } PIXEL02_32 PIXEL03_82 PIXEL11_0 PIXEL12_32 PIXEL13_82 if (Diff(w[8], w[4])) { PIXEL20_10 PIXEL21_30 PIXEL30_80 PIXEL31_10 } else { PIXEL20_12 PIXEL21_0 PIXEL30_20 PIXEL31_11 } PIXEL22_30 PIXEL23_61 PIXEL32_10 PIXEL33_80 break; } case 122: { if (Diff(w[4], w[2])) { PIXEL00_80 PIXEL01_10 PIXEL10_10 PIXEL11_30 } else { PIXEL00_20 PIXEL01_12 PIXEL10_11 PIXEL11_0 } if (Diff(w[2], w[6])) { PIXEL02_10 PIXEL03_80 PIXEL12_30 PIXEL13_10 } else { PIXEL02_11 PIXEL03_20 PIXEL12_0 PIXEL13_12 } if (Diff(w[8], w[4])) { PIXEL20_0 PIXEL30_0 PIXEL31_0 } else { PIXEL20_50 PIXEL30_50 PIXEL31_50 } PIXEL21_0 if (Diff(w[6], w[8])) { PIXEL22_30 PIXEL23_10 PIXEL32_10 PIXEL33_80 } else { PIXEL22_0 PIXEL23_11 PIXEL32_12 PIXEL33_20 } break; } case 94: { if (Diff(w[4], w[2])) { PIXEL00_80 PIXEL01_10 PIXEL10_10 PIXEL11_30 } else { PIXEL00_20 PIXEL01_12 PIXEL10_11 PIXEL11_0 } if (Diff(w[2], w[6])) { PIXEL02_0 PIXEL03_0 PIXEL13_0 } else { PIXEL02_50 PIXEL03_50 PIXEL13_50 } PIXEL12_0 if (Diff(w[8], w[4])) { PIXEL20_10 PIXEL21_30 PIXEL30_80 PIXEL31_10 } else { PIXEL20_12 PIXEL21_0 PIXEL30_20 PIXEL31_11 } if (Diff(w[6], w[8])) { PIXEL22_30 PIXEL23_10 PIXEL32_10 PIXEL33_80 } else { PIXEL22_0 PIXEL23_11 PIXEL32_12 PIXEL33_20 } break; } case 218: { if (Diff(w[4], w[2])) { PIXEL00_80 PIXEL01_10 PIXEL10_10 PIXEL11_30 } else { PIXEL00_20 PIXEL01_12 PIXEL10_11 PIXEL11_0 } if (Diff(w[2], w[6])) { PIXEL02_10 PIXEL03_80 PIXEL12_30 PIXEL13_10 } else { PIXEL02_11 PIXEL03_20 PIXEL12_0 PIXEL13_12 } if (Diff(w[8], w[4])) { PIXEL20_10 PIXEL21_30 PIXEL30_80 PIXEL31_10 } else { PIXEL20_12 PIXEL21_0 PIXEL30_20 PIXEL31_11 } PIXEL22_0 if (Diff(w[6], w[8])) { PIXEL23_0 PIXEL32_0 PIXEL33_0 } else { PIXEL23_50 PIXEL32_50 PIXEL33_50 } break; } case 91: { if (Diff(w[4], w[2])) { PIXEL00_0 PIXEL01_0 PIXEL10_0 } else { PIXEL00_50 PIXEL01_50 PIXEL10_50 } if (Diff(w[2], w[6])) { PIXEL02_10 PIXEL03_80 PIXEL12_30 PIXEL13_10 } else { PIXEL02_11 PIXEL03_20 PIXEL12_0 PIXEL13_12 } PIXEL11_0 if (Diff(w[8], w[4])) { PIXEL20_10 PIXEL21_30 PIXEL30_80 PIXEL31_10 } else { PIXEL20_12 PIXEL21_0 PIXEL30_20 PIXEL31_11 } if (Diff(w[6], w[8])) { PIXEL22_30 PIXEL23_10 PIXEL32_10 PIXEL33_80 } else { PIXEL22_0 PIXEL23_11 PIXEL32_12 PIXEL33_20 } break; } case 229: { PIXEL00_20 PIXEL01_60 PIXEL02_60 PIXEL03_20 PIXEL10_60 PIXEL11_70 PIXEL12_70 PIXEL13_60 PIXEL20_82 PIXEL21_32 PIXEL22_31 PIXEL23_81 PIXEL30_82 PIXEL31_32 PIXEL32_31 PIXEL33_81 break; } case 167: { PIXEL00_81 PIXEL01_31 PIXEL02_32 PIXEL03_82 PIXEL10_81 PIXEL11_31 PIXEL12_32 PIXEL13_82 PIXEL20_60 PIXEL21_70 PIXEL22_70 PIXEL23_60 PIXEL30_20 PIXEL31_60 PIXEL32_60 PIXEL33_20 break; } case 173: { PIXEL00_82 PIXEL01_82 PIXEL02_60 PIXEL03_20 PIXEL10_32 PIXEL11_32 PIXEL12_70 PIXEL13_60 PIXEL20_31 PIXEL21_31 PIXEL22_70 PIXEL23_60 PIXEL30_81 PIXEL31_81 PIXEL32_60 PIXEL33_20 break; } case 181: { PIXEL00_20 PIXEL01_60 PIXEL02_81 PIXEL03_81 PIXEL10_60 PIXEL11_70 PIXEL12_31 PIXEL13_31 PIXEL20_60 PIXEL21_70 PIXEL22_32 PIXEL23_32 PIXEL30_20 PIXEL31_60 PIXEL32_82 PIXEL33_82 break; } case 186: { if (Diff(w[4], w[2])) { PIXEL00_80 PIXEL01_10 PIXEL10_10 PIXEL11_30 } else { PIXEL00_20 PIXEL01_12 PIXEL10_11 PIXEL11_0 } if (Diff(w[2], w[6])) { PIXEL02_10 PIXEL03_80 PIXEL12_30 PIXEL13_10 } else { PIXEL02_11 PIXEL03_20 PIXEL12_0 PIXEL13_12 } PIXEL20_31 PIXEL21_31 PIXEL22_32 PIXEL23_32 PIXEL30_81 PIXEL31_81 PIXEL32_82 PIXEL33_82 break; } case 115: { PIXEL00_81 PIXEL01_31 if (Diff(w[2], w[6])) { PIXEL02_10 PIXEL03_80 PIXEL12_30 PIXEL13_10 } else { PIXEL02_11 PIXEL03_20 PIXEL12_0 PIXEL13_12 } PIXEL10_81 PIXEL11_31 PIXEL20_82 PIXEL21_32 if (Diff(w[6], w[8])) { PIXEL22_30 PIXEL23_10 PIXEL32_10 PIXEL33_80 } else { PIXEL22_0 PIXEL23_11 PIXEL32_12 PIXEL33_20 } PIXEL30_82 PIXEL31_32 break; } case 93: { PIXEL00_82 PIXEL01_82 PIXEL02_81 PIXEL03_81 PIXEL10_32 PIXEL11_32 PIXEL12_31 PIXEL13_31 if (Diff(w[8], w[4])) { PIXEL20_10 PIXEL21_30 PIXEL30_80 PIXEL31_10 } else { PIXEL20_12 PIXEL21_0 PIXEL30_20 PIXEL31_11 } if (Diff(w[6], w[8])) { PIXEL22_30 PIXEL23_10 PIXEL32_10 PIXEL33_80 } else { PIXEL22_0 PIXEL23_11 PIXEL32_12 PIXEL33_20 } break; } case 206: { if (Diff(w[4], w[2])) { PIXEL00_80 PIXEL01_10 PIXEL10_10 PIXEL11_30 } else { PIXEL00_20 PIXEL01_12 PIXEL10_11 PIXEL11_0 } PIXEL02_32 PIXEL03_82 PIXEL12_32 PIXEL13_82 if (Diff(w[8], w[4])) { PIXEL20_10 PIXEL21_30 PIXEL30_80 PIXEL31_10 } else { PIXEL20_12 PIXEL21_0 PIXEL30_20 PIXEL31_11 } PIXEL22_31 PIXEL23_81 PIXEL32_31 PIXEL33_81 break; } case 205: case 201: { PIXEL00_82 PIXEL01_82 PIXEL02_60 PIXEL03_20 PIXEL10_32 PIXEL11_32 PIXEL12_70 PIXEL13_60 if (Diff(w[8], w[4])) { PIXEL20_10 PIXEL21_30 PIXEL30_80 PIXEL31_10 } else { PIXEL20_12 PIXEL21_0 PIXEL30_20 PIXEL31_11 } PIXEL22_31 PIXEL23_81 PIXEL32_31 PIXEL33_81 break; } case 174: case 46: { if (Diff(w[4], w[2])) { PIXEL00_80 PIXEL01_10 PIXEL10_10 PIXEL11_30 } else { PIXEL00_20 PIXEL01_12 PIXEL10_11 PIXEL11_0 } PIXEL02_32 PIXEL03_82 PIXEL12_32 PIXEL13_82 PIXEL20_31 PIXEL21_31 PIXEL22_70 PIXEL23_60 PIXEL30_81 PIXEL31_81 PIXEL32_60 PIXEL33_20 break; } case 179: case 147: { PIXEL00_81 PIXEL01_31 if (Diff(w[2], w[6])) { PIXEL02_10 PIXEL03_80 PIXEL12_30 PIXEL13_10 } else { PIXEL02_11 PIXEL03_20 PIXEL12_0 PIXEL13_12 } PIXEL10_81 PIXEL11_31 PIXEL20_60 PIXEL21_70 PIXEL22_32 PIXEL23_32 PIXEL30_20 PIXEL31_60 PIXEL32_82 PIXEL33_82 break; } case 117: case 116: { PIXEL00_20 PIXEL01_60 PIXEL02_81 PIXEL03_81 PIXEL10_60 PIXEL11_70 PIXEL12_31 PIXEL13_31 PIXEL20_82 PIXEL21_32 if (Diff(w[6], w[8])) { PIXEL22_30 PIXEL23_10 PIXEL32_10 PIXEL33_80 } else { PIXEL22_0 PIXEL23_11 PIXEL32_12 PIXEL33_20 } PIXEL30_82 PIXEL31_32 break; } case 189: { PIXEL00_82 PIXEL01_82 PIXEL02_81 PIXEL03_81 PIXEL10_32 PIXEL11_32 PIXEL12_31 PIXEL13_31 PIXEL20_31 PIXEL21_31 PIXEL22_32 PIXEL23_32 PIXEL30_81 PIXEL31_81 PIXEL32_82 PIXEL33_82 break; } case 231: { PIXEL00_81 PIXEL01_31 PIXEL02_32 PIXEL03_82 PIXEL10_81 PIXEL11_31 PIXEL12_32 PIXEL13_82 PIXEL20_82 PIXEL21_32 PIXEL22_31 PIXEL23_81 PIXEL30_82 PIXEL31_32 PIXEL32_31 PIXEL33_81 break; } case 126: { PIXEL00_80 PIXEL01_10 if (Diff(w[2], w[6])) { PIXEL02_0 PIXEL03_0 PIXEL13_0 } else { PIXEL02_50 PIXEL03_50 PIXEL13_50 } PIXEL10_10 PIXEL11_30 PIXEL12_0 if (Diff(w[8], w[4])) { PIXEL20_0 PIXEL30_0 PIXEL31_0 } else { PIXEL20_50 PIXEL30_50 PIXEL31_50 } PIXEL21_0 PIXEL22_30 PIXEL23_10 PIXEL32_10 PIXEL33_80 break; } case 219: { if (Diff(w[4], w[2])) { PIXEL00_0 PIXEL01_0 PIXEL10_0 } else { PIXEL00_50 PIXEL01_50 PIXEL10_50 } PIXEL02_10 PIXEL03_80 PIXEL11_0 PIXEL12_30 PIXEL13_10 PIXEL20_10 PIXEL21_30 PIXEL22_0 if (Diff(w[6], w[8])) { PIXEL23_0 PIXEL32_0 PIXEL33_0 } else { PIXEL23_50 PIXEL32_50 PIXEL33_50 } PIXEL30_80 PIXEL31_10 break; } case 125: { if (Diff(w[8], w[4])) { PIXEL00_82 PIXEL10_32 PIXEL20_0 PIXEL21_0 PIXEL30_0 PIXEL31_0 } else { PIXEL00_11 PIXEL10_13 PIXEL20_83 PIXEL21_70 PIXEL30_50 PIXEL31_21 } PIXEL01_82 PIXEL02_81 PIXEL03_81 PIXEL11_32 PIXEL12_31 PIXEL13_31 PIXEL22_30 PIXEL23_10 PIXEL32_10 PIXEL33_80 break; } case 221: { PIXEL00_82 PIXEL01_82 PIXEL02_81 if (Diff(w[6], w[8])) { PIXEL03_81 PIXEL13_31 PIXEL22_0 PIXEL23_0 PIXEL32_0 PIXEL33_0 } else { PIXEL03_12 PIXEL13_14 PIXEL22_70 PIXEL23_83 PIXEL32_21 PIXEL33_50 } PIXEL10_32 PIXEL11_32 PIXEL12_31 PIXEL20_10 PIXEL21_30 PIXEL30_80 PIXEL31_10 break; } case 207: { if (Diff(w[4], w[2])) { PIXEL00_0 PIXEL01_0 PIXEL02_32 PIXEL03_82 PIXEL10_0 PIXEL11_0 } else { PIXEL00_50 PIXEL01_83 PIXEL02_13 PIXEL03_11 PIXEL10_21 PIXEL11_70 } PIXEL12_32 PIXEL13_82 PIXEL20_10 PIXEL21_30 PIXEL22_31 PIXEL23_81 PIXEL30_80 PIXEL31_10 PIXEL32_31 PIXEL33_81 break; } case 238: { PIXEL00_80 PIXEL01_10 PIXEL02_32 PIXEL03_82 PIXEL10_10 PIXEL11_30 PIXEL12_32 PIXEL13_82 if (Diff(w[8], w[4])) { PIXEL20_0 PIXEL21_0 PIXEL30_0 PIXEL31_0 PIXEL32_31 PIXEL33_81 } else { PIXEL20_21 PIXEL21_70 PIXEL30_50 PIXEL31_83 PIXEL32_14 PIXEL33_12 } PIXEL22_31 PIXEL23_81 break; } case 190: { PIXEL00_80 PIXEL01_10 if (Diff(w[2], w[6])) { PIXEL02_0 PIXEL03_0 PIXEL12_0 PIXEL13_0 PIXEL23_32 PIXEL33_82 } else { PIXEL02_21 PIXEL03_50 PIXEL12_70 PIXEL13_83 PIXEL23_13 PIXEL33_11 } PIXEL10_10 PIXEL11_30 PIXEL20_31 PIXEL21_31 PIXEL22_32 PIXEL30_81 PIXEL31_81 PIXEL32_82 break; } case 187: { if (Diff(w[4], w[2])) { PIXEL00_0 PIXEL01_0 PIXEL10_0 PIXEL11_0 PIXEL20_31 PIXEL30_81 } else { PIXEL00_50 PIXEL01_21 PIXEL10_83 PIXEL11_70 PIXEL20_14 PIXEL30_12 } PIXEL02_10 PIXEL03_80 PIXEL12_30 PIXEL13_10 PIXEL21_31 PIXEL22_32 PIXEL23_32 PIXEL31_81 PIXEL32_82 PIXEL33_82 break; } case 243: { PIXEL00_81 PIXEL01_31 PIXEL02_10 PIXEL03_80 PIXEL10_81 PIXEL11_31 PIXEL12_30 PIXEL13_10 PIXEL20_82 PIXEL21_32 if (Diff(w[6], w[8])) { PIXEL22_0 PIXEL23_0 PIXEL30_82 PIXEL31_32 PIXEL32_0 PIXEL33_0 } else { PIXEL22_70 PIXEL23_21 PIXEL30_11 PIXEL31_13 PIXEL32_83 PIXEL33_50 } break; } case 119: { if (Diff(w[2], w[6])) { PIXEL00_81 PIXEL01_31 PIXEL02_0 PIXEL03_0 PIXEL12_0 PIXEL13_0 } else { PIXEL00_12 PIXEL01_14 PIXEL02_83 PIXEL03_50 PIXEL12_70 PIXEL13_21 } PIXEL10_81 PIXEL11_31 PIXEL20_82 PIXEL21_32 PIXEL22_30 PIXEL23_10 PIXEL30_82 PIXEL31_32 PIXEL32_10 PIXEL33_80 break; } case 237: case 233: { PIXEL00_82 PIXEL01_82 PIXEL02_60 PIXEL03_20 PIXEL10_32 PIXEL11_32 PIXEL12_70 PIXEL13_60 PIXEL20_0 PIXEL21_0 PIXEL22_31 PIXEL23_81 if (Diff(w[8], w[4])) { PIXEL30_0 } else { PIXEL30_20 } PIXEL31_0 PIXEL32_31 PIXEL33_81 break; } case 175: case 47: { if (Diff(w[4], w[2])) { PIXEL00_0 } else { PIXEL00_20 } PIXEL01_0 PIXEL02_32 PIXEL03_82 PIXEL10_0 PIXEL11_0 PIXEL12_32 PIXEL13_82 PIXEL20_31 PIXEL21_31 PIXEL22_70 PIXEL23_60 PIXEL30_81 PIXEL31_81 PIXEL32_60 PIXEL33_20 break; } case 183: case 151: { PIXEL00_81 PIXEL01_31 PIXEL02_0 if (Diff(w[2], w[6])) { PIXEL03_0 } else { PIXEL03_20 } PIXEL10_81 PIXEL11_31 PIXEL12_0 PIXEL13_0 PIXEL20_60 PIXEL21_70 PIXEL22_32 PIXEL23_32 PIXEL30_20 PIXEL31_60 PIXEL32_82 PIXEL33_82 break; } case 245: case 244: { PIXEL00_20 PIXEL01_60 PIXEL02_81 PIXEL03_81 PIXEL10_60 PIXEL11_70 PIXEL12_31 PIXEL13_31 PIXEL20_82 PIXEL21_32 PIXEL22_0 PIXEL23_0 PIXEL30_82 PIXEL31_32 PIXEL32_0 if (Diff(w[6], w[8])) { PIXEL33_0 } else { PIXEL33_20 } break; } case 250: { PIXEL00_80 PIXEL01_10 PIXEL02_10 PIXEL03_80 PIXEL10_10 PIXEL11_30 PIXEL12_30 PIXEL13_10 if (Diff(w[8], w[4])) { PIXEL20_0 PIXEL30_0 PIXEL31_0 } else { PIXEL20_50 PIXEL30_50 PIXEL31_50 } PIXEL21_0 PIXEL22_0 if (Diff(w[6], w[8])) { PIXEL23_0 PIXEL32_0 PIXEL33_0 } else { PIXEL23_50 PIXEL32_50 PIXEL33_50 } break; } case 123: { if (Diff(w[4], w[2])) { PIXEL00_0 PIXEL01_0 PIXEL10_0 } else { PIXEL00_50 PIXEL01_50 PIXEL10_50 } PIXEL02_10 PIXEL03_80 PIXEL11_0 PIXEL12_30 PIXEL13_10 if (Diff(w[8], w[4])) { PIXEL20_0 PIXEL30_0 PIXEL31_0 } else { PIXEL20_50 PIXEL30_50 PIXEL31_50 } PIXEL21_0 PIXEL22_30 PIXEL23_10 PIXEL32_10 PIXEL33_80 break; } case 95: { if (Diff(w[4], w[2])) { PIXEL00_0 PIXEL01_0 PIXEL10_0 } else { PIXEL00_50 PIXEL01_50 PIXEL10_50 } if (Diff(w[2], w[6])) { PIXEL02_0 PIXEL03_0 PIXEL13_0 } else { PIXEL02_50 PIXEL03_50 PIXEL13_50 } PIXEL11_0 PIXEL12_0 PIXEL20_10 PIXEL21_30 PIXEL22_30 PIXEL23_10 PIXEL30_80 PIXEL31_10 PIXEL32_10 PIXEL33_80 break; } case 222: { PIXEL00_80 PIXEL01_10 if (Diff(w[2], w[6])) { PIXEL02_0 PIXEL03_0 PIXEL13_0 } else { PIXEL02_50 PIXEL03_50 PIXEL13_50 } PIXEL10_10 PIXEL11_30 PIXEL12_0 PIXEL20_10 PIXEL21_30 PIXEL22_0 if (Diff(w[6], w[8])) { PIXEL23_0 PIXEL32_0 PIXEL33_0 } else { PIXEL23_50 PIXEL32_50 PIXEL33_50 } PIXEL30_80 PIXEL31_10 break; } case 252: { PIXEL00_80 PIXEL01_61 PIXEL02_81 PIXEL03_81 PIXEL10_10 PIXEL11_30 PIXEL12_31 PIXEL13_31 if (Diff(w[8], w[4])) { PIXEL20_0 PIXEL30_0 PIXEL31_0 } else { PIXEL20_50 PIXEL30_50 PIXEL31_50 } PIXEL21_0 PIXEL22_0 PIXEL23_0 PIXEL32_0 if (Diff(w[6], w[8])) { PIXEL33_0 } else { PIXEL33_20 } break; } case 249: { PIXEL00_82 PIXEL01_82 PIXEL02_61 PIXEL03_80 PIXEL10_32 PIXEL11_32 PIXEL12_30 PIXEL13_10 PIXEL20_0 PIXEL21_0 PIXEL22_0 if (Diff(w[6], w[8])) { PIXEL23_0 PIXEL32_0 PIXEL33_0 } else { PIXEL23_50 PIXEL32_50 PIXEL33_50 } if (Diff(w[8], w[4])) { PIXEL30_0 } else { PIXEL30_20 } PIXEL31_0 break; } case 235: { if (Diff(w[4], w[2])) { PIXEL00_0 PIXEL01_0 PIXEL10_0 } else { PIXEL00_50 PIXEL01_50 PIXEL10_50 } PIXEL02_10 PIXEL03_80 PIXEL11_0 PIXEL12_30 PIXEL13_61 PIXEL20_0 PIXEL21_0 PIXEL22_31 PIXEL23_81 if (Diff(w[8], w[4])) { PIXEL30_0 } else { PIXEL30_20 } PIXEL31_0 PIXEL32_31 PIXEL33_81 break; } case 111: { if (Diff(w[4], w[2])) { PIXEL00_0 } else { PIXEL00_20 } PIXEL01_0 PIXEL02_32 PIXEL03_82 PIXEL10_0 PIXEL11_0 PIXEL12_32 PIXEL13_82 if (Diff(w[8], w[4])) { PIXEL20_0 PIXEL30_0 PIXEL31_0 } else { PIXEL20_50 PIXEL30_50 PIXEL31_50 } PIXEL21_0 PIXEL22_30 PIXEL23_61 PIXEL32_10 PIXEL33_80 break; } case 63: { if (Diff(w[4], w[2])) { PIXEL00_0 } else { PIXEL00_20 } PIXEL01_0 if (Diff(w[2], w[6])) { PIXEL02_0 PIXEL03_0 PIXEL13_0 } else { PIXEL02_50 PIXEL03_50 PIXEL13_50 } PIXEL10_0 PIXEL11_0 PIXEL12_0 PIXEL20_31 PIXEL21_31 PIXEL22_30 PIXEL23_10 PIXEL30_81 PIXEL31_81 PIXEL32_61 PIXEL33_80 break; } case 159: { if (Diff(w[4], w[2])) { PIXEL00_0 PIXEL01_0 PIXEL10_0 } else { PIXEL00_50 PIXEL01_50 PIXEL10_50 } PIXEL02_0 if (Diff(w[2], w[6])) { PIXEL03_0 } else { PIXEL03_20 } PIXEL11_0 PIXEL12_0 PIXEL13_0 PIXEL20_10 PIXEL21_30 PIXEL22_32 PIXEL23_32 PIXEL30_80 PIXEL31_61 PIXEL32_82 PIXEL33_82 break; } case 215: { PIXEL00_81 PIXEL01_31 PIXEL02_0 if (Diff(w[2], w[6])) { PIXEL03_0 } else { PIXEL03_20 } PIXEL10_81 PIXEL11_31 PIXEL12_0 PIXEL13_0 PIXEL20_61 PIXEL21_30 PIXEL22_0 if (Diff(w[6], w[8])) { PIXEL23_0 PIXEL32_0 PIXEL33_0 } else { PIXEL23_50 PIXEL32_50 PIXEL33_50 } PIXEL30_80 PIXEL31_10 break; } case 246: { PIXEL00_80 PIXEL01_10 if (Diff(w[2], w[6])) { PIXEL02_0 PIXEL03_0 PIXEL13_0 } else { PIXEL02_50 PIXEL03_50 PIXEL13_50 } PIXEL10_61 PIXEL11_30 PIXEL12_0 PIXEL20_82 PIXEL21_32 PIXEL22_0 PIXEL23_0 PIXEL30_82 PIXEL31_32 PIXEL32_0 if (Diff(w[6], w[8])) { PIXEL33_0 } else { PIXEL33_20 } break; } case 254: { PIXEL00_80 PIXEL01_10 if (Diff(w[2], w[6])) { PIXEL02_0 PIXEL03_0 PIXEL13_0 } else { PIXEL02_50 PIXEL03_50 PIXEL13_50 } PIXEL10_10 PIXEL11_30 PIXEL12_0 if (Diff(w[8], w[4])) { PIXEL20_0 PIXEL30_0 PIXEL31_0 } else { PIXEL20_50 PIXEL30_50 PIXEL31_50 } PIXEL21_0 PIXEL22_0 PIXEL23_0 PIXEL32_0 if (Diff(w[6], w[8])) { PIXEL33_0 } else { PIXEL33_20 } break; } case 253: { PIXEL00_82 PIXEL01_82 PIXEL02_81 PIXEL03_81 PIXEL10_32 PIXEL11_32 PIXEL12_31 PIXEL13_31 PIXEL20_0 PIXEL21_0 PIXEL22_0 PIXEL23_0 if (Diff(w[8], w[4])) { PIXEL30_0 } else { PIXEL30_20 } PIXEL31_0 PIXEL32_0 if (Diff(w[6], w[8])) { PIXEL33_0 } else { PIXEL33_20 } break; } case 251: { if (Diff(w[4], w[2])) { PIXEL00_0 PIXEL01_0 PIXEL10_0 } else { PIXEL00_50 PIXEL01_50 PIXEL10_50 } PIXEL02_10 PIXEL03_80 PIXEL11_0 PIXEL12_30 PIXEL13_10 PIXEL20_0 PIXEL21_0 PIXEL22_0 if (Diff(w[6], w[8])) { PIXEL23_0 PIXEL32_0 PIXEL33_0 } else { PIXEL23_50 PIXEL32_50 PIXEL33_50 } if (Diff(w[8], w[4])) { PIXEL30_0 } else { PIXEL30_20 } PIXEL31_0 break; } case 239: { if (Diff(w[4], w[2])) { PIXEL00_0 } else { PIXEL00_20 } PIXEL01_0 PIXEL02_32 PIXEL03_82 PIXEL10_0 PIXEL11_0 PIXEL12_32 PIXEL13_82 PIXEL20_0 PIXEL21_0 PIXEL22_31 PIXEL23_81 if (Diff(w[8], w[4])) { PIXEL30_0 } else { PIXEL30_20 } PIXEL31_0 PIXEL32_31 PIXEL33_81 break; } case 127: { if (Diff(w[4], w[2])) { PIXEL00_0 } else { PIXEL00_20 } PIXEL01_0 if (Diff(w[2], w[6])) { PIXEL02_0 PIXEL03_0 PIXEL13_0 } else { PIXEL02_50 PIXEL03_50 PIXEL13_50 } PIXEL10_0 PIXEL11_0 PIXEL12_0 if (Diff(w[8], w[4])) { PIXEL20_0 PIXEL30_0 PIXEL31_0 } else { PIXEL20_50 PIXEL30_50 PIXEL31_50 } PIXEL21_0 PIXEL22_30 PIXEL23_10 PIXEL32_10 PIXEL33_80 break; } case 191: { if (Diff(w[4], w[2])) { PIXEL00_0 } else { PIXEL00_20 } PIXEL01_0 PIXEL02_0 if (Diff(w[2], w[6])) { PIXEL03_0 } else { PIXEL03_20 } PIXEL10_0 PIXEL11_0 PIXEL12_0 PIXEL13_0 PIXEL20_31 PIXEL21_31 PIXEL22_32 PIXEL23_32 PIXEL30_81 PIXEL31_81 PIXEL32_82 PIXEL33_82 break; } case 223: { if (Diff(w[4], w[2])) { PIXEL00_0 PIXEL01_0 PIXEL10_0 } else { PIXEL00_50 PIXEL01_50 PIXEL10_50 } PIXEL02_0 if (Diff(w[2], w[6])) { PIXEL03_0 } else { PIXEL03_20 } PIXEL11_0 PIXEL12_0 PIXEL13_0 PIXEL20_10 PIXEL21_30 PIXEL22_0 if (Diff(w[6], w[8])) { PIXEL23_0 PIXEL32_0 PIXEL33_0 } else { PIXEL23_50 PIXEL32_50 PIXEL33_50 } PIXEL30_80 PIXEL31_10 break; } case 247: { PIXEL00_81 PIXEL01_31 PIXEL02_0 if (Diff(w[2], w[6])) { PIXEL03_0 } else { PIXEL03_20 } PIXEL10_81 PIXEL11_31 PIXEL12_0 PIXEL13_0 PIXEL20_82 PIXEL21_32 PIXEL22_0 PIXEL23_0 PIXEL30_82 PIXEL31_32 PIXEL32_0 if (Diff(w[6], w[8])) { PIXEL33_0 } else { PIXEL33_20 } break; } case 255: { if (Diff(w[4], w[2])) { PIXEL00_0 } else { PIXEL00_20 } PIXEL01_0 PIXEL02_0 if (Diff(w[2], w[6])) { PIXEL03_0 } else { PIXEL03_20 } PIXEL10_0 PIXEL11_0 PIXEL12_0 PIXEL13_0 PIXEL20_0 PIXEL21_0 PIXEL22_0 PIXEL23_0 if (Diff(w[8], w[4])) { PIXEL30_0 } else { PIXEL30_20 } PIXEL31_0 PIXEL32_0 if (Diff(w[6], w[8])) { PIXEL33_0 } else { PIXEL33_20 } break; } } gles2n64/src/F3D.h000664 001750 001750 00000006355 12655644434 014610 0ustar00sergiosergio000000 000000 #ifndef F3D_H #define F3D_H #include "Types.h" #ifdef __cplusplus extern "C" { #endif #define F3D_MTX_STACKSIZE 10 #define F3D_MTX_MODELVIEW 0x00 #define F3D_MTX_PROJECTION 0x01 #define F3D_MTX_MUL 0x00 #define F3D_MTX_LOAD 0x02 #define F3D_MTX_NOPUSH 0x00 #define F3D_MTX_PUSH 0x04 #define F3D_TEXTURE_ENABLE 0x00000002 #define F3D_SHADING_SMOOTH 0x00000200 #define F3D_CULL_FRONT 0x00001000 #define F3D_CULL_BACK 0x00002000 #define F3D_CULL_BOTH 0x00003000 #define F3D_CLIPPING 0x00000000 #define F3D_MV_VIEWPORT 0x80 #define F3D_MWO_aLIGHT_1 0x00 #define F3D_MWO_bLIGHT_1 0x04 #define F3D_MWO_aLIGHT_2 0x20 #define F3D_MWO_bLIGHT_2 0x24 #define F3D_MWO_aLIGHT_3 0x40 #define F3D_MWO_bLIGHT_3 0x44 #define F3D_MWO_aLIGHT_4 0x60 #define F3D_MWO_bLIGHT_4 0x64 #define F3D_MWO_aLIGHT_5 0x80 #define F3D_MWO_bLIGHT_5 0x84 #define F3D_MWO_aLIGHT_6 0xa0 #define F3D_MWO_bLIGHT_6 0xa4 #define F3D_MWO_aLIGHT_7 0xc0 #define F3D_MWO_bLIGHT_7 0xc4 #define F3D_MWO_aLIGHT_8 0xe0 #define F3D_MWO_bLIGHT_8 0xe4 // FAST3D commands #define F3D_SPNOOP 0x00 #define F3D_MTX 0x01 #define F3D_RESERVED0 0x02 #define F3D_MOVEMEM 0x03 #define F3D_VTX 0x04 #define F3D_RESERVED1 0x05 #define F3D_DL 0x06 #define F3D_RESERVED2 0x07 #define F3D_RESERVED3 0x08 #define F3D_SPRITE2D_BASE 0x09 #define F3D_TRI1 0xBF #define F3D_CULLDL 0xBE #define F3D_POPMTX 0xBD #define F3D_MOVEWORD 0xBC #define F3D_TEXTURE 0xBB #define F3D_SETOTHERMODE_H 0xBA #define F3D_SETOTHERMODE_L 0xB9 #define F3D_ENDDL 0xB8 #define F3D_SETGEOMETRYMODE 0xB7 #define F3D_CLEARGEOMETRYMODE 0xB6 //#define F3D_LINE3D 0xB5 // Only used in Line3D #define F3D_QUAD 0xB5 #define F3D_RDPHALF_1 0xB4 #define F3D_RDPHALF_2 0xB3 #define F3D_RDPHALF_CONT 0xB2 #define F3D_TRI4 0xB1 #define F3D_TRI_UNKNOWN 0xC0 void F3D_SPNoOp( u32 w0, u32 w1 ); void F3D_Mtx( u32 w0, u32 w1 ); void F3D_Reserved0( u32 w0, u32 w1 ); void F3D_MoveMem( u32 w0, u32 w1 ); void F3D_Vtx( u32 w0, u32 w1 ); void F3D_Reserved1( u32 w0, u32 w1 ); void F3D_DList( u32 w0, u32 w1 ); void F3D_Reserved2( u32 w0, u32 w1 ); void F3D_Reserved3( u32 w0, u32 w1 ); void F3D_Sprite2D_Base( u32 w0, u32 w1 ); void F3D_Tri1( u32 w0, u32 w1 ); void F3D_CullDL( u32 w0, u32 w1 ); void F3D_PopMtx( u32 w0, u32 w1 ); void F3D_MoveWord( u32 w0, u32 w1 ); void F3D_Texture( u32 w0, u32 w1 ); void F3D_SetOtherMode_H( u32 w0, u32 w1 ); void F3D_SetOtherMode_L( u32 w0, u32 w1 ); void F3D_EndDL( u32 w0, u32 w1 ); void F3D_SetGeometryMode( u32 w0, u32 w1 ); void F3D_ClearGeometryMode( u32 w0, u32 w1 ); //void F3D_Line3D( u32 w0, u32 w1 ); void F3D_Quad( u32 w0, u32 w1 ); void F3D_RDPHalf_1( u32 w0, u32 w1 ); void F3D_RDPHalf_2( u32 w0, u32 w1 ); void F3D_RDPHalf_Cont( u32 w0, u32 w1 ); void F3D_Tri4( u32 w0, u32 w1 ); void F3D_Init(); #ifdef __cplusplus } #endif #endif mupen64plus-core/src/api/config.h000664 001750 001750 00000003452 12655644434 020031 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-core - api/config.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2009 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file contains the Core configuration functions */ #include "m64p_types.h" /* these functions are only to be used within the Core library */ m64p_error ConfigInit(const char *ConfigDirOverride, const char *DataDirOverride); m64p_error ConfigShutdown(void); glide2gl/src/Glide64/glide64_gSP.h000664 001750 001750 00000050003 12655644434 017553 0ustar00sergiosergio000000 000000 typedef struct DRAWOBJECT_t { float objX; float objY; float scaleW; float scaleH; int16_t imageW; int16_t imageH; uint16_t imageStride; uint16_t imageAdrs; uint8_t imageFmt; uint8_t imageSiz; uint8_t imagePal; uint8_t imageFlags; } DRAWOBJECT; struct MAT2D { float A, B, C, D; float X, Y; float BaseScaleX; float BaseScaleY; } mat_2d = {1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f}; // positional and texel coordinate clipping #define CCLIP2(ux,lx,ut,lt,un,ln,uc,lc) \ if (ux > lx || lx < uc || ux > lc) return; \ if (ux < uc) { \ float p = (uc-ux)/(lx-ux); \ ut = p*(lt-ut)+ut; \ un = p*(ln-un)+un; \ ux = uc; \ } \ if (lx > lc) { \ float p = (lc-ux)/(lx-ux); \ lt = p*(lt-ut)+ut; \ ln = p*(ln-un)+un; \ lx = lc; \ } //forward decls static void uc6_draw_polygons (VERTEX v[4]); static void uc6_read_object_data (DRAWOBJECT *d); static void uc6_init_tile(const DRAWOBJECT *d); extern uint32_t dma_offset_mtx; extern int32_t cur_mtx; extern uint32_t dma_offset_mtx; extern uint32_t dma_offset_vtx; extern int32_t billboarding; int dzdx = 0; int deltaZ = 0; VERTEX **org_vtx; //software backface culling. Gonetz // mega modifications by Dave2001 static int cull_tri(VERTEX **v) // type changed to VERTEX** [Dave2001] { int i, draw, iarea; unsigned int mode; float x1, y1, x2, y2, area; if (v[0]->scr_off & v[1]->scr_off & v[2]->scr_off) return true; // Triangle can't be culled, if it need clipping draw = false; for (i=0; i<3; i++) { if (!v[i]->screen_translated) { v[i]->sx = rdp.view_trans[0] + v[i]->x_w * rdp.view_scale[0] + rdp.offset_x; v[i]->sy = rdp.view_trans[1] + v[i]->y_w * rdp.view_scale[1] + rdp.offset_y; v[i]->sz = rdp.view_trans[2] + v[i]->z_w * rdp.view_scale[2]; v[i]->screen_translated = 1; } if (v[i]->w < 0.01f) //need clip_z. can't be culled now draw = 1; } rdp.u_cull_mode = (rdp.flags & CULLMASK); if (draw || rdp.u_cull_mode == 0 || rdp.u_cull_mode == CULLMASK) //no culling set { rdp.u_cull_mode >>= CULLSHIFT; return false; } x1 = v[0]->sx - v[1]->sx; y1 = v[0]->sy - v[1]->sy; x2 = v[2]->sx - v[1]->sx; y2 = v[2]->sy - v[1]->sy; area = y1 * x2 - x1 * y2; iarea = *(int*)&area; mode = (rdp.u_cull_mode << 19UL); rdp.u_cull_mode >>= CULLSHIFT; if ((iarea & 0x7FFFFFFF) == 0) { //LRDP (" zero area triangles\n"); return true; } if ((rdp.flags & CULLMASK) && ((int)(iarea ^ mode)) >= 0) { //LRDP (" culled\n"); return true; } return false; } static void gSPCombineMatrices(void) { MulMatrices(rdp.model, rdp.proj, rdp.combined); g_gdp.flags ^= UPDATE_MULT_MAT; } /* clip_w - clips aint the z-axis */ static void clip_w (void) { int i; int index = 0; int n = rdp.n_global; VERTEX *tmp = (VERTEX*)rdp.vtxbuf2; /* Swap vertex buffers */ rdp.vtxbuf2 = rdp.vtxbuf; rdp.vtxbuf = tmp; rdp.vtx_buffer ^= 1; // Check the vertices for clipping for (i=0; i < n; i++) { bool save_inpoint = false; VERTEX *first, *second, *current = NULL, *current2 = NULL; int j = i+1; if (j == 3) j = 0; first = (VERTEX*)&rdp.vtxbuf2[i]; second = (VERTEX*)&rdp.vtxbuf2[j]; if (first->w >= 0.01f) { if (second->w >= 0.01f) // Both are in, save the last one { save_inpoint = true; } else // First is in, second is out, save intersection { current = first; current2 = second; } } else { if (second->w >= 0.01f) // First is out, second is in, save intersection & in point { current = second; current2 = first; save_inpoint = true; } } if (current && current2) { float percent = (-current->w) / (current2->w - current->w); rdp.vtxbuf[index].not_zclipped = 0; rdp.vtxbuf[index].x = current->x + (current2->x - current->x) * percent; rdp.vtxbuf[index].y = current->y + (current2->y - current->y) * percent; rdp.vtxbuf[index].z = current->z + (current2->z - current->z) * percent; rdp.vtxbuf[index].u[0] = current->u[0] + (current2->u[0] - current->u[0]) * percent; rdp.vtxbuf[index].v[0] = current->v[0] + (current2->v[0] - current->v[0]) * percent; rdp.vtxbuf[index].u[1] = current->u[1] + (current2->u[1] - current->u[1]) * percent; rdp.vtxbuf[index].v[1] = current->v[1] + (current2->v[1] - current->v[1]) * percent; rdp.vtxbuf[index].w = settings.depth_bias * 0.01f; rdp.vtxbuf[index++].number = first->number | second->number; } if (save_inpoint) { // Save the in point rdp.vtxbuf[index] = rdp.vtxbuf2[j]; rdp.vtxbuf[index++].not_zclipped = 1; } } rdp.n_global = index; } static void draw_tri_depth(VERTEX **vtx) { float X0 = vtx[0]->sx / rdp.scale_x; float Y0 = vtx[0]->sy / rdp.scale_y; float X1 = vtx[1]->sx / rdp.scale_x; float Y1 = vtx[1]->sy / rdp.scale_y; float X2 = vtx[2]->sx / rdp.scale_x; float Y2 = vtx[2]->sy / rdp.scale_y; float diffy_02 = Y0 - Y2; float diffy_12 = Y1 - Y2; float diffx_02 = X0 - X2; float diffx_12 = X1 - X2; float denom = (diffx_02 * diffy_12 - diffx_12 * diffy_02); if(denom * denom > 0.0) { float diffz_02 = vtx[0]->sz - vtx[2]->sz; float diffz_12 = vtx[1]->sz - vtx[2]->sz; float fdzdx = (diffz_02 * diffy_12 - diffz_12 * diffy_02) / denom; if ((rdp.rm & ZMODE_DECAL) == ZMODE_DECAL) { // Calculate deltaZ per polygon for Decal z-mode float fdzdy = (float)((diffz_02*diffx_12 - diffz_12*diffx_02) / denom); float fdz = (float)(fabs(fdzdx) + fabs(fdzdy)); deltaZ = max(8, (int)fdz); } dzdx = (int)(fdzdx * 65536.0); } } static INLINE void draw_tri_uv_calculation_update_shift(unsigned cur_tile, unsigned index, VERTEX *v) { int32_t shifter = g_gdp.tile[cur_tile].shift_s; if (shifter) { if (shifter > 10) v->u[index] *= (float)(1 << (16 - shifter)); else v->u[index] /= (float)(1 << shifter); } shifter = g_gdp.tile[cur_tile].shift_t; if (shifter) { if (shifter > 10) v->v[index] *= (float)(1 << (16 - shifter)); else v->v[index] /= (float)(1 << shifter); } v->u[index] -= rdp.tiles[cur_tile].f_ul_s; v->v[index] -= rdp.tiles[cur_tile].f_ul_t; v->u[index] = rdp.cur_cache[index]->c_off + rdp.cur_cache[index]->c_scl_x * v->u[index]; v->v[index] = rdp.cur_cache[index]->c_off + rdp.cur_cache[index]->c_scl_y * v->v[index]; v->u_w[index] = v->u[index] / v->w; v->v_w[index] = v->v[index] / v->w; } static void draw_tri_uv_calculation(VERTEX **vtx, VERTEX *v) { unsigned i; //FRDP(" * CALCULATING VERTEX U/V: %d\n", v->number); if (!(rdp.geom_mode & G_LIGHTING)) { if (!(rdp.geom_mode & UPDATE_SCISSOR)) { if (rdp.geom_mode & G_SHADE) glideSetVertexFlatShading(v, vtx, rdp.cmd1); else glideSetVertexPrimShading(v, g_gdp.prim_color.total); } } // Fix texture coordinates if (!v->uv_scaled) { v->ou *= rdp.tiles[rdp.cur_tile].s_scale; v->ov *= rdp.tiles[rdp.cur_tile].t_scale; v->uv_scaled = 1; if (!(rdp.othermode_h & RDP_PERSP_TEX_ENABLE)) { // v->oow = v->w = 1.0f; v->ou *= 0.5f; v->ov *= 0.5f; } } v->u[1] = v->u[0] = v->ou; v->v[1] = v->v[0] = v->ov; for (i = 0; i < 2; i++) { unsigned index = i+1; if (rdp.tex >= index && rdp.cur_cache[i]) draw_tri_uv_calculation_update_shift(rdp.cur_tile+i, i, v); } v->uv_calculated = rdp.tex_ctr; } static void draw_tri (VERTEX **vtx, uint16_t linew) { int i; org_vtx = vtx; for (i = 0; i < 3; i++) { VERTEX *v = (VERTEX*)vtx[i]; if (v->uv_calculated != rdp.tex_ctr) draw_tri_uv_calculation(vtx, v); if (v->shade_mod != cmb.shade_mod_hash) apply_shade_mods (v); } rdp.clip = 0; vtx[0]->not_zclipped = vtx[1]->not_zclipped = vtx[2]->not_zclipped = 1; // Set vertex buffers rdp.vtxbuf = rdp.vtx1; // copy from v to rdp.vtx1 rdp.vtxbuf2 = rdp.vtx2; rdp.vtx_buffer = 0; rdp.n_global = 3; rdp.vtxbuf[0] = *vtx[0]; rdp.vtxbuf[0].number = 1; rdp.vtxbuf[1] = *vtx[1]; rdp.vtxbuf[1].number = 2; rdp.vtxbuf[2] = *vtx[2]; rdp.vtxbuf[2].number = 4; if ((vtx[0]->scr_off & 16) || (vtx[1]->scr_off & 16) || (vtx[2]->scr_off & 16)) clip_w(); do_triangle_stuff (linew, false); } static void cull_trianglefaces(VERTEX **v, unsigned iterations, bool do_update, bool do_cull, int32_t wd) { uint32_t i; int32_t vcount = 0; if (do_update) update(); for (i = 0; i < iterations; i++, vcount += 3) { if (do_cull) if (cull_tri(v + vcount)) continue; deltaZ = dzdx = 0; if (wd == 0 && (fb_depth_render_enabled || (rdp.rm & ZMODE_DECAL) == ZMODE_DECAL)) draw_tri_depth(v + vcount); draw_tri (v + vcount, wd); } } static void pre_update(void) { // This is special, not handled in update(), but here // Matrix Pre-multiplication idea by Gonetz (Gonetz@ngs.ru) if (g_gdp.flags & UPDATE_MULT_MAT) gSPCombineMatrices(); if (g_gdp.flags & UPDATE_LIGHTS) { uint32_t l; g_gdp.flags ^= UPDATE_LIGHTS; // Calculate light vectors for (l = 0; l < rdp.num_lights; l++) { InverseTransformVector(&rdp.light[l].dir[0], rdp.light_vector[l], rdp.model); NormalizeVector (rdp.light_vector[l]); } } } static void gSPClipVertex_G64(uint32_t v) { VERTEX *vtx = (VERTEX*)&rdp.vtx[v]; vtx->scr_off = 0; if (vtx->x > +vtx->w) vtx->scr_off |= 2; if (vtx->x < -vtx->w) vtx->scr_off |= 1; if (vtx->y > +vtx->w) vtx->scr_off |= 8; if (vtx->y < -vtx->w) vtx->scr_off |= 4; if (vtx->w < 0.1f) vtx->scr_off |= 16; } /* * Loads into the RSP vertex buffer the vertices that will be used by the * gSP1Triangle commands to generate polygons. * * v - Segment address of the vertex list pointer to a list of vertices. * n - Number of vertices (1 - 32). * v0 - Starting index in vertex buffer where vertices are to be loaded into. */ static void gSPVertex_G64(uint32_t v, uint32_t n, uint32_t v0) { unsigned int i; float x, y, z; uint32_t iter = 16; void *vertex = (void*)(gfx_info.RDRAM + v); for (i=0; i < (n * iter); i+= iter) { VERTEX *vtx = (VERTEX*)&rdp.vtx[v0 + (i / iter)]; int16_t *rdram = (int16_t*)vertex; uint8_t *rdram_u8 = (uint8_t*)vertex; uint8_t *color = (uint8_t*)(rdram_u8 + 12); y = (float)rdram[0]; x = (float)rdram[1]; vtx->flags = (uint16_t)rdram[2]; z = (float)rdram[3]; vtx->ov = (float)rdram[4]; vtx->ou = (float)rdram[5]; vtx->uv_scaled = 0; vtx->a = color[0]; vtx->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0]; vtx->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1]; vtx->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2]; vtx->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3]; vtx->uv_calculated = 0xFFFFFFFF; vtx->screen_translated = 0; vtx->shade_mod = 0; if (fabs(vtx->w) < 0.001) vtx->w = 0.001f; vtx->oow = 1.0f / vtx->w; vtx->x_w = vtx->x * vtx->oow; vtx->y_w = vtx->y * vtx->oow; vtx->z_w = vtx->z * vtx->oow; CalculateFog (vtx); gSPClipVertex_G64(v0 + (i / iter)); if (rdp.geom_mode & G_LIGHTING) { vtx->vec[0] = (int8_t)color[3]; vtx->vec[1] = (int8_t)color[2]; vtx->vec[2] = (int8_t)color[1]; if (settings.ucode == 2 && rdp.geom_mode & G_POINT_LIGHTING) { float tmpvec[3] = {x, y, z}; calc_point_light (vtx, tmpvec); } else { NormalizeVector (vtx->vec); calc_light (vtx); } if (rdp.geom_mode & G_TEXTURE_GEN) { if (rdp.geom_mode & G_TEXTURE_GEN_LINEAR) calc_linear (vtx); else calc_sphere (vtx); } } else { vtx->r = color[3]; vtx->g = color[2]; vtx->b = color[1]; } vertex = (char*)vertex + iter; } } static void gSPLookAt_G64(uint32_t l, uint32_t n) { int8_t *rdram_s8 = (int8_t*) (gfx_info.RDRAM + RSP_SegmentToPhysical(l)); int8_t dir_x = rdram_s8[11]; int8_t dir_y = rdram_s8[10]; int8_t dir_z = rdram_s8[9]; rdp.lookat[n][0] = (float)(dir_x) / 127.0f; rdp.lookat[n][1] = (float)(dir_y) / 127.0f; rdp.lookat[n][2] = (float)(dir_z) / 127.0f; rdp.use_lookat = (n == 0) || (n == 1 && (dir_x || dir_y)); } static void gSPLight_G64(uint32_t l, int32_t n) { int16_t *rdram = (int16_t*)(gfx_info.RDRAM + RSP_SegmentToPhysical(l)); uint8_t *rdram_u8 = (uint8_t*)(gfx_info.RDRAM + RSP_SegmentToPhysical(l)); int8_t *rdram_s8 = (int8_t*) (gfx_info.RDRAM + RSP_SegmentToPhysical(l)); --n; if (n < 8) { /* Get the data */ rdp.light[n].nonblack = rdram_u8[3]; rdp.light[n].nonblack += rdram_u8[2]; rdp.light[n].nonblack += rdram_u8[1]; rdp.light[n].col[0] = rdram_u8[3] / 255.0f; rdp.light[n].col[1] = rdram_u8[2] / 255.0f; rdp.light[n].col[2] = rdram_u8[1] / 255.0f; rdp.light[n].col[3] = 1.0f; // ** Thanks to Icepir8 for pointing this out ** // Lighting must be signed byte instead of byte rdp.light[n].dir[0] = (float)rdram_s8[11] / 127.0f; rdp.light[n].dir[1] = (float)rdram_s8[10] / 127.0f; rdp.light[n].dir[2] = (float)rdram_s8[9] / 127.0f; rdp.light[n].x = (float)rdram[5]; rdp.light[n].y = (float)rdram[4]; rdp.light[n].z = (float)rdram[7]; rdp.light[n].ca = (float)rdram[0] / 16.0f; rdp.light[n].la = (float)rdram[4]; rdp.light[n].qa = (float)rdram[13] / 8.0f; //g_gdp.flags |= UPDATE_LIGHTS; } } static void gSPViewport_G64(uint32_t v) { int16_t *rdram = (int16_t*)(gfx_info.RDRAM + RSP_SegmentToPhysical( v )); int16_t scale_y = rdram[0] >> 2; int16_t scale_x = rdram[1] >> 2; int16_t scale_z = rdram[3]; int16_t trans_x = rdram[5] >> 2; int16_t trans_y = rdram[4] >> 2; int16_t trans_z = rdram[7]; if (settings.correct_viewport) { scale_x = abs(scale_x); scale_y = abs(scale_y); } rdp.view_scale[0] = scale_x * rdp.scale_x; rdp.view_scale[1] = -scale_y * rdp.scale_y; rdp.view_scale[2] = 32.0f * scale_z; rdp.view_trans[0] = trans_x * rdp.scale_x; rdp.view_trans[1] = trans_y * rdp.scale_y; rdp.view_trans[2] = 32.0f * trans_z; g_gdp.flags |= UPDATE_VIEWPORT; } static void gSPFogFactor_G64(int16_t fm, int16_t fo ) { rdp.fog_multiplier = fm; rdp.fog_offset = fo; } static void gSPNumLights_G64(int32_t n) { if (n > 12) return; rdp.num_lights = n; g_gdp.flags |= UPDATE_LIGHTS; } static void gSPForceMatrix_G64( uint32_t mptr ) { uint32_t address = RSP_SegmentToPhysical( mptr ); load_matrix(rdp.combined, address); g_gdp.flags &= ~UPDATE_MULT_MAT; } static void gSPPopMatrixN_G64(uint32_t param, uint32_t num ) { if (rdp.model_i > num - 1) { rdp.model_i -= num; } memcpy (rdp.model, rdp.model_stack[rdp.model_i], 64); g_gdp.flags |= UPDATE_MULT_MAT; } static void gSPPopMatrix_G64(uint32_t param) { switch (param) { case 0: // modelview if (rdp.model_i > 0) { rdp.model_i--; memcpy (rdp.model, rdp.model_stack[rdp.model_i], 64); g_gdp.flags |= UPDATE_MULT_MAT; } break; case 1: // projection, can't break; default: #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR | DEBUG_MATRIX, "// Attempting to pop matrix stack below 0\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_MATRIX, "gSPPopMatrix( %s );\n", (param == G_MTX_MODELVIEW) ? "G_MTX_MODELVIEW" : (param == G_MTX_PROJECTION) ? "G_MTX_PROJECTION" : "G_MTX_INVALID" ); #endif break; } } static void gSPLightColor_G64( uint32_t lightNum, uint32_t packedColor ) { lightNum--; if (lightNum < 8) { rdp.light[lightNum].col[0] = _SHIFTR( packedColor, 24, 8 ) * 0.0039215689f; rdp.light[lightNum].col[1] = _SHIFTR( packedColor, 16, 8 ) * 0.0039215689f; rdp.light[lightNum].col[2] = _SHIFTR( packedColor, 8, 8 ) * 0.0039215689f; rdp.light[lightNum].col[3] = 255; } } static void gSPDlistCount_G64(uint32_t count, uint32_t v) { uint32_t address = RSP_SegmentToPhysical(v); if (rdp.pc_i >= 9 || address == 0) return; rdp.pc_i ++; // go to the next PC in the stack rdp.pc[rdp.pc_i] = address; // jump to the address rdp.dl_count = count + 1; } static void gSPModifyVertex_G64( uint32_t vtx, uint32_t where, uint32_t val ) { VERTEX *v = (VERTEX*)&rdp.vtx[vtx]; switch (where) { case 0: uc6_obj_sprite(rdp.cmd0, rdp.cmd1); break; case G_MWO_POINT_RGBA: v->r = (uint8_t)(val >> 24); v->g = (uint8_t)((val >> 16) & 0xFF); v->b = (uint8_t)((val >> 8) & 0xFF); v->a = (uint8_t)(val & 0xFF); v->shade_mod = 0; break; case G_MWO_POINT_ST: { float scale = (rdp.othermode_h & RDP_PERSP_TEX_ENABLE) ? 0.03125f : 0.015625f; v->ou = (float)((int16_t)(val>>16)) * scale; v->ov = (float)((int16_t)(val&0xFFFF)) * scale; v->uv_calculated = 0xFFFFFFFF; v->uv_scaled = 1; } break; case G_MWO_POINT_XYSCREEN: { float scr_x = (float)((int16_t)(val>>16)) / 4.0f; float scr_y = (float)((int16_t)(val&0xFFFF)) / 4.0f; v->screen_translated = 2; v->sx = scr_x * rdp.scale_x + rdp.offset_x; v->sy = scr_y * rdp.scale_y + rdp.offset_y; if (v->w < 0.01f) { v->w = 1.0f; v->oow = 1.0f; v->z_w = 1.0f; } v->sz = rdp.view_trans[2] + v->z_w * rdp.view_scale[2]; v->scr_off = 0; if (scr_x < 0) v->scr_off |= 1; if (scr_x > rdp.vi_width) v->scr_off |= 2; if (scr_y < 0) v->scr_off |= 4; if (scr_y > rdp.vi_height) v->scr_off |= 8; if (v->w < 0.1f) v->scr_off |= 16; } break; case G_MWO_POINT_ZSCREEN: { float scr_z = _FIXED2FLOAT((int16_t)_SHIFTR(val, 16, 16), 15); v->z_w = (scr_z - rdp.view_trans[2]) / rdp.view_scale[2]; v->z = v->z_w * v->w; } break; } } static void gSPEndDisplayList_G64(void) { if (rdp.pc_i > 0) rdp.pc_i --; else { //LRDP("RDP end\n"); // Halt execution here rdp.halt = 1; } } static bool gSPCullVertices_G64( uint32_t v0, uint32_t vn ) { uint32_t i, clip = 0; if (vn < v0) { // Aidyn Chronicles - The First Mage seems to pass parameters in reverse order. const uint32_t v = v0; v0 = vn; vn = v; } /* Wipeout 64 passes vn = 512, increasing MAX_VTX to 512+ doesn't fix. */ if (vn > MAX_VTX) return false; for (i = v0; i <= vn; i++) { VERTEX *v = (VERTEX*)&rdp.vtx[i]; // Check if completely off the screen (quick frustrum clipping for 90 FOV) if (v->x >= -v->w) clip |= 0x01; if (v->x <= v->w) clip |= 0x02; if (v->y >= -v->w) clip |= 0x04; if (v->y <= v->w) clip |= 0x08; if (v->w >= 0.1f) clip |= 0x10; if (clip == 0x1F) return false; } return true; } static void gSPCullDisplayList_G64( uint32_t v0, uint32_t vn ) { if (gSPCullVertices_G64( v0, vn )) gSPEndDisplayList_G64(); } mupen64plus-core/000700 001750 001750 00000000000 12656647145 015036 5ustar00sergiosergio000000 000000 gles2n64/src/F3D.c000664 001750 001750 00000017511 12655644434 014577 0ustar00sergiosergio000000 000000 #include "gles2N64.h" #include "Debug.h" #include "F3D.h" #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gSP.h" #include "gDP.h" #include "GBI.h" #include "OpenGL.h" #include "DepthBuffer.h" #include "Config.h" void F3D_SPNoOp( u32 w0, u32 w1 ) { gSPNoOp(); } void F3D_Mtx( u32 w0, u32 w1 ) { if (_SHIFTR( w0, 0, 16 ) != 64) { #ifdef DEBUG DebugMsg( DEBUG_MEDIUM | DEBUG_HIGH | DEBUG_ERROR, "G_MTX: address = 0x%08X length = %i params = 0x%02X\n", w1, _SHIFTR( w0, 0, 16 ), _SHIFTR( w0, 16, 8 ) ); #endif return; } gSPMatrix( w1, _SHIFTR( w0, 16, 8 ) ); } void F3D_Reserved0( u32 w0, u32 w1 ) { #ifdef DEBUG DebugMsg( DEBUG_MEDIUM | DEBUG_IGNORED | DEBUG_UNKNOWN, "G_RESERVED0: w0=0x%08lX w1=0x%08lX\n", w0, w1 ); #endif } void F3D_MoveMem( u32 w0, u32 w1 ) { switch (_SHIFTR( w0, 16, 8 )) { case F3D_MV_VIEWPORT://G_MV_VIEWPORT: gSPViewport( w1 ); break; case G_MV_MATRIX_1: gSPForceMatrix( w1 ); // force matrix takes four commands __RSP.PC[__RSP.PCi] += 24; break; case G_MV_L0: gSPLight( w1, LIGHT_1 ); break; case G_MV_L1: gSPLight( w1, LIGHT_2 ); break; case G_MV_L2: gSPLight( w1, LIGHT_3 ); break; case G_MV_L3: gSPLight( w1, LIGHT_4 ); break; case G_MV_L4: gSPLight( w1, LIGHT_5 ); break; case G_MV_L5: gSPLight( w1, LIGHT_6 ); break; case G_MV_L6: gSPLight( w1, LIGHT_7 ); break; case G_MV_L7: gSPLight( w1, LIGHT_8 ); break; case G_MV_LOOKATX: gSPLookAt(w1, 0); break; case G_MV_LOOKATY: gSPLookAt(w1, 1); break; } } void F3D_Vtx( u32 w0, u32 w1 ) { gSPVertex( w1, _SHIFTR( w0, 20, 4 ) + 1, _SHIFTR( w0, 16, 4 ) ); } void F3D_Reserved1( u32 w0, u32 w1 ) { } void F3D_DList( u32 w0, u32 w1 ) { switch (_SHIFTR( w0, 16, 8 )) { case G_DL_PUSH: gSPDisplayList( w1 ); break; case G_DL_NOPUSH: gSPBranchList( w1 ); break; } } void F3D_Reserved2( u32 w0, u32 w1 ) { } void F3D_Reserved3( u32 w0, u32 w1 ) { } void F3D_Sprite2D_Base( u32 w0, u32 w1 ) { gSPSprite2DBase( w1 ); } void F3D_Tri1( u32 w0, u32 w1 ) { gSP1Triangle( _SHIFTR( w1, 16, 8 ) / 10, _SHIFTR( w1, 8, 8 ) / 10, _SHIFTR( w1, 0, 8 ) / 10); } void F3D_CullDL( u32 w0, u32 w1 ) { gSPCullDisplayList( _SHIFTR( w0, 0, 24 ) / 40, (w1 / 40) - 1 ); } void F3D_PopMtx( u32 w0, u32 w1 ) { gSPPopMatrix( w1 ); } void F3D_MoveWord( u32 w0, u32 w1 ) { switch (_SHIFTR( w0, 0, 8 )) { case G_MW_MATRIX: gSPInsertMatrix( _SHIFTR( w0, 8, 16 ), w1 ); break; case G_MW_NUMLIGHT: gSPNumLights( ((w1 - 0x80000000) >> 5) - 1 ); break; case G_MW_CLIP: gSPClipRatio( w1 ); break; case G_MW_SEGMENT: gSPSegment( _SHIFTR( w0, 10, 4 ), w1 & 0x00FFFFFF ); break; case G_MW_FOG: gSPFogFactor( (s16)_SHIFTR( w1, 16, 16 ), (s16)_SHIFTR( w1, 0, 16 ) ); break; case G_MW_LIGHTCOL: switch (_SHIFTR( w0, 8, 16 )) { case F3D_MWO_aLIGHT_1: gSPLightColor( LIGHT_1, w1 ); break; case F3D_MWO_aLIGHT_2: gSPLightColor( LIGHT_2, w1 ); break; case F3D_MWO_aLIGHT_3: gSPLightColor( LIGHT_3, w1 ); break; case F3D_MWO_aLIGHT_4: gSPLightColor( LIGHT_4, w1 ); break; case F3D_MWO_aLIGHT_5: gSPLightColor( LIGHT_5, w1 ); break; case F3D_MWO_aLIGHT_6: gSPLightColor( LIGHT_6, w1 ); break; case F3D_MWO_aLIGHT_7: gSPLightColor( LIGHT_7, w1 ); break; case F3D_MWO_aLIGHT_8: gSPLightColor( LIGHT_8, w1 ); break; } break; case G_MW_POINTS: { const u32 val = _SHIFTR(w0, 8, 16); gSPModifyVertex(val / 40, val % 40, w1); } break; case G_MW_PERSPNORM: gSPPerspNormalize( w1 ); break; } } void F3D_Texture( u32 w0, u32 w1 ) { gSPTexture( _FIXED2FLOAT( _SHIFTR( w1, 16, 16 ), 16 ), _FIXED2FLOAT( _SHIFTR( w1, 0, 16 ), 16 ), _SHIFTR( w0, 11, 3 ), _SHIFTR( w0, 8, 3 ), _SHIFTR( w0, 0, 8 ) ); } void F3D_SetOtherMode_H( u32 w0, u32 w1 ) { const u32 length = _SHIFTR(w0, 0, 8); const u32 shift = _SHIFTR(w0, 8, 8); gSPSetOtherMode_H(length, shift, w1); } void F3D_SetOtherMode_L( u32 w0, u32 w1 ) { const u32 length = _SHIFTR(w0, 0, 8); const u32 shift = _SHIFTR(w0, 8, 8); gSPSetOtherMode_L(length, shift, w1); } void F3D_EndDL( u32 w0, u32 w1 ) { gSPEndDisplayList(); } void F3D_SetGeometryMode( u32 w0, u32 w1 ) { gSPSetGeometryMode( w1 ); } void F3D_ClearGeometryMode( u32 w0, u32 w1 ) { gSPClearGeometryMode( w1 ); } void F3D_Quad( u32 w0, u32 w1 ) { gSP1Quadrangle( _SHIFTR( w1, 24, 8 ) / 10, _SHIFTR( w1, 16, 8 ) / 10, _SHIFTR( w1, 8, 8 ) / 10, _SHIFTR( w1, 0, 8 ) / 10 ); } void F3D_RDPHalf_1( u32 w0, u32 w1 ) { gDP.half_1 = w1; RDP_Half_1(w1); } void F3D_RDPHalf_2( u32 w0, u32 w1 ) { gDP.half_2 = w1; } void F3D_RDPHalf_Cont( u32 w0, u32 w1 ) { } void F3D_Tri4( u32 w0, u32 w1 ) { gSP4Triangles( _SHIFTR( w1, 28, 4 ), _SHIFTR( w0, 12, 4 ), _SHIFTR( w1, 24, 4 ), _SHIFTR( w1, 20, 4 ), _SHIFTR( w0, 8, 4 ), _SHIFTR( w1, 16, 4 ), _SHIFTR( w1, 12, 4 ), _SHIFTR( w0, 4, 4 ), _SHIFTR( w1, 8, 4 ), _SHIFTR( w1, 4, 4 ), _SHIFTR( w0, 0, 4 ), _SHIFTR( w1, 0, 4 ) ); } void F3D_Init(void) { gSPSetupFunctions(); // Set GeometryMode flags GBI_InitFlags( F3D ); GBI.PCStackSize = 10; // GBI Command Command Value Command Function GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_MTX, F3D_MTX, F3D_Mtx ); GBI_SetGBI( G_RESERVED0, F3D_RESERVED0, F3D_Reserved0 ); GBI_SetGBI( G_MOVEMEM, F3D_MOVEMEM, F3D_MoveMem ); GBI_SetGBI( G_VTX, F3D_VTX, F3D_Vtx ); GBI_SetGBI( G_RESERVED1, F3D_RESERVED1, F3D_Reserved1 ); GBI_SetGBI( G_DL, F3D_DL, F3D_DList ); GBI_SetGBI( G_RESERVED2, F3D_RESERVED2, F3D_Reserved2 ); GBI_SetGBI( G_RESERVED3, F3D_RESERVED3, F3D_Reserved3 ); GBI_SetGBI( G_SPRITE2D_BASE, F3D_SPRITE2D_BASE, F3D_Sprite2D_Base ); GBI_SetGBI( G_TRI1, F3D_TRI1, F3D_Tri1 ); GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3D_CullDL ); GBI_SetGBI( G_POPMTX, F3D_POPMTX, F3D_PopMtx ); GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3D_MoveWord ); GBI_SetGBI( G_TEXTURE, F3D_TEXTURE, F3D_Texture ); GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L ); GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL ); GBI_SetGBI( G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, F3D_SetGeometryMode ); GBI_SetGBI( G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE, F3D_ClearGeometryMode ); GBI_SetGBI( G_QUAD, F3D_QUAD, F3D_Quad ); GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_RDPHALF_CONT, F3D_RDPHALF_CONT, F3D_RDPHalf_Cont ); GBI_SetGBI( G_TRI4, F3D_TRI4, F3D_Tri4 ); } glide2gl/src/Glide64/ucode02.h000664 001750 001750 00000030321 12655644434 017006 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** static void calc_point_light (VERTEX *v, float * vpos) { uint32_t l; float color[3]; color[0] = rdp.light[rdp.num_lights].col[0]; color[1] = rdp.light[rdp.num_lights].col[1]; color[2] = rdp.light[rdp.num_lights].col[2]; for (l = 0; l < rdp.num_lights; l++) { float light_intensity = 0.0f; if (rdp.light[l].nonblack) { float lvec[3], light_len2, light_len, at; lvec[0] = rdp.light[l].x - vpos[0]; lvec[1] = rdp.light[l].y - vpos[1]; lvec[2] = rdp.light[l].z - vpos[2]; light_len2 = lvec[0] * lvec[0] + lvec[1] * lvec[1] + lvec[2] * lvec[2]; light_len = sqrtf(light_len2); //FRDP ("calc_point_light: len: %f, len2: %f\n", light_len, light_len2); at = rdp.light[l].ca + light_len/65535.0f*rdp.light[l].la + light_len2/65535.0f*rdp.light[l].qa; if (at > 0.0f) light_intensity = 1/at;//DotProduct (lvec, nvec) / (light_len * normal_len * at); } if (light_intensity > 0.0f) { color[0] += rdp.light[l].col[0] * light_intensity; color[1] += rdp.light[l].col[1] * light_intensity; color[2] += rdp.light[l].col[2] * light_intensity; } } if (color[0] > 1.0f) color[0] = 1.0f; if (color[1] > 1.0f) color[1] = 1.0f; if (color[2] > 1.0f) color[2] = 1.0f; v->r = (uint8_t)(color[0]*255.0f); v->g = (uint8_t)(color[1]*255.0f); v->b = (uint8_t)(color[2]*255.0f); } static void uc2_vertex(uint32_t w0, uint32_t w1) { uint32_t addr, geom_mode; int v0, n; if (!(w0 & 0x00FFFFFF)) { uc6_obj_rectangle(w0, w1); return; } pre_update(); addr = RSP_SegmentToPhysical(w1); n = (w0 >> 12) & 0xFF; v0 = ((w0 >> 1) & 0x7F) - n; if (v0 < 0) return; geom_mode = rdp.geom_mode; if ((settings.hacks&hack_Fzero) && (rdp.geom_mode & G_TEXTURE_GEN)) { if (((int16_t*)gfx_info.RDRAM)[(((addr) >> 1) + 4)^1] || ((int16_t*)gfx_info.RDRAM)[(((addr) >> 1) + 5)^1]) rdp.geom_mode ^= G_TEXTURE_GEN; } gSPVertex_G64(addr, n, v0); rdp.geom_mode = geom_mode; } static void uc2_modifyvtx(uint32_t w0, uint32_t w1) { gSPModifyVertex_G64( _SHIFTR( w0, 1, 15 ), _SHIFTR( w0, 16, 8 ), w1 ); } static void uc2_culldl(uint32_t w0, uint32_t w1) { gSPCullDisplayList_G64( _SHIFTR( w0, 1, 15 ), _SHIFTR( w1, 1, 15 ) ); } static void uc2_tri1(uint32_t w0, uint32_t w1) { VERTEX *v[3]; if ((w0 & 0x00FFFFFF) == 0x17) { uc6_obj_loadtxtr(w0, w1); return; } if (rdp.skip_drawing) return; v[0] = &rdp.vtx[_SHIFTR(w0, 17, 7)]; v[1] = &rdp.vtx[_SHIFTR(w0, 9, 7)]; v[2] = &rdp.vtx[_SHIFTR(w0, 1, 7)]; cull_trianglefaces(v, 1, true, true, 0); } static void uc2_quad(uint32_t w0, uint32_t w1) { VERTEX *v[6]; if ((w0 & 0x00FFFFFF) == 0x2F) { uint32_t command = w0 >> 24; if (command == 0x6) { uc6_obj_ldtx_sprite(w0, w1); return; } if (command == 0x7) { uc6_obj_ldtx_rect(w0, w1); return; } } if (rdp.skip_drawing) return; v[0] = &rdp.vtx[_SHIFTR(w0, 17, 7)]; v[1] = &rdp.vtx[_SHIFTR(w0, 9, 7)]; v[2] = &rdp.vtx[_SHIFTR(w0, 1, 7)]; v[3] = &rdp.vtx[_SHIFTR(w1, 17, 7)]; v[4] = &rdp.vtx[_SHIFTR(w1, 9, 7)]; v[5] = &rdp.vtx[_SHIFTR(w1, 1, 7)]; cull_trianglefaces(v, 2, true, true, 0); } static void uc2_line3d(uint32_t w0, uint32_t w1) { if ( (w0 & 0xFF) == 0x2F ) uc6_ldtx_rect_r(w0, w1); else { VERTEX *v[3]; uint32_t cull_mode; uint16_t width; v[0] = &rdp.vtx[(w0 >> 17) & 0x7F]; v[1] = &rdp.vtx[(w0 >> 9) & 0x7F]; v[2] = &rdp.vtx[(w0 >> 9) & 0x7F]; width = (uint16_t)(w0 + 3)&0xFF; cull_mode = (rdp.flags & CULLMASK) >> CULLSHIFT; rdp.flags |= CULLMASK; g_gdp.flags |= UPDATE_CULL_MODE; cull_trianglefaces(v, 1, true, true, width); rdp.flags ^= CULLMASK; rdp.flags |= cull_mode << CULLSHIFT; g_gdp.flags |= UPDATE_CULL_MODE; } } static void uc2_special3(uint32_t w0, uint32_t w1) { } static void uc2_special2(uint32_t w0, uint32_t w1) { } static void uc2_dma_io(uint32_t w0, uint32_t w1) { } static void uc2_pop_matrix(uint32_t w0, uint32_t w1) { gSPPopMatrixN_G64( 0, w1 >> 6 ); } static void uc2_geom_mode(uint32_t w0, uint32_t w1) { // Switch around some things uint32_t clr_mode = (w0 & 0x00DFC9FF) | ((w0 & 0x00000600) << 3) | ((w0 & 0x00200000) >> 12) | 0xFF000000; uint32_t set_mode = (w1 & 0xFFDFC9FF) | ((w1 & 0x00000600) << 3) | ((w1 & 0x00200000) >> 12); rdp.geom_mode &= clr_mode; rdp.geom_mode |= set_mode; if (rdp.geom_mode & G_ZBUFFER) { if (!(rdp.flags & ZBUF_ENABLED)) { rdp.flags |= ZBUF_ENABLED; g_gdp.flags |= UPDATE_ZBUF_ENABLED; } } else { if ((rdp.flags & ZBUF_ENABLED)) { if (!settings.flame_corona || (rdp.rm != 0x00504341)) //hack for flame's corona rdp.flags ^= ZBUF_ENABLED; g_gdp.flags |= UPDATE_ZBUF_ENABLED; } } if (rdp.geom_mode & CULL_FRONT) { if (!(rdp.flags & CULL_FRONT)) { rdp.flags |= CULL_FRONT; g_gdp.flags |= UPDATE_CULL_MODE; } } else { if (rdp.flags & CULL_FRONT) { rdp.flags ^= CULL_FRONT; g_gdp.flags |= UPDATE_CULL_MODE; } } if (rdp.geom_mode & CULL_BACK) { if (!(rdp.flags & CULL_BACK)) { rdp.flags |= CULL_BACK; g_gdp.flags |= UPDATE_CULL_MODE; } } else { if (rdp.flags & CULL_BACK) { rdp.flags ^= CULL_BACK; g_gdp.flags |= UPDATE_CULL_MODE; } } if (rdp.geom_mode & G_FOG) { if (!(rdp.flags & FOG_ENABLED)) { rdp.flags |= FOG_ENABLED; g_gdp.flags |= UPDATE_FOG_ENABLED; } } else { if (rdp.flags & FOG_ENABLED) { rdp.flags ^= FOG_ENABLED; g_gdp.flags |= UPDATE_FOG_ENABLED; } } } static void uc2_matrix(uint32_t w0, uint32_t w1) { DECLAREALIGN16VAR(m[4][4]); uint8_t command; if (!(w0 & 0x00FFFFFF)) { uc6_obj_rectangle_r(w0, w1); return; } load_matrix(m, RSP_SegmentToPhysical(w1)); command = (uint8_t)((w0 ^ 1) & 0xFF); switch (command) { case 0: // modelview mul nopush modelview_mul (m); break; case 1: // modelview mul push modelview_mul_push (m); break; case 2: // modelview load nopush modelview_load (m); break; case 3: // modelview load push modelview_load_push (m); break; case 4: // projection mul nopush case 5: // projection mul push, can't push projection projection_mul (m); break; case 6: // projection load nopush case 7: // projection load push, can't push projection projection_load (m); break; default: FRDP_E ("Unknown matrix command, %02lx", command); FRDP ("Unknown matrix command, %02lx", command); } } static void uc2_moveword(uint32_t w0, uint32_t w1) { uint16_t offset = (uint16_t)(w0 & 0xFFFF); switch (_SHIFTR( w0, 16, 8)) { case G_MW_MATRIX: // NOTE: right now it's assuming that it sets the integer part first. This could // be easily fixed, but only if i had something to test with. // do matrix pre-mult so it's re-updated next time if (g_gdp.flags & UPDATE_MULT_MAT) { g_gdp.flags ^= UPDATE_MULT_MAT; MulMatrices(rdp.model, rdp.proj, rdp.combined); } if (w0 & 0x20) // fractional part { float fpart; int index_x = (w0 & 0x1F) >> 1; int index_y = index_x >> 2; index_x &= 3; fpart = (w1>>16)/65536.0f; rdp.combined[index_y][index_x] = (float)(int)rdp.combined[index_y][index_x]; rdp.combined[index_y][index_x] += fpart; fpart = (w1&0xFFFF)/65536.0f; rdp.combined[index_y][index_x+1] = (float)(int)rdp.combined[index_y][index_x+1]; rdp.combined[index_y][index_x+1] += fpart; } else { int index_x = (w0 & 0x1F) >> 1; int index_y = index_x >> 2; index_x &= 3; rdp.combined[index_y][index_x] = (short)(w1>>16); rdp.combined[index_y][index_x+1] = (short)(w1&0xFFFF); } break; case G_MW_NUMLIGHT: gSPNumLights_G64( w1 / 24); break; case G_MW_CLIP: if (offset == 0x04) { rdp.clip_ratio = (float)vi_integer_sqrt(w1); g_gdp.flags |= UPDATE_VIEWPORT; } break; case G_MW_SEGMENT: if ((w1 & BMASK) < BMASK) rdp.segment[(offset >> 2) & 0xF] = w1; break; case G_MW_FOG: gSPFogFactor_G64((int16_t)_SHIFTR(w1, 16, 16), (int16_t)_SHIFTR(w1, 0, 16)); /*offset must be 0 for move_fog, but it can be non zero in Nushi Zuri 64 - Shiokaze ni Notte * low-level display list has setothermode commands in this place, so this is obviously not move_fog. */ if (offset == 0x04) rdp.tlut_mode = (w1 == 0xffffffff) ? 0 : 2; break; case G_MW_LIGHTCOL: gSPLightColor_G64((_SHIFTR( w0, 0, 16 ) / 24) + 1, w1 ); break; case G_MW_FORCEMTX: /* Handled in movemem */ break; case G_MW_PERSPNORM: /* implement something here? */ break; } } static void uc2_movemem(uint32_t w0, uint32_t w1) { switch (_SHIFTR(w0, 0, 8)) { case 0: case 2: uc6_obj_movemem(w0, w1); break; case F3DEX2_MV_VIEWPORT: gSPViewport_G64( w1 ); break; case G_MV_MATRIX: gSPForceMatrix_G64(w1); /* force matrix takes two commands */ rdp.pc[rdp.pc_i] += 8; break; case G_MV_LIGHT: { const uint32_t offset = (_SHIFTR( w0, 5, 11)) & 0x7F8; uint32_t n = offset / 24; if (n < 2) gSPLookAt_G64(w1, n); else gSPLight_G64(w1, n - 1); } break; } } static void uc2_load_ucode(uint32_t w0, uint32_t w1) { } static void uc2_rdphalf_2(uint32_t w0, uint32_t w1) { } static void uc2_dlist_cnt(uint32_t w0, uint32_t w1) { gSPDlistCount_G64(_SHIFTR( w0, 0, 8 ), w1); } gles2n64/src/Config.h000664 001750 001750 00000004200 12655644434 015424 0ustar00sergiosergio000000 000000 #ifndef CONFIG_H #define CONFIG_H #include enum Aspect { aStretch = 0, a43 = 1, a169 = 2, aAdjust = 3, aTotal = 4 }; #ifdef __cplusplus extern "C" { #endif #ifdef __LIBRETRO__ // Prefix symbol #define config gln64config #endif #include #define BILINEAR_3POINT 0 #define BILINEAR_STANDARD 1 typedef struct { int version; struct { int width, height; } screen; struct { int force, width, height; } video; struct { int maxAnisotropy; float maxAnisotropyF; int enableMipmap; uint32_t bilinearMode; int useIA; int fastCRC; } texture; struct { uint32_t enableFog; uint32_t enableNoise; uint32_t enableLOD; uint32_t enableHWLighting; uint32_t enableCustomSettings; uint32_t hacks; } generalEmulation; struct { uint32_t enable; uint32_t copyToRDRAM; uint32_t copyDepthToRDRAM; uint32_t copyFromRDRAM; uint32_t detectCFB; uint32_t N64DepthCompare; uint32_t aspect; // 0: stretch ; 1: 4/3 ; 2: 16/9; 3: adjust uint32_t validityCheckMethod; // 0: checksum; 1: fill RDRAM } frameBufferEmulation; int zHack; int enableNoise; int hackAlpha; bool stretchVideo; bool romPAL; //is the rom PAL char romName[21]; } Config; #define hack_Ogre64 (1<<0) //Ogre Battle 64 background copy #define hack_noDepthFrameBuffers (1<<1) //Do not use depth buffers as texture #define hack_blurPauseScreen (1<<2) //Game copies frame buffer to depth buffer area, CPU blurs it. That image is used as background for pause screen. #define hack_scoreboard (1<<3) //Copy data from RDRAM to auxilary frame buffer. Scoreboard in Mario Tennis. #define hack_pilotWings (1<<4) //Special blend mode for PilotWings. #define hack_subscreen (1<<5) //Fix subscreen delay in Zelda OOT #define hack_legoRacers (1<<6) //LEGO racers course map #define hack_blastCorps (1<<7) //Blast Corps black polygons extern Config config; void Config_gln64_LoadConfig(void); void Config_gln64_LoadRomConfig(unsigned char* header); #ifdef __cplusplus } #endif #endif gles2rice/src/RSP_GBI_Sprite2D.h000664 001750 001750 00000012606 12655644434 017404 0ustar00sergiosergio000000 000000 /* Copyright (C) 2002 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // Sprite2D Ucodes #include "Render.h" Sprite2DInfo g_Sprite2DInfo; uint32_t g_SavedUcode=1; void RSP_GBI_Sprite2DBase(Gfx *gfx) { int8_t *rdram_s8 = (int8_t*)gfx_info.RDRAM; uint32_t dwAddr = RSPSegmentAddr((gfx->words.w1)); dwAddr &= (g_dwRamSize-1); //RSP_RDP_NOIMPL("RDP: Sprite2D (0x%08x 0x%08x)", (gfx->words.w0), (gfx->words.w1)); g_Sprite2DInfo.spritePtr = (SpriteStruct *)(rdram_s8 + dwAddr); DEBUGGER_PAUSE_AND_DUMP_COUNT_N(NEXT_SPRITE_2D, {DebuggerAppendMsg("Pause after Sprite2DBase: Addr=%08X\n", dwAddr);}); } typedef struct{ uint32_t SourceImagePointer; uint32_t TlutPointer; short SubImageWidth; short Stride; char SourceImageBitSize; char SourceImageType; short SubImageHeight; short scaleY; short scaleX; short SourceImageOffsetS; char dummy1[2]; short px; short SourceImageOffsetT; char dummy2[2]; short py; } PuzzleMasterSprite; void RSP_GBI_Sprite2D_PuzzleMaster64(Gfx *gfx) { int8_t *rdram_s8 = (int8_t*)gfx_info.RDRAM; uint32_t dwAddr = RSPSegmentAddr((gfx->words.w1)); dwAddr &= (g_dwRamSize-1); g_Sprite2DInfo.spritePtr = (SpriteStruct *)(rdram_s8 + dwAddr); g_Sprite2DInfo.flipX = 0; g_Sprite2DInfo.flipY = 0; g_Sprite2DInfo.px = 0; g_Sprite2DInfo.py = 0; SpriteStruct tempInfo; memcpy(&tempInfo, g_Sprite2DInfo.spritePtr, sizeof(SpriteStruct)); PuzzleMasterSprite info; memcpy(&info, g_Sprite2DInfo.spritePtr, sizeof(PuzzleMasterSprite)); g_Sprite2DInfo.px = info.px>>2; g_Sprite2DInfo.py = info.py>>2; g_Sprite2DInfo.scaleX = info.scaleX / 1024.0f; g_Sprite2DInfo.scaleY = info.scaleY / 1024.0f; tempInfo.SourceImageOffsetS = info.SourceImageOffsetS; tempInfo.SourceImageOffsetT = info.SourceImageOffsetT; g_Sprite2DInfo.spritePtr = &tempInfo; CRender::g_pRender->DrawSprite2D(g_Sprite2DInfo, 1); DEBUGGER_PAUSE_AND_DUMP_COUNT_N(NEXT_SPRITE_2D, {DebuggerAppendMsg("Pause after Sprite2DBase: Addr=%08X\n", dwAddr);}); } void RSP_GBI1_Sprite2DDraw(Gfx *gfx) { // This ucode is shared by PopMtx and gSPSprite2DDraw g_Sprite2DInfo.px = (short)(((gfx->words.w1)>>16)&0xFFFF)/4; g_Sprite2DInfo.py = (short)((gfx->words.w1)&0xFFFF)/4; //RSP_RDP_NOIMPL("gSPSprite2DDraw is not implemented", (gfx->words.w0), (gfx->words.w1)); CRender::g_pRender->DrawSprite2D(g_Sprite2DInfo, 1); DEBUGGER_PAUSE_AND_DUMP_COUNT_N(NEXT_SPRITE_2D, {DebuggerAppendMsg("Pause after Sprite2DDraw at (%d, %d)\n", g_Sprite2DInfo.px, g_Sprite2DInfo.py);}); LoadedUcodeMap[RSP_SPRITE2D_SCALEFLIP] = &RSP_GBI1_CullDL; LoadedUcodeMap[RSP_SPRITE2D_DRAW] = &RSP_GBI1_PopMtx; LoadedUcodeMap[RSP_SPRITE2D_BASE] = &RSP_GBI1_Sprite2DBase; } void RSP_GBI0_Sprite2DDraw(Gfx *gfx) { // This ucode is shared by PopMtx and gSPSprite2DDraw g_Sprite2DInfo.px = (short)(((gfx->words.w1)>>16)&0xFFFF)/4; g_Sprite2DInfo.py = (short)((gfx->words.w1)&0xFFFF)/4; //RSP_RDP_NOIMPL("gSPSprite2DDraw is not implemented", (gfx->words.w0), (gfx->words.w1)); CRender::g_pRender->DrawSprite2D(g_Sprite2DInfo, 0); DEBUGGER_PAUSE_AND_DUMP_COUNT_N(NEXT_SPRITE_2D, {TRACE0("Pause after Sprite2DDraw\n");}); } void RSP_GBI1_Sprite2DScaleFlip(Gfx *gfx) { g_Sprite2DInfo.scaleX = (((gfx->words.w1)>>16)&0xFFFF)/1024.0f; g_Sprite2DInfo.scaleY = ((gfx->words.w1)&0xFFFF)/1024.0f; if( ((gfx->words.w1)&0xFFFF) < 0x100 ) { g_Sprite2DInfo.scaleY = g_Sprite2DInfo.scaleX; } g_Sprite2DInfo.flipX = (uint8_t)(((gfx->words.w0)>>8)&0xFF); g_Sprite2DInfo.flipY = (uint8_t)((gfx->words.w0)&0xFF); //RSP_RDP_NOIMPL("RSP_SPRITE2D_SCALEFLIP is not implemented", (gfx->words.w0), (gfx->words.w1)); DEBUGGER_PAUSE_AND_DUMP_COUNT_N(NEXT_SPRITE_2D, {DebuggerAppendMsg("Pause after Sprite2DScaleFlip, Flip (%d,%d), Scale (%f, %f)\n", g_Sprite2DInfo.flipX, g_Sprite2DInfo.flipY, g_Sprite2DInfo.scaleX, g_Sprite2DInfo.scaleY);}); } void RSP_GBI1_Sprite2DBase(Gfx *gfx) { if( !status.bUseModifiedUcodeMap ) { memcpy( &LoadedUcodeMap, &ucodeMap1, sizeof(UcodeMap)); status.bUseModifiedUcodeMap = true; } LoadedUcodeMap[RSP_SPRITE2D_BASE] = &RSP_GBI_Sprite2DBase; LoadedUcodeMap[RSP_SPRITE2D_SCALEFLIP] = &RSP_GBI1_Sprite2DScaleFlip; LoadedUcodeMap[RSP_SPRITE2D_DRAW] = &RSP_GBI1_Sprite2DDraw; TRACE0("Adding Sprite2D ucodes to ucode 1"); RSP_GBI_Sprite2DBase(gfx); } void RSP_GBI0_Sprite2DBase(Gfx *gfx) { //Weired, this ucode 0 game is using ucode 1, but sprite2D cmd is working differently from //normal ucode1 sprite2D game TRACE0("Ucode 0 game is using Sprite2D, and using ucode 1 codes, create a new ucode for me"); RSP_GBI_Sprite2DBase(gfx); } gles2rice/src/Texture.cpp000664 001750 001750 00000020727 12655644434 016541 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "TextureManager.h" ////////////////////////////////////////// // Constructors / Deconstructors // Probably shouldn't need more than 4096 * 4096 CTexture::CTexture(uint32_t dwWidth, uint32_t dwHeight, TextureUsage usage) : m_dwWidth(dwWidth), m_dwHeight(dwHeight), m_dwCreatedTextureWidth(dwWidth), m_dwCreatedTextureHeight(dwHeight), m_fXScale(1.0f), m_fYScale(1.0f), m_bScaledS(false), m_bScaledT(false), m_bClampedS(false), m_bClampedT(false), m_bIsEnhancedTexture(false), m_Usage(usage), m_pTexture(NULL), m_dwTextureFmt(TEXTURE_FMT_A8R8G8B8) { // fix me, do something here } CTexture::~CTexture(void) { } TextureFmt CTexture::GetSurfaceFormat(void) { if (m_pTexture == NULL) return TEXTURE_FMT_UNKNOWN; else return m_dwTextureFmt; } uint32_t CTexture::GetPixelSize() { if( m_dwTextureFmt == TEXTURE_FMT_A8R8G8B8 ) return 4; else return 2; } // There are reasons to create this function. D3D and OGL will only create surface of width and height // as 2's pow, for example, N64's 20x14 image, D3D and OGL will create a 32x16 surface. // When we using such a surface as D3D texture, and the U and V address is for the D3D and OGL surface // width and height. It is still OK if the U and V addr value is less than the real image within // the D3D surface. But we will have problems if the U and V addr value is larger than it, or even // large then 1.0. // In such a case, we need to scale the image to the D3D surface dimension, to ease the U/V addr // limition void CTexture::ScaleImageToSurface(bool scaleS, bool scaleT) { uint8_t g_ucTempBuffer[1024*1024*4]; if( scaleS==false && scaleT==false) return; // If the image is not scaled, call this function to scale the real image to // the D3D given dimension uint32_t width = scaleS ? m_dwWidth : m_dwCreatedTextureWidth; uint32_t height = scaleT ? m_dwHeight : m_dwCreatedTextureHeight; uint32_t xDst, yDst; uint32_t xSrc, ySrc; DrawInfo di; if (!StartUpdate(&di)) { return; } int pixSize = GetPixelSize(); // Copy across from the temp buffer to the surface switch (pixSize) { case 4: { memcpy((uint8_t*)g_ucTempBuffer, (uint8_t*)(di.lpSurface), m_dwHeight*m_dwCreatedTextureWidth*4); uint32_t * pDst; uint32_t * pSrc; for (yDst = 0; yDst < m_dwCreatedTextureHeight; yDst++) { // ySrc ranges from 0..m_dwHeight // I'd rather do this but sometimes very narrow (i.e. 1 pixel) // surfaces are created which results in /0... //ySrc = (yDst * (m_dwHeight-1)) / (d3dTextureHeight-1); ySrc = (uint32_t)((yDst * height) / m_dwCreatedTextureHeight+0.49f); pSrc = (uint32_t*)((uint8_t*)g_ucTempBuffer + (ySrc * m_dwCreatedTextureWidth * 4)); pDst = (uint32_t*)((uint8_t*)di.lpSurface + (yDst * di.lPitch)); for (xDst = 0; xDst < m_dwCreatedTextureWidth; xDst++) { xSrc = (uint32_t)((xDst * width) / m_dwCreatedTextureWidth+0.49f); pDst[xDst] = pSrc[xSrc]; } } } break; case 2: { memcpy((uint8_t*)g_ucTempBuffer, (uint8_t*)(di.lpSurface), m_dwHeight*m_dwCreatedTextureWidth*2); uint16_t * pDst; uint16_t * pSrc; for (yDst = 0; yDst < m_dwCreatedTextureHeight; yDst++) { // ySrc ranges from 0..m_dwHeight ySrc = (yDst * height) / m_dwCreatedTextureHeight; pSrc = (uint16_t*)((uint8_t*)g_ucTempBuffer + (ySrc * m_dwCreatedTextureWidth * 2)); pDst = (uint16_t*)((uint8_t*)di.lpSurface + (yDst * di.lPitch)); for (xDst = 0; xDst < m_dwCreatedTextureWidth; xDst++) { xSrc = (xDst * width) / m_dwCreatedTextureWidth; pDst[xDst] = pSrc[xSrc]; } } } break; } EndUpdate(&di); if( scaleS ) m_bScaledS = true; if( scaleT ) m_bScaledT = true; } void CTexture::ClampImageToSurfaceS() { if( !m_bClampedS && m_dwWidth < m_dwCreatedTextureWidth ) { DrawInfo di; if( StartUpdate(&di) ) { if( m_dwTextureFmt == TEXTURE_FMT_A8R8G8B8 ) { for( uint32_t y = 0; y>16); uint32_t dwGreen = (uint8_t)((dw & 0x0000FF00)>>8 ); uint32_t dwBlue = (uint8_t)((dw & 0x000000FF) ); uint32_t dwAlpha = (dwRed+dwGreen+dwBlue)/3; dw &= 0x00FFFFFF; dw |= (dwAlpha<<24); /* uint32_t dw = dwSrc[x]; if( (dw&0x00FFFFFF) > 0 ) dw |= 0xFF000000; else dw &= 0x00FFFFFF; */ } } EndUpdate(&di); } else { //TRACE0("Cannot lock texture"); } } glide2gl/src/Glide64/glidemain.c000664 001750 001750 00000056173 12655644434 017506 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** #include "Gfx_1.3.h" #include "Util.h" #include "3dmath.h" #include "Combine.h" #include "TexCache.h" #include "CRC.h" #include "FBtoScreen.h" #include "DepthBufferRender.h" #include "Glide64_Ini.h" #include "api/libretro.h" extern void CRC_BuildTable(); extern retro_log_printf_t log_cb; extern uint32_t screen_aspectmodehint; #if defined(__GNUC__) #include #elif defined(__MSC__) #include #define PATH_MAX MAX_PATH #endif #define G64_VERSION "G64 Mk2" #define RELTIME "Date: " __DATE__// " Time: " __TIME__ #ifdef __LIBRETRO__ // Prefix API #define VIDEO_TAG(X) glide64##X #define ReadScreen2 VIDEO_TAG(ReadScreen2) #define PluginStartup VIDEO_TAG(PluginStartup) #define PluginShutdown VIDEO_TAG(PluginShutdown) #define PluginGetVersion VIDEO_TAG(PluginGetVersion) #define CaptureScreen VIDEO_TAG(CaptureScreen) #define ChangeWindow VIDEO_TAG(ChangeWindow) #define CloseDLL VIDEO_TAG(CloseDLL) #define DllTest VIDEO_TAG(DllTest) #define DrawScreen VIDEO_TAG(DrawScreen) #define GetDllInfo VIDEO_TAG(GetDllInfo) #define InitiateGFX VIDEO_TAG(InitiateGFX) #define MoveScreen VIDEO_TAG(MoveScreen) #define RomClosed VIDEO_TAG(RomClosed) #define RomOpen VIDEO_TAG(RomOpen) #define ShowCFB VIDEO_TAG(ShowCFB) #define SetRenderingCallback VIDEO_TAG(SetRenderingCallback) #define UpdateScreen VIDEO_TAG(UpdateScreen) #define ViStatusChanged VIDEO_TAG(ViStatusChanged) #define ViWidthChanged VIDEO_TAG(ViWidthChanged) #define ReadScreen VIDEO_TAG(ReadScreen) #define FBGetFrameBufferInfo VIDEO_TAG(FBGetFrameBufferInfo) #define FBRead VIDEO_TAG(FBRead) #define FBWrite VIDEO_TAG(FBWrite) #define ProcessDList VIDEO_TAG(ProcessDList) #define ProcessRDPList VIDEO_TAG(ProcessRDPList) #define ResizeVideoOutput VIDEO_TAG(ResizeVideoOutput) #define InitGfx VIDEO_TAG(InitGfx) #endif void (*_gSPVertex)(uint32_t addr, uint32_t n, uint32_t v0); int romopen = false; int exception = false; /* custom macros made up by cxd4 for tracking the system type better */ #define OS_TV_TYPE_PAL 0 #define OS_TV_TYPE_NTSC 1 #define OS_TV_TYPE_MPAL 2 unsigned int region; // ref rate // 60=0x0, 70=0x1, 72=0x2, 75=0x3, 80=0x4, 90=0x5, 100=0x6, 85=0x7, 120=0x8, none=0xff uint32_t BMASK = 0x7FFFFF; // Reality display processor structure struct RDP rdp; SETTINGS settings = { false, 640, 480, 0, 0 }; VOODOO voodoo = {0, 0}; uint32_t offset_textures = 0; uint32_t offset_texbuf1 = 0; int capture_screen = 0; char capture_path[256]; // SOME FUNCTION DEFINITIONS void glide_set_filtering(unsigned value); static void (*l_DebugCallback)(void *, int, const char *) = NULL; static void *l_DebugCallContext = NULL; void _ChangeSize(void) { float res_scl_y = (float)settings.res_y / 240.0f; uint32_t dwHStartReg = *gfx_info.VI_H_START_REG; uint32_t dwVStartReg = *gfx_info.VI_V_START_REG; float fscale_x = 0.0; float fscale_y = 0.0; float aspect = 0.0; uint32_t hstart = dwHStartReg >> 16; uint32_t hend = dwHStartReg & 0xFFFF; uint32_t vstart = dwVStartReg >> 16; uint32_t vend = dwVStartReg & 0xFFFF; rdp.scale_1024 = settings.scr_res_x / 1024.0f; rdp.scale_768 = settings.scr_res_y / 768.0f; uint32_t scale_x = *gfx_info.VI_X_SCALE_REG & 0xFFF; uint32_t scale_y = *gfx_info.VI_Y_SCALE_REG & 0xFFF; if (!scale_x) return; if (!scale_y) return; fscale_x = (float)scale_x / 1024.0f; fscale_y = (float)scale_y / 2048.0f; // dunno... but sometimes this happens if (hend == hstart) hend = (int)(*gfx_info.VI_WIDTH_REG / fscale_x); rdp.vi_width = (hend - hstart) * fscale_x; rdp.vi_height = (vend - vstart) * fscale_y * 1.0126582f; aspect = (settings.adjust_aspect && (fscale_y > fscale_x) && (rdp.vi_width > rdp.vi_height)) ? fscale_x/fscale_y : 1.0f; rdp.scale_x = (float)settings.res_x / rdp.vi_width; if (region != OS_TV_TYPE_NTSC && settings.pal230) { // odd... but pal games seem to want 230 as height... rdp.scale_y = res_scl_y * (230.0f / rdp.vi_height) * aspect; } else { rdp.scale_y = (float)settings.res_y / rdp.vi_height * aspect; } rdp.offset_y = ((float)settings.res_y - rdp.vi_height * rdp.scale_y) * 0.5f; if (((uint32_t)rdp.vi_width <= (*gfx_info.VI_WIDTH_REG)/2) && (rdp.vi_width > rdp.vi_height)) rdp.scale_y *= 0.5f; g_gdp.__clip.xh = 0; g_gdp.__clip.yh = 0; g_gdp.__clip.xl = (uint32_t)rdp.vi_width; g_gdp.__clip.yl = (uint32_t)rdp.vi_height; g_gdp.flags |= UPDATE_VIEWPORT | UPDATE_SCISSOR; } void ChangeSize(void) { float offset_y; switch (screen_aspectmodehint) { case 0: //4:3 if (settings.scr_res_x >= settings.scr_res_y * 4.0f / 3.0f) { settings.res_y = settings.scr_res_y; settings.res_x = (uint32_t)(settings.res_y * 4.0f / 3.0f); } else { settings.res_x = settings.scr_res_x; settings.res_y = (uint32_t)(settings.res_x / 4.0f * 3.0f); } break; case 1: //16:9 if (settings.scr_res_x >= settings.scr_res_y * 16.0f / 9.0f) { settings.res_y = settings.scr_res_y; settings.res_x = (uint32_t)(settings.res_y * 16.0f / 9.0f); } else { settings.res_x = settings.scr_res_x; settings.res_y = (uint32_t)(settings.res_x / 16.0f * 9.0f); } break; default: //stretch or original settings.res_x = settings.scr_res_x; settings.res_y = settings.scr_res_y; } _ChangeSize (); rdp.offset_x = (settings.scr_res_x - settings.res_x) / 2.0f; offset_y = (settings.scr_res_y - settings.res_y) / 2.0f; settings.res_x += (uint32_t)rdp.offset_x; settings.res_y += (uint32_t)offset_y; rdp.offset_y += offset_y; if (settings.aspectmode == 3) // original { rdp.scale_x = rdp.scale_y = 1.0f; rdp.offset_x = (settings.scr_res_x - rdp.vi_width) / 2.0f; rdp.offset_y = (settings.scr_res_y - rdp.vi_height) / 2.0f; } // settings.res_x = settings.scr_res_x; // settings.res_y = settings.scr_res_y; } void WriteLog(m64p_msg_level level, const char *msg, ...) { #ifdef DEBUG_GLIDE2GL char buf[1024]; va_list args; va_start(args, msg); vsnprintf(buf, 1023, msg, args); buf[1023]='\0'; va_end(args); if (l_DebugCallback) { l_DebugCallback(l_DebugCallContext, level, buf); } else fprintf(stdout, buf); #endif } int GetTexAddrUMA(int tmu, int texsize) { int addr; addr = voodoo.tmem_ptr[0]; voodoo.tmem_ptr[0] += texsize; voodoo.tmem_ptr[1] = voodoo.tmem_ptr[0]; return addr; } void guLoadTextures(void) { int tbuf_size = 0; bool log2_2048 = (settings.scr_res_x > 1024) ? true : false; tbuf_size = grTexCalcMemRequired(log2_2048 ? GR_LOD_LOG2_2048 : GR_LOD_LOG2_1024, GR_ASPECT_LOG2_1x1, GR_TEXFMT_RGB_565); offset_textures = tbuf_size + 16; } int InitGfx(void) { rdp_reset (); if (!grSstWinOpen()) { ERRLOG("Error setting display mode"); return false; } // get the # of TMUs available voodoo.tex_max_addr = grTexMaxAddress(GR_TMU0); grStipplePattern(settings.stipple_pattern); InitCombine(); if (settings.fog) { guFogGenerateLinear(0.0f, 255.0f); } else settings.fog = false; grDepthBufferMode (GR_DEPTHBUFFER_ZBUFFER); grDepthBufferFunction(GR_CMP_LESS); grDepthMask(FXTRUE); settings.res_x = settings.scr_res_x; settings.res_y = settings.scr_res_y; ChangeSize(); guLoadTextures (); ClearCache (); return true; } void ReleaseGfx(void) { VLOG("ReleaseGfx ()\n"); grSstWinClose (0); rdp_free(); } // new API code begins here! EXPORT void CALL ReadScreen2(void *dest, int *width, int *height, int front) { GrLfbInfo_t info; uint8_t *line = (uint8_t*)dest; *width = settings.res_x; *height = settings.res_y; if (!line) return; info.size = sizeof(GrLfbInfo_t); if (grLfbLock (GR_LFB_READ_ONLY, GR_BUFFER_FRONTBUFFER, GR_LFBWRITEMODE_888, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { uint32_t y, x; // Copy the screen, let's hope this works. for (y = 0; y < settings.res_y; y++) { uint8_t *ptr = (uint8_t*) info.lfbPtr + (info.strideInBytes * y); for (x = 0; x < settings.res_x; x++) { line[x*3] = ptr[2]; // red line[x*3+1] = ptr[1]; // green line[x*3+2] = ptr[0]; // blue ptr += 4; } line += settings.res_x * 3; } // Unlock the frontbuffer grLfbUnlock (GR_LFB_READ_ONLY, GR_BUFFER_FRONTBUFFER); } } EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context, void (*DebugCallback)(void *, int, const char *)) { l_DebugCallback = DebugCallback; l_DebugCallContext = Context; ReadSettings(); return M64ERR_SUCCESS; } EXPORT m64p_error CALL PluginShutdown(void) { return M64ERR_SUCCESS; } EXPORT m64p_error CALL PluginGetVersion(m64p_plugin_type *PluginType, int *PluginVersion, int *APIVersion, const char **PluginNamePtr, int *Capabilities) { /* set version info */ if (PluginType != NULL) *PluginType = M64PLUGIN_GFX; if (PluginVersion != NULL) *PluginVersion = 0x016304; if (APIVersion != NULL) *APIVersion = VIDEO_PLUGIN_API_VERSION; if (PluginNamePtr != NULL) *PluginNamePtr = "Glide64mk2 Video Plugin"; if (Capabilities != NULL) *Capabilities = 0; return M64ERR_SUCCESS; } /****************************************************************** Function: CaptureScreen Purpose: This function dumps the current frame to a file input: pointer to the directory to save the file to output: none *******************************************************************/ EXPORT void CALL CaptureScreen ( char * Directory ) { capture_screen = 1; strcpy (capture_path, Directory); } /****************************************************************** Function: ChangeWindow Purpose: to change the window between fullscreen and window mode. If the window was in fullscreen this should change the screen to window mode and vice vesa. input: none output: none *******************************************************************/ //#warning ChangeWindow unimplemented EXPORT void CALL ChangeWindow (void) { } /****************************************************************** Function: CloseDLL Purpose: This function is called when the emulator is closing down allowing the dll to de-initialise. input: none output: none *******************************************************************/ void CALL CloseDLL (void) { ZLUT_release(); ClearCache (); } /****************************************************************** Function: DrawScreen Purpose: This function is called when the emulator receives a WM_PAINT message. This allows the gfx to fit in when it is being used in the desktop. input: none output: none *******************************************************************/ void CALL DrawScreen (void) { } /****************************************************************** Function: GetDllInfo Purpose: This function allows the emulator to gather information about the dll by filling in the PluginInfo structure. input: a pointer to a PLUGIN_INFO stucture that needs to be filled by the function. (see def above) output: none *******************************************************************/ void CALL GetDllInfo ( PLUGIN_INFO * PluginInfo ) { PluginInfo->Version = 0x0103; // Set to 0x0103 PluginInfo->Type = PLUGIN_TYPE_GFX; // Set to PLUGIN_TYPE_GFX sprintf (PluginInfo->Name, "Glide64mk2 "G64_VERSION RELTIME); // Name of the DLL // If DLL supports memory these memory options then set them to TRUE or FALSE // if it does not support it PluginInfo->NormalMemory = true; // a normal uint8_t array PluginInfo->MemoryBswaped = true; // a normal uint8_t array where the memory has been pre // bswap on a dword (32 bits) boundry } /****************************************************************** Function: InitiateGFX Purpose: This function is called when the DLL is started to give information from the emulator that the n64 graphics uses. This is not called from the emulation thread. Input: Gfx_Info is passed to this function which is defined above. Output: TRUE on success FALSE on failure to initialise ** note on interrupts **: To generate an interrupt set the appropriate bit in MI_INTR_REG and then call the function CheckInterrupts to tell the emulator that there is a waiting interrupt. *******************************************************************/ EXPORT int CALL InitiateGFX (GFX_INFO Gfx_Info) { char name[21] = "DEFAULT"; rdp_new(); // Assume scale of 1 for debug purposes rdp.scale_x = 1.0f; rdp.scale_y = 1.0f; memset (&settings, 0, sizeof(SETTINGS)); ReadSettings (); ReadSpecialSettings (name); math_init (); TexCacheInit (); CRC_BuildTable(); CountCombine(); if (fb_depth_render_enabled) ZLUT_init(); return true; } /****************************************************************** Function: MoveScreen Purpose: This function is called in response to the emulator receiving a WM_MOVE passing the xpos and ypos passed from that message. input: xpos - the x-coordinate of the upper-left corner of the client area of the window. ypos - y-coordinate of the upper-left corner of the client area of the window. output: none *******************************************************************/ EXPORT void CALL MoveScreen (int xpos, int ypos) { } /****************************************************************** Function: RomClosed Purpose: This function is called when a rom is closed. input: none output: none *******************************************************************/ EXPORT void CALL RomClosed (void) { romopen = false; ReleaseGfx (); } static void CheckDRAMSize(void) { uint32_t test = gfx_info.RDRAM[0x007FFFFF] + 1; if (test) BMASK = 0x7FFFFF; else BMASK = 0x3FFFFF; if (log_cb) log_cb(RETRO_LOG_INFO, "Detected RDRAM size: %08lx\n", BMASK); } /****************************************************************** Function: RomOpen Purpose: This function is called when a rom is open. (from the emulation thread) input: none output: none *******************************************************************/ EXPORT int CALL RomOpen (void) { int i; char name[21] = "DEFAULT"; no_dlist = true; romopen = true; ucode_error_report = true; // allowed to report ucode errors rdp_reset (); /* cxd4 -- Glide64 tries to predict PAL scaling based on the ROM header. */ region = OS_TV_TYPE_NTSC; /* Invalid region codes are probably NTSC betas. */ switch (gfx_info.HEADER[BYTE4_XOR_BE(0x3E)]) { case 'A': /* generic NTSC, not documented, used by 1080 Snowboarding */ region = OS_TV_TYPE_NTSC; break; case 'B': /* Brazilian */ region = OS_TV_TYPE_MPAL; break; case 'C': /* Chinese */ region = OS_TV_TYPE_NTSC; break; case 'D': /* German */ region = OS_TV_TYPE_PAL ; break; case 'E': /* North America */ region = OS_TV_TYPE_NTSC; break; case 'F': /* French */ region = OS_TV_TYPE_PAL ; break; case 'G': /* Gateway 64 (NTSC) */ region = OS_TV_TYPE_NTSC; break; case 'H': /* Dutch */ region = OS_TV_TYPE_PAL ; break; case 'I': /* Italian */ region = OS_TV_TYPE_PAL ; break; case 'J': /* Japanese */ region = OS_TV_TYPE_NTSC; break; case 'K': /* Korean */ region = OS_TV_TYPE_NTSC; break; case 'L': /* Gateway 64 (PAL) */ region = OS_TV_TYPE_PAL ; break; case 'N': /* Canadian */ region = OS_TV_TYPE_NTSC; break; case 'P': /* European (basic spec.) */ region = OS_TV_TYPE_PAL ; break; case 'S': /* Spanish */ region = OS_TV_TYPE_PAL ; break; case 'U': /* Australian */ region = OS_TV_TYPE_PAL ; break; case 'W': /* Scandinavian */ region = OS_TV_TYPE_PAL ; break; case 'X': case 'Y': case 'Z': /* documented "others", always PAL I think? */ region = OS_TV_TYPE_PAL ; break; } ReadSpecialSettings (name); // get the name of the ROM for (i = 0; i < 20; i++) name[i] = gfx_info.HEADER[(32+i)^3]; name[20] = 0; // remove all trailing spaces while (name[strlen(name)-1] == ' ') name[strlen(name)-1] = 0; strncpy(rdp.RomName, name, sizeof(name)); ReadSpecialSettings (name); ClearCache (); CheckDRAMSize(); OPEN_RDP_LOG (); OPEN_RDP_E_LOG (); InitGfx (); rdp_setfuncs(); // ** return true; } /****************************************************************** Function: ShowCFB Purpose: Useally once Dlists are started being displayed, cfb is ignored. This function tells the dll to start displaying them again. input: none output: none *******************************************************************/ bool no_dlist = true; EXPORT void CALL ShowCFB (void) { no_dlist = true; VLOG ("ShowCFB ()\n"); } EXPORT void CALL SetRenderingCallback(void (*callback)(int)) { } static void drawViRegBG(void) { bool drawn; FB_TO_SCREEN_INFO fb_info; fb_info.width = *gfx_info.VI_WIDTH_REG; fb_info.height = (uint32_t)rdp.vi_height; fb_info.ul_x = 0; fb_info.lr_x = fb_info.width - 1; fb_info.ul_y = 0; fb_info.lr_y = fb_info.height - 1; fb_info.opaque = 1; fb_info.addr = *gfx_info.VI_ORIGIN_REG; fb_info.size = *gfx_info.VI_STATUS_REG & 3; rdp.last_bg = fb_info.addr; drawn = DrawFrameBufferToScreen(&fb_info); if (settings.hacks&hack_Lego && drawn) { rdp.updatescreen = 1; newSwapBuffers (); DrawFrameBufferToScreen(&fb_info); } } /****************************************************************** Function: UpdateScreen Purpose: This function is called in response to a vsync of the screen were the VI bit in MI_INTR_REG has already been set input: none output: none *******************************************************************/ uint32_t update_screen_count = 0; EXPORT void CALL UpdateScreen (void) { bool forced_update = false; uint32_t width = (*gfx_info.VI_WIDTH_REG) << 1; if (*gfx_info.VI_ORIGIN_REG > width) update_screen_count++; if ( (settings.frame_buffer & fb_cpu_write_hack) && (update_screen_count > ((settings.hacks&hack_Lego) ? 15U : 30U)) && (rdp.last_bg == 0) ) { //DirectCPUWrite hack update_screen_count = 0; no_dlist = true; ClearCache (); width = (*gfx_info.VI_WIDTH_REG) << 1; if (*gfx_info.VI_ORIGIN_REG > width) update_screen_count++; } if( no_dlist ) { if( *gfx_info.VI_ORIGIN_REG > width ) { ChangeSize(); LRDP("ChangeSize done\n"); if (rdp.vi_height != 0) drawViRegBG(); rdp.updatescreen = 1; forced_update = true; } else return; } if (settings.swapmode == 0 || forced_update) newSwapBuffers (); if (settings.swapmode_retro && BUFFERSWAP) retro_return(true); } static void DrawWholeFrameBufferToScreen(void) { FB_TO_SCREEN_INFO fb_info; static uint32_t toScreenCI = 0; if (rdp.ci_width < 200) return; if (rdp.cimg == toScreenCI) return; if (rdp.ci_height == 0) return; toScreenCI = rdp.cimg; fb_info.addr = rdp.cimg; fb_info.size = g_gdp.fb_size; fb_info.width = rdp.ci_width; fb_info.height = rdp.ci_height; fb_info.ul_x = 0; fb_info.lr_x = rdp.ci_width-1; fb_info.ul_y = 0; fb_info.lr_y = rdp.ci_height-1; fb_info.opaque = 0; DrawFrameBufferToScreen(&fb_info); if (!(settings.frame_buffer & fb_ref)) memset(gfx_info.RDRAM+rdp.cimg, 0, (rdp.ci_width*rdp.ci_height) << g_gdp.fb_size >> 1); } uint32_t curframe = 0; extern int need_to_compile; void glide_set_filtering(unsigned value) { if(settings.filtering != value){ need_to_compile = 1; settings.filtering = value; } } void newSwapBuffers(void) { if (!rdp.updatescreen) return; rdp.updatescreen = 0; g_gdp.flags |= UPDATE_SCISSOR | UPDATE_COMBINE | UPDATE_ZBUF_ENABLED | UPDATE_CULL_MODE; grClipWindow (0, 0, settings.scr_res_x, settings.scr_res_y); grDepthBufferFunction (GR_CMP_ALWAYS); grDepthMask (FXFALSE); if (settings.frame_buffer & fb_read_back_to_screen) DrawWholeFrameBufferToScreen(); { grBufferSwap (settings.vsync); if (settings.buff_clear) { grDepthMask (FXTRUE); grBufferClear (0, 0, 0xFFFF); } } if (settings.frame_buffer & fb_read_back_to_screen2) DrawWholeFrameBufferToScreen(); frame_count ++; } /****************************************************************** Function: ViStatusChanged Purpose: This function is called to notify the dll that the ViStatus registers value has been changed. input: none output: none *******************************************************************/ EXPORT void CALL ViStatusChanged(void) { } /****************************************************************** Function: ViWidthChanged Purpose: This function is called to notify the dll that the ViWidth registers value has been changed. input: none output: none *******************************************************************/ EXPORT void CALL ViWidthChanged(void) { } gles2rice/src/CSortedList.h000664 001750 001750 00000006764 12655644434 016752 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _SORTED_LIST_H_ #define _SORTED_LIST_H_ #include template class CSortedList { private: Key *keys; Element *elements; int curSize; int maxSize; public: CSortedList(int size=1000) { maxSize = size; curSize = 0; keys = new Key[size]; elements = new Element[size]; } ~CSortedList() { delete [] keys; delete [] elements; } int size() { return curSize; } void clear() { curSize = 0; } void add(Key key, Element ele) { int i = find(key); if( i >= 0 ) { elements[i] = ele; return; } if( curSize == maxSize ) { // Need to increase maxSize Key *oldkeys = keys; Element *oldelements = elements; int oldmaxsize = maxSize; maxSize *= 2; keys = new Key[maxSize]; elements = new Element[maxSize]; memcpy((void*)keys,(void*)oldkeys,oldmaxsize*sizeof(Key)); memcpy((void*)elements,(void*)oldelements,oldmaxsize*sizeof(Element)); } for( i=0; i key ) { // Found the spot break; } } for( int j=curSize; j>i; j-- ) { keys[j] = keys[j-1]; elements[j] = elements[j-1]; } keys[i] = key; elements[i] = ele; curSize++; } Element operator[](int index) { if( index >= curSize ) index = curSize-1; else if( index < 0 ) index = 0; return elements[index]; } Element get(Key key) { int index = Find(key); return this->operator[](index); } // Binary search int find(Key key) { if( curSize <= 0 ) return -1; int dwMin = 0; int dwMax = curSize - 1; int index = -1; int dwRange; int dwIndex; while (true) { dwRange = dwMax - dwMin; dwIndex = dwMin + (dwRange/2); if( keys[dwIndex] == key ) { index = dwIndex; break; } // If the range is 0, and we didn't match above, then it must be unmatched if (dwRange == 0) break; // If lower, check from min..index // If higher, check from index..max if (key < keys[dwIndex]) { // Lower dwMax = dwIndex; } else { // Higher dwMin = dwIndex + 1; } } return index; } }; #endif mupen64plus-video-gliden64/src/GLideN64.cpp000664 001750 001750 00000000105 12655644434 021402 0ustar00sergiosergio000000 000000 char pluginName[] = "GLideN64"; wchar_t pluginNameW[] = L"GLideN64"; libretro/boolean.h000664 001750 001750 00000002040 12655644434 015325 0ustar00sergiosergio000000 000000 /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. * * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with RetroArch. * If not, see . */ #ifndef __RARCH_BOOLEAN_H #define __RARCH_BOOLEAN_H #ifndef __cplusplus #if defined(_MSC_VER) && !defined(SN_TARGET_PS3) /* Hack applied for MSVC when compiling in C89 mode as it isn't C99 compliant. */ #define bool unsigned char #define true 1 #define false 0 #else #include #endif #endif #endif mupen64plus-core/src/api/config.c000664 001750 001750 00000126336 12655644434 020033 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-core - api/config.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2009 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file contains the Core config functions which will be exported * outside of the core library. */ #include #include #include #define M64P_CORE_PROTOTYPES 1 #include "m64p_types.h" #include "m64p_config.h" #include "config.h" #include "callbacks.h" #include "main/util.h" #include "osal/preproc.h" #ifdef __LIBRETRO__ /* Cxd4 RSP */ #include "../../../mupen64plus-rsp-cxd4/config.h" /* TODO/FIXME - put this in some header */ #define GFX_GLIDE64 0 #define GFX_RICE 1 #define GFX_GLN64 2 #define GFX_ANGRYLION 3 #endif /* local types */ #define MUPEN64PLUS_CFG_NAME "mupen64plus.cfg" #define SECTION_MAGIC 0xDBDC0580 typedef struct _config_var { char *name; m64p_type type; union { int integer; float number; char *string; } val; char *comment; struct _config_var *next; } config_var; typedef struct _config_section { int magic; char *name; struct _config_var *first_var; struct _config_section *next; } config_section; typedef config_section *config_list; /* local variables */ static int l_ConfigInit = 0; static int l_SaveConfigOnExit = 0; static char *l_DataDirOverride = NULL; static char *l_ConfigDirOverride = NULL; static config_list l_ConfigListActive = NULL; static config_list l_ConfigListSaved = NULL; /* --------------- */ /* local functions */ /* --------------- */ static int is_numeric(const char *string) { char chTemp[16]; float fTemp; int rval = sscanf(string, "%f%8s", &fTemp, chTemp); /* I want to find exactly one matched input item: a number with no garbage on the end */ /* I use sscanf() instead of a custom loop because this routine must handle locales in which the decimal separator is not '.' */ return (rval == 1); } /* This function returns a pointer to the pointer of the requested section * (i.e. a pointer the next field of the previous element, or to the first node). * * If there's no section named 'ParamName', returns the pointer to the next * field of the last element in the list (such that derefencing it is NULL). * * Useful for operations that need to modify the links, e.g. deleting a section. */ static config_section **find_section_link(config_list *list, const char *ParamName) { config_section **curr_sec_link; for (curr_sec_link = list; *curr_sec_link != NULL; curr_sec_link = &(*curr_sec_link)->next) { if (osal_insensitive_strcmp(ParamName, (*curr_sec_link)->name) == 0) break; } return curr_sec_link; } /* This function is similar to the previous function, but instead it returns a * pointer to the pointer to the next section whose name is alphabetically * greater than or equal to 'ParamName'. * * Useful for inserting a section in its alphabetical position. */ static config_section **find_alpha_section_link(config_list *list, const char *ParamName) { config_section **curr_sec_link; for (curr_sec_link = list; *curr_sec_link != NULL; curr_sec_link = &(*curr_sec_link)->next) { if (osal_insensitive_strcmp((*curr_sec_link)->name, ParamName) >= 0) break; } return curr_sec_link; } static config_section *find_section(config_list list, const char *ParamName) { return *find_section_link(&list, ParamName); } static config_var *config_var_create(const char *ParamName, const char *ParamHelp) { config_var *var = (config_var *) malloc(sizeof(config_var)); if (var == NULL || ParamName == NULL) return NULL; memset(var, 0, sizeof(config_var)); var->name = strdup(ParamName); if (var->name == NULL) { free(var); return NULL; } var->type = M64TYPE_INT; var->val.integer = 0; if (ParamHelp != NULL) { var->comment = strdup(ParamHelp); if (var->comment == NULL) { free(var->name); free(var); return NULL; } } else var->comment = NULL; var->next = NULL; return var; } static config_var *find_section_var(config_section *section, const char *ParamName) { /* walk through the linked list of variables in the section */ config_var *curr_var; for (curr_var = section->first_var; curr_var != NULL; curr_var = curr_var->next) { if (osal_insensitive_strcmp(ParamName, curr_var->name) == 0) return curr_var; } /* couldn't find this configuration parameter */ return NULL; } static void append_var_to_section(config_section *section, config_var *var) { config_var *last_var; if (section == NULL || var == NULL || section->magic != SECTION_MAGIC) return; if (section->first_var == NULL) { section->first_var = var; return; } last_var = section->first_var; while (last_var->next != NULL) last_var = last_var->next; last_var->next = var; } static void delete_var(config_var *var) { if (var->type == M64TYPE_STRING) free(var->val.string); free(var->name); free(var->comment); free(var); } static void delete_section(config_section *pSection) { config_var *curr_var; if (pSection == NULL) return; curr_var = pSection->first_var; while (curr_var != NULL) { config_var *next_var = curr_var->next; delete_var(curr_var); curr_var = next_var; } free(pSection->name); free(pSection); } static void delete_list(config_list *pConfigList) { config_section *curr_section = *pConfigList; while (curr_section != NULL) { config_section *next_section = curr_section->next; /* delete the section itself */ delete_section(curr_section); curr_section = next_section; } *pConfigList = NULL; } static config_section *config_section_create(const char *ParamName) { config_section *sec; if (ParamName == NULL) return NULL; sec = (config_section *) malloc(sizeof(config_section)); if (sec == NULL) return NULL; sec->magic = SECTION_MAGIC; sec->name = strdup(ParamName); if (sec->name == NULL) { free(sec); return NULL; } sec->first_var = NULL; sec->next = NULL; return sec; } static config_section * section_deepcopy(config_section *orig_section) { config_section *new_section; config_var *orig_var, *last_new_var; /* Input validation */ if (orig_section == NULL) return NULL; /* create and copy section struct */ new_section = config_section_create(orig_section->name); if (new_section == NULL) return NULL; /* create and copy all section variables */ orig_var = orig_section->first_var; last_new_var = NULL; while (orig_var != NULL) { config_var *new_var = config_var_create(orig_var->name, orig_var->comment); if (new_var == NULL) { delete_section(new_section); return NULL; } new_var->type = orig_var->type; switch (orig_var->type) { case M64TYPE_INT: case M64TYPE_BOOL: new_var->val.integer = orig_var->val.integer; break; case M64TYPE_FLOAT: new_var->val.number = orig_var->val.number; break; case M64TYPE_STRING: if (orig_var->val.string != NULL) { new_var->val.string = strdup(orig_var->val.string); if (new_var->val.string == NULL) { delete_section(new_section); return NULL; } } else new_var->val.string = NULL; break; } /* add the new variable to the new section */ if (last_new_var == NULL) new_section->first_var = new_var; else last_new_var->next = new_var; last_new_var = new_var; /* advance variable pointer in original section variable list */ orig_var = orig_var->next; } return new_section; } static void copy_configlist_active_to_saved(void) { config_section *curr_section = l_ConfigListActive; config_section *last_section = NULL; /* delete any pre-existing Saved config list */ delete_list(&l_ConfigListSaved); /* duplicate all of the config sections in the Active list, adding them to the Saved list */ while (curr_section != NULL) { config_section *new_section = section_deepcopy(curr_section); if (new_section == NULL) break; if (last_section == NULL) l_ConfigListSaved = new_section; else last_section->next = new_section; last_section = new_section; curr_section = curr_section->next; } } /* ----------------------------------------------------------- */ /* these functions are only to be used within the Core library */ /* ----------------------------------------------------------- */ m64p_error ConfigInit(const char *ConfigDirOverride, const char *DataDirOverride) { if (l_ConfigInit) return M64ERR_ALREADY_INIT; l_ConfigInit = 1; return M64ERR_SUCCESS; } m64p_error ConfigShutdown(void) { /* reset the initialized flag */ if (!l_ConfigInit) return M64ERR_NOT_INIT; l_ConfigInit = 0; /* free any malloc'd local variables */ if (l_DataDirOverride != NULL) { free(l_DataDirOverride); l_DataDirOverride = NULL; } if (l_ConfigDirOverride != NULL) { free(l_ConfigDirOverride); l_ConfigDirOverride = NULL; } /* free all of the memory in the 2 lists */ delete_list(&l_ConfigListActive); delete_list(&l_ConfigListSaved); return M64ERR_SUCCESS; } /* ------------------------------------------------ */ /* Selector functions, exported outside of the Core */ /* ------------------------------------------------ */ EXPORT m64p_error CALL ConfigListSections(void *context, void (*SectionListCallback)(void * context, const char * SectionName)) { config_section *curr_section; if (!l_ConfigInit) return M64ERR_NOT_INIT; if (SectionListCallback == NULL) return M64ERR_INPUT_ASSERT; /* just walk through the section list, making a callback for each section name */ curr_section = l_ConfigListActive; while (curr_section != NULL) { (*SectionListCallback)(context, curr_section->name); curr_section = curr_section->next; } return M64ERR_SUCCESS; } EXPORT m64p_error CALL ConfigOpenSection(const char *SectionName, m64p_handle *ConfigSectionHandle) { config_section **curr_section; config_section *new_section; if (!l_ConfigInit) return M64ERR_NOT_INIT; if (SectionName == NULL || ConfigSectionHandle == NULL) return M64ERR_INPUT_ASSERT; /* walk through the section list, looking for a case-insensitive name match */ curr_section = find_alpha_section_link(&l_ConfigListActive, SectionName); if (*curr_section != NULL && osal_insensitive_strcmp(SectionName, (*curr_section)->name) == 0) { *ConfigSectionHandle = *curr_section; return M64ERR_SUCCESS; } /* didn't find the section, so create new one */ new_section = config_section_create(SectionName); if (new_section == NULL) return M64ERR_NO_MEMORY; /* add section to list in alphabetical order */ new_section->next = *curr_section; *curr_section = new_section; *ConfigSectionHandle = new_section; return M64ERR_SUCCESS; } EXPORT m64p_error CALL ConfigListParameters(m64p_handle ConfigSectionHandle, void *context, void (*ParameterListCallback)(void * context, const char *ParamName, m64p_type ParamType)) { config_section *section; config_var *curr_var; if (!l_ConfigInit) return M64ERR_NOT_INIT; if (ConfigSectionHandle == NULL || ParameterListCallback == NULL) return M64ERR_INPUT_ASSERT; section = (config_section *) ConfigSectionHandle; if (section->magic != SECTION_MAGIC) return M64ERR_INPUT_INVALID; /* walk through this section's parameter list, making a callback for each parameter */ curr_var = section->first_var; while (curr_var != NULL) { (*ParameterListCallback)(context, curr_var->name, curr_var->type); curr_var = curr_var->next; } return M64ERR_SUCCESS; } EXPORT int CALL ConfigHasUnsavedChanges(const char *SectionName) { config_section *input_section, *curr_section; config_var *active_var, *saved_var; /* check input conditions */ if (!l_ConfigInit) { DebugMessage(M64MSG_ERROR, "ConfigHasUnsavedChanges(): Core config not initialized!"); return 0; } /* if SectionName is NULL or blank, then check all sections */ if (SectionName == NULL || strlen(SectionName) < 1) { int iNumActiveSections = 0, iNumSavedSections = 0; /* first, search through all sections in Active list. Recursively call ourself and return 1 if changed */ curr_section = l_ConfigListActive; while (curr_section != NULL) { if (ConfigHasUnsavedChanges(curr_section->name)) return 1; curr_section = curr_section->next; iNumActiveSections++; } /* Next, count the number of Saved sections and see if the count matches */ curr_section = l_ConfigListSaved; while (curr_section != NULL) { curr_section = curr_section->next; iNumSavedSections++; } if (iNumActiveSections == iNumSavedSections) return 0; /* no changes */ else return 1; } /* walk through the Active section list, looking for a case-insensitive name match with input string */ input_section = find_section(l_ConfigListActive, SectionName); if (input_section == NULL) { DebugMessage(M64MSG_ERROR, "ConfigHasUnsavedChanges(): section name '%s' not found!", SectionName); return 0; } /* walk through the Saved section list, looking for a case-insensitive name match */ curr_section = find_section(l_ConfigListSaved, SectionName); if (curr_section == NULL) { /* if this section isn't present in saved list, then it has been newly created */ return 1; } /* compare all of the variables in the two sections. They are expected to be in the same order */ active_var = input_section->first_var; saved_var = curr_section->first_var; while (active_var != NULL && saved_var != NULL) { if (strcmp(active_var->name, saved_var->name) != 0) return 1; if (active_var->type != saved_var->type) return 1; switch(active_var->type) { case M64TYPE_INT: if (active_var->val.integer != saved_var->val.integer) return 1; break; case M64TYPE_FLOAT: if (active_var->val.number != saved_var->val.number) return 1; break; case M64TYPE_BOOL: if ((active_var->val.integer != 0) != (saved_var->val.integer != 0)) return 1; break; case M64TYPE_STRING: if (active_var->val.string == NULL) { DebugMessage(M64MSG_ERROR, "ConfigHasUnsavedChanges(): Variable '%s' NULL Active string pointer!", active_var->name); return 1; } if (saved_var->val.string == NULL) { DebugMessage(M64MSG_ERROR, "ConfigHasUnsavedChanges(): Variable '%s' NULL Saved string pointer!", active_var->name); return 1; } if (strcmp(active_var->val.string, saved_var->val.string) != 0) return 1; break; default: DebugMessage(M64MSG_ERROR, "ConfigHasUnsavedChanges(): Invalid variable '%s' type %i!", active_var->name, active_var->type); return 1; } if (active_var->comment != NULL && saved_var->comment != NULL && strcmp(active_var->comment, saved_var->comment) != 0) return 1; active_var = active_var->next; saved_var = saved_var->next; } /* any extra new variables on the end, or deleted variables? */ if (active_var != NULL || saved_var != NULL) return 1; /* exactly the same */ return 0; } /* ------------------------------------------------------- */ /* Modifier functions, exported outside of the Core */ /* ------------------------------------------------------- */ EXPORT m64p_error CALL ConfigDeleteSection(const char *SectionName) { config_section **curr_section_link; config_section *next_section; if (!l_ConfigInit) return M64ERR_NOT_INIT; if (l_ConfigListActive == NULL) return M64ERR_INPUT_NOT_FOUND; /* find the named section and pull it out of the list */ curr_section_link = find_section_link(&l_ConfigListActive, SectionName); if (*curr_section_link == NULL) return M64ERR_INPUT_NOT_FOUND; next_section = (*curr_section_link)->next; /* delete the named section */ delete_section(*curr_section_link); /* fix the pointer to point to the next section after the deleted one */ *curr_section_link = next_section; return M64ERR_SUCCESS; } EXPORT m64p_error CALL ConfigSaveFile(void) { if (!l_ConfigInit) return M64ERR_NOT_INIT; /* copy the active config list to the saved config list */ copy_configlist_active_to_saved(); return M64ERR_SUCCESS; } EXPORT m64p_error CALL ConfigSaveSection(const char *SectionName) { return M64ERR_SUCCESS; } EXPORT m64p_error CALL ConfigRevertChanges(const char *SectionName) { config_section **active_section_link, *active_section, *saved_section, *new_section; /* check input conditions */ if (!l_ConfigInit) return M64ERR_NOT_INIT; if (SectionName == NULL) return M64ERR_INPUT_ASSERT; /* walk through the Active section list, looking for a case-insensitive name match with input string */ active_section_link = find_section_link(&l_ConfigListActive, SectionName); active_section = *active_section_link; if (active_section == NULL) return M64ERR_INPUT_NOT_FOUND; /* walk through the Saved section list, looking for a case-insensitive name match */ saved_section = find_section(l_ConfigListSaved, SectionName); if (saved_section == NULL) { /* if this section isn't present in saved list, then it has been newly created */ return M64ERR_INPUT_NOT_FOUND; } /* copy the section as it is on the disk */ new_section = section_deepcopy(saved_section); if (new_section == NULL) return M64ERR_NO_MEMORY; /* replace active_section with saved_section in the linked list */ *active_section_link = new_section; new_section->next = active_section->next; /* release memory associated with active_section */ delete_section(active_section); return M64ERR_SUCCESS; } /* ------------------------------------------------------- */ /* Generic Get/Set functions, exported outside of the Core */ /* ------------------------------------------------------- */ EXPORT m64p_error CALL ConfigSetParameter(m64p_handle ConfigSectionHandle, const char *ParamName, m64p_type ParamType, const void *ParamValue) { config_section *section; config_var *var; /* check input conditions */ if (!l_ConfigInit) return M64ERR_NOT_INIT; if (ConfigSectionHandle == NULL || ParamName == NULL || ParamValue == NULL || (int) ParamType < 1 || (int) ParamType > 4) return M64ERR_INPUT_ASSERT; section = (config_section *) ConfigSectionHandle; if (section->magic != SECTION_MAGIC) return M64ERR_INPUT_INVALID; /* if this parameter doesn't already exist, then create it and add it to the section */ var = find_section_var(section, ParamName); if (var == NULL) { var = config_var_create(ParamName, NULL); if (var == NULL) return M64ERR_NO_MEMORY; append_var_to_section(section, var); } /* cleanup old values */ switch (var->type) { case M64TYPE_STRING: free(var->val.string); break; default: break; } /* set this parameter's value */ var->type = ParamType; switch(ParamType) { case M64TYPE_INT: var->val.integer = *((int *) ParamValue); break; case M64TYPE_FLOAT: var->val.number = *((float *) ParamValue); break; case M64TYPE_BOOL: var->val.integer = (*((int *) ParamValue) != 0); break; case M64TYPE_STRING: var->val.string = strdup((char *)ParamValue); if (var->val.string == NULL) return M64ERR_NO_MEMORY; break; default: /* this is logically impossible because of the ParamType check at the top of this function */ break; } return M64ERR_SUCCESS; } EXPORT m64p_error CALL ConfigGetParameter(m64p_handle ConfigSectionHandle, const char *ParamName, m64p_type ParamType, void *ParamValue, int MaxSize) { config_section *section; config_var *var; /* check input conditions */ if (!l_ConfigInit) return M64ERR_NOT_INIT; if (ConfigSectionHandle == NULL || ParamName == NULL || ParamValue == NULL || (int) ParamType < 1 || (int) ParamType > 4) return M64ERR_INPUT_ASSERT; section = (config_section *) ConfigSectionHandle; if (section->magic != SECTION_MAGIC) return M64ERR_INPUT_INVALID; /* if this parameter doesn't already exist, return an error */ var = find_section_var(section, ParamName); if (var == NULL) return M64ERR_INPUT_NOT_FOUND; /* call the specific Get function to translate the parameter to the desired type */ switch(ParamType) { case M64TYPE_INT: if (MaxSize < sizeof(int)) return M64ERR_INPUT_INVALID; if (var->type != M64TYPE_INT && var->type != M64TYPE_FLOAT) return M64ERR_WRONG_TYPE; *((int *) ParamValue) = ConfigGetParamInt(ConfigSectionHandle, ParamName); break; case M64TYPE_FLOAT: if (MaxSize < sizeof(float)) return M64ERR_INPUT_INVALID; if (var->type != M64TYPE_INT && var->type != M64TYPE_FLOAT) return M64ERR_WRONG_TYPE; *((float *) ParamValue) = ConfigGetParamFloat(ConfigSectionHandle, ParamName); break; case M64TYPE_BOOL: if (MaxSize < sizeof(int)) return M64ERR_INPUT_INVALID; if (var->type != M64TYPE_BOOL && var->type != M64TYPE_INT) return M64ERR_WRONG_TYPE; *((int *) ParamValue) = ConfigGetParamBool(ConfigSectionHandle, ParamName); break; case M64TYPE_STRING: { const char *string; if (MaxSize < 1) return M64ERR_INPUT_INVALID; if (var->type != M64TYPE_STRING && var->type != M64TYPE_BOOL) return M64ERR_WRONG_TYPE; string = ConfigGetParamString(ConfigSectionHandle, ParamName); strncpy((char *) ParamValue, string, MaxSize); *((char *) ParamValue + MaxSize - 1) = 0; break; } default: /* this is logically impossible because of the ParamType check at the top of this function */ break; } return M64ERR_SUCCESS; } EXPORT m64p_error CALL ConfigGetParameterType(m64p_handle ConfigSectionHandle, const char *ParamName, m64p_type *ParamType) { config_section *section; config_var *var; /* check input conditions */ if (!l_ConfigInit) return M64ERR_NOT_INIT; if (ConfigSectionHandle == NULL || ParamName == NULL || ParamType == NULL) return M64ERR_INPUT_ASSERT; section = (config_section *) ConfigSectionHandle; if (section->magic != SECTION_MAGIC) return M64ERR_INPUT_INVALID; /* if this parameter doesn't already exist, return an error */ var = find_section_var(section, ParamName); if (var == NULL) return M64ERR_INPUT_NOT_FOUND; *ParamType = var->type; return M64ERR_SUCCESS; } EXPORT const char * CALL ConfigGetParameterHelp(m64p_handle ConfigSectionHandle, const char *ParamName) { config_section *section; config_var *var; /* check input conditions */ if (!l_ConfigInit || ConfigSectionHandle == NULL || ParamName == NULL) return NULL; section = (config_section *) ConfigSectionHandle; if (section->magic != SECTION_MAGIC) return NULL; /* if this parameter doesn't exist, return an error */ var = find_section_var(section, ParamName); if (var == NULL) return NULL; return var->comment; } /* ------------------------------------------------------- */ /* Special Get/Set functions, exported outside of the Core */ /* ------------------------------------------------------- */ EXPORT m64p_error CALL ConfigSetDefaultInt(m64p_handle ConfigSectionHandle, const char *ParamName, int ParamValue, const char *ParamHelp) { config_section *section; config_var *var; /* check input conditions */ if (!l_ConfigInit) return M64ERR_NOT_INIT; if (ConfigSectionHandle == NULL || ParamName == NULL) return M64ERR_INPUT_ASSERT; section = (config_section *) ConfigSectionHandle; if (section->magic != SECTION_MAGIC) return M64ERR_INPUT_INVALID; /* if this parameter already exists, then just return successfully */ var = find_section_var(section, ParamName); if (var != NULL) return M64ERR_SUCCESS; /* otherwise create a new config_var object and add it to this section */ var = config_var_create(ParamName, ParamHelp); if (var == NULL) return M64ERR_NO_MEMORY; var->type = M64TYPE_INT; var->val.integer = ParamValue; append_var_to_section(section, var); return M64ERR_SUCCESS; } EXPORT m64p_error CALL ConfigSetDefaultFloat(m64p_handle ConfigSectionHandle, const char *ParamName, float ParamValue, const char *ParamHelp) { config_section *section; config_var *var; /* check input conditions */ if (!l_ConfigInit) return M64ERR_NOT_INIT; if (ConfigSectionHandle == NULL || ParamName == NULL) return M64ERR_INPUT_ASSERT; section = (config_section *) ConfigSectionHandle; if (section->magic != SECTION_MAGIC) return M64ERR_INPUT_INVALID; /* if this parameter already exists, then just return successfully */ var = find_section_var(section, ParamName); if (var != NULL) return M64ERR_SUCCESS; /* otherwise create a new config_var object and add it to this section */ var = config_var_create(ParamName, ParamHelp); if (var == NULL) return M64ERR_NO_MEMORY; var->type = M64TYPE_FLOAT; var->val.number = ParamValue; append_var_to_section(section, var); return M64ERR_SUCCESS; } EXPORT m64p_error CALL ConfigSetDefaultBool(m64p_handle ConfigSectionHandle, const char *ParamName, int ParamValue, const char *ParamHelp) { config_section *section; config_var *var; /* check input conditions */ if (!l_ConfigInit) return M64ERR_NOT_INIT; if (ConfigSectionHandle == NULL || ParamName == NULL) return M64ERR_INPUT_ASSERT; section = (config_section *) ConfigSectionHandle; if (section->magic != SECTION_MAGIC) return M64ERR_INPUT_INVALID; /* if this parameter already exists, then just return successfully */ var = find_section_var(section, ParamName); if (var != NULL) return M64ERR_SUCCESS; /* otherwise create a new config_var object and add it to this section */ var = config_var_create(ParamName, ParamHelp); if (var == NULL) return M64ERR_NO_MEMORY; var->type = M64TYPE_BOOL; var->val.integer = ParamValue ? 1 : 0; append_var_to_section(section, var); return M64ERR_SUCCESS; } EXPORT m64p_error CALL ConfigSetDefaultString(m64p_handle ConfigSectionHandle, const char *ParamName, const char * ParamValue, const char *ParamHelp) { config_section *section; config_var *var; /* check input conditions */ if (!l_ConfigInit) return M64ERR_NOT_INIT; if (ConfigSectionHandle == NULL || ParamName == NULL || ParamValue == NULL) return M64ERR_INPUT_ASSERT; section = (config_section *) ConfigSectionHandle; if (section->magic != SECTION_MAGIC) return M64ERR_INPUT_INVALID; /* if this parameter already exists, then just return successfully */ var = find_section_var(section, ParamName); if (var != NULL) return M64ERR_SUCCESS; /* otherwise create a new config_var object and add it to this section */ var = config_var_create(ParamName, ParamHelp); if (var == NULL) return M64ERR_NO_MEMORY; var->type = M64TYPE_STRING; var->val.string = strdup(ParamValue); if (var->val.string == NULL) { delete_var(var); return M64ERR_NO_MEMORY; } append_var_to_section(section, var); return M64ERR_SUCCESS; } #ifdef __LIBRETRO__ // Conifg overrides #include "libretro.h" extern retro_environment_t environ_cb; typedef struct { int value; const char* name; } value_pair; static int choose_value(const char* value_name, const value_pair* values) { int i; if (value_name) { struct retro_variable var = { value_name, 0 }; environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var); for (i = 0; var.value && values && values[i].name; i ++) { if (strcmp(values[i].name, var.value) == 0) return values[i].value; } } return -1; } #endif EXPORT int CALL ConfigGetParamInt(m64p_handle ConfigSectionHandle, const char *ParamName) { int i; config_section *section; config_var *var; static const struct { const char* ParamName; const char* RetroName; const value_pair Values[32]; } libretro_translate[] = { { "R4300Emulator", "mupen64-cpucore", { { 0, "pure_interpreter" }, { 1, "cached_interpreter" }, { 2, "dynamic_recompiler" }, { 3, "neb_dynamic_recompiler" }, { 0, 0 } } }, { "ScreenWidth", "mupen64-screensize", { { 320, "320x200" }, { 320, "320x240" }, { 400, "400x256" }, { 512, "512x384" }, { 640, "640x200" }, { 640, "640x350" }, { 640, "640x400" }, { 640, "640x480" }, { 800, "800x600" }, { 960, "960x720" }, { 856, "856x480" }, { 512, "512x256" }, { 1024, "1024x768" }, { 1280, "1280x1024" }, { 1600, "1600x1200" }, { 400, "400x300" }, { 1152, "1152x864" }, { 1280, "1280x960" }, { 1600, "1600x1024" }, { 1920, "1920x1440" }, { 2048, "2048x1536" }, { 2048, "2048x2048" }, { 0, 0 } } }, { "ScreenHeight", "mupen64-screensize", { { 200, "320x200" }, { 240, "320x240" }, { 256, "400x256" }, { 384, "512x384" }, { 200, "640x200" }, { 350, "640x350" }, { 400, "640x400" }, { 480, "640x480" }, { 600, "800x600" }, { 720, "960x720" }, { 480, "856x480" }, { 256, "512x256" }, { 768, "1024x768" }, { 1024, "1280x1024" }, { 1200, "1600x1200" }, { 300, "400x300" }, { 854, "1152x864" }, { 960, "1280x960" }, { 1024, "1600x1024" }, { 1440, "1920x1440" }, { 1536, "2048x1536" }, { 2048, "2048x2048" }, { 0, 0 } } }, { "DisableExtraMem", "mupen64-disable_expmem", { { 0, "enabled" }, { 1, "disabled" }, } }, { "BootDevice", "mupen64-boot-device", { { 0, "Default" }, { 1, "64DD IPL" }, } }, { 0, 0, { {0, 0} } } }; #ifdef __LIBRETRO__ if (!strcmp(ParamName, "AnisoFilter")) #ifdef GLES return 0; #else return 1; #endif for (i = 0; libretro_translate[i].ParamName; i ++) { if (strcmp(ParamName, libretro_translate[i].ParamName) == 0) { int result = choose_value(libretro_translate[i].RetroName, libretro_translate[i].Values); if (result >= 0) return result; break; } } #endif /* check input conditions */ if (!l_ConfigInit || ConfigSectionHandle == NULL || ParamName == NULL) { DebugMessage(M64MSG_ERROR, "ConfigGetParamInt(): Input assertion!"); return 0; } section = (config_section *) ConfigSectionHandle; if (section->magic != SECTION_MAGIC) { DebugMessage(M64MSG_ERROR, "ConfigGetParamInt(): ConfigSectionHandle invalid!"); return 0; } /* if this parameter doesn't already exist, return an error */ var = find_section_var(section, ParamName); if (var == NULL) { DebugMessage(M64MSG_ERROR, "ConfigGetParamInt(): Parameter '%s' not found!", ParamName); return 0; } /* translate the actual variable type to an int */ switch(var->type) { case M64TYPE_INT: return var->val.integer; case M64TYPE_FLOAT: return (int) var->val.number; case M64TYPE_BOOL: return (var->val.integer != 0); case M64TYPE_STRING: return atoi(var->val.string); default: DebugMessage(M64MSG_ERROR, "ConfigGetParamInt(): invalid internal parameter type for '%s'", ParamName); return 0; } return 0; } EXPORT float CALL ConfigGetParamFloat(m64p_handle ConfigSectionHandle, const char *ParamName) { config_section *section; config_var *var; /* check input conditions */ if (!l_ConfigInit || ConfigSectionHandle == NULL || ParamName == NULL) { DebugMessage(M64MSG_ERROR, "ConfigGetParamFloat(): Input assertion!"); return 0.0; } section = (config_section *) ConfigSectionHandle; if (section->magic != SECTION_MAGIC) { DebugMessage(M64MSG_ERROR, "ConfigGetParamFloat(): ConfigSectionHandle invalid!"); return 0.0; } /* if this parameter doesn't already exist, return an error */ var = find_section_var(section, ParamName); if (var == NULL) { DebugMessage(M64MSG_ERROR, "ConfigGetParamFloat(): Parameter '%s' not found!", ParamName); return 0.0; } /* translate the actual variable type to an int */ switch(var->type) { case M64TYPE_INT: return (float) var->val.integer; case M64TYPE_FLOAT: return var->val.number; case M64TYPE_BOOL: return (var->val.integer != 0) ? 1.0f : 0.0f; case M64TYPE_STRING: return (float) atof(var->val.string); default: DebugMessage(M64MSG_ERROR, "ConfigGetParamFloat(): invalid internal parameter type for '%s'", ParamName); return 0.0; } return 0.0; } EXPORT int CALL ConfigGetParamBool(m64p_handle ConfigSectionHandle, const char *ParamName) { int i; extern int overlay; config_section *section; config_var *var; static const struct { const char* ParamName; const char* RetroName; const value_pair Values[32]; } libretro_translate[] = { { "64DD", "mupen64-64dd-hardware", { { 0, "disabled" }, { 1, "enabled" } } }, { 0, 0, { {0, 0} } } }; for (i = 0; libretro_translate[i].ParamName; i ++) { if (strcmp(ParamName, libretro_translate[i].ParamName) == 0) { int result = choose_value(libretro_translate[i].RetroName, libretro_translate[i].Values); if (result >= 0) return result; break; } } if (!strcmp(ParamName, "DisplayListToGraphicsPlugin")) { return CFG_HLE_GFX; } if (!strcmp(ParamName, "AudioListToAudioPlugin")) { return CFG_HLE_AUD; } if (!strcmp(ParamName, "WaitForCPUHost")) { return false; } if (!strcmp(ParamName, "SupportCPUSemaphoreLock")) { return false; } if (!strcmp(ParamName, "VIOverlay")) return overlay; if (!strcmp(ParamName, "Fullscreen")) return true; if (!strcmp(ParamName, "VerticalSync")) return false; if (!strcmp(ParamName, "FBO")) return true; if (!strcmp(ParamName, "AnisotropicFiltering")) #ifdef GLES return false; #else return true; #endif /* check input conditions */ if (!l_ConfigInit || ConfigSectionHandle == NULL || ParamName == NULL) { DebugMessage(M64MSG_ERROR, "ConfigGetParamBool(): Input assertion!"); return 0; } section = (config_section *) ConfigSectionHandle; if (section->magic != SECTION_MAGIC) { DebugMessage(M64MSG_ERROR, "ConfigGetParamBool(): ConfigSectionHandle invalid!"); return 0; } /* if this parameter doesn't already exist, return an error */ var = find_section_var(section, ParamName); if (var == NULL) { DebugMessage(M64MSG_ERROR, "ConfigGetParamBool(): Parameter '%s' not found!", ParamName); return 0; } /* translate the actual variable type to an int */ switch(var->type) { case M64TYPE_INT: return (var->val.integer != 0); case M64TYPE_FLOAT: return (var->val.number != 0.0); case M64TYPE_BOOL: return var->val.integer; case M64TYPE_STRING: return (osal_insensitive_strcmp(var->val.string, "true") == 0); default: DebugMessage(M64MSG_ERROR, "ConfigGetParamBool(): invalid internal parameter type for '%s'", ParamName); return 0; } return 0; } EXPORT const char * CALL ConfigGetParamString(m64p_handle ConfigSectionHandle, const char *ParamName) { static char outstr[64]; /* warning: not thread safe */ config_section *section; config_var *var; /* check input conditions */ if (!l_ConfigInit || ConfigSectionHandle == NULL || ParamName == NULL) { DebugMessage(M64MSG_ERROR, "ConfigGetParamString(): Input assertion!"); return ""; } section = (config_section *) ConfigSectionHandle; if (section->magic != SECTION_MAGIC) { DebugMessage(M64MSG_ERROR, "ConfigGetParamString(): ConfigSectionHandle invalid!"); return ""; } /* if this parameter doesn't already exist, return an error */ var = find_section_var(section, ParamName); if (var == NULL) { DebugMessage(M64MSG_ERROR, "ConfigGetParamString(): Parameter '%s' not found!", ParamName); return ""; } /* translate the actual variable type to an int */ switch(var->type) { case M64TYPE_INT: snprintf(outstr, 63, "%i", var->val.integer); outstr[63] = 0; return outstr; case M64TYPE_FLOAT: snprintf(outstr, 63, "%f", var->val.number); outstr[63] = 0; return outstr; case M64TYPE_BOOL: return (var->val.integer ? "True" : "False"); case M64TYPE_STRING: return var->val.string; default: DebugMessage(M64MSG_ERROR, "ConfigGetParamString(): invalid internal parameter type for '%s'", ParamName); return ""; } return ""; } /* ------------------------------------------------------ */ /* OS Abstraction functions, exported outside of the Core */ /* ------------------------------------------------------ */ extern const char* retro_get_system_directory(); EXPORT const char * CALL ConfigGetSharedDataFilepath(const char *filename) { static char configpath[PATH_MAX]; if (filename == NULL) return NULL; snprintf(configpath, PATH_MAX, "%s/%s", retro_get_system_directory(), filename); /* TODO: Return NULL if file does not exist */ return configpath; } EXPORT const char * CALL ConfigGetUserConfigPath(void) { return retro_get_system_directory(); } EXPORT const char * CALL ConfigGetUserDataPath(void) { return retro_get_system_directory(); } EXPORT const char * CALL ConfigGetUserCachePath(void) { return retro_get_system_directory(); } jni/Android.mk000664 001750 001750 00000003532 12655644434 014413 0ustar00sergiosergio000000 000000 LOCAL_PATH := $(call my-dir) PERFTEST = 0 HAVE_HWFBE = 0 HAVE_SHARED_CONTEXT=0 SINGLE_THREAD=0 GLIDE2GL=1 GLIDE64MK2=0 GLES = 1 include $(CLEAR_VARS) LOCAL_MODULE := retro ROOT_DIR := .. LIBRETRO_DIR = ../libretro ifeq ($(TARGET_ARCH),arm) LOCAL_ARM_MODE := arm LOCAL_CFLAGS := -marm WITH_DYNAREC := arm COMMON_FLAGS := -DANDROID_ARM -DDYNAREC -DNEW_DYNAREC=3 -DNO_ASM WITH_DYNAREC := arm ifeq ($(TARGET_ARCH_ABI), armeabi-v7a) LOCAL_ARM_NEON := true HAVE_NEON := 1 endif endif ifeq ($(TARGET_ARCH),x86) COMMON_FLAGS := -DANDROID_X86 -DDYNAREC -D__SSE2__ -D__SSE__ -D__SOFTFP__ WITH_DYNAREC := x86 endif ifeq ($(TARGET_ARCH),mips) COMMON_FLAGS := -DANDROID_MIPS endif ifeq ($(NDK_TOOLCHAIN_VERSION), 4.6) COMMON_FLAGS += -DANDROID_OLD_GCC endif SOURCES_C := SOURCES_CXX := SOURCES_ASM := INCFLAGS := include $(ROOT_DIR)/Makefile.common LOCAL_SRC_FILES := $(SOURCES_CXX) $(SOURCES_C) $(SOURCES_ASM) # Video Plugins ifeq ($(HAVE_HWFBE), 1) COMMON_FLAGS += -DHAVE_HWFBE endif ifeq ($(HAVE_SHARED_CONTEXT), 1) COMMON_FLAGS += -DHAVE_SHARED_CONTEXT endif ifeq ($(SINGLE_THREAD), 1) COMMON_FLAGS += -DSINGLE_THREAD endif PLATFORM_EXT := unix ifeq ($(GLIDE64MK2),1) COMMON_FLAGS += -DGLIDE64_MK2 endif COMMON_FLAGS += -DM64P_CORE_PROTOTYPES -D_ENDUSER_RELEASE -DM64P_PLUGIN_API -D__LIBRETRO__ -DINLINE="inline" -DSDL_VIDEO_OPENGL_ES2=1 -DANDROID -DSINC_LOWER_QUALITY -DHAVE_LOGGER -DHAVE_COMBINE_EXT -fexceptions $(GLFLAGS) -DGLES COMMON_OPTFLAGS = -O3 -ffast-math LOCAL_CFLAGS += $(COMMON_OPTFLAGS) $(COMMON_FLAGS) $(INCFLAGS) LOCAL_CXXFLAGS += $(COMMON_OPTFLAGS) $(COMMON_FLAGS) $(INCFLAGS) LOCAL_LDLIBS += -lGLESv2 LOCAL_C_INCLUDES = $(CORE_DIR)/src $(CORE_DIR)/src/api $(VIDEODIR_GLIDE)/Glitch64/inc $(LIBRETRO_DIR)/libco $(LIBRETRO_DIR) ifeq ($(PERFTEST), 1) LOCAL_CFLAGS += -DPERF_TEST LOCAL_CXXFLAGS += -DPERF_TEST endif include $(BUILD_SHARED_LIBRARY) glide2gl/src/Glide64/Help/Glide64 Readme.html000664 001750 001750 00000114647 12655644434 021544 0ustar00sergiosergio000000 000000

Glide64


International Emulation Project

Version: "Napalm WX"

Author: Sergey 'Gonetz' Lipski (Russia)

Disclaimer:

Neither I, nor anyone who is working with me, will take ANY responsibility for your actions or if this program causes harm to anything, including you and your computer, in any way, physically or mentally.

Table of Contents:

  1. What is Glide64?
  2. The Very Quick Start
  3. Common Settings
  4. Emulation settings
  5. About hardware frame buffer emulation
  6. Texture enhancement and hi-resolution textures
  7. Hotkeys
  8. Specific Game Settings

 

1. What is Glide64?

Glide64 is a graphics plugin for Nintendo 64 emulators. It can run natively on 3dfx cards, or via a OpenGL-based wrapper for modern video cards. The project started on 29 December 2001 by David 'Dave2001' Forrester (USA). Gugaman (Brazil) and Sergey 'Gonetz' Lipski (that is me) joined him at February 2002. We worked together until the autumn of 2002. Then, Dave2001 and Gugaman left the project. Since that time I'm the only developer of the plugin. However, I'm not the only one, who works on this project. The Glide64 project includes two additional libraries beside the plugin itself. The first one is the library known as the 'Glitch64' wrapper, previously known as "Hacktarux's glide wrapper", named after its original author, Hacktarux (France). It then was heavily modified & improved by Vincent 'ziggy' Penne (France) and Brad 'mudlord' Miller (Australia). The second library is a texture enhancement module named 'GlideHQ', created by Hiroshi 'KoolSmoky' Morii (Japan). Beside that, lots of people from around the world helped me to test the plugin and gave me valuable advices on how to improve it. The main tester of this version is Olivieryuyu (France); and additional testing, advices and friendly support was provided by Wes 'Legend' McDaniel (USA).

2. The Very Quick Start

To install Glide64:

  1. Open archive and copy everything from the 'Plugin' folder into the folder where all your N64 plugins are stored (this is usually the 'Plugin' folder in your emulator's folder, e.g. Project64\Plugin).
  2. If you don’t have a Voodoo card, make sure you copy the glide3x.dll file from the 'Wrapper' folder into your emulator's folder.

To setup Glide64:

  1. Launch your emulator.
  2. Select Glide64 as your graphics plugin.
  3. Select 'Configure graphics plugin'
  4. In Glide64 configuration dialog, on the 'Common settings' tab, in the "Rendering" section, select your desired windowed and full screen resolution. 

Glide64 is now ready to use. If you're a novice in N64 emulation, you may skip the rest of this document, start your favorite games and enjoy! If you are an experienced emu fan, or a curious person, read further for explanation for other options and various tips and tricks.

3. Common Settings

3.1 Rendering

Rendering related settings described here.

3.1.1 Common

'Windowed or 3dfx card resolution' - This option selects the fullscreen resolution for 3dfx cards and windowed resolution for other cards. Note: for 3dfx cards the plugin must be in fullscreen mode to see anything.

'Vertical sync' - This option will enable the vertical sync, which will prevent tearing. Note: this option will ONLY have effect if vsync is set to "Software Controlled".

3.1.2 OpenGL settings

'Anisotropic filtering'  -  This filter sharpens and brings out the details of textures that recede into the distance. When activated, it will use the max anisotropy your video card supports. However, this will override native way of texture filtering and may cause visual artifacts in some games.

'Autodetect VRAM Size' - If checked, plugin will try to autodetect VRAM size. But if this appears wrong, please uncheck and set it to correct value. Currently VRAM autodetection is implemented only for Windows.

'Use Frame buffer objects' - Changes the way frame buffer effects are rendered - with or without usage of the OpenGL Frame Buffer Objects (FBO) extension. The choice depends on game and your video card. FBO off is good for NVIDIA cards, while for ATI cards, it's usually best that FBOs are turned on. Also, some FB effects work only with one of the methods, no matter which card you have. On the whole, with FBO off, compatibility/accuracy is a bit better (which is the case for Resident Evil 2). However, with FBO on with some systems, it can actually be a bit faster in cases.

3.2 On screen display

These settings are located in 'Common settings' tab - in the 'On screen display' section. You may select them with no worries - these settings do not impact the emulation.

Select any or all options in the 'Speed' option group to see how fast the game is running. 'FPS counter' will show you the actual frames per second (FPS) for the current game. This number depends on the running game. The 'VI/s counter' will show you the number of visual interrupts per second received by the plugin. This number must be 50 for PAL games and 60 for NTSC games.  '% speed' will show you, how fast your game is emulated; 100% means that the currently emulated game runs at perfect speed. 'FPS transparent' option makes the background of the counter(s) transparent.

Select 'Clock enabled' in the 'Time' group to see the current  time. Select 'Clock is 24-hour' to see the time in 24-hour format. Time information will be displayed in the lower right corner of the screen.

3.3 Other

All other common settings are grouped in the 'Other' section.

'Show advanced emulation options' - Enable 'Emulation settings' tab. Read more in 'Emulation settings' section.

'Show texture enhancement options' - Enable 'Texture enhancement' tab. Read more in 'Texture enhancement and hi-resolution textures' section.

'Screenshot format' - Format, in which screen shots will be saved. Currently you may choose 'BMP', 'PNG' or 'JPEG'.

'Glide card #' - This option is only for users with multiple 3dfx cards installed in one machine. This selects the glide card number to use. If you only have one glide card installed in your system, set this option to #1. Otherwise, select the number that corresponds to the glide card you want to use.

4. Emulation settings

Warning: The plugin already has optimal settings for all games. Changing these settings is dangerous: it can cause glitches and instability. Access to emulation settings is disabled by default.

To enable 'Emulation settings' tab, check 'Show advanced emulation options' on the 'Common settings tab' and close the configuration dialog. Open configuration dialog again and the 'Emulation settings' tab will now be available.

Important: 'Emulation settings' tab operates in 2 different ways depending on whether or not a game is running.

  • When no game is running, you may change "default" emulation settings. The plugin uses these settings when a game does not have corresponding custom settings. Again, it is strongly recommended to not touch anything here.
  • When a game IS running, this tab shows emulation settings the game is using. Any changes will be applied immediately after you close the configuration dialog. You will be asked - save the changes in the ini file or use them in the current session only. If you choose 'Yes', your changes will be saved in the custom section of the ini file and will be used permanently. Otherwise, new setting will be used until the game stops or new save state loaded.
4.1 General options

'Filtering mode' - you may set 'Force bilinear', 'Automatic' or 'Force point-sampled' mode. You also may easily switch between filtering modes during game play by pressing the backspace button.

'Buffer swapping modes' - It's hard to explain the difference between these modes. Just select any available option. If a game suffers from flickering, select another buffer swapping mode and see if that fixes the problem.

'LOD calculation'. The N64 uses a very special way to implement mip-mapping, which is not available on PC hardware. Glide64 implements a rough approximation of N64 mip-mapping, which can be enabled by setting 'LOD calculation' option to 'fast' or 'precise'. The result is not always good though.

'Aspect ratio' - Most N64 games use 4:3 aspect ratio, but some support widescreen too. You may select appropriate aspect here and set widescreen mode in game settings. In 'Stretch' mode the output will be stretched to the entire screen, other modes may add black boarders if necessary.

'Fog' - Sets fog emulation on/off.

'Buffer clear on every frame' - Forces the frame buffer to be cleared every frame drawn. Usually frame buffer clear is controlled by the game. However, in some cases it is not well emulated, and some garbage may be left on the screen. In such cases, this option must be set on.

4.2. Frame buffer emulation

N64 games often use auxiliary frame buffers to implement special game effects like motion blur or for optimization purposes. The console can allocate as many auxiliary frame buffers as needed and then use them as usual textures. PC video cards usually use only one buffer per frame, thus emulation of frame buffer effects is always a hard problem. Glide64 implements lot of methods of frame buffer emulation, to support as many effects as possible. Most games will work fine with pre-defined settings, but some effects require additional options to be set. Known cases are described in the Compatibility List and in the Specific Game Settings. You may set the following options:

'Enable frame buffer emulation' - When this option is on, the plugin will try to detect frame buffer effects usage and emulate them. This option is off by default, but for all games, which use frame buffer effects, it will be automatically turned on.

'Hardware frame buffer emulation' - Enables hardware frame buffer emulation. Usually, this must be set on, except some rare cases, mentioned in the Compatibility List. Read next chapter for explanation of hardware frame buffer emulation.

'Motion blur' - Enables motion blur emulation. Motion blur works slow without hardware frame buffer emulation, so it is made optional. This option usually must be on, because most of cards support hardware frame buffer emulation. You may also switch it on/off during game play by pressing ALT-B.

'Read every frame' - In some cases,  Glide64 cannot detect frame buffer usage by the game. In this case the only way to emulate frame buffer effects, is to read every rendered frame from video memory and put it into the emulated RDRAM. Reading from video memory is usually slow, so this method of frame buffer emulation is optional. You may also switch it on/off during game play by pressing ALT-V.

'Get frame buffer info' - This is another way to emulate frame buffer effects, which the plugin cannot detect. This option allows the plugin to get notification about frame buffer usage from the emulator and thus emulate frame buffer effects without slowdown. Currently it works only with Mupen64 (and even Mupen is not 100% reliable with this). Do not enable this option with 1964, otherwise the emulator will crash.

'Render N64 frame buffer as texture'. The N64 architecture allows the CPU to write directly into the frame buffer. Sometimes N64 games uses this ability, which may lead to graphics lost during emulation, since graphics plugin does not know, that some graphics are already written in the N64 frame buffer by the CPU. Some examples of this are: falling pills in Dr.Mario and rain in Jet Force Gemini. When this option is enabled, content of each N64 frame buffer is rendered as a texture over the current rendered frame. This prevents graphics loss, but may cause slowdowns and various glitches in some games.

'Detect CPU write to N64 frame buffer'- This option works as the previous options, but the plugin is trying to detect, when a game uses CPU writes to the N64 frame buffer. The N64 frame buffer is rendered only when CPU writes is detected. Use this option for those games, in which you see still image or no image at all for some time with no reason.

4.3. Depth buffer emulation

Sometimes N64 games use values in the depth buffer to decide, when to render some particular object or not. This is often used for coronas, which must be rendered only if they are not covered by other objects in the 3D scene. To emulate it properly, the N64 depth buffer must be filled with correct values. Glide64 uses software rendering to fill the N64 depth buffer. It is enabled by default. If you experience performance issues, set the 'Software depth buffer rendering' option off.

5. About hardware frame buffer emulation

The usual method of frame buffer emulation, which theoretically should always work, is to render auxiliary frame buffers into the main video buffer and then read it from video memory into main memory, and put into the structure representing N64 memory (RDRAM). This approach has 2 main disadvantages:

1) auxiliary frame buffers may be visible when they should n't be.

2) reading from video memory is a very slow operation, thus many frame buffer effects will be slow.

Also, image taken from video memory must be scaled down to N64 native resolution (usually 320x240), thus quality lost is inevitable. To avoid these problems, Glide64 uses the Glide3x extension, which allows it to create auxiliary frame buffers right into video memory, like the N64 does. This allows the plugin to run frame buffer effects without speed hits or quality loss. Hardware frame buffer emulation (HWFBE) greatly improves many games, but it has some restrictions:

1) HWFBE is in fact a hack - auxiliary frame buffers are not put into N64 memory. When a game uses a texture located in RDRAM corresponding to an auxiliary frame buffer, the plugin uses the texture located in video memory instead. The game may use this area in RDRAM for different textures later, but the plugin will use it's auxiliary buffer anyway, which leads to serious glitches. I have tried to reduce the probability of this situation, but it is still possible. If you encounter it, switch to windowed mode, and then back to full screen again.

2) The Glide extension used for HWFBE is fully supported by Voodoo 4/5 only. Banshee and Voodoo3 cards also support it, but only for small auxiliary frame buffers (e.g. shadows). Other Voodoo cards do not support it at all!

3) HWFBE may not work for Voodoo4/5 if the anti-aliasing option is set to "fastest performance". Use any other option there.

4) Anti-aliasing is not applicable to auxiliary frame buffers.

5) The wrapper support HWFBE almost fully, but it has its peculiarities. Two ways of hardware frame buffer emulation are implemented in the wrapper - with, and without usage of the OpenGL Frame Buffer Objects (FBO) extension. The method with FBO's works fast on any card, which supports FBO's, but it may cause depth issues, since framebuffer objects use their own depth buffer. The method without FBO's works on almost any card, has no problems with depth buffer usage, but it may work slowly on ATI cards. To switch between these methods set the 'Use frame buffer objects' option on/off. 

6. Texture enhancement and hi-resolution textures

Texture enhancement is done via GlideHQ - a real-time texture enhancer library with hi-resolution texture pack support. GlideHQ is an independent DLL, which dynamically loaded by Glide64, when it is needed. GlideHQ itself has no user interface; all its settings are placed on the 'Texture enhancement' tab. This tab is disabled by default. To enable it, check 'Show texture enhancement options' on the 'Common settings' tab and close the configuration dialog. Open configuration dialog again and switch to 'Texture enhancement' tab.

6.1. Texture enhancement

GlideHQ uses variety of methods to enhance the original N64 textures.

'Filter' - Apply a filter to either smooth or sharpen textures. There are 4 different smoothing filters and 2 different sharpening filters. The higher the number, the stronger the effect, i.e. 'Smoothing filter 4' will have a much more noticeable effect than 'Smoothing filter 1'. Be aware that performance may have an impact depending on the game and/or the PC.

'Enhancement' - 7 different filters are selectable here, each one with a distinctive look. Be aware of possible performance impacts.
Important: 'Store' mode - saves textures in cache "as is". It can improve performance in games, which load many textures. Disable 'Ignore backgrounds' option for better result.

'Texture cache' - Enhanced and filtered textures are cached for later use. This helps boost performance if there are subsequent requests for the same texture, which is the case for most games. Normally, 128MB should be more than enough but there is a sweet spot for each game. 32MB will be enough for Super Mario, but Conker's BFD streams a lot of textures so setting 256MB or more will boost performance.

'Compress texture cache' - Memory will be compressed so that more textures can be held in the texture cache. The compression ratio varies with each texture, but 1/5 of the original size would be a modest approximation. They will be decompressed on-the-fly, before being downloaded to the gfx hardware. This option will still help save memory space even when using texture compressions such as FXT1 and S3TC.

'Apply texture compression' - Textures will be compressed using selected texture compression method. The overall compression ratio is about 1/6 for FXT1 and 1/4 for S3TC. In addition to saving space on the texture cache, the space occupied on the GFX hardware's texture RAM, by the enhanced textures, will be greatly reduced. This minimizes texture RAM usage, decreasing the number of texture swaps to the GFX hardware leading to performance gains. However, due to the nature of lossy compression of FXT1 and S3TC, using this option can sometimes lead to quality degradtion of small size textures and color banding of gradient colored textures.

'Ignore backgrounds' - It is used to skip enhancement for wide narrow textures, usually used for backgrounds. This may save texture memory greatly and increase performance.

6.2 Hi-resolution textures

GlideHQ supports hi-resolution texture packs, and texture dumping/editing.

'Format' - Chose which method is to be used for loading Hi-res texture packs. Only Rice's format is available currently. Leave on 'None' if you will not be needing to load hi-res packs.

'Alternative CRC calculation' - This option enables emulation of a palette CRC calculation bug in RiceVideo. If some textures are not loaded, try to set this option on/off. This option is disabled in texture dumping mode.

'Texture dumping/editing mode' - In this mode, you have that ability to dump textures on screen to the appropriate folder. You can also reload textures while the game is running to see how they look instantly - big time saver! Hotkeys: "R" reloads hires textures from texture pack - "D" toggles texture dumps on/off.

'Use alpha channel fully' - When this option is off, 16bit rgba textures will be loaded using RiceVideo style - with 1bit for alpha channel. When it is on, GlideHQ will check, how alpha channel is used by the hires texture, and select most appropriate format for it. This gives texture designers freedom to play with alpha, as they need, regardless of format of original N64 texture. For older and badly designed texture packs it may cause unwanted black borders.

'Compress texture cache'  - When game started, plugin loads all its hi-resolution textures into PC memory. Since hi-resolution textures are usually large, the whole pack can take hundreds megabytes of memory. Cache compression allows to save memory space greatly. Textures will be decompressed on-the-fly, before being downloaded to the gfx hardware. This option will still help save memory space even when using texture compression.

'Apply texture compression' - Textures will be compressed using selected texture compression method. The overall compression ratio is about 1/6 for FXT1 and 1/4 for S3TC. In addition to saving space on the texture cache, the space occupied on the GFX hardware's texture RAM, by the enhanced textures, will be greatly reduced. This minimizes texture RAM usage, decreasing the number of texture swaps to the GFX hardware leading to performance gains. However, due to the nature of lossy compression of FXT1 and S3TC, using this option can sometimes lead to quality degradtion of small size textures and color banding of gradient colored textures.

'Force 16bpp textures' - The color of the textures will be reduced to 16bpp. This is another space saver and performance enhancer. This halves the space used on the texture cache and the GFX hardware's texture RAM. Color reduction is done so that the original quality is preserved as much as possible. Depending on the texture, this usually is hardly noticeable. Sometimes though, it can be: skies are a good example.

'Tile textures' - When on, wide texture will be split on several tiles to fit in one 256-width texture. This tiled texture takes much less video memory space and thus overall performance will increase. However, corresponding polygons must be split too, and this is not polished yet- various issues are possible, including black lines and polygons distortions.

6.3 Common

'Texture compression method' - Select the method for texture compression. 3dfx cards support both FXT1 and S3TC, other cards can use S3TC only.

'Save texture cache to hard disk' - For enhanced textures cache: this will save all previously loaded and enhanced textures to the hard drive. So upon next game launch, all the textures will be instantly loaded, resulting in smoother performance for all your games. For high-resolution textures cache: After creation, loading hi-res texture will take only a few seconds upon game launch, as opposed to the 5 - 60 seconds a pack can take to load without this cache file. The only downside here is upon any changes to the pack, the cache file will need to be manually deleted. Saved cache files go into a folder called "Cache" within the "Plugins" folder.

7. Hotkeys

Glide64 uses the following hotkeys:

"BACKSPACE" - Cycle between texture filtering modes. Currently selected mode will be shown in the status line on the bottom of the screen for a short time.

"Alt"+"V" - Toggles read every frame on/off. Current status of this option will be shown in the status line on the bottom of the screen for a short time.

"Alt"+"B" - Toggles motion blur on/off. Current status of this option will be shown in the status line on the bottom of the screen for a short time.

GlideHQ uses the following hotkeys:

"D" - toggles texture dumps on/off.

"R" - reloads hires textures from the texture pack.

 8. Specific Game Settings

Banjo-Kazooie

The puzzle effect is not emulated by default. To see it, either set 'Read every frame' option on or set 'Get frame buffer info' and run this game with Mupen64.

Beetle Adventure Racing / HSV Adventure Racing

Fog. The fog in this game is implemented in a very specific way. When rendering of the current frame is finished, the depth buffer, filled during rendering of this frame, is used as a texture and blended with the color buffer. As the result, the frame becomes fogged, and the fog is thicker where depth values are higher. Glide64 implements two ways to emulate this effect, software and hardware ones.

Software emulation uses software depth buffer rendering. It works on all cards, but has two disadvantages:

 - Alpha testing is not used during software depth buffer rendering. As the result, the pixels, which would normally be rejected by alpha testing, are stored in the depth buffer. This causes artifacts in the produced fog.

- The software depth buffer has original (that is low) N64 resolution output. When it is used as a texture, blended with the high-resolution frame buffer, aliasing is visible.

Hardware emulation produces perfect fog, but currently it works only on 3dfx Voodoo 4/5's. These cards use the same depth buffer format, as the N64, and they can allocate the depth buffer right in the texture memory, so it can be easily used as a texture, as on N64 hardware. In both cases, the 'Software depth buffer rendering' option must be on.


On car reflection. Your car (the car you drive) should reflect the environment in this game. That is, various objects, which you roll by, should be reflected on your car. This is implemented via the usage of frame buffer content. Emulation of this effect implies frame buffer emulation. Unfortunately, this can't be done in hardware, because the texture, which is used as a reflection, is not a part of the frame buffer - it is the result of frame buffer post processing, made on the N64 CPU. Thus, the only way to emulate this effect is to use the 'Read every frame' option. If your hardware allows you to use this option without slowdown, you are lucky.

Bio Hazard 2 / Resident Evil 2

This game uses pre-rendered depth buffers, which are stored in the game's ROM, and are loaded into the depth buffer memory area each frame before rendering is started. This is hard to emulate, and especially hard to emulate efficiently. The following options must be set:

'Hardware frame buffer emulation' - on

'Software depth buffer rendering' - on

'Use Framebuffer Objects' - off

To get good sound in this game, use Mupen64 with Azimer's HLE sound plugin v.056. However, the game may flicker in some places with Mupen64.  

Conker's Bad Fur Day

The game is well emulated with default settings. However, there are two special effects in this game, which require special settings: the black-and-white "It's war" cut-scene, and the Uga-Buga pixilated effect. To see these effects, set the following options:
'Read every frame' - on
'Render N64 frame buffer as texture' - on
The game is not playable with these settings, so use them only to see these particular effects.

Note for ATI users: you must set 'Use Framebuffer Objects' option on, otherwise the game will work very slow.

Fushigi no Dungeon - Furai no Shiren 2 (J)

To see correct background in menus, either set 'Read every frame' option on or set 'Get frame buffer info' and run this game with Mupen64.

Legend of Zelda, The - Majora's Mask

Lens of  Truth may not work, if 'Use Framebuffer Objects' option set off .
Also, when Lens of Truth is used, some objects outside of the lens can be cut. This is not a bug - depth buffer copy must be emulated to fully emulate Lens of Truth. It is currently supported only by 3dfx Voodoo 4/5 cards.

Mario Story / Paper Mario

To see correct background in the menu subscreen, either set the 'Read every frame' option on or set 'Get frame buffer info' and run this game with Mupen64. 

Perfect Dark

Frame buffer emulation must be disabled in multiplayer mode to avoid flickering. Most of the special effects used will not work without frame buffer emulation, but it's not that important for multiplayer.

For settings for other games check the Compatibility List.


mupen64plus-video-gliden64/src/GBI.cpp000664 001750 001750 00000020367 12655644434 020543 0ustar00sergiosergio000000 000000 #include #include #include #include #include #include #include "convert.h" #include "N64.h" #include "GLideN64.h" #include "GBI.h" #include "RDP.h" #include "RSP.h" #include "F3D.h" #include "F3DEX.h" #include "F3DEX2.h" #include "L3D.h" #include "L3DEX.h" #include "L3DEX2.h" #include "S2DEX.h" #include "S2DEX2.h" #include "F3DDKR.h" #include "F3DSWSE.h" #include "F3DWRUS.h" #include "F3DPD.h" #include "F3DEX2CBFD.h" #include "ZSort.h" #include "CRC.h" #include "Log.h" #include "OpenGL.h" #include "Debug.h" u32 last_good_ucode = (u32) -1; SpecialMicrocodeInfo specialMicrocodes[] = { { F3D, FALSE, 0xe62a706d, "Fast3D" }, { F3D, FALSE, 0x7d372819, "Fast3D" }, { F3D, FALSE, 0x2edee7be, "Fast3D" }, { F3D, FALSE, 0xe01e14be, "Fast3D" }, { F3DWRUS, FALSE, 0xd17906e2, "RSP SW Version: 2.0D, 04-01-96" }, { F3DSWSE, FALSE, 0x94c4c833, "RSP SW Version: 2.0D, 04-01-96" }, { F3DEX, TRUE, 0x637b4b58, "RSP SW Version: 2.0D, 04-01-96" }, { F3D, TRUE, 0x54c558ba, "RSP SW Version: 2.0D, 04-01-96" }, // Pilot Wings { F3D, TRUE, 0x302bca09, "RSP SW Version: 2.0G, 09-30-96" }, // GoldenEye { S2DEX, FALSE, 0x9df31081, "RSP Gfx ucode S2DEX 1.06 Yoshitaka Yasumoto Nintendo." }, { F3DDKR, FALSE, 0x8d91244f, "Diddy Kong Racing" }, { F3DDKR, FALSE, 0x6e6fc893, "Diddy Kong Racing" }, { F3DJFG, FALSE, 0xbde9d1fb, "Jet Force Gemini" }, { F3DPD, TRUE, 0x1c4f7869, "Perfect Dark" }, { Turbo3D, FALSE, 0x2bdcfc8a, "Turbo3D" }, { F3DEX2CBFD, TRUE, 0x1b4ace88, "Conker's Bad Fur Day" } }; u32 G_RDPHALF_1, G_RDPHALF_2, G_RDPHALF_CONT; u32 G_SPNOOP; u32 G_SETOTHERMODE_H, G_SETOTHERMODE_L; u32 G_DL, G_ENDDL, G_CULLDL, G_BRANCH_Z; u32 G_LOAD_UCODE; u32 G_MOVEMEM, G_MOVEWORD; u32 G_MTX, G_POPMTX; u32 G_GEOMETRYMODE, G_SETGEOMETRYMODE, G_CLEARGEOMETRYMODE; u32 G_TEXTURE; u32 G_DMA_IO, G_DMA_DL, G_DMA_TRI, G_DMA_MTX, G_DMA_VTX, G_DMA_TEX_OFFSET, G_DMA_OFFSETS; u32 G_SPECIAL_1, G_SPECIAL_2, G_SPECIAL_3; u32 G_VTX, G_MODIFYVTX, G_VTXCOLORBASE; u32 G_TRI1, G_TRI2, G_TRI4; u32 G_QUAD, G_LINE3D; u32 G_RESERVED0, G_RESERVED1, G_RESERVED2, G_RESERVED3; u32 G_SPRITE2D_BASE; u32 G_BG_1CYC, G_BG_COPY; u32 G_OBJ_RECTANGLE, G_OBJ_SPRITE, G_OBJ_MOVEMEM; u32 G_SELECT_DL, G_OBJ_RENDERMODE, G_OBJ_RECTANGLE_R; u32 G_OBJ_LOADTXTR, G_OBJ_LDTX_SPRITE, G_OBJ_LDTX_RECT, G_OBJ_LDTX_RECT_R; u32 G_RDPHALF_0; u32 G_MTX_STACKSIZE; u32 G_MTX_MODELVIEW; u32 G_MTX_PROJECTION; u32 G_MTX_MUL; u32 G_MTX_LOAD; u32 G_MTX_NOPUSH; u32 G_MTX_PUSH; u32 G_TEXTURE_ENABLE; u32 G_SHADING_SMOOTH; u32 G_CULL_FRONT; u32 G_CULL_BACK; u32 G_CULL_BOTH; u32 G_CLIPPING; u32 G_MV_VIEWPORT; u32 G_MWO_aLIGHT_1, G_MWO_bLIGHT_1; u32 G_MWO_aLIGHT_2, G_MWO_bLIGHT_2; u32 G_MWO_aLIGHT_3, G_MWO_bLIGHT_3; u32 G_MWO_aLIGHT_4, G_MWO_bLIGHT_4; u32 G_MWO_aLIGHT_5, G_MWO_bLIGHT_5; u32 G_MWO_aLIGHT_6, G_MWO_bLIGHT_6; u32 G_MWO_aLIGHT_7, G_MWO_bLIGHT_7; u32 G_MWO_aLIGHT_8, G_MWO_bLIGHT_8; GBIInfo GBI; void GBI_Unknown( u32 w0, u32 w1 ) { #ifdef DEBUG if (Debug.level == DEBUG_LOW) DebugMsg( DEBUG_LOW | DEBUG_UNKNOWN, "UNKNOWN GBI COMMAND 0x%02X", _SHIFTR( w0, 24, 8 ) ); if (Debug.level == DEBUG_MEDIUM) DebugMsg( DEBUG_MEDIUM | DEBUG_UNKNOWN, "Unknown GBI Command 0x%02X", _SHIFTR( w0, 24, 8 ) ); else if (Debug.level == DEBUG_HIGH) DebugMsg( DEBUG_HIGH | DEBUG_UNKNOWN, "// Unknown GBI Command 0x%02X", _SHIFTR( w0, 24, 8 ) ); #endif } void GBIInfo::init() { m_pCurrent = NULL; _flushCommands(); } void GBIInfo::destroy() { m_pCurrent = NULL; m_list.clear(); } bool GBIInfo::isHWLSupported() const { if (m_pCurrent == NULL) return false; switch (m_pCurrent->type) { case S2DEX: case S2DEX2: case F3DDKR: case F3DJFG: case F3DEX2CBFD: return false; } return true; } void GBIInfo::_flushCommands() { std::fill(std::begin(cmd), std::end(cmd), GBI_Unknown); } void GBIInfo::_makeCurrent(MicrocodeInfo * _pCurrent) { if (_pCurrent->type == NONE) { LOG(LOG_ERROR, "[GLideN64]: error - unknown ucode!!!\n"); return; } if (m_pCurrent == NULL || (m_pCurrent->type != _pCurrent->type)) { m_pCurrent = _pCurrent; _flushCommands(); RDP_Init(); G_TRI1 = G_TRI2 = G_TRI4 = G_QUAD = -1; // For correct work of gSPFlushTriangles() switch (m_pCurrent->type) { case F3D: F3D_Init(); break; case F3DEX: F3DEX_Init(); break; case F3DEX2: F3DEX2_Init(); break; case L3D: L3D_Init(); break; case L3DEX: L3DEX_Init(); break; case L3DEX2: L3DEX2_Init(); break; case S2DEX: S2DEX_Init(); break; case S2DEX2: S2DEX2_Init(); break; case F3DDKR: F3DDKR_Init(); break; case F3DJFG: F3DJFG_Init(); break; case F3DSWSE: F3DSWSE_Init(); break; case F3DWRUS: F3DWRUS_Init(); break; case F3DPD: F3DPD_Init(); break; case Turbo3D: F3D_Init(); break; case ZSortp: ZSort_Init(); break; case F3DEX2CBFD:F3DEX2CBFD_Init(); break; } #ifndef GLESX if (m_pCurrent->NoN) { // Disable near and far plane clipping glEnable(GL_DEPTH_CLAMP); // Enable Far clipping plane in vertex shader glEnable(GL_CLIP_DISTANCE0); } else { glDisable(GL_DEPTH_CLAMP); glDisable(GL_CLIP_DISTANCE0); } #endif } else if (m_pCurrent->NoN != _pCurrent->NoN) { #ifndef GLESX if (_pCurrent->NoN) { // Disable near and far plane clipping glEnable(GL_DEPTH_CLAMP); // Enable Far clipping plane in vertex shader glEnable(GL_CLIP_DISTANCE0); } else { glDisable(GL_DEPTH_CLAMP); glDisable(GL_CLIP_DISTANCE0); } #endif } m_pCurrent = _pCurrent; } bool GBIInfo::_makeExistingMicrocodeCurrent(u32 uc_start, u32 uc_dstart, u32 uc_dsize) { auto iter = std::find_if(m_list.begin(), m_list.end(), [=](const MicrocodeInfo& info) { return info.address == uc_start && info.dataAddress == uc_dstart && info.dataSize == uc_dsize; }); if (iter == m_list.end()) return false; _makeCurrent(&*iter); return true; } void GBIInfo::loadMicrocode(u32 uc_start, u32 uc_dstart, u16 uc_dsize) { if (_makeExistingMicrocodeCurrent(uc_start, uc_dstart, uc_dsize)) return; m_list.emplace_front(); MicrocodeInfo & current = m_list.front(); current.address = uc_start; current.dataAddress = uc_dstart; current.dataSize = uc_dsize; current.NoN = false; current.textureGen = true; current.branchLessZ = true; current.type = NONE; // See if we can identify it by CRC const u32 uc_crc = CRC_Calculate( 0xFFFFFFFF, &RDRAM[uc_start & 0x1FFFFFFF], 4096 ); const u32 numSpecialMicrocodes = sizeof(specialMicrocodes) / sizeof(SpecialMicrocodeInfo); for (u32 i = 0; i < numSpecialMicrocodes; ++i) { if (uc_crc == specialMicrocodes[i].crc) { current.type = specialMicrocodes[i].type; current.NoN = specialMicrocodes[i].NoN; _makeCurrent(¤t); return; } } // See if we can identify it by text char uc_data[2048]; UnswapCopyWrap(RDRAM, uc_dstart & 0x1FFFFFFF, (u8*)uc_data, 0, 0x7FF, 2048); char uc_str[256]; strcpy(uc_str, "Not Found"); for (u32 i = 0; i < 2048; ++i) { if ((uc_data[i] == 'R') && (uc_data[i+1] == 'S') && (uc_data[i+2] == 'P')) { u32 j = 0; while (uc_data[i+j] > 0x0A) { uc_str[j] = uc_data[i+j]; j++; } uc_str[j] = 0x00; int type = NONE; if (strncmp( &uc_str[4], "SW", 2 ) == 0) type = F3D; else if (strncmp( &uc_str[4], "Gfx", 3 ) == 0) { current.NoN = (strstr( uc_str + 4, ".NoN") != NULL); if (strncmp( &uc_str[14], "F3D", 3 ) == 0) { if (uc_str[28] == '1' || strncmp(&uc_str[28], "0.95", 4) == 0 || strncmp(&uc_str[28], "0.96", 4) == 0) type = F3DEX; else if (uc_str[31] == '2') type = F3DEX2; if (strncmp(&uc_str[14], "F3DF", 4) == 0) current.textureGen = false; else if (strncmp(&uc_str[14], "F3DZ", 4) == 0) current.branchLessZ = false; } else if (strncmp( &uc_str[14], "L3D", 3 ) == 0) { u32 t = 22; while (!std::isdigit(uc_str[t]) && t++ < j); if (uc_str[t] == '1') type = L3DEX; else if (uc_str[t] == '2') type = L3DEX2; } else if (strncmp( &uc_str[14], "S2D", 3 ) == 0) { u32 t = 20; while (!std::isdigit(uc_str[t]) && t++ < j); if (uc_str[t] == '1') type = S2DEX; else if (uc_str[t] == '2') type = S2DEX2; } else if (strncmp(&uc_str[14], "ZSortp", 6) == 0) { type = ZSortp; } } if (type != NONE) { current.type = type; _makeCurrent(¤t); return; } break; } } assert(false && "unknown ucode!!!'n"); _makeCurrent(¤t); } mupen64plus-video-gliden64/src/N64.cpp000664 001750 001750 00000000166 12655644434 020504 0ustar00sergiosergio000000 000000 #include "N64.h" u8 *HEADER; u8 *DMEM; u8 *IMEM; u64 TMEM[512]; u8 *RDRAM; u32 RDRAMSize; bool ConfigOpen = false; libretro-common/include/libco.h000664 001750 001750 00000000734 12655644434 017717 0ustar00sergiosergio000000 000000 /* libco version: 0.16 (2010-12-24) license: public domain */ #ifndef LIBCO_H #define LIBCO_H #ifdef LIBCO_C #ifdef LIBCO_MP #define thread_local __thread #else #define thread_local #endif #endif #ifdef __cplusplus extern "C" { #endif typedef void* cothread_t; cothread_t co_active(); cothread_t co_create(unsigned int, void (*)(void)); void co_delete(cothread_t); void co_switch(cothread_t); #ifdef __cplusplus } #endif /* ifndef LIBCO_H */ #endif gles2rice/src/DeviceBuilder.h000664 001750 001750 00000005101 12655644434 017241 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _DEVICE_BUILDER_H #define _DEVICE_BUILDER_H #include "Blender.h" #include "Combiner.h" #include "Config.h" #include "GraphicsContext.h" #include "TextureManager.h" //======================================================================== class CDeviceBuilder { public: virtual CGraphicsContext * CreateGraphicsContext(void)=0; virtual CRender * CreateRender(void)=0; virtual CTexture * CreateTexture(uint32_t dwWidth, uint32_t dwHeight, TextureUsage usage = AS_NORMAL)=0; virtual CColorCombiner * CreateColorCombiner(CRender *pRender)=0; virtual CBlender * CreateAlphaBlender(CRender *pRender)=0; void DeleteGraphicsContext(void); void DeleteRender(void); void DeleteColorCombiner(void); void DeleteAlphaBlender(void); static void DeleteBuilder(void); static CDeviceBuilder* GetBuilder(void); static void SelectDeviceType(SupportedDeviceType type); static SupportedDeviceType GetDeviceType(void); static SupportedDeviceType GetGeneralDeviceType(void); static SupportedDeviceType m_deviceGeneralType; protected: CDeviceBuilder(); virtual ~CDeviceBuilder(); static CDeviceBuilder* CreateBuilder(SupportedDeviceType type); static SupportedDeviceType m_deviceType; static CDeviceBuilder* m_pInstance; CRender* m_pRender; CGraphicsContext* m_pGraphicsContext; CColorCombiner* m_pColorCombiner; CBlender* m_pAlphaBlender; }; class OGLDeviceBuilder : public CDeviceBuilder { friend class CDeviceBuilder; public: CGraphicsContext * CreateGraphicsContext(void); CRender * CreateRender(void); CTexture * CreateTexture(uint32_t dwWidth, uint32_t dwHeight, TextureUsage usage = AS_NORMAL); CColorCombiner * CreateColorCombiner(CRender *pRender); CBlender * CreateAlphaBlender(CRender *pRender); protected: OGLDeviceBuilder() {}; virtual ~OGLDeviceBuilder() {}; }; #endif tools/pj64tosrm.c000664 001750 001750 00000017764 12655644434 015112 0ustar00sergiosergio000000 000000 /* pj64tosrm * Combine Project64's save files (*.eep, *.mpk, *.fla, *.sra) into a * libretro-mupen64 save file (*.srm). * * KNOWN BUGS: * - Some NRage Input Plugin saves may not work regardless of the type. * - Some very old Project64 saves may not work regardless of the type/plugin used. */ #if defined(_WIN32) || defined(_WIN32) # include # include #else # include #endif #include #include #include #include #ifdef _MSC_VER # define strcasecmp _stricmp # define access _access #endif /* from libretro's mupen64+ source (save_memory_data) */ static struct { uint8_t eeprom[0x800]; uint8_t mempack[4][0x8000]; uint8_t sram[0x8000]; uint8_t flashram[0x20000]; } srm; static struct { char srm[513]; char eep[513]; char mpk[513]; char sra[513]; char fla[513]; } files; static uint8_t mempack_init[] = { 0x81,0x01,0x02,0x03, 0x04,0x05,0x06,0x07, 0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f, 0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17, 0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f, 0xff,0xff,0xff,0xff, 0x05,0x1a,0x5f,0x13, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0x01,0xff, 0x66,0x25,0x99,0xcd, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0xff,0xff,0xff,0xff, 0x05,0x1a,0x5f,0x13, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0x01,0xff, 0x66,0x25,0x99,0xcd, 0xff,0xff,0xff,0xff, 0x05,0x1a,0x5f,0x13, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0x01,0xff, 0x66,0x25,0x99,0xcd, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0xff,0xff,0xff,0xff, 0x05,0x1a,0x5f,0x13, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0x01,0xff, 0x66,0x25,0x99,0xcd, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x71,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03 }; static void die(const char *msg) { puts(msg); exit(-1); } static int overwrite_confirm(const char *msg) { char buf[1024]; sprintf(buf, "Do you want to overwrite %s?", msg); #if defined(_WIN32) || defined(_WIN32) int ret = MessageBoxA(NULL, buf, "Confirm action", MB_ICONWARNING | MB_DEFBUTTON2 | MB_YESNO); return ret == IDYES; #else printf("%s (y/n):", buf); return getc(stdin) == 'y'; #endif } static int is_empty_mem(uint8_t *mem, size_t size) { int i; if (mem == srm.eeprom || mem == srm.sram) { for (i = size-1; i >= 0; --i) { if (mem[i] != 0) return 0; } } else if (mem == srm.flashram) { for (i = size-1; i >= 0; --i) { if (mem[i] != 0xff) return 0; } } else if (mem == (uint8_t*)srm.mempack) { for (i = 0; i < 4; i++) { if (memcpy(mempack_init, srm.mempack[i], 272) != 0) return 0; } } else die("unsupported memory"); return 1; } static void read_mem(const char *filename, void *dest, size_t size) { FILE *fp = fopen(filename, "rb"); if (!fp) { perror(filename); exit(EXIT_FAILURE); } fread(dest, size, 1, fp); if (ferror(fp)) { perror(filename); fclose(fp); exit(EXIT_FAILURE); } fclose(fp); } static void write_mem(const char *filename, void *source, size_t size) { FILE *fp = fopen(filename, "wb"); if (!fp) { perror(filename); exit(EXIT_FAILURE); } fwrite(source, size, 1, fp); if (ferror(fp)) { perror(filename); fclose(fp); exit(EXIT_FAILURE); } fclose(fp); } /* from libretro mupen64+ format_saved_memory()*/ static void format_srm(void) { int i,j; memset(srm.sram, 0, sizeof(srm.sram)); memset(srm.eeprom, 0, sizeof(srm.eeprom)); memset(srm.flashram, 0xff, sizeof(srm.flashram)); for (i=0; i<4; i++) { for (j=0; j<0x8000; j+=2) { srm.mempack[i][j] = 0; srm.mempack[i][j+1] = 0x03; } memcpy(srm.mempack[i], mempack_init, 272); } } static int ext_matches(const char *ext, const char *filename) { const char *suffix = strrchr(filename, '.'); return suffix ? strcasecmp(ext, suffix+1) == 0 : 0; } static void change_extension(char *dst, const char *src, const char *newext) { const char *ext = strrchr(src, '.'); if (ext) strncpy(dst, src, ext - src); else strcpy(dst, src); strcat(dst, newext); } int main(int argc, char *argv[]) { FILE *fp; int i; format_srm(); memset(&files, 0, sizeof(files)); if (argc < 2) { Usage: printf("Usage:\n"); printf(" To create a srm file: %s [file.eep] [file.mpk] [file.sra] [file.fla]\n", argv[0]); printf(" To extract a srm file: %s \n\n", argv[0]); printf("Output files will be placed in the same directory of the input files.\n"); exit(EXIT_FAILURE); } for (i = 1; i < argc; ++i) { if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help") || !strcmp(argv[i], "/?")) goto Usage; if (ext_matches("srm", argv[i])) strncpy(files.srm, argv[i], 512); if (ext_matches("eep", argv[i])) strncpy(files.eep, argv[i], 512); if (ext_matches("mpk", argv[i])) strncpy(files.mpk, argv[i], 512); if (ext_matches("sra", argv[i])) strncpy(files.sra, argv[i], 512); if (ext_matches("fla", argv[i])) strncpy(files.fla, argv[i], 512); } if (*files.srm) { puts("Running in srm extraction mode"); read_mem(files.srm, &srm, sizeof(srm)); if (!is_empty_mem(srm.eeprom, sizeof(srm.eeprom))) change_extension(files.eep, files.srm, ".eep"); if (!is_empty_mem((uint8_t*)srm.mempack, sizeof(srm.mempack))) change_extension(files.mpk, files.srm, ".mpk"); if (!is_empty_mem(srm.sram, sizeof(srm.sram))) change_extension(files.sra, files.srm, ".sra"); if (!is_empty_mem(srm.flashram, sizeof(srm.flashram))) change_extension(files.fla, files.srm, ".fla"); int over = ((*files.eep && access(files.eep, 0) != -1) || (*files.mpk && access(files.mpk, 0) != -1) || (*files.sra && access(files.sra, 0) != -1) || (*files.fla && access(files.fla, 0) != -1)); if (over && !overwrite_confirm("existing saves in the source directory")) { puts("existing saves unmodified."); exit(EXIT_SUCCESS); } if (*files.eep) write_mem(files.eep, srm.eeprom, sizeof(srm.eeprom)); if (*files.mpk) write_mem(files.mpk, srm.mempack, sizeof(srm.mempack)); if (*files.sra) write_mem(files.sra, srm.sram, sizeof(srm.sram)); if (*files.fla) write_mem(files.fla, srm.flashram, sizeof(srm.flashram)); } else { puts("srm file unspecified, running in srm creation mode"); if (!files.eep && !files.mpk && !files.sra && !files.fla) die("no input files."); /* pick the first filename */ if (!*files.srm) { if (*files.eep) change_extension(files.srm, files.eep, ".srm"); else if (*files.mpk) change_extension(files.srm, files.mpk, ".srm"); else if (*files.sra) change_extension(files.srm, files.sra, ".srm"); else if (*files.fla) change_extension(files.srm, files.fla, ".srm"); if (strlen(files.srm) + 3 > 512) die("path too long"); } if (*files.eep) read_mem(files.eep, srm.eeprom, sizeof(srm.eeprom)); if (*files.mpk) read_mem(files.mpk, srm.mempack, sizeof(srm.mempack)); if (*files.sra) read_mem(files.sra, srm.sram, sizeof(srm.sram)); if (*files.fla) read_mem(files.fla, srm.flashram, sizeof(srm.flashram)); int over = access(files.srm, 0 /*F_OK*/) != -1; if (over && !overwrite_confirm(files.srm)) { printf("%s unmodified.\n", files.srm); exit(EXIT_SUCCESS); } printf("Writting srm data to %s...\n", files.srm); fp = fopen(files.srm, "wb"); if (!fp) { perror(files.srm); exit(EXIT_FAILURE); } fwrite(srm.eeprom, sizeof(srm.eeprom), 1, fp); fwrite(srm.mempack, sizeof(srm.mempack), 1, fp); fwrite(srm.sram, sizeof(srm.sram), 1, fp); fwrite(srm.flashram, sizeof(srm.flashram), 1, fp); fclose(fp); } return EXIT_SUCCESS; } mupen64plus-video-gliden64/src/FrameBufferEmulationIssues.txt000664 001750 001750 00000013347 12655644434 025435 0ustar00sergiosergio000000 000000 Ïðîáëåìû ñ ýìóëÿöèåé ôðåéì áóôåðà. Zelda MM: ïðîâåðêà íà òî, ÷òî ñîäåðæèìîå áóôåðà çàïîëíåíî pBuffer->fillcolor îáëàìûâàåòñÿ íà ýêðàíå ïàóçû. Ïðè÷èíà: Êàäð êîïèðóåòñÿ â áóôåð, êîòîðûé ñ íà÷àëå îòðèñîâêè èñïîëüçóåòñÿ ïîä depth buffer è ÷èñòèòñÿ 0xfffcfffc. Ïðîãðàììà ìåæäó âûçîâàìè dysplay list ÷òî-òî ñàìà ïèøåò â ýòîò áóôåð (âûñòàâëÿåò alpha â 1), è íà ñëåäóþùåì êàäðå ïðîâåðêà íå ñðàáàòûâàåò. detect fb final results: rdp.frame_buffers[0].status = ci_main, addr: 00000500, height: 0 rdp.frame_buffers[1].status = ci_zimg, addr: 00383ac0, height: 240 rdp.frame_buffers[2].status = ci_main, addr: 00000500, height: 240 rdp.frame_buffers[3].status = ci_main, addr: 00000500, height: 240 rdp.frame_buffers[4].status = ci_main, addr: 00000500, height: 240 rdp.frame_buffers[5].status = ci_main, addr: 00000500, height: 240 rdp.frame_buffers[6].status = ci_copy, addr: 00383ac0, height: 240 rdp.frame_buffers[7].status = ci_main, addr: 00000500, height: 240 rdp.frame_buffers[8].status = ci_aux, addr: 00784600, height: 240 rdp.frame_buffers[9].status = ci_main, addr: 00000500, height: 240 rdp.frame_buffers[10].status = ci_main, addr: 00000500, height: 240 DetectFrameBufferUsage End detect fb final results: rdp.frame_buffers[0].status = ci_main, addr: 00000500, height: 240 rdp.frame_buffers[1].status = ci_main, addr: 00000500, height: 240 rdp.frame_buffers[2].status = ci_main, addr: 00000500, height: 240 rdp.frame_buffers[3].status = ci_main, addr: 00000500, height: 240 DetectFrameBufferUsage End Ðåøåíèå: ïðîâåðÿòü òîëüêî 16áèò áóôåð è áåç àëüôà áèòà. Zelda OOT: Òà æå ïðîáëåìà ñ ýêðàíîì ïàóçû, ÷òî â Zelda MM Ê òîìó æå ýêðàí íå ðàáîòàåò åñëè âêëþ÷åí subscreen fix! Mario Tennis: Scoreboard. Òàáëèöà ñ÷¸òà è äàò÷èê ñêîðîñòè ïîäà÷è âûãëÿäÿò êàê ÷¸ðíûé ôîí ñ òåêñòîì. Ïðè÷èíà: òåêñòóðû òàáëèöû è äàò÷èêà ãðóçÿòñÿ â ïàìÿòü. Òåêñòà â íèõ íåò, ïóñòûå îáëàñòè. Ìû âèäèì ýòè òåêñòóðû ïðè îòêëþ÷åííîé ýìóëÿöèè áóôåðà êàäðà. Êîãäà íóæíî îáíîâèòü òåêñò, èãðà çàâîäèò âñïîìîãàòåëüíûé áóôåð êàäðà ïî àäðåñó, ãäå ëåæèò òåêñòóðà, è ðåíäèò òåêñò â íóæíûõ ìåñòàõ. Ïîòîì òåêñòóðà ñ òåêñòîì íàêëàäûâàåòñÿ íà ïîëèãîíû òàáëèöû. Òàê êàê àäðåñ áóôåðà ñîâïàäàåò ñ àäðåñîì òåêñòóðû, áóôåð èñïîëüçóåòñÿ âìåñòî íåå, à â íåì òîëüêî òåêñò. Ðåøåíèå: ïîñëå îòðèñîâêè êîïèðîâàòü ñîäåðæèìîå áóôåðà îáðàòíî â RDRAM. Íóæíî íàéòè íîðìàëüíîå óñëîâèå äëÿ îïðåäåëåíèÿ òàêîãî áóôåðà. Ïîêà àäðåñà áóôåðîâ çàõàðäêîäàíû. F1 Pole Position: Ïðîáëåìû ñ ôîíîì â ìåíþ. Ïîñëå òèòðîâ çàïóñêàåòñÿ äåìî ñ 3D ìîäåëÿìè. Èñïîëüçóåòñÿ áóôåð ãëóáèíû. Ïðå ïåðåõîäå ñíîâà ê ìåíþ òåêòóðû ôîíà ãðóçÿòñÿ â îáëàñòü, êîòîðàÿ èñïîëüçîâàëàñü ïîä z áóôåð. Ó áóôåðà ôëàã cleared ñáðîøåí ïîñëå çàïèñè z áóôåðà â RDRAM, ïðîâåðêà âàëèäíîñòè íå íàõîäèò ïðîáëåì. è òåêòóðà ãðóçèòñÿ èç ïóñòîãî áóôåðà. Ðåøåíèå: Depth copy to RDRAM çàïèñûâàåò checksum çàïèñàííûõ äàííûõ â áóôåð, ñîîòâåñòâóþùèé áóôåðó ãëóáèíû. Òîãäà â äàëüíåéøåì ïðîâåðêà ïî checksum óäàëèò ýòîò áóôåð. Upd: Ðåøåíèå ïëîõîå. Ëîìàåò subscreen in Zelda OOT. Èãðà ìåíÿåò îáëàñòü z áóôåðà (âûñòàâëÿåò alpha = 1) êîãäà èñïîëüçóåò åãî êàê ôîí äëÿ ýêðàíà ïàóçû. Checksum íå áúåò. Ðåøåíèå - ðàçäåëèòü îïöèè hack_noDepthFrameBuffers è hack_blurPauseScreen Äëÿ ýòîé èãðû âêëþ÷èòü hack_noDepthFrameBuffers è ïðîñòî óáèðàòü áóôåð ãëóáèíû ïðè ïîïûòêå ñ÷èòàòü èç íåãî òåêñòóðó. Mickey's Speedway USA: pause screen ðàáîòàåò òàê: â îáëàñòü òåêóùåãî áóôåðà ãëóáèíû êîïèðóåòñÿ áóôåð êàäðà, êîòîðûé â äàííûé ìîìåíò îòîáðàæàåòñ ÿ íà ýêðàíå. Äàëåå ýòîò áóôåð ðàçìûâàåòñÿ íà óðîâíå CPU è ïîòîì èñïîëüçóåòñÿ êàê òåêñòóðà. Ïîäîáíûé ìåõàíèçì ðàáîòàåò â Conker BFD. ×òîáû ïîëó÷èòü ðàçìûòèå íóæíî êîïèðîâàòü áóôåð êàäðà â RDRAM, à â ìîìåíò âûçîâà ïàóçû ñêîïèðîâàòü åãî (memcopy) â áóôåð ãëóáèíû â RDRAM. Ïðè ýòîì íóæíî ÷òîáû ýòà îáëàñòü íå î÷èñòèëàñü ÷åðåç gDPFillRDRAM ïðè ñìåíå áóôåðà. Äëÿ ïî÷èíêè îòêëþ÷èë âûçîâ gDPFillRDRAM åñëè m_isDepthBuffer == true. Jet Force Gemini: Îáíàðóæèëàñü ïðîáëåìà ñ âñïîìîãàòåëüíûì 8áèò áóôåðîì äëÿ òåíåé. Áóôåð ñîçäàåòñÿ îòäåëüíûì display list'îì. Áóôåð ñîçäàåòñÿ, î÷èùàåòñÿ fillrect, ñòîèò ôëàã cleared. Ïîñëå ýòîãî èãðà ïèøåò ïàðó áàéò â ñåðåäèíå áóôåðà, è â ñëåäóþùåì display list, ãäå áóôåð èñïîëüçóåòñÿ, ïðîâåðêà ïî RDRAM íå ñðàáàòûâàåò. Ïðèøëîñü ñäåëàòü ïðîâåðêó íå ñòðîãîé, à îòñåêàòü åñëè êîëè÷åñòâî îøèáî÷íûõ ïèêñåëîâ â áóôåðå ìåíüøå ïîðîãîâîãî çíà÷åíèÿ. Ïîêà ñäåëàë ïîðîã â 1%. Pokemon Stadium 2: Âîçíèêëà ïðîáëåìà ñ ïîðòðåòàìè ïîêåìîíîâ. Ïîðòðåòû ñîçäàþòñÿ â âñïîìîãàòåëüíûõ áóôåðàõ êîãäà íà ýêðàíå îòîáðàæàåòñÿ ìåíþ âûáîðà ïîêåìîíîâ.  ýòîò ìîìåíò ðàáîòàåò interlaced âèäåî ðåæèì. Ïîòîì èãðà ïåðåêëþ÷àåòñÿ â ðåæèì áèòâû, è ïåðåêëþ÷àåò âèäåî ðåæèì â non-interlaced. Ïðè ïåðåêëþ÷åíèèè ðåæèìîâ âñå áóôåðû ñáðàñûâàëèñü è ïîðòðåòû òåðÿëèñü. Ïðèøëîñü ñäåëàòü ñáðîñ òîëüêî äëÿ ïîëíîýêðàííûõ áóôåðîâ. Pokemon Stadium: Èãðà èñïîëüçóåò êó÷ó âñïîìîãàòåëüíûõ áóôåðîâ äëÿ îòðèñîâêè ìåíþ. Ïðè ýòîì áóôåðà ìîãóò èìåòü îäèíàêîâóþ øèðèíó, íî ðàçíóþ âûñîòó. È ðàñïîëàãàòüñÿ äðóã çà äðóãîì. Êîä, êîòîðûé ïðîâåðÿåò ïåðåñå÷åíèå íîâîãî áóôåðà ñ ñóùåñòâóþùèìè è âûáðàñûâàåò âñå ïåðåñåêàþùèåñÿ áóôåðà, â äàííîì ñëó÷àå âûêèäûâàë áîëüøóþ ÷àñòü áóôåðîâ èç çà íåâåðíî ïðîñòàâëåííîé âûñîòû, à çíà÷èò è íèæíåãî àäðåñà áóôåðà. Ïðèøëîñü ïðàâèòü êîä êîððåêöèè âûñîòû áóôåðà, è âûçûâàòü ìåòîä ïîèñêà ïåðåñå÷åíèé ïîñëå êîððåêöèè. Blast Corps: Âîçíèêëà ïðîáëåìà ñ depth image, êîòîðàÿ ïðèâîäèëà ê îñòàíîâêå âèäåî äðàéâåðà. Èãðà ñîçäàâàëà âñïîìîãàòåëüíûé depth image äëÿ âñïîìîãàòåëüíîãî color image. Àäðåñ âñïîìîãàòåëüíîãî depth image ñîâïàäàë ñ àäðåñîì îñíîâíîãî, íî øèðèíà ñòàâèëàñü òàêàÿ æå êàê ó âñïîìîãàòåëüíîãî color image. Èç-çà ïîñëåäîâàòåëüíîñòè êîìàíä ïëàãèí íå âîâðåìÿ ïðîñåêàë èçìåíåíèå ðàçìåðîâ depth image, ÷òî ïðèâîäèëî ê óñòàíîâêå íåâåðíîãî depth buffer äëÿ FBO è ê êðàõó äðàéâåðà. Ðåøåíèå: Ïðè âûçîâå setcolorimage, åñëè color image == depth image, âûçûâàòü depthBufferList().saveBuffer, êîòîðûé ïðè íåîáõîäèìîñòè ïåðåñîçäàñò depth buffer. mupen64plus-core/tools/regtests/daily-tests.cfg000664 001750 001750 00000014203 12655644434 022772 0ustar00sergiosergio000000 000000 #/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # * Mupen64plus - daily-tests.cfg * # * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * # * Copyright (C) 2008-2009 Richard Goedeken * # * * # * This program is free software; you can redistribute it and/or modify * # * it under the terms of the GNU General Public License as published by * # * the Free Software Foundation; either version 2 of the License, or * # * (at your option) any later version. * # * * # * This program is distributed in the hope that it will be useful, * # * but WITHOUT ANY WARRANTY; without even the implied warranty of * # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * # * GNU General Public License for more details. * # * * # * You should have received a copy of the GNU General Public License * # * along with this program; if not, write to the * # * Free Software Foundation, Inc., * # * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ # Daily regression test config file for Mupen64Plus # # To set up an automatic nightly test, run "crontab -e" and add a line like this: # # 30 03 * * * export DISPLAY=:0 ; /home/username/software/regtests/regression-video.py # # This will launch the test at 3:30am each night. You will need to replace the path to the # regression-video.py script with the correct path for your system. You may also need to # disable your screen saver to make this work. # Global test settings rompath = /path/to/N64/ROMs sendemail = me@mydomain.com {Core Library} url = http://bitbucket.org/richard42/mupen64plus-core outputfiles = libmupen64plus.so.2 testbuilds = 32-bit build on 64-bit system, LIRC build, No Assembly build, Debug Info build, R4300 Debugger build testbuildparams = all BITS=32, all LIRC=1, all NO_ASM=1, all DEBUG=1 DBG_CORE=1 DBG_COUNT=1 DBG_COMPARE=1 DBG_PROFILE=1, all DEBUGGER=1 videobuild = 64-bit basic build videobuildparams = all {Console UI} url = http://bitbucket.org/richard42/mupen64plus-ui-console outputfiles = mupen64plus testbuilds = 32-bit build testbuildparams = all BITS=32 videobuild = 64-bit videobuildparams = all {Video-Rice} url = http://bitbucket.org/richard42/mupen64plus-video-rice outputfiles = mupen64plus-video-rice.so testbuilds = 32-bit build, no assembly build, debug build testbuildparams = all BITS=32, all NO_ASM=1, all DEBUG=1 videobuild = 64-bit videobuildparams = all {Audio-SDL} url = http://bitbucket.org/richard42/mupen64plus-audio-sdl outputfiles = mupen64plus-audio-sdl.so testbuilds = 32-bit build testbuildparams = all BITS=32 videobuild = 64-bit videobuildparams = all {Input-SDL} url = http://bitbucket.org/richard42/mupen64plus-input-sdl outputfiles = mupen64plus-input-sdl.so testbuilds = 32-bit build testbuildparams = all BITS=32 videobuild = 64-bit videobuildparams = all {RSP-HLE} url = http://bitbucket.org/richard42/mupen64plus-rsp-hle outputfiles = mupen64plus-rsp-hle.so testbuilds = 32-bit build testbuildparams = all BITS=32 videobuild = 64-bit videobuildparams = all # Game-specific settings [1080 Snowboarding (E) (M4) [!].z64] screenshots = 22, 147, 276, 354, 540, 684 [Airboarders 64.z64] screenshots = 46, 450, 475, 508, 548, 632 [Automobili Lamborghini.z64] screenshots = 35, 226, 532, 586, 632, 682, 752, 838 [Banjo-Kazooie.z64] screenshots = 26, 129, 287, 536, 581, 627 [Batman Beyond - Return of the Joker.z64] screenshots = 42, 352, 613, 1178 [Bomberman 64 (U) [!].z64] screenshots = 72, 578, 767, 950, 1110, 1219 [Bust-A-Move '99.z64] screenshots = 119,966,1186,1282,1378,1479,1691,2082 [Cruis'n USA.z64] screenshots = 0, 93, 191, 250, 308, 420 [Doom 64.z64] screenshots = 18, 364, 469 [Earthworm Jim 3D.z64] screenshots = 42, 354, 770, 877, 991, 1285, 1364, 1487 [Elmo's Letter Adventure.z64] screenshots = 49, 393, 1389 [Fighting Force 64.z64] screenshots = 35, 353, 919 ,1044, 1401, 2267 [Forsaken 64.z64] screenshots = 27, 527 [Gauntlet Legends.v64] screenshots = 31, 503, 792, 929, 1038, 1228, 1284, 1412, 1589 skipvideo = glN64 [Iggy's Reckin' Balls.z64] screenshots = 142, 493, 531, 726, 824 [Kirby 64 - The Crystal Shards (U) [!].z64] screenshots = 28, 164, 439, 606, 859, 979, 1115, 1203, 1384, 1612, 1921, 2170 [Mario Kart 64 (U) [!].z64] screenshots = 41, 104, 260, 572, 629, 897, 961 [Micro Machines 64 Turbo.z64] screenshots = 52, 142, 250, 511, 623, 690, 743 [Mischief Makers.z64] screenshots = 85, 360, 607, 882, 1043, 1155, 1259, 1334, 1489 [Mortal Kombat 4 (U) [!].z64] screenshots = 37, 171, 319, 517 [Paper Mario (U) [!].z64] screenshots = 57, 235, 595, 843, 1177, 1401 [Penny Racers.z64] screenshots = 24, 462, 620, 755 skipvideo = rice, glide64 [Quake 64 (U) [!].z64] screenshots = 35, 319, 427 [Road Rash 64.z64] screenshots = 44, 330, 459, 634 [San Francisco Rush - Extreme Racing.z64] screenshots = 17, 93, 246, 282, 397, 509, 704 [Star Fox 64 (U) (V1.1) [!].z64] screenshots = 35, 295, 458, 794, 929, 1390 [Super Mario 64 (U) [!].z64] screenshots = 17, 119, 199, 330, 421 [Super Smash Bros..z64] screenshots = 40, 78, 185, 590, 1008, 1117, 1349, 1566, 1639, 1683, 1745, 1805 [Taz Express (E) (M6) [!].z64] screenshots = 25, 119, 167, 322 [TheLegendofZeldaOcarinaofTime.v64] screenshots = 84, 299, 380, 513, 601, 706, 770 [Top Gear Rally.z64] screenshots = 62, 194, 299, 454, 557, 861, 937, 970, 1072, 1228, 1273, 1342 [Turok - Dinosaur Hunter.z64] screenshots = 51, 222, 301, 438, 554, 910, 975, 1004 [Wave Race 64.z64] screenshots = 25, 99, 214, 275, 333, 389, 426 [Wetrix.N64] screenshots = 66, 176, 353, 440, 545, 742, 827, 863 [Worms - Armageddon (U) (M3) [!].z64] screenshots = 38, 375 [Yoshi's Story (U) (M2) [!].z64] screenshots = 68, 276, 340, 572, 638 mupen64plus-video-gliden64/src/GLES2/Shaders_gles2.h000664 001750 001750 00000032603 12655644434 023104 0ustar00sergiosergio000000 000000 #define SHADER_VERSION "#version 100 \n" static const char* vertex_shader = SHADER_VERSION "#if (__VERSION__ > 120) \n" "# define IN in \n" "# define OUT out \n" "#else \n" "# define IN attribute \n" "# define OUT varying \n" "#endif // __VERSION \n" "IN highp vec4 aPosition; \n" "IN lowp vec4 aColor; \n" "IN highp vec2 aTexCoord0; \n" "IN highp vec2 aTexCoord1; \n" "IN lowp float aNumLights; \n" " \n" "uniform int uRenderState; \n" "uniform int uTexturePersp; \n" " \n" "uniform int uFogMode; \n" "uniform lowp int uFogUsage; \n" "uniform lowp float uFogAlpha; \n" "uniform mediump vec2 uFogScale; \n" " \n" "uniform mediump vec2 uTexScale; \n" "uniform mediump vec2 uTexOffset[2]; \n" "uniform mediump vec2 uCacheScale[2]; \n" "uniform mediump vec2 uCacheOffset[2]; \n" "uniform mediump vec2 uCacheShiftScale[2]; \n" "uniform lowp ivec2 uCacheFrameBuffer; \n" "OUT lowp vec4 vShadeColor; \n" "OUT mediump vec2 vTexCoord0; \n" "OUT mediump vec2 vTexCoord1; \n" "OUT mediump vec2 vLodTexCoord; \n" "OUT lowp float vNumLights; \n" "OUT mediump float vFogFragCoord; \n" "mediump vec2 calcTexCoord(in vec2 texCoord, in int idx) \n" "{ \n" " vec2 texCoordOut = texCoord*uCacheShiftScale[idx]; \n" " texCoordOut -= uTexOffset[idx]; \n" " if (uCacheFrameBuffer[idx] != 0) \n" " texCoordOut.t = -texCoordOut.t; \n" " return (uCacheOffset[idx] + texCoordOut)* uCacheScale[idx];\n" "} \n" " \n" "void main() \n" "{ \n" " gl_Position = aPosition; \n" " vFogFragCoord = 0.0; \n" " vShadeColor = aColor; \n" " if (uRenderState == 1) { \n" " vec2 texCoord = aTexCoord0; \n" " texCoord *= uTexScale; \n" " if (uTexturePersp == 0) texCoord *= 0.5; \n" " vTexCoord0 = calcTexCoord(texCoord, 0); \n" " vTexCoord1 = calcTexCoord(texCoord, 1); \n" " vLodTexCoord = texCoord * uCacheShiftScale[0]; \n" " vNumLights = aNumLights; \n" " if (uFogMode == 0) { \n" " if (aPosition.z < -aPosition.w) \n" " vFogFragCoord = -uFogScale.s + uFogScale.t; \n" " else \n" " vFogFragCoord = aPosition.z/aPosition.w*uFogScale.s \n" " + uFogScale.t; \n" " } else if (uFogMode == 1) { \n" " vFogFragCoord = uFogAlpha; \n" " } else if (uFogMode == 2) { \n" " vFogFragCoord = 1.0 - uFogAlpha; \n" " } \n" " vFogFragCoord = clamp(vFogFragCoord, 0.0, 1.0); \n" " lowp int fogUsage = uFogUsage; \n" " if (fogUsage >= 256) fogUsage -= 256; \n" " if (fogUsage == 1 && uFogMode == 0) \n" " vShadeColor.a = vFogFragCoord; \n" " } else { \n" " vTexCoord0 = aTexCoord0; \n" " vTexCoord1 = aTexCoord1; \n" " vNumLights = 0.0; \n" " if (uFogMode == 1) vFogFragCoord = uFogAlpha; \n" " else if (uFogMode == 2) vFogFragCoord = 1.0 - uFogAlpha; \n" " } \n" "} \n" ; static const char* vertex_shader_notex = SHADER_VERSION "#if (__VERSION__ > 120) \n" "# define IN in \n" "# define OUT out \n" "#else \n" "# define IN attribute \n" "# define OUT varying \n" "#endif // __VERSION \n" "IN highp vec4 aPosition; \n" "IN lowp vec4 aColor; \n" "IN lowp float aNumLights; \n" " \n" "uniform int uRenderState; \n" " \n" "uniform int uFogMode; \n" "uniform lowp int uFogUsage; \n" "uniform lowp float uFogAlpha; \n" "uniform mediump vec2 uFogScale; \n" " \n" "OUT lowp vec4 vShadeColor; \n" "OUT lowp float vNumLights; \n" "OUT mediump float vFogFragCoord; \n" " \n" "void main() \n" "{ \n" " gl_Position = aPosition; \n" " vFogFragCoord = 0.0; \n" " vShadeColor = aColor; \n" " if (uRenderState == 1) { \n" " vNumLights = aNumLights; \n" " if (uFogMode == 0) { \n" " if (aPosition.z < -aPosition.w) \n" " vFogFragCoord = -uFogScale.s + uFogScale.t; \n" " else \n" " vFogFragCoord = aPosition.z/aPosition.w*uFogScale.s \n" " + uFogScale.t; \n" " } else if (uFogMode == 1) { \n" " vFogFragCoord = uFogAlpha; \n" " } else if (uFogMode == 2) { \n" " vFogFragCoord = 1.0 - uFogAlpha; \n" " } \n" " vFogFragCoord = clamp(vFogFragCoord, 0.0, 1.0); \n" " lowp int fogUsage = uFogUsage; \n" " if (fogUsage >= 256) fogUsage -= 256; \n" " if (fogUsage == 1 && uFogMode == 0) \n" " vShadeColor.a = vFogFragCoord; \n" " } else { \n" " vNumLights = 0.0; \n" " if (uFogMode == 1) vFogFragCoord = uFogAlpha; \n" " else if (uFogMode == 2) vFogFragCoord = 1.0 - uFogAlpha; \n" " } \n" "} \n" ; static const char* fragment_shader_header_common_variables = SHADER_VERSION "#if (__VERSION__ > 120) \n" "# define IN in \n" "# define OUT out \n" "#else \n" "# define IN varying \n" "# define OUT \n" "#endif // __VERSION __ \n" "uniform sampler2D uTex0; \n" "uniform sampler2D uTex1; \n" "uniform lowp vec4 uFogColor; \n" "uniform lowp vec4 uCenterColor;\n" "uniform lowp vec4 uScaleColor; \n" "uniform lowp vec4 uBlendColor; \n" "uniform lowp vec4 uEnvColor; \n" "uniform lowp vec4 uPrimColor; \n" "uniform lowp float uPrimLod; \n" "uniform lowp float uK4; \n" "uniform lowp float uK5; \n" "uniform mediump vec2 uScreenScale; \n" "uniform lowp int uAlphaCompareMode; \n" "uniform lowp int uFogUsage; \n" "uniform lowp ivec2 uFbMonochrome; \n" "uniform lowp ivec2 uFbFixedAlpha;\n" "uniform lowp int uSpecialBlendMode;\n" "uniform lowp int uEnableAlphaTest; \n" "uniform lowp float uAlphaTestValue;\n" "uniform mediump vec2 uDepthScale; \n" "IN lowp vec4 vShadeColor; \n" "IN mediump vec2 vTexCoord0;\n" "IN mediump vec2 vTexCoord1;\n" "IN mediump vec2 vLodTexCoord;\n" "IN lowp float vNumLights; \n" "IN mediump float vFogFragCoord;\n" "lowp vec3 input_color; \n" "OUT lowp vec4 fragColor; \n" "lowp int nCurrentTile; \n" ; static const char* fragment_shader_header_common_variables_notex = SHADER_VERSION "#if (__VERSION__ > 120) \n" "# define IN in \n" "# define OUT out \n" "#else \n" "# define IN varying \n" "# define OUT \n" "#endif // __VERSION __ \n" "uniform lowp vec4 uFogColor; \n" "uniform lowp vec4 uCenterColor;\n" "uniform lowp vec4 uScaleColor; \n" "uniform lowp vec4 uBlendColor; \n" "uniform lowp vec4 uEnvColor; \n" "uniform lowp vec4 uPrimColor; \n" "uniform lowp float uPrimLod; \n" "uniform lowp float uK4; \n" "uniform lowp float uK5; \n" "uniform mediump vec2 uScreenScale; \n" "uniform lowp int uAlphaCompareMode; \n" "uniform lowp int uFogUsage; \n" "uniform lowp int uSpecialBlendMode;\n" "uniform lowp int uEnableAlphaTest; \n" "uniform lowp float uAlphaTestValue;\n" "uniform mediump vec2 uDepthScale; \n" "IN lowp vec4 vShadeColor; \n" "IN lowp float vNumLights; \n" "IN mediump float vFogFragCoord;\n" "lowp vec3 input_color; \n" "OUT lowp vec4 fragColor; \n" ; static const char* fragment_shader_header_common_functions = " \n" "lowp float snoise(); \n" "void calc_light(in lowp float fLights, in lowp vec3 input_color, out lowp vec3 output_color);\n" "mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1); \n" "lowp vec4 readTex(in sampler2D tex, in mediump vec2 texCoord, in lowp int fbMonochrome, in bool fbFixedAlpha); \n" #ifdef USE_TOONIFY "void toonify(in mediump float intensity); \n" #endif ; static const char* fragment_shader_header_common_functions_notex = " \n" "lowp float snoise(); \n" "void calc_light(in lowp float fLights, in lowp vec3 input_color, out lowp vec3 output_color);\n" ; static const char* fragment_shader_calc_light = "uniform mediump vec3 uLightDirection[8]; \n" "uniform lowp vec3 uLightColor[8]; \n" "void calc_light(in lowp float fLights, in lowp vec3 input_color, out lowp vec3 output_color) {\n" " output_color = input_color; \n" " lowp int nLights = int(floor(fLights + 0.5)); \n" " if (nLights == 0) \n" " return; \n" " output_color = uLightColor[nLights]; \n" " mediump float intensity; \n" " mediump vec3 n = normalize(input_color); \n" " for (int i = 0; i < nLights; i++) { \n" " intensity = max(dot(n, uLightDirection[i]), 0.0); \n" " output_color += intensity*uLightColor[i]; \n" " }; \n" " clamp(output_color, 0.0, 1.0); \n" "} \n" ; static const char* fragment_shader_header_main = " \n" "void main() \n" "{ \n" " lowp vec4 vec_color, combined_color; \n" " lowp float alpha1, alpha2; \n" " lowp vec3 color1, color2; \n" ; #ifdef USE_TOONIFY static const char* fragment_shader_toonify = " \n" "void toonify(in mediump float intensity) { \n" " if (intensity > 0.5) \n" " return; \n" " else if (intensity > 0.125) \n" " fragColor = vec4(vec3(fragColor)*0.5, fragColor.a);\n" " else \n" " fragColor = vec4(vec3(fragColor)*0.2, fragColor.a);\n" "} \n" ; #endif static const char* fragment_shader_end = "} \n" ; static const char* fragment_shader_fake_mipmap = "uniform lowp int uMaxTile; \n" "uniform mediump float uMinLod; \n" " \n" "mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1) { \n" " readtex0 = texture2D(uTex0, vTexCoord0); \n" " readtex1 = texture2D(uTex1, vTexCoord1); \n" " if (uMaxTile == 0) return 1.0; \n" " return uMinLod; \n" "} \n" ; static const char* fragment_shader_readtex = "lowp vec4 readTex(in sampler2D tex, in mediump vec2 texCoord, in lowp int fbMonochrome, in bool fbFixedAlpha) \n" "{ \n" " lowp vec4 texColor = texture2D(tex, texCoord); \n" " if (fbMonochrome == 1) texColor = vec4(texColor.r); \n" " else if (fbMonochrome == 2) \n" " texColor.rgb = vec3(dot(vec3(0.2126, 0.7152, 0.0722), texColor.rgb)); \n" " if (fbFixedAlpha) texColor.a = 0.825; \n" " return texColor; \n" "} \n" ; static const char* fragment_shader_readtex_3point = "uniform mediump vec2 uTextureSize[2]; \n" "uniform lowp int uTextureFilterMode; \n" // 3 point texture filtering. // Original author: ArthurCarvalho // GLSL implementation: twinaphex, mupen64plus-libretro project. "#define TEX_OFFSET(off) texture2D(tex, texCoord - (off)/texSize) \n" "lowp vec4 filter3point(in sampler2D tex, in mediump vec2 texCoord) \n" "{ \n" " mediump vec2 texSize = uTextureSize[nCurrentTile]; \n" " mediump vec2 offset = fract(texCoord*texSize - vec2(0.5)); \n" " offset -= step(1.0, offset.x + offset.y); \n" " lowp vec4 c0 = TEX_OFFSET(offset); \n" " lowp vec4 c1 = TEX_OFFSET(vec2(offset.x - sign(offset.x), offset.y)); \n" " lowp vec4 c2 = TEX_OFFSET(vec2(offset.x, offset.y - sign(offset.y))); \n" " return c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0); \n" "} \n" "lowp vec4 readTex(in sampler2D tex, in mediump vec2 texCoord, in lowp int fbMonochrome, in bool fbFixedAlpha) \n" "{ \n" " lowp vec4 texStandard = texture2D(tex, texCoord); \n" " lowp vec4 tex3Point = filter3point(tex, texCoord); \n" " lowp vec4 texColor = uTextureFilterMode == 0 ? texStandard : tex3Point; \n" " if (fbMonochrome == 1) texColor = vec4(texColor.r); \n" " else if (fbMonochrome == 2) \n" " texColor.rgb = vec3(dot(vec3(0.2126, 0.7152, 0.0722), texColor.rgb)); \n" " if (fbFixedAlpha) texColor.a = 0.825; \n" " return texColor; \n" "} \n" ; static const char* fragment_shader_noise = "uniform sampler2D uTexNoise; \n" "lowp float snoise() \n" "{ \n" " mediump vec2 texSize = vec2(640.0, 580.0); \n" " mediump vec2 coord = gl_FragCoord.xy/uScreenScale/texSize; \n" " return texture2D(uTexNoise, coord).r; \n" "} \n" ; static const char* fragment_shader_dummy_noise = " \n" "lowp float snoise() \n" "{ \n" " return 1.0; \n" "} \n" ; static const char* default_vertex_shader = SHADER_VERSION "#if (__VERSION__ > 120) \n" "# define IN in \n" "#else \n" "# define IN attribute \n" "#endif // __VERSION \n" "IN highp vec4 aPosition; \n" "void main() \n" "{ \n" " gl_Position = aPosition; \n" "} \n" ; static const char* zelda_monochrome_fragment_shader = SHADER_VERSION "uniform sampler2D uColorImage; \n" "uniform mediump vec2 uScreenSize; \n" "void main() \n" "{ \n" " mediump vec2 coord = gl_FragCoord.xy/uScreenSize; \n" " lowp vec4 tex = texture2D(uColorImage, coord); \n" " lowp float c = dot(vec4(0.2126, 0.7152, 0.0722, 0.0), tex); \n" " gl_FragColor = vec4(c, c, c, 1.0); \n" "} \n" ; gles2rice/src/VectorMath.cpp000664 001750 001750 00000017104 12655644434 017150 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - VectorMath.cpp * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Rice1964 * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include "VectorMath.h" //---------- XMATRIX XMATRIX::XMATRIX() { } XMATRIX::XMATRIX( const float *pIn ) { memcpy(m, pIn, 16*4); } XMATRIX::XMATRIX( const MATRIX &pIn ) { memcpy(m, pIn.m, 16*4); } XMATRIX::XMATRIX( float _11, float _12, float _13, float _14, float _21, float _22, float _23, float _24, float _31, float _32, float _33, float _34, float _41, float _42, float _43, float _44 ) { this->_11 = _11; this->_12 = _12; this->_13 = _13; this->_14 = _14; this->_21 = _21; this->_22 = _22; this->_23 = _23; this->_24 = _24; this->_31 = _31; this->_32 = _32; this->_33 = _33; this->_34 = _34; this->_41 = _41; this->_42 = _42; this->_43 = _43; this->_44 = _44; } float& XMATRIX::operator () ( unsigned int Row, unsigned int Col ) { return m[Row][Col]; } float XMATRIX::operator () ( unsigned int Row, unsigned int Col ) const { return m[Row][Col]; } XMATRIX::operator float* () { return (float*)m; } XMATRIX::operator const float* () const { return (float*)m; } XMATRIX& XMATRIX::operator *= ( const XMATRIX &pIn ) { XMATRIX mTemp(*this); *this = mTemp*pIn; return *this; } XMATRIX& XMATRIX::operator += ( const XMATRIX &pIn ) { XMATRIX mTemp(*this); *this = mTemp+pIn; return *this; } XMATRIX& XMATRIX::operator -= ( const XMATRIX &pIn ) { XMATRIX mTemp(*this); *this = mTemp-pIn; return *this; } XMATRIX& XMATRIX::operator *= ( float f) { for (int i=0; i<16; i++) { ((float*)m)[i] *= f; } return *this; } XMATRIX& XMATRIX::operator /= ( float f) { for (int i=0; i<16; i++) { ((float*)m)[i] /= f; } return *this; } XMATRIX XMATRIX::operator + () const { return *this; } XMATRIX XMATRIX::operator - () const { XMATRIX mTemp; for (int i=0; i<16; i++) { ((float*)mTemp.m)[i] = -((float*)m)[i]; } return mTemp; } XMATRIX XMATRIX::operator * ( const XMATRIX &pIn ) const { XMATRIX mTemp; for (int i=0; i<4; i++) { for (int j=0; j<4; j++) { mTemp.m[i][j] = m[i][0]*pIn.m[0][j] + m[i][1]*pIn.m[1][j] + m[i][2]*pIn.m[2][j] + m[i][3]*pIn.m[3][j]; } } return mTemp; } XMATRIX XMATRIX::operator + ( const XMATRIX &pIn ) const { XMATRIX mTemp; for (int i=0; i<16; i++) { ((float*)mTemp.m)[i] = ((float*)m)[i] + ((float*)pIn.m)[i]; } return mTemp; } XMATRIX XMATRIX::operator - ( const XMATRIX &pIn ) const { XMATRIX mTemp; for (int i=0; i<16; i++) { ((float*)mTemp.m)[i] = ((float*)m)[i] - ((float*)pIn.m)[i]; } return mTemp; } /* XMATRIX operator * ( float ) const; XMATRIX operator / ( float ) const; friend XMATRIX operator * ( float, const XMATRIX & ); bool operator == ( const XMATRIX & ) const; bool operator != ( const XMATRIX & ) const; */ //---------- VECTOR3 XVECTOR3::XVECTOR3() { } XVECTOR3::XVECTOR3( const float *f ) { x = f[0]; y = f[1]; z = f[2]; } XVECTOR3::XVECTOR3( const VECTOR3 &v ) { x = v.x; y = v.y; z = v.z; } XVECTOR3::XVECTOR3( float _x, float _y, float _z ) { x = _x; y = _y; z = _z; } /* // casting inline operator float* (); inline operator const float* () const; // assignment operators inline XVECTOR3& operator += ( const XVECTOR3 &op ); inline XVECTOR3& operator -= ( const XVECTOR3 &op ); inline XVECTOR3& operator *= ( float op ); inline XVECTOR3& operator /= ( float op ); // unary operators inline XVECTOR3 operator + () const; inline XVECTOR3 operator - () const; // binary operators inline XVECTOR3 operator + ( const XVECTOR3 &op ) const; inline XVECTOR3 operator - ( const XVECTOR3 &op ) const; inline XVECTOR3 operator * ( float op ) const; inline XVECTOR3 operator / ( float op ) const; friend XVECTOR3 operator * ( float, const XVECTOR3& ); inline bool operator == ( const XVECTOR3 &op ) const; inline bool operator != ( const XVECTOR3 &op ) const; */ //---------- XVECTOR4 XVECTOR4::XVECTOR4() { } /* XVECTOR4( const float *f ); XVECTOR4( const VECTOR4 &v ); XVECTOR4( float _x, float _y, float _z, float _w ); // casting inline operator float* (); inline operator const float* () const; // assignment operators inline XVECTOR4& operator += ( const XVECTOR4 &op ); inline XVECTOR4& operator -= ( const XVECTOR4 &op ); inline XVECTOR4& operator *= ( float op ); inline XVECTOR4& operator /= ( float op ); // unary operators inline XVECTOR4 operator + () const; inline XVECTOR4 operator - () const; // binary operators inline XVECTOR4 operator + ( const XVECTOR4 &op ) const; inline XVECTOR4 operator - ( const XVECTOR4 &op ) const; inline XVECTOR4 operator * ( float op ) const; inline XVECTOR4 operator / ( float op ) const; friend XVECTOR4 operator * ( float, const XVECTOR4& ); inline bool operator == ( const XVECTOR4 &op ) const; inline bool operator != ( const XVECTOR4 &op ) const; */ //---------- OTHER XMATRIX* MatrixTranspose( XMATRIX* pOut, const XMATRIX* pM ) { pOut->_11 = pM->_11; pOut->_12 = pM->_21; pOut->_13 = pM->_31; pOut->_14 = pM->_41; pOut->_21 = pM->_12; pOut->_22 = pM->_22; pOut->_23 = pM->_32; pOut->_24 = pM->_42; pOut->_31 = pM->_13; pOut->_32 = pM->_23; pOut->_33 = pM->_33; pOut->_34 = pM->_43; pOut->_41 = pM->_14; pOut->_42 = pM->_24; pOut->_43 = pM->_34; pOut->_44 = pM->_44; return pOut; } XVECTOR4 Vec3Transform( XVECTOR4 *pOut, const XVECTOR3 *pV, const XMATRIX *pM ) { pOut->x = pV->x*pM->_11 + pV->y*pM->_21 + pV->z*pM->_31 + pM->_41; pOut->y = pV->x*pM->_12 + pV->y*pM->_22 + pV->z*pM->_32 + pM->_42; pOut->z = pV->x*pM->_13 + pV->y*pM->_23 + pV->z*pM->_33 + pM->_43; pOut->w = pV->x*pM->_14 + pV->y*pM->_24 + pV->z*pM->_34 + pM->_44; return *pOut; } gles2n64/src/3DMath.h000664 001750 001750 00000002013 12655644434 015277 0ustar00sergiosergio000000 000000 #ifndef _3DMATH_H #define _3DMATH_H #include #ifdef __cplusplus extern "C" { #endif #define DotProduct gln64DotProduct extern void (*MultMatrix)(float m0[4][4], float m1[4][4], float dest[4][4]); extern void (*TransformVectorNormalize)(float vec[3], float mtx[4][4]); extern void (*Normalize)(float v[3]); extern float (*DotProduct)(const float v0[3], const float v1[3]); static INLINE void CopyMatrix( float m0[4][4], float m1[4][4] ) { memcpy( m0, m1, 16 * sizeof( float ) ); } static INLINE void MultMatrix2( float m0[4][4], float m1[4][4] ) { float dst[4][4]; MultMatrix(m0, m1, dst); memcpy( m0, dst, sizeof(float) * 16 ); } static INLINE void Transpose3x3Matrix( float mtx[4][4] ) { float tmp; tmp = mtx[0][1]; mtx[0][1] = mtx[1][0]; mtx[1][0] = tmp; tmp = mtx[0][2]; mtx[0][2] = mtx[2][0]; mtx[2][0] = tmp; tmp = mtx[1][2]; mtx[1][2] = mtx[2][1]; mtx[2][1] = tmp; } #ifdef __NEON_OPT void MathInitNeon(); #endif #ifdef __cplusplus } #endif #endif mupen64plus-video-gliden64/src/L3DEX2.h000664 001750 001750 00000000227 12655644434 020501 0ustar00sergiosergio000000 000000 #ifndef L3DEX2_H #define L3DEX2_H #include "Types.h" #define L3DEX2_LINE3D 0x08 void L3DEX2_Line3D( u32 w0, u32 w1 ); void L3DEX2_Init(); #endif libretro-common/glsym/rglgen.c000664 001750 001750 00000003454 12655644434 017612 0ustar00sergiosergio000000 000000 /* Copyright (C) 2010-2015 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this libretro SDK code part (glsym). * --------------------------------------------------------------------------------------- * * Permission is hereby granted, free of charge, * to any person obtaining a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include #include #include void rglgen_resolve_symbols_custom(rglgen_proc_address_t proc, const struct rglgen_sym_map *map) { for (; map->sym; map++) { rglgen_func_t func = proc(map->sym); memcpy(map->ptr, &func, sizeof(func)); } } void rglgen_resolve_symbols(rglgen_proc_address_t proc) { rglgen_resolve_symbols_custom(proc, rglgen_symbol_map); } gles2n64/src/3DMath.c000664 001750 001750 00000005351 12655644434 015302 0ustar00sergiosergio000000 000000 #include #ifdef __LIBRETRO__ // Prefix symbol #define DotProduct gln64DotProduct #endif static void MultMatrix_default( float m0[4][4], float m1[4][4], float dest[4][4]) { dest[0][0] = m0[0][0]*m1[0][0] + m0[1][0]*m1[0][1] + m0[2][0]*m1[0][2] + m0[3][0]*m1[0][3]; dest[1][0] = m0[0][0]*m1[1][0] + m0[1][0]*m1[1][1] + m0[2][0]*m1[1][2] + m0[3][0]*m1[1][3]; dest[2][0] = m0[0][0]*m1[2][0] + m0[1][0]*m1[2][1] + m0[2][0]*m1[2][2] + m0[3][0]*m1[2][3]; dest[3][0] = m0[3][0]*m1[3][3] + m0[2][0]*m1[3][2] + m0[1][0]*m1[3][1] + m0[0][0]*m1[3][0]; dest[0][1] = m0[0][1]*m1[0][0] + m0[1][1]*m1[0][1] + m0[2][1]*m1[0][2] + m0[3][1]*m1[0][3]; dest[1][1] = m0[0][1]*m1[1][0] + m0[1][1]*m1[1][1] + m0[2][1]*m1[1][2] + m0[3][1]*m1[1][3]; dest[2][1] = m0[0][1]*m1[2][0] + m0[1][1]*m1[2][1] + m0[2][1]*m1[2][2] + m0[3][1]*m1[2][3]; dest[3][1] = m0[3][1]*m1[3][3] + m0[2][1]*m1[3][2] + m0[1][1]*m1[3][1] + m0[0][1]*m1[3][0]; dest[0][2] = m0[0][2]*m1[0][0] + m0[1][2]*m1[0][1] + m0[2][2]*m1[0][2] + m0[3][2]*m1[0][3]; dest[1][2] = m0[0][2]*m1[1][0] + m0[1][2]*m1[1][1] + m0[2][2]*m1[1][2] + m0[3][2]*m1[1][3]; dest[2][2] = m0[0][2]*m1[2][0] + m0[1][2]*m1[2][1] + m0[2][2]*m1[2][2] + m0[3][2]*m1[2][3]; dest[3][2] = m0[3][2]*m1[3][3] + m0[2][2]*m1[3][2] + m0[1][2]*m1[3][1] + m0[0][2]*m1[3][0]; dest[0][3] = m0[0][3]*m1[0][0] + m0[1][3]*m1[0][1] + m0[2][3]*m1[0][2] + m0[3][3]*m1[0][3]; dest[1][3] = m0[0][3]*m1[1][0] + m0[1][3]*m1[1][1] + m0[2][3]*m1[1][2] + m0[3][3]*m1[1][3]; dest[2][3] = m0[0][3]*m1[2][0] + m0[1][3]*m1[2][1] + m0[2][3]*m1[2][2] + m0[3][3]*m1[2][3]; dest[3][3] = m0[3][3]*m1[3][3] + m0[2][3]*m1[3][2] + m0[1][3]*m1[3][1] + m0[0][3]*m1[3][0]; } static void Normalize_default(float v[3]) { float len = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; if (len != 0.0f) { len = sqrtf( len ); v[0] /= len; v[1] /= len; v[2] /= len; } } static void TransformVectorNormalize_default(float vec[3], float mtx[4][4]) { float len; float x = vec[0]; float y = vec[1]; float z = vec[2]; vec[0] = mtx[0][0] * x + mtx[1][0] * y + mtx[2][0] * z; vec[1] = mtx[0][1] * x + mtx[1][1] * y + mtx[2][1] * z; vec[2] = mtx[0][2] * x + mtx[1][2] * y + mtx[2][2] * z; Normalize_default(vec); } static float DotProduct_default(const float v0[3], const float v1[3]) { return v0[0]*v1[0] + v0[1]*v1[1] + v0[2]*v1[2]; } void (*MultMatrix)(float m0[4][4], float m1[4][4], float dest[4][4]) = MultMatrix_default; void (*TransformVectorNormalize)(float vec[3], float mtx[4][4]) = TransformVectorNormalize_default; void (*Normalize)(float v[3]) = Normalize_default; float (*DotProduct)(const float v0[3], const float v1[3]) = DotProduct_default; gles2rice/src/OGLExtCombiner.h000664 001750 001750 00000007620 12655644434 017324 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _OGLEXT_COMBINER_H_ #define _OGLEXT_COMBINER_H_ #include #include "osal_opengl.h" #include "OGLCombiner.h" typedef union { struct { uint8_t arg0; uint8_t arg1; uint8_t arg2; }; uint8_t args[3]; } OGLExt1CombType; typedef struct { union { struct { GLenum rgbOp; GLenum alphaOp; }; GLenum ops[2]; }; union { struct { uint8_t rgbArg0; uint8_t rgbArg1; uint8_t rgbArg2; uint8_t alphaArg0; uint8_t alphaArg1; uint8_t alphaArg2; }; struct { OGLExt1CombType rgbComb; OGLExt1CombType alphaComb; }; OGLExt1CombType Combs[2]; }; union { struct { GLint rgbArg0gl; GLint rgbArg1gl; GLint rgbArg2gl; }; GLint glRGBArgs[3]; }; union { struct { GLint rgbFlag0gl; GLint rgbFlag1gl; GLint rgbFlag2gl; }; GLint glRGBFlags[3]; }; union { struct { GLint alphaArg0gl; GLint alphaArg1gl; GLint alphaArg2gl; }; GLint glAlphaArgs[3]; }; union { struct { GLint alphaFlag0gl; GLint alphaFlag1gl; GLint alphaFlag2gl; }; GLint glAlphaFlags[3]; }; int tex; bool textureIsUsed; //float scale; //Will not be used } OGLExtCombinerType; typedef struct { uint32_t dwMux0; uint32_t dwMux1; OGLExtCombinerType units[8]; int numOfUnits; uint32_t constantColor; // For 1.4 v2 combiner bool primIsUsed; bool envIsUsed; bool lodFracIsUsed; } OGLExtCombinerSaveType; //======================================================================== // OpenGL 1.4 combiner which support Texture Crossbar feature class COGLColorCombiner4 : public COGLColorCombiner { public: bool Initialize(void); protected: friend class OGLDeviceBuilder; void InitCombinerCycle12(void); void InitCombinerCycleFill(void); virtual void GenerateCombinerSetting(int index); virtual void GenerateCombinerSettingConstants(int index); virtual int ParseDecodedMux(); COGLColorCombiner4(CRender *pRender); ~COGLColorCombiner4() {}; bool m_bSupportModAdd_ATI; bool m_bSupportModSub_ATI; GLint m_maxTexUnits; int m_lastIndex; uint32_t m_dwLastMux0; uint32_t m_dwLastMux1; #ifdef DEBUGGER void DisplaySimpleMuxString(void); #endif protected: virtual int SaveParsedResult(OGLExtCombinerSaveType &result); static GLint MapRGBArgFlags(uint8_t arg); static GLint MapAlphaArgFlags(uint8_t arg); static const char* GetOpStr(GLenum op); static GLint RGBArgsMap4[]; std::vector m_vCompiledSettings; private: virtual int ParseDecodedMux2Units(); virtual int FindCompiledMux(); virtual GLint MapRGBArgs(uint8_t arg); virtual GLint MapAlphaArgs(uint8_t arg); }; #endif gles2rice/src/osal_preproc.h000664 001750 001750 00000004041 12655644434 017225 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - osal_preproc.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2009 Richard Goedeken * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* this header file is for system-dependent #defines, #includes, and typedefs */ #ifndef OSAL_PREPROC_H #define OSAL_PREPROC_H #ifdef _MSC_VER #define ALIGN(BYTES,DATA) __declspec(align(BYTES)) DATA #else #define ALIGN(BYTES,DATA) DATA __attribute__((aligned(BYTES))) #endif typedef struct { int top; int bottom; int right; int left; } M64P_RECT; #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif #endif // OSAL_PREPROC_H gles2n64/src/Types.h000664 001750 001750 00000002332 12655644434 015327 0ustar00sergiosergio000000 000000 #ifndef TYPES_H #define TYPES_H #include typedef uint8_t u8; /* unsigned 8-bit */ typedef uint16_t u16; /* unsigned 16-bit */ typedef uint32_t u32; /* unsigned 32-bit */ typedef uint64_t u64; /* unsigned 64-bit */ typedef int8_t s8; /* signed 8-bit */ typedef int16_t s16; /* signed 16-bit */ typedef int32_t s32; /* signed 32-bit */ typedef int64_t s64; /* signed 64-bit */ typedef volatile uint8_t vu8; /* unsigned 8-bit */ typedef volatile uint16_t vu16; /* unsigned 16-bit */ typedef volatile uint32_t vu32; /* unsigned 32-bit */ typedef volatile uint64_t vu64; /* unsigned 64-bit */ typedef volatile int8_t vs8; /* signed 8-bit */ typedef volatile int16_t vs16; /* signed 16-bit */ typedef volatile int32_t vs32; /* signed 32-bit */ typedef volatile int64_t vs64; /* signed 64-bit */ typedef float f32; /* single prec floating point */ typedef double f64; /* double prec floating point */ #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #ifndef NULL #define NULL 0 #endif #ifndef MIN #define MIN(a,b) (((a)<(b))?(a):(b)) #endif #ifndef MAX #define MAX(a,b) (((a)>(b))?(a):(b)) #endif #endif // TYPES_H mupen64plus-core/doc/new_dynarec.txt000664 001750 001750 00000064501 12655644434 020661 0ustar00sergiosergio000000 000000 This page describes the dynamic recompiler in [[Mupen64Plus]], and the changes made for the ARM port. ==The original dynamic recompiler by Hacktarux== The dynamic recompiler used in Mupen64plus v1.5 is based on the original written by Hacktarux in 2002. It recompiles contiguous blocks of MIPS instructions. First, each instruction is decoded into a dynamically-allocated 132-byte data structure. typedef struct _precomp_instr { void (*ops)(); union { struct { long long int *rs; long long int *rt; short immediate; } i; struct { unsigned int inst_index; } j; struct { long long int *rs; long long int *rt; long long int *rd; unsigned char sa; unsigned char nrd; } r; struct { unsigned char base; unsigned char ft; short offset; } lf; struct { unsigned char ft; unsigned char fs; unsigned char fd; } cf; } f; unsigned int addr; /* word-aligned instruction address in r4300 address space */ unsigned int local_addr; /* byte offset to start of corresponding x86_64 instructions, from start of code block */ reg_cache_struct reg_cache_infos; } precomp_instr; The decoded instructions are then compiled, generating x86 instructions for each MIPS instruction. A 32K block is allocated with malloc() to hold the x86 code. If this size proves insufficient, it is incrementally resized with realloc(). MIPS registers are allocated to x86 registers with a least-recently-used replacement policy. All cached registers are written back prior to a branch, or a memory read or write. To facilitate invalidation and replacement of modified code blocks, each 4K page is compiled separately. If a sequence of instructions crosses a 4K page boundary, the current block is ended, and the next instructions will be compiled as a separate block. Branch instructions within a 4K page are compiled as branches directly to the target address. Branches which cross a 4K page go through an indirect address lookup. Compiled code blocks are invalidated on write. On an actual MIPS CPU, the instruction cache is invalidated using the CACHE instruction, however a few N64 games clear the cache using other methods. Trapping writes appears to be the most reliable method of ensuring cache coherency in the emulated system. The cache instruction is ignored. ==Problems with the original design== The most significant performance problem with this design is its excessive memory usage. The decoded instruction data is retained (132 bytes for each MIPS instruction) and occasionally referenced during execution. Memory accesses frequently miss the L2 cache, resulting in poor performance. Additionally, the register cache is relatively inefficient, since all registers are flushed before any read or write operation. ==A new approach== To reduce memory usage, the new design allocates a single large block of memory (generally 32 MiB, but the size is configurable) which is used for recompiled code. This memory is allocated using mmap with the PROT_EXEC bit set, to ensure operation on CPUs with no-execute (NX) page permissions. Contiguous blocks of MIPS instructions are compiled (that is, it does not attempt to follow branches or 'hot-paths'). The recompiler consists of eight stages, plus a linker, and a memory manager. Compiled blocks are invalidated on write, as before, however as the compiler will cross a 4K page, writes may invalidate adjacent pages as well. Currently the dynarec generates x86, x86-64, ARMv5, and ARMv7 (little-endian). Most of the code is shared between the architectures, but a different code generator is included at compile time, using different #include statements depending on the CPU type. ==Pass 1: Disassembly== When an instruction address is encountered which has not been compiled, the function new_recompile_block is called, with the (virtual) address of the target instruction as its sole parameter. If the address is invalid, the function returns a nonzero value and the caller is responsible for handling the pagefault. Instructions are decoded until an unconditional jump, usually a return, is encountered. Disassembly is ordinarilly continued past a JAL (subroutine call) instruction, however this strategy is abandoned if invalid instructions are encountered. Up to 4096 instructions (16K of MIPS code) may be disassembled at once. Surprisingly, some games do actually reach this limit. ==Pass 2: Liveness analysis== After disassembly, liveness analysis is performed on the registers. This determines when a particular register will no longer be used, and thus can be removed from the register cache. A separate analysis is done on the upper 32 bits of 64-bit registers. This can determine when only the lower 32 bits of a register are significant, thus allowing use of a 32-bit register. This enables more efficient code generation on 32-bit processors. ==Pass 3: Register allocation== The 31 MIPS registers must be mapped onto seven available registers on x86, or twelve available registers on ARM. Instructions with 64-bit results require two registers on 32-bit host processors. 32-bit instructions require only one. A flag is set for registers containing 32-bit values, and these registers will be sign-extended before they are written to the register file. Registers are made available using a least-soon-needed replacement policy. When the register cache is full, and no registers can be eliminated using the liveness analysis, a ten-instruction lookahead is used to determine which registers will not be needed soon and these registers are evicted from the cache. ==Pass 4: Free unused registers== After the initial register allocation, the allocations are reviewed to determine if any registers remain allocated longer than necessary. These are then removed from the register cache. This avoids having to write back a large number of registers just before a branch, and makes more registers available for the next pass. ==Pass 5: Pre-allocate registers== If a register will be used soon and needs to be loaded, try to load it early if the register is available. This improves execution on CPUs with a load-use penalty. ==Pass 6: Optimize clean/dirty state== If a cached register is 'dirty' and needs to be written out, try to do so as soon as the register will no longer be modified. This avoids having to write the same register on multiple code paths due to conditional branches. Additionally, try to avoid writing out dirty registers inside of loops. ==Pass 7: Identify where registers are assumed to be 32-bit== When a 64-bit register is mapped to a 32-bit register with the assumption that the value will be sign-extended before being used, it is necessary to ensure that no register contains a 64-bit value when branching to such a location. These instructions are flagged to identify them as requiring 32-bit inputs. This information is used by the linker, and the exception return (ERET) handler. ==Pass 8: Assembly== This generates and outputs the recompiled code. Following the main code block, handlers for certain exceptions as well as alternate entry points are added. If a recompiled instruction relies on a certain MIPS register being cached in a certain native register, then a short 'stub' of code is generated to load the necessary registers. When an instruction outside of this block needs to jump to that location, it will instead jump to the stub. The necessary registers will be loaded, and then it will jump into the main code sequence. On architectures which require literal pools (ARMv5) these are inserted as necessary. ==Linker== The linker fills in all unresolved branches. Branches within the block are linked to their target address. Branches which jump outside of the block are linked to their target if that address has been compiled already. These inter-block branches are recorded in the jump_out array. This information will be used to remove the links in the event that the target of the branch is invalidated. Unresolved branches point to a stub which loads the address of the branch instruction and the virtual address of its target into registers, and calls the dynamic linker. When this code is executed, the dynamic linker will compile the target if necessary, and then patch the branch instruction with the new address. ==Memory manager== The last step in new_recompile_block is to ensure that there will be sufficient memory available to compile the next block. If there is not, then the oldest blocks are purged. The dynarec cache can be described as a 32MB circular buffer divided into eight segments. Memory is allocated in order from beginning to end. When there are less than 2 empty segments, the next segment in sequence is cleared, wrapping around to the beginning of the buffer. This continues as memory is needed, wrapping around from end to beginning. ==Invalidation and restoration== Normally, code blocks are looked up via a hash table, using the virtual address of the target instruction. However, for purposes of invalidation, blocks are grouped by physical address. This can be described as a virtually-indexed, physically-tagged (VIPT) cache. References to compiled blocks are stored in one of 4096 linked lists in the jump_in array. Each list covers a 4K block of memory, and 2048 such lists are sufficient to cover the 8MB of RAM in the Nintendo 64. The remaining lists are for code in ROM, and the bootloader in SP memory. When a write hits a memory page marked as cached, all entries in the corresponding list are invalidated. If any code is found to cross a 4K boundary, the adjacent lists are invalidated also. Sometimes blocks may be invalidated even when none of the code is actually modified. This can happen if data is written to memory in the same 4K page, or if code is reloaded without actually modifying it. If blocks which were previously invalidated are subsequently found to be unmodified, those blocks are marked in the restore_candidate array. If the block remains unmodified, it will be restored as a valid block, to avoid recompiling blocks which do not need to be recompiled. This is performed by the clean_blocks function which is called periodically. The jump_in array, which lists unmodified blocks, is physically indexed, however the jump_dirty array, which lists potentially-modified blocks, is virtually indexed. This allows blocks which have changed physical addresses, but are still at the same virtual address, to be recognized as being the same as before, and not in need of recompilation. ==Dynamic linker== Branches with unresolved addresses jump to the dynamic linker. This will look through the jump_in list corresponding to the physical page containing the virtual target address. If found, the branch instruction will be patched with the address, and then it will jump to this address. If not found, the jump_dirty list will be searched for blocks which were previously compiled but may have been modified. If a potential match is found, the code will be compared against a cached copy to determine if any changes have been made. If not, then it will jump to the block. Because the memory could be modified again, branch instructions referencing these blocks are not altered, and continue to point to the dynamic linker. These blocks will continue to be verified each time they are called, until restored to the jump_in list by the clean_blocks function described above. If no compiled block is found, or the existing block was modified, the target is recompiled. ==Address lookup== When a JR (jump register) instruction is encountered, the address of the recompiled code must be looked up using the address of the MIPS code. The majority of such instructions jump to the link register (r31) to return to the location following a JAL (call) instruction. When a JAL or JALR is executed, the address of the following instruction is inserted into a small 32-entry hash table, which is checked when a JR r31 instruction is executed. This allows for a quick return from subroutine calls. If the JR instruction uses a register other than r31, or the small hash table lookup fails to find a match, a larger 131072-entry hash table is checked. This table contains 65536 bins with up to 2 addresses per bin. If this also fails to find a match (which occurs less than 1% of the time) an exhaustive search of all compiled addresses within that 4K memory page is performed. If no match is found by any of these methods, the target address is compiled, and the new address is inserted into the hash table. ==Cycle counting== Cycles are counted before each branch by adding the cycles from the preceding instructions to a specific register. The cycle count is in R10 on ARM and ESI on x86. The value in this register is normally a negative number. When this number exceeds zero, a conditional branch is taken which jumps to an interrupt handler. For example, the following x86 code adds eight cycles: add $8,%esi jns interrupt_handler The conditional branch jumps to a small bit of code located after the main compiled block, which saves the cached registers to the register file, sets the instruction pointer which will be used upon return from the interrupt, and then calls cc_interrupt. As in the original mupen64plus, the emulated clock runs at 37.5 MHz, and each instruction takes 2 clock cycles. ==Interrupt handler== When the cycle count register reaches its limit, cc_interrupt is called, which in turn calls gen_interupt [sic]. If interrupts are not enabled, cc_interrupt returns. If interrupts are enabled, and an interrupt is to be taken, the pending_exception flag will be set. In this case, cc_interrupt does not return, and instead pops the stack and causes an unconditional jump to the address in pcaddr (usually 0x80000180). There is one additional case where the interrupt handler may be called. If interrupts were disabled, and are enabled by writing to coprocessor 0 register 12, any pending interrupts are handled immediately. ==Delay slots== MIPS has 'delay slots', where the instruction after the branch is executed before the branch is taken. Instructions in delay slots are issued out-of-order in the recompiled code. [[Image:Recompiler delay slot reordering.png]] When a branch jumps into the delay slot of another branch, this case must be handled slightly differently: [[Image:Recompiler delay slot reordering 2.png]] The branch test and delay slot are executed in-order if a dependency exists, or for 'likely' branches where the delay slot is nullified when the branch condition is false. These cases are infrequent (typically less than 10% of branches). ==Constant propagation== When an instruction loads a constant into a register, the register is tagged as a constant. The constant tag will be retained if subsequent instructions modify the constant using other constants. During assembly, such a sequence of instructions is combined into a single load. For example: LUI r8,12340000 --> mov $0x12345678,%eax ORI r8,r8,5678 This optimization is not performed where a branch target intervenes, eg ... LUI r8,12340000 --> mov $0x12340000,%eax L1: ORI r8,r8,5678 --> or $0x5678,%eax ... BEQ r0,r0,L1 Registers containing constants are identified by bits in the isconst and wasconst fields of the regstat structure. The wasconst bit is set for a register if the register contained a known constant before the instruction, and the isconst bit is set for a register if the register will contain a known constant after the instruction executes. ==Translation lookaside buffer emulation== Most Nintendo 64 games do not use virtual memory, but some do. At startup, main memory is directly mapped at addresses from 0x80000000 to 0x803FFFFF, or up to 0x807FFFFF if the memory expansion is used. Normally, read or write operations are checked against this range, and if outside this range, control is passed to the appropriate I/O handler. This is done as follows: MIPS instruction: LW r1,8(r2) ARM code: add r1, r2, #8 cmp r1, #8388608 bvc handler ldr r1, [r1] If there are valid entries in the TLB, this would instead be compiled as follows: add r1, r2, #8 mov r0, #264 add r0, r0, r1, lsr #12 ldr r0, [r11, r0, lsl #2] tst r0, r0 bmi handler ldr r1, [r1, r0, lsl #2] This looks up the offset in the memory_map table (which, in this example, is located at r11+264*4). The high bit is tested to determine whether a valid mapping exists for this page. ==Page fault emulation== If a memory address references an invalid page, a conditional branch is taken to a bit of code placed after the main block. This will save any modified cached registers, and call an appropriate handler function for the address. The handler will either perform I/O, or generate an exception (pagefault). ==Mapping executable pages== If the dynamic recompiler encounters code which is not in contiguous physical memory, it will end the block at the page boundary, so that the block can be removed cleanly if the mapping is changed. There is a special case of this, where a branch and delay slot span two pages. If a branch instruction is the last instruction in a virtual memory page, it is compiled in a different manner than other branches. The branch condition is evaluated, and the target address is placed in a register (%ebp on x86, and r8 on ARM). A special form of the dynamic linker (dyna_linker_ds) is used to link the branch to its corresponding delay slot in another block. If no page fault occurs, the delay slot executes and then jumps to the address in the register. For conditional branches that are not taken, the target address is the next instruction. This code is generated by the pagespan_assemble function. == Self-modifying code detection == Pages not containing code which has been compiled or where the code may have been modified since compilation are marked in the invalid_code array. Writes are checked against this array, and if a write hits a valid (compiled and unmodified) page, invalidate_block is called: MIPS instruction: SW r1,8(r2) ARM code: ldr r3, [r11, #88] // pointer to invalid_code add r4, r2, #8 cmp r4, #8388608 bvc handler str r1, [r4] ldrb r14, [r3, r4 lsr #12] cmp r14, #1 bne invstub In TLB mode, the invalid_code array is not checked directly. Instead, pages are marked non-writable in memory_map. == Long jumps == Branch instructions are limited to a +/-32MB range on ARM. In some cases, the dynamic recompiler needs to generate calls to locations beyond this range. This is accomplished via a jump table located at the end of the code generation area, and the full address is loaded via a pointer. The jump table is generated in arch_init(). As these indirect jumps cause some delay, it is best to avoid this situation if possible, by locating this area close to the other executable code. == Compile options == === ARMv5_ONLY === If this is defined, the UXTH instruction is not used, and the dynamic recompiler will generate literal pools instead of using movw/movt. This provides compatibility with older processors, but generates somewhat less efficient code. === RAM_OFFSET === When compiling for ARM, this allocates an additional register which is used to add an offset to all pointers to memory addresses between 0x80000000 and 0x807FFFFF. This allows the N64's memory to be mapped at an alternate address. This incurs a small performance penalty, but is required for certain operating systems (eg Google Android, which places shared libraries at 0x80000000). This option is not used for x86. The x86 instruction set allows for a full 32-bit offset in the instruction encoding, making it unnecessary to allocate an additional register for this purpose. === CORTEX_A8_BRANCH_PREDICTION_HACK === If this is defined, the dynamic recompiler will avoid generating consecutive branch instructions without another instruction in between. This avoids a possible branch misprediction on the Cortex-A8 due to this processor having dual instruction decoders, but only one branch-prediction unit. See [[Assembly Code Optimization]] for details. === USE_MINI_HT === If this is defined, attempt to look up return addresses in a small hash table before checking the larger hash table. Usually improves performance. === IMM_PREFETCH === If this is defined, the x86 PREFETCH instruction is used to prefetch entries from the hash table. The increase in code size often outweighs the benefit of this. === REG_PREFETCH === Similar to the above, but loads the address into a register first, then uses the ARM PLD instruction. The increase in code size almost always outweighs the benefit of this. === R29_HACK === Assume that the stack pointer (r29) is always a valid memory address and do not check it. It is similar to the optimization described [http://strmnnrmn.blogspot.com/2007/08/interesting-dynarec-hack.html here]. This can crash the emulator and is not enabled by default. == Debugging == Debugging information can be obtained by defining the assem_debug macro as printf. This will cause the dynamic recompiler to print debugging information to stdout. For each disassembled MIPS instruction, an entry similar to the following will be printed: U: r1 r8 r11 r16 r31 UU: r29 32: r0 r9 pre: eax=-1 ecx=9 edx=-1 ebx=-1 ebp=29 esi=36 edi=-1 needs: ecx ebp esi r: r9 entry: eax=-1 ecx=9 edx=-1 ebx=-1 ebp=29 esi=36 edi=-1 dirty: ecx ebp esi 800001d8: LW r16,r29+14 eax=16 ecx=9 edx=-1 ebx=-1 ebp=29 esi=36 edi=-1 dirty: eax ecx ebp esi 32: r0 r9 r16 U: A list of MIPS registers which will not be used before they are overwritten (liveness analysis) UU: A list of MIPS registers for which the upper 32 bits will not be used before they are overwritten 32: Registers that contain 32-bit sign-extended values pre: The state of the register mapping prior to execution of this instruction. (-1 = no mapping; 36 = cycle count; The complete list of values with special meanings can be found in the source code) needs: a list of register mappings that were considered necessary and which could not be eliminated to make room for other mappings r: Registers that are known to contain 32-bit values and where optimizations rely on the assumption that the register does not contain a value outside of the range -231 to 231-1 entry: The minimum set of register mappings required to jump to this point dirty: Cached registers that have been modified and will need to be written back address: instruction - The decoded opcode, followed by the register mapping in effect after this instruction executes An asterisk (*) designates locations which are the target of a branch instruction. Constant propagation will not be performed across these points. After the complete disassembly, the recompiled native code is shown. Note that the output can be quite voluminous; 20-30 MB is typical. ==Potential improvements== ===Copy propagation/offset propagation=== A common instruction sequence is of the form: LUI r9,12340000 ADD r9,r9,r8 LW r9,5678(r9) It would be helpful to recognize this as a load from r8+12345678. The current constant propagation code does not do so. ===Constant propagation and register assignment=== Constant propagation is currently done after register assignment. Registers are assigned even if the register will always contain a known value. In certain cases, such as where the constant is used only to generate a memory address, this could be avoided and no register would need to be allocated. ===Unaligned memory access=== A small improvement could be made by combining adjacent LWL/LWR instructions. The potential gain from doing so is very limited because these instructions typically represent less than 1% of all memory accesses. ===SLT/branch merging=== A frequent occurrence in MIPS code is an SLT or SLTI instruction followed by a branch. This is generated relatively inefficiently on x86 and ARM, first doing a compare and set, then testing this value and doing a conditional branch. Doing only one comparison would save at least one instruction, and could potentially save up to three instructions if the liveness analysis reveals that the result of the SLT instruction is used nowhere else. While a potentially useful optimization, there are several problems with this approach. First, there are often additional instructions between the slt and the branch. These must be checked to make sure they do not modify the registers as that would prevent reordering the instruction stream as desired. Secondly, if the result of the slt is found to be live, but unmodified, on both paths of the branch, clean_registers will normally write this value before the branch, to avoid duplicating the writeback code on both paths of the branch. This optimization would have to be removed if the slt was combined with the branch. ===x86-64=== Currently the x86-64 backend generates only 32-bit instructions. Proper 64-bit code generation would improve performance. ===PowerPC=== It would be possible to add a PowerPC code generator to the dynamic recompiler. Currently no one is working on this. (The mupen64gc project is using a different codebase.) The following is a summary of the changes which would be necessary to add a PowerPC backend. The slt* instructions use conditional moves, which are unavailable on PowerPC. A suitable alternative (such as moves from the condition register) would need to be used. The assembler can generate as much as 256K of code in a single block, however conditional branches on PowerPC are limited to +/-64K. It will be necessary to either restrict the block size, or insert jump tables in a manner similar to the literal pools on ARM. PowerPC generally relies on early branch resolution rather than statistical branch prediction. Scheduling branch condition tests earlier may be advantageous. (For example, the address bounds check could be done in address_generation, rather than just before the load or store. Similarly it may be advantageous to test the branch condition and update the cycle count before executing the delay slot.) ===MIPS=== Recompiling MIPS into MIPS would be relatively straightforward, however the current code generator has no facility for filling delay slots. This capability would be required for efficient code generation. [[Category:Emulators]] [[Category:Optimization]] [[Category:Development]] jni/000700 001750 001750 00000000000 12656647145 012466 5ustar00sergiosergio000000 000000 gles2rice/src/DeviceBuilder.cpp000664 001750 001750 00000012754 12655644434 017610 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include // < __LIBRETRO__: Needed for exit() #include "osal_opengl.h" #include "DeviceBuilder.h" #include "FrameBuffer.h" #include "OGLCombiner.h" #include "OGLDebug.h" #include "OGLExtRender.h" #include "OGLGraphicsContext.h" #include "OGLTexture.h" #include "OGLES2FragmentShaders.h" //======================================================================== CDeviceBuilder* CDeviceBuilder::m_pInstance=NULL; SupportedDeviceType CDeviceBuilder::m_deviceType = DIRECTX_DEVICE; SupportedDeviceType CDeviceBuilder::m_deviceGeneralType = DIRECTX_DEVICE; CDeviceBuilder* CDeviceBuilder::GetBuilder(void) { if( m_pInstance == NULL ) CreateBuilder(m_deviceType); return m_pInstance; } void CDeviceBuilder::SelectDeviceType(SupportedDeviceType type) { if( type != m_deviceType && m_pInstance != NULL ) { DeleteBuilder(); } CDeviceBuilder::m_deviceType = type; switch(type) { case OGL_DEVICE: case OGL_1_1_DEVICE: case OGL_1_2_DEVICE: case OGL_1_3_DEVICE: case OGL_1_4_DEVICE: case OGL_TNT2_DEVICE: case NVIDIA_OGL_DEVICE: case OGL_FRAGMENT_PROGRAM: CDeviceBuilder::m_deviceGeneralType = OGL_DEVICE; break; default: break; } } SupportedDeviceType CDeviceBuilder::GetDeviceType(void) { return CDeviceBuilder::m_deviceType; } SupportedDeviceType CDeviceBuilder::GetGeneralDeviceType(void) { return CDeviceBuilder::m_deviceGeneralType; } CDeviceBuilder* CDeviceBuilder::CreateBuilder(SupportedDeviceType type) { if( m_pInstance == NULL ) { switch( type ) { case OGL_DEVICE: case OGL_1_1_DEVICE: case OGL_1_2_DEVICE: case OGL_1_3_DEVICE: case OGL_1_4_DEVICE: case OGL_TNT2_DEVICE: case NVIDIA_OGL_DEVICE: case OGL_FRAGMENT_PROGRAM: m_pInstance = new OGLDeviceBuilder(); break; default: DebugMessage(M64MSG_ERROR, "CreateBuilder: unknown OGL device type"); exit(1); } } return m_pInstance; } void CDeviceBuilder::DeleteBuilder(void) { delete m_pInstance; m_pInstance = NULL; } CDeviceBuilder::CDeviceBuilder() : m_pRender(NULL), m_pGraphicsContext(NULL), m_pColorCombiner(NULL), m_pAlphaBlender(NULL) { } CDeviceBuilder::~CDeviceBuilder() { DeleteGraphicsContext(); DeleteRender(); DeleteColorCombiner(); DeleteAlphaBlender(); } void CDeviceBuilder::DeleteGraphicsContext(void) { if( m_pGraphicsContext != NULL ) { delete m_pGraphicsContext; CGraphicsContext::g_pGraphicsContext = m_pGraphicsContext = NULL; } SAFE_DELETE(g_pFrameBufferManager); } void CDeviceBuilder::DeleteRender(void) { if( m_pRender != NULL ) { delete m_pRender; CRender::g_pRender = m_pRender = NULL; CRender::gRenderReferenceCount = 0; } } void CDeviceBuilder::DeleteColorCombiner(void) { if( m_pColorCombiner != NULL ) { delete m_pColorCombiner; m_pColorCombiner = NULL; } } void CDeviceBuilder::DeleteAlphaBlender(void) { if( m_pAlphaBlender != NULL ) { delete m_pAlphaBlender; m_pAlphaBlender = NULL; } } //======================================================================== CGraphicsContext * OGLDeviceBuilder::CreateGraphicsContext(void) { if( m_pGraphicsContext == NULL ) { m_pGraphicsContext = new COGLGraphicsContext(); CGraphicsContext::g_pGraphicsContext = m_pGraphicsContext; } g_pFrameBufferManager = new FrameBufferManager; return m_pGraphicsContext; } CRender * OGLDeviceBuilder::CreateRender(void) { if( m_pRender == NULL ) { COGLGraphicsContext &context = *((COGLGraphicsContext*)CGraphicsContext::g_pGraphicsContext); m_pRender = new COGLExtRender(); CRender::g_pRender = m_pRender; } return m_pRender; } CTexture * OGLDeviceBuilder::CreateTexture(uint32_t dwWidth, uint32_t dwHeight, TextureUsage usage) { COGLTexture *txtr = new COGLTexture(dwWidth, dwHeight, usage); if( txtr->m_pTexture == NULL ) { delete txtr; TRACE0("Cannot create new texture, out of video memory"); return NULL; } else return txtr; } CColorCombiner * OGLDeviceBuilder::CreateColorCombiner(CRender *pRender) { if( m_pColorCombiner == NULL ) { m_deviceType = (SupportedDeviceType)options.OpenglRenderSetting; m_pColorCombiner = new COGL_FragmentProgramCombiner(pRender); DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Fragment Program"); } return m_pColorCombiner; } CBlender * OGLDeviceBuilder::CreateAlphaBlender(CRender *pRender) { if( m_pAlphaBlender == NULL ) { m_pAlphaBlender = new COGLBlender(pRender); } return m_pAlphaBlender; } libretro-common/libco/000700 001750 001750 00000000000 12656647145 016106 5ustar00sergiosergio000000 000000 gles2n64/src/COPYING000664 001750 001750 00000017220 12655644434 015107 0ustar00sergiosergio000000 000000 This directory contains the source code of gles2n64 ported to Android by yongzh (freeman.yong@gmail.com). The original source code is available at: http://code.google.com/p/gles2n64/ GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. gles2n64/src/Textures.h000664 001750 001750 00000004203 12655644434 016045 0ustar00sergiosergio000000 000000 #ifndef TEXTURES_H #define TEXTURES_H #ifdef __LIBRETRO__ // Use SDL_opengles2.h instead of GLES2/gl2.h #include #else #include #endif #include "convert.h" #ifdef __cplusplus extern "C" { #endif typedef u32 (*GetTexelFunc)( u64 *src, u16 x, u16 i, u8 palette ); typedef struct CachedTexture { GLuint glName; u32 address; u32 crc; float offsetS, offsetT; u32 maskS, maskT; u32 clampS, clampT; u32 mirrorS, mirrorT; u32 line; u32 size; u32 format; u32 tMem; u32 palette; u32 width, height; // N64 width and height u32 clampWidth, clampHeight; // Size to clamp to u32 realWidth, realHeight; // Actual texture size f32 scaleS, scaleT; // Scale to map to 0.0-1.0 f32 shiftScaleS, shiftScaleT; // Scale to shift u32 textureBytes; struct CachedTexture *lower, *higher; u32 lastDList; u8 max_level; u8 frameBufferTexture; } CachedTexture; #define TEXTURECACHE_MAX (8 * 1024 * 1024) #define TEXTUREBUFFER_SIZE (512 * 1024) typedef struct TextureCache { CachedTexture *current[2]; CachedTexture *bottom, *top; CachedTexture *dummy; u32 cachedBytes; u32 numCached; u32 hits, misses; GLuint glNoiseNames[32]; } TextureCache; extern TextureCache cache; static INLINE u32 pow2( u32 dim ) { u32 i = 1; while (i < dim) i <<= 1; return i; } static INLINE u32 powof( u32 dim ) { u32 num, i; num = 1; i = 0; while (num < dim) { num <<= 1; i++; } return i; } CachedTexture *TextureCache_AddTop(); void TextureCache_MoveToTop( CachedTexture *newtop ); void TextureCache_Remove( CachedTexture *texture ); void TextureCache_RemoveBottom(); void TextureCache_Init(); void TextureCache_Destroy(); void TextureCache_Update( u32 t ); void TextureCache_ActivateTexture( u32 t, CachedTexture *texture ); void TextureCache_ActivateNoise( u32 t ); void TextureCache_ActivateDummy( u32 t ); bool TextureCache_Verify(); #ifdef __cplusplus } #endif #endif tools/Makefile000664 001750 001750 00000000766 12655644434 014530 0ustar00sergiosergio000000 000000 binext := ifeq ($(platform),win32) binext := .exe static := 1 endif ifeq ($(static),1) lflags += -static-libgcc -static endif cflags += -O2 -g -Wall $(extracflags) lflags += libs += -lm bins += pj64tosrm$(binext) m64pmigrate$(binext) .PHONY: all clean all: $(bins) clean: -rm -f $(bins) pj64tosrm$(binext): pj64tosrm.c $(CC) $(cflags) -o$@ $(lflags) $< $(libs) m64pmigrate$(binext): m64pmigrate.c $(CC) $(cflags) -o$@ $(lflags) $< $(libs) %.o: %.c $(CC) $(cflags) -c -o $@ $< gles2n64/src/Debug.h000664 001750 001750 00000001437 12655644434 015256 0ustar00sergiosergio000000 000000 #if !defined( DEBUG_H ) && defined( DEBUG ) #define DEBUG_H #include #define DEBUG_LOW 0x1000 #define DEBUG_MEDIUM 0x2000 #define DEBUG_HIGH 0x4000 #define DEBUG_DETAIL 0x8000 #define DEBUG_HANDLED 0x0001 #define DEBUG_UNHANDLED 0x0002 #define DEBUG_IGNORED 0x0004 #define DEBUG_UNKNOWN 0x0008 #define DEBUG_ERROR 0x0010 #define DEBUG_COMBINE 0x0020 #define DEBUG_TEXTURE 0x0040 #define DEBUG_VERTEX 0x0080 #define DEBUG_TRIANGLE 0x0100 #define DEBUG_MATRIX 0x0200 #define OpenDebugDlg() #define CloseDebugDlg() #define StartDump(filename) #define EndDump() #define DebugMsg(type, format, ... ) printf(format, ## __VA_ARGS__) #define DebugRSPState(pci, pc, cmd, w0, w1) #endif // DEBUG_H mupen64plus-core/doc/emuwiki-api-doc/Mupen64Plus_v2.0_Design_Proposal_3.txt000664 001750 001750 00000011724 12655644434 027607 0ustar00sergiosergio000000 000000 [http://mupen64plus.retrouprising.com Project page] == Primary Goal == The primary goal of this re-architecture is to split this large project into smaller projects which may proceed to be developed independently of each other. The advantages of the new architecture are: * The build system can be greatly simplified * Each module can use its own build system. For example, the Qt GUI might switch to cmake for better Qt integration. * Porting the emulator core to other platforms (namely Win32) will be greatly simplified by removing the most platform-specific pieces. * Making releases for each package will be simpler and faster * Mupen64Plus may be included into the Debian/Ubuntu repositories since glN64 (with its 'unknown' license) will be a separate project == Topography == This re-architecture will force us to lay boundaries with well-defined APIs between different parts of the emulator. Here are some initial suggestions for the new layout of the modules: # Mupen64plus-core #* To simplify porting to other platforms, the core needs to be as lean as possible #* For this reason, the GUI interfaces, the ROM cache, and the zip/lzma/7zip decompressors will be removed #* The core will contain the code for: #** Emulating the R4300 main CPU and memory systems #** Loading and configuring plugins #** Reading, parsing, and writing all configuration files for the core + plugins #** Parsing and returning information about ROM images #** Core user interface for keyboard and LIRC input #** Savestates and screenshots #** An on-screen display #** Cheat and debugger core functions #** 'Dummy' plugins # Mupen64plus-console, Mupen64plus-gtk, Mupen64plus-qt #* Command-line only, GTK, and Qt front-end interfaces #* Each front-end for the core library will be a separate project #* The ROM cache code will be forked and included into both GUIs #* The front-ends will be responsible for finding and loading the core library and the plugins #* The dynamic library handle of the core will be passed to all the plugins, and the dynamic library handle of the plugins will be passed to the core #* The front-ends will be responsible for loading and decompressing the ROM image, and passing a pointer to the core # Plugins (RiceVideo, glN64, glide64, Blight Input, JTTL Audio) #* The plugins will be spun off into separate projects #* The plugin API will change, and will be incompatible with the old Zilmar spec == Project Owners == Richard42 will retain ownership of the Mupen64plus-core and Mupen64plus-console modules. I will recommend that Slougi take ownership of the Qt GUI. The plugins and GTK GUI are up for grabs. == Work To Do == Tasks which have been completed will be marked with the strikethrough format. === Prior to starting on the code === # Write design document for Core API #* Front-end + debugger + cheat #* Configuration interface #* Video plugin #* Audio plugin #* Input plugin #* RSP plugin # Set up new Mercurial repository for project === Coding tasks === # First steps #* Split & fork the source files into new structure # Core #* Refactor/simplify makefiles #* Remove #include statements from header files #* Write new configuration load/parse/save functionality #* Separate event loop out of main.c into new source file #* Fix broken WM_KeyDown/WM_KeyUp commands sent to input plugin #* Remove main() function #* Remove main/winlnxdefs.h #* Add new shared library interface (Must be thread-safe and re-entrant where necessary) #** api/callbacks.c #** api/common.c #** api/config.c #** api/debugger.c #** api/frontend.c #** api/vidext.c #* Refactor core code for new debug info interface (instead of printf(), send back to front-end) #* Modify plugin-handling code to use new plugin API #* Fix 64-bit dynamic recompiler for dynamic lib #* Update translate.c file handling and translations #* Update cheat.c cheat code handling #* Remove compare_core.c, add core comparison feature to console-ui #* Generate versioned core library #* Simplify makefile / pre.mk #* Refactor install.sh #* Go through google code issue list, apply patches and close issue reports # Front-ends #* Refactor/simplify makefiles ## CLI ##* Write from scratch, based on main.c ##* Update man page ## GUI-Qt ##* Adapt from previous mupen64puls Qt GUI code, pulling code from CLI front-end (Slougi) ## GUI-GTK ##* Adapt from previous mupen64puls GTK GUI code, pulling code from CLI front-end (TBD) # Plug-ins #* For each plug-in: #** m64p-rsp-hle #** m64p-audio-sdl #** m64p-video-rice #** m64p-input-sdl #* Remove existing configuration read/write code #* Add Deadzone and Scaling parameters to Blight Input plugin #* Refactor to use new configuration interface through core library #* Refactor for changes in core plugin API #* Refactor for new debug info interface (instead of printf(), send back to front-end) mupen64plus-core/src/si/game_controller.h000664 001750 001750 00000004354 12655644434 021604 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - game_controller.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_SI_GAME_CONTROLLER_H #define M64P_SI_GAME_CONTROLLER_H #include #include "mempak.h" #include "rumblepak.h" enum pak_type { PAK_NONE, PAK_MEM, PAK_RUMBLE, PAK_TRANSFER }; struct game_controller { /* external controller input */ void* user_data; int (*is_connected)(void*,enum pak_type*); uint32_t (*get_input)(void*); struct mempak mempak; struct rumblepak rumblepak; }; int game_controller_is_connected(struct game_controller* cont, enum pak_type* pak); uint32_t game_controller_get_input(struct game_controller* cont); void process_controller_command(struct game_controller* cont, uint8_t* cmd); void read_controller(struct game_controller* cont, uint8_t* cmd); #endif gles2n64/src/Textures.c000664 001750 001750 00000136666 12655644434 016063 0ustar00sergiosergio000000 000000 #include #include #include #include "Common.h" #include "Config.h" #include "OpenGL.h" #include "Textures.h" #include "GBI.h" #include "RSP.h" #include "gDP.h" #include "gSP.h" #include "N64.h" #include "CRC.h" #include "convert.h" #include "FrameBuffer.h" #define FORMAT_NONE 0 #define FORMAT_I8 1 #define FORMAT_IA88 2 #define FORMAT_RGBA4444 3 #define FORMAT_RGBA5551 4 #define FORMAT_RGBA8888 5 #ifdef __GNUC__ # define likely(x) __builtin_expect((x),1) # define unlikely(x) __builtin_expect((x),0) # define prefetch(x, y) __builtin_prefetch((x),(y)) #else # define likely(x) (x) # define unlikely(x) (x) # define prefetch(x, y) #endif TextureCache cache; static INLINE u32 GetNone( u64 *src, u16 x, u16 i, u8 palette ) { return 0x00000000; } static INLINE u32 GetCI4IA_RGBA4444( u64 *src, u16 x, u16 i, u8 palette ) { u8 color4B; color4B = ((u8*)src)[(x>>1)^(i<<1)]; if (x & 1) return IA88_RGBA4444( *(u16*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] ); else return IA88_RGBA4444( *(u16*)&TMEM[256 + (palette << 4) + (color4B >> 4)] ); } static INLINE u32 GetCI4IA_RGBA8888( u64 *src, u16 x, u16 i, u8 palette ) { u8 color4B; color4B = ((u8*)src)[(x>>1)^(i<<1)]; if (x & 1) return IA88_RGBA8888( *(u16*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] ); else return IA88_RGBA8888( *(u16*)&TMEM[256 + (palette << 4) + (color4B >> 4)] ); } static INLINE u32 GetCI4RGBA_RGBA5551( u64 *src, u16 x, u16 i, u8 palette ) { u8 color4B; color4B = ((u8*)src)[(x>>1)^(i<<1)]; if (x & 1) return RGBA5551_RGBA5551( *(u16*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] ); else return RGBA5551_RGBA5551( *(u16*)&TMEM[256 + (palette << 4) + (color4B >> 4)] ); } static INLINE u32 GetCI4RGBA_RGBA8888( u64 *src, u16 x, u16 i, u8 palette ) { u8 color4B; color4B = ((u8*)src)[(x>>1)^(i<<1)]; if (x & 1) return RGBA5551_RGBA8888( *(u16*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] ); else return RGBA5551_RGBA8888( *(u16*)&TMEM[256 + (palette << 4) + (color4B >> 4)] ); } static INLINE u32 GetIA31_RGBA8888( u64 *src, u16 x, u16 i, u8 palette ) { u8 color4B; color4B = ((u8*)src)[(x>>1)^(i<<1)]; return IA31_RGBA8888( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) ); } static INLINE u32 GetIA31_RGBA4444( u64 *src, u16 x, u16 i, u8 palette ) { u8 color4B; color4B = ((u8*)src)[(x>>1)^(i<<1)]; return IA31_RGBA4444( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) ); } static INLINE u32 GetI4_RGBA8888( u64 *src, u16 x, u16 i, u8 palette ) { u8 color4B; color4B = ((u8*)src)[(x>>1)^(i<<1)]; return I4_RGBA8888( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) ); } static INLINE u32 GetI4_RGBA4444( u64 *src, u16 x, u16 i, u8 palette ) { u8 color4B; color4B = ((u8*)src)[(x>>1)^(i<<1)]; return I4_RGBA4444( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) ); } static INLINE u32 GetCI8IA_RGBA4444( u64 *src, u16 x, u16 i, u8 palette ) { return IA88_RGBA4444( *(u16*)&TMEM[256 + ((u8*)src)[x^(i<<1)]] ); } static INLINE u32 GetCI8IA_RGBA8888( u64 *src, u16 x, u16 i, u8 palette ) { return IA88_RGBA8888( *(u16*)&TMEM[256 + ((u8*)src)[x^(i<<1)]] ); } static INLINE u32 GetCI8RGBA_RGBA5551( u64 *src, u16 x, u16 i, u8 palette ) { return RGBA5551_RGBA5551( *(u16*)&TMEM[256 + ((u8*)src)[x^(i<<1)]] ); } static INLINE u32 GetCI8RGBA_RGBA8888( u64 *src, u16 x, u16 i, u8 palette ) { return RGBA5551_RGBA8888( *(u16*)&TMEM[256 + ((u8*)src)[x^(i<<1)]] ); } static INLINE u32 GetIA44_RGBA8888( u64 *src, u16 x, u16 i, u8 palette ) { return IA44_RGBA8888(((u8*)src)[x^(i<<1)]); } static INLINE u32 GetIA44_RGBA4444( u64 *src, u16 x, u16 i, u8 palette ) { return IA44_RGBA4444(((u8*)src)[x^(i<<1)]); } static INLINE u32 GetI8_RGBA8888( u64 *src, u16 x, u16 i, u8 palette ) { return I8_RGBA8888(((u8*)src)[x^(i<<1)]); } static INLINE u32 GetI8_RGBA4444( u64 *src, u16 x, u16 i, u8 palette ) { return I8_RGBA4444(((u8*)src)[x^(i<<1)]); } static INLINE u32 GetCI16IA_RGBA8888(u64 *src, u16 x, u16 i, u8 palette) { const u16 tex = ((u16*)src)[x^i]; const u16 col = (*(u16*)&TMEM[256 + (tex >> 8)]); const u16 c = col >> 8; const u16 a = col & 0xFF; return (a << 24) | (c << 16) | (c << 8) | c; } static INLINE u32 GetCI16IA_RGBA4444(u64 *src, u16 x, u16 i, u8 palette) { const u16 tex = ((u16*)src)[x^i]; const u16 col = (*(u16*)&TMEM[256 + (tex >> 8)]); const u16 c = col >> 12; const u16 a = col & 0x0F; return (a << 12) | (c << 8) | (c << 4) | c; } static INLINE u32 GetCI16RGBA_RGBA8888(u64 *src, u16 x, u16 i, u8 palette) { const u16 tex = ((u16*)src)[x^i]; return RGBA5551_RGBA8888(*(u16*)&TMEM[256 + (tex >> 8)]); } static INLINE u32 GetCI16RGBA_RGBA5551(u64 *src, u16 x, u16 i, u8 palette) { const u16 tex = ((u16*)src)[x^i]; return RGBA5551_RGBA5551(*(u16*)&TMEM[256 + (tex >> 8)]); } static INLINE u32 GetRGBA5551_RGBA8888(u64 *src, u16 x, u16 i, u8 palette) { u16 tex = ((u16*)src)[x^i]; return RGBA5551_RGBA8888(tex); } static INLINE u32 GetRGBA5551_RGBA5551( u64 *src, u16 x, u16 i, u8 palette ) { u16 tex = ((u16*)src)[x^i]; return RGBA5551_RGBA5551(tex); } static INLINE u32 GetIA88_RGBA8888( u64 *src, u16 x, u16 i, u8 palette ) { return IA88_RGBA8888(((u16*)src)[x^i]); } static INLINE u32 GetIA88_RGBA4444( u64 *src, u16 x, u16 i, u8 palette ) { return IA88_RGBA4444(((u16*)src)[x^i]); } static INLINE u32 GetRGBA8888_RGBA8888( u64 *src, u16 x, u16 i, u8 palette ) { return ((u32*)src)[x^i]; } static INLINE u32 GetRGBA8888_RGBA4444( u64 *src, u16 x, u16 i, u8 palette ) { return RGBA8888_RGBA4444(((u32*)src)[x^i]); } u32 YUV_RGBA8888(u8 y, u8 u, u8 v) { s32 r = (s32)(y + (1.370705f * (v - 128))); s32 g = (s32)((y - (0.698001f * (v - 128)) - (0.337633f * (u - 128)))); s32 b = (s32)(y + (1.732446f * (u - 128))); //clipping the result if (r > 255) r = 255; if (g > 255) g = 255; if (b > 255) b = 255; if (r < 0) r = 0; if (g < 0) g = 0; if (b < 0) b = 0; return (0xff << 24) | (b << 16) | (g << 8) | r; } u16 YUV_RGBA4444(u8 y, u8 u, u8 v) { return RGBA8888_RGBA4444(YUV_RGBA8888(y, u, v)); } static INLINE void GetYUV_RGBA8888(u64 * src, u32 * dst, u16 x) { const u32 t = (((u32*)src)[x]); u8 y1 = (u8)t & 0xFF; u8 v = (u8)(t >> 8) & 0xFF; u8 y0 = (u8)(t >> 16) & 0xFF; u8 u = (u8)(t >> 24) & 0xFF; u32 c = YUV_RGBA8888(y0, u, v); *(dst++) = c; c = YUV_RGBA8888(y1, u, v); *(dst++) = c; } static INLINE void GetYUV_RGBA4444(u64 * src, u16 * dst, u16 x) { const u32 t = (((u32*)src)[x]); u8 y1 = (u8)t & 0xFF; u8 v = (u8)(t >> 8) & 0xFF; u8 y0 = (u8)(t >> 16) & 0xFF; u8 u = (u8)(t >> 24) & 0xFF; u16 c = YUV_RGBA4444(y0, u, v); *(dst++) = c; c = YUV_RGBA4444(y1, u, v); *(dst++) = c; } const struct TextureLoadParameters { GetTexelFunc Get16; GLenum glType16; GLint glInternalFormat16; GetTexelFunc Get32; GLenum glType32; GLint glInternalFormat32; u32 autoFormat, lineShift, maxTexels; } imageFormat[4][4][5] = { // G_TT_NONE { // Get16 glType16 glInternalFormat16 Get32 glType32 glInternalFormat32 autoFormat { // 4-bit { GetI4_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetI4_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 4, 8192 }, // RGBA as I { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 4, 8192 }, // YUV { GetI4_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetI4_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 4, 8192 }, // CI without palette { GetIA31_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetIA31_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 4, 8192 }, // IA { GetI4_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetI4_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 4, 8192 }, // I }, { // 8-bit { GetI8_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetI8_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA, 3, 4096 }, // RGBA as I { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 4096 }, // YUV { GetI8_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetI8_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA, 3, 4096 }, // CI without palette { GetIA44_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetIA44_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 3, 4096 }, // IA { GetI8_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetI8_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA, 3, 4096 }, // I }, { // 16-bit { GetRGBA5551_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetRGBA5551_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 2, 2048 }, // RGBA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 2, 2048 }, // YUV { GetIA88_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetIA88_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA, 2, 2048 }, // CI as IA { GetIA88_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetIA88_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA, 2, 2048 }, // IA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 2048 }, // I }, { // 32-bit { GetRGBA8888_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetRGBA8888_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA, 2, 1024 }, // RGBA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // YUV { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // CI { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // IA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // I } }, // DUMMY { // Get16 glType16 glInternalFormat16 Get32 glType32 glInternalFormat32 autoFormat { // 4-bit { GetCI4RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI4RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 4, 4096 }, // CI (Banjo-Kazooie uses this, doesn't make sense, but it works...) { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 4, 8192 }, // YUV { GetCI4RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI4RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 4, 4096 }, // CI { GetCI4RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI4RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 4, 4096 }, // IA as CI { GetCI4RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI4RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 4, 4096 }, // I as CI }, { // 8-bit { GetCI8RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI8RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 3, 2048 }, // RGBA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 4096 }, // YUV { GetCI8RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI8RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 3, 2048 }, // CI { GetCI8RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI8RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 3, 2048 }, // IA as CI { GetCI8RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI8RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 3, 2048 }, // I as CI }, { // 16-bit { GetCI16RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetRGBA5551_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 2, 2048 }, // RGBA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 2, 2048 }, // YUV { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 2048 }, // CI { GetCI16RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI16RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 2, 2048 }, // IA as CI { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 2048 }, // I }, { // 32-bit { GetRGBA8888_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetRGBA8888_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA, 2, 1024 }, // RGBA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // YUV { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // CI { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // IA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // I } }, // G_TT_RGBA16 { // Get16 glType16 glInternalFormat16 Get32 glType32 glInternalFormat32 autoFormat { // 4-bit { GetCI4RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI4RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 4, 4096 }, // CI (Banjo-Kazooie uses this, doesn't make sense, but it works...) { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 4, 8192 }, // YUV { GetCI4RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI4RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 4, 4096 }, // CI { GetCI4RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI4RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 4, 4096 }, // IA as CI { GetCI4RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI4RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 4, 4096 }, // I as CI }, { // 8-bit { GetCI8RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI8RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 3, 2048 }, // RGBA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 4096 }, // YUV { GetCI8RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI8RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 3, 2048 }, // CI { GetCI8RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI8RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 3, 2048 }, // IA as CI { GetCI8RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI8RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 3, 2048 }, // I as CI }, { // 16-bit { GetCI16RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetRGBA5551_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 2, 2048 }, // RGBA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 2, 2048 }, // YUV { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 2048 }, // CI { GetCI16RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, GetCI16RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGB5_A1, 2, 2048 }, // IA as CI { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 2048 }, // I }, { // 32-bit { GetRGBA8888_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetRGBA8888_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA, 2, 1024 }, // RGBA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // YUV { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // CI { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // IA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // I } }, // G_TT_IA16 { // Get16 glType16 glInternalFormat16 Get32 glType32 glInternalFormat32 autoFormat { // 4-bit { GetCI4IA_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetCI4IA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 4, 4096 }, // IA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 4, 8192 }, // YUV { GetCI4IA_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetCI4IA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 4, 4096 }, // CI { GetCI4IA_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetCI4IA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 4, 4096 }, // IA as CI { GetCI4IA_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetCI4IA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 4, 4096 }, // I as CI }, { // 8-bit { GetCI8IA_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetCI8IA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 3, 2048 }, // RGBA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 4096 }, // YUV { GetCI8IA_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetCI8IA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 3, 2048 }, // CI { GetCI8IA_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetCI8IA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 3, 2048 }, // IA as CI { GetCI8IA_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetCI8IA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 3, 2048 }, // I as CI }, { // 16-bit { GetCI16IA_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetCI16IA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA, 2, 2048 }, // RGBA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 2, 2048 }, // YUV { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 2048 }, // CI { GetCI16IA_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetCI16IA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA, 2, 2048 }, // IA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 2048 }, // I }, { // 32-bit { GetRGBA8888_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetRGBA8888_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA, 2, 1024 }, // RGBA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // YUV { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // CI { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // IA { GetNone, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA4, 0, 1024 }, // I } } }; int isTexCacheInit = 0; void TextureCache_Init(void) { int x, y, i; u8 noise[64*64*2]; u32 dummyTexture[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; isTexCacheInit = 1; cache.current[0] = NULL; cache.current[1] = NULL; cache.top = NULL; cache.bottom = NULL; cache.numCached = 0; cache.cachedBytes = 0; glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glGenTextures( 32, cache.glNoiseNames ); srand((unsigned)time(NULL)); for (i = 0; i < 32; i++) { glBindTexture( GL_TEXTURE_2D, cache.glNoiseNames[i] ); for (y = 0; y < 64; y++) { for (x = 0; x < 64; x++) { u32 r = rand() & 0xFF; noise[y*64*2+x*2] = r; noise[y*64*2+x*2+1] = r; } } glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 64, 64, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, noise); } cache.dummy = TextureCache_AddTop(); cache.dummy->address = 0; cache.dummy->clampS = 1; cache.dummy->clampT = 1; cache.dummy->clampWidth = 2; cache.dummy->clampHeight = 2; cache.dummy->crc = 0; cache.dummy->format = 0; cache.dummy->size = 0; cache.dummy->frameBufferTexture = false; cache.dummy->width = 2; cache.dummy->height = 2; cache.dummy->realWidth = 2; cache.dummy->realHeight = 2; cache.dummy->maskS = 0; cache.dummy->maskT = 0; cache.dummy->scaleS = 0.5f; cache.dummy->scaleT = 0.5f; cache.dummy->shiftScaleS = 1.0f; cache.dummy->shiftScaleT = 1.0f; cache.dummy->textureBytes = 2 * 2 * 4; cache.dummy->tMem = 0; glBindTexture( GL_TEXTURE_2D, cache.dummy->glName ); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, dummyTexture); cache.cachedBytes = cache.dummy->textureBytes; TextureCache_ActivateDummy(0); TextureCache_ActivateDummy(1); CRC_BuildTable(); } bool TextureCache_Verify(void) { u16 i; CachedTexture *current; i = 0; current = cache.top; while (current) { i++; current = current->lower; } if (i != cache.numCached) return false; i = 0; current = cache.bottom; while (current) { i++; current = current->higher; } if (i != cache.numCached) return false; return true; } void TextureCache_RemoveBottom(void) { CachedTexture *newBottom = cache.bottom->higher; glDeleteTextures( 1, &cache.bottom->glName ); cache.cachedBytes -= cache.bottom->textureBytes; if (cache.bottom == cache.top) cache.top = NULL; free( cache.bottom ); cache.bottom = newBottom; if (cache.bottom) cache.bottom->lower = NULL; cache.numCached--; } void TextureCache_Remove( CachedTexture *texture ) { if ((texture == cache.bottom) && (texture == cache.top)) { cache.top = NULL; cache.bottom = NULL; } else if (texture == cache.bottom) { cache.bottom = texture->higher; if (cache.bottom) cache.bottom->lower = NULL; } else if (texture == cache.top) { cache.top = texture->lower; if (cache.top) cache.top->higher = NULL; } else { texture->higher->lower = texture->lower; texture->lower->higher = texture->higher; } glDeleteTextures( 1, &texture->glName ); cache.cachedBytes -= texture->textureBytes; free( texture ); cache.numCached--; } CachedTexture *TextureCache_AddTop(void) { CachedTexture *newtop; while (cache.cachedBytes > TEXTURECACHE_MAX) { if (cache.bottom != cache.dummy) TextureCache_RemoveBottom(); else if (cache.dummy->higher) TextureCache_Remove( cache.dummy->higher ); } newtop = (CachedTexture*)malloc( sizeof( CachedTexture ) ); glGenTextures( 1, &newtop->glName ); newtop->lower = cache.top; newtop->higher = NULL; if (cache.top) cache.top->higher = newtop; if (!cache.bottom) cache.bottom = newtop; cache.top = newtop; cache.numCached++; return newtop; } void TextureCache_MoveToTop( CachedTexture *newtop ) { if (newtop == cache.top) return; if (newtop == cache.bottom) { cache.bottom = newtop->higher; cache.bottom->lower = NULL; } else { newtop->higher->lower = newtop->lower; newtop->lower->higher = newtop->higher; } newtop->higher = NULL; newtop->lower = cache.top; cache.top->higher = newtop; cache.top = newtop; } void TextureCache_Destroy(void) { while (cache.bottom) TextureCache_RemoveBottom(); glDeleteTextures( 32, cache.glNoiseNames ); glDeleteTextures( 1, &cache.dummy->glName ); cache.top = NULL; cache.bottom = NULL; } struct TileSizes { u32 maskWidth, clampWidth, width, realWidth; u32 maskHeight, clampHeight, height, realHeight; }; static void _calcTileSizes(u32 _t, struct TileSizes *_sizes, gDPTile * _pLoadTile) { gDPTile * pTile = _t < 2 ? gSP.textureTile[_t] : &gDP.tiles[_t]; const struct TextureLoadParameters *loadParams = (const struct TextureLoadParameters*) &imageFormat[gDP.otherMode.textureLUT][pTile->size][pTile->format]; const u32 maxTexels = loadParams->maxTexels; const u32 tileWidth = ((pTile->lrs - pTile->uls) & 0x03FF) + 1; const u32 tileHeight = ((pTile->lrt - pTile->ult) & 0x03FF) + 1; const bool bUseLoadSizes = _pLoadTile != NULL && _pLoadTile->loadType == LOADTYPE_TILE && (pTile->tmem == _pLoadTile->tmem); u32 loadWidth = 0, loadHeight = 0; if (bUseLoadSizes) { loadWidth = ((_pLoadTile->lrs - _pLoadTile->uls) & 0x03FF) + 1; loadHeight = ((_pLoadTile->lrt - _pLoadTile->ult) & 0x03FF) + 1; } const u32 lineWidth = pTile->line << loadParams->lineShift; const u32 lineHeight = lineWidth != 0 ? min(maxTexels / lineWidth, tileHeight) : 0; u32 maskWidth = 1 << pTile->masks; u32 maskHeight = 1 << pTile->maskt; u32 width, height; struct gDPLoadTileInfo *info = (struct gDPLoadTileInfo*)&gDP.loadInfo[pTile->tmem]; if (info->loadType == LOADTYPE_TILE) { if (pTile->masks && ((maskWidth * maskHeight) <= maxTexels)) width = maskWidth; // Use mask width if set and valid else { width = min(info->width, info->texWidth); if (info->size > pTile->size) width <<= info->size - pTile->size; } if (pTile->maskt && ((maskWidth * maskHeight) <= maxTexels)) height = maskHeight; else height = info->height; } else { if (pTile->masks && ((maskWidth * maskHeight) <= maxTexels)) width = maskWidth; // Use mask width if set and valid else if ((tileWidth * tileHeight) <= maxTexels) width = tileWidth; // else use tile width if valid else width = lineWidth; // else use line-based width if (pTile->maskt && ((maskWidth * maskHeight) <= maxTexels)) height = maskHeight; else if ((tileWidth * tileHeight) <= maxTexels) height = tileHeight; else height = lineHeight; } _sizes->clampWidth = (pTile->clamps && gDP.otherMode.cycleType != G_CYC_COPY) ? tileWidth : width; _sizes->clampHeight = (pTile->clampt && gDP.otherMode.cycleType != G_CYC_COPY) ? tileHeight : height; if (_sizes->clampWidth > 256) pTile->clamps = 0; if (_sizes->clampHeight > 256) pTile->clampt = 0; // Make sure masking is valid if (maskWidth > width) { pTile->masks = powof(width); maskWidth = 1 << pTile->masks; } if (maskHeight > height) { pTile->maskt = powof(height); maskHeight = 1 << pTile->maskt; } _sizes->maskWidth = maskWidth; _sizes->maskHeight = maskHeight; _sizes->width = width; _sizes->height = height; if (pTile->clamps != 0) _sizes->realWidth = _sizes->clampWidth; else if (pTile->masks != 0) _sizes->realWidth = _sizes->maskWidth; else _sizes->realWidth = _sizes->width; if (pTile->clampt != 0) _sizes->realHeight = _sizes->clampHeight; else if (pTile->maskt != 0) _sizes->realHeight = _sizes->maskHeight; else _sizes->realHeight = _sizes->height; if (gSP.texture.level > gSP.texture.tile) { _sizes->realWidth = pow2(_sizes->realWidth); _sizes->realHeight = pow2(_sizes->realHeight); } } static void _loadBackground( CachedTexture *pTexture ) { u32 *pDest; u8 *pSwapped, *pSrc; u32 numBytes, bpl; u32 x, y, j, tx, ty; u16 clampSClamp; u16 clampTClamp; GetTexelFunc GetTexel; GLuint glInternalFormat; GLenum glType; const struct TextureLoadParameters *loadParams = (const struct TextureLoadParameters*) &imageFormat[pTexture->format == 2 ? G_TT_RGBA16 : G_TT_NONE][pTexture->size][pTexture->format]; if (loadParams->autoFormat == GL_RGBA) { pTexture->textureBytes = (pTexture->realWidth * pTexture->realHeight) << 2; GetTexel = loadParams->Get32; glInternalFormat = loadParams->glInternalFormat32; glType = loadParams->glType32; } else { pTexture->textureBytes = (pTexture->realWidth * pTexture->realHeight) << 1; GetTexel = loadParams->Get16; glInternalFormat = loadParams->glInternalFormat16; glType = loadParams->glType16; } bpl = gSP.bgImage.width << gSP.bgImage.size >> 1; numBytes = bpl * gSP.bgImage.height; pSwapped = (u8*)malloc(numBytes); //assert(pSwapped != NULL); UnswapCopyWrap(gfx_info.RDRAM, gSP.bgImage.address, pSwapped, 0, RDRAMSize, numBytes); pDest = (u32*)malloc(pTexture->textureBytes); //assert(pDest != NULL); clampSClamp = pTexture->width - 1; clampTClamp = pTexture->height - 1; j = 0; for (y = 0; y < pTexture->realHeight; y++) { ty = min(y, (u32)clampTClamp); pSrc = &pSwapped[bpl * ty]; for (x = 0; x < pTexture->realWidth; x++) { tx = min(x, (u32)clampSClamp); if (glInternalFormat == GL_RGBA) ((u32*)pDest)[j++] = GetTexel((u64*)pSrc, tx, 0, pTexture->palette); else ((u16*)pDest)[j++] = GetTexel((u64*)pSrc, tx, 0, pTexture->palette); } } bool bLoaded = false; #if 0 if ((config.textureFilter.txEnhancementMode | config.textureFilter.txFilterMode) != 0 && config.textureFilter.txFilterIgnoreBG == 0 && TFH.isInited()) { GHQTexInfo ghqTexInfo; if (txfilter_filter((u8*)pDest, pTexture->realWidth, pTexture->realHeight, glInternalFormat, (uint64)pTexture->crc, &ghqTexInfo) != 0 && ghqTexInfo.data != NULL) { if (ghqTexInfo.width % 2 != 0 && ghqTexInfo.format != GL_RGBA) glPixelStorei(GL_UNPACK_ALIGNMENT, 2); glTexImage2D(GL_TEXTURE_2D, 0, ghqTexInfo.format, ghqTexInfo.width, ghqTexInfo.height, 0, ghqTexInfo.texture_format, ghqTexInfo.pixel_type, ghqTexInfo.data); _updateCachedTexture(ghqTexInfo, pTexture); bLoaded = true; } } #endif if (!bLoaded) { if (pTexture->realWidth % 2 != 0 && glInternalFormat != GL_RGBA) glPixelStorei(GL_UNPACK_ALIGNMENT, 2); glTexImage2D(GL_TEXTURE_2D, 0, glInternalFormat, pTexture->realWidth, pTexture->realHeight, 0, GL_RGBA, glType, pDest); } glPixelStorei(GL_UNPACK_ALIGNMENT, 1); free(pDest); } static INLINE void TextureCache_getTextureDestData(CachedTexture *tmptex, u32* pDest, GLuint glInternalFormat, GetTexelFunc GetTexel, u16* pLine) { u64 *pSrc; u16 x, y, i, j, tx, ty; u16 mirrorSBit, maskSMask, clampSClamp; u16 mirrorTBit, maskTMask, clampTClamp; if (tmptex->maskS > 0) { clampSClamp = tmptex->clampS ? tmptex->clampWidth - 1 : (tmptex->mirrorS ? (tmptex->width << 1) - 1 : tmptex->width - 1); maskSMask = (1 << tmptex->maskS) - 1; mirrorSBit = (tmptex->mirrorS != 0 || tmptex->realWidth/ tmptex->width == 2) ? 1 << tmptex->maskS : 0; } else { clampSClamp = min(tmptex->clampWidth, tmptex->width) - 1; maskSMask = 0xFFFF; mirrorSBit = 0x0000; } if (tmptex->maskT > 0) { clampTClamp = tmptex->clampT ? tmptex->clampHeight - 1 : (tmptex->mirrorT ? (tmptex->height << 1) - 1 : tmptex->height - 1); maskTMask = (1 << tmptex->maskT) - 1; mirrorTBit = (tmptex->mirrorT != 0 || tmptex->realHeight / tmptex->height == 2) ? 1 << tmptex->maskT : 0; } else { clampTClamp = min(tmptex->clampHeight, tmptex->height) - 1; maskTMask = 0xFFFF; mirrorTBit = 0x0000; } if (tmptex->size == G_IM_SIZ_32b) { const u16 * tmem16 = (u16*)TMEM; const u32 tbase = tmptex->tMem << 2; int wid_64 = (tmptex->clampWidth) << 2; if (wid_64 & 15) wid_64 += 16; wid_64 &= 0xFFFFFFF0; wid_64 >>= 3; int line32 = tmptex->line << 1; line32 = (line32 - wid_64) << 3; if (wid_64 < 1) wid_64 = 1; int width = wid_64 << 1; line32 = width + (line32 >> 2); u16 gr, ab; j = 0; for (y = 0; y < tmptex->realHeight; ++y) { ty = min(y, clampTClamp) & maskTMask; if (y & mirrorTBit) ty ^= maskTMask; u32 tline = tbase + line32 * ty; u32 xorval = (ty & 1) ? 3 : 1; for (x = 0; x < tmptex->realWidth; ++x) { tx = min(x, clampSClamp) & maskSMask; if (x & mirrorSBit) tx ^= maskSMask; u32 taddr = ((tline + tx) ^ xorval) & 0x3ff; gr = swapword(tmem16[taddr]); ab = swapword(tmem16[taddr | 0x400]); pDest[j++] = (ab << 16) | gr; } } } else if (tmptex->format == G_IM_FMT_YUV) { j = 0; *pLine <<= 1; for (y = 0; y < tmptex->realHeight; ++y) { pSrc = &TMEM[tmptex->tMem] + *pLine * y; for (x = 0; x < tmptex->realWidth / 2; x++) { if (glInternalFormat == GL_RGBA) GetYUV_RGBA8888(pSrc, pDest + j, x); else GetYUV_RGBA4444(pSrc, (u16*)pDest + j, x); j += 2; } } } else { j = 0; for (y = 0; y < tmptex->realHeight; ++y) { ty = min(y, clampTClamp) & maskTMask; if (y & mirrorTBit) ty ^= maskTMask; pSrc = &TMEM[(tmptex->tMem + *pLine * ty) & 0x1FF]; i = (ty & 1) << 1; for (x = 0; x < tmptex->realWidth; ++x) { tx = min(x, clampSClamp) & maskSMask; if (x & mirrorSBit) tx ^= maskSMask; if (glInternalFormat == GL_RGBA) pDest[j++] = GetTexel(pSrc, tx, i, tmptex->palette); else ((u16*)pDest)[j++] = GetTexel(pSrc, tx, i, tmptex->palette); } } } } static void _load(u32 _tile, CachedTexture *_pTexture) { u32 *pDest; u16 line; GetTexelFunc GetTexel; GLuint glInternalFormat; GLenum glType; u32 sizeShift; u64 ricecrc = 0; const struct TextureLoadParameters *loadParams = (const struct TextureLoadParameters*)&imageFormat[gDP.otherMode.textureLUT][_pTexture->size][_pTexture->format]; if (loadParams->autoFormat == GL_RGBA) { sizeShift = 2; _pTexture->textureBytes = (_pTexture->realWidth * _pTexture->realHeight) << sizeShift; GetTexel = loadParams->Get32; glInternalFormat = loadParams->glInternalFormat32; glType = loadParams->glType32; } else { sizeShift = 1; _pTexture->textureBytes = (_pTexture->realWidth * _pTexture->realHeight) << sizeShift; GetTexel = loadParams->Get16; glInternalFormat = loadParams->glInternalFormat16; glType = loadParams->glType16; } pDest = (u32*)malloc(_pTexture->textureBytes); GLint mipLevel = 0, maxLevel = 0; if (config.generalEmulation.enableLOD != 0 && gSP.texture.level > gSP.texture.tile + 1) maxLevel = _tile == 0 ? 0 : gSP.texture.level - gSP.texture.tile - 1; _pTexture->max_level = maxLevel; CachedTexture tmptex = {0}; memcpy(&tmptex, _pTexture, sizeof(CachedTexture)); line = tmptex.line; while (true) { TextureCache_getTextureDestData(&tmptex, pDest, glInternalFormat, GetTexel, &line); bool bLoaded = false; #if 0 if (m_toggleDumpTex && config.textureFilter.txHiresEnable != 0 && config.textureFilter.txDump != 0) { txfilter_dmptx((u8*)pDest, tmptex.realWidth, tmptex.realHeight, tmptex.realWidth, glInternalFormat, (unsigned short)(_pTexture->format << 8 | _pTexture->size), ricecrc); } #endif #if 0 else if ((config.textureFilter.txEnhancementMode | config.textureFilter.txFilterMode) != 0 && maxLevel == 0 && (config.textureFilter.txFilterIgnoreBG == 0 || (RSP.cmd != G_TEXRECT && RSP.cmd != G_TEXRECTFLIP)) && TFH.isInited()) { GHQTexInfo ghqTexInfo; if (txfilter_filter((u8*)pDest, tmptex.realWidth, tmptex.realHeight, glInternalFormat, (uint64)_pTexture->crc, &ghqTexInfo) != 0 && ghqTexInfo.data != NULL) { glTexImage2D(GL_TEXTURE_2D, 0, ghqTexInfo.format, ghqTexInfo.width, ghqTexInfo.height, 0, ghqTexInfo.texture_format, ghqTexInfo.pixel_type, ghqTexInfo.data); _updateCachedTexture(ghqTexInfo, _pTexture); bLoaded = true; } } #endif if (!bLoaded) { if (tmptex.realWidth % 2 != 0 && glInternalFormat != GL_RGBA) glPixelStorei(GL_UNPACK_ALIGNMENT, 2); glTexImage2D(GL_TEXTURE_2D, mipLevel, glInternalFormat, tmptex.realWidth, tmptex.realHeight, 0, GL_RGBA, glType, pDest); } if (mipLevel == maxLevel) break; ++mipLevel; const u32 tileMipLevel = gSP.texture.tile + mipLevel + 1; gDPTile *mipTile = (gDPTile*)&gDP.tiles[tileMipLevel]; line = mipTile->line; tmptex.tMem = mipTile->tmem; tmptex.palette = mipTile->palette; tmptex.maskS = mipTile->masks; tmptex.maskT = mipTile->maskt; struct TileSizes sizes; _calcTileSizes(tileMipLevel, &sizes, NULL); tmptex.width = sizes.width; tmptex.clampWidth = sizes.clampWidth; tmptex.height = sizes.height; tmptex.clampHeight = sizes.clampHeight; // Ensure mip-map levels size consistency. if (tmptex.realWidth > 1) tmptex.realWidth >>= 1; if (tmptex.realHeight > 1) tmptex.realHeight >>= 1; _pTexture->textureBytes += (tmptex.realWidth * tmptex.realHeight) << sizeShift; } glPixelStorei(GL_UNPACK_ALIGNMENT, 1); free(pDest); } struct TextureParams { u16 width; u16 height; u16 clampWidth; u16 clampHeight; u8 maskS; u8 maskT; u8 mirrorS; u8 mirrorT; u8 clampS; u8 clampT; u8 format; u8 size; }; static u32 _calculateCRC(u32 t, const struct TextureParams *_params) { const u32 line = gSP.textureTile[t]->line; const u32 lineBytes = line << 3; const u64 *src = (u64*)&TMEM[gSP.textureTile[t]->tmem]; u32 crc = 0xFFFFFFFF; crc = Hash_Calculate(crc, src, _params->height*lineBytes); if (gSP.textureTile[t]->size == G_IM_SIZ_32b) { src = (u64*)&TMEM[gSP.textureTile[t]->tmem + 256]; crc = Hash_Calculate(crc, src, _params->height*lineBytes); } if (gDP.otherMode.textureLUT != G_TT_NONE || gSP.textureTile[t]->format == G_IM_FMT_CI) { if (gSP.textureTile[t]->size == G_IM_SIZ_4b) crc = Hash_Calculate( crc, &gDP.paletteCRC16[gSP.textureTile[t]->palette], 4 ); else if (gSP.textureTile[t]->size == G_IM_SIZ_8b) crc = Hash_Calculate( crc, &gDP.paletteCRC256, 4 ); } crc = Hash_Calculate(crc, _params, sizeof(_params)); return crc; } void TextureCache_ActivateTexture( u32 t, CachedTexture *_pTexture ) { bool bUseBilinear; glActiveTexture( GL_TEXTURE0 + t ); glBindTexture( GL_TEXTURE_2D, _pTexture->glName ); bUseBilinear = (gDP.otherMode.textureFilter | (gSP.objRendermode&G_OBJRM_BILERP)) != 0; if (config.texture.bilinearMode == BILINEAR_STANDARD) { if (bUseBilinear) { if (_pTexture->max_level > 0) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); else glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } else { if (_pTexture->max_level > 0) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); else glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } } else { // 3 point filter if (_pTexture->max_level > 0) { // Apply standard bilinear to mipmap textures if (bUseBilinear) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } } else if (bUseBilinear && config.generalEmulation.enableLOD != 0 && gSP.texture.level > gSP.texture.tile) { // Apply standard bilinear to first tile of mipmap texture glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } else { // Don't use texture filter. Texture will be filtered by 3 point filter shader glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } } #ifndef GLES glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, _pTexture->max_level); #endif /* Set clamping modes */ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, _pTexture->clampS ? GL_CLAMP_TO_EDGE : _pTexture->mirrorS ? GL_MIRRORED_REPEAT : GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, _pTexture->clampT ? GL_CLAMP_TO_EDGE : _pTexture->mirrorT ? GL_MIRRORED_REPEAT : GL_REPEAT); if (OGL.renderState == RS_TRIANGLE && config.texture.maxAnisotropy > 0) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, config.texture.maxAnisotropy); } _pTexture->lastDList = __RSP.DList; TextureCache_MoveToTop( _pTexture ); cache.current[t] = _pTexture; } void TextureCache_ActivateDummy( u32 t) { glActiveTexture(GL_TEXTURE0 + t); glBindTexture(GL_TEXTURE_2D, cache.dummy->glName ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } int _background_compare(CachedTexture *current, u32 crc) { if ((current != NULL) && (current->crc == crc) && (current->width == gSP.bgImage.width) && (current->height == gSP.bgImage.height) && (current->format == gSP.bgImage.format) && (current->size == gSP.bgImage.size)) return 1; else return 0; } void _updateBackground(void) { u32 numBytes, crc; CachedTexture *current; CachedTexture *pCurrent; numBytes = gSP.bgImage.width * gSP.bgImage.height << gSP.bgImage.size >> 1; crc = Hash_Calculate( 0xFFFFFFFF, &gfx_info.RDRAM[gSP.bgImage.address], numBytes ); if (gDP.otherMode.textureLUT != G_TT_NONE || gSP.bgImage.format == G_IM_FMT_CI) { if (gSP.bgImage.size == G_IM_SIZ_4b) crc = Hash_Calculate( crc, &gDP.paletteCRC16[gSP.bgImage.palette], 4 ); else if (gSP.bgImage.size == G_IM_SIZ_8b) crc = Hash_Calculate( crc, &gDP.paletteCRC256, 4 ); } //before we traverse cache, check to see if texture is already bound: if (_background_compare(cache.current[0], crc)) return; current = (CachedTexture*)cache.top; while (current) { if (_background_compare(current, crc)) { TextureCache_ActivateTexture( 0, current ); cache.hits++; return; } current = current->lower; } cache.misses++; glActiveTexture(GL_TEXTURE0); pCurrent = TextureCache_AddTop(); glBindTexture( GL_TEXTURE_2D, pCurrent->glName ); pCurrent->address = gSP.bgImage.address; pCurrent->crc = crc; pCurrent->format = gSP.bgImage.format; pCurrent->size = gSP.bgImage.size; pCurrent->width = gSP.bgImage.width; pCurrent->height = gSP.bgImage.height; pCurrent->clampWidth = gSP.bgImage.width; pCurrent->clampHeight = gSP.bgImage.height; pCurrent->palette = gSP.bgImage.palette; pCurrent->maskS = 0; pCurrent->maskT = 0; pCurrent->mirrorS = 0; pCurrent->mirrorT = 0; pCurrent->clampS = 0; pCurrent->clampT = 0; pCurrent->line = 0; pCurrent->tMem = 0; pCurrent->lastDList = __RSP.DList; pCurrent->frameBufferTexture = false; pCurrent->realWidth = gSP.bgImage.width; pCurrent->realHeight = gSP.bgImage.height; pCurrent->scaleS = 1.0f / (f32)(pCurrent->realWidth); pCurrent->scaleT = 1.0f / (f32)(pCurrent->realHeight); pCurrent->shiftScaleS = 1.0f; pCurrent->shiftScaleT = 1.0f; pCurrent->offsetS = 0.5f; pCurrent->offsetT = 0.5f; _loadBackground( pCurrent ); TextureCache_ActivateTexture( 0, pCurrent ); cache.cachedBytes += pCurrent->textureBytes; cache.current[0] = pCurrent; } int _texture_compare(u32 t, CachedTexture *current, u32 crc, u32 width, u32 height, u32 clampWidth, u32 clampHeight) { return ((current != NULL) && (current->crc == crc) && (current->width == width) && (current->height == height) && (current->clampWidth == clampWidth) && (current->clampHeight == clampHeight) && (current->maskS == gSP.textureTile[t]->masks) && (current->maskT == gSP.textureTile[t]->maskt) && (current->mirrorS == gSP.textureTile[t]->mirrors) && (current->mirrorT == gSP.textureTile[t]->mirrort) && (current->clampS == gSP.textureTile[t]->clamps) && (current->clampT == gSP.textureTile[t]->clampt) && (current->format == gSP.textureTile[t]->format) && (current->size == gSP.textureTile[t]->size)); } static void _updateShiftScale(u32 _t, CachedTexture *_pTexture) { _pTexture->shiftScaleS = 1.0f; _pTexture->shiftScaleT = 1.0f; if (gSP.textureTile[_t]->shifts > 10) _pTexture->shiftScaleS = (f32)(1 << (16 - gSP.textureTile[_t]->shifts)); else if (gSP.textureTile[_t]->shifts > 0) _pTexture->shiftScaleS /= (f32)(1 << gSP.textureTile[_t]->shifts); if (gSP.textureTile[_t]->shiftt > 10) _pTexture->shiftScaleT = (f32)(1 << (16 - gSP.textureTile[_t]->shiftt)); else if (gSP.textureTile[_t]->shiftt > 0) _pTexture->shiftScaleT /= (f32)(1 << gSP.textureTile[_t]->shiftt); } void TextureCache_Update( u32 _t ) { CachedTexture *current; CachedTexture *pCurrent; u32 crc; struct TextureParams params; struct TileSizes sizes; switch (gSP.textureTile[_t]->textureMode) { case TEXTUREMODE_BGIMAGE: _updateBackground(); return; case TEXTUREMODE_FRAMEBUFFER: FrameBuffer_ActivateBufferTexture( _t, gSP.textureTile[_t]->frameBuffer ); return; case TEXTUREMODE_FRAMEBUFFER_BG: FrameBuffer_ActivateBufferTextureBG( _t, gSP.textureTile[_t]->frameBuffer ); return; } if (gDP.otherMode.textureLOD == G_TL_LOD && gSP.texture.level == gSP.texture.tile && _t == 1) { cache.current[1] = cache.current[0]; TextureCache_ActivateTexture(_t, cache.current[_t]); return; } if (gSP.texture.tile == 7 && _t == 0 && gSP.textureTile[0] == gDP.loadTile && gDP.loadTile->loadType == LOADTYPE_BLOCK && gSP.textureTile[0]->tmem == gSP.textureTile[1]->tmem) gSP.textureTile[0] = gSP.textureTile[1]; _calcTileSizes(_t, &sizes, gDP.loadTile); params.width = sizes.width; params.height = sizes.height; params.clampWidth = sizes.clampWidth; params.clampHeight = sizes.clampHeight; params.maskS = gSP.textureTile[_t]->masks; params.maskT = gSP.textureTile[_t]->maskt; params.mirrorS = gSP.textureTile[_t]->mirrors; params.mirrorT = gSP.textureTile[_t]->mirrort; params.clampS = gSP.textureTile[_t]->clamps; params.clampT = gSP.textureTile[_t]->clampt; params.format = gSP.textureTile[_t]->format; params.size = gSP.textureTile[_t]->size; crc = _calculateCRC(_t, ¶ms ); //before we traverse cache, check to see if texture is already bound: if (_texture_compare(_t, cache.current[_t], crc, params.width, params.height, params.clampWidth, params.clampHeight)) { _updateShiftScale(_t, cache.current[_t]); TextureCache_ActivateTexture(_t, cache.current[_t]); return; } current = cache.top; while (current) { if (_texture_compare(_t, current, crc, params.width, params.height, params.clampWidth, params.clampHeight)) { _updateShiftScale(_t, current); TextureCache_ActivateTexture(_t, current ); cache.hits++; return; } current = current->lower; } cache.misses++; glActiveTexture( GL_TEXTURE0 + _t); pCurrent = TextureCache_AddTop(); glBindTexture( GL_TEXTURE_2D, pCurrent->glName ); pCurrent->address = gDP.textureImage.address; pCurrent->crc = crc; pCurrent->format = gSP.textureTile[_t]->format; pCurrent->size = gSP.textureTile[_t]->size; pCurrent->width = sizes.width; pCurrent->height = sizes.height; pCurrent->clampWidth = sizes.clampWidth; pCurrent->clampHeight = sizes.clampHeight; pCurrent->palette = gSP.textureTile[_t]->palette; pCurrent->maskS = gSP.textureTile[_t]->masks; pCurrent->maskT = gSP.textureTile[_t]->maskt; pCurrent->mirrorS = gSP.textureTile[_t]->mirrors; pCurrent->mirrorT = gSP.textureTile[_t]->mirrort; pCurrent->clampS = gSP.textureTile[_t]->clamps; pCurrent->clampT = gSP.textureTile[_t]->clampt; pCurrent->line = gSP.textureTile[_t]->line; pCurrent->tMem = gSP.textureTile[_t]->tmem; pCurrent->lastDList = __RSP.DList; pCurrent->realWidth = sizes.realWidth; pCurrent->realHeight = sizes.realHeight; pCurrent->scaleS = 1.0f / (f32)(pCurrent->realWidth); pCurrent->scaleT = 1.0f / (f32)(pCurrent->realHeight); pCurrent->offsetS = 0.5f; pCurrent->offsetT = 0.5f; pCurrent->shiftScaleS = 1.0f; pCurrent->shiftScaleT = 1.0f; _updateShiftScale(_t, pCurrent); _load(_t, pCurrent ); TextureCache_ActivateTexture(_t, pCurrent ); cache.cachedBytes += pCurrent->textureBytes; cache.current[_t] = pCurrent; } void TextureCache_ActivateNoise(u32 t) { glActiveTexture(GL_TEXTURE0 + t); glBindTexture(GL_TEXTURE_2D, cache.glNoiseNames[__RSP.DList & 0x1F]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); } glide2gl/src/Glide64/ucode01.h000664 001750 001750 00000007757 12655644434 017026 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** // // vertex - loads vertices // static void uc1_vertex(uint32_t w0, uint32_t w1) { int32_t v0 = (w0 >> 17) & 0x7F; // Current vertex int32_t n = (w0 >> 10) & 0x3F; // Number to copy rsp_vertex(v0, n); } static void uc1_tri1(uint32_t w0, uint32_t w1) { VERTEX *v[3]; if (rdp.skip_drawing) return; v[0] = &rdp.vtx[(w1 >> 17) & 0x7F]; v[1] = &rdp.vtx[(w1 >> 9) & 0x7F]; v[2] = &rdp.vtx[(w1 >> 1) & 0x7F]; cull_trianglefaces(v, 1, true, true, 0); } static void uc1_tri2(uint32_t w0, uint32_t w1) { VERTEX *v[6]; if (rdp.skip_drawing) return; v[0] = &rdp.vtx[(w0 >> 17) & 0x7F]; v[1] = &rdp.vtx[(w0 >> 9) & 0x7F]; v[2] = &rdp.vtx[(w0 >> 1) & 0x7F]; v[3] = &rdp.vtx[(w1 >> 17) & 0x7F]; v[4] = &rdp.vtx[(w1 >> 9) & 0x7F]; v[5] = &rdp.vtx[(w1 >> 1) & 0x7F]; cull_trianglefaces(v, 2, true, true, 0); } static void uc1_line3d(uint32_t w0, uint32_t w1) { if (!settings.force_quad3d && ((w1 & 0xFF000000) == 0) && ((w0 & 0x00FFFFFF) == 0)) { uint32_t cull_mode; VERTEX *v[3]; uint16_t width = (uint16_t)(w1 & 0xFF) + 3; v[0] = &rdp.vtx[(w1 >> 17) & 0x7F]; v[1] = &rdp.vtx[(w1 >> 9) & 0x7F]; v[2] = &rdp.vtx[(w1 >> 9) & 0x7F]; cull_mode = (rdp.flags & CULLMASK) >> CULLSHIFT; rdp.flags |= CULLMASK; g_gdp.flags |= UPDATE_CULL_MODE; cull_trianglefaces(v, 1, true, true, width); rdp.flags ^= CULLMASK; rdp.flags |= cull_mode << CULLSHIFT; g_gdp.flags |= UPDATE_CULL_MODE; } else { VERTEX *v[6]; v[0] = &rdp.vtx[(w1 >> 25) & 0x7F]; v[1] = &rdp.vtx[(w1 >> 17) & 0x7F]; v[2] = &rdp.vtx[(w1 >> 9) & 0x7F]; v[3] = &rdp.vtx[(w1 >> 1) & 0x7F]; v[4] = &rdp.vtx[(w1 >> 25) & 0x7F]; v[5] = &rdp.vtx[(w1 >> 9) & 0x7F]; cull_trianglefaces(v, 2, true, true, 0); } } uint32_t branch_dl = 0; static void uc1_rdphalf_1(uint32_t w0, uint32_t w1) { branch_dl = w1; rdphalf_1(w0, w1); } static void uc1_branch_z(uint32_t w0, uint32_t w1) { uint32_t addr = RSP_SegmentToPhysical(branch_dl); uint32_t vtx = (w0 & 0xFFF) >> 1; if( fabs(rdp.vtx[vtx].z) <= (w1/*&0xFFFF*/) ) rdp.pc[rdp.pc_i] = addr; } libretro/libretro.c000664 001750 001750 00000063743 12655644434 015544 0ustar00sergiosergio000000 000000 #include #include #include #include #include "api/libretro.h" #ifndef SINGLE_THREAD #include #endif #include "api/m64p_frontend.h" #include "plugin/plugin.h" #include "api/m64p_types.h" #include "r4300/r4300.h" #include "memory/memory.h" #include "main/main.h" #include "main/version.h" #include "main/savestates.h" #include "pi/pi_controller.h" #include "si/pif.h" #include "libretro_memory.h" /* Cxd4 RSP */ #include "../mupen64plus-rsp-cxd4/config.h" #include "plugin/audio_libretro/audio_plugin.h" int glide64InitGfx(void); void gles2n64_reset(void); struct retro_perf_callback perf_cb; retro_get_cpu_features_t perf_get_cpu_features_cb = NULL; retro_log_printf_t log_cb = NULL; retro_video_refresh_t video_cb = NULL; retro_input_poll_t poll_cb = NULL; retro_input_state_t input_cb = NULL; retro_audio_sample_batch_t audio_batch_cb = NULL; retro_environment_t environ_cb = NULL; struct retro_rumble_interface rumble; save_memory_data saved_memory; #ifndef SINGLE_THREAD cothread_t main_thread; static cothread_t cpu_thread; #endif float polygonOffsetFactor; float polygonOffsetUnits; int astick_deadzone; bool flip_only; static uint8_t* game_data = NULL; static uint32_t game_size = 0; static bool emu_initialized = false; static unsigned initial_boot = true; static unsigned audio_buffer_size = 2048; static unsigned retro_filtering = 0; static bool reinit_screen = false; static bool first_context_reset = false; static bool pushed_frame = false; unsigned frame_dupe = false; extern uint32_t *blitter_buf; enum gfx_plugin_type gfx_plugin; uint32_t gfx_plugin_accuracy = 2; static enum rsp_plugin_type rsp_plugin; uint32_t screen_width; uint32_t screen_height; uint32_t screen_pitch; uint32_t screen_aspectmodehint; extern unsigned int VI_REFRESH; unsigned int BUFFERSWAP; unsigned int FAKE_SDL_TICKS; // after the controller's CONTROL* member has been assigned we can update // them straight from here... extern struct { CONTROL *control; BUTTONS buttons; } controller[4]; // ...but it won't be at least the first time we're called, in that case set // these instead for input_plugin to read. int pad_pak_types[4]; int pad_present[4] = {1, 1, 1, 1}; static void n64DebugCallback(void* aContext, int aLevel, const char* aMessage) { char buffer[1024]; snprintf(buffer, 1024, "mupen64plus: %s\n", aMessage); if (log_cb) log_cb(RETRO_LOG_INFO, buffer); } extern m64p_rom_header ROM_HEADER; static void core_settings_autoselect_gfx_plugin(void) { struct retro_variable gfx_var = { "mupen64-gfxplugin", 0 }; environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &gfx_var); if (gfx_var.value && strcmp(gfx_var.value, "auto") != 0) return; gfx_plugin = GFX_GLIDE64; } unsigned libretro_get_gfx_plugin(void) { return gfx_plugin; } static void core_settings_autoselect_rsp_plugin(void); static void core_settings_set_defaults(void) { /* Load GFX plugin core option */ struct retro_variable gfx_var = { "mupen64-gfxplugin", 0 }; struct retro_variable rsp_var = { "mupen64-rspplugin", 0 }; environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &gfx_var); environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &rsp_var); if (gfx_var.value) { if (gfx_var.value && !strcmp(gfx_var.value, "auto")) core_settings_autoselect_gfx_plugin(); if (gfx_var.value && !strcmp(gfx_var.value, "gln64")) gfx_plugin = GFX_GLN64; if (gfx_var.value && !strcmp(gfx_var.value, "rice")) gfx_plugin = GFX_RICE; if(gfx_var.value && !strcmp(gfx_var.value, "glide64")) gfx_plugin = GFX_GLIDE64; if(gfx_var.value && !strcmp(gfx_var.value, "angrylion")) gfx_plugin = GFX_ANGRYLION; } else gfx_plugin = GFX_GLIDE64; gfx_var.key = "mupen64-gfxplugin-accuracy"; gfx_var.value = NULL; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &gfx_var) && gfx_var.value) { if (gfx_var.value && !strcmp(gfx_var.value, "veryhigh")) gfx_plugin_accuracy = 3; else if (gfx_var.value && !strcmp(gfx_var.value, "high")) gfx_plugin_accuracy = 2; else if (gfx_var.value && !strcmp(gfx_var.value, "medium")) gfx_plugin_accuracy = 1; else if (gfx_var.value && !strcmp(gfx_var.value, "low")) gfx_plugin_accuracy = 0; } /* Load RSP plugin core option */ rsp_plugin = RSP_HLE; if (rsp_var.value) { if (rsp_var.value && !strcmp(rsp_var.value, "auto")) core_settings_autoselect_rsp_plugin(); if (rsp_var.value && !strcmp(rsp_var.value, "hle")) rsp_plugin = RSP_HLE; if (rsp_var.value && !strcmp(rsp_var.value, "cxd4")) rsp_plugin = RSP_CXD4; } } static void core_settings_autoselect_rsp_plugin(void) { struct retro_variable rsp_var = { "mupen64-rspplugin", 0 }; environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &rsp_var); if (rsp_var.value && strcmp(rsp_var.value, "auto") != 0) return; rsp_plugin = RSP_HLE; if ( (sl(ROM_HEADER.CRC1) == 0x7EAE2488 && sl(ROM_HEADER.CRC2) == 0x9D40A35A) /* Biohazard 2 (J) [!] */ || (sl(ROM_HEADER.CRC1) == 0x9B500E8E && sl(ROM_HEADER.CRC2) == 0xE90550B3) /* Resident Evil 2 (E) (M2) [!] */ || (sl(ROM_HEADER.CRC1) == 0xAA18B1A5 && sl(ROM_HEADER.CRC2) == 0x7DB6AEB) /* Resident Evil 2 (U) [!] */ || (!strcmp((const char*)ROM_HEADER.Name, "GAUNTLET LEGENDS")) ) { rsp_plugin = RSP_CXD4; } if (!strcmp((const char*)ROM_HEADER.Name, "CONKER BFD")) rsp_plugin = RSP_HLE; } static void setup_variables(void) { struct retro_variable variables[] = { { "mupen64-cpucore", #ifdef DYNAREC #if defined(IOS) || defined(ANDROID) "CPU Core; cached_interpreter|pure_interpreter|dynamic_recompiler" }, #else "CPU Core; dynamic_recompiler|cached_interpreter|pure_interpreter" }, #endif #else "CPU Core; cached_interpreter|pure_interpreter" }, #endif {"mupen64-audio-buffer-size", "Audio Buffer Size (restart); 2048|1024"}, {"mupen64-astick-deadzone", "Analog Deadzone (percent); 15|20|25|30|0|5|10"}, {"mupen64-pak1", "Player 1 Pak; none|memory|rumble"}, {"mupen64-pak2", "Player 2 Pak; none|memory|rumble"}, {"mupen64-pak3", "Player 3 Pak; none|memory|rumble"}, {"mupen64-pak4", "Player 4 Pak; none|memory|rumble"}, { "mupen64-disable_expmem", "Enable Expansion Pak RAM; enabled|disabled" }, { "mupen64-gfxplugin-accuracy", "GFX Accuracy (restart); medium|high|veryhigh|low" }, { "mupen64-gfxplugin", "GFX Plugin; auto|glide64|gln64|rice|angrylion" }, { "mupen64-rspplugin", "RSP Plugin; auto|hle|cxd4" }, { "mupen64-screensize", "Resolution (restart); 640x480|960x720|1280x960|1600x1200|1920x1440|2240x1680|320x240" }, { "mupen64-aspectratiohint", "Aspect ratio hint (reinit); normal|widescreen" }, { "mupen64-filtering", "Texture Filtering; automatic|N64 3-point|bilinear|nearest" }, { "mupen64-polyoffset-factor", "(Glide64) Polygon Offset Factor; -3.0|-2.5|-2.0|-1.5|-1.0|-0.5|0.0|0.5|1.0|1.5|2.0|2.5|3.0|3.5|4.0|4.5|5.0|-3.5|-4.0|-4.5|-5.0" }, { "mupen64-polyoffset-units", "(Glide64) Polygon Offset Units; -3.0|-2.5|-2.0|-1.5|-1.0|-0.5|0.0|0.5|1.0|1.5|2.0|2.5|3.0|3.5|4.0|4.5|5.0|-3.5|-4.0|-4.5|-5.0" }, { "mupen64-angrylion-vioverlay", "(Angrylion) VI Overlay; disabled|enabled" }, { "mupen64-virefresh", "VI Refresh (Overclock); 1500|2200" }, { "mupen64-bufferswap", "Buffer Swap; on|off" }, { "mupen64-framerate", "Framerate (restart); original|fullspeed" }, { "mupen64-vcache-vbo", "(Glide64) Vertex cache VBO (restart); off|on" }, { "mupen64-boot-device", "Boot Device; Default|64DD IPL" }, { "mupen64-64dd-hardware", "64DD Hardware; disabled|enabled" }, { NULL, NULL }, }; environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, variables); } static bool emu_step_load_data() { if(CoreStartup(FRONTEND_API_VERSION, ".", ".", "Core", n64DebugCallback, 0, 0) && log_cb) log_cb(RETRO_LOG_ERROR, "mupen64plus: Failed to initialize core\n"); log_cb(RETRO_LOG_INFO, "EmuThread: M64CMD_ROM_OPEN\n"); if(CoreDoCommand(M64CMD_ROM_OPEN, game_size, (void*)game_data)) { if (log_cb) log_cb(RETRO_LOG_ERROR, "mupen64plus: Failed to load ROM\n"); goto load_fail; } free(game_data); game_data = NULL; log_cb(RETRO_LOG_INFO, "EmuThread: M64CMD_ROM_GET_HEADER\n"); if(CoreDoCommand(M64CMD_ROM_GET_HEADER, sizeof(ROM_HEADER), &ROM_HEADER)) { if (log_cb) log_cb(RETRO_LOG_ERROR, "mupen64plus; Failed to query ROM header information\n"); goto load_fail; } return true; load_fail: free(game_data); game_data = NULL; stop = 1; return false; } bool emu_step_render() { if (flip_only) { if (gfx_plugin == GFX_ANGRYLION) video_cb((screen_pitch == 0) ? NULL : blitter_buf, screen_width, screen_height, screen_pitch); else video_cb(RETRO_HW_FRAME_BUFFER_VALID, screen_width, screen_height, 0); pushed_frame = true; return true; } if (!pushed_frame && frame_dupe) // Dupe. Not duping violates libretro API, consider it a speedhack. video_cb(NULL, screen_width, screen_height, screen_pitch); return false; } static void emu_step_initialize(void) { if (emu_initialized) return; emu_initialized = true; core_settings_set_defaults(); core_settings_autoselect_gfx_plugin(); core_settings_autoselect_rsp_plugin(); plugin_connect_all(gfx_plugin, rsp_plugin); log_cb(RETRO_LOG_INFO, "EmuThread: M64CMD_EXECUTE. \n"); CoreDoCommand(M64CMD_EXECUTE, 0, NULL); } void reinit_gfx_plugin(void) { if(first_context_reset) { first_context_reset = false; #ifdef SINGLE_THREAD emu_step_initialize(); #else co_switch(cpu_thread); #endif } if (gfx_plugin == GFX_GLIDE64) glide64InitGfx(); else if (gfx_plugin == GFX_GLN64) gles2n64_reset(); } #ifndef SINGLE_THREAD static void EmuThreadFunction(void) { if (!emu_step_load_data()) goto load_fail; //ROM is loaded, switch back to main thread so retro_load_game can return (returning failure if needed). //We'll continue here once the context is reset. co_switch(main_thread); emu_step_initialize(); //Context is reset too, everything is safe to use. Now back to main thread so we don't start pushing frames outside retro_run. co_switch(main_thread); main_run(); log_cb(RETRO_LOG_INFO, "EmuThread: co_switch main_thread. \n"); co_switch(main_thread); load_fail: //NEVER RETURN! That's how libco rolls while(1) { if (log_cb) log_cb(RETRO_LOG_ERROR, "Running Dead N64 Emulator"); co_switch(main_thread); } } #endif const char* retro_get_system_directory(void) { const char* dir; environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir); return dir ? dir : "."; } void retro_set_video_refresh(retro_video_refresh_t cb) { video_cb = cb; } void retro_set_audio_sample(retro_audio_sample_t cb) { } void retro_set_audio_sample_batch(retro_audio_sample_batch_t cb) { audio_batch_cb = cb; } void retro_set_input_poll(retro_input_poll_t cb) { poll_cb = cb; } void retro_set_input_state(retro_input_state_t cb) { input_cb = cb; } void retro_set_environment(retro_environment_t cb) { environ_cb = cb; setup_variables(); } void retro_get_system_info(struct retro_system_info *info) { info->library_name = "Mupen64Plus"; info->library_version = "2.0-rc2"; info->valid_extensions = "n64|v64|z64|bin|u1|ndd"; info->need_fullpath = false; info->block_extract = false; } // Get the system type associated to a ROM country code. static m64p_system_type rom_country_code_to_system_type(char country_code) { switch (country_code) { // PAL codes case 0x44: case 0x46: case 0x49: case 0x50: case 0x53: case 0x55: case 0x58: case 0x59: return SYSTEM_PAL; // NTSC codes case 0x37: case 0x41: case 0x45: case 0x4a: default: // Fallback for unknown codes return SYSTEM_NTSC; } } void retro_get_system_av_info(struct retro_system_av_info *info) { m64p_system_type region = rom_country_code_to_system_type(ROM_HEADER.destination_code); info->geometry.base_width = screen_width; info->geometry.base_height = screen_height; info->geometry.max_width = screen_width; info->geometry.max_height = screen_height; info->geometry.aspect_ratio = 4.0 / 3.0; info->timing.fps = (region == SYSTEM_PAL) ? 50.0 : (60/1.001); // TODO: Actual timing info->timing.sample_rate = 44100.0; } unsigned retro_get_region (void) { m64p_system_type region = rom_country_code_to_system_type(ROM_HEADER.destination_code); return ((region == SYSTEM_PAL) ? RETRO_REGION_PAL : RETRO_REGION_NTSC); } void retro_init(void) { struct retro_log_callback log; unsigned colorMode = RETRO_PIXEL_FORMAT_XRGB8888; screen_pitch = 0; if (environ_cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &log)) log_cb = log.log; else log_cb = NULL; if (environ_cb(RETRO_ENVIRONMENT_GET_PERF_INTERFACE, &perf_cb)) perf_get_cpu_features_cb = perf_cb.get_cpu_features; else perf_get_cpu_features_cb = NULL; environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &colorMode); environ_cb(RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE, &rumble); //hacky stuff for Glide64 polygonOffsetUnits = -3.0f; polygonOffsetFactor = -3.0f; #ifndef SINGLE_THREAD main_thread = co_active(); cpu_thread = co_create(65536 * sizeof(void*) * 16, EmuThreadFunction); #endif } void retro_deinit(void) { main_stop(); main_exit(); #ifndef SINGLE_THREAD co_delete(cpu_thread); #endif deinit_audio_libretro(); if (perf_cb.perf_log) perf_cb.perf_log(); } #include "../mupen64plus-video-angrylion/vi.h" extern void glide_set_filtering(unsigned value); extern void ChangeSize(); void update_variables(bool startup) { static float last_aspect = 4.0 / 3.0; struct retro_variable var; var.key = "mupen64-screensize"; var.value = NULL; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { /* TODO/FIXME - hack - force screen width and height back to 640x480 in case * we change it with Angrylion. If we ever want to support variable resolution sizes in Angrylion * then we need to drop this. */ if (gfx_plugin == GFX_ANGRYLION || sscanf(var.value ? var.value : "640x480", "%dx%d", &screen_width, &screen_height) != 2) { screen_width = 640; screen_height = 480; } } if (startup) { var.key = "mupen64-audio-buffer-size"; var.value = NULL; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) audio_buffer_size = atoi(var.value); var.key = "mupen64-gfxplugin"; var.value = NULL; environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var); if (var.value) { if (!strcmp(var.value, "auto")) core_settings_autoselect_gfx_plugin(); if (!strcmp(var.value, "gln64")) gfx_plugin = GFX_GLN64; if (!strcmp(var.value, "rice")) gfx_plugin = GFX_RICE; if(!strcmp(var.value, "glide64")) gfx_plugin = GFX_GLIDE64; if(!strcmp(var.value, "angrylion")) gfx_plugin = GFX_ANGRYLION; } else gfx_plugin = GFX_GLIDE64; } var.key = "mupen64-angrylion-vioverlay"; var.value = NULL; environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var); if (var.value) { if(!strcmp(var.value, "enabled")) overlay = 1; else if(!strcmp(var.value, "disabled")) overlay = 0; } else overlay = 1; CFG_HLE_GFX = (gfx_plugin != GFX_ANGRYLION) ? 1 : 0; CFG_HLE_AUD = 0; /* There is no HLE audio code in libretro audio plugin. */ var.key = "mupen64-filtering"; var.value = NULL; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { if (!strcmp(var.value, "automatic")) retro_filtering = 0; else if (!strcmp(var.value, "N64 3-point")) #ifdef DISABLE_3POINT retro_filtering = 3; #else retro_filtering = 1; #endif else if (!strcmp(var.value, "nearest")) retro_filtering = 2; else if (!strcmp(var.value, "bilinear")) retro_filtering = 3; if (gfx_plugin == GFX_GLIDE64) { log_cb(RETRO_LOG_DEBUG, "set glide filtering mode\n"); glide_set_filtering(retro_filtering); } } if (!startup) { var.key = "mupen64-aspectratiohint"; var.value = NULL; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { float aspect_val = 4.0 / 3.0; float aspectmode = 0; if (!strcmp(var.value, "widescreen")) { aspect_val = 16.0 / 9.0; aspectmode = 1; } else if (!strcmp(var.value, "normal")) { aspect_val = 4.0 / 3.0; aspectmode = 0; } if (aspect_val != last_aspect) { screen_aspectmodehint = aspectmode; switch (gfx_plugin) { case GFX_GLIDE64: ChangeSize(); break; default: break; } last_aspect = aspect_val; reinit_screen = true; } } } var.key = "mupen64-polyoffset-factor"; var.value = NULL; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { float new_val = (float)atoi(var.value); polygonOffsetFactor = new_val; } var.key = "mupen64-polyoffset-units"; var.value = NULL; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { float new_val = (float)atoi(var.value); polygonOffsetUnits = new_val; } var.key = "mupen64-astick-deadzone"; var.value = NULL; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) astick_deadzone = (int)(atoi(var.value) * 0.01f * 0x8000); var.key = "mupen64-gfxplugin-accuracy"; var.value = NULL; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { if (var.value && !strcmp(var.value, "veryhigh")) gfx_plugin_accuracy = 3; else if (var.value && !strcmp(var.value, "high")) gfx_plugin_accuracy = 2; else if (var.value && !strcmp(var.value, "medium")) gfx_plugin_accuracy = 1; else if (var.value && !strcmp(var.value, "low")) gfx_plugin_accuracy = 0; } var.key = "mupen64-virefresh"; var.value = NULL; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { if (!strcmp(var.value, "1500")) VI_REFRESH = 1500; else if (!strcmp(var.value, "2200")) VI_REFRESH = 2200; } var.key = "mupen64-bufferswap"; var.value = NULL; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { if (!strcmp(var.value, "on")) BUFFERSWAP = true; else if (!strcmp(var.value, "off")) BUFFERSWAP = false; } var.key = "mupen64-framerate"; var.value = NULL; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value && initial_boot) { if (!strcmp(var.value, "original")) frame_dupe = false; else if (!strcmp(var.value, "fullspeed")) frame_dupe = true; } { struct retro_variable pk1var = { "mupen64-pak1" }; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &pk1var) && pk1var.value) { int p1_pak = PLUGIN_NONE; if (!strcmp(pk1var.value, "rumble")) p1_pak = PLUGIN_RAW; else if (!strcmp(pk1var.value, "memory")) p1_pak = PLUGIN_MEMPAK; // If controller struct is not initialised yet, set pad_pak_types instead // which will be looked at when initialising the controllers. if (controller[0].control) controller[0].control->Plugin = p1_pak; else pad_pak_types[0] = p1_pak; } } { struct retro_variable pk2var = { "mupen64-pak2" }; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &pk2var) && pk2var.value) { int p2_pak = PLUGIN_NONE; if (!strcmp(pk2var.value, "rumble")) p2_pak = PLUGIN_RAW; else if (!strcmp(pk2var.value, "memory")) p2_pak = PLUGIN_MEMPAK; if (controller[1].control) controller[1].control->Plugin = p2_pak; else pad_pak_types[1] = p2_pak; } } { struct retro_variable pk3var = { "mupen64-pak3" }; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &pk3var) && pk3var.value) { int p3_pak = PLUGIN_NONE; if (!strcmp(pk3var.value, "rumble")) p3_pak = PLUGIN_RAW; else if (!strcmp(pk3var.value, "memory")) p3_pak = PLUGIN_MEMPAK; if (controller[2].control) controller[2].control->Plugin = p3_pak; else pad_pak_types[2] = p3_pak; } } { struct retro_variable pk4var = { "mupen64-pak4" }; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &pk4var) && pk4var.value) { int p4_pak = PLUGIN_NONE; if (!strcmp(pk4var.value, "rumble")) p4_pak = PLUGIN_RAW; else if (!strcmp(pk4var.value, "memory")) p4_pak = PLUGIN_MEMPAK; if (controller[3].control) controller[3].control->Plugin = p4_pak; else pad_pak_types[3] = p4_pak; } } } static void format_saved_memory(void) { format_sram(saved_memory.sram); format_eeprom(saved_memory.eeprom, sizeof(saved_memory.eeprom)); format_flashram(saved_memory.flashram); format_mempak(saved_memory.mempack[0]); format_mempak(saved_memory.mempack[1]); format_mempak(saved_memory.mempack[2]); format_mempak(saved_memory.mempack[3]); } bool retro_load_game(const struct retro_game_info *game) { struct retro_hw_render_callback *render = NULL; format_saved_memory(); update_variables(true); initial_boot = false; init_audio_libretro(audio_buffer_size); if ((render = (struct retro_hw_render_callback*)retro_gl_init())) { if (!environ_cb(RETRO_ENVIRONMENT_SET_HW_RENDER, render)) { if (log_cb) log_cb(RETRO_LOG_ERROR, "mupen64plus: libretro frontend doesn't have OpenGL support."); return false; } } game_data = malloc(game->size); memcpy(game_data, game->data, game->size); game_size = game->size; #ifdef SINGLE_THREAD if (!emu_step_load_data()) return false; #else stop = false; //Finish ROM load before doing anything funny, so we can return failure if needed. co_switch(cpu_thread); if (stop) return false; #endif first_context_reset = true; return true; } void retro_unload_game(void) { stop = 1; #ifndef SINGLE_THREAD co_switch(cpu_thread); #endif CoreDoCommand(M64CMD_ROM_CLOSE, 0, NULL); emu_initialized = false; } void retro_run (void) { static bool updated = false; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated) update_variables(false); #ifdef SINGLE_THREAD if (gfx_plugin == GFX_ANGRYLION && !emu_initialized) emu_step_initialize(); #endif FAKE_SDL_TICKS += 16; pushed_frame = false; if (reinit_screen) { bool ret; struct retro_system_av_info info; retro_get_system_av_info(&info); switch (screen_aspectmodehint) { case 0: info.geometry.aspect_ratio = 4.0 / 3.0; break; case 1: info.geometry.aspect_ratio = 16.0 / 9.0; break; } ret = environ_cb(RETRO_ENVIRONMENT_SET_GEOMETRY, &info.geometry); reinit_screen = false; } do { #ifndef HAVE_SHARED_CONTEXT sglEnter(); #endif #ifdef SINGLE_THREAD stop = 0; main_run(); stop = 0; #else co_switch(cpu_thread); #endif #ifndef HAVE_SHARED_CONTEXT sglExit(); #endif } while (emu_step_render()); } void retro_reset (void) { CoreDoCommand(M64CMD_RESET, 1, (void*)0); } void *retro_get_memory_data(unsigned type) { return (type == RETRO_MEMORY_SAVE_RAM) ? &saved_memory : 0; } size_t retro_get_memory_size(unsigned type) { return (type == RETRO_MEMORY_SAVE_RAM) ? sizeof(saved_memory) : 0; } size_t retro_serialize_size (void) { return 16788288 + 1024; // < 16MB and some change... ouch } bool retro_serialize(void *data, size_t size) { if (savestates_save_m64p(data, size)) return true; return false; } bool retro_unserialize(const void * data, size_t size) { if (savestates_load_m64p(data, size)) return true; return false; } //Needed to be able to detach controllers for Lylat Wars multiplayer //Only sets if controller struct is initialised as addon paks do. void retro_set_controller_port_device(unsigned in_port, unsigned device) { if (in_port < 4){ switch(device) { case RETRO_DEVICE_NONE: if (controller[in_port].control){ controller[in_port].control->Present = 0; break; } else { pad_present[in_port] = 0; break; } case RETRO_DEVICE_JOYPAD: default: if (controller[in_port].control){ controller[in_port].control->Present = 1; break; } else { pad_present[in_port] = 1; break; } } } } // Stubs unsigned retro_api_version(void) { return RETRO_API_VERSION; } bool retro_load_game_special(unsigned game_type, const struct retro_game_info *info, size_t num_info) { return false; } void retro_cheat_reset(void) { } void retro_cheat_set(unsigned unused, bool unused1, const char* unused2) { } mupen64plus-core/src/si/game_controller.c000664 001750 001750 00000012571 12655644434 021577 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - game_controller.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "game_controller.h" #include "pif.h" #include "api/m64p_types.h" #include "api/callbacks.h" #ifdef COMPARE_CORE #include "api/debugger.h" #endif #include #include static uint8_t pak_data_crc(uint8_t *data) { int i; uint8_t crc = 0; for (i = 0; i <= 0x20; i++) { int mask; for (mask = 0x80; mask >= 1; mask >>= 1) { int xor_tap = (crc & 0x80) ? 0x85 : 0x00; crc <<= 1; if (i != 0x20 && (data[i] & mask)) crc |= 1; crc ^= xor_tap; } } return crc; } static void read_controller_read_buttons(struct game_controller* cont, uint8_t* cmd) { enum pak_type pak; int connected = game_controller_is_connected(cont, &pak); if (!connected) return; *((uint32_t*)(cmd + 3)) = game_controller_get_input(cont); #ifdef COMPARE_CORE CoreCompareDataSync(4, cmd + 3); #endif } static void controller_status_command(struct game_controller* cont, uint8_t* cmd) { enum pak_type pak; int connected = game_controller_is_connected(cont, &pak); if (cmd[1] & 0x80) return; if (!connected) { cmd[1] |= 0x80; return; } cmd[3] = 0x05; cmd[4] = 0x00; switch(pak) { case PAK_MEM: case PAK_RUMBLE: case PAK_TRANSFER: cmd[5] = 1; break; case PAK_NONE: default: cmd[5] = 0; } } static void controller_read_buttons_command(struct game_controller* cont, uint8_t* cmd) { enum pak_type pak; int connected = game_controller_is_connected(cont, &pak); if (!connected) cmd[1] |= 0x80; /* NOTE: buttons reading is done in read_controller_read_buttons instead */ } static void controller_read_pak_command(struct game_controller* cont, uint8_t* cmd) { enum pak_type pak; int connected = game_controller_is_connected(cont, &pak); if (!connected) { cmd[1] |= 0x80; return; } switch (pak) { case PAK_NONE: memset(&cmd[5], 0, 0x20); break; case PAK_MEM: mempak_read_command(&cont->mempak, cmd); break; case PAK_RUMBLE: rumblepak_read_command(&cont->rumblepak, cmd); break; case PAK_TRANSFER: /* TODO */ break; default: DebugMessage(M64MSG_WARNING, "Unknown plugged pak %d", (int)pak); } cmd[0x25] = pak_data_crc(&cmd[5]); } static void controller_write_pak_command(struct game_controller* cont, uint8_t* cmd) { enum pak_type pak; int connected = game_controller_is_connected(cont, &pak); if (!connected) { cmd[1] |= 0x80; return; } switch (pak) { case PAK_NONE: /* do nothing */ break; case PAK_MEM: mempak_write_command(&cont->mempak, cmd); break; case PAK_RUMBLE: rumblepak_write_command(&cont->rumblepak, cmd); break; case PAK_TRANSFER: /* TODO */ break; default: DebugMessage(M64MSG_WARNING, "Unknown plugged pak %d", (int)pak); } cmd[0x25] = pak_data_crc(&cmd[5]); } int game_controller_is_connected(struct game_controller* cont, enum pak_type* pak) { return cont->is_connected(cont->user_data, pak); } uint32_t game_controller_get_input(struct game_controller* cont) { return cont->get_input(cont->user_data); } void process_controller_command(struct game_controller* cont, uint8_t* cmd) { switch (cmd[2]) { case PIF_CMD_STATUS: case PIF_CMD_RESET: controller_status_command(cont, cmd); break; case PIF_CMD_CONTROLLER_READ: controller_read_buttons_command(cont, cmd); break; case PIF_CMD_PAK_READ: controller_read_pak_command(cont, cmd); break; case PIF_CMD_PAK_WRITE: controller_write_pak_command(cont, cmd); break; } } void read_controller(struct game_controller* cont, uint8_t* cmd) { switch (cmd[2]) { case PIF_CMD_CONTROLLER_READ: read_controller_read_buttons(cont, cmd); break; } } mupen64plus-video-gliden64/src/OGL3X/UniformBlock.cpp000664 001750 001750 00000023423 12655644434 023364 0ustar00sergiosergio000000 000000 #include "UniformBlock.h" #include "../Config.h" #include "../Textures.h" static const char * strTextureUniforms[UniformBlock::tuTotal] = { "uTexScale", "uTexOffset", "uCacheScale", "uCacheOffset", "uCacheShiftScale", "uCacheFrameBuffer" }; static const char * strColorUniforms[UniformBlock::cuTotal] = { "uFogColor", "uCenterColor", "uScaleColor", "uBlendColor", "uEnvColor", "uPrimColor", "uPrimLod", "uK4", "uK5" }; static const char * strLightUniforms[UniformBlock::luTotal] = { "uLightDirection", "uLightColor" }; UniformBlock::UniformBlock() : m_currentBuffer(0), m_renderer(video().getRender().getRenderer()) { } UniformBlock::~UniformBlock() { } void UniformBlock::_initTextureBuffer(GLuint _program) { const GLint blockSize = m_textureBlock.initBuffer(_program, "TextureBlock", strTextureUniforms); if (blockSize == 0) return; m_textureBlockData.resize(blockSize); GLbyte * pData = m_textureBlockData.data(); memset(pData, 0, blockSize); glBindBuffer(GL_UNIFORM_BUFFER, m_textureBlock.m_buffer); glBufferData(GL_UNIFORM_BUFFER, blockSize, 0, GL_DYNAMIC_DRAW); glBindBufferBase(GL_UNIFORM_BUFFER, m_textureBlock.m_blockBindingPoint, m_textureBlock.m_buffer); updateTextureParameters(); } void UniformBlock::_initColorsBuffer(GLuint _program) { const GLint blockSize = m_colorsBlock.initBuffer(_program, "ColorsBlock", strColorUniforms); if (blockSize == 0) return; m_colorsBlockData.resize(blockSize); GLbyte * pData = m_colorsBlockData.data(); memset(pData, 0, blockSize); memcpy(pData + m_colorsBlock.m_offsets[cuFogColor], &gDP.fogColor.r, sizeof(f32)* 4); memcpy(pData + m_colorsBlock.m_offsets[cuCenterColor], &gDP.key.center.r, sizeof(f32)* 4); memcpy(pData + m_colorsBlock.m_offsets[cuScaleColor], &gDP.key.scale.r, sizeof(f32)* 4); memcpy(pData + m_colorsBlock.m_offsets[cuEnvColor], &gDP.envColor.r, sizeof(f32)* 4); memcpy(pData + m_colorsBlock.m_offsets[cuPrimColor], &gDP.primColor.r, sizeof(f32)* 4); *(f32*)(pData + m_colorsBlock.m_offsets[cuPrimLod]) = gDP.primColor.l; *(f32*)(pData + m_colorsBlock.m_offsets[cuK4]) = gDP.convert.k4*0.0039215689f; *(f32*)(pData + m_colorsBlock.m_offsets[cuK5]) = gDP.convert.k5*0.0039215689f; glBindBuffer(GL_UNIFORM_BUFFER, m_colorsBlock.m_buffer); glBufferData(GL_UNIFORM_BUFFER, blockSize, pData, GL_DYNAMIC_DRAW); glBindBufferBase(GL_UNIFORM_BUFFER, m_colorsBlock.m_blockBindingPoint, m_colorsBlock.m_buffer); m_currentBuffer = m_colorsBlock.m_buffer; } void UniformBlock::_initLightBuffer(GLuint _program) { const GLint blockSize = m_lightBlock.initBuffer(_program, "LightBlock", strLightUniforms); if (blockSize == 0) return; m_lightBlockData.resize(blockSize); GLbyte * pData = m_lightBlockData.data(); memset(pData, 0, blockSize); glBindBuffer(GL_UNIFORM_BUFFER, m_lightBlock.m_buffer); glBufferData(GL_UNIFORM_BUFFER, blockSize, 0, GL_DYNAMIC_DRAW); glBindBufferBase(GL_UNIFORM_BUFFER, m_lightBlock.m_blockBindingPoint, m_lightBlock.m_buffer); updateLightParameters(); } bool UniformBlock::_isDataChanged(void * _pBuffer, const void * _pData, u32 _dataSize) { u32 * pSrc = (u32*)_pData; u32 * pDst = (u32*)_pBuffer; u32 cnt = _dataSize / 4; for (u32 i = 0; i < cnt; ++i) { if (pSrc[i] != pDst[i]) { memcpy(_pBuffer, _pData, _dataSize); return true; } } return false; } void UniformBlock::bindWithShaderCombiner(ShaderCombiner * _pCombiner) { const GLuint program = _pCombiner->m_program; if (_pCombiner->usesTexture()) { if (m_textureBlock.m_buffer == 0) _initTextureBuffer(program); else { const GLint blockIndex = glGetUniformBlockIndex(program, "TextureBlock"); if (blockIndex != GL_INVALID_INDEX) glUniformBlockBinding(program, blockIndex, m_textureBlock.m_blockBindingPoint); } } if (m_colorsBlock.m_buffer == 0) _initColorsBuffer(program); else { const GLint blockIndex = glGetUniformBlockIndex(program, "ColorsBlock"); if (blockIndex != GL_INVALID_INDEX) glUniformBlockBinding(program, blockIndex, m_colorsBlock.m_blockBindingPoint); } if (_pCombiner->usesShadeColor() && config.generalEmulation.enableHWLighting != 0) { if (m_lightBlock.m_buffer == 0) _initLightBuffer(program); else { const GLint blockIndex = glGetUniformBlockIndex(program, "LightBlock"); if (blockIndex != GL_INVALID_INDEX) glUniformBlockBinding(program, blockIndex, m_lightBlock.m_blockBindingPoint); } } } void UniformBlock::setColorData(ColorUniforms _index, u32 _dataSize, const void * _data) { if (m_colorsBlock.m_buffer == 0) return; if (!_isDataChanged(m_colorsBlockData.data() + m_colorsBlock.m_offsets[_index], _data, _dataSize)) return; if (m_currentBuffer != m_colorsBlock.m_buffer) { m_currentBuffer = m_colorsBlock.m_buffer; glBindBuffer(GL_UNIFORM_BUFFER, m_colorsBlock.m_buffer); } if (m_renderer != OGLRender::glrAdreno) glBufferSubData(GL_UNIFORM_BUFFER, m_colorsBlock.m_offsets[_index], _dataSize, _data); else glBufferData(GL_UNIFORM_BUFFER, m_colorsBlockData.size(), m_colorsBlockData.data(), GL_STATIC_DRAW); } void UniformBlock::updateTextureParameters() { if (m_textureBlock.m_buffer == 0) return; GLbyte * pData = m_textureBlockData.data(); f32 texScale[4] = { gSP.texture.scales, gSP.texture.scalet, 0, 0 }; memcpy(pData + m_textureBlock.m_offsets[tuTexScale], texScale, m_textureBlock.m_offsets[tuTexOffset] - m_textureBlock.m_offsets[tuTexScale]); f32 texOffset[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; if (gSP.textureTile[0] != NULL) { if (gSP.textureTile[0]->textureMode != TEXTUREMODE_BGIMAGE && gSP.textureTile[0]->textureMode != TEXTUREMODE_FRAMEBUFFER_BG) { texOffset[0] = gSP.textureTile[0]->fuls; texOffset[1] = gSP.textureTile[0]->fult; FrameBuffer * pBuffer = gSP.textureTile[0]->frameBuffer; if (pBuffer != NULL) { if (gSP.textureTile[0]->masks > 0 && gSP.textureTile[0]->clamps == 0) texOffset[0] = float(gSP.textureTile[0]->uls % (1 << gSP.textureTile[0]->masks)); if (gSP.textureTile[0]->maskt > 0 && gSP.textureTile[0]->clampt == 0) texOffset[1] = float(gSP.textureTile[0]->ult % (1 << gSP.textureTile[0]->maskt)); } } } if (gSP.textureTile[1] != 0) { texOffset[4] = gSP.textureTile[1]->fuls; texOffset[5] = gSP.textureTile[1]->fult; FrameBuffer * pBuffer = gSP.textureTile[1]->frameBuffer; if (pBuffer != NULL) { if (gSP.textureTile[1]->masks > 0 && gSP.textureTile[1]->clamps == 0) texOffset[4] = float(gSP.textureTile[1]->uls % (1 << gSP.textureTile[1]->masks)); if (gSP.textureTile[1]->maskt > 0 && gSP.textureTile[1]->clampt == 0) texOffset[5] = float(gSP.textureTile[1]->ult % (1 << gSP.textureTile[1]->maskt)); } } memcpy(pData + m_textureBlock.m_offsets[tuTexOffset], texOffset, m_textureBlock.m_offsets[tuCacheScale] - m_textureBlock.m_offsets[tuTexOffset]); f32 texCacheScale[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; f32 texCacheOffset[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; f32 texCacheShiftScale[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; GLint texCacheFrameBuffer[4] = { 0, 0, 0, 0 }; TextureCache & cache = textureCache(); if (cache.current[0]) { texCacheScale[0] = cache.current[0]->scaleS; texCacheScale[1] = cache.current[0]->scaleT; texCacheOffset[0] = cache.current[0]->offsetS; texCacheOffset[1] = cache.current[0]->offsetT; f32 shiftScaleS = 1.0f; f32 shiftScaleT = 1.0f; getTextureShiftScale(0, cache, shiftScaleS, shiftScaleT); texCacheShiftScale[0] = shiftScaleS; texCacheShiftScale[1] = shiftScaleT; texCacheFrameBuffer[0] = cache.current[0]->frameBufferTexture; } if (cache.current[1]) { texCacheScale[4] = cache.current[1]->scaleS; texCacheScale[5] = cache.current[1]->scaleT; texCacheOffset[4] = cache.current[1]->offsetS; texCacheOffset[5] = cache.current[1]->offsetT; f32 shiftScaleS = 1.0f; f32 shiftScaleT = 1.0f; getTextureShiftScale(1, cache, shiftScaleS, shiftScaleT); texCacheShiftScale[4] = shiftScaleS; texCacheShiftScale[5] = shiftScaleT; texCacheFrameBuffer[1] = cache.current[1]->frameBufferTexture; } memcpy(pData + m_textureBlock.m_offsets[tuCacheScale], texCacheScale, m_textureBlock.m_offsets[tuCacheOffset] - m_textureBlock.m_offsets[tuCacheScale]); memcpy(pData + m_textureBlock.m_offsets[tuCacheOffset], texCacheOffset, m_textureBlock.m_offsets[tuCacheShiftScale] - m_textureBlock.m_offsets[tuCacheOffset]); memcpy(pData + m_textureBlock.m_offsets[tuCacheShiftScale], texCacheShiftScale, m_textureBlock.m_offsets[tuCacheFrameBuffer] - m_textureBlock.m_offsets[tuCacheShiftScale]); memcpy(pData + m_textureBlock.m_offsets[tuCacheFrameBuffer], texCacheFrameBuffer, m_textureBlockData.size() - m_textureBlock.m_offsets[tuCacheFrameBuffer]); if (m_currentBuffer != m_textureBlock.m_buffer) { m_currentBuffer = m_textureBlock.m_buffer; glBindBuffer(GL_UNIFORM_BUFFER, m_textureBlock.m_buffer); } if (m_renderer != OGLRender::glrAdreno) glBufferSubData(GL_UNIFORM_BUFFER, m_textureBlock.m_offsets[tuTexScale], m_textureBlockData.size(), pData); else glBufferData(GL_UNIFORM_BUFFER, m_textureBlockData.size(), m_textureBlockData.data(), GL_STATIC_DRAW); } void UniformBlock::updateLightParameters() { if (m_lightBlock.m_buffer == 0) return; GLbyte * pData = m_lightBlockData.data(); const u32 arraySize = m_lightBlock.m_offsets[luLightColor] / 8; for (s32 i = 0; i <= gSP.numLights; ++i) { memcpy(pData + m_lightBlock.m_offsets[luLightDirection] + arraySize*i, &gSP.lights[i].x, arraySize); memcpy(pData + m_lightBlock.m_offsets[luLightColor] + arraySize*i, &gSP.lights[i].r, arraySize); } if (m_currentBuffer != m_lightBlock.m_buffer) { m_currentBuffer = m_lightBlock.m_buffer; glBindBuffer(GL_UNIFORM_BUFFER, m_lightBlock.m_buffer); } if (m_renderer != OGLRender::glrAdreno) glBufferSubData(GL_UNIFORM_BUFFER, m_lightBlock.m_offsets[luLightDirection], m_lightBlockData.size(), pData); else glBufferData(GL_UNIFORM_BUFFER, m_lightBlockData.size(), m_lightBlockData.data(), GL_STATIC_DRAW); } UniformCollection * createUniformCollection() { return new UniformBlock(); } mupen64plus-video-gliden64/src/mupenplus/OpenGL_mupenplus.cpp000664 001750 001750 00000011135 12655644434 025417 0ustar00sergiosergio000000 000000 #include "GLideN64_mupenplus.h" #include #include "../GLideN64.h" #include "../OpenGL.h" #include "../gDP.h" #include "../Config.h" #include "../Revision.h" #include "../Log.h" #ifdef VC #include #endif #if !defined(OS_WINDOWS) || defined(GLES2) || defined(GLES3) || defined(GLES3_1) void initGLFunctions() { } #endif class OGLVideoMupenPlus : public OGLVideo { public: OGLVideoMupenPlus() {} private: void _setAttributes(); void _getDisplaySize(); virtual bool _start(); virtual void _stop(); virtual void _swapBuffers(); virtual void _saveScreenshot(); virtual bool _resizeWindow(); virtual void _changeWindow(); }; OGLVideo & OGLVideo::get() { static OGLVideoMupenPlus video; return video; } void OGLVideoMupenPlus::_setAttributes() { #ifdef GLES2 CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MAJOR_VERSION, 2); CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MINOR_VERSION, 0); LOG(LOG_VERBOSE, "[gles2GlideN64]: _setAttributes\n"); #elif defined(GLES3) CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MAJOR_VERSION, 3); CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MINOR_VERSION, 0); #elif defined(GLES3_1) CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MAJOR_VERSION, 3); CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MINOR_VERSION, 1); #elif defined(OS_MAC_OS_X) CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MAJOR_VERSION, 3); CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MINOR_VERSION, 2); #else // Do nothing #endif CoreVideo_GL_SetAttribute(M64P_GL_DOUBLEBUFFER, 1); CoreVideo_GL_SetAttribute(M64P_GL_SWAP_CONTROL, config.video.verticalSync); CoreVideo_GL_SetAttribute(M64P_GL_BUFFER_SIZE, 32); CoreVideo_GL_SetAttribute(M64P_GL_DEPTH_SIZE, 16); if (config.video.multisampling > 0 && config.frameBufferEmulation.enable == 0) { CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLEBUFFERS, 1); if (config.video.multisampling <= 2) CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 2); else if (config.video.multisampling <= 4) CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 4); else if (config.video.multisampling <= 8) CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 8); else CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 16); } } bool OGLVideoMupenPlus::_start() { CoreVideo_Init(); _setAttributes(); m_bFullscreen = config.video.fullscreen > 0; m_screenWidth = config.video.windowedWidth; m_screenHeight = config.video.windowedHeight; _getDisplaySize(); _setBufferSize(); printf("(II) Setting video mode %dx%d...\n", m_screenWidth, m_screenHeight); const m64p_video_flags flags = M64VIDEOFLAG_SUPPORT_RESIZING; if (CoreVideo_SetVideoMode(m_screenWidth, m_screenHeight, 0, m_bFullscreen ? M64VIDEO_FULLSCREEN : M64VIDEO_WINDOWED, flags) != M64ERR_SUCCESS) { //printf("(EE) Error setting videomode %dx%d\n", m_screenWidth, m_screenHeight); LOG(LOG_ERROR, "[gles2GlideN64]: Error setting videomode %dx%d\n", m_screenWidth, m_screenHeight); CoreVideo_Quit(); return false; } LOG(LOG_VERBOSE, "[gles2GlideN64]: Create setting videomode %dx%d\n", m_screenWidth, m_screenHeight); return true; } void OGLVideoMupenPlus::_stop() { CoreVideo_Quit(); } void OGLVideoMupenPlus::_swapBuffers() { // if emulator defined a render callback function, call it before buffer swap if (renderCallback != NULL) { glUseProgram(0); if (config.frameBufferEmulation.N64DepthCompare == 0) { glViewport(0, getHeightOffset(), getScreenWidth(), getScreenHeight()); gSP.changed |= CHANGED_VIEWPORT; } gDP.changed |= CHANGED_COMBINE; (*renderCallback)((gDP.changed&CHANGED_CPU_FB_WRITE) == 0 ? 1 : 0); } CoreVideo_GL_SwapBuffers(); } void OGLVideoMupenPlus::_saveScreenshot() { } bool OGLVideoMupenPlus::_resizeWindow() { _setAttributes(); m_bFullscreen = false; m_width = m_screenWidth = m_resizeWidth; m_height = m_screenHeight = m_resizeHeight; if (CoreVideo_ResizeWindow(m_screenWidth, m_screenHeight) != M64ERR_SUCCESS) { printf("(EE) Error setting videomode %dx%d\n", m_screenWidth, m_screenHeight); m_width = m_screenWidth = config.video.windowedWidth; m_height = m_screenHeight = config.video.windowedHeight; CoreVideo_Quit(); return false; } _setBufferSize(); isGLError(); // reset GL error. return true; } void OGLVideoMupenPlus::_changeWindow() { CoreVideo_ToggleFullScreen(); } void OGLVideoMupenPlus::_getDisplaySize() { #ifdef VC if( m_bFullscreen ) { // Use VC get_display_size function to get the current screen resolution u32 fb_width; u32 fb_height; if (graphics_get_display_size(0 /* LCD */, &fb_width, &fb_height) < 0) printf("ERROR: Failed to get display size\n"); else { m_screenWidth = fb_width; m_screenHeight = fb_height; } } #endif } mupen64plus-core/src/r4300/hacktarux_dynarec/gtlb.c000664 001750 001750 00000004137 12655644434 023206 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - gtlb.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include "assemble.h" #include "r4300/cached_interp.h" #include "r4300/recomph.h" #include "r4300/r4300.h" #include "r4300/ops.h" void gentlbwi(void) { gencallinterp((native_type)cached_interpreter_table.TLBWI, 0); } void gentlbp(void) { gencallinterp((native_type)cached_interpreter_table.TLBP, 0); } void gentlbr(void) { gencallinterp((native_type)cached_interpreter_table.TLBR, 0); } void generet(void) { gencallinterp((native_type)cached_interpreter_table.ERET, 1); } void gentlbwr(void) { gencallinterp((native_type)cached_interpreter_table.TLBWR, 0); } mupen64plus-video-gliden64/src/ZSort.h000664 001750 001750 00000000107 12655644434 020656 0ustar00sergiosergio000000 000000 #ifndef ZSORT_H #define ZSORT_H void ZSort_Init(); #endif // ZSORT_H mupen64plus-video-gliden64/src/F3DSWSE.h000664 001750 001750 00000000103 12655644434 020647 0ustar00sergiosergio000000 000000 #ifndef F3DSWSE_H #define F3DSWSE_H void F3DSWSE_Init(); #endif mupen64plus-video-gliden64/src/VI.h000664 001750 001750 00000000562 12655644434 020120 0ustar00sergiosergio000000 000000 #ifndef VI_H #define VI_H #include "Types.h" struct VIInfo { u32 width, widthPrev, height, real_height; f32 rwidth, rheight; u32 lastOrigin; bool interlaced; bool PAL; VIInfo() : width(0), widthPrev(0), height(0), real_height(0), lastOrigin(-1), interlaced(false), PAL(false) {} }; extern VIInfo VI; void VI_UpdateSize(); void VI_UpdateScreen(); #endif libretro/brumme_crc.c000664 001750 001750 00000023120 12655644434 016021 0ustar00sergiosergio000000 000000 /* * Stephan Brumme's CRC32 implementation * * This file has been truncated because the original contents contain many * implementations and a test programs that we are not interested in. * * * crc32_4bytes, crc32_8bytes and crc32_16bytes are based/derived from Intel's * Slicing-by-4 algorithm available at http://sourceforge.net/projects/slicing-by-8/ * * See http://create.stephan-brumme.com/crc32/ for more information. * * ------------------------------- * * LICENSE (retrieved in 2015-05-24) * * All source code published on http://create.stephan-brumme.com and its * sub-pages is licensed similar to the zlib license: * * This software is provided 'as-is', without any express or implied warranty. * In no event will the author be held liable for any damages arising from the * use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. * * If you use this software in a product, an acknowledgment in the product * documentation would be appreciated but is not required. * * Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * * If you like / hate / ignore my software, send me an email or, even better, a * nice postcard. Thank you ! :) * * ------------------------------- * * Author note: * if running on an embedded system, you might consider shrinking the * big Crc32Lookup table: * - crc32_4bytes needs only Crc32Lookup[0..3] * - crc32_8bytes needs only Crc32Lookup[0..7] * - crc32_16bytes needs all of Crc32Lookup */ #include #include #include #ifdef _MSC_VER typedef unsigned __int8 uint8_t; typedef unsigned __int32 uint32_t; typedef signed __int32 int32_t; #else #include #endif /// zlib's CRC32 polynomial //static const uint32_t Polynomial = 0xEDB88320; static const uint32_t Polynomial = 0x04C11DB7; /* same as libretro_crc.c */ #define MaxSlice 16 static uint32_t Crc32Lookup[MaxSlice][256]; static bool table_initialized = false; static INLINE uint32_t swap(uint32_t x) { #if defined(__GNUC__) || defined(__clang__) return __builtin_bswap32(x); #else #if defined(_MSC_VER) return _byteswap_ulong(x); #else return (x >> 24) | ((x >> 8) & 0x0000FF00) | ((x << 8) & 0x00FF0000) | (x << 24); #endif #endif } static uint32_t crc32_1byte(const void* data, size_t length, uint32_t previousCrc32); static uint32_t crc32_4bytes(const void* data, size_t length, uint32_t previousCrc32); static uint32_t crc32_8bytes(const void* data, size_t length, uint32_t previousCrc32); static uint32_t crc32_16bytes(const void* data, size_t length, uint32_t previousCrc32); void CRC_BuildTable(void) { int i, j, slice; if (table_initialized) return; table_initialized = true; for (i = 0; i <= 0xFF; i++) { uint32_t crc = i; for (j = 0; j < 8; j++) crc = (crc >> 1) ^ ((crc & 1) * Polynomial); Crc32Lookup[0][i] = crc; } for (slice = 1; slice < MaxSlice; slice++) for (i = 0; i <= 0xFF; i++) Crc32Lookup[slice][i] = (Crc32Lookup[slice - 1][i] >> 8) ^ Crc32Lookup[0][Crc32Lookup[slice - 1][i] & 0xFF]; } unsigned int CRC32(unsigned int crc, void *buffer, unsigned int count) { return crc32_8bytes(buffer, count, crc); } uint32_t CRC_Calculate(void *buffer, uint32_t count) { return CRC32(0xffffffff, buffer, count); } uint32_t adler32(uint32_t adler, void *buf, int len) { return CRC32(adler, buf, len); } /// compute CRC32 (standard algorithm) static uint32_t crc32_1byte(const void* data, size_t length, uint32_t previousCrc32) { uint32_t crc = ~previousCrc32; // same as previousCrc32 ^ 0xFFFFFFFF const uint8_t* current = (const uint8_t*) data; while (length-- > 0) crc = (crc >> 8) ^ Crc32Lookup[0][(crc & 0xFF) ^ *current++]; return ~crc; // same as crc ^ 0xFFFFFFFF } /// compute CRC32 (Slicing-by-4 algorithm) static uint32_t crc32_4bytes(const void* data, size_t length, uint32_t previousCrc32) { uint32_t crc = ~previousCrc32; // same as previousCrc32 ^ 0xFFFFFFFF const uint32_t* current = (const uint32_t*) data; // process four bytes at once (Slicing-by-4) while (length >= 4) { #ifdef MSB_FIRST uint32_t one = *current++ ^ swap(crc); crc = Crc32Lookup[0][ one & 0xFF] ^ Crc32Lookup[1][(one>> 8) & 0xFF] ^ Crc32Lookup[2][(one>>16) & 0xFF] ^ Crc32Lookup[3][(one>>24) & 0xFF]; #else uint32_t one = *current++ ^ crc; crc = Crc32Lookup[0][(one>>24) & 0xFF] ^ Crc32Lookup[1][(one>>16) & 0xFF] ^ Crc32Lookup[2][(one>> 8) & 0xFF] ^ Crc32Lookup[3][ one & 0xFF]; #endif length -= 4; } const uint8_t* currentChar = (const uint8_t*) current; // remaining 1 to 3 bytes (standard algorithm) while (length-- != 0) crc = (crc >> 8) ^ Crc32Lookup[0][(crc & 0xFF) ^ *currentChar++]; return ~crc; // same as crc ^ 0xFFFFFFFF } /// compute CRC32 (Slicing-by-8 algorithm) static uint32_t crc32_8bytes(const void* data, size_t length, uint32_t previousCrc32) { uint32_t crc = ~previousCrc32; // same as previousCrc32 ^ 0xFFFFFFFF const uint32_t* current = (const uint32_t*) data; // process eight bytes at once (Slicing-by-8) while (length >= 8) { #ifdef MSB_FIRST uint32_t one = *current++ ^ swap(crc); uint32_t two = *current++; crc = Crc32Lookup[0][ two & 0xFF] ^ Crc32Lookup[1][(two>> 8) & 0xFF] ^ Crc32Lookup[2][(two>>16) & 0xFF] ^ Crc32Lookup[3][(two>>24) & 0xFF] ^ Crc32Lookup[4][ one & 0xFF] ^ Crc32Lookup[5][(one>> 8) & 0xFF] ^ Crc32Lookup[6][(one>>16) & 0xFF] ^ Crc32Lookup[7][(one>>24) & 0xFF]; #else uint32_t one = *current++ ^ crc; uint32_t two = *current++; crc = Crc32Lookup[0][(two>>24) & 0xFF] ^ Crc32Lookup[1][(two>>16) & 0xFF] ^ Crc32Lookup[2][(two>> 8) & 0xFF] ^ Crc32Lookup[3][ two & 0xFF] ^ Crc32Lookup[4][(one>>24) & 0xFF] ^ Crc32Lookup[5][(one>>16) & 0xFF] ^ Crc32Lookup[6][(one>> 8) & 0xFF] ^ Crc32Lookup[7][ one & 0xFF]; #endif length -= 8; } const uint8_t* currentChar = (const uint8_t*) current; // remaining 1 to 7 bytes (standard algorithm) while (length-- != 0) crc = (crc >> 8) ^ Crc32Lookup[0][(crc & 0xFF) ^ *currentChar++]; return ~crc; // same as crc ^ 0xFFFFFFFF } /// compute CRC32 (Slicing-by-16 algorithm) static uint32_t crc32_16bytes(const void* data, size_t length, uint32_t previousCrc32) { uint32_t crc = ~previousCrc32; // same as previousCrc32 ^ 0xFFFFFFFF const uint32_t* current = (const uint32_t*) data; // enabling optimization (at least -O2) automatically unrolls the inner for-loop const size_t Unroll = 4; const size_t BytesAtOnce = 16 * Unroll; while (length >= BytesAtOnce) { size_t unrolling; for (unrolling = 0; unrolling < Unroll; unrolling++) { #ifdef MSB_FIRST uint32_t one = *current++ ^ swap(crc); uint32_t two = *current++; uint32_t three = *current++; uint32_t four = *current++; crc = Crc32Lookup[ 0][ four & 0xFF] ^ Crc32Lookup[ 1][(four >> 8) & 0xFF] ^ Crc32Lookup[ 2][(four >> 16) & 0xFF] ^ Crc32Lookup[ 3][(four >> 24) & 0xFF] ^ Crc32Lookup[ 4][ three & 0xFF] ^ Crc32Lookup[ 5][(three >> 8) & 0xFF] ^ Crc32Lookup[ 6][(three >> 16) & 0xFF] ^ Crc32Lookup[ 7][(three >> 24) & 0xFF] ^ Crc32Lookup[ 8][ two & 0xFF] ^ Crc32Lookup[ 9][(two >> 8) & 0xFF] ^ Crc32Lookup[10][(two >> 16) & 0xFF] ^ Crc32Lookup[11][(two >> 24) & 0xFF] ^ Crc32Lookup[12][ one & 0xFF] ^ Crc32Lookup[13][(one >> 8) & 0xFF] ^ Crc32Lookup[14][(one >> 16) & 0xFF] ^ Crc32Lookup[15][(one >> 24) & 0xFF]; #else uint32_t one = *current++ ^ crc; uint32_t two = *current++; uint32_t three = *current++; uint32_t four = *current++; crc = Crc32Lookup[ 0][(four >> 24) & 0xFF] ^ Crc32Lookup[ 1][(four >> 16) & 0xFF] ^ Crc32Lookup[ 2][(four >> 8) & 0xFF] ^ Crc32Lookup[ 3][ four & 0xFF] ^ Crc32Lookup[ 4][(three >> 24) & 0xFF] ^ Crc32Lookup[ 5][(three >> 16) & 0xFF] ^ Crc32Lookup[ 6][(three >> 8) & 0xFF] ^ Crc32Lookup[ 7][ three & 0xFF] ^ Crc32Lookup[ 8][(two >> 24) & 0xFF] ^ Crc32Lookup[ 9][(two >> 16) & 0xFF] ^ Crc32Lookup[10][(two >> 8) & 0xFF] ^ Crc32Lookup[11][ two & 0xFF] ^ Crc32Lookup[12][(one >> 24) & 0xFF] ^ Crc32Lookup[13][(one >> 16) & 0xFF] ^ Crc32Lookup[14][(one >> 8) & 0xFF] ^ Crc32Lookup[15][ one & 0xFF]; #endif } length -= BytesAtOnce; } const uint8_t* currentChar = (const uint8_t*) current; // remaining 1 to 63 bytes (standard algorithm) while (length-- != 0) crc = (crc >> 8) ^ Crc32Lookup[0][(crc & 0xFF) ^ *currentChar++]; return ~crc; // same as crc ^ 0xFFFFFFFF } gles2rice/src/GraphicsContext.cpp000664 001750 001750 00000003401 12655644434 020174 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define M64P_PLUGIN_PROTOTYPES 1 #include "m64p_plugin.h" #include "m64p_vidext.h" #include "FrameBuffer.h" #include "OGLGraphicsContext.h" #include "Video.h" CGraphicsContext* CGraphicsContext::g_pGraphicsContext = NULL; bool CGraphicsContext::needCleanScene = false; CGraphicsContext * CGraphicsContext::Get(void) { return CGraphicsContext::g_pGraphicsContext; } CGraphicsContext::CGraphicsContext() { } CGraphicsContext::~CGraphicsContext() { g_pFrameBufferManager->CloseUp(); } void CGraphicsContext::InitWindowInfo() { } bool CGraphicsContext::Initialize(uint32_t dwWidth, uint32_t dwHeight) { g_pFrameBufferManager->Initialize(); return true; } bool CGraphicsContext::ResizeInitialize(uint32_t dwWidth, uint32_t dwHeight ) { return true; } void CGraphicsContext::CleanUp() { } // This is a static function, will be called when the plugin DLL is initialized void CGraphicsContext::InitDeviceParameters(void) { // To initialize device parameters for OpenGL COGLGraphicsContext::InitDeviceParameters(); } mupen64plus-video-gliden64/src/GLideNHQ/Ext_TxFilter.h000664 001750 001750 00000017113 12655644434 023516 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __EXT_TXFILTER_H__ #define __EXT_TXFILTER_H__ #ifdef OS_WINDOWS #include #define TXHMODULE HMODULE #define DLOPEN(a) LoadLibraryW(a) #define DLCLOSE(a) FreeLibrary(a) #define DLSYM(a, b) GetProcAddress(a, b) #define GETCWD(a, b) GetCurrentDirectoryW(a, b) #define CHDIR(a) SetCurrentDirectoryW(a) #else #include #include #include #define MAX_PATH 4095 #define TXHMODULE void* #define DLOPEN(a) dlopen(a, RTLD_LAZY|RTLD_GLOBAL) #define DLCLOSE(a) dlclose(a) #define DLSYM(a, b) dlsym(a, b) #define GETCWD(a, b) getcwd(b, a) #define CHDIR(a) chdir(a) #endif #ifdef __MSC__ typedef __int64 int64; typedef unsigned __int64 uint64; #else typedef long long int64; typedef unsigned long long uint64; typedef unsigned char boolean; #endif #define NO_OPTIONS 0x00000000 #define FILTER_MASK 0x000000ff #define NO_FILTER 0x00000000 #define SMOOTH_FILTER_MASK 0x0000000f #define NO_SMOOTH_FILTER 0x00000000 #define SMOOTH_FILTER_1 0x00000001 #define SMOOTH_FILTER_2 0x00000002 #define SMOOTH_FILTER_3 0x00000003 #define SMOOTH_FILTER_4 0x00000004 #define SHARP_FILTER_MASK 0x000000f0 #define NO_SHARP_FILTER 0x00000000 #define SHARP_FILTER_1 0x00000010 #define SHARP_FILTER_2 0x00000020 #define ENHANCEMENT_MASK 0x00000f00 #define NO_ENHANCEMENT 0x00000000 #define X2_ENHANCEMENT 0x00000100 #define X2SAI_ENHANCEMENT 0x00000200 #define HQ2X_ENHANCEMENT 0x00000300 #define LQ2X_ENHANCEMENT 0x00000400 #define HQ4X_ENHANCEMENT 0x00000500 #define HQ2XS_ENHANCEMENT 0x00000600 #define LQ2XS_ENHANCEMENT 0x00000700 #define BRZ2X_ENHANCEMENT 0x00000800 #define BRZ3X_ENHANCEMENT 0x00000900 #define BRZ4X_ENHANCEMENT 0x00000a00 #define BRZ5X_ENHANCEMENT 0x00000b00 #define BRZ6X_ENHANCEMENT 0x00000c00 #define HIRESTEXTURES_MASK 0x000f0000 #define NO_HIRESTEXTURES 0x00000000 #define GHQ_HIRESTEXTURES 0x00010000 #define RICE_HIRESTEXTURES 0x00020000 #define JABO_HIRESTEXTURES 0x00030000 //#define COMPRESS_TEX 0x00100000 // Not used anymore //#define COMPRESS_HIRESTEX 0x00200000 // Not used anymore #define GZ_TEXCACHE 0x00400000 #define GZ_HIRESTEXCACHE 0x00800000 #define DUMP_TEXCACHE 0x01000000 #define DUMP_HIRESTEXCACHE 0x02000000 #define TILE_HIRESTEX 0x04000000 #define UNDEFINED_0 0x08000000 #define FORCE16BPP_HIRESTEX 0x10000000 #define FORCE16BPP_TEX 0x20000000 #define LET_TEXARTISTS_FLY 0x40000000 /* a little freedom for texture artists */ #define DUMP_TEX 0x80000000 struct GHQTexInfo { unsigned char *data; int width; int height; unsigned int format; unsigned short texture_format; unsigned short pixel_type; unsigned char is_hires_tex; GHQTexInfo() : data(NULL), width(0), height(0), format(0), texture_format(0), pixel_type(0), is_hires_tex(0) {} }; /* Callback to display hires texture info. * Gonetz * * void DispInfo(const char *format, ...) * { * va_list args; * char buf[INFO_BUF]; * * va_start(args, format); * vsprintf(buf, format, args); * va_end(args); * * printf(buf); * } */ #define INFO_BUF 4095 typedef void (*dispInfoFuncExt)(const wchar_t *format, ...); /* dll exports */ /* Use TXFilter as a library. Define exported functions. */ #ifdef OS_WINDOWS #ifdef TXFILTER_LIB #define TAPI __declspec(dllexport) #define TAPIENTRY #else #define TAPI #define TAPIENTRY #endif #else // OS_WINDOWS #ifdef TXFILTER_LIB #define TAPI __attribute__((visibility("default"))) #define TAPIENTRY #else #define TAPI #define TAPIENTRY #endif #endif // OS_WINDOWS #ifdef TXFILTER_DLL typedef unsigned char uint8; typedef unsigned short uint16; typedef unsigned long uint32; boolean ext_ghq_init(int maxwidth, /* maximum texture width supported by hardware */ int maxheight,/* maximum texture height supported by hardware */ int maxbpp, /* maximum texture bpp supported by hardware */ int options, /* options */ int cachesize,/* cache textures to system memory */ const wchar_t *path, /* plugin directory. must be smaller than MAX_PATH */ const wchar_t *ident, /* name of ROM. must be no longer than 64 in character. */ dispInfoFuncExt callback /* callback function to display info */ ); void ext_ghq_shutdown(void); boolean ext_ghq_txfilter(unsigned char *src, /* input texture */ int srcwidth, /* width of input texture */ int srcheight, /* height of input texture */ unsigned short srcformat, /* format of input texture */ uint64 g64crc, /* glide64 crc */ GHQTexInfo *info /* output */ ); boolean ext_ghq_hirestex(uint64 g64crc, /* glide64 crc */ uint64 r_crc64, /* checksum hi:palette low:texture */ unsigned short *palette, /* palette for CI textures */ GHQTexInfo *info /* output */ ); uint64 ext_ghq_checksum(unsigned char *src, /* input texture */ int width, /* width of texture */ int height, /* height of texture */ int size, /* type of texture pixel */ int rowStride, /* row stride in bytes */ unsigned char *palette /* palette */ ); boolean ext_ghq_dmptx(unsigned char *src, /* input texture (must be in 3Dfx Glide format) */ int width, /* width of texture */ int height, /* height of texture */ int rowStridePixel, /* row stride of input texture in pixels */ unsigned short gfmt, /* glide format of input texture */ unsigned short n64fmt,/* N64 format hi:format low:size */ uint64 r_crc64 /* checksum hi:palette low:texture */ ); boolean ext_ghq_reloadhirestex(); #else typedef unsigned char uint8; typedef unsigned short uint16; typedef unsigned long uint32; #ifdef __cplusplus extern "C"{ #endif TAPI boolean TAPIENTRY txfilter_init(int maxwidth, int maxheight, int maxbpp, int options, int cachesize, const wchar_t *path, const wchar_t * texPackPath, const wchar_t*ident, dispInfoFuncExt callback); TAPI void TAPIENTRY txfilter_shutdown(void); TAPI boolean TAPIENTRY txfilter_filter(uint8 *src, int srcwidth, int srcheight, uint16 srcformat, uint64 g64crc, GHQTexInfo *info); TAPI boolean TAPIENTRY txfilter_hirestex(uint64 g64crc, uint64 r_crc64, uint16 *palette, GHQTexInfo *info); TAPI uint64 TAPIENTRY txfilter_checksum(uint8 *src, int width, int height, int size, int rowStride, uint8 *palette); TAPI boolean TAPIENTRY txfilter_dmptx(uint8 *src, int width, int height, int rowStridePixel, uint16 gfmt, uint16 n64fmt, uint64 r_crc64); TAPI boolean TAPIENTRY txfilter_reloadhirestex(); #ifdef __cplusplus } #endif #endif /* TXFILTER_DLL */ #endif /* __EXT_TXFILTER_H__ */ mupen64plus-core/src/r4300/hacktarux_dynarec/assemble_struct.h000664 001750 001750 00000003676 12655644434 025471 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - assemble_struct.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2007 Richard Goedeken (Richard42) * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef __ASSEMBLE_STRUCT_H__ #define __ASSEMBLE_STRUCT_H__ #ifdef __x86_64__ #define JUMP_WRAPPER_SIZE 84 #else #define JUMP_WRAPPER_SIZE 62 #endif typedef struct _reg_cache_struct { int need_map; void *needed_registers[8]; unsigned char jump_wrapper[JUMP_WRAPPER_SIZE]; int need_cop1_check; } reg_cache_struct; #endif /* __ASSEMBLE_STRUCT_H__ */ mupen64plus-core/INSTALL000664 001750 001750 00000001515 12655644434 016102 0ustar00sergiosergio000000 000000 Mupen64Plus-Core INSTALL ------------------------ This text file was written to explain the installation process of the Mupen64Plus-Core module. If this module is part of a Mupen64Plus source code bundle, the user should run the "m64p_install.sh" script in the root of the unzipped bundle to install all of the included modules in the bundle. If this module is a standalone source code release, you should build the library from source code and install it via the makefile, like this: $ cd projects/unix $ make all $ sudo make install If you want to build the Mupen64Plus-Core module for installation in a home folder for a single user, you may build it like this (replacing with your desired local installation path): $ cd projects/unix $ make all SHAREDIR= $ make install LIBDIR= SHAREDIR= tools/000700 001750 001750 00000000000 12656647145 013046 5ustar00sergiosergio000000 000000 mupen64plus-video-gliden64/src/S2DEX.h000664 001750 001750 00000015064 12655644434 020432 0ustar00sergiosergio000000 000000 #ifndef S2DEX_H #define S2DEX_H #define G_BGLT_LOADBLOCK 0x0033 #define G_BGLT_LOADTILE 0xfff4 #define G_BG_FLAG_FLIPS 0x01 #define G_BG_FLAG_FLIPT 0x10 #define G_OBJRM_NOTXCLAMP 0x01 #define G_OBJRM_XLU 0x02 #define G_OBJRM_ANTIALIAS 0x04 #define G_OBJRM_BILERP 0x08 #define G_OBJRM_SHRINKSIZE_1 0x10 #define G_OBJRM_SHRINKSIZE_2 0x20 #define G_OBJRM_WIDEN 0x40 struct uObjScaleBg { u16 imageW; /* Texture width (8-byte alignment, u10.2) */ u16 imageX; /* x-coordinate of upper-left position of texture (u10.5) */ u16 frameW; /* Transfer destination frame width (u10.2) */ s16 frameX; /* x-coordinate of upper-left position of transfer destination frame (s10.2) */ u16 imageH; /* Texture height (u10.2) */ u16 imageY; /* y-coordinate of upper-left position of texture (u10.5) */ u16 frameH; /* Transfer destination frame height (u10.2) */ s16 frameY; /* y-coordinate of upper-left position of transfer destination frame (s10.2) */ u32 imagePtr; /* Address of texture source in DRAM*/ u8 imageSiz; /* Texel size G_IM_SIZ_4b (4 bits/texel) G_IM_SIZ_8b (8 bits/texel) G_IM_SIZ_16b (16 bits/texel) G_IM_SIZ_32b (32 bits/texel) */ u8 imageFmt; /*Texel format G_IM_FMT_RGBA (RGBA format) G_IM_FMT_YUV (YUV format) G_IM_FMT_CI (CI format) G_IM_FMT_IA (IA format) G_IM_FMT_I (I format) */ u16 imageLoad; /* Method for loading the BG image texture G_BGLT_LOADBLOCK (use LoadBlock) G_BGLT_LOADTILE (use LoadTile) */ u16 imageFlip; /* Image inversion on/off (horizontal direction only) 0 (normal display (no inversion)) G_BG_FLAG_FLIPS (horizontal inversion of texture image) */ u16 imagePal; /* Position of palette for 4-bit color index texture (4-bit precision, 0~15) */ u16 scaleH; /* y-direction scale value (u5.10) */ u16 scaleW; /* x-direction scale value (u5.10) */ s32 imageYorig; /* image drawing origin (s20.5)*/ u8 padding[4]; /* Padding */ }; /* 40 bytes */ struct uSprite { u32 imagePtr; u32 tlutPtr; s16 imageW; s16 stride; s8 imageSiz; s8 imageFmt; s16 imageH; s16 imageY; s16 imageX; s8 dummy[4]; }; /* 24 bytes */ struct uObjSprite { u16 scaleW; /* Width-direction scaling (u5.10) */ s16 objX; /* x-coordinate of upper-left corner of OBJ (s10.2) */ u16 paddingX; /* Unused (always 0) */ u16 imageW; /* Texture width (length in s direction, u10.5) */ u16 scaleH; /* Height-direction scaling (u5.10) */ s16 objY; /* y-coordinate of upper-left corner of OBJ (s10.2) */ u16 paddingY; /* Unused (always 0) */ u16 imageH; /* Texture height (length in t direction, u10.5) */ u16 imageAdrs; /* Texture starting position in TMEM (In units of 64-bit words) */ u16 imageStride; /* Texel wrapping width (In units of 64-bit words) */ u8 imageFlags; /* Display flag (*) More than one of the following flags can be specified as the bit sum of the flags: 0 (Normal display (no inversion)) G_OBJ_FLAG_FLIPS (s-direction (x) inversion) G_OBJ_FLAG_FLIPT (t-direction (y) inversion) */ u8 imagePal; /* Position of palette for 4-bit color index texture (4-bit precision, 0~7) */ u8 imageSiz; /* Texel size G_IM_SIZ_4b (4 bits/texel) G_IM_SIZ_8b (8 bits/texel) G_IM_SIZ_16b (16 bits/texel) G_IM_SIZ_32b (32 bits/texel) */ u8 imageFmt; /* Texel format G_IM_FMT_RGBA (RGBA format) G_IM_FMT_YUV (YUV format) G_IM_FMT_CI (CI format) G_IM_FMT_IA (IA format) G_IM_FMT_I (I format) */ }; /* 24 bytes */ struct uObjTxtrBlock { u32 type; /* Structure identifier (G_OBJLT_TXTRBLOCK) */ u32 image; /* Texture source address in DRAM (8-byte alignment) */ u16 tsize; /* Texture size (specified by GS_TB_TSIZE) */ u16 tmem; /* TMEM word address where texture will be loaded (8-byte word) */ u16 sid; /* Status ID (multiple of 4: either 0, 4, 8, or 12) */ u16 tline; /* Texture line width (specified by GS_TB_TLINE) */ u32 flag; /* Status flag */ u32 mask; /* Status mask */ }; /* 24 bytes */ struct uObjTxtrTile { u32 type; /* Structure identifier (G_OBJLT_TXTRTILE) */ u32 image; /* Texture source address in DRAM (8-byte alignment) */ u16 twidth; /* Texture width (specified by GS_TT_TWIDTH) */ u16 tmem; /* TMEM word address where texture will be loaded (8-byte word) */ u16 sid; /* Status ID (multiple of 4: either 0, 4, 8, or 12) */ u16 theight;/* Texture height (specified by GS_TT_THEIGHT) */ u32 flag; /* Status flag */ u32 mask; /* Status mask */ }; /* 24 bytes */ struct uObjTxtrTLUT { u32 type; /* Structure identifier (G_OBJLT_TLUT) */ u32 image; /* Texture source address in DRAM */ u16 pnum; /* Number of palettes to load - 1 */ u16 phead; /* Palette position at start of load (256~511) */ u16 sid; /* Status ID (multiple of 4: either 0, 4, 8, or 12) */ u16 zero; /* Always assign 0 */ u32 flag; /* Status flag */ u32 mask; /* Status mask */ }; /* 24 bytes */ typedef union { uObjTxtrBlock block; uObjTxtrTile tile; uObjTxtrTLUT tlut; } uObjTxtr; struct uObjTxSprite { uObjTxtr txtr; uObjSprite sprite; }; struct uObjMtx { s32 A, B, C, D; /* s15.16 */ s16 Y, X; /* s10.2 */ u16 BaseScaleY; /* u5.10 */ u16 BaseScaleX; /* u5.10 */ }; struct uObjSubMtx { s16 Y, X; /* s10.2 */ u16 BaseScaleY; /* u5.10 */ u16 BaseScaleX; /* u5.10 */ }; void S2DEX_BG_1Cyc(u32 w0, u32 w1); void S2DEX_BG_Copy( u32 w0, u32 w1 ); void S2DEX_Obj_Rectangle( u32 w0, u32 w1 ); void S2DEX_Obj_Sprite( u32 w0, u32 w1 ); void S2DEX_Obj_MoveMem( u32 w0, u32 w1 ); void S2DEX_Select_DL( u32 w0, u32 w1 ); void S2DEX_Obj_RenderMode( u32 w0, u32 w1 ); void S2DEX_Obj_Rectangle_R( u32 w0, u32 w1 ); void S2DEX_Obj_LoadTxtr( u32 w0, u32 w1 ); void S2DEX_Obj_LdTx_Sprite( u32 w0, u32 w1 ); void S2DEX_Obj_LdTx_Rect( u32 w0, u32 w1 ); void S2DEX_Obj_LdTx_Rect_R( u32 w0, u32 w1 ); void S2DEX_Init(); #define S2DEX_MV_MATRIX 0 #define S2DEX_MV_SUBMUTRIX 2 #define S2DEX_MV_VIEWPORT 8 #define S2DEX_BG_1CYC 0x01 #define S2DEX_BG_COPY 0x02 #define S2DEX_OBJ_RECTANGLE 0x03 #define S2DEX_OBJ_SPRITE 0x04 #define S2DEX_OBJ_MOVEMEM 0x05 #define S2DEX_LOAD_UCODE 0xAF #define S2DEX_SELECT_DL 0xB0 #define S2DEX_OBJ_RENDERMODE 0xB1 #define S2DEX_OBJ_RECTANGLE_R 0xB2 #define S2DEX_OBJ_LOADTXTR 0xC1 #define S2DEX_OBJ_LDTX_SPRITE 0xC2 #define S2DEX_OBJ_LDTX_RECT 0xC3 #define S2DEX_OBJ_LDTX_RECT_R 0xC4 #define S2DEX_RDPHALF_0 0xE4 #endif gles2rice/INSTALL000664 001750 001750 00000001520 12655644434 014625 0ustar00sergiosergio000000 000000 Mupen64Plus-Video-Rice INSTALL ------------------------------ This text file was written to explain the installation process of the Mupen64Plus-Video-Rice module. If this module is part of a Mupen64Plus source code bundle, the user should run the "m64p_install.sh" script in the root of the unzipped bundle to install all of the included modules in the bundle. If this module is a standalone source code release, you should build the library from source code and install it via the makefile, like this: $ cd projects/unix $ make all $ sudo make install If you want to build the Mupen64Plus-Video-Rice module for installation in a home folder for a single user, you may build it like this (replacing with your desired local installation path): $ cd projects/unix $ make all $ make install LIBDIR= SHAREDIR= mupen64plus-rsp-cxd4/COPYING000664 001750 001750 00000015610 12655644434 016621 0ustar00sergiosergio000000 000000 Creative Commons Legal Code CC0 1.0 Universal CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER. Statement of Purpose The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work"). Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others. For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights. 1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following: i. the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work; ii. moral rights retained by the original author(s) and/or performer(s); iii. publicity and privacy rights pertaining to a person's image or likeness depicted in a Work; iv. rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below; v. rights protecting the extraction, dissemination, use and reuse of data in a Work; vi. database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and vii. other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof. 2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose. 3. Public License Fallback. Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose. 4. Limitations and Disclaimers. a. No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document. b. Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law. c. Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work. d. Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work. libretro-common/include/glsym/rglgen_headers.h000664 001750 001750 00000005007 12655644434 022731 0ustar00sergiosergio000000 000000 /* Copyright (C) 2010-2015 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this libretro SDK code part (glsym). * --------------------------------------------------------------------------------------- * * Permission is hereby granted, free of charge, * to any person obtaining a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef RGLGEN_HEADERS_H__ #define RGLGEN_HEADERS_H__ #ifdef HAVE_EGL #include #include #endif #if defined(IOS) #if defined(HAVE_OPENGLES3) #include #include #else #include #include #endif #elif defined(__APPLE__) #include #include #elif defined(HAVE_PSGL) #include #include #elif defined(HAVE_OPENGL_MODERN) #include #include #elif defined(HAVE_OPENGLES3) #include #include /* There are no GLES3 extensions yet. */ #elif defined(HAVE_OPENGLES2) #include #include #elif defined(HAVE_OPENGLES1) #include #include #else #if defined(_WIN32) && !defined(_XBOX) #define WIN32_LEAN_AND_MEAN #include #endif #include #include #endif #ifndef GL_MAP_WRITE_BIT #define GL_MAP_WRITE_BIT 0x0002 #endif #ifndef GL_MAP_INVALIDATE_BUFFER_BIT #define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 #endif #ifndef GL_RED_INTEGER #define GL_RED_INTEGER 0x8D94 #endif #endif mupen64plus-core/src/main/md5.h000664 001750 001750 00000006531 12655644434 017425 0ustar00sergiosergio000000 000000 /* Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. L. Peter Deutsch ghost@aladdin.com */ /* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */ /* Independent implementation of MD5 (RFC 1321). This code implements the MD5 Algorithm defined in RFC 1321, whose text is available at http://www.ietf.org/rfc/rfc1321.txt The code is derived from the text of the RFC, including the test suite (section A.5) but excluding the rest of Appendix A. It does not include any code or documentation that is identified in the RFC as being copyrighted. The original and principal author of md5.h is L. Peter Deutsch . Other authors are noted in the change history that follows (in reverse chronological order): 2002-04-13 lpd Removed support for non-ANSI compilers; removed references to Ghostscript; clarified derivation from RFC 1321; now handles byte order either statically or dynamically. 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); added conditionalization for C++ compilation from Martin Purschke . 1999-05-03 lpd Original version. */ #ifndef md5_INCLUDED # define md5_INCLUDED /* * This package supports both compile-time and run-time determination of CPU * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is * defined as non-zero, the code will be compiled to run only on big-endian * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to * run on either big- or little-endian CPUs, but will run slightly less * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. */ typedef unsigned char md5_byte_t; /* 8-bit byte */ typedef unsigned int md5_word_t; /* 32-bit word */ /* Define the state of the MD5 Algorithm. */ typedef struct md5_state_s { md5_word_t count[2]; /* message length in bits, lsw first */ md5_word_t abcd[4]; /* digest buffer */ md5_byte_t buf[64]; /* accumulate block */ } md5_state_t; #ifdef __cplusplus extern "C" { #endif /* Initialize the algorithm. */ void md5_init(md5_state_t *pms); /* Append a string to the message. */ void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); /* Finish the message and return the digest. */ void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); #ifdef __cplusplus } /* end extern "C" */ #endif #endif /* md5_INCLUDED */ mupen64plus-core/src/r4300/pure_interp.h000664 001750 001750 00000003364 12655644434 021121 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - pure_interp.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_R4300_PURE_INTERP_H #define M64P_R4300_PURE_INTERP_H /* FIXME: belongs to gr4300 module */ extern unsigned int op_R4300; void pure_interpreter_init(void); void pure_interpreter(void); #endif /* M64P_R4300_PURE_INTERP_H */ mupen64plus-core/src/api/msvc_compat.h000664 001750 001750 00000003554 12655644434 021102 0ustar00sergiosergio000000 000000 /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2014 - Daniel De Matteis * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. * * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with RetroArch. * If not, see . */ #ifndef __RARCH_MSVC_COMPAT_H #define __RARCH_MSVC_COMPAT_H #ifdef _MSC_VER #undef UNICODE /* Do not bother with UNICODE at this time. */ #include #include #include /* Python headers defines ssize_t and sets HAVE_SSIZE_T. * Cannot duplicate these efforts. */ #ifndef HAVE_SSIZE_T #if defined(_WIN64) typedef __int64 ssize_t; #elif defined(_WIN32) typedef int ssize_t; #endif #endif #define mkdir(dirname, unused) _mkdir(dirname) #define snprintf _snprintf #define strtoull _strtoui64 #undef strcasecmp #define strcasecmp _stricmp #undef strncasecmp #define strncasecmp _strnicmp /* Disable some of the annoying warnings. */ #pragma warning(disable : 4800) #pragma warning(disable : 4805) #pragma warning(disable : 4244) #pragma warning(disable : 4305) #pragma warning(disable : 4146) #pragma warning(disable : 4267) #pragma warning(disable : 4723) #pragma warning(disable : 4996) #define roundf(in) (in >= 0.0f ? floorf(in + 0.5f) : ceilf(in - 0.5f)) #ifndef PATH_MAX #define PATH_MAX _MAX_PATH #endif #ifndef SIZE_MAX #define SIZE_MAX _UI32_MAX #endif #endif #endif gles2n64/src/Common.h000664 001750 001750 00000000705 12655644434 015455 0ustar00sergiosergio000000 000000 #ifndef __COMMON_H__ #define __COMMON_H__ #include #define LOG_NONE 0 #define LOG_ERROR 1 #define LOG_MINIMAL 2 #define LOG_WARNING 3 #define LOG_VERBOSE 4 #define LOG_LEVEL LOG_WARNING //#define DBG_LOGS #ifdef DBG_LOGS #define LOG(A, ...) fprintf(stdout, __VA_ARGS__) #else #define LOG(A, ...) #endif #ifndef max #define max(a, b) ((a) > (b) ? (a) : (b)) #endif #ifndef min #define min(a, b) ((a) < (b) ? (a) : (b)) #endif #endif mupen64plus-video-gliden64/src/OGL3X/Shaders_ogl3x.h000664 001750 001750 00000056711 12655644434 023152 0ustar00sergiosergio000000 000000 #if defined(GLES3_1) #define MAIN_SHADER_VERSION "#version 310 es \n" #define AUXILIARY_SHADER_VERSION "\n" #elif defined(GLES3) #define MAIN_SHADER_VERSION "#version 300 es \n" #define AUXILIARY_SHADER_VERSION "\n" #else #define MAIN_SHADER_VERSION "#version 330 core \n" #define AUXILIARY_SHADER_VERSION "#version 330 core \n" #endif static const char* vertex_shader = MAIN_SHADER_VERSION "in highp vec4 aPosition; \n" "in lowp vec4 aColor; \n" "in highp vec2 aTexCoord0; \n" "in highp vec2 aTexCoord1; \n" "in lowp float aNumLights; \n" " \n" "uniform int uRenderState; \n" "uniform int uTexturePersp; \n" " \n" "uniform int uFogMode; \n" "uniform lowp int uFogUsage; \n" "uniform lowp float uFogAlpha; \n" "uniform mediump vec2 uFogScale; \n" " \n" "layout (std140) uniform TextureBlock { \n" " mediump vec2 uTexScale; \n" " mediump vec2 uTexOffset[2]; \n" " mediump vec2 uCacheScale[2]; \n" " mediump vec2 uCacheOffset[2]; \n" " mediump vec2 uCacheShiftScale[2]; \n" " lowp ivec2 uCacheFrameBuffer; \n" "}; \n" "out lowp vec4 vShadeColor; \n" "out mediump vec2 vTexCoord0; \n" "out mediump vec2 vTexCoord1; \n" "out mediump vec2 vLodTexCoord; \n" "out lowp float vNumLights; \n" "out mediump float vFogFragCoord; \n" "mediump vec2 calcTexCoord(in vec2 texCoord, in int idx) \n" "{ \n" " vec2 texCoordOut = texCoord*uCacheShiftScale[idx]; \n" " texCoordOut -= uTexOffset[idx]; \n" " if (uCacheFrameBuffer[idx] != 0) \n" " texCoordOut.t = -texCoordOut.t; \n" " return (uCacheOffset[idx] + texCoordOut)* uCacheScale[idx];\n" "} \n" " \n" "void main() \n" "{ \n" " gl_Position = aPosition; \n" " vFogFragCoord = 0.0; \n" " vShadeColor = aColor; \n" " if (uRenderState == 1) { \n" " vec2 texCoord = aTexCoord0; \n" " texCoord *= uTexScale; \n" " if (uTexturePersp == 0) texCoord *= 0.5; \n" " vTexCoord0 = calcTexCoord(texCoord, 0); \n" " vTexCoord1 = calcTexCoord(texCoord, 1); \n" " vLodTexCoord = texCoord; \n" " vNumLights = aNumLights; \n" " if (uFogMode == 0) { \n" " if (aPosition.z < -aPosition.w) \n" " vFogFragCoord = -uFogScale.s + uFogScale.t; \n" " else \n" " vFogFragCoord = aPosition.z/aPosition.w*uFogScale.s \n" " + uFogScale.t; \n" " } else if (uFogMode == 1) { \n" " vFogFragCoord = uFogAlpha; \n" " } else if (uFogMode == 2) { \n" " vFogFragCoord = 1.0 - uFogAlpha; \n" " } \n" " vFogFragCoord = clamp(vFogFragCoord, 0.0, 1.0); \n" " lowp int fogUsage = uFogUsage; \n" " if (fogUsage >= 256) fogUsage -= 256; \n" " if (fogUsage == 1 && uFogMode == 0) \n" " vShadeColor.a = vFogFragCoord; \n" " } else { \n" " vTexCoord0 = aTexCoord0; \n" " vTexCoord1 = aTexCoord1; \n" " vNumLights = 0.0; \n" " if (uFogMode == 1) vFogFragCoord = uFogAlpha; \n" " else if (uFogMode == 2) vFogFragCoord = 1.0 - uFogAlpha; \n" " } \n" #ifndef GLESX " gl_ClipDistance[0] = gl_Position.w - gl_Position.z; \n" #endif "} \n" ; static const char* vertex_shader_notex = MAIN_SHADER_VERSION "in highp vec4 aPosition; \n" "in lowp vec4 aColor; \n" "in lowp float aNumLights; \n" " \n" "uniform int uRenderState; \n" " \n" "uniform int uFogMode; \n" "uniform lowp int uFogUsage; \n" "uniform lowp float uFogAlpha; \n" "uniform mediump vec2 uFogScale; \n" " \n" "out lowp vec4 vShadeColor; \n" "out lowp float vNumLights; \n" "out mediump float vFogFragCoord; \n" " \n" "void main() \n" "{ \n" " gl_Position = aPosition; \n" " vFogFragCoord = 0.0; \n" " vShadeColor = aColor; \n" " if (uRenderState == 1) { \n" " vNumLights = aNumLights; \n" " if (uFogMode == 0) { \n" " if (aPosition.z < -aPosition.w) \n" " vFogFragCoord = -uFogScale.s + uFogScale.t; \n" " else \n" " vFogFragCoord = aPosition.z/aPosition.w*uFogScale.s \n" " + uFogScale.t; \n" " } else if (uFogMode == 1) { \n" " vFogFragCoord = uFogAlpha; \n" " } else if (uFogMode == 2) { \n" " vFogFragCoord = 1.0 - uFogAlpha; \n" " } \n" " vFogFragCoord = clamp(vFogFragCoord, 0.0, 1.0); \n" " lowp int fogUsage = uFogUsage; \n" " if (fogUsage >= 256) fogUsage -= 256; \n" " if (fogUsage == 1 && uFogMode == 0) \n" " vShadeColor.a = vFogFragCoord; \n" " } else { \n" " vNumLights = 0.0; \n" " if (uFogMode == 1) vFogFragCoord = uFogAlpha; \n" " else if (uFogMode == 2) vFogFragCoord = 1.0 - uFogAlpha; \n" " } \n" #ifndef GLESX " gl_ClipDistance[0] = gl_Position.w - gl_Position.z; \n" #endif "} \n" ; static const char* fragment_shader_header_common_variables = MAIN_SHADER_VERSION "uniform sampler2D uTex0; \n" "uniform sampler2D uTex1; \n" #ifdef GL_MULTISAMPLING_SUPPORT "uniform lowp sampler2DMS uMSTex0; \n" "uniform lowp sampler2DMS uMSTex1; \n" "uniform lowp ivec2 uMSTexEnabled; \n" #endif "layout (std140) uniform ColorsBlock {\n" " lowp vec4 uFogColor; \n" " lowp vec4 uCenterColor; \n" " lowp vec4 uScaleColor; \n" " lowp vec4 uBlendColor; \n" " lowp vec4 uEnvColor; \n" " lowp vec4 uPrimColor; \n" " lowp float uPrimLod; \n" " lowp float uK4; \n" " lowp float uK5; \n" "}; \n" #ifdef GLESX "uniform mediump vec2 uScreenScale; \n" #endif "uniform lowp int uAlphaCompareMode; \n" "uniform lowp int uAlphaDitherMode; \n" "uniform lowp int uColorDitherMode; \n" "uniform lowp int uFogUsage; \n" "uniform lowp ivec2 uFbMonochrome; \n" "uniform lowp ivec2 uFbFixedAlpha;\n" "uniform lowp int uSpecialBlendMode;\n" "uniform lowp int uEnableAlphaTest; \n" "uniform lowp float uAlphaTestValue;\n" "uniform mediump vec2 uDepthScale; \n" "in lowp vec4 vShadeColor; \n" "in mediump vec2 vTexCoord0;\n" "in mediump vec2 vTexCoord1;\n" "in mediump vec2 vLodTexCoord;\n" "in lowp float vNumLights; \n" "in mediump float vFogFragCoord;\n" "lowp vec3 input_color; \n" "out lowp vec4 fragColor; \n" ; static const char* fragment_shader_header_common_variables_notex = MAIN_SHADER_VERSION "layout (std140) uniform ColorsBlock {\n" " lowp vec4 uFogColor; \n" " lowp vec4 uCenterColor; \n" " lowp vec4 uScaleColor; \n" " lowp vec4 uBlendColor; \n" " lowp vec4 uEnvColor; \n" " lowp vec4 uPrimColor; \n" " lowp float uPrimLod; \n" " lowp float uK4; \n" " lowp float uK5; \n" "}; \n" #ifdef GLESX "uniform mediump vec2 uScreenScale; \n" #endif "uniform lowp int uAlphaCompareMode; \n" "uniform lowp int uAlphaDitherMode; \n" "uniform lowp int uColorDitherMode; \n" "uniform lowp int uFogUsage; \n" "uniform lowp int uSpecialBlendMode;\n" "uniform lowp int uEnableAlphaTest; \n" "uniform lowp float uAlphaTestValue;\n" "uniform mediump vec2 uDepthScale; \n" "in lowp vec4 vShadeColor; \n" "in lowp float vNumLights; \n" "in mediump float vFogFragCoord;\n" "lowp vec3 input_color; \n" "out lowp vec4 fragColor; \n" ; static const char* fragment_shader_header_common_functions = " \n" "lowp float snoise(); \n" "void calc_light(in lowp float fLights, in lowp vec3 input_color, out lowp vec3 output_color);\n" "mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1); \n" "lowp vec4 readTex(in sampler2D tex, in mediump vec2 texCoord, in lowp int fbMonochrome, in bool fbFixedAlpha); \n" #ifdef GL_MULTISAMPLING_SUPPORT "lowp vec4 readTexMS(in lowp sampler2DMS mstex, in mediump vec2 texCoord, in lowp int fbMonochrome, in bool fbFixedAlpha); \n" #endif // GL_MULTISAMPLING_SUPPORT "bool depth_compare(); \n" "void colorNoiseDither(in lowp float _noise, inout lowp vec3 _color); \n" "void alphaNoiseDither(in lowp float _noise, inout lowp float _alpha);\n" #ifdef USE_TOONIFY "void toonify(in mediump float intensity); \n" #endif ; static const char* fragment_shader_header_common_functions_notex = " \n" "lowp float snoise(); \n" "void calc_light(in lowp float fLights, in lowp vec3 input_color, out lowp vec3 output_color);\n" "bool depth_compare(); \n" "void colorNoiseDither(in lowp float _noise, inout lowp vec3 _color); \n" "void alphaNoiseDither(in lowp float _noise, inout lowp float _alpha);\n" ; static const char* fragment_shader_calc_light = AUXILIARY_SHADER_VERSION "layout (std140) uniform LightBlock { \n" " mediump vec3 uLightDirection[8]; \n" " lowp vec3 uLightColor[8]; \n" "}; \n" "void calc_light(in lowp float fLights, in lowp vec3 input_color, out lowp vec3 output_color) {\n" " output_color = input_color; \n" " lowp int nLights = int(floor(fLights + 0.5)); \n" " if (nLights == 0) \n" " return; \n" " output_color = uLightColor[nLights]; \n" " mediump float intensity; \n" " mediump vec3 n = normalize(input_color); \n" " for (int i = 0; i < nLights; i++) { \n" " intensity = max(dot(n, uLightDirection[i]), 0.0); \n" " output_color += intensity*uLightColor[i]; \n" " }; \n" " clamp(output_color, 0.0, 1.0); \n" "} \n" ; static const char* fragment_shader_header_main = " \n" "void main() \n" "{ \n" #ifdef GLESX "#ifdef GL_NV_fragdepth \n" " gl_FragDepth = clamp((gl_FragCoord.z * 2.0 - 1.0) * uDepthScale.s + uDepthScale.t, 0.0, 1.0); \n" "#endif \n" #else " gl_FragDepth = clamp((gl_FragCoord.z * 2.0 - 1.0) * uDepthScale.s + uDepthScale.t, 0.0, 1.0); \n" #endif " lowp vec4 vec_color, combined_color; \n" " lowp float alpha1, alpha2; \n" " lowp vec3 color1, color2; \n" ; static const char* fragment_shader_dither = AUXILIARY_SHADER_VERSION "void colorNoiseDither(in lowp float _noise, inout lowp vec3 _color) \n" "{ \n" " mediump vec3 tmpColor = _color*255.0; \n" " mediump ivec3 iColor = ivec3(tmpColor); \n" //" iColor &= 248; \n" // does not work with HW lighting enabled (why?!) " iColor |= ivec3(tmpColor*_noise)&7; \n" " _color = vec3(iColor)/255.0; \n" "} \n" "void alphaNoiseDither(in lowp float _noise, inout lowp float _alpha) \n" "{ \n" " mediump float tmpAlpha = _alpha*255.0; \n" " mediump int iAlpha = int(tmpAlpha); \n" //" iAlpha &= 248; \n" // causes issue #518. need further investigation " iAlpha |= int(tmpAlpha*_noise)&7; \n" " _alpha = float(iAlpha)/255.0; \n" "} \n" ; #ifdef USE_TOONIFY static const char* fragment_shader_toonify = " \n" "void toonify(in mediump float intensity) { \n" " if (intensity > 0.5) \n" " return; \n" " else if (intensity > 0.125) \n" " fragColor = vec4(vec3(fragColor)*0.5, fragColor.a);\n" " else \n" " fragColor = vec4(vec3(fragColor)*0.2, fragColor.a);\n" "} \n" ; #endif static const char* fragment_shader_end = "} \n" ; static const char* fragment_shader_mipmap = #ifndef GLESX AUXILIARY_SHADER_VERSION "in mediump vec2 vTexCoord0; \n" "in mediump vec2 vTexCoord1; \n" "in mediump vec2 vLodTexCoord; \n" "uniform sampler2D uTex0; \n" "uniform sampler2D uTex1; \n" "uniform mediump vec2 uScreenScale; \n" #endif "uniform lowp int uEnableLod; \n" "uniform mediump float uMinLod; \n" "uniform lowp int uMaxTile; \n" "uniform lowp int uTextureDetail; \n" " \n" "mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1) { \n" " readtex0 = texture(uTex0, vTexCoord0); \n" " readtex1 = textureLod(uTex1, vTexCoord1, 0.0); \n" " if (uMaxTile == 0) return 1.0; \n" " \n" " mediump float fMaxTile = float(uMaxTile); \n" #if 1 " mediump vec2 dx = abs(dFdx(vLodTexCoord)); \n" " dx *= uScreenScale; \n" " mediump float lod = max(dx.x, dx.y); \n" #else " mediump vec2 dx = dFdx(vLodTexCoord); \n" " dx *= uScreenScale; \n" " mediump vec2 dy = dFdy(vLodTexCoord); \n" " dy *= uScreenScale; \n" " mediump float lod = max(length(dx), length(dy)); \n" #endif " bool magnify = lod < 1.0; \n" " mediump float lod_tile = magnify ? 0.0 : floor(log2(floor(lod))); \n" " bool distant = lod > 128.0 || lod_tile >= fMaxTile; \n" " mediump float lod_frac = fract(lod/pow(2.0, lod_tile)); \n" " if (magnify) lod_frac = max(lod_frac, uMinLod); \n" " if (uTextureDetail == 0) { \n" " if (distant) lod_frac = 1.0; \n" " else if (magnify) lod_frac = 0.0; \n" " } \n" " if (magnify && ((uTextureDetail & 1) != 0)) \n" " lod_frac = 1.0 - lod_frac; \n" " if (uEnableLod == 0) return lod_frac; \n" " \n" " lod_tile = min(lod_tile, fMaxTile); \n" " lowp float lod_tile_m1 = max(0.0, lod_tile - 1.0); \n" " lowp vec4 lodT = textureLod(uTex1, vTexCoord1, lod_tile); \n" " lowp vec4 lodT_m1 = textureLod(uTex1, vTexCoord1, lod_tile_m1); \n" " lowp vec4 lodT_p1 = textureLod(uTex1, vTexCoord1, lod_tile + 1.0); \n" " if (lod_tile < 1.0) { \n" " if (magnify) { \n" // !sharpen && !detail " if (uTextureDetail == 0) readtex1 = readtex0; \n" " } else { \n" // detail " if ((uTextureDetail & 2) != 0 ) { \n" " readtex0 = lodT; \n" " readtex1 = lodT_p1; \n" " } \n" " } \n" " } else { \n" " if ((uTextureDetail & 2) != 0 ) { \n" " readtex0 = lodT; \n" " readtex1 = lodT_p1; \n" " } else { \n" " readtex0 = lodT_m1; \n" " readtex1 = lodT; \n" " } \n" " } \n" " return lod_frac; \n" "} \n" ; static const char* fragment_shader_fake_mipmap = "uniform lowp int uMaxTile; \n" "uniform mediump float uMinLod; \n" " \n" "mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1) { \n" " readtex0 = texture(uTex0, vTexCoord0); \n" " readtex1 = texture(uTex1, vTexCoord1); \n" " if (uMaxTile == 0) return 1.0; \n" " return uMinLod; \n" "} \n" ; static const char* fragment_shader_readtex = AUXILIARY_SHADER_VERSION "lowp vec4 readTex(in sampler2D tex, in mediump vec2 texCoord, in lowp int fbMonochrome, in bool fbFixedAlpha) \n" "{ \n" " lowp vec4 texColor = texture(tex, texCoord); \n" " if (fbMonochrome == 1) texColor = vec4(texColor.r); \n" " else if (fbMonochrome == 2) \n" " texColor.rgb = vec3(dot(vec3(0.2126, 0.7152, 0.0722), texColor.rgb)); \n" " if (fbFixedAlpha) texColor.a = 0.825; \n" " return texColor; \n" "} \n" ; static const char* fragment_shader_readtex_3point = AUXILIARY_SHADER_VERSION "uniform lowp int uTextureFilterMode; \n" // 3 point texture filtering. // Original author: ArthurCarvalho // GLSL implementation: twinaphex, mupen64plus-libretro project. "#define TEX_OFFSET(off) texture(tex, texCoord - (off)/texSize) \n" "lowp vec4 filter3point(in sampler2D tex, in mediump vec2 texCoord) \n" "{ \n" " mediump vec2 texSize = vec2(textureSize(tex,0)); \n" " mediump vec2 offset = fract(texCoord*texSize - vec2(0.5)); \n" " offset -= step(1.0, offset.x + offset.y); \n" " lowp vec4 c0 = TEX_OFFSET(offset); \n" " lowp vec4 c1 = TEX_OFFSET(vec2(offset.x - sign(offset.x), offset.y)); \n" " lowp vec4 c2 = TEX_OFFSET(vec2(offset.x, offset.y - sign(offset.y))); \n" " return c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0); \n" "} \n" "lowp vec4 readTex(in sampler2D tex, in mediump vec2 texCoord, in lowp int fbMonochrome, in bool fbFixedAlpha) \n" "{ \n" " lowp vec4 texStandard = texture(tex, texCoord); \n" " lowp vec4 tex3Point = filter3point(tex, texCoord); \n" " lowp vec4 texColor = uTextureFilterMode == 0 ? texStandard : tex3Point; \n" " if (fbMonochrome == 1) texColor = vec4(texColor.r); \n" " else if (fbMonochrome == 2) \n" " texColor.rgb = vec3(dot(vec3(0.2126, 0.7152, 0.0722), texColor.rgb)); \n" " if (fbFixedAlpha) texColor.a = 0.825; \n" " return texColor; \n" "} \n" ; #ifdef GL_MULTISAMPLING_SUPPORT static const char* fragment_shader_readtex_ms = AUXILIARY_SHADER_VERSION "uniform lowp int uMSAASamples; \n" "uniform lowp float uMSAAScale; \n" "lowp vec4 sampleMS(in lowp sampler2DMS mstex, in mediump ivec2 ipos) \n" "{ \n" " lowp vec4 texel = vec4(0.0); \n" " for (int i = 0; i < uMSAASamples; ++i) \n" " texel += texelFetch(mstex, ipos, i); \n" " return texel * uMSAAScale; \n" "} \n" " \n" "lowp vec4 readTexMS(in lowp sampler2DMS mstex, in mediump vec2 texCoord, in lowp int fbMonochrome, in bool fbFixedAlpha) \n" "{ \n" " mediump vec2 msTexSize = vec2(textureSize(mstex)); \n" " mediump ivec2 itexCoord = ivec2(msTexSize * texCoord); \n" " lowp vec4 texColor = sampleMS(mstex, itexCoord); \n" " if (fbMonochrome == 1) texColor = vec4(texColor.r); \n" " else if (fbMonochrome == 2) \n" " texColor.rgb = vec3(dot(vec3(0.2126, 0.7152, 0.0722), texColor.rgb)); \n" " if (fbFixedAlpha) texColor.a = 0.825; \n" " return texColor; \n" "} \n" ; #endif // GL_MULTISAMPLING_SUPPORT static const char* fragment_shader_noise = AUXILIARY_SHADER_VERSION #ifndef GLESX "uniform mediump vec2 uScreenScale; \n" #endif "uniform sampler2D uTexNoise; \n" "lowp float snoise() \n" "{ \n" " ivec2 coord = ivec2(gl_FragCoord.xy/uScreenScale); \n" " return texelFetch(uTexNoise, coord, 0).r; \n" "} \n" ; static const char* fragment_shader_dummy_noise = " \n" "lowp float snoise() \n" "{ \n" " return 1.0; \n" "} \n" ; #ifdef GL_IMAGE_TEXTURES_SUPPORT static const char* depth_compare_shader_float = #ifndef GLESX "#version 430 \n" "layout(binding = 2, rg32f) uniform coherent image2D uDepthImage;\n" #else "layout(binding = 2, rgba32f) highp uniform coherent image2D uDepthImage;\n" #endif //"uniform int uEnableDepth; \n" "uniform lowp int uDepthMode; \n" "uniform lowp int uDepthSource; \n" "uniform lowp int uEnableDepthCompare; \n" "uniform lowp int uEnableDepthUpdate; \n" "uniform mediump float uDeltaZ; \n" "bool depth_compare() \n" "{ \n" //" if (uEnableDepth == 0) return true; \n" " ivec2 coord = ivec2(gl_FragCoord.xy); \n" " highp vec4 depth = imageLoad(uDepthImage,coord); \n" " highp float bufZ = depth.r; \n" " highp float curZ = gl_FragDepth; \n" " highp float dz, dzMin; \n" " if (uDepthSource == 1) { \n" " dzMin = dz = uDeltaZ; \n" " } else { \n" " dz = 4.0*fwidth(gl_FragDepth); \n" " dzMin = min(dz, depth.g); \n" " } \n" " bool bInfront = curZ < bufZ; \n" " bool bFarther = (curZ + dzMin) >= bufZ; \n" " bool bNearer = (curZ - dzMin) <= bufZ; \n" " bool bMax = bufZ == 1.0; \n" " bool bRes; \n" " switch (uDepthMode) { \n" " case 1: \n" " bRes = bMax || bNearer; \n" " break; \n" " case 0: \n" " case 2: \n" " bRes = bMax || bInfront; \n" " break; \n" " case 3: \n" " bRes = bFarther && bNearer && !bMax; \n" " break; \n" " default: \n" " bRes = bInfront; \n" " break; \n" " } \n" " if (uEnableDepthUpdate != 0 && bRes) { \n" " highp vec4 depth_out = vec4(gl_FragDepth, dz, 1.0, 1.0); \n" " imageStore(uDepthImage,coord, depth_out); \n" " } \n" " memoryBarrierImage(); \n" " if (uEnableDepthCompare != 0) \n" " return bRes; \n" " return true; \n" "} \n" ; static const char* shadow_map_fragment_shader_float = #ifndef GLESX "#version 420 core \n" "layout(binding = 0, r16ui) uniform readonly uimage2D uZlutImage;\n" "layout(binding = 1, r16ui) uniform readonly uimage2D uTlutImage;\n" #else MAIN_SHADER_VERSION "layout(binding = 0, r32ui) highp uniform readonly uimage2D uZlutImage;\n" "layout(binding = 1, r32ui) highp uniform readonly uimage2D uTlutImage;\n" #endif "layout(binding = 0) uniform sampler2D uDepthImage; \n" "uniform lowp vec4 uFogColor; \n" "out lowp vec4 fragColor; \n" "lowp float get_alpha() \n" "{ \n" " mediump ivec2 coord = ivec2(gl_FragCoord.xy); \n" " highp float bufZ = texelFetch(uDepthImage,coord, 0).r; \n" " highp int iZ = bufZ > 0.999 ? 262143 : int(floor(bufZ * 262143.0));\n" " mediump int y0 = clamp(iZ/512, 0, 511); \n" " mediump int x0 = iZ - 512*y0; \n" " highp uint iN64z = imageLoad(uZlutImage,ivec2(x0,y0)).r; \n" " highp float n64z = clamp(float(iN64z)/65532.0, 0.0, 1.0);\n" " highp int index = min(255, int(n64z*255.0)); \n" " highp uint iAlpha = imageLoad(uTlutImage,ivec2(index,0)).r;\n" " return float(iAlpha>>8)/255.0; \n" "} \n" "void main() \n" "{ \n" " fragColor = vec4(uFogColor.rgb, get_alpha()); \n" "} \n" ; #endif // GL_IMAGE_TEXTURES_SUPPORT static const char* default_vertex_shader = MAIN_SHADER_VERSION "in highp vec4 aPosition; \n" "void main() \n" "{ \n" " gl_Position = aPosition; \n" "} \n" ; #if 0 // Do palette based monochrome image. Exactly as N64 does static const char* zelda_monochrome_fragment_shader = "#version 420 core \n" "layout(binding = 0) uniform sampler2D uColorImage; \n" "layout(binding = 1, r16ui) uniform readonly uimage2D uTlutImage;\n" "out lowp vec4 fragColor; \n" "lowp float get_color() \n" "{ \n" " ivec2 coord = ivec2(gl_FragCoord.xy); \n" " vec4 color = 31.0*texelFetch(uColorImage, coord, 0); \n" " int r = int(color.r); int g = int(color.g); int b = int(color.b);\n" //" int a = 0; if ((color.r + color.g + color.b) > 0) a = 32768;\n" //" int color16 = 32768 + r*1024 + g*32 + b; \n" " int color16 = r*1024 + g*32 + b; \n" " int index = min(255, color16/256); \n" " uint iAlpha = imageLoad(uTlutImage,ivec2(index,0)).r; \n" " memoryBarrier(); \n" " return clamp(float((iAlpha&255) + index)/255.0, 0.0, 1.0); \n" "} \n" "void main() \n" "{ \n" " fragColor = vec4(vec3(get_color()), 1.0); \n" "} \n" ; #else // Cheat it static const char* zelda_monochrome_fragment_shader = MAIN_SHADER_VERSION "uniform sampler2D uColorImage; \n" "out lowp vec4 fragColor; \n" "void main() \n" "{ \n" " mediump ivec2 coord = ivec2(gl_FragCoord.xy); \n" " lowp vec4 tex = texelFetch(uColorImage, coord, 0); \n" //" lowp float c = (tex.r + tex.g + tex.b) / 3.0f; \n" " lowp float c = dot(vec4(0.2126, 0.7152, 0.0722, 0.0), tex);\n" " fragColor = vec4(c, c, c, 1.0); \n" "} \n" ; #endif mupen64plus-core/src/main/md5.c000664 001750 001750 00000027231 12655644434 017420 0ustar00sergiosergio000000 000000 /* Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. L. Peter Deutsch ghost@aladdin.com */ /* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */ /* Independent implementation of MD5 (RFC 1321). This code implements the MD5 Algorithm defined in RFC 1321, whose text is available at http://www.ietf.org/rfc/rfc1321.txt The code is derived from the text of the RFC, including the test suite (section A.5) but excluding the rest of Appendix A. It does not include any code or documentation that is identified in the RFC as being copyrighted. The original and principal author of md5.c is L. Peter Deutsch . Other authors are noted in the change history that follows (in reverse chronological order): 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order either statically or dynamically; added missing #include in library. 2002-03-11 lpd Corrected argument list for main(), and added int return type, in test program and T value program. 2002-02-21 lpd Added missing #include in test program. 2000-07-03 lpd Patched to eliminate warnings about "constant is unsigned in ANSI C, signed in traditional"; made test program self-checking. 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). 1999-05-03 lpd Original version. */ #include "md5.h" #include #define T_MASK ((md5_word_t)~0) #define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) #define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) #define T3 0x242070db #define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) #define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) #define T6 0x4787c62a #define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) #define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) #define T9 0x698098d8 #define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) #define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) #define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) #define T13 0x6b901122 #define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) #define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) #define T16 0x49b40821 #define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) #define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) #define T19 0x265e5a51 #define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) #define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) #define T22 0x02441453 #define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) #define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) #define T25 0x21e1cde6 #define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) #define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) #define T28 0x455a14ed #define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) #define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) #define T31 0x676f02d9 #define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) #define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) #define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) #define T35 0x6d9d6122 #define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) #define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) #define T38 0x4bdecfa9 #define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) #define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) #define T41 0x289b7ec6 #define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) #define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) #define T44 0x04881d05 #define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) #define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) #define T47 0x1fa27cf8 #define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) #define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) #define T50 0x432aff97 #define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) #define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) #define T53 0x655b59c3 #define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) #define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) #define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) #define T57 0x6fa87e4f #define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) #define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) #define T60 0x4e0811a1 #define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) #define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) #define T63 0x2ad7d2bb #define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) static void md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) { md5_word_t a = pms->abcd[0], b = pms->abcd[1], c = pms->abcd[2], d = pms->abcd[3]; md5_word_t t; #ifdef MSB_FIRST /* Define storage only for big-endian CPUs. */ md5_word_t X[16]; #else /* Define storage for little-endian or both types of CPUs. */ md5_word_t xbuf[16]; const md5_word_t *X; #endif #ifdef MSB_FIRST { /* * On big-endian machines, we must arrange the bytes in the * right order. */ const md5_byte_t *xp = data; int i; #define xbuf X /* (static only) */ for (i = 0; i < 16; ++i, xp += 4) xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); } #else { /* * On little-endian machines, we can process properly aligned * data without copying it. */ if (!((data - (const md5_byte_t *)0) & 3)) { /* data are properly aligned */ X = (const md5_word_t *)data; } else { /* not aligned */ memcpy(xbuf, data, 64); X = xbuf; } } #endif #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) /* Round 1. */ /* Let [abcd k s i] denote the operation a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ #define F(x, y, z) (((x) & (y)) | (~(x) & (z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + F(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 0, 7, T1); SET(d, a, b, c, 1, 12, T2); SET(c, d, a, b, 2, 17, T3); SET(b, c, d, a, 3, 22, T4); SET(a, b, c, d, 4, 7, T5); SET(d, a, b, c, 5, 12, T6); SET(c, d, a, b, 6, 17, T7); SET(b, c, d, a, 7, 22, T8); SET(a, b, c, d, 8, 7, T9); SET(d, a, b, c, 9, 12, T10); SET(c, d, a, b, 10, 17, T11); SET(b, c, d, a, 11, 22, T12); SET(a, b, c, d, 12, 7, T13); SET(d, a, b, c, 13, 12, T14); SET(c, d, a, b, 14, 17, T15); SET(b, c, d, a, 15, 22, T16); #undef SET /* Round 2. */ /* Let [abcd k s i] denote the operation a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ #define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + G(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 1, 5, T17); SET(d, a, b, c, 6, 9, T18); SET(c, d, a, b, 11, 14, T19); SET(b, c, d, a, 0, 20, T20); SET(a, b, c, d, 5, 5, T21); SET(d, a, b, c, 10, 9, T22); SET(c, d, a, b, 15, 14, T23); SET(b, c, d, a, 4, 20, T24); SET(a, b, c, d, 9, 5, T25); SET(d, a, b, c, 14, 9, T26); SET(c, d, a, b, 3, 14, T27); SET(b, c, d, a, 8, 20, T28); SET(a, b, c, d, 13, 5, T29); SET(d, a, b, c, 2, 9, T30); SET(c, d, a, b, 7, 14, T31); SET(b, c, d, a, 12, 20, T32); #undef SET /* Round 3. */ /* Let [abcd k s t] denote the operation a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ #define H(x, y, z) ((x) ^ (y) ^ (z)) #define SET(a, b, c, d, k, s, Ti)\ t = a + H(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 5, 4, T33); SET(d, a, b, c, 8, 11, T34); SET(c, d, a, b, 11, 16, T35); SET(b, c, d, a, 14, 23, T36); SET(a, b, c, d, 1, 4, T37); SET(d, a, b, c, 4, 11, T38); SET(c, d, a, b, 7, 16, T39); SET(b, c, d, a, 10, 23, T40); SET(a, b, c, d, 13, 4, T41); SET(d, a, b, c, 0, 11, T42); SET(c, d, a, b, 3, 16, T43); SET(b, c, d, a, 6, 23, T44); SET(a, b, c, d, 9, 4, T45); SET(d, a, b, c, 12, 11, T46); SET(c, d, a, b, 15, 16, T47); SET(b, c, d, a, 2, 23, T48); #undef SET /* Round 4. */ /* Let [abcd k s t] denote the operation a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ #define I(x, y, z) ((y) ^ ((x) | ~(z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + I(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 0, 6, T49); SET(d, a, b, c, 7, 10, T50); SET(c, d, a, b, 14, 15, T51); SET(b, c, d, a, 5, 21, T52); SET(a, b, c, d, 12, 6, T53); SET(d, a, b, c, 3, 10, T54); SET(c, d, a, b, 10, 15, T55); SET(b, c, d, a, 1, 21, T56); SET(a, b, c, d, 8, 6, T57); SET(d, a, b, c, 15, 10, T58); SET(c, d, a, b, 6, 15, T59); SET(b, c, d, a, 13, 21, T60); SET(a, b, c, d, 4, 6, T61); SET(d, a, b, c, 11, 10, T62); SET(c, d, a, b, 2, 15, T63); SET(b, c, d, a, 9, 21, T64); #undef SET /* Then perform the following additions. (That is increment each of the four registers by the value it had before this block was started.) */ pms->abcd[0] += a; pms->abcd[1] += b; pms->abcd[2] += c; pms->abcd[3] += d; } void md5_init(md5_state_t *pms) { pms->count[0] = pms->count[1] = 0; pms->abcd[0] = 0x67452301; pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; pms->abcd[3] = 0x10325476; } void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) { const md5_byte_t *p = data; int left = nbytes; int offset = (pms->count[0] >> 3) & 63; md5_word_t nbits = (md5_word_t)(nbytes << 3); if (nbytes <= 0) return; /* Update the message length. */ pms->count[1] += nbytes >> 29; pms->count[0] += nbits; if (pms->count[0] < nbits) pms->count[1]++; /* Process an initial partial block. */ if (offset) { int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); memcpy(pms->buf + offset, p, copy); if (offset + copy < 64) return; p += copy; left -= copy; md5_process(pms, pms->buf); } /* Process full blocks. */ for (; left >= 64; p += 64, left -= 64) md5_process(pms, p); /* Process a final partial block. */ if (left) memcpy(pms->buf, p, left); } void md5_finish(md5_state_t *pms, md5_byte_t digest[16]) { static const md5_byte_t pad[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; md5_byte_t data[8]; int i; /* Save the length before padding. */ for (i = 0; i < 8; ++i) data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); /* Pad to 56 bytes mod 64. */ md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); /* Append the length. */ md5_append(pms, data, 8); for (i = 0; i < 16; ++i) digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); } mupen64plus-core/src/r4300/pure_interp.c000664 001750 001750 00000100264 12655644434 021111 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - pure_interp.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2015 Nebuleon * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include "api/m64p_types.h" #include "api/callbacks.h" #include "api/debugger.h" #include "memory/memory.h" #include "main/main.h" #include "osal/preproc.h" /* TLBWrite requires invalid_code and blocks from cached_interp.h, but only if * (at run time) the active core is not the Pure Interpreter. */ #include "cached_interp.h" #include "r4300.h" #include "cp0_private.h" #include "cp1_private.h" #include "exception.h" #include "interupt.h" #include "tlb.h" #ifdef DBG #include "debugger/dbg_types.h" #include "debugger/debugger.h" #endif static precomp_instr interp_PC; unsigned int op_R4300; static void InterpretOpcode(void); uint32_t adler32(uint32_t adler, void *buf, int len); #define PCADDR interp_PC.addr #define ADD_TO_PC(x) interp_PC.addr += x*4; #define DECLARE_INSTRUCTION(name) static void name(uint32_t op) #define DECLARE_JUMP(name, destination, condition, link, likely, cop1) \ static void name(uint32_t op) \ { \ const int take_jump = (condition); \ const uint32_t jump_target = (destination); \ int64_t *link_register = (int64_t*)(link); \ if (cop1 && check_cop1_unusable()) \ return; \ if (link_register != ®[0]) \ *link_register = SE32(interp_PC.addr + 8); \ interp_PC.addr += 4; \ if (!likely || take_jump) \ { \ delay_slot=1; \ InterpretOpcode(); \ cp0_update_count(); \ cp0_update_count(); \ delay_slot=0; \ if (take_jump && !skip_jump) \ interp_PC.addr = jump_target; \ } \ else \ { \ interp_PC.addr += 4; \ cp0_update_count(); \ } \ last_addr = interp_PC.addr; \ if (next_interupt <= g_cp0_regs[CP0_COUNT_REG]) \ gen_interupt(); \ } \ static void name##_IDLE(uint32_t op) \ { \ const int take_jump = (condition); \ if (cop1 && check_cop1_unusable()) \ return; \ if (take_jump) \ { \ int skip; \ cp0_update_count(); \ skip = next_interupt - g_cp0_regs[CP0_COUNT_REG]; \ if (skip > 3) \ g_cp0_regs[CP0_COUNT_REG] += (skip & UINT32_C(0xFFFFFFFC)); \ else name(op); \ } \ else name(op); \ } #define CHECK_MEMORY() #define RD_OF(op) (((op) >> 11) & 0x1F) #define RS_OF(op) (((op) >> 21) & 0x1F) #define RT_OF(op) (((op) >> 16) & 0x1F) #define SA_OF(op) (((op) >> 6) & 0x1F) #define IMM16S_OF(op) ((int16_t) (op)) #define IMM16U_OF(op) ((uint16_t) (op)) #define FD_OF(op) (((op) >> 6) & 0x1F) #define FS_OF(op) (((op) >> 11) & 0x1F) #define FT_OF(op) (((op) >> 16) & 0x1F) #define JUMP_OF(op) ((op) & UINT32_C(0x3FFFFFF)) /* Determines whether a relative jump in a 16-bit immediate goes back to the * same instruction without doing any work in its delay slot. The jump is * relative to the instruction in the delay slot, so 1 instruction backwards * (-1) goes back to the jump. */ #define IS_RELATIVE_IDLE_LOOP(op, addr) (IMM16S_OF(op) == -1 && *fast_mem_access((addr) + 4) == 0) /* Determines whether an absolute jump in a 26-bit immediate goes back to the * same instruction without doing any work in its delay slot. The jump is * in the same 256 MiB segment as the delay slot, so if the jump instruction * is at the last address in its segment, it does not jump back to itself. */ #define IS_ABSOLUTE_IDLE_LOOP(op, addr) \ (JUMP_OF(op) == ((addr) & UINT32_C(0x0FFFFFFF)) >> 2 \ && ((addr) & UINT32_C(0x0FFFFFFF)) != UINT32_C(0x0FFFFFFC) \ && *fast_mem_access((addr) + 4) == 0) #define SE8(a) ((int64_t) ((int8_t) (a))) #define SE16(a) ((int64_t) ((int16_t) (a))) #define SE32(a) ((int64_t) ((int32_t) (a))) /* These macros are like those in macros.h, but they parse opcode fields. */ #define rrt reg[RT_OF(op)] #define rrd reg[RD_OF(op)] #define rfs FS_OF(op) #define rrs reg[RS_OF(op)] #define rsa SA_OF(op) #define irt reg[RT_OF(op)] #define ioffset IMM16S_OF(op) #define iimmediate IMM16S_OF(op) #define irs reg[RS_OF(op)] #define ibase reg[RS_OF(op)] #define jinst_index JUMP_OF(op) #define lfbase RS_OF(op) #define lfft FT_OF(op) #define lfoffset IMM16S_OF(op) #define cfft FT_OF(op) #define cffs FS_OF(op) #define cffd FD_OF(op) /* 32 bits macros */ #ifdef MSB_FIRST #define rrt32 *((int32_t*) ®[RT_OF(op)] + 1) #define rrd32 *((int32_t*) ®[RD_OF(op)] + 1) #define rrs32 *((int32_t*) ®[RS_OF(op)] + 1) #define irs32 *((int32_t*) ®[RS_OF(op)] + 1) #define irt32 *((int32_t*) ®[RT_OF(op)] + 1) #else #define rrt32 *((int32_t*) ®[RT_OF(op)]) #define rrd32 *((int32_t*) ®[RD_OF(op)]) #define rrs32 *((int32_t*) ®[RS_OF(op)]) #define irs32 *((int32_t*) ®[RS_OF(op)]) #define irt32 *((int32_t*) ®[RT_OF(op)]) #endif // two functions are defined from the macros above but never used // these prototype declarations will prevent a warning #if defined(__GNUC__) && !defined(__clang__) static void JR_IDLE(uint32_t) __attribute__((used)); static void JALR_IDLE(uint32_t) __attribute__((used)); #endif #include "interpreter.c" void InterpretOpcode() { uint32_t op = *fast_mem_access(PC->addr); switch ((op >> 26) & 0x3F) { case 0: /* SPECIAL prefix */ switch (op & 0x3F) { case 0: /* SPECIAL opcode 0: SLL */ if (RD_OF(op) != 0) SLL(op); else NOP(0); break; case 2: /* SPECIAL opcode 2: SRL */ if (RD_OF(op) != 0) SRL(op); else NOP(0); break; case 3: /* SPECIAL opcode 3: SRA */ if (RD_OF(op) != 0) SRA(op); else NOP(0); break; case 4: /* SPECIAL opcode 4: SLLV */ if (RD_OF(op) != 0) SLLV(op); else NOP(0); break; case 6: /* SPECIAL opcode 6: SRLV */ if (RD_OF(op) != 0) SRLV(op); else NOP(0); break; case 7: /* SPECIAL opcode 7: SRAV */ if (RD_OF(op) != 0) SRAV(op); else NOP(0); break; case 8: JR(op); break; case 9: /* SPECIAL opcode 9: JALR */ /* Note: This can omit the check for Rd == 0 because the JALR * function checks for link_register != ®[0]. If you're * using this as a reference for a JIT, do check Rd == 0 in it. */ JALR(op); break; case 12: SYSCALL(op); break; case 13: /* SPECIAL opcode 13: BREAK (Not implemented) */ NI(op); break; case 15: SYNC(op); break; case 16: /* SPECIAL opcode 16: MFHI */ if (RD_OF(op) != 0) MFHI(op); else NOP(0); break; case 17: MTHI(op); break; case 18: /* SPECIAL opcode 18: MFLO */ if (RD_OF(op) != 0) MFLO(op); else NOP(0); break; case 19: MTLO(op); break; case 20: /* SPECIAL opcode 20: DSLLV */ if (RD_OF(op) != 0) DSLLV(op); else NOP(0); break; case 22: /* SPECIAL opcode 22: DSRLV */ if (RD_OF(op) != 0) DSRLV(op); else NOP(0); break; case 23: /* SPECIAL opcode 23: DSRAV */ if (RD_OF(op) != 0) DSRAV(op); else NOP(0); break; case 24: MULT(op); break; case 25: MULTU(op); break; case 26: DIV(op); break; case 27: DIVU(op); break; case 28: DMULT(op); break; case 29: DMULTU(op); break; case 30: DDIV(op); break; case 31: DDIVU(op); break; case 32: /* SPECIAL opcode 32: ADD */ if (RD_OF(op) != 0) ADD(op); else NOP(0); break; case 33: /* SPECIAL opcode 33: ADDU */ if (RD_OF(op) != 0) ADDU(op); else NOP(0); break; case 34: /* SPECIAL opcode 34: SUB */ if (RD_OF(op) != 0) SUB(op); else NOP(0); break; case 35: /* SPECIAL opcode 35: SUBU */ if (RD_OF(op) != 0) SUBU(op); else NOP(0); break; case 36: /* SPECIAL opcode 36: AND */ if (RD_OF(op) != 0) AND(op); else NOP(0); break; case 37: /* SPECIAL opcode 37: OR */ if (RD_OF(op) != 0) OR(op); else NOP(0); break; case 38: /* SPECIAL opcode 38: XOR */ if (RD_OF(op) != 0) XOR(op); else NOP(0); break; case 39: /* SPECIAL opcode 39: NOR */ if (RD_OF(op) != 0) NOR(op); else NOP(0); break; case 42: /* SPECIAL opcode 42: SLT */ if (RD_OF(op) != 0) SLT(op); else NOP(0); break; case 43: /* SPECIAL opcode 43: SLTU */ if (RD_OF(op) != 0) SLTU(op); else NOP(0); break; case 44: /* SPECIAL opcode 44: DADD */ if (RD_OF(op) != 0) DADD(op); else NOP(0); break; case 45: /* SPECIAL opcode 45: DADDU */ if (RD_OF(op) != 0) DADDU(op); else NOP(0); break; case 46: /* SPECIAL opcode 46: DSUB */ if (RD_OF(op) != 0) DSUB(op); else NOP(0); break; case 47: /* SPECIAL opcode 47: DSUBU */ if (RD_OF(op) != 0) DSUBU(op); else NOP(0); break; case 48: /* SPECIAL opcode 48: TGE (Not implemented) */ case 49: /* SPECIAL opcode 49: TGEU (Not implemented) */ case 50: /* SPECIAL opcode 50: TLT (Not implemented) */ case 51: /* SPECIAL opcode 51: TLTU (Not implemented) */ NI(op); break; case 52: TEQ(op); break; case 54: /* SPECIAL opcode 54: TNE (Not implemented) */ NI(op); break; case 56: /* SPECIAL opcode 56: DSLL */ if (RD_OF(op) != 0) DSLL(op); else NOP(0); break; case 58: /* SPECIAL opcode 58: DSRL */ if (RD_OF(op) != 0) DSRL(op); else NOP(0); break; case 59: /* SPECIAL opcode 59: DSRA */ if (RD_OF(op) != 0) DSRA(op); else NOP(0); break; case 60: /* SPECIAL opcode 60: DSLL32 */ if (RD_OF(op) != 0) DSLL32(op); else NOP(0); break; case 62: /* SPECIAL opcode 62: DSRL32 */ if (RD_OF(op) != 0) DSRL32(op); else NOP(0); break; case 63: /* SPECIAL opcode 63: DSRA32 */ if (RD_OF(op) != 0) DSRA32(op); else NOP(0); break; default: /* SPECIAL opcodes 1, 5, 10, 11, 14, 21, 40, 41, 53, 55, 57, 61: Reserved Instructions */ RESERVED(op); break; } /* switch (op & 0x3F) for the SPECIAL prefix */ break; case 1: /* REGIMM prefix */ switch ((op >> 16) & 0x1F) { case 0: /* REGIMM opcode 0: BLTZ */ if (IS_RELATIVE_IDLE_LOOP(op, PC->addr)) BLTZ_IDLE(op); else BLTZ(op); break; case 1: /* REGIMM opcode 1: BGEZ */ if (IS_RELATIVE_IDLE_LOOP(op, PC->addr)) BGEZ_IDLE(op); else BGEZ(op); break; case 2: /* REGIMM opcode 2: BLTZL */ if (IS_RELATIVE_IDLE_LOOP(op, PC->addr)) BLTZL_IDLE(op); else BLTZL(op); break; case 3: /* REGIMM opcode 3: BGEZL */ if (IS_RELATIVE_IDLE_LOOP(op, PC->addr)) BGEZL_IDLE(op); else BGEZL(op); break; case 8: /* REGIMM opcode 8: TGEI (Not implemented) */ case 9: /* REGIMM opcode 9: TGEIU (Not implemented) */ case 10: /* REGIMM opcode 10: TLTI (Not implemented) */ case 11: /* REGIMM opcode 11: TLTIU (Not implemented) */ case 12: /* REGIMM opcode 12: TEQI (Not implemented) */ case 14: /* REGIMM opcode 14: TNEI (Not implemented) */ NI(op); break; case 16: /* REGIMM opcode 16: BLTZAL */ if (IS_RELATIVE_IDLE_LOOP(op, PC->addr)) BLTZAL_IDLE(op); else BLTZAL(op); break; case 17: /* REGIMM opcode 17: BGEZAL */ if (IS_RELATIVE_IDLE_LOOP(op, PC->addr)) BGEZAL_IDLE(op); else BGEZAL(op); break; case 18: /* REGIMM opcode 18: BLTZALL */ if (IS_RELATIVE_IDLE_LOOP(op, PC->addr)) BLTZALL_IDLE(op); else BLTZALL(op); break; case 19: /* REGIMM opcode 19: BGEZALL */ if (IS_RELATIVE_IDLE_LOOP(op, PC->addr)) BGEZALL_IDLE(op); else BGEZALL(op); break; default: /* REGIMM opcodes 4..7, 13, 15, 20..31: Reserved Instructions */ RESERVED(op); break; } /* switch ((op >> 16) & 0x1F) for the REGIMM prefix */ break; case 2: /* Major opcode 2: J */ if (IS_ABSOLUTE_IDLE_LOOP(op, PC->addr)) J_IDLE(op); else J(op); break; case 3: /* Major opcode 3: JAL */ if (IS_ABSOLUTE_IDLE_LOOP(op, PC->addr)) JAL_IDLE(op); else JAL(op); break; case 4: /* Major opcode 4: BEQ */ if (IS_RELATIVE_IDLE_LOOP(op, PC->addr)) BEQ_IDLE(op); else BEQ(op); break; case 5: /* Major opcode 5: BNE */ if (IS_RELATIVE_IDLE_LOOP(op, PC->addr)) BNE_IDLE(op); else BNE(op); break; case 6: /* Major opcode 6: BLEZ */ if (IS_RELATIVE_IDLE_LOOP(op, PC->addr)) BLEZ_IDLE(op); else BLEZ(op); break; case 7: /* Major opcode 7: BGTZ */ if (IS_RELATIVE_IDLE_LOOP(op, PC->addr)) BGTZ_IDLE(op); else BGTZ(op); break; case 8: /* Major opcode 8: ADDI */ if (RT_OF(op) != 0) ADDI(op); else NOP(0); break; case 9: /* Major opcode 9: ADDIU */ if (RT_OF(op) != 0) ADDIU(op); else NOP(0); break; case 10: /* Major opcode 10: SLTI */ if (RT_OF(op) != 0) SLTI(op); else NOP(0); break; case 11: /* Major opcode 11: SLTIU */ if (RT_OF(op) != 0) SLTIU(op); else NOP(0); break; case 12: /* Major opcode 12: ANDI */ if (RT_OF(op) != 0) ANDI(op); else NOP(0); break; case 13: /* Major opcode 13: ORI */ if (RT_OF(op) != 0) ORI(op); else NOP(0); break; case 14: /* Major opcode 14: XORI */ if (RT_OF(op) != 0) XORI(op); else NOP(0); break; case 15: /* Major opcode 15: LUI */ if (RT_OF(op) != 0) LUI(op); else NOP(0); break; case 16: /* Coprocessor 0 prefix */ switch ((op >> 21) & 0x1F) { case 0: /* Coprocessor 0 opcode 0: MFC0 */ if (RT_OF(op) != 0) MFC0(op); else NOP(0); break; case 4: MTC0(op); break; case 16: /* Coprocessor 0 opcode 16: TLB */ switch (op & 0x3F) { case 1: TLBR(op); break; case 2: TLBWI(op); break; case 6: TLBWR(op); break; case 8: TLBP(op); break; case 24: ERET(op); break; default: /* TLB sub-opcodes 0, 3..5, 7, 9..23, 25..63: Reserved Instructions */ RESERVED(op); break; } /* switch (op & 0x3F) for Coprocessor 0 TLB opcodes */ break; default: /* Coprocessor 0 opcodes 1..3, 4..15, 17..31: Reserved Instructions */ RESERVED(op); break; } /* switch ((op >> 21) & 0x1F) for the Coprocessor 0 prefix */ break; case 17: /* Coprocessor 1 prefix */ switch ((op >> 21) & 0x1F) { case 0: /* Coprocessor 1 opcode 0: MFC1 */ if (RT_OF(op) != 0) MFC1(op); else NOP(0); break; case 1: /* Coprocessor 1 opcode 1: DMFC1 */ if (RT_OF(op) != 0) DMFC1(op); else NOP(0); break; case 2: /* Coprocessor 1 opcode 2: CFC1 */ if (RT_OF(op) != 0) CFC1(op); else NOP(0); break; case 4: MTC1(op); break; case 5: DMTC1(op); break; case 6: CTC1(op); break; case 8: /* Coprocessor 1 opcode 8: Branch on C1 condition... */ switch ((op >> 16) & 0x3) { case 0: /* opcode 0: BC1F */ if (IS_RELATIVE_IDLE_LOOP(op, PC->addr)) BC1F_IDLE(op); else BC1F(op); break; case 1: /* opcode 1: BC1T */ if (IS_RELATIVE_IDLE_LOOP(op, PC->addr)) BC1T_IDLE(op); else BC1T(op); break; case 2: /* opcode 2: BC1FL */ if (IS_RELATIVE_IDLE_LOOP(op, PC->addr)) BC1FL_IDLE(op); else BC1FL(op); break; case 3: /* opcode 3: BC1TL */ if (IS_RELATIVE_IDLE_LOOP(op, PC->addr)) BC1TL_IDLE(op); else BC1TL(op); break; } /* switch ((op >> 16) & 0x3) for branches on C1 condition */ break; case 16: /* Coprocessor 1 S-format opcodes */ switch (op & 0x3F) { case 0: ADD_S(op); break; case 1: SUB_S(op); break; case 2: MUL_S(op); break; case 3: DIV_S(op); break; case 4: SQRT_S(op); break; case 5: ABS_S(op); break; case 6: MOV_S(op); break; case 7: NEG_S(op); break; case 8: ROUND_L_S(op); break; case 9: TRUNC_L_S(op); break; case 10: CEIL_L_S(op); break; case 11: FLOOR_L_S(op); break; case 12: ROUND_W_S(op); break; case 13: TRUNC_W_S(op); break; case 14: CEIL_W_S(op); break; case 15: FLOOR_W_S(op); break; case 33: CVT_D_S(op); break; case 36: CVT_W_S(op); break; case 37: CVT_L_S(op); break; case 48: C_F_S(op); break; case 49: C_UN_S(op); break; case 50: C_EQ_S(op); break; case 51: C_UEQ_S(op); break; case 52: C_OLT_S(op); break; case 53: C_ULT_S(op); break; case 54: C_OLE_S(op); break; case 55: C_ULE_S(op); break; case 56: C_SF_S(op); break; case 57: C_NGLE_S(op); break; case 58: C_SEQ_S(op); break; case 59: C_NGL_S(op); break; case 60: C_LT_S(op); break; case 61: C_NGE_S(op); break; case 62: C_LE_S(op); break; case 63: C_NGT_S(op); break; default: /* Coprocessor 1 S-format opcodes 16..32, 34..35, 38..47: Reserved Instructions */ RESERVED(op); break; } /* switch (op & 0x3F) for Coprocessor 1 S-format opcodes */ break; case 17: /* Coprocessor 1 D-format opcodes */ switch (op & 0x3F) { case 0: ADD_D(op); break; case 1: SUB_D(op); break; case 2: MUL_D(op); break; case 3: DIV_D(op); break; case 4: SQRT_D(op); break; case 5: ABS_D(op); break; case 6: MOV_D(op); break; case 7: NEG_D(op); break; case 8: ROUND_L_D(op); break; case 9: TRUNC_L_D(op); break; case 10: CEIL_L_D(op); break; case 11: FLOOR_L_D(op); break; case 12: ROUND_W_D(op); break; case 13: TRUNC_W_D(op); break; case 14: CEIL_W_D(op); break; case 15: FLOOR_W_D(op); break; case 32: CVT_S_D(op); break; case 36: CVT_W_D(op); break; case 37: CVT_L_D(op); break; case 48: C_F_D(op); break; case 49: C_UN_D(op); break; case 50: C_EQ_D(op); break; case 51: C_UEQ_D(op); break; case 52: C_OLT_D(op); break; case 53: C_ULT_D(op); break; case 54: C_OLE_D(op); break; case 55: C_ULE_D(op); break; case 56: C_SF_D(op); break; case 57: C_NGLE_D(op); break; case 58: C_SEQ_D(op); break; case 59: C_NGL_D(op); break; case 60: C_LT_D(op); break; case 61: C_NGE_D(op); break; case 62: C_LE_D(op); break; case 63: C_NGT_D(op); break; default: /* Coprocessor 1 D-format opcodes 16..31, 33..35, 38..47: Reserved Instructions */ RESERVED(op); break; } /* switch (op & 0x3F) for Coprocessor 1 D-format opcodes */ break; case 20: /* Coprocessor 1 W-format opcodes */ switch (op & 0x3F) { case 32: CVT_S_W(op); break; case 33: CVT_D_W(op); break; default: /* Coprocessor 1 W-format opcodes 0..31, 34..63: Reserved Instructions */ RESERVED(op); break; } break; case 21: /* Coprocessor 1 L-format opcodes */ switch (op & 0x3F) { case 32: CVT_S_L(op); break; case 33: CVT_D_L(op); break; default: /* Coprocessor 1 L-format opcodes 0..31, 34..63: Reserved Instructions */ RESERVED(op); break; } break; default: /* Coprocessor 1 opcodes 3, 7, 9..15, 18..19, 22..31: Reserved Instructions */ RESERVED(op); break; } /* switch ((op >> 21) & 0x1F) for the Coprocessor 1 prefix */ break; case 20: /* Major opcode 20: BEQL */ if (IS_RELATIVE_IDLE_LOOP(op, PC->addr)) BEQL_IDLE(op); else BEQL(op); break; case 21: /* Major opcode 21: BNEL */ if (IS_RELATIVE_IDLE_LOOP(op, PC->addr)) BNEL_IDLE(op); else BNEL(op); break; case 22: /* Major opcode 22: BLEZL */ if (IS_RELATIVE_IDLE_LOOP(op, PC->addr)) BLEZL_IDLE(op); else BLEZL(op); break; case 23: /* Major opcode 23: BGTZL */ if (IS_RELATIVE_IDLE_LOOP(op, PC->addr)) BGTZL_IDLE(op); else BGTZL(op); break; case 24: /* Major opcode 24: DADDI */ if (RT_OF(op) != 0) DADDI(op); else NOP(0); break; case 25: /* Major opcode 25: DADDIU */ if (RT_OF(op) != 0) DADDIU(op); else NOP(0); break; case 26: /* Major opcode 26: LDL */ if (RT_OF(op) != 0) LDL(op); else NOP(0); break; case 27: /* Major opcode 27: LDR */ if (RT_OF(op) != 0) LDR(op); else NOP(0); break; case 32: /* Major opcode 32: LB */ if (RT_OF(op) != 0) LB(op); else NOP(0); break; case 33: /* Major opcode 33: LH */ if (RT_OF(op) != 0) LH(op); else NOP(0); break; case 34: /* Major opcode 34: LWL */ if (RT_OF(op) != 0) LWL(op); else NOP(0); break; case 35: /* Major opcode 35: LW */ if (RT_OF(op) != 0) LW(op); else NOP(0); break; case 36: /* Major opcode 36: LBU */ if (RT_OF(op) != 0) LBU(op); else NOP(0); break; case 37: /* Major opcode 37: LHU */ if (RT_OF(op) != 0) LHU(op); else NOP(0); break; case 38: /* Major opcode 38: LWR */ if (RT_OF(op) != 0) LWR(op); else NOP(0); break; case 39: /* Major opcode 39: LWU */ if (RT_OF(op) != 0) LWU(op); else NOP(0); break; case 40: SB(op); break; case 41: SH(op); break; case 42: SWL(op); break; case 43: SW(op); break; case 44: SDL(op); break; case 45: SDR(op); break; case 46: SWR(op); break; case 47: CACHE(op); break; case 48: /* Major opcode 48: LL */ if (RT_OF(op) != 0) LL(op); else NOP(0); break; case 49: LWC1(op); break; case 52: /* Major opcode 52: LLD (Not implemented) */ NI(op); break; case 53: LDC1(op); break; case 55: /* Major opcode 55: LD */ if (RT_OF(op) != 0) LD(op); else NOP(0); break; case 56: /* Major opcode 56: SC */ if (RT_OF(op) != 0) SC(op); else NOP(0); break; case 57: SWC1(op); break; case 60: /* Major opcode 60: SCD (Not implemented) */ NI(op); break; case 61: SDC1(op); break; case 63: SD(op); break; default: /* Major opcodes 18..19, 28..31, 50..51, 54, 58..59, 62: Reserved Instructions */ RESERVED(op); break; } /* switch ((op >> 26) & 0x3F) */ } void pure_interpreter_init(void) { stop = 0; PC = &interp_PC; PC->addr = last_addr = 0xa4000040; } void pure_interpreter(void) { #ifdef COMPARE_CORE CoreCompareCallback(); #endif #ifdef DBG if (g_DebuggerActive) update_debugger(PC->addr); #endif InterpretOpcode(); } mupen64plus-core/src/si/af_rtc.h000664 001750 001750 00000003676 12655644434 017674 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - af_rtc.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_SI_AF_RTC_H #define M64P_SI_AF_RTC_H #include struct tm; struct af_rtc { /* external time source */ void* user_data; const struct tm* (*get_time)(void*); }; const struct tm* af_rtc_get_time(struct af_rtc* rtc); void af_rtc_status_command(struct af_rtc* rtc, uint8_t* cmd); void af_rtc_read_command(struct af_rtc* rtc, uint8_t* cmd); void af_rtc_write_command(struct af_rtc* rtc, uint8_t* cmd); #endif glide2gl/src/Glitch64/glide.h000664 001750 001750 00000050700 12655644434 017022 0ustar00sergiosergio000000 000000 #ifndef __GLIDE_H__ #define __GLIDE_H__ #define GL_GLEXT_PROTOTYPES #include #include "boolean.h" #include "../../../mupen64plus-core/src/rdp_common/gdp.h" #ifdef __cplusplus extern "C" { #endif /* ** ----------------------------------------------------------------------- ** TYPE DEFINITIONS ** ----------------------------------------------------------------------- */ /* ** fundamental types */ #define FXTRUE 1 #define FXFALSE 0 /* ** helper macros */ #define FXBIT( i ) ( 1L << (i) ) typedef int (*GrProc)(); /* ** ----------------------------------------------------------------------- ** CONSTANTS AND TYPES ** ----------------------------------------------------------------------- */ #define GR_MIPMAPLEVELMASK_EVEN FXBIT(0) #define GR_MIPMAPLEVELMASK_ODD FXBIT(1) #define GR_MIPMAPLEVELMASK_BOTH (GR_MIPMAPLEVELMASK_EVEN | GR_MIPMAPLEVELMASK_ODD ) #define GR_LODBIAS_BILINEAR 0.5 #define GR_LODBIAS_TRILINEAR 0.0 #define GR_TMU0 0x0 #define GR_TMU1 0x1 #define GR_TMU2 0x2 #define GR_COMBINE_FUNCTION_ZERO 0x0 #define GR_COMBINE_FUNCTION_NONE GR_COMBINE_FUNCTION_ZERO #define GR_COMBINE_FUNCTION_LOCAL 0x1 #define GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2 #define GR_COMBINE_FUNCTION_SCALE_OTHER 0x3 #define GR_COMBINE_FUNCTION_BLEND_OTHER GR_COMBINE_FUNCTION_SCALE_OTHER #define GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4 #define GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5 #define GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6 #define GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7 #define GR_COMBINE_FUNCTION_BLEND GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL #define GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8 #define GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9 #define GR_COMBINE_FUNCTION_BLEND_LOCAL GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL #define GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10 #define GR_COMBINE_FACTOR_ZERO 0x0 #define GR_COMBINE_FACTOR_NONE GR_COMBINE_FACTOR_ZERO #define GR_COMBINE_FACTOR_LOCAL 0x1 #define GR_COMBINE_FACTOR_OTHER_ALPHA 0x2 #define GR_COMBINE_FACTOR_LOCAL_ALPHA 0x3 #define GR_COMBINE_FACTOR_TEXTURE_ALPHA 0x4 #define GR_COMBINE_FACTOR_TEXTURE_RGB 0x5 #define GR_COMBINE_FACTOR_DETAIL_FACTOR GR_COMBINE_FACTOR_TEXTURE_ALPHA #define GR_COMBINE_FACTOR_LOD_FRACTION 0x5 #define GR_COMBINE_FACTOR_ONE 0x8 #define GR_COMBINE_FACTOR_ONE_MINUS_LOCAL 0x9 #define GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA 0xa #define GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA 0xb #define GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA 0xc #define GR_COMBINE_FACTOR_ONE_MINUS_DETAIL_FACTOR GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA #define GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION 0xd #define GR_COMBINE_LOCAL_ITERATED 0x0 #define GR_COMBINE_LOCAL_CONSTANT 0x1 #define GR_COMBINE_LOCAL_NONE GR_COMBINE_LOCAL_CONSTANT #define GR_COMBINE_LOCAL_DEPTH 0x2 #define GR_COMBINE_OTHER_ITERATED 0x0 #define GR_COMBINE_OTHER_TEXTURE 0x1 #define GR_COMBINE_OTHER_CONSTANT 0x2 #define GR_COMBINE_OTHER_NONE GR_COMBINE_OTHER_CONSTANT #define GR_ALPHASOURCE_CC_ALPHA 0x0 #define GR_ALPHASOURCE_ITERATED_ALPHA 0x1 #define GR_ALPHASOURCE_TEXTURE_ALPHA 0x2 #define GR_ALPHASOURCE_TEXTURE_ALPHA_TIMES_ITERATED_ALPHA 0x3 #define GR_COLORCOMBINE_ZERO 0x0 #define GR_COLORCOMBINE_CCRGB 0x1 #define GR_COLORCOMBINE_ITRGB 0x2 #define GR_COLORCOMBINE_ITRGB_DELTA0 0x3 #define GR_COLORCOMBINE_DECAL_TEXTURE 0x4 #define GR_COLORCOMBINE_TEXTURE_TIMES_CCRGB 0x5 #define GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB 0x6 #define GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB_DELTA0 0x7 #define GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB_ADD_ALPHA 0x8 #define GR_COLORCOMBINE_TEXTURE_TIMES_ALPHA 0x9 #define GR_COLORCOMBINE_TEXTURE_TIMES_ALPHA_ADD_ITRGB 0xa #define GR_COLORCOMBINE_TEXTURE_ADD_ITRGB 0xb #define GR_COLORCOMBINE_TEXTURE_SUB_ITRGB 0xc #define GR_COLORCOMBINE_CCRGB_BLEND_ITRGB_ON_TEXALPHA 0xd #define GR_COLORCOMBINE_DIFF_SPEC_A 0xe #define GR_COLORCOMBINE_DIFF_SPEC_B 0xf #define GR_COLORCOMBINE_ONE 0x10 #define GR_BLEND_ZERO GL_ZERO #define GR_BLEND_SRC_ALPHA GL_SRC_ALPHA #define GR_BLEND_SRC_COLOR 0x2 #define GR_BLEND_DST_COLOR GR_BLEND_SRC_COLOR #define GR_BLEND_DST_ALPHA 0x3 #define GR_BLEND_ONE GL_ONE #define GR_BLEND_ONE_MINUS_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA #define GR_BLEND_ONE_MINUS_SRC_COLOR 0x6 #define GR_BLEND_ONE_MINUS_DST_COLOR GR_BLEND_ONE_MINUS_SRC_COLOR #define GR_BLEND_ONE_MINUS_DST_ALPHA 0x7 #define GR_BLEND_RESERVED_8 0x8 #define GR_BLEND_RESERVED_9 0x9 #define GR_BLEND_RESERVED_A 0xa #define GR_BLEND_RESERVED_B 0xb #define GR_BLEND_RESERVED_C 0xc #define GR_BLEND_RESERVED_D 0xd #define GR_BLEND_RESERVED_E 0xe #define GR_BLEND_ALPHA_SATURATE 0xf #define GR_BLEND_PREFOG_COLOR GR_BLEND_ALPHA_SATURATE #define GR_ASPECT_LOG2_8x1 3 /* 8W x 1H */ #define GR_ASPECT_LOG2_4x1 2 /* 4W x 1H */ #define GR_ASPECT_LOG2_2x1 1 /* 2W x 1H */ #define GR_ASPECT_LOG2_1x1 0 /* 1W x 1H */ #define GR_ASPECT_LOG2_1x2 -1 /* 1W x 2H */ #define GR_ASPECT_LOG2_1x4 -2 /* 1W x 4H */ #define GR_ASPECT_LOG2_1x8 -3 /* 1W x 8H */ #define GR_BUFFER_FRONTBUFFER 0x0 #define GR_BUFFER_BACKBUFFER 0x1 #define GR_BUFFER_AUXBUFFER 0x2 #define GR_BUFFER_DEPTHBUFFER 0x3 #define GR_BUFFER_ALPHABUFFER 0x4 #define GR_BUFFER_TRIPLEBUFFER 0x5 #define GR_CHROMAKEY_DISABLE 0x0 #define GR_CHROMAKEY_ENABLE 0x1 #define GR_CHROMARANGE_RGB_ALL_EXT 0x0 #define GR_CHROMARANGE_DISABLE_EXT 0x00 #define GR_CHROMARANGE_ENABLE_EXT 0x01 #define GR_TEXCHROMA_DISABLE_EXT 0x0 #define GR_TEXCHROMA_ENABLE_EXT 0x1 #define GR_TEXCHROMARANGE_RGB_ALL_EXT 0x0 #define GR_CMP_NEVER GL_NEVER #define GR_CMP_LESS GL_LESS #define GR_CMP_EQUAL GL_EQUAL #define GR_CMP_LEQUAL GL_LEQUAL #define GR_CMP_GREATER GL_GREATER #define GR_CMP_NOTEQUAL GL_NOTEQUAL #define GR_CMP_GEQUAL GL_EQUAL #define GR_CMP_ALWAYS GL_ALWAYS #define GR_COLORFORMAT_ARGB 0x0 #define GR_COLORFORMAT_ABGR 0x1 #define GR_COLORFORMAT_RGBA 0x2 #define GR_COLORFORMAT_BGRA 0x3 #define GR_CULL_DISABLE 0x0 #define GR_CULL_NEGATIVE 0x1 #define GR_CULL_POSITIVE 0x2 #define GR_DEPTHBUFFER_DISABLE 0x0 #define GR_DEPTHBUFFER_ZBUFFER 0x1 #define GR_DEPTHBUFFER_WBUFFER 0x2 #define GR_DEPTHBUFFER_ZBUFFER_COMPARE_TO_BIAS 0x3 #define GR_DEPTHBUFFER_WBUFFER_COMPARE_TO_BIAS 0x4 #define GR_DITHER_DISABLE 0x0 #define GR_DITHER_2x2 0x1 #define GR_DITHER_4x4 0x2 #define GR_STIPPLE_DISABLE 0x0 #define GR_STIPPLE_PATTERN 0x1 #define GR_STIPPLE_ROTATE 0x2 #define GR_FOG_DISABLE 0x0 #define GR_FOG_WITH_TABLE_ON_Q 0x1 #define GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT 0x2 #define GR_LFB_READ_ONLY 0x00 #define GR_LFB_WRITE_ONLY 0x01 #define GR_LFB_IDLE 0x00 #define GR_LFB_NOIDLE 0x10 #define GR_LFB_WRITE_ONLY_EXPLICIT_EXT 0x02 /* explicitly not allow reading from the lfb pointer */ #define GR_LFBBYPASS_DISABLE 0x0 #define GR_LFBBYPASS_ENABLE 0x1 #define GR_LFBWRITEMODE_565 0x0 /* RGB:RGB */ #define GR_LFBWRITEMODE_555 0x1 /* RGB:RGB */ #define GR_LFBWRITEMODE_1555 0x2 /* ARGB:ARGB */ #define GR_LFBWRITEMODE_RESERVED1 0x3 #define GR_LFBWRITEMODE_888 0x4 /* RGB */ #define GR_LFBWRITEMODE_8888 0x5 /* ARGB */ #define GR_LFBWRITEMODE_RESERVED2 0x6 #define GR_LFBWRITEMODE_RESERVED3 0x7 #define GR_LFBWRITEMODE_RESERVED4 0x8 #define GR_LFBWRITEMODE_RESERVED5 0x9 #define GR_LFBWRITEMODE_RESERVED6 0xa #define GR_LFBWRITEMODE_RESERVED7 0xb #define GR_LFBWRITEMODE_565_DEPTH 0xc /* RGB:DEPTH */ #define GR_LFBWRITEMODE_555_DEPTH 0xd /* RGB:DEPTH */ #define GR_LFBWRITEMODE_1555_DEPTH 0xe /* ARGB:DEPTH */ #define GR_LFBWRITEMODE_ZA16 0xf /* DEPTH:DEPTH */ #define GR_LFBWRITEMODE_ANY 0xFF #define GR_ORIGIN_UPPER_LEFT 0x0 #define GR_ORIGIN_LOWER_LEFT 0x1 #define GR_ORIGIN_ANY 0xFF typedef struct { int size; void *lfbPtr; uint32_t strideInBytes; int32_t writeMode; int32_t origin; } GrLfbInfo_t; #define GR_LOD_LOG2_256 0x8 #define GR_LOD_LOG2_128 0x7 #define GR_LOD_LOG2_64 0x6 #define GR_LOD_LOG2_32 0x5 #define GR_LOD_LOG2_16 0x4 #define GR_LOD_LOG2_8 0x3 #define GR_LOD_LOG2_4 0x2 #define GR_LOD_LOG2_2 0x1 #define GR_LOD_LOG2_1 0x0 #define GR_MIPMAP_DISABLE 0x0 /* no mip mapping */ #define GR_MIPMAP_NEAREST 0x1 /* use nearest mipmap */ #define GR_MIPMAP_NEAREST_DITHER 0x2 /* GR_MIPMAP_NEAREST + LOD dith */ #define GR_SMOOTHING_DISABLE 0x0 #define GR_SMOOTHING_ENABLE 0x1 #define GR_TEXTURECLAMP_WRAP GL_REPEAT #define GR_TEXTURECLAMP_CLAMP GL_CLAMP_TO_EDGE #define GR_TEXTURECLAMP_MIRROR_EXT GL_MIRRORED_REPEAT #define GR_TEXTUREFILTER_POINT_SAMPLED 0x0 #define GR_TEXTUREFILTER_3POINT_LINEAR 0x1 #define GR_TEXTUREFILTER_BILINEAR 0x2 /* KoolSmoky - */ #define GR_TEXFMT_8BIT 0x0 #define GR_TEXFMT_RGB_332 GR_TEXFMT_8BIT #define GR_TEXFMT_YIQ_422 0x1 #define GR_TEXFMT_ALPHA_8 0x2 /* (0..0xFF) alpha */ #define GR_TEXFMT_INTENSITY_8 0x3 /* (0..0xFF) intensity */ #define GR_TEXFMT_ALPHA_INTENSITY_44 0x4 #define GR_TEXFMT_P_8 0x5 /* 8-bit palette */ #define GR_TEXFMT_RSVD0 0x6 /* GR_TEXFMT_P_8_RGBA */ #define GR_TEXFMT_P_8_6666 GR_TEXFMT_RSVD0 #define GR_TEXFMT_P_8_6666_EXT GR_TEXFMT_RSVD0 #define GR_TEXFMT_RSVD1 0x7 #define GR_TEXFMT_16BIT 0x8 #define GR_TEXFMT_ARGB_8332 GR_TEXFMT_16BIT #define GR_TEXFMT_AYIQ_8422 0x9 #define GR_TEXFMT_RGB_565 0xa #define GR_TEXFMT_ARGB_1555 0xb #define GR_TEXFMT_ARGB_4444 0xc #define GR_TEXFMT_ALPHA_INTENSITY_88 0xd #define GR_TEXFMT_AP_88 0xe /* 8-bit alpha 8-bit palette */ #define GR_TEXFMT_RSVD2 0xf #define GR_TEXFMT_RSVD4 GR_TEXFMT_RSVD2 #define GR_MODE_DISABLE 0x0 #define GR_MODE_ENABLE 0x1 /* Types of data in strips */ #define GR_FLOAT 0 #define GR_U8 1 /* ** grDrawVertexArray/grDrawVertexArrayContiguous primitive type */ #define GR_POINTS 0 #define GR_LINE_STRIP 1 #define GR_LINES 2 #define GR_POLYGON 3 #define GR_TRIANGLE_STRIP GL_TRIANGLE_STRIP #define GR_TRIANGLE_FAN GL_TRIANGLE_FAN #define GR_TRIANGLES GL_TRIANGLES /* ** grGetString types */ #define GR_EXTENSION 0xa0 #define GR_HARDWARE 0xa1 #define GR_RENDERER 0xa2 #define GR_VENDOR 0xa3 #define GR_VERSION 0xa4 /* ** ----------------------------------------------------------------------- ** STRUCTURES ** ----------------------------------------------------------------------- */ typedef struct { int32_t smallLodLog2; int32_t largeLodLog2; int32_t aspectRatioLog2; int32_t format; int width; int height; void *data; } GrTexInfo; #define GR_LFB_SRC_FMT_565 0x00 #define GR_LFB_SRC_FMT_555 0x01 #define GR_LFB_SRC_FMT_1555 0x02 #define GR_LFB_SRC_FMT_888 0x04 #define GR_LFB_SRC_FMT_8888 0x05 #define GR_LFB_SRC_FMT_565_DEPTH 0x0c #define GR_LFB_SRC_FMT_555_DEPTH 0x0d #define GR_LFB_SRC_FMT_1555_DEPTH 0x0e #define GR_LFB_SRC_FMT_ZA16 0x0f #define GR_LFB_SRC_FMT_RLE16 0x80 /* ** ----------------------------------------------------------------------- ** FUNCTION PROTOTYPES ** ----------------------------------------------------------------------- */ /* ** rendering functions */ void grDrawPoint( const void *pt ); void grDrawLine( const void *v1, const void *v2 ); void grVertexLayout(uint32_t param, int32_t offset, uint32_t mode); void grDrawVertexArrayContiguous(uint32_t mode, uint32_t Count, void *pointers); void grBufferClear(uint32_t color, uint32_t alpha, uint32_t depth); void grBufferSwap(uint32_t swap_interval); /* * Vertex Cache functions * * these are public just to allow reuse of the vertex cache vbo in some * specific places. you probably do not want to use them. */ void vbo_enable(); void vbo_disable(); void vbo_bind(); void vbo_unbind(); void vbo_buffer_data(void *data, size_t size); /* ** error management */ typedef void (*GrErrorCallbackFnc_t)( const char *string, int32_t fatal ); void grErrorSetCallback( GrErrorCallbackFnc_t fnc ); /* ** SST routines */ uint32_t grSstWinOpen(void); int32_t grSstWinClose( uint32_t context ); /* ** Glide configuration and special effect maintenance functions */ void grAlphaBlendFunction(GLenum rgb_sf, GLenum rgb_df, GLenum alpha_sf, GLenum alpha_df); void grAlphaCombine( int32_t function, int32_t factor, int32_t local, int32_t other, int32_t invert ); void grAlphaTestFunction( int32_t function, uint8_t value, int set_alpha_ref); void grAlphaTestReferenceValue( uint8_t value ); void grChromakeyMode( int32_t mode ); void grChromakeyValue( uint32_t value ); void grClipWindow(uint32_t minx, uint32_t miny, uint32_t maxx, uint32_t maxy); void grColorCombine( int32_t function, int32_t factor, int32_t local, int32_t other, int32_t invert ); void grColorMask(bool rgb, bool a); void grCullMode( int32_t mode ); void grConstantColorValue( uint32_t value ); void grDepthBiasLevel( int32_t level ); void grDepthBufferFunction(GLenum func); #define grDepthBufferMode(mode) \ { \ if (mode == GR_DEPTHBUFFER_DISABLE) \ glDisable(GL_DEPTH_TEST); \ else \ glEnable(GL_DEPTH_TEST); \ } void grDepthMask(bool mask); void grFogMode( int32_t mode, uint32_t fogcolor ); void grLoadGammaTable( uint32_t nentries, uint32_t *red, uint32_t *green, uint32_t *blue); void grDepthRange( float n, float f ); void grStippleMode( int32_t mode ); void grStipplePattern( uint32_t mode ); void grViewport( int32_t x, int32_t y, int32_t width, int32_t height ); /* ** texture mapping control functions */ uint32_t grTexCalcMemRequired( int32_t lodmax, int32_t aspect, int32_t fmt); #define TMU_SIZE (8 * 2048 * 2048) #define grTexMaxAddress(tmu) ((TMU_SIZE * 2) - 1) void grTexSource( int32_t tmu, uint32_t startAddress, uint32_t evenOdd, GrTexInfo *info, int do_download); void grTexFilterClampMode( int32_t tmu, int32_t s_clampmode, int32_t t_clampmode, int32_t minfilter_mode, int32_t magfilter_mode ); void grTexCombine( int32_t tmu, int32_t rgb_function, int32_t rgb_factor, int32_t alpha_function, int32_t alpha_factor, int32_t rgb_invert, int32_t alpha_invert ); void grTexDetailControl( int32_t tmu, int lod_bias, uint8_t detail_scale, float detail_max ); void grTexMipMapMode( int32_t tmu, int32_t mode, int32_t lodBlend ); /* ** linear frame buffer functions */ int32_t grLfbLock( int32_t type, int32_t buffer, int32_t writeMode, int32_t origin, int32_t pixelPipeline, GrLfbInfo_t *info ); #define grLfbUnlock(type, buffer) (true) void grLfbConstantAlpha( uint8_t alpha ); void grLfbConstantDepth( uint32_t depth ); void grLfbWriteColorSwizzle(int32_t swizzleBytes, int32_t swapWords); void grLfbWriteColorFormat(int32_t colorFormat); int32_t grLfbWriteRegion( int32_t dst_buffer, uint32_t dst_x, uint32_t dst_y, uint32_t src_format, uint32_t src_width, uint32_t src_height, int32_t pixelPipeline, int32_t src_stride, void *src_data ); int32_t grLfbReadRegion( int32_t src_buffer, uint32_t src_x, uint32_t src_y, uint32_t src_width, uint32_t src_height, uint32_t dst_stride, void *dst_data ); #define guFogGenerateLinear(nearZ, farZ) \ { \ fogStart = (nearZ) / 255.0f; \ fogEnd = (farZ) / 255.0f; \ } extern unsigned int BUFFERSWAP; #define NUM_TMU 2 // Vertex structure typedef struct { float x, y, z, q; uint8_t b; // These values are arranged like this so that *(uint32_t*)(VERTEX+?) is uint8_t g; // ARGB format that glide can use. uint8_t r; uint8_t a; float coord[4]; float f; //fog float u[2]; float v[2]; float w; uint16_t flags; float vec[3]; // normal vector float sx, sy, sz; float x_w, y_w, z_w, oow; float u_w[2]; float v_w[2]; uint8_t not_zclipped; uint8_t screen_translated; uint8_t uv_scaled; uint32_t uv_calculated; // like crc uint32_t shade_mod; uint32_t color_backup; float ou, ov; int number; // way to identify it int scr_off, z_off; // off the screen? } VERTEX; // ZIGGY framebuffer copy extension // allow to copy the depth or color buffer from back/front to front/back #define GR_FBCOPY_MODE_DEPTH 0 #define GR_FBCOPY_MODE_COLOR 1 #define GR_FBCOPY_BUFFER_BACK 0 #define GR_FBCOPY_BUFFER_FRONT 1 // COMBINE extension #define GR_FUNC_MODE_ZERO 0x00 #define GR_FUNC_MODE_X 0x01 #define GR_FUNC_MODE_ONE_MINUS_X 0x02 #define GR_FUNC_MODE_NEGATIVE_X 0x03 #define GR_FUNC_MODE_X_MINUS_HALF 0x04 #define GR_CMBX_ZERO 0x00 #define GR_CMBX_TEXTURE_ALPHA 0x01 #define GR_CMBX_ALOCAL 0x02 #define GR_CMBX_AOTHER 0x03 #define GR_CMBX_B 0x04 #define GR_CMBX_CONSTANT_ALPHA 0x05 #define GR_CMBX_CONSTANT_COLOR 0x06 #define GR_CMBX_DETAIL_FACTOR 0x07 #define GR_CMBX_ITALPHA 0x08 #define GR_CMBX_ITRGB 0x09 #define GR_CMBX_LOCAL_TEXTURE_ALPHA 0x0a #define GR_CMBX_LOCAL_TEXTURE_RGB 0x0b #define GR_CMBX_LOD_FRAC 0x0c #define GR_CMBX_OTHER_TEXTURE_ALPHA 0x0d #define GR_CMBX_OTHER_TEXTURE_RGB 0x0e #define GR_CMBX_TEXTURE_RGB 0x0f #define GR_CMBX_TMU_CALPHA 0x10 #define GR_CMBX_TMU_CCOLOR 0x11 void grColorCombineExt(uint32_t a, uint32_t a_mode, uint32_t b, uint32_t b_mode, uint32_t c, int32_t c_invert, uint32_t d, int32_t d_invert, uint32_t shift, int32_t invert); void grAlphaCombineExt(uint32_t a, uint32_t a_mode, uint32_t b, uint32_t b_mode, uint32_t c, int32_t c_invert, uint32_t d, int32_t d_invert, uint32_t shift, int32_t invert); void grTexColorCombineExt(int32_t tmu, uint32_t a, uint32_t a_mode, uint32_t b, uint32_t b_mode, uint32_t c, int32_t c_invert, uint32_t d, int32_t d_invert, uint32_t shift, int32_t invert); void grTexAlphaCombineExt(int32_t tmu, uint32_t a, uint32_t a_mode, uint32_t b, uint32_t b_mode, uint32_t c, int32_t c_invert, uint32_t d, int32_t d_invert, uint32_t shift, int32_t invert, uint32_t ccolor_value); void grColorCombineExt(uint32_t a, uint32_t a_mode, uint32_t b, uint32_t b_mode, uint32_t c, int32_t c_invert, uint32_t d, int32_t d_invert, uint32_t shift, int32_t invert); void grAlphaCombineExt(uint32_t a, uint32_t a_mode, uint32_t b, uint32_t b_mode, uint32_t c, int32_t c_invert, uint32_t d, int32_t d_invert, uint32_t shift, int32_t invert); extern void grChromaRangeExt(uint32_t color0, uint32_t color1, uint32_t mode); extern void grChromaRangeModeExt(int32_t mode); extern void grTexChromaRangeExt(int32_t tmu, uint32_t color0, uint32_t color1, int32_t mode); extern void grTexChromaModeExt(int32_t tmu, int32_t mode); extern int width, height; extern float fogStart, fogEnd; #ifdef __cplusplus } #endif #endif /* __GLIDE_H__ */ Makefile000664 001750 001750 00000025070 12655644434 013363 0ustar00sergiosergio000000 000000 DEBUG=0 PERF_TEST=0 HAVE_SHARED_CONTEXT=0 SINGLE_THREAD=0 GLIDEN64=0 WITH_CRC=brumme DYNAFLAGS := INCFLAGS := COREFLAGS := CPUFLAGS := UNAME=$(shell uname -a) # Dirs ROOT_DIR := . LIBRETRO_DIR := $(ROOT_DIR)/libretro ifeq ($(platform),) platform = unix ifeq ($(UNAME),) platform = win else ifneq ($(findstring MINGW,$(UNAME)),) platform = win else ifneq ($(findstring Darwin,$(UNAME)),) platform = osx else ifneq ($(findstring win,$(UNAME)),) platform = win endif endif # system platform system_platform = unix ifeq ($(shell uname -a),) EXE_EXT = .exe system_platform = win else ifneq ($(findstring Darwin,$(shell uname -a)),) system_platform = osx arch = intel ifeq ($(shell uname -p),powerpc) arch = ppc endif else ifneq ($(findstring MINGW,$(shell uname -a)),) system_platform = win endif # Cross compile ? ifeq (,$(ARCH)) ARCH = $(shell uname -m) endif # Target Dynarec WITH_DYNAREC = $(ARCH) ifeq ($(ARCH), $(filter $(ARCH), i386 i686)) WITH_DYNAREC = x86 endif TARGET_NAME := mupen64plus CC_AS ?= $(CC) # Unix ifneq (,$(findstring unix,$(platform))) TARGET := $(TARGET_NAME)_libretro.so LDFLAGS += -shared -Wl,--version-script=$(LIBRETRO_DIR)/link.T -Wl,--no-undefined fpic = -fPIC ifneq (,$(findstring gles,$(platform))) GLES = 1 GL_LIB := -lGLESv2 else GL_LIB := -lGL endif PLATFORM_EXT := unix # Raspberry Pi else ifneq (,$(findstring rpi,$(platform))) TARGET := $(TARGET_NAME)_libretro.so LDFLAGS += -shared -Wl,--version-script=$(LIBRETRO_DIR)/link.T fpic = -fPIC GLES = 1 GL_LIB := -L/opt/vc/lib -lGLESv2 INCFLAGS += -I/opt/vc/include ifneq (,$(findstring rpi2,$(platform))) CPUFLAGS += -DNO_ASM -DARM -D__arm__ -DARM_ASM -D__NEON_OPT -DNOSSE CFLAGS = -mcpu=cortex-a7 -mfloat-abi=hard CXXFLAGS = -mcpu=cortex-a7 -mfloat-abi=hard HAVE_NEON = 0 else CPUFLAGS += -DARMv5_ONLY -DNO_ASM endif PLATFORM_EXT := unix WITH_DYNAREC=arm # ODROIDs else ifneq (,$(findstring odroid,$(platform))) TARGET := $(TARGET_NAME)_libretro.so BOARD := $(shell cat /proc/cpuinfo | grep -i odroid | awk '{print $$3}') LDFLAGS += -shared -Wl,--version-script=$(LIBRETRO_DIR)/link.T fpic = -fPIC GLES = 1 GL_LIB := -lGLESv2 CPUFLAGS += -DNO_ASM -DARM -D__arm__ -DARM_ASM -D__NEON_OPT -DNOSSE CFLAGS += -marm -mfloat-abi=hard -mfpu=neon CXXFLAGS += -marm -mfloat-abi=hard -mfpu=neon GLIDE2GL = 1 HAVE_NEON = 1 ifneq (,$(findstring ODROIDC,$(BOARD))) # ODROID-C1 CFLAGS += -mcpu=cortex-a5 CXXFLAGS += -mcpu=cortex-a5 else ifneq (,$(findstring ODROID-XU3,$(BOARD))) # ODROID-XU3 & -XU3 Lite ifeq "$(shell expr `gcc -dumpversion` \>= 4.9)" "1" CFLAGS += -march=armv7ve -mcpu=cortex-a15.cortex-a7 CXXFLAGS += -march=armv7ve -mcpu=cortex-a15.cortex-a7 else CFLAGS += -mcpu=cortex-a9 CXXFLAGS += -mcpu=cortex-a9 endif else # ODROID-U2, -U3, -X & -X2 CFLAGS += -mcpu=cortex-a9 CXXFLAGS += -mcpu=cortex-a9 endif PLATFORM_EXT := unix WITH_DYNAREC=arm # i.MX6 else ifneq (,$(findstring imx6,$(platform))) TARGET := $(TARGET_NAME)_libretro.so LDFLAGS += -shared -Wl,--version-script=$(LIBRETRO_DIR)/link.T fpic = -fPIC GLES = 1 GL_LIB := -lGLESv2 CPUFLAGS += -DNO_ASM PLATFORM_EXT := unix WITH_DYNAREC=arm HAVE_NEON=1 # OS X else ifneq (,$(findstring osx,$(platform))) TARGET := $(TARGET_NAME)_libretro.dylib LDFLAGS += -dynamiclib OSXVER = `sw_vers -productVersion | cut -d. -f 2` OSX_LT_MAVERICKS = `(( $(OSXVER) <= 9)) && echo "YES"` LDFLAGS += -mmacosx-version-min=10.7 LDFLAGS += -stdlib=libc++ fpic = -fPIC PLATCFLAGS += -D__MACOSX__ -DOSX GL_LIB := -framework OpenGL PLATFORM_EXT := unix # Target Dynarec ifeq ($(ARCH), $(filter $(ARCH), ppc)) WITH_DYNAREC = endif # iOS else ifneq (,$(findstring ios,$(platform))) ifeq ($(IOSSDK),) IOSSDK := $(shell xcodebuild -version -sdk iphoneos Path) endif TARGET := $(TARGET_NAME)_libretro_ios.dylib DEFINES += -DIOS GLES = 1 WITH_DYNAREC=arm PLATFORM_EXT := unix PLATCFLAGS += -DHAVE_POSIX_MEMALIGN -DNO_ASM PLATCFLAGS += -DIOS -marm CPUFLAGS += -DNO_ASM -DARM -D__arm__ -DARM_ASM -D__NEON_OPT CPUFLAGS += -marm -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp LDFLAGS += -dynamiclib GLIDE2GL=1 GLIDE64MK2=0 HAVE_NEON=1 fpic = -fPIC GL_LIB := -framework OpenGLES CC = clang -arch armv7 -isysroot $(IOSSDK) CC_AS = perl ./tools/gas-preprocessor.pl $(CC) CXX = clang++ -arch armv7 -isysroot $(IOSSDK) ifeq ($(platform),ios9) CC += -miphoneos-version-min=8.0 CC_AS += -miphoneos-version-min=8.0 CXX += -miphoneos-version-min=8.0 PLATCFLAGS += -miphoneos-version-min=8.0 else CC += -miphoneos-version-min=5.0 CC_AS += -miphoneos-version-min=5.0 CXX += -miphoneos-version-min=5.0 PLATCFLAGS += -miphoneos-version-min=5.0 endif # Theos iOS else ifneq (,$(findstring theos_ios,$(platform))) DEPLOYMENT_IOSVERSION = 5.0 TARGET = iphone:latest:$(DEPLOYMENT_IOSVERSION) ARCHS = armv7 TARGET_IPHONEOS_DEPLOYMENT_VERSION=$(DEPLOYMENT_IOSVERSION) THEOS_BUILD_DIR := objs include $(THEOS)/makefiles/common.mk LIBRARY_NAME = $(TARGET_NAME)_libretro_ios DEFINES += -DIOS GLES = 1 WITH_DYNAREC=arm PLATCFLAGS += -DHAVE_POSIX_MEMALIGN -DNO_ASM PLATCFLAGS += -DIOS -marm CPUFLAGS += -DNO_ASM -DARM -D__arm__ -DARM_ASM -D__NEON_OPT -DNOSSE GLIDE2GL=1 GLIDE64MK2=0 HAVE_NEON=1 # Android else ifneq (,$(findstring android,$(platform))) fpic = -fPIC TARGET := $(TARGET_NAME)_libretro_android.so LDFLAGS += -shared -Wl,--version-script=$(LIBRETRO_DIR)/link.T -Wl,--no-undefined -Wl,--warn-common GL_LIB := -lGLESv2 CC = arm-linux-androideabi-gcc CXX = arm-linux-androideabi-g++ WITH_DYNAREC=arm GLES = 1 PLATCFLAGS += -DANDROID CPUCFLAGS += -DNO_ASM HAVE_NEON = 1 CPUFLAGS += -marm -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -D__arm__ -DARM_ASM -D__NEON_OPT CFLAGS += -DANDROID PLATFORM_EXT := unix # QNX else ifeq ($(platform), qnx) fpic = -fPIC TARGET := $(TARGET_NAME)_libretro_qnx.so LDFLAGS += -shared -Wl,--version-script=$(LIBRETRO_DIR)/link.T -Wl,--no-undefined -Wl,--warn-common GL_LIB := -lGLESv2 CC = qcc -Vgcc_ntoarmv7le CC_AS = qcc -Vgcc_ntoarmv7le CXX = QCC -Vgcc_ntoarmv7le AR = QCC -Vgcc_ntoarmv7le WITH_DYNAREC=arm GLES = 1 PLATCFLAGS += -DNO_ASM -D__BLACKBERRY_QNX__ HAVE_NEON = 1 CPUFLAGS += -marm -mcpu=cortex-a9 -mfpu=neon -mfloat-abi=softfp -D__arm__ -DARM_ASM -D__NEON_OPT CFLAGS += -D__QNX__ PLATFORM_EXT := unix # ARM else ifneq (,$(findstring armv,$(platform))) TARGET := $(TARGET_NAME)_libretro.so LDFLAGS += -shared -Wl,--version-script=$(LIBRETRO_DIR)/link.T -Wl,--no-undefined fpic := -fPIC CPUFLAGS += -DNO_ASM -DARM -D__arm__ -DARM_ASM -DNOSSE WITH_DYNAREC=arm PLATCFLAGS += -DARM ifneq (,$(findstring gles,$(platform))) GLES = 1 GL_LIB := -lGLESv2 else GL_LIB := -lGL endif ifneq (,$(findstring cortexa5,$(platform))) CPUFLAGS += -marm -mcpu=cortex-a5 else ifneq (,$(findstring cortexa8,$(platform))) CPUFLAGS += -marm -mcpu=cortex-a8 else ifneq (,$(findstring cortexa9,$(platform))) CPUFLAGS += -marm -mcpu=cortex-a9 else ifneq (,$(findstring cortexa15a7,$(platform))) CPUFLAGS += -marm -mcpu=cortex-a15.cortex-a7 else CPUFLAGS += -marm endif ifneq (,$(findstring neon,$(platform))) CPUFLAGS += -D__NEON_OPT -mfpu=neon HAVE_NEON = 1 endif ifneq (,$(findstring softfloat,$(platform))) CPUFLAGS += -mfloat-abi=softfp else ifneq (,$(findstring hardfloat,$(platform))) CPUFLAGS += -mfloat-abi=hard endif # emscripten else ifeq ($(platform), emscripten) TARGET := $(TARGET_NAME)_libretro_emscripten.bc GLES := 1 GLIDE2GL=1 WITH_DYNAREC := CPUFLAGS += -Dasm=asmerror -D__asm__=asmerror -DNO_ASM -DNOSSE SINGLE_THREAD := 1 PLATCFLAGS += -Drglgen_symbol_map=mupen_rglgen_symbol_map \ -Dmain_exit=mupen_main_exit \ -Dadler32=mupen_adler32 \ -Drglgen_resolve_symbols_custom=mupen_rglgen_resolve_symbols_custom \ -Drglgen_resolve_symbols=mupen_rglgen_resolve_symbols \ -Dsinc_resampler=mupen_sinc_resampler \ -Dnearest_resampler=mupen_nearest_resampler \ -DCC_resampler=mupen_CC_resampler \ -Daudio_resampler_driver_find_handle=mupen_audio_resampler_driver_find_handle \ -Daudio_resampler_driver_find_ident=mupen_audio_resampler_driver_find_ident \ -Drarch_resampler_realloc=mupen_rarch_resampler_realloc \ -Daudio_convert_s16_to_float_C=mupen_audio_convert_s16_to_float_C \ -Daudio_convert_float_to_s16_C=mupen_audio_convert_float_to_s16_C \ -Daudio_convert_init_simd=mupen_audio_convert_init_simd HAVE_NEON = 0 PLATFORM_EXT := unix #HAVE_SHARED_CONTEXT := 1 # Windows else ifneq (,$(findstring win,$(platform))) TARGET := $(TARGET_NAME)_libretro.dll LDFLAGS += -shared -static-libgcc -static-libstdc++ -Wl,--version-script=$(LIBRETRO_DIR)/link.T -lwinmm -lgdi32 GL_LIB := -lopengl32 PLATFORM_EXT := win32 CC = gcc CXX = g++ endif include Makefile.common ifeq ($(HAVE_NEON), 1) COREFLAGS += -DHAVE_NEON endif ifeq ($(PERF_TEST), 1) COREFLAGS += -DPERF_TEST endif ifeq ($(HAVE_SHARED_CONTEXT), 1) COREFLAGS += -DHAVE_SHARED_CONTEXT endif ifeq ($(SINGLE_THREAD), 1) COREFLAGS += -DSINGLE_THREAD endif COREFLAGS += -D__LIBRETRO__ -DINLINE="inline" -DM64P_PLUGIN_API -DM64P_CORE_PROTOTYPES \ -D_ENDUSER_RELEASE -DSDL_VIDEO_OPENGL_ES2=1 -DSINC_LOWER_QUALITY -DHAVE_COMBINE_EXT ifeq ($(DEBUG), 1) CPUOPTS += -O0 -g CPUOPTS += -DOPENGL_DEBUG else CPUOPTS += -O2 -DNDEBUG endif ifeq ($(GLIDEN64), 1) COREFLAGS += -std=c++0x endif ifeq ($(platform), qnx) CFLAGS += -Wp,-MMD CXXFLAGS += -Wp,-MMD else CFLAGS += -std=gnu89 -MMD CXXFLAGS += -std=gnu++98 -MMD endif ### Finalize ### OBJECTS += $(SOURCES_CXX:.cpp=.o) $(SOURCES_C:.c=.o) $(SOURCES_ASM:.S=.o) CXXFLAGS += $(CPUOPTS) $(COREFLAGS) $(INCFLAGS) $(PLATCFLAGS) $(fpic) $(PLATCFLAGS) $(CPUFLAGS) $(GLFLAGS) $(DYNAFLAGS) CFLAGS += $(CPUOPTS) $(COREFLAGS) $(INCFLAGS) $(PLATCFLAGS) $(fpic) $(PLATCFLAGS) $(CPUFLAGS) $(GLFLAGS) $(DYNAFLAGS) ifeq ($(findstring Haiku,$(UNAME)),) LDFLAGS += -lm endif LDFLAGS += $(fpic) ifeq ($(platform), theos_ios) COMMON_FLAGS := -DIOS $(COMMON_DEFINES) $(INCFLAGS) -I$(THEOS_INCLUDE_PATH) -Wno-error $(LIBRARY_NAME)_ASFLAGS += $(CFLAGS) $(COMMON_FLAGS) $(LIBRARY_NAME)_CFLAGS += $(CFLAGS) $(COMMON_FLAGS) $(LIBRARY_NAME)_CXXFLAGS += $(CXXFLAGS) $(COMMON_FLAGS) ${LIBRARY_NAME}_FILES = $(SOURCES_CXX) $(SOURCES_C) $(SOURCES_ASM) ${LIBRARY_NAME}_FRAMEWORKS = OpenGLES ${LIBRARY_NAME}_LIBRARIES = z include $(THEOS_MAKE_PATH)/library.mk else all: $(TARGET) $(TARGET): $(OBJECTS) $(CXX) -o $@ $(OBJECTS) $(LDFLAGS) $(GL_LIB) %.o: %.S $(CC_AS) $(CFLAGS) -c $< -o $@ %.o: %.c $(CC) $(CFLAGS) -c $< -o $@ %.o: %.cpp $(CXX) $(CXXFLAGS) -c $< -o $@ clean: rm -f $(OBJECTS) $(TARGET) $(OBJECTS:.o=.d) .PHONY: clean -include $(OBJECTS:.o=.d) endif mupen64plus-video-gliden64/src/Textures.h000664 001750 001750 00000005654 12655644434 021434 0ustar00sergiosergio000000 000000 #ifndef TEXTURES_H #define TEXTURES_H #include #include "CRC.h" #include "convert.h" extern const GLuint g_noiseTexIndex; extern const GLuint g_MSTex0Index; typedef u32 (*GetTexelFunc)( u64 *src, u16 x, u16 i, u8 palette ); struct CachedTexture { CachedTexture(GLuint _glName) : glName(_glName), max_level(0), frameBufferTexture(fbNone) {} GLuint glName; u32 crc; // float fulS, fulT; // WORD ulS, ulT, lrS, lrT; float offsetS, offsetT; u8 maskS, maskT; u8 clampS, clampT; u8 mirrorS, mirrorT; u16 line; u16 size; u16 format; u32 tMem; u32 palette; u16 width, height; // N64 width and height u16 clampWidth, clampHeight; // Size to clamp to u16 realWidth, realHeight; // Actual texture size f32 scaleS, scaleT; // Scale to map to 0.0-1.0 f32 shiftScaleS, shiftScaleT; // Scale to shift u32 textureBytes; u32 lastDList; u32 address; u8 max_level; enum { fbNone = 0, fbOneSample = 1, fbMultiSample = 2 } frameBufferTexture; }; struct TextureCache { CachedTexture * current[2]; void init(); void destroy(); CachedTexture * addFrameBufferTexture(); void addFrameBufferTextureSize(u32 _size) {m_cachedBytes += _size;} void removeFrameBufferTexture(CachedTexture * _pTexture); void activateTexture(u32 _t, CachedTexture *_pTexture); void activateDummy(u32 _t); void activateMSDummy(u32 _t); void update(u32 _t); static TextureCache & get(); private: TextureCache() : m_pDummy(NULL), m_hits(0), m_misses(0), m_maxBytes(0), m_cachedBytes(0), m_curUnpackAlignment(4), m_toggleDumpTex(false) { current[0] = NULL; current[1] = NULL; CRC_BuildTable(); } TextureCache(const TextureCache &); void _checkCacheSize(); CachedTexture * _addTexture(u32 _crc32); void _load(u32 _tile, CachedTexture *_pTexture); bool _loadHiresTexture(u32 _tile, CachedTexture *_pTexture, u64 & _ricecrc); void _loadBackground(CachedTexture *pTexture); bool _loadHiresBackground(CachedTexture *_pTexture); void _updateBackground(); void _clear(); void _initDummyTexture(CachedTexture * _pDummy); void _getTextureDestData(CachedTexture& tmptex, u32* pDest, GLuint glInternalFormat, GetTexelFunc GetTexel, u16* pLine); typedef std::list Textures; typedef std::map Texture_Locations; typedef std::map FBTextures; Textures m_textures; Texture_Locations m_lruTextureLocations; FBTextures m_fbTextures; CachedTexture * m_pDummy; CachedTexture * m_pMSDummy; u32 m_hits, m_misses; u32 m_maxBytes; u32 m_cachedBytes; GLint m_curUnpackAlignment; bool m_toggleDumpTex; }; void getTextureShiftScale(u32 tile, const TextureCache & cache, f32 & shiftScaleS, f32 & shiftScaleT); inline TextureCache & textureCache() { return TextureCache::get(); } inline u32 pow2( u32 dim ) { u32 i = 1; while (i < dim) i <<= 1; return i; } inline u32 powof( u32 dim ) { u32 num = 1; u32 i = 0; while (num < dim) { num <<= 1; i++; } return i; } #endif mupen64plus-video-gliden64/licenses/000700 001750 001750 00000000000 12656647145 020433 5ustar00sergiosergio000000 000000 mupen64plus-core/src/si/af_rtc.c000664 001750 001750 00000004705 12655644434 017661 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - af_rtc.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "af_rtc.h" #include "api/m64p_types.h" #include "api/callbacks.h" #include static uint8_t byte2bcd(int n) { n %= 100; return ((n / 10) << 4) | (n % 10); } const struct tm* af_rtc_get_time(struct af_rtc* rtc) { return rtc->get_time(rtc->user_data); } void af_rtc_status_command(struct af_rtc *rtc, uint8_t *cmd) { /* AF-RTC status query */ cmd[3] = 0x00; cmd[4] = 0x10; cmd[5] = 0x00; } void af_rtc_read_command(struct af_rtc *rtc, uint8_t *cmd) { const struct tm *rtc_time; /* read RTC block (cmd[3]: block number) */ switch (cmd[3]) { case 0: cmd[4] = 0x00; cmd[5] = 0x02; cmd[12] = 0x00; break; case 1: DebugMessage(M64MSG_ERROR, "AF-RTC read command: cannot read block 1"); break; case 2: rtc_time = af_rtc_get_time(rtc); cmd[4] = byte2bcd(rtc_time->tm_sec); cmd[5] = byte2bcd(rtc_time->tm_min); cmd[6] = 0x80 + byte2bcd(rtc_time->tm_hour); cmd[7] = byte2bcd(rtc_time->tm_mday); cmd[8] = byte2bcd(rtc_time->tm_wday); cmd[9] = byte2bcd(rtc_time->tm_mon + 1); cmd[10] = byte2bcd(rtc_time->tm_year); cmd[11] = byte2bcd(rtc_time->tm_year / 100); cmd[12] = 0x00; /* status */ break; } } void af_rtc_write_command(struct af_rtc *rtc, uint8_t* cmd) { /* write RTC block */ DebugMessage(M64MSG_ERROR, "AF-RTC write command: not yet implemented"); } mupen64plus-core/src/r4300/hacktarux_dynarec/gcop1_d.c000664 001750 001750 00000073262 12655644434 023577 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - gcop1_d.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2007 Richard Goedeken (Richard42) * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include "assemble.h" #include "interpret.h" #include "r4300/recomph.h" #include "r4300/r4300.h" #include "r4300/ops.h" #include "r4300/cp1_private.h" void genadd_d(void) { #ifdef INTERPRET_ADD_D gencallinterp((native_type)cached_interpreter_table.ADD_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.ft])); fadd_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fd])); fstp_preg64_qword(RAX); #else mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.ft])); fadd_preg32_qword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd])); fstp_preg32_qword(EAX); #endif #endif } void gensub_d(void) { #ifdef INTERPRET_SUB_D gencallinterp((native_type)cached_interpreter_table.SUB_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.ft])); fsub_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fd])); fstp_preg64_qword(RAX); #else mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.ft])); fsub_preg32_qword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd])); fstp_preg32_qword(EAX); #endif #endif } void genmul_d(void) { #ifdef INTERPRET_MUL_D gencallinterp((native_type)cached_interpreter_table.MUL_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.ft])); fmul_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fd])); fstp_preg64_qword(RAX); #else mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.ft])); fmul_preg32_qword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd])); fstp_preg32_qword(EAX); #endif #endif } void gendiv_d(void) { #ifdef INTERPRET_DIV_D gencallinterp((native_type)cached_interpreter_table.DIV_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.ft])); fdiv_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fd])); fstp_preg64_qword(RAX); #else mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.ft])); fdiv_preg32_qword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd])); fstp_preg32_qword(EAX); #endif #endif } void gensqrt_d(void) { #ifdef INTERPRET_SQRT_D gencallinterp((native_type)cached_interpreter_table.SQRT_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); fsqrt(); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fd])); fstp_preg64_qword(RAX); #else mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); fsqrt(); mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd])); fstp_preg32_qword(EAX); #endif #endif } void genabs_d(void) { #ifdef INTERPRET_ABS_D gencallinterp((native_type)cached_interpreter_table.ABS_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); fabs_(); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fd])); fstp_preg64_qword(RAX); #else mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); fabs_(); mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd])); fstp_preg32_qword(EAX); #endif #endif } void genmov_d(void) { #ifdef INTERPRET_MOV_D gencallinterp((native_type)cached_interpreter_table.MOV_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); mov_reg32_preg64(EBX, RAX); mov_reg32_preg64pimm32(ECX, RAX, 4); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fd])); mov_preg64_reg32(RAX, EBX); mov_preg64pimm32_reg32(RAX, 4, ECX); #else mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fs])); mov_reg32_preg32(EBX, EAX); mov_reg32_preg32pimm32(ECX, EAX, 4); mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd])); mov_preg32_reg32(EAX, EBX); mov_preg32pimm32_reg32(EAX, 4, ECX); #endif #endif } void genneg_d(void) { #ifdef INTERPRET_NEG_D gencallinterp((native_type)cached_interpreter_table.NEG_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); fchs(); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fd])); fstp_preg64_qword(RAX); #else mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); fchs(); mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd])); fstp_preg32_qword(EAX); #endif #endif } void genround_l_d(void) { #ifdef INTERPRET_ROUND_L_D gencallinterp((native_type)cached_interpreter_table.ROUND_L_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ fldcw_m16rel((uint16_t*)&round_mode); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fd])); fistp_preg64_qword(RAX); fldcw_m16rel((uint16_t*)&rounding_mode); #else fldcw_m16((uint16_t*)&round_mode); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fd])); fistp_preg32_qword(EAX); fldcw_m16((uint16_t*)&rounding_mode); #endif #endif } void gentrunc_l_d(void) { #ifdef INTERPRET_TRUNC_L_D gencallinterp((native_type)cached_interpreter_table.TRUNC_L_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ fldcw_m16rel((uint16_t*)&trunc_mode); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fd])); fistp_preg64_qword(RAX); fldcw_m16rel((uint16_t*)&rounding_mode); #else fldcw_m16((uint16_t*)&trunc_mode); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fd])); fistp_preg32_qword(EAX); fldcw_m16((uint16_t*)&rounding_mode); #endif #endif } void genceil_l_d(void) { #ifdef INTERPRET_CEIL_L_D gencallinterp((native_type)cached_interpreter_table.CEIL_L_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ fldcw_m16rel((uint16_t*)&ceil_mode); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fd])); fistp_preg64_qword(RAX); fldcw_m16rel((uint16_t*)&rounding_mode); #else fldcw_m16((uint16_t*)&ceil_mode); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fd])); fistp_preg32_qword(EAX); fldcw_m16((uint16_t*)&rounding_mode); #endif #endif } void genfloor_l_d(void) { #ifdef INTERPRET_FLOOR_L_D gencallinterp((native_type)cached_interpreter_table.FLOOR_L_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ fldcw_m16rel((uint16_t*)&floor_mode); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fd])); fistp_preg64_qword(RAX); fldcw_m16rel((uint16_t*)&rounding_mode); #else fldcw_m16((uint16_t*)&floor_mode); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fd])); fistp_preg32_qword(EAX); fldcw_m16((uint16_t*)&rounding_mode); #endif #endif } void genround_w_d(void) { #ifdef INTERPRET_ROUND_W_D gencallinterp((native_type)cached_interpreter_table.ROUND_W_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ fldcw_m16rel((uint16_t*)&round_mode); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fd])); fistp_preg64_dword(RAX); fldcw_m16rel((uint16_t*)&rounding_mode); #else fldcw_m16((uint16_t*)&round_mode); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_simple[dst->f.cf.fd])); fistp_preg32_dword(EAX); fldcw_m16((uint16_t*)&rounding_mode); #endif #endif } void gentrunc_w_d(void) { #ifdef INTERPRET_TRUNC_W_D gencallinterp((native_type)cached_interpreter_table.TRUNC_W_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ fldcw_m16rel((uint16_t*)&trunc_mode); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fd])); fistp_preg64_dword(RAX); fldcw_m16rel((uint16_t*)&rounding_mode); #else fldcw_m16((uint16_t*)&trunc_mode); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_simple[dst->f.cf.fd])); fistp_preg32_dword(EAX); fldcw_m16((uint16_t*)&rounding_mode); #endif #endif } void genceil_w_d(void) { #ifdef INTERPRET_CEIL_W_D gencallinterp((native_type)cached_interpreter_table.CEIL_W_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ fldcw_m16rel((uint16_t*)&ceil_mode); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fd])); fistp_preg64_dword(RAX); fldcw_m16rel((uint16_t*)&rounding_mode); #else fldcw_m16((uint16_t*)&ceil_mode); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_simple[dst->f.cf.fd])); fistp_preg32_dword(EAX); fldcw_m16((uint16_t*)&rounding_mode); #endif #endif } void genfloor_w_d(void) { #ifdef INTERPRET_FLOOR_W_D gencallinterp((native_type)cached_interpreter_table.FLOOR_W_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ fldcw_m16rel((uint16_t*)&floor_mode); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fd])); fistp_preg64_dword(RAX); fldcw_m16rel((uint16_t*)&rounding_mode); #else fldcw_m16((uint16_t*)&floor_mode); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_simple[dst->f.cf.fd])); fistp_preg32_dword(EAX); fldcw_m16((uint16_t*)&rounding_mode); #endif #endif } void gencvt_s_d(void) { #ifdef INTERPRET_CVT_S_D gencallinterp((native_type)cached_interpreter_table.CVT_S_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fd])); fstp_preg64_dword(RAX); #else mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_simple[dst->f.cf.fd])); fstp_preg32_dword(EAX); #endif #endif } void gencvt_w_d(void) { #ifdef INTERPRET_CVT_W_D gencallinterp((native_type)cached_interpreter_table.CVT_W_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fd])); fistp_preg64_dword(RAX); #else mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_simple[dst->f.cf.fd])); fistp_preg32_dword(EAX); #endif #endif } void gencvt_l_d(void) { #ifdef INTERPRET_CVT_L_D gencallinterp((native_type)cached_interpreter_table.CVT_L_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fd])); fistp_preg64_qword(RAX); #else mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fd])); fistp_preg32_qword(EAX); #endif #endif } void genc_f_d(void) { #ifdef INTERPRET_C_F_D gencallinterp((native_type)cached_interpreter_table.C_F_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); #else and_m32_imm32((unsigned int*)&FCR31, ~0x800000); #endif #endif } void genc_un_d(void) { #ifdef INTERPRET_C_UN_D gencallinterp((native_type)cached_interpreter_table.C_UN_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.ft])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); fucomip_fpreg(1); ffree_fpreg(0); jp_rj(13); and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 jmp_imm_short(11); // 2 or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 #else mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); fucomip_fpreg(1); ffree_fpreg(0); jp_rj(12); and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 jmp_imm_short(10); // 2 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 #endif #endif } void genc_eq_d(void) { #ifdef INTERPRET_C_EQ_D gencallinterp((native_type)cached_interpreter_table.C_EQ_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.ft])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); fucomip_fpreg(1); ffree_fpreg(0); jne_rj(13); // 2 or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 jmp_imm_short(11); // 2 and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 #else mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); fucomip_fpreg(1); ffree_fpreg(0); jne_rj(12); // 2 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif #endif } void genc_ueq_d(void) { #ifdef INTERPRET_C_UEQ_D gencallinterp((native_type)cached_interpreter_table.C_UEQ_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.ft])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); fucomip_fpreg(1); ffree_fpreg(0); jp_rj(15); jne_rj(13); or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 jmp_imm_short(11); // 2 and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 #else mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); fucomip_fpreg(1); ffree_fpreg(0); jp_rj(14); jne_rj(12); or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif #endif } void genc_olt_d(void) { #ifdef INTERPRET_C_OLT_D gencallinterp((native_type)cached_interpreter_table.C_OLT_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.ft])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); fucomip_fpreg(1); ffree_fpreg(0); jae_rj(13); // 2 or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 jmp_imm_short(11); // 2 and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 #else mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); fucomip_fpreg(1); ffree_fpreg(0); jae_rj(12); // 2 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif #endif } void genc_ult_d(void) { #ifdef INTERPRET_C_ULT_D gencallinterp((native_type)cached_interpreter_table.C_ULT_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.ft])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); fucomip_fpreg(1); ffree_fpreg(0); jp_rj(15); jae_rj(13); // 2 or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 jmp_imm_short(11); // 2 and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 #else mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); fucomip_fpreg(1); ffree_fpreg(0); jp_rj(14); jae_rj(12); // 2 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif #endif } void genc_ole_d(void) { #ifdef INTERPRET_C_OLE_D gencallinterp((native_type)cached_interpreter_table.C_OLE_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.ft])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); fucomip_fpreg(1); ffree_fpreg(0); ja_rj(13); // 2 or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 jmp_imm_short(11); // 2 and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 #else mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); fucomip_fpreg(1); ffree_fpreg(0); ja_rj(12); // 2 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif #endif } void genc_ule_d(void) { #ifdef INTERPRET_C_ULE_D gencallinterp((native_type)cached_interpreter_table.C_ULE_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.ft])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); fucomip_fpreg(1); ffree_fpreg(0); jp_rj(15); ja_rj(13); // 2 or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 jmp_imm_short(11); // 2 and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 #else mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); fucomip_fpreg(1); ffree_fpreg(0); jp_rj(14); ja_rj(12); // 2 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif #endif } void genc_sf_d(void) { #ifdef INTERPRET_C_SF_D gencallinterp((native_type)cached_interpreter_table.C_SF_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.ft])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); fcomip_fpreg(1); ffree_fpreg(0); and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); #else mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); fcomip_fpreg(1); ffree_fpreg(0); and_m32_imm32((unsigned int*)&FCR31, ~0x800000); #endif #endif } void genc_ngle_d(void) { #ifdef INTERPRET_C_NGLE_D gencallinterp((native_type)cached_interpreter_table.C_NGLE_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.ft])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); fcomip_fpreg(1); ffree_fpreg(0); jp_rj(13); and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 jmp_imm_short(11); // 2 or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 #else mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); fcomip_fpreg(1); ffree_fpreg(0); jp_rj(12); and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 jmp_imm_short(10); // 2 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 #endif #endif } void genc_seq_d(void) { #ifdef INTERPRET_C_SEQ_D gencallinterp((native_type)cached_interpreter_table.C_SEQ_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.ft])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); fcomip_fpreg(1); ffree_fpreg(0); jne_rj(13); // 2 or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 jmp_imm_short(11); // 2 and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 #else mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); fcomip_fpreg(1); ffree_fpreg(0); jne_rj(12); // 2 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif #endif } void genc_ngl_d(void) { #ifdef INTERPRET_C_NGL_D gencallinterp((native_type)cached_interpreter_table.C_NGL_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.ft])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); fcomip_fpreg(1); ffree_fpreg(0); jp_rj(15); jne_rj(13); or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 jmp_imm_short(11); // 2 and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 #else mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); fcomip_fpreg(1); ffree_fpreg(0); jp_rj(14); jne_rj(12); or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif #endif } void genc_lt_d(void) { #ifdef INTERPRET_C_LT_D gencallinterp((native_type)cached_interpreter_table.C_LT_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.ft])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); fcomip_fpreg(1); ffree_fpreg(0); jae_rj(13); // 2 or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 jmp_imm_short(11); // 2 and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 #else mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); fcomip_fpreg(1); ffree_fpreg(0); jae_rj(12); // 2 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif #endif } void genc_nge_d(void) { #ifdef INTERPRET_C_NGE_D gencallinterp((native_type)cached_interpreter_table.C_NGE_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.ft])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); fcomip_fpreg(1); ffree_fpreg(0); jp_rj(15); jae_rj(13); // 2 or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 jmp_imm_short(11); // 2 and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 #else mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); fcomip_fpreg(1); ffree_fpreg(0); jp_rj(14); jae_rj(12); // 2 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif #endif } void genc_le_d(void) { #ifdef INTERPRET_C_LE_D gencallinterp((native_type)cached_interpreter_table.C_LE_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.ft])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); fcomip_fpreg(1); ffree_fpreg(0); ja_rj(13); // 2 or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 jmp_imm_short(11); // 2 and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 #else mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); fcomip_fpreg(1); ffree_fpreg(0); ja_rj(12); // 2 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif #endif } void genc_ngt_d(void) { #ifdef INTERPRET_C_NGT_D gencallinterp((native_type)cached_interpreter_table.C_NGT_D, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.ft])); fld_preg64_qword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fs])); fld_preg64_qword(RAX); fcomip_fpreg(1); ffree_fpreg(0); jp_rj(15); ja_rj(13); // 2 or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 jmp_imm_short(11); // 2 and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 #else mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); fcomip_fpreg(1); ffree_fpreg(0); jp_rj(14); ja_rj(12); // 2 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif #endif } mupen64plus-core/src/r4300/hacktarux_dynarec/gcop1_s.c000664 001750 001750 00000073022 12655644434 023610 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - gcop1_s.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2007 Richard Goedeken (Richard42) * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include "assemble.h" #include "interpret.h" #include "r4300/recomph.h" #include "r4300/r4300.h" #include "r4300/ops.h" #include "r4300/macros.h" #include "r4300/cp1_private.h" void genadd_s(void) { #ifdef INTERPRET_ADD_S gencallinterp((native_type)cached_interpreter_table.ADD_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.ft])); fadd_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fd])); fstp_preg64_dword(RAX); #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.ft])); fadd_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fd])); fstp_preg32_dword(EAX); #endif #endif } void gensub_s(void) { #ifdef INTERPRET_SUB_S gencallinterp((native_type)cached_interpreter_table.SUB_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.ft])); fsub_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fd])); fstp_preg64_dword(RAX); #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.ft])); fsub_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fd])); fstp_preg32_dword(EAX); #endif #endif } void genmul_s(void) { #ifdef INTERPRET_MUL_S gencallinterp((native_type)cached_interpreter_table.MUL_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.ft])); fmul_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fd])); fstp_preg64_dword(RAX); #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.ft])); fmul_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fd])); fstp_preg32_dword(EAX); #endif #endif } void gendiv_s(void) { #ifdef INTERPRET_DIV_S gencallinterp((native_type)cached_interpreter_table.DIV_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.ft])); fdiv_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fd])); fstp_preg64_dword(RAX); #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.ft])); fdiv_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fd])); fstp_preg32_dword(EAX); #endif #endif } void gensqrt_s(void) { #ifdef INTERPRET_SQRT_S gencallinterp((native_type)cached_interpreter_table.SQRT_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); fsqrt(); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fd])); fstp_preg64_dword(RAX); #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); fsqrt(); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fd])); fstp_preg32_dword(EAX); #endif #endif } void genabs_s(void) { #ifdef INTERPRET_ABS_S gencallinterp((native_type)cached_interpreter_table.ABS_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); fabs_(); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fd])); fstp_preg64_dword(RAX); #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); fabs_(); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fd])); fstp_preg32_dword(EAX); #endif #endif } void genmov_s(void) { #ifdef INTERPRET_MOV_S gencallinterp((native_type)cached_interpreter_table.MOV_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); mov_reg32_preg64(EBX, RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fd])); mov_preg64_reg32(RAX, EBX); #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); mov_reg32_preg32(EBX, EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fd])); mov_preg32_reg32(EAX, EBX); #endif #endif } void genneg_s(void) { #ifdef INTERPRET_NEG_S gencallinterp((native_type)cached_interpreter_table.NEG_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); fchs(); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fd])); fstp_preg64_dword(RAX); #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); fchs(); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fd])); fstp_preg32_dword(EAX); #endif #endif } void genround_l_s(void) { #ifdef INTERPRET_ROUND_L_S gencallinterp((native_type)cached_interpreter_table.ROUND_L_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ fldcw_m16rel((uint16_t*)&round_mode); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fd])); fistp_preg64_qword(RAX); fldcw_m16rel((uint16_t*)&rounding_mode); #else fldcw_m16((uint16_t*)&round_mode); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd])); fistp_preg32_qword(EAX); fldcw_m16((uint16_t*)&rounding_mode); #endif #endif } void gentrunc_l_s(void) { #ifdef INTERPRET_TRUNC_L_S gencallinterp((native_type)cached_interpreter_table.TRUNC_L_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ fldcw_m16rel((uint16_t*)&trunc_mode); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fd])); fistp_preg64_qword(RAX); fldcw_m16rel((uint16_t*)&rounding_mode); #else fldcw_m16((uint16_t*)&trunc_mode); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd])); fistp_preg32_qword(EAX); fldcw_m16((uint16_t*)&rounding_mode); #endif #endif } void genceil_l_s(void) { #ifdef INTERPRET_CEIL_L_S gencallinterp((native_type)cached_interpreter_table.CEIL_L_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ fldcw_m16rel((uint16_t*)&ceil_mode); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fd])); fistp_preg64_qword(RAX); fldcw_m16rel((uint16_t*)&rounding_mode); #else fldcw_m16((uint16_t*)&ceil_mode); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd])); fistp_preg32_qword(EAX); fldcw_m16((uint16_t*)&rounding_mode); #endif #endif } void genfloor_l_s(void) { #ifdef INTERPRET_FLOOR_L_S gencallinterp((native_type)cached_interpreter_table.FLOOR_L_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ fldcw_m16rel((uint16_t*)&floor_mode); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fd])); fistp_preg64_qword(RAX); fldcw_m16rel((uint16_t*)&rounding_mode); #else fldcw_m16((uint16_t*)&floor_mode); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd])); fistp_preg32_qword(EAX); fldcw_m16((uint16_t*)&rounding_mode); #endif #endif } void genround_w_s(void) { #ifdef INTERPRET_ROUND_W_S gencallinterp((native_type)cached_interpreter_table.ROUND_W_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ fldcw_m16rel((uint16_t*)&round_mode); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fd])); fistp_preg64_dword(RAX); fldcw_m16rel((uint16_t*)&rounding_mode); #else fldcw_m16((uint16_t*)&round_mode); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fd])); fistp_preg32_dword(EAX); fldcw_m16((uint16_t*)&rounding_mode); #endif #endif } void gentrunc_w_s(void) { #ifdef INTERPRET_TRUNC_W_S gencallinterp((native_type)cached_interpreter_table.TRUNC_W_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ fldcw_m16rel((uint16_t*)&trunc_mode); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fd])); fistp_preg64_dword(RAX); fldcw_m16rel((uint16_t*)&rounding_mode); #else fldcw_m16((uint16_t*)&trunc_mode); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fd])); fistp_preg32_dword(EAX); fldcw_m16((uint16_t*)&rounding_mode); #endif #endif } void genceil_w_s(void) { #ifdef INTERPRET_CEIL_W_S gencallinterp((native_type)cached_interpreter_table.CEIL_W_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ fldcw_m16rel((uint16_t*)&ceil_mode); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fd])); fistp_preg64_dword(RAX); fldcw_m16rel((uint16_t*)&rounding_mode); #else fldcw_m16((uint16_t*)&ceil_mode); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fd])); fistp_preg32_dword(EAX); fldcw_m16((uint16_t*)&rounding_mode); #endif #endif } void genfloor_w_s(void) { #ifdef INTERPRET_FLOOR_W_S gencallinterp((native_type)cached_interpreter_table.FLOOR_W_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ fldcw_m16rel((uint16_t*)&floor_mode); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fd])); fistp_preg64_dword(RAX); fldcw_m16rel((uint16_t*)&rounding_mode); #else fldcw_m16((uint16_t*)&floor_mode); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fd])); fistp_preg32_dword(EAX); fldcw_m16((uint16_t*)&rounding_mode); #endif #endif } void gencvt_d_s(void) { #ifdef INTERPRET_CVT_D_S gencallinterp((native_type)cached_interpreter_table.CVT_D_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fd])); fstp_preg64_qword(RAX); #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd])); fstp_preg32_qword(EAX); #endif #endif } void gencvt_w_s(void) { #ifdef INTERPRET_CVT_W_S gencallinterp((native_type)cached_interpreter_table.CVT_W_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fd])); fistp_preg64_dword(RAX); #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fd])); fistp_preg32_dword(EAX); #endif #endif } void gencvt_l_s(void) { #ifdef INTERPRET_CVT_L_S gencallinterp((native_type)cached_interpreter_table.CVT_L_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_double[dst->f.cf.fd])); fistp_preg64_qword(RAX); #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd])); fistp_preg32_qword(EAX); #endif #endif } void genc_f_s(void) { #ifdef INTERPRET_C_F_S gencallinterp((native_type)cached_interpreter_table.C_F_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); #else and_m32_imm32((unsigned int*)&FCR31, ~0x800000); #endif #endif } void genc_un_s(void) { #ifdef INTERPRET_C_UN_S gencallinterp((native_type)cached_interpreter_table.C_UN_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.ft])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); fucomip_fpreg(1); ffree_fpreg(0); jp_rj(13); and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 jmp_imm_short(11); // 2 or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.ft])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); fucomip_fpreg(1); ffree_fpreg(0); jp_rj(12); and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 jmp_imm_short(10); // 2 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 #endif #endif } void genc_eq_s(void) { #ifdef INTERPRET_C_EQ_S gencallinterp((native_type)cached_interpreter_table.C_EQ_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.ft])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); fucomip_fpreg(1); ffree_fpreg(0); jne_rj(13); or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 jmp_imm_short(11); // 2 and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.ft])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); fucomip_fpreg(1); ffree_fpreg(0); jne_rj(12); or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif #endif } void genc_ueq_s(void) { #ifdef INTERPRET_C_UEQ_S gencallinterp((native_type)cached_interpreter_table.C_UEQ_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.ft])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); fucomip_fpreg(1); ffree_fpreg(0); jp_rj(15); jne_rj(13); or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 jmp_imm_short(11); // 2 and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.ft])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); fucomip_fpreg(1); ffree_fpreg(0); jp_rj(14); jne_rj(12); or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif #endif } void genc_olt_s(void) { #ifdef INTERPRET_C_OLT_S gencallinterp((native_type)cached_interpreter_table.C_OLT_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.ft])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); fucomip_fpreg(1); ffree_fpreg(0); jae_rj(13); or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 jmp_imm_short(11); // 2 and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.ft])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); fucomip_fpreg(1); ffree_fpreg(0); jae_rj(12); or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif #endif } void genc_ult_s(void) { #ifdef INTERPRET_C_ULT_S gencallinterp((native_type)cached_interpreter_table.C_ULT_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.ft])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); fucomip_fpreg(1); ffree_fpreg(0); jp_rj(15); jae_rj(13); or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 jmp_imm_short(11); // 2 and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.ft])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); fucomip_fpreg(1); ffree_fpreg(0); jp_rj(14); jae_rj(12); or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif #endif } void genc_ole_s(void) { #ifdef INTERPRET_C_OLE_S gencallinterp((native_type)cached_interpreter_table.C_OLE_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.ft])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); fucomip_fpreg(1); ffree_fpreg(0); ja_rj(13); or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 jmp_imm_short(11); // 2 and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.ft])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); fucomip_fpreg(1); ffree_fpreg(0); ja_rj(12); or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif #endif } void genc_ule_s(void) { #ifdef INTERPRET_C_ULE_S gencallinterp((native_type)cached_interpreter_table.C_ULE_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.ft])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); fucomip_fpreg(1); ffree_fpreg(0); jp_rj(15); ja_rj(13); or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 jmp_imm_short(11); // 2 and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.ft])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); fucomip_fpreg(1); ffree_fpreg(0); jp_rj(14); ja_rj(12); or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif #endif } void genc_sf_s(void) { #ifdef INTERPRET_C_SF_S gencallinterp((native_type)cached_interpreter_table.C_SF_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.ft])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); fcomip_fpreg(1); ffree_fpreg(0); and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.ft])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); fcomip_fpreg(1); ffree_fpreg(0); and_m32_imm32((unsigned int*)&FCR31, ~0x800000); #endif #endif } void genc_ngle_s(void) { #ifdef INTERPRET_C_NGLE_S gencallinterp((native_type)cached_interpreter_table.C_NGLE_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.ft])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); fcomip_fpreg(1); ffree_fpreg(0); jp_rj(13); and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 jmp_imm_short(11); // 2 or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.ft])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); fcomip_fpreg(1); ffree_fpreg(0); jp_rj(12); and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 jmp_imm_short(10); // 2 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 #endif #endif } void genc_seq_s(void) { #ifdef INTERPRET_C_SEQ_S gencallinterp((native_type)cached_interpreter_table.C_SEQ_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.ft])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); fcomip_fpreg(1); ffree_fpreg(0); jne_rj(13); or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 jmp_imm_short(11); // 2 and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.ft])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); fcomip_fpreg(1); ffree_fpreg(0); jne_rj(12); or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif #endif } void genc_ngl_s(void) { #ifdef INTERPRET_C_NGL_S gencallinterp((native_type)cached_interpreter_table.C_NGL_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.ft])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); fcomip_fpreg(1); ffree_fpreg(0); jp_rj(15); jne_rj(13); or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 jmp_imm_short(11); // 2 and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.ft])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); fcomip_fpreg(1); ffree_fpreg(0); jp_rj(14); jne_rj(12); or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif #endif } void genc_lt_s(void) { #ifdef INTERPRET_C_LT_S gencallinterp((native_type)cached_interpreter_table.C_LT_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.ft])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); fcomip_fpreg(1); ffree_fpreg(0); jae_rj(13); or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 jmp_imm_short(11); // 2 and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.ft])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); fcomip_fpreg(1); ffree_fpreg(0); jae_rj(12); or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif #endif } void genc_nge_s(void) { #ifdef INTERPRET_C_NGE_S gencallinterp((native_type)cached_interpreter_table.C_NGE_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.ft])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); fcomip_fpreg(1); ffree_fpreg(0); jp_rj(15); jae_rj(13); or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 jmp_imm_short(11); // 2 and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.ft])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); fcomip_fpreg(1); ffree_fpreg(0); jp_rj(14); jae_rj(12); or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif #endif } void genc_le_s(void) { #ifdef INTERPRET_C_LE_S gencallinterp((native_type)cached_interpreter_table.C_LE_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.ft])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); fcomip_fpreg(1); ffree_fpreg(0); ja_rj(13); or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 jmp_imm_short(11); // 2 and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.ft])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); fcomip_fpreg(1); ffree_fpreg(0); ja_rj(12); or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif #endif } void genc_ngt_s(void) { #ifdef INTERPRET_C_NGT_S gencallinterp((native_type)cached_interpreter_table.C_NGT_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.ft])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (uint64_t *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); fcomip_fpreg(1); ffree_fpreg(0); jp_rj(15); ja_rj(13); or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 jmp_imm_short(11); // 2 and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.ft])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); fcomip_fpreg(1); ffree_fpreg(0); jp_rj(14); ja_rj(12); or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif #endif } mupen64plus-core/src/api/common.c000664 001750 001750 00000011075 12655644434 020047 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-core - api/common.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2009 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file contains the Core common functions which will be exported * outside of the core library. */ #include #define M64P_CORE_PROTOTYPES 1 #include "m64p_types.h" #include "m64p_common.h" #include "../main/version.h" EXPORT m64p_error CALL PluginGetVersion(m64p_plugin_type *PluginType, int *PluginVersion, int *APIVersion, const char **PluginNamePtr, int *Capabilities) { /* set version info */ if (PluginType != NULL) *PluginType = M64PLUGIN_CORE; if (PluginVersion != NULL) *PluginVersion = MUPEN_CORE_VERSION; if (APIVersion != NULL) *APIVersion = FRONTEND_API_VERSION; if (PluginNamePtr != NULL) *PluginNamePtr = MUPEN_CORE_NAME; if (Capabilities != NULL) { *Capabilities = 0; #if defined(DBG) *Capabilities |= M64CAPS_DEBUGGER; #endif #if defined(DYNAREC) *Capabilities |= M64CAPS_DYNAREC; #endif #if defined(COMPARE_CORE) *Capabilities |= M64CAPS_CORE_COMPARE; #endif } return M64ERR_SUCCESS; } EXPORT m64p_error CALL CoreGetAPIVersions(int *ConfigVersion, int *DebugVersion, int *VidextVersion, int *ExtraVersion) { /* set version info */ if (ConfigVersion != NULL) *ConfigVersion = CONFIG_API_VERSION; if (DebugVersion != NULL) *DebugVersion = DEBUG_API_VERSION; if (VidextVersion != NULL) *VidextVersion = VIDEXT_API_VERSION; if (ExtraVersion != NULL) *ExtraVersion = 0; return M64ERR_SUCCESS; } static const char *ErrorMessages[] = { "SUCCESS: No error", "NOT_INIT: A function was called before it's associated module was initialized", "ALREADY_INIT: Initialization function called twice", "INCOMPATIBLE: API versions between components are incompatible", "INPUT_ASSERT: Invalid function parameters, such as a NULL pointer", "INPUT_INVALID: An input function parameter is logically invalid", "INPUT_NOT_FOUND: The input parameter(s) specified a particular item which was not found", "NO_MEMORY: Memory allocation failed", "FILES: Error opening, creating, reading, or writing to a file", "INTERNAL: logical inconsistency in program code. Probably a bug.", "INVALID_STATE: An operation was requested which is not allowed in the current state", "PLUGIN_FAIL: A plugin function returned a fatal error", "SYSTEM_FAIL: A system function call, such as an SDL or file operation, failed", "UNSUPPORTED: Function call is not supported (ie, core not built with debugger)", "WRONG_TYPE: A given input type parameter cannot be used for desired operation" }; EXPORT const char * CALL CoreErrorMessage(m64p_error ReturnCode) { int i = (int) ReturnCode; if (i < 0 || i > (sizeof(ErrorMessages) / sizeof(char *))) return "ERROR: Invalid m64p_error code given to CoreErrorMessage()"; return ErrorMessages[i]; } mupen64plus-video-gliden64/src/GLideNHQ/bldno.h000664 001750 001750 00000000075 12655644434 022232 0ustar00sergiosergio000000 000000 #define BUILD_NUMBER 13480 #define BUILD_NUMBER_STR "13480" mupen64plus-core/tools/uninstall_binary_bundle.sh000755 001750 001750 00000005377 12655644434 023466 0ustar00sergiosergio000000 000000 #!/bin/sh # # mupen64plus binary bundle uninstall script # # Copyright 2007-2013 The Mupen64Plus Development Team # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # set -e export PATH=/bin:/usr/bin usage() { printf "usage: $(basename $0) [PREFIX] [SHAREDIR] [BINDIR] [LIBDIR] [PLUGINDIR] [MANDIR] \tPREFIX - installation directories prefix (default: /usr/local) \tSHAREDIR - path to Mupen64Plus shared data files (default: \$PREFIX/share/mupen64plus) \tBINDIR - path to Mupen64Plus binary program files (default: \$PREFIX/bin) \tLIBDIR - path to Mupen64Plus core library (default: \$PREFIX/lib) \tPLUGINDIR - path to Mupen64Plus plugin libraries (default: \$PREFIX/lib/mupen64plus) \tMANDIR - path to manual files (default: \$PREFIX/man) " } if [ $# -gt 6 ]; then usage exit 1 fi PREFIX="${1:-/usr/local}" SHAREDIR="${2:-${PREFIX}/share/mupen64plus}" BINDIR="${3:-${PREFIX}/bin}" LIBDIR="${4:-${PREFIX}/lib}" PLUGINDIR="${5:-${PREFIX}/lib/mupen64plus}" MANDIR="${6:-${PREFIX}/share/man}" printf "Uninstalling Mupen64Plus Binary Bundle from ${PREFIX}\n" # Mupen64Plus-Core rm -f "${LIBDIR}"/libmupen64plus.so* /sbin/ldconfig rm -f "${SHAREDIR}/font.ttf" rm -f "${SHAREDIR}/mupen64plus.cht" rm -f "${SHAREDIR}/mupen64plus.ini" rm -f "${SHAREDIR}"/doc/* # Mupen64Plus-ROM rm -f "${SHAREDIR}/m64p_test_rom.v64" # Mupen64Plus-UI-Console rm -f "${BINDIR}/mupen64plus" rm -f "${MANDIR}/man6/mupen64plus.6" # Plugins rm -f "${PLUGINDIR}/mupen64plus-audio-sdl.so" rm -f "${PLUGINDIR}/mupen64plus-input-sdl.so" rm -f "${PLUGINDIR}/mupen64plus-rsp-hle.so" rm -f "${PLUGINDIR}/mupen64plus-video-rice.so" rm -f "${PLUGINDIR}/mupen64plus-video-glide64mk2.so" rm -f "${SHAREDIR}/RiceVideoLinux.ini" rm -f "${SHAREDIR}/InputAutoCfg.ini" rm -f "${SHAREDIR}/Glide64mk2.ini" # get rid of the empty dirs rmdir --ignore-fail-on-non-empty "${SHAREDIR}/doc" rmdir --ignore-fail-on-non-empty "${SHAREDIR}" rmdir --ignore-fail-on-non-empty "${BINDIR}" rmdir --ignore-fail-on-non-empty "${LIBDIR}" rmdir --ignore-fail-on-non-empty "${PLUGINDIR}" rmdir --ignore-fail-on-non-empty "${MANDIR}/man6" rmdir --ignore-fail-on-non-empty "${MANDIR}" printf "Done.\n" gles2rice/src/OGLTexture.cpp000664 001750 001750 00000010472 12655644434 017077 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "Config.h" #include "Debugger.h" #include "OGLDebug.h" #include "OGLGraphicsContext.h" #include "OGLTexture.h" #include "TextureManager.h" COGLTexture::COGLTexture(uint32_t dwWidth, uint32_t dwHeight, TextureUsage usage) : CTexture(dwWidth,dwHeight,usage), m_glFmt(GL_RGBA) { // FIXME: If usage is AS_RENDER_TARGET, we need to create pbuffer instead of regular texture m_dwTextureFmt = TEXTURE_FMT_A8R8G8B8; // Always use 32bit to load texture glGenTextures( 1, &m_dwTextureName ); OPENGL_CHECK_ERRORS; // Make the width and height be the power of 2 uint32_t w; for (w = 1; w < dwWidth; w <<= 1); m_dwCreatedTextureWidth = w; for (w = 1; w < dwHeight; w <<= 1); m_dwCreatedTextureHeight = w; if (dwWidth*dwHeight > 256*256) TRACE4("Large texture: (%d x %d), created as (%d x %d)", dwWidth, dwHeight,m_dwCreatedTextureWidth,m_dwCreatedTextureHeight); m_fYScale = (float)m_dwCreatedTextureHeight/(float)m_dwHeight; m_fXScale = (float)m_dwCreatedTextureWidth/(float)m_dwWidth; m_pTexture = malloc(m_dwCreatedTextureWidth * m_dwCreatedTextureHeight * GetPixelSize()); switch( options.textureQuality ) { case TXT_QUALITY_DEFAULT: if( options.colorQuality == TEXTURE_FMT_A4R4G4B4 ) m_glFmt = GL_RGBA4; break; case TXT_QUALITY_32BIT: break; case TXT_QUALITY_16BIT: m_glFmt = GL_RGBA4; break; }; LOG_TEXTURE(TRACE2("New texture: (%d, %d)", dwWidth, dwHeight)); glBindTexture(GL_TEXTURE_2D, m_dwTextureName); glTexImage2D(GL_TEXTURE_2D, 0, m_glFmt, m_dwCreatedTextureWidth, m_dwCreatedTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_pTexture); } COGLTexture::~COGLTexture() { // FIXME: If usage is AS_RENDER_TARGET, we need to destroy the pbuffer glDeleteTextures(1, &m_dwTextureName ); OPENGL_CHECK_ERRORS; free(m_pTexture); m_pTexture = NULL; m_dwWidth = 0; m_dwHeight = 0; } bool COGLTexture::StartUpdate(DrawInfo *di) { if (m_pTexture == NULL) return false; di->dwHeight = (uint16_t)m_dwHeight; di->dwWidth = (uint16_t)m_dwWidth; di->dwCreatedHeight = m_dwCreatedTextureHeight; di->dwCreatedWidth = m_dwCreatedTextureWidth; di->lpSurface = m_pTexture; di->lPitch = GetPixelSize()*m_dwCreatedTextureWidth; return true; } void COGLTexture::EndUpdate(DrawInfo *di) { COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext); // we need this to check if the GL extension is available glBindTexture(GL_TEXTURE_2D, m_dwTextureName); OPENGL_CHECK_ERRORS; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); OPENGL_CHECK_ERRORS; // Mipmap support if(options.mipmapping) { // Set Mipmap glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); OPENGL_CHECK_ERRORS; glGenerateMipmap(GL_TEXTURE_2D); OPENGL_CHECK_ERRORS; } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); OPENGL_CHECK_ERRORS; } // Copy the image data from main memory to video card texture memory //GL_BGRA_IMG works on Adreno but not inside profiler. glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_dwCreatedTextureWidth, m_dwCreatedTextureHeight, GL_RGBA, GL_UNSIGNED_BYTE, m_pTexture); OPENGL_CHECK_ERRORS; } // Keep in mind that the real texture is not scaled to fix the created OpenGL texture yet. // when the image is need to be scaled, ScaleImageToSurface in CTexure will be called to // scale the image automatically mupen64plus-rsp-hle/src/alist_nead.c000664 001750 001750 00000037601 12655644434 020536 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-rsp-hle - alist_nead.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * Copyright (C) 2009 Richard Goedeken * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include "common.h" #include "alist.h" #include "hle_external.h" #include "hle_internal.h" #include "memory.h" /* remove windows define to 0x06 */ #ifdef DUPLICATE #undef DUPLICATE #endif /* audio commands definition */ static void UNKNOWN(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint8_t acmd = (w1 >> 24); HleWarnMessage(hle->user_defined, "Unknown audio command %d: %08x %08x", acmd, w1, w2); } static void SPNOOP(struct hle_t* UNUSED(hle), uint32_t UNUSED(w1), uint32_t UNUSED(w2)) { } static void LOADADPCM(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint16_t count = w1; uint32_t address = (w2 & 0xffffff); dram_load_u16(hle, (uint16_t*)hle->alist_nead.table, address, count >> 1); } static void SETLOOP(struct hle_t* hle, uint32_t UNUSED(w1), uint32_t w2) { hle->alist_nead.loop = w2 & 0xffffff; } static void SETBUFF(struct hle_t* hle, uint32_t w1, uint32_t w2) { hle->alist_nead.in = w1; hle->alist_nead.out = (w2 >> 16); hle->alist_nead.count = w2; } static void ADPCM(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint8_t flags = (w1 >> 16); uint32_t address = (w2 & 0xffffff); alist_adpcm( hle, flags & 0x1, flags & 0x2, flags & 0x4, hle->alist_nead.out, hle->alist_nead.in, (hle->alist_nead.count + 0x1f) & ~0x1f, hle->alist_nead.table, hle->alist_nead.loop, address); } static void CLEARBUFF(struct hle_t* hle, uint32_t w1, uint32_t count) { uint16_t dmem = w1; if (count != 0) alist_clear(hle, dmem, count); } static void LOADBUFF(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint16_t count = (w1 >> 12) & 0xfff; uint16_t dmem = (w1 & 0xfff); uint32_t address = (w2 & 0xffffff); alist_load(hle, dmem, address, count); } static void SAVEBUFF(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint16_t count = (w1 >> 12) & 0xfff; uint16_t dmem = (w1 & 0xfff); uint32_t address = (w2 & 0xffffff); alist_save(hle, dmem, address, count); } static void MIXER(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint16_t count = (w1 >> 12) & 0xff0; int16_t gain = w1; uint16_t dmemi = (w2 >> 16); uint16_t dmemo = w2; alist_mix(hle, dmemo, dmemi, count, gain); } static void RESAMPLE(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint8_t flags = (w1 >> 16); uint16_t pitch = w1; uint32_t address = (w2 & 0xffffff); alist_resample( hle, flags & 0x1, false, /* TODO: check which ABI supports it */ hle->alist_nead.out, hle->alist_nead.in, (hle->alist_nead.count + 0xf) & ~0xf, pitch << 1, address); } static void RESAMPLE_ZOH(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint16_t pitch = w1; uint16_t pitch_accu = w2; alist_resample_zoh( hle, hle->alist_nead.out, hle->alist_nead.in, hle->alist_nead.count, pitch << 1, pitch_accu); } static void DMEMMOVE(struct hle_t* hle, uint32_t w1, uint32_t count) { uint16_t dmemi = w1; uint16_t dmemo = (count >> 16); if (count != 0) alist_move(hle, dmemo, dmemi, (count + 3) & ~3); } static void ENVSETUP1_MK(struct hle_t* hle, uint32_t w1, uint32_t w2) { hle->alist_nead.env_values[2] = (w1 >> 8) & 0xff00; hle->alist_nead.env_steps[2] = 0; hle->alist_nead.env_steps[0] = (w2 >> 16); hle->alist_nead.env_steps[1] = w2; } static void ENVSETUP1(struct hle_t* hle, uint32_t w1, uint32_t w2) { hle->alist_nead.env_values[2] = (w1 >> 8) & 0xff00; hle->alist_nead.env_steps[2] = w1; hle->alist_nead.env_steps[0] = (w2 >> 16); hle->alist_nead.env_steps[1] = w2; } static void ENVSETUP2(struct hle_t* hle, uint32_t UNUSED(w1), uint32_t w2) { hle->alist_nead.env_values[0] = (w2 >> 16); hle->alist_nead.env_values[1] = w2; } static void ENVMIXER_MK(struct hle_t* hle, uint32_t w1, uint32_t w2) { int16_t xors[4]; uint16_t dmemi = (w1 >> 12) & 0xff0; uint8_t count = (w1 >> 8) & 0xff; uint16_t dmem_dl = (w2 >> 20) & 0xff0; uint16_t dmem_dr = (w2 >> 12) & 0xff0; uint16_t dmem_wl = (w2 >> 4) & 0xff0; uint16_t dmem_wr = (w2 << 4) & 0xff0; xors[2] = 0; /* unsupported by this ucode */ xors[3] = 0; /* unsupported by this ucode */ xors[0] = 0 - (int16_t)((w1 & 0x2) >> 1); xors[1] = 0 - (int16_t)((w1 & 0x1) ); alist_envmix_nead( hle, false, /* unsupported by this ucode */ dmem_dl, dmem_dr, dmem_wl, dmem_wr, dmemi, count, hle->alist_nead.env_values, hle->alist_nead.env_steps, xors); } static void ENVMIXER(struct hle_t* hle, uint32_t w1, uint32_t w2) { int16_t xors[4]; uint16_t dmemi = (w1 >> 12) & 0xff0; uint8_t count = (w1 >> 8) & 0xff; bool swap_wet_LR = (w1 >> 4) & 0x1; uint16_t dmem_dl = (w2 >> 20) & 0xff0; uint16_t dmem_dr = (w2 >> 12) & 0xff0; uint16_t dmem_wl = (w2 >> 4) & 0xff0; uint16_t dmem_wr = (w2 << 4) & 0xff0; xors[2] = 0 - (int16_t)((w1 & 0x8) >> 1); xors[3] = 0 - (int16_t)((w1 & 0x4) >> 1); xors[0] = 0 - (int16_t)((w1 & 0x2) >> 1); xors[1] = 0 - (int16_t)((w1 & 0x1) ); alist_envmix_nead( hle, swap_wet_LR, dmem_dl, dmem_dr, dmem_wl, dmem_wr, dmemi, count, hle->alist_nead.env_values, hle->alist_nead.env_steps, xors); } static void DUPLICATE(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint8_t count = (w1 >> 16); uint16_t dmemi = w1; uint16_t dmemo = (w2 >> 16); alist_repeat64(hle, dmemo, dmemi, count); } static void INTERL(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint16_t count = w1; uint16_t dmemi = (w2 >> 16); uint16_t dmemo = w2; alist_copy_every_other_sample(hle, dmemo, dmemi, count); } static void INTERLEAVE_MK(struct hle_t* hle, uint32_t UNUSED(w1), uint32_t w2) { uint16_t left = (w2 >> 16); uint16_t right = w2; if (hle->alist_nead.count != 0) alist_interleave(hle, hle->alist_nead.out, left, right, hle->alist_nead.count); } static void INTERLEAVE(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint16_t count = ((w1 >> 12) & 0xff0); uint16_t dmemo = w1; uint16_t left = (w2 >> 16); uint16_t right = w2; alist_interleave(hle, dmemo, left, right, count); } static void ADDMIXER(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint16_t count = (w1 >> 12) & 0xff0; uint16_t dmemi = (w2 >> 16); uint16_t dmemo = w2; alist_add(hle, dmemo, dmemi, count); } static void HILOGAIN(struct hle_t* hle, uint32_t w1, uint32_t w2) { int8_t gain = (w1 >> 16); /* Q4.4 signed */ uint16_t count = w1; uint16_t dmem = (w2 >> 16); alist_multQ44(hle, dmem, count, gain); } static void FILTER(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint16_t dmem = w1; uint8_t flags = (w1 >> 16); uint32_t address = (w2 & 0xffffff); if (flags > 1) { hle->alist_nead.filter_count = w1; hle->alist_nead.filter_lut_address[0] = address; /* t6 */ return; } hle->alist_nead.filter_lut_address[1] = address + 0x10; /* t5 */ alist_filter(hle, dmem, hle->alist_nead.filter_count, address, hle->alist_nead.filter_lut_address); } static void SEGMENT(struct hle_t* UNUSED(hle), uint32_t UNUSED(w1), uint32_t UNUSED(w2)) { } static void NEAD_16(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint8_t count = (w1 >> 16); uint16_t dmemi = w1; uint16_t dmemo = (w2 >> 16); uint16_t block_size = w2; alist_copy_blocks(hle, dmemo, dmemi, block_size, count); } static void POLEF(struct hle_t* hle, uint32_t w1, uint32_t w2) { uint8_t flags = (w1 >> 16); uint16_t gain = w1; uint32_t address = (w2 & 0xffffff); if (hle->alist_nead.count != 0) alist_polef( hle, flags & A_INIT, hle->alist_nead.out, hle->alist_nead.in, hle->alist_nead.count, gain, hle->alist_nead.table, address); } void alist_process_nead_mk(struct hle_t* hle) { static const acmd_callback_t ABI[0x20] = { SPNOOP, ADPCM, CLEARBUFF, SPNOOP, SPNOOP, RESAMPLE, SPNOOP, SEGMENT, SETBUFF, SPNOOP, DMEMMOVE, LOADADPCM, MIXER, INTERLEAVE_MK, POLEF, SETLOOP, NEAD_16, INTERL, ENVSETUP1_MK, ENVMIXER_MK, LOADBUFF, SAVEBUFF, ENVSETUP2, SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP }; alist_process(hle, ABI, 0x20); } void alist_process_nead_sf(struct hle_t* hle) { static const acmd_callback_t ABI[0x20] = { SPNOOP, ADPCM, CLEARBUFF, SPNOOP, ADDMIXER, RESAMPLE, RESAMPLE_ZOH, SPNOOP, SETBUFF, SPNOOP, DMEMMOVE, LOADADPCM, MIXER, INTERLEAVE_MK, POLEF, SETLOOP, NEAD_16, INTERL, ENVSETUP1, ENVMIXER, LOADBUFF, SAVEBUFF, ENVSETUP2, SPNOOP, HILOGAIN, UNKNOWN, DUPLICATE, SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP }; alist_process(hle, ABI, 0x20); } void alist_process_nead_sfj(struct hle_t* hle) { static const acmd_callback_t ABI[0x20] = { SPNOOP, ADPCM, CLEARBUFF, SPNOOP, ADDMIXER, RESAMPLE, RESAMPLE_ZOH, SPNOOP, SETBUFF, SPNOOP, DMEMMOVE, LOADADPCM, MIXER, INTERLEAVE_MK, POLEF, SETLOOP, NEAD_16, INTERL, ENVSETUP1, ENVMIXER, LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN, HILOGAIN, UNKNOWN, DUPLICATE, SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP }; alist_process(hle, ABI, 0x20); } void alist_process_nead_fz(struct hle_t* hle) { static const acmd_callback_t ABI[0x20] = { UNKNOWN, ADPCM, CLEARBUFF, SPNOOP, ADDMIXER, RESAMPLE, SPNOOP, SPNOOP, SETBUFF, SPNOOP, DMEMMOVE, LOADADPCM, MIXER, INTERLEAVE, SPNOOP, SETLOOP, NEAD_16, INTERL, ENVSETUP1, ENVMIXER, LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN, SPNOOP, UNKNOWN, DUPLICATE, SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP }; alist_process(hle, ABI, 0x20); } void alist_process_nead_wrjb(struct hle_t* hle) { static const acmd_callback_t ABI[0x20] = { SPNOOP, ADPCM, CLEARBUFF, UNKNOWN, ADDMIXER, RESAMPLE, RESAMPLE_ZOH, SPNOOP, SETBUFF, SPNOOP, DMEMMOVE, LOADADPCM, MIXER, INTERLEAVE, SPNOOP, SETLOOP, NEAD_16, INTERL, ENVSETUP1, ENVMIXER, LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN, HILOGAIN, UNKNOWN, DUPLICATE, FILTER, SPNOOP, SPNOOP, SPNOOP, SPNOOP }; alist_process(hle, ABI, 0x20); } void alist_process_nead_ys(struct hle_t* hle) { static const acmd_callback_t ABI[0x18] = { UNKNOWN, ADPCM, CLEARBUFF, UNKNOWN, ADDMIXER, RESAMPLE, RESAMPLE_ZOH, FILTER, SETBUFF, DUPLICATE, DMEMMOVE, LOADADPCM, MIXER, INTERLEAVE, HILOGAIN, SETLOOP, NEAD_16, INTERL, ENVSETUP1, ENVMIXER, LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN }; alist_process(hle, ABI, 0x18); } void alist_process_nead_1080(struct hle_t* hle) { static const acmd_callback_t ABI[0x18] = { UNKNOWN, ADPCM, CLEARBUFF, UNKNOWN, ADDMIXER, RESAMPLE, RESAMPLE_ZOH, FILTER, SETBUFF, DUPLICATE, DMEMMOVE, LOADADPCM, MIXER, INTERLEAVE, HILOGAIN, SETLOOP, NEAD_16, INTERL, ENVSETUP1, ENVMIXER, LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN }; alist_process(hle, ABI, 0x18); } void alist_process_nead_oot(struct hle_t* hle) { static const acmd_callback_t ABI[0x18] = { UNKNOWN, ADPCM, CLEARBUFF, UNKNOWN, ADDMIXER, RESAMPLE, RESAMPLE_ZOH, FILTER, SETBUFF, DUPLICATE, DMEMMOVE, LOADADPCM, MIXER, INTERLEAVE, HILOGAIN, SETLOOP, NEAD_16, INTERL, ENVSETUP1, ENVMIXER, LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN }; alist_process(hle, ABI, 0x18); } void alist_process_nead_mm(struct hle_t* hle) { static const acmd_callback_t ABI[0x18] = { UNKNOWN, ADPCM, CLEARBUFF, SPNOOP, ADDMIXER, RESAMPLE, RESAMPLE_ZOH, FILTER, SETBUFF, DUPLICATE, DMEMMOVE, LOADADPCM, MIXER, INTERLEAVE, HILOGAIN, SETLOOP, NEAD_16, INTERL, ENVSETUP1, ENVMIXER, LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN }; alist_process(hle, ABI, 0x18); } void alist_process_nead_mmb(struct hle_t* hle) { static const acmd_callback_t ABI[0x18] = { SPNOOP, ADPCM, CLEARBUFF, SPNOOP, ADDMIXER, RESAMPLE, RESAMPLE_ZOH, FILTER, SETBUFF, DUPLICATE, DMEMMOVE, LOADADPCM, MIXER, INTERLEAVE, HILOGAIN, SETLOOP, NEAD_16, INTERL, ENVSETUP1, ENVMIXER, LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN }; alist_process(hle, ABI, 0x18); } void alist_process_nead_ac(struct hle_t* hle) { static const acmd_callback_t ABI[0x18] = { UNKNOWN, ADPCM, CLEARBUFF, SPNOOP, ADDMIXER, RESAMPLE, RESAMPLE_ZOH, FILTER, SETBUFF, DUPLICATE, DMEMMOVE, LOADADPCM, MIXER, INTERLEAVE, HILOGAIN, SETLOOP, NEAD_16, INTERL, ENVSETUP1, ENVMIXER, LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN }; alist_process(hle, ABI, 0x18); } mupen64plus-video-gliden64/src/GBI.h000664 001750 001750 00000044535 12655644434 020213 0ustar00sergiosergio000000 000000 #ifndef GBI_H #define GBI_H #include #include "Types.h" // Microcode Types #define F3D 0 #define F3DEX 1 #define F3DEX2 2 #define L3D 3 #define L3DEX 4 #define L3DEX2 5 #define S2DEX 6 #define S2DEX2 7 #define F3DPD 8 #define F3DDKR 9 #define F3DJFG 10 #define F3DSWSE 11 #define F3DWRUS 12 #define F3DEX2CBFD 13 #define Turbo3D 14 #define ZSortp 15 #define NONE 16 // Fixed point conversion factors #define FIXED2FLOATRECIP1 0.5f #define FIXED2FLOATRECIP2 0.25f #define FIXED2FLOATRECIP3 0.125f #define FIXED2FLOATRECIP4 0.0625f #define FIXED2FLOATRECIP5 0.03125f #define FIXED2FLOATRECIP6 0.015625f #define FIXED2FLOATRECIP7 0.0078125f #define FIXED2FLOATRECIP8 0.00390625f #define FIXED2FLOATRECIP9 0.001953125f #define FIXED2FLOATRECIP10 0.0009765625f #define FIXED2FLOATRECIP11 0.00048828125f #define FIXED2FLOATRECIP12 0.00024414063f #define FIXED2FLOATRECIP13 0.00012207031f #define FIXED2FLOATRECIP14 6.1035156e-05f #define FIXED2FLOATRECIP15 3.0517578e-05f #define FIXED2FLOATRECIP16 1.5258789e-05f #define _FIXED2FLOAT( v, b ) \ ((f32)v * FIXED2FLOATRECIP##b) // Useful macros for decoding GBI command's parameters #define _SHIFTL( v, s, w ) \ (((u32)v & ((0x01 << w) - 1)) << s) #define _SHIFTR( v, s, w ) \ (((u32)v >> s) & ((0x01 << w) - 1)) // BG flags #define G_BGLT_LOADBLOCK 0x0033 #define G_BGLT_LOADTILE 0xfff4 #define G_BG_FLAG_FLIPS 0x01 #define G_BG_FLAG_FLIPT 0x10 // Sprite object render modes #define G_OBJRM_NOTXCLAMP 0x01 #define G_OBJRM_XLU 0x02 /* Ignored */ #define G_OBJRM_ANTIALIAS 0x04 /* Ignored */ #define G_OBJRM_BILERP 0x08 #define G_OBJRM_SHRINKSIZE_1 0x10 #define G_OBJRM_SHRINKSIZE_2 0x20 #define G_OBJRM_WIDEN 0x40 // Sprite texture loading types #define G_OBJLT_TXTRBLOCK 0x00001033 #define G_OBJLT_TXTRTILE 0x00fc1034 #define G_OBJLT_TLUT 0x00000030 // These are all the constant flags #define G_ZBUFFER 0x00000001 #define G_SHADE 0x00000004 #define G_FOG 0x00010000 #define G_LIGHTING 0x00020000 #define G_TEXTURE_GEN 0x00040000 #define G_TEXTURE_GEN_LINEAR 0x00080000 #define G_LOD 0x00100000 #define G_POINT_LIGHTING 0x00400000 #define G_MV_MMTX 2 #define G_MV_PMTX 6 #define G_MV_LIGHT 10 #define G_MV_POINT 12 #define G_MV_MATRIX 14 #define G_MV_NORMALES 14 #define G_MVO_LOOKATX 0 #define G_MVO_LOOKATY 24 #define G_MVO_L0 48 #define G_MVO_L1 72 #define G_MVO_L2 96 #define G_MVO_L3 120 #define G_MVO_L4 144 #define G_MVO_L5 168 #define G_MVO_L6 192 #define G_MVO_L7 216 #define G_MV_LOOKATY 0x82 #define G_MV_LOOKATX 0x84 #define G_MV_L0 0x86 #define G_MV_L1 0x88 #define G_MV_L2 0x8a #define G_MV_L3 0x8c #define G_MV_L4 0x8e #define G_MV_L5 0x90 #define G_MV_L6 0x92 #define G_MV_L7 0x94 #define G_MV_TXTATT 0x96 #define G_MV_MATRIX_1 0x9E #define G_MV_MATRIX_2 0x98 #define G_MV_MATRIX_3 0x9A #define G_MV_MATRIX_4 0x9C #define G_MW_MATRIX 0x00 #define G_MW_NUMLIGHT 0x02 #define G_MW_CLIP 0x04 #define G_MW_SEGMENT 0x06 #define G_MW_FOG 0x08 #define G_MW_LIGHTCOL 0x0A #define G_MW_FORCEMTX 0x0C #define G_MW_POINTS 0x0C #define G_MW_PERSPNORM 0x0E #define G_MW_COORD_MOD 0x10 #define G_MWO_NUMLIGHT 0x00 #define G_MWO_CLIP_RNX 0x04 #define G_MWO_CLIP_RNY 0x0c #define G_MWO_CLIP_RPX 0x14 #define G_MWO_CLIP_RPY 0x1c #define G_MWO_SEGMENT_0 0x00 #define G_MWO_SEGMENT_1 0x01 #define G_MWO_SEGMENT_2 0x02 #define G_MWO_SEGMENT_3 0x03 #define G_MWO_SEGMENT_4 0x04 #define G_MWO_SEGMENT_5 0x05 #define G_MWO_SEGMENT_6 0x06 #define G_MWO_SEGMENT_7 0x07 #define G_MWO_SEGMENT_8 0x08 #define G_MWO_SEGMENT_9 0x09 #define G_MWO_SEGMENT_A 0x0a #define G_MWO_SEGMENT_B 0x0b #define G_MWO_SEGMENT_C 0x0c #define G_MWO_SEGMENT_D 0x0d #define G_MWO_SEGMENT_E 0x0e #define G_MWO_SEGMENT_F 0x0f #define G_MWO_FOG 0x00 #define G_MWO_MATRIX_XX_XY_I 0x00 #define G_MWO_MATRIX_XZ_XW_I 0x04 #define G_MWO_MATRIX_YX_YY_I 0x08 #define G_MWO_MATRIX_YZ_YW_I 0x0C #define G_MWO_MATRIX_ZX_ZY_I 0x10 #define G_MWO_MATRIX_ZZ_ZW_I 0x14 #define G_MWO_MATRIX_WX_WY_I 0x18 #define G_MWO_MATRIX_WZ_WW_I 0x1C #define G_MWO_MATRIX_XX_XY_F 0x20 #define G_MWO_MATRIX_XZ_XW_F 0x24 #define G_MWO_MATRIX_YX_YY_F 0x28 #define G_MWO_MATRIX_YZ_YW_F 0x2C #define G_MWO_MATRIX_ZX_ZY_F 0x30 #define G_MWO_MATRIX_ZZ_ZW_F 0x34 #define G_MWO_MATRIX_WX_WY_F 0x38 #define G_MWO_MATRIX_WZ_WW_F 0x3C #define G_MWO_POINT_RGBA 0x10 #define G_MWO_POINT_ST 0x14 #define G_MWO_POINT_XYSCREEN 0x18 #define G_MWO_POINT_ZSCREEN 0x1C #ifdef DEBUG static const char *MWOPointText[] = { "G_MWO_POINT_RGBA", "G_MWO_POINT_ST", "G_MWO_POINT_XYSCREEN", "G_MWO_POINT_ZSCREEN" }; static const char *MWOMatrixText[] = { "G_MWO_MATRIX_XX_XY_I", "G_MWO_MATRIX_XZ_XW_I", "G_MWO_MATRIX_YX_YY_I", "G_MWO_MATRIX_YZ_YW_I", "G_MWO_MATRIX_ZX_ZY_I", "G_MWO_MATRIX_ZZ_ZW_I", "G_MWO_MATRIX_WX_WY_I", "G_MWO_MATRIX_WZ_WW_I", "G_MWO_MATRIX_XX_XY_F", "G_MWO_MATRIX_XZ_XW_F", "G_MWO_MATRIX_YX_YY_F", "G_MWO_MATRIX_YZ_YW_F", "G_MWO_MATRIX_ZX_ZY_F", "G_MWO_MATRIX_ZZ_ZW_F", "G_MWO_MATRIX_WX_WY_F", "G_MWO_MATRIX_WZ_WW_F" }; #endif // These flags change between ucodes extern u32 G_MTX_STACKSIZE; extern u32 G_MTX_MODELVIEW; extern u32 G_MTX_PROJECTION; extern u32 G_MTX_MUL; extern u32 G_MTX_LOAD; extern u32 G_MTX_NOPUSH; extern u32 G_MTX_PUSH; extern u32 G_TEXTURE_ENABLE; extern u32 G_SHADING_SMOOTH; extern u32 G_CULL_FRONT; extern u32 G_CULL_BACK; extern u32 G_CULL_BOTH; extern u32 G_CLIPPING; extern u32 G_MV_VIEWPORT; extern u32 G_MWO_aLIGHT_1, G_MWO_bLIGHT_1; extern u32 G_MWO_aLIGHT_2, G_MWO_bLIGHT_2; extern u32 G_MWO_aLIGHT_3, G_MWO_bLIGHT_3; extern u32 G_MWO_aLIGHT_4, G_MWO_bLIGHT_4; extern u32 G_MWO_aLIGHT_5, G_MWO_bLIGHT_5; extern u32 G_MWO_aLIGHT_6, G_MWO_bLIGHT_6; extern u32 G_MWO_aLIGHT_7, G_MWO_bLIGHT_7; extern u32 G_MWO_aLIGHT_8, G_MWO_bLIGHT_8; // Image formats #define G_IM_FMT_RGBA 0 #define G_IM_FMT_YUV 1 #define G_IM_FMT_CI 2 #define G_IM_FMT_IA 3 #define G_IM_FMT_I 4 // Image sizes #define G_IM_SIZ_4b 0 #define G_IM_SIZ_8b 1 #define G_IM_SIZ_16b 2 #define G_IM_SIZ_32b 3 #define G_IM_SIZ_DD 5 #define G_TX_MIRROR 0x1 #define G_TX_CLAMP 0x2 #ifdef DEBUG static const char *ImageFormatText[] = { "G_IM_FMT_RGBA", "G_IM_FMT_YUV", "G_IM_FMT_CI", "G_IM_FMT_IA", "G_IM_FMT_I", "G_IM_FMT_INVALID", "G_IM_FMT_INVALID", "G_IM_FMT_INVALID" }; static const char *ImageSizeText[] = { "G_IM_SIZ_4b", "G_IM_SIZ_8b", "G_IM_SIZ_16b", "G_IM_SIZ_32b" }; static const char *SegmentText[] = { "G_MWO_SEGMENT_0", "G_MWO_SEGMENT_1", "G_MWO_SEGMENT_2", "G_MWO_SEGMENT_3", "G_MWO_SEGMENT_4", "G_MWO_SEGMENT_5", "G_MWO_SEGMENT_6", "G_MWO_SEGMENT_7", "G_MWO_SEGMENT_8", "G_MWO_SEGMENT_9", "G_MWO_SEGMENT_A", "G_MWO_SEGMENT_B", "G_MWO_SEGMENT_C", "G_MWO_SEGMENT_D", "G_MWO_SEGMENT_E", "G_MWO_SEGMENT_F" }; #endif #define G_NOOP 0x00 #define G_IMMFIRST -65 // These GBI commands are common to all ucodes #define G_SETCIMG 0xFF /* -1 */ #define G_SETZIMG 0xFE /* -2 */ #define G_SETTIMG 0xFD /* -3 */ #define G_SETCOMBINE 0xFC /* -4 */ #define G_SETENVCOLOR 0xFB /* -5 */ #define G_SETPRIMCOLOR 0xFA /* -6 */ #define G_SETBLENDCOLOR 0xF9 /* -7 */ #define G_SETFOGCOLOR 0xF8 /* -8 */ #define G_SETFILLCOLOR 0xF7 /* -9 */ #define G_FILLRECT 0xF6 /* -10 */ #define G_SETTILE 0xF5 /* -11 */ #define G_LOADTILE 0xF4 /* -12 */ #define G_LOADBLOCK 0xF3 /* -13 */ #define G_SETTILESIZE 0xF2 /* -14 */ #define G_LOADTLUT 0xF0 /* -16 */ #define G_RDPSETOTHERMODE 0xEF /* -17 */ #define G_SETPRIMDEPTH 0xEE /* -18 */ #define G_SETSCISSOR 0xED /* -19 */ #define G_SETCONVERT 0xEC /* -20 */ #define G_SETKEYR 0xEB /* -21 */ #define G_SETKEYGB 0xEA /* -22 */ #define G_RDPFULLSYNC 0xE9 /* -23 */ #define G_RDPTILESYNC 0xE8 /* -24 */ #define G_RDPPIPESYNC 0xE7 /* -25 */ #define G_RDPLOADSYNC 0xE6 /* -26 */ #define G_TEXRECTFLIP 0xE5 /* -27 */ #define G_TEXRECT 0xE4 /* -28 */ #define G_RDPNOOP 0xC0 #define G_TRI_FILL 0xC8 /* fill triangle: 11001000 */ #define G_TRI_SHADE 0xCC /* shade triangle: 11001100 */ #define G_TRI_TXTR 0xCA /* texture triangle: 11001010 */ #define G_TRI_SHADE_TXTR 0xCE /* shade, texture triangle: 11001110 */ #define G_TRI_FILL_ZBUFF 0xC9 /* fill, zbuff triangle: 11001001 */ #define G_TRI_SHADE_ZBUFF 0xCD /* shade, zbuff triangle: 11001101 */ #define G_TRI_TXTR_ZBUFF 0xCB /* texture, zbuff triangle: 11001011 */ #define G_TRI_SHADE_TXTR_ZBUFF 0xCF /* shade, txtr, zbuff trngl: 11001111 */ /* * G_SETOTHERMODE_L sft: shift count */ #define G_MDSFT_ALPHACOMPARE 0 #define G_MDSFT_ZSRCSEL 2 #define G_MDSFT_RENDERMODE 3 #define G_MDSFT_BLENDER 16 /* * G_SETOTHERMODE_H sft: shift count */ #define G_MDSFT_BLENDMASK 0 /* unsupported */ #define G_MDSFT_ALPHADITHER 4 #define G_MDSFT_RGBDITHER 6 #define G_MDSFT_COMBKEY 8 #define G_MDSFT_TEXTCONV 9 #define G_MDSFT_TEXTFILT 12 #define G_MDSFT_TEXTLUT 14 #define G_MDSFT_TEXTLOD 16 #define G_MDSFT_TEXTDETAIL 17 #define G_MDSFT_TEXTPERSP 19 #define G_MDSFT_CYCLETYPE 20 #define G_MDSFT_COLORDITHER 22 /* unsupported in HW 2.0 */ #define G_MDSFT_PIPELINE 23 /* G_SETOTHERMODE_H gPipelineMode */ #define G_PM_1PRIMITIVE 1 #define G_PM_NPRIMITIVE 0 /* G_SETOTHERMODE_H gSetCycleType */ #define G_CYC_1CYCLE 0 #define G_CYC_2CYCLE 1 #define G_CYC_COPY 2 #define G_CYC_FILL 3 /* G_SETOTHERMODE_H gSetTexturePersp */ #define G_TP_NONE 0 #define G_TP_PERSP 1 /* G_SETOTHERMODE_H gSetTextureDetail */ #define G_TD_CLAMP 0 #define G_TD_SHARPEN 1 #define G_TD_DETAIL 2 /* G_SETOTHERMODE_H gSetTextureLOD */ #define G_TL_TILE 0 #define G_TL_LOD 1 /* G_SETOTHERMODE_H gSetTextureLUT */ #define G_TT_NONE 0 #define G_TT_RGBA16 2 #define G_TT_IA16 3 /* G_SETOTHERMODE_H gSetTextureFilter */ #define G_TF_POINT 0 #define G_TF_AVERAGE 3 #define G_TF_BILERP 2 /* G_SETOTHERMODE_H gSetTextureConvert */ #define G_TC_CONV 0 #define G_TC_FILTCONV 5 #define G_TC_FILT 6 /* G_SETOTHERMODE_H gSetCombineKey */ #define G_CK_NONE 0 #define G_CK_KEY 1 /* G_SETOTHERMODE_H gSetColorDither */ #define G_CD_MAGICSQ 0 #define G_CD_BAYER 1 #define G_CD_NOISE 2 #define G_CD_DISABLE 3 #define G_CD_ENABLE G_CD_NOISE /* HW 1.0 compatibility mode */ /* G_SETOTHERMODE_H gSetAlphaDither */ #define G_AD_PATTERN 0 #define G_AD_NOTPATTERN 1 #define G_AD_NOISE 2 #define G_AD_DISABLE 3 /* G_SETOTHERMODE_L gSetAlphaCompare */ #define G_AC_NONE 0 #define G_AC_THRESHOLD 1 #define G_AC_DITHER 3 /* G_SETOTHERMODE_L gSetDepthSource */ #define G_ZS_PIXEL 0 #define G_ZS_PRIM 1 /* G_SETOTHERMODE_L gSetRenderMode */ #define AA_EN 1 #define Z_CMP 1 #define Z_UPD 1 #define IM_RD 1 #define CLR_ON_CVG 1 #define CVG_DST_CLAMP 0 #define CVG_DST_WRAP 1 #define CVG_DST_FULL 2 #define CVG_DST_SAVE 3 #define ZMODE_OPA 0 #define ZMODE_INTER 1 #define ZMODE_XLU 2 #define ZMODE_DEC 3 #define CVG_X_ALPHA 1 #define ALPHA_CVG_SEL 1 #define FORCE_BL 1 #define TEX_EDGE 0 // not used #define G_SC_NON_INTERLACE 0 #define G_SC_EVEN_INTERLACE 2 #define G_SC_ODD_INTERLACE 3 #ifdef DEBUG static const char *AAEnableText = "AA_EN"; static const char *DepthCompareText = "Z_CMP"; static const char *DepthUpdateText = "Z_UPD"; static const char *ClearOnCvgText = "CLR_ON_CVG"; static const char *CvgXAlphaText = "CVG_X_ALPHA"; static const char *AlphaCvgSelText = "ALPHA_CVG_SEL"; static const char *ForceBlenderText = "FORCE_BL"; static const char *AlphaCompareText[] = { "G_AC_NONE", "G_AC_THRESHOLD", "G_AC_INVALID", "G_AC_DITHER" }; static const char *DepthSourceText[] = { "G_ZS_PIXEL", "G_ZS_PRIM" }; static const char *AlphaDitherText[] = { "G_AD_PATTERN", "G_AD_NOTPATTERN", "G_AD_NOISE", "G_AD_DISABLE" }; static const char *ColorDitherText[] = { "G_CD_MAGICSQ", "G_CD_BAYER", "G_CD_NOISE", "G_CD_DISABLE" }; static const char *CombineKeyText[] = { "G_CK_NONE", "G_CK_KEY" }; static const char *TextureConvertText[] = { "G_TC_CONV", "G_TC_INVALID", "G_TC_INVALID", "G_TC_INVALID", "G_TC_INVALID", "G_TC_FILTCONV", "G_TC_FILT", "G_TC_INVALID" }; static const char *TextureFilterText[] = { "G_TF_POINT", "G_TF_INVALID", "G_TF_BILERP", "G_TF_AVERAGE" }; static const char *TextureLUTText[] = { "G_TT_NONE", "G_TT_INVALID", "G_TT_RGBA16", "G_TT_IA16" }; static const char *TextureLODText[] = { "G_TL_TILE", "G_TL_LOD" }; static const char *TextureDetailText[] = { "G_TD_CLAMP", "G_TD_SHARPEN", "G_TD_DETAIL" }; static const char *TexturePerspText[] = { "G_TP_NONE", "G_TP_PERSP" }; static const char *CycleTypeText[] = { "G_CYC_1CYCLE", "G_CYC_2CYCLE", "G_CYC_COPY", "G_CYC_FILL" }; static const char *PipelineModeText[] = { "G_PM_NPRIMITIVE", "G_PM_1PRIMITIVE" }; static const char *CvgDestText[] = { "CVG_DST_CLAMP", "CVG_DST_WRAP", "CVG_DST_FULL", "CVG_DST_SAVE" }; static const char *DepthModeText[] = { "ZMODE_OPA", "ZMODE_INTER", "ZMODE_XLU", "ZMODE_DEC" }; static const char *ScissorModeText[] = { "G_SC_NON_INTERLACE", "G_SC_INVALID", "G_SC_EVEN_INTERLACE", "G_SC_ODD_INTERLACE" }; #endif #ifdef DEBUG static const char *saRGBText[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "NOISE", "1", "0", "0", "0", "0", "0", "0", "0", "0" }; static const char *sbRGBText[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "CENTER", "K4", "0", "0", "0", "0", "0", "0", "0", "0" }; static const char *mRGBText[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "SCALE", "COMBINED_ALPHA", "TEXEL0_ALPHA", "TEXEL1_ALPHA", "PRIMITIVE_ALPHA", "SHADE_ALPHA", "ENV_ALPHA", "LOD_FRACTION", "PRIM_LOD_FRAC", "K5", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" }; static const char *aRGBText[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "1", "0", }; static const char *saAText[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "1", "0", }; static const char *sbAText[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "1", "0", }; static const char *mAText[] = { "LOD_FRACTION", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "PRIM_LOD_FRAC", "0", }; static const char *aAText[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "1", "0", }; #endif extern u32 G_RDPHALF_1, G_RDPHALF_2, G_RDPHALF_CONT; extern u32 G_SPNOOP; extern u32 G_SETOTHERMODE_H, G_SETOTHERMODE_L; extern u32 G_DL, G_ENDDL, G_CULLDL, G_BRANCH_Z; extern u32 G_LOAD_UCODE; extern u32 G_MOVEMEM, G_MOVEWORD; extern u32 G_MTX, G_POPMTX; extern u32 G_GEOMETRYMODE, G_SETGEOMETRYMODE, G_CLEARGEOMETRYMODE; extern u32 G_TEXTURE; extern u32 G_DMA_IO, G_DMA_DL, G_DMA_TRI, G_DMA_MTX, G_DMA_VTX, G_DMA_TEX_OFFSET, G_DMA_OFFSETS; extern u32 G_SPECIAL_1, G_SPECIAL_2, G_SPECIAL_3; extern u32 G_VTX, G_MODIFYVTX, G_VTXCOLORBASE; extern u32 G_TRI1, G_TRI2, G_TRI4; extern u32 G_QUAD, G_LINE3D; extern u32 G_RESERVED0, G_RESERVED1, G_RESERVED2, G_RESERVED3; extern u32 G_SPRITE2D_BASE; extern u32 G_BG_1CYC, G_BG_COPY; extern u32 G_OBJ_RECTANGLE, G_OBJ_SPRITE, G_OBJ_MOVEMEM; extern u32 G_SELECT_DL, G_OBJ_RENDERMODE, G_OBJ_RECTANGLE_R; extern u32 G_OBJ_LOADTXTR, G_OBJ_LDTX_SPRITE, G_OBJ_LDTX_RECT, G_OBJ_LDTX_RECT_R; extern u32 G_RDPHALF_0; #define LIGHT_1 1 #define LIGHT_2 2 #define LIGHT_3 3 #define LIGHT_4 4 #define LIGHT_5 5 #define LIGHT_6 6 #define LIGHT_7 7 #define LIGHT_8 8 #define G_DL_PUSH 0x00 #define G_DL_NOPUSH 0x01 typedef struct { s16 y; s16 x; u16 flag; s16 z; s16 t; s16 s; union { struct { u8 a; u8 b; u8 g; u8 r; } color; struct { s8 a; s8 z; // b s8 y; //g s8 x; //r } normal; }; } Vertex; typedef struct { s16 y, x; u16 ci; s16 z; s16 t, s; } PDVertex; typedef struct { u8 v2, v1, v0, flag; s16 t0, s0; s16 t1, s1; s16 t2, s2; } DKRTriangle; struct Light { u8 pad0, b, g, r; u8 pad1, b2, g2, r2; s8 pad2, z, y, x; }; // GBI commands typedef void (*GBIFunc)( u32 w0, u32 w1 ); //extern GBIFunc GBICmd[256]; struct SpecialMicrocodeInfo { u32 type; u32 NoN; u32 crc; const char *text; }; struct MicrocodeInfo { u32 address, dataAddress; u16 dataSize; u32 type; u32 crc; bool NoN; bool textureGen; bool branchLessZ; }; struct GBIInfo { GBIFunc cmd[256]; u32 PCStackSize; void init(); void destroy(); void loadMicrocode(u32 uc_start, u32 uc_dstart, u16 uc_dsize); u32 getMicrocodeType() const {return m_pCurrent != NULL ? m_pCurrent->type : NONE;} bool isHWLSupported() const; bool isNoN() const { return m_pCurrent != NULL ? m_pCurrent->NoN : false; } bool isTextureGen() const { return m_pCurrent != NULL ? m_pCurrent->textureGen: true; } bool isBranchLessZ() const { return m_pCurrent != NULL ? m_pCurrent->branchLessZ : true; } private: void _flushCommands(); void _makeCurrent(MicrocodeInfo * _pCurrent); bool _makeExistingMicrocodeCurrent(u32 uc_start, u32 uc_dstart, u32 uc_dsize); MicrocodeInfo * m_pCurrent; typedef std::list Microcodes; Microcodes m_list; }; extern GBIInfo GBI; // Allows easier setting of GBI commands #define GBI_SetGBI( command, value, function ) \ command = value; \ GBI.cmd[command] = function #define GBI_InitFlags( ucode ) \ G_MTX_STACKSIZE = ucode##_MTX_STACKSIZE; \ G_MTX_MODELVIEW = ucode##_MTX_MODELVIEW; \ G_MTX_PROJECTION = ucode##_MTX_PROJECTION; \ G_MTX_MUL = ucode##_MTX_MUL; \ G_MTX_LOAD = ucode##_MTX_LOAD; \ G_MTX_NOPUSH = ucode##_MTX_NOPUSH; \ G_MTX_PUSH = ucode##_MTX_PUSH; \ \ G_TEXTURE_ENABLE = ucode##_TEXTURE_ENABLE; \ G_SHADING_SMOOTH = ucode##_SHADING_SMOOTH; \ G_CULL_FRONT = ucode##_CULL_FRONT; \ G_CULL_BACK = ucode##_CULL_BACK; \ G_CULL_BOTH = ucode##_CULL_BOTH; \ G_CLIPPING = ucode##_CLIPPING; \ \ G_MV_VIEWPORT = ucode##_MV_VIEWPORT; \ \ G_MWO_aLIGHT_1 = ucode##_MWO_aLIGHT_1; \ G_MWO_bLIGHT_1 = ucode##_MWO_bLIGHT_1; \ G_MWO_aLIGHT_2 = ucode##_MWO_aLIGHT_2; \ G_MWO_bLIGHT_2 = ucode##_MWO_bLIGHT_2; \ G_MWO_aLIGHT_3 = ucode##_MWO_aLIGHT_3; \ G_MWO_bLIGHT_3 = ucode##_MWO_bLIGHT_3; \ G_MWO_aLIGHT_4 = ucode##_MWO_aLIGHT_4; \ G_MWO_bLIGHT_4 = ucode##_MWO_bLIGHT_4; \ G_MWO_aLIGHT_5 = ucode##_MWO_aLIGHT_5; \ G_MWO_bLIGHT_5 = ucode##_MWO_bLIGHT_5; \ G_MWO_aLIGHT_6 = ucode##_MWO_aLIGHT_6; \ G_MWO_bLIGHT_6 = ucode##_MWO_bLIGHT_6; \ G_MWO_aLIGHT_7 = ucode##_MWO_aLIGHT_7; \ G_MWO_bLIGHT_7 = ucode##_MWO_bLIGHT_7; \ G_MWO_aLIGHT_8 = ucode##_MWO_aLIGHT_8; \ G_MWO_bLIGHT_8 = ucode##_MWO_bLIGHT_8; #endif mupen64plus-core/src/ri/rdram_detection_hack.h000664 001750 001750 00000003210 12655644434 022546 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - rdram_detection_hack.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_RI_RDRAM_DETECTION_HACK_H #define M64P_RI_RDRAM_DETECTION_HACK_H void force_detected_rdram_size_hack(void); #endif mupen64plus-core/src/plugin/audio_libretro/boolean.h000664 001750 001750 00000002040 12655644434 023723 0ustar00sergiosergio000000 000000 /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. * * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with RetroArch. * If not, see . */ #ifndef __RARCH_BOOLEAN_H #define __RARCH_BOOLEAN_H #ifndef __cplusplus #if defined(_MSC_VER) && !defined(SN_TARGET_PS3) /* Hack applied for MSVC when compiling in C89 mode as it isn't C99 compliant. */ #define bool unsigned char #define true 1 #define false 0 #else #include #endif #endif #endif mupen64plus-video-gliden64/src/ShaderUtils.cpp000664 001750 001750 00000015153 12655644434 022366 0ustar00sergiosergio000000 000000 #include #include #include "ShaderUtils.h" #include "Log.h" static const GLsizei nShaderLogSize = 1024; bool checkShaderCompileStatus(GLuint obj) { GLint status; glGetShaderiv(obj, GL_COMPILE_STATUS, &status); if (status == GL_FALSE) { GLchar shader_log[nShaderLogSize]; GLsizei nLogSize = nShaderLogSize; glGetShaderInfoLog(obj, nShaderLogSize, &nLogSize, shader_log); shader_log[nLogSize] = 0; LOG(LOG_ERROR, "shader_compile error: %s\n", shader_log); return false; } return true; } bool checkProgramLinkStatus(GLuint obj) { GLint status; glGetProgramiv(obj, GL_LINK_STATUS, &status); if (status == GL_FALSE) { GLsizei nLogSize = nShaderLogSize; GLchar shader_log[nShaderLogSize]; glGetProgramInfoLog(obj, nShaderLogSize, &nLogSize, shader_log); LOG(LOG_ERROR, "shader_link error: %s\n", shader_log); return false; } return true; } GLuint createShaderProgram(const char * _strVertex, const char * _strFragment) { GLuint vertex_shader_object = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex_shader_object, 1, &_strVertex, NULL); glCompileShader(vertex_shader_object); assert(checkShaderCompileStatus(vertex_shader_object)); GLuint fragment_shader_object = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment_shader_object, 1, &_strFragment, NULL); glCompileShader(fragment_shader_object); assert(checkShaderCompileStatus(fragment_shader_object)); GLuint program = glCreateProgram(); glBindAttribLocation(program, SC_POSITION, "aPosition"); glAttachShader(program, vertex_shader_object); glAttachShader(program, fragment_shader_object); glLinkProgram(program); glDeleteShader(vertex_shader_object); glDeleteShader(fragment_shader_object); assert(checkProgramLinkStatus(program)); return program; } static const char* fragment_shader_blender = // Mace " if (uSpecialBlendMode == 1) \n" " color1 = color1 * alpha1 + uBlendColor.rgb * (1.0 - alpha1); \n" // Bomberman2 " else if (uSpecialBlendMode == 2) \n" " color1 = uBlendColor.rgb * uFogColor.a + color1 * (1.0 - uFogColor.a); \n" // Conker BFD " else if (uSpecialBlendMode == 3) \n" " color1 = color1 * uFogColor.a + uFogColor.rgb * (1.0 - uFogColor.a); \n" ; static const char *ColorInput[] = { "combined_color.rgb", "readtex0.rgb", "readtex1.rgb", "uPrimColor.rgb", "vec_color.rgb", "uEnvColor.rgb", "uCenterColor.rgb", "uScaleColor.rgb", "combined_color.a", "vec3(readtex0.a)", "vec3(readtex1.a)", "vec3(uPrimColor.a)", "vec3(vec_color.a)", "vec3(uEnvColor.a)", "vec3(lod_frac)", "vec3(uPrimLod)", "vec3(0.5 + 0.5*snoise())", "vec3(uK4)", "vec3(uK5)", "vec3(1.0)", "vec3(0.0)" }; static const char *AlphaInput[] = { "combined_color.a", "readtex0.a", "readtex1.a", "uPrimColor.a", "vec_color.a", "uEnvColor.a", "uCenterColor.a", "uScaleColor.a", "combined_color.a", "readtex0.a", "readtex1.a", "uPrimColor.a", "vec_color.a", "uEnvColor.a", "lod_frac", "uPrimLod", "0.5 + 0.5*snoise()", "uK4", "uK5", "1.0", "0.0" }; inline int correctFirstStageParam(int _param) { switch (_param) { case TEXEL1: return TEXEL0; case TEXEL1_ALPHA: return TEXEL0_ALPHA; } return _param; } static void _correctFirstStageParams(CombinerStage & _stage) { for (int i = 0; i < _stage.numOps; ++i) { _stage.op[i].param1 = correctFirstStageParam(_stage.op[i].param1); _stage.op[i].param2 = correctFirstStageParam(_stage.op[i].param2); _stage.op[i].param3 = correctFirstStageParam(_stage.op[i].param3); } } inline int correctSecondStageParam(int _param) { switch (_param) { case TEXEL0: return TEXEL1; case TEXEL1: return TEXEL0; case TEXEL0_ALPHA: return TEXEL1_ALPHA; case TEXEL1_ALPHA: return TEXEL0_ALPHA; } return _param; } static void _correctSecondStageParams(CombinerStage & _stage) { for (int i = 0; i < _stage.numOps; ++i) { _stage.op[i].param1 = correctSecondStageParam(_stage.op[i].param1); _stage.op[i].param2 = correctSecondStageParam(_stage.op[i].param2); _stage.op[i].param3 = correctSecondStageParam(_stage.op[i].param3); } } static int _compileCombiner(const CombinerStage & _stage, const char** _Input, char * _strCombiner) { char buf[128]; bool bBracketOpen = false; int nRes = 0; for (int i = 0; i < _stage.numOps; ++i) { switch (_stage.op[i].op) { case LOAD: sprintf(buf, "(%s ", _Input[_stage.op[i].param1]); strcat(_strCombiner, buf); bBracketOpen = true; nRes |= 1 << _stage.op[i].param1; break; case SUB: if (bBracketOpen) { sprintf(buf, "- %s)", _Input[_stage.op[i].param1]); bBracketOpen = false; } else sprintf(buf, "- %s", _Input[_stage.op[i].param1]); strcat(_strCombiner, buf); nRes |= 1 << _stage.op[i].param1; break; case ADD: if (bBracketOpen) { sprintf(buf, "+ %s)", _Input[_stage.op[i].param1]); bBracketOpen = false; } else sprintf(buf, "+ %s", _Input[_stage.op[i].param1]); strcat(_strCombiner, buf); nRes |= 1 << _stage.op[i].param1; break; case MUL: if (bBracketOpen) { sprintf(buf, ")*%s", _Input[_stage.op[i].param1]); bBracketOpen = false; } else sprintf(buf, "*%s", _Input[_stage.op[i].param1]); strcat(_strCombiner, buf); nRes |= 1 << _stage.op[i].param1; break; case INTER: sprintf(buf, "mix(%s, %s, %s)", _Input[_stage.op[0].param2], _Input[_stage.op[0].param1], _Input[_stage.op[0].param3]); strcat(_strCombiner, buf); nRes |= 1 << _stage.op[i].param1; nRes |= 1 << _stage.op[i].param2; nRes |= 1 << _stage.op[i].param3; break; // default: // assert(false); } } if (bBracketOpen) strcat(_strCombiner, ")"); strcat(_strCombiner, "; \n"); return nRes; } int compileCombiner(Combiner & _color, Combiner & _alpha, char * _strShader) { if (gDP.otherMode.cycleType == G_CYC_1CYCLE) { _correctFirstStageParams(_alpha.stage[0]); _correctFirstStageParams(_color.stage[0]); } strcpy(_strShader, " alpha1 = "); int nInputs = _compileCombiner(_alpha.stage[0], AlphaInput, _strShader); strcat(_strShader, " color1 = "); nInputs |= _compileCombiner(_color.stage[0], ColorInput, _strShader); strcat(_strShader, fragment_shader_blender); strcat(_strShader, " combined_color = vec4(color1, alpha1); \n"); if (_alpha.numStages == 2) { strcat(_strShader, " alpha2 = "); _correctSecondStageParams(_alpha.stage[1]); nInputs |= _compileCombiner(_alpha.stage[1], AlphaInput, _strShader); } else strcat(_strShader, " alpha2 = alpha1; \n"); if (_color.numStages == 2) { strcat(_strShader, " color2 = "); _correctSecondStageParams(_color.stage[1]); nInputs |= _compileCombiner(_color.stage[1], ColorInput, _strShader); } else strcat(_strShader, " color2 = color1; \n"); return nInputs; }mupen64plus-core/src/ri/rdram_detection_hack.c000664 001750 001750 00000004024 12655644434 022545 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - rdram_detection_hack.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "rdram_detection_hack.h" #include "ri_controller.h" #include "main/main.h" #include "si/si_controller.h" #include /* HACK: force detected RDRAM size * This hack is triggered just before initial ROM loading (see pi_controller.c) * * Proper emulation of RI/RDRAM subsystem is required to avoid this hack. */ void force_detected_rdram_size_hack(void) { uint32_t address = (g_si.pif.cic.version != CIC_X105) ? 0x318 : 0x3f0; g_ri.rdram.dram[address/4] = g_ri.rdram.dram_size; } mupen64plus-core/src/plugin/audio_libretro/drivers_resampler/cc_resampler_neon.S000664 001750 001750 00000020375 12655644434 031500 0ustar00sergiosergio000000 000000 /* RetroArch - A frontend for libretro. * Copyright (C) 2014-2015 - Ali Bouhlel ( aliaspider@gmail.com ) * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. * * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with RetroArch. * If not, see . */ #if defined(__ARM_NEON__) #ifndef CC_RESAMPLER_PRECISION #define CC_RESAMPLER_PRECISION 1 #endif #ifndef __MACH__ .arm #endif .align 4 .globl resampler_CC_downsample_neon .globl _resampler_CC_downsample_neon # size_t resampler_CC_downsample_neon(float *outp, const float *inp, # rarch_CC_resampler_t* re_, size_t input_frames, float ratio); # r0: outp initial (and output_frames return value) # r1: inp initial/current # r2: re_ [r2+0] --> {q14,q15}=buffer , [r2+32] --> s5=distance # r3: input_frames/inp_max # r4: outp current # r5: # r6: # r7: # q0: d0: s0: 0.0 # q4: d8: s16: min(ratio, 1.0) # s1: 1.0 # s17: min(ratio, 1.0) # d1: s2: 2.0 # d9: s18: min(ratio, 1.0) # s3: 3.0 # s19: min(ratio, 1.0) # q1: d2: s4: ratio # q5: d10: s20: 1.0 # s5: distance # s21: 1.0 # d3: s6: (1.0/ratio) # d11: s22: 1.0 # s7: (1.0/ratio)+0.5 # s23: 1.0 # q2: d4: s8: 0.5 # q6: d12: s24: 3.0 # s9: 0.5 # s25: 3.0 # d5: s10: 0.5 # d13: s26: 3.0 # s11: 0.5 # s27: 3.0 # q3: d6: s12: -0.5 # q7: d14: s28: 0.25 # s13: -0.5 # s29: 0.25 # d7: s14: -0.5 # d15: s30: 0.25 # s15: -0.5 # s31: 0.25 # q8: d16: (temp) # q12: d24: (temp) # (temp) # (temp) # d17: (temp) # d25: (temp) # (temp) # (temp) # q9: d18: (temp) # q13: d26: (temp) # (temp) # (temp) # d19: (temp) # d27: (temp) # (temp) # (temp) # q10: d20: (temp) # q14: d28: buffer[0] # (temp) # buffer[1] # d21: (temp) # d29: buffer[2] # (temp) # buffer[3] # q11: d22: (temp) # q15: d30: buffer[4] # (temp) # buffer[5] # d23: (temp) # d31: buffer[6] # (temp) # buffer[7] resampler_CC_downsample_neon: _resampler_CC_downsample_neon: vld1.f32 {q14-q15}, [r2, :256] vldr s4, [sp] vpush {q4,q5,q6,q7} push {r4} mov r4, r0 veor q0, q0, q0 vmov.f32 s1, #1.0 vmov.f32 s2, #2.0 vmov.f32 s3, #3.0 vmov.f32 q2, #0.5 vmov.f32 q3, #-0.5 vmov.f32 q5, #1.0 vmov.f32 q6, #3.0 vmov.f32 q7, #0.25 vldr s5, [r2, #32] vdiv.f32 s6, s20, s4 vadd.f32 s7, s6, s8 vdup.f32 q4, d2[0] vmin.f32 q4, q4, q5 lsl r3, #3 add r3, r3, r1 cmp r3, r1 beq 3f 1: vdup.f32 q8, d3[0] vmul.f32 q8, q8, q0 vdup.f32 q9, d2[1] vsub.f32 q8, q9, q8 vadd.f32 q10, q8, q2 vsub.f32 q11, q8, q2 vmul.f32 q10, q10, q4 vmul.f32 q11, q11, q4 #if (CC_RESAMPLER_PRECISION > 0) vmul.f32 q8, q10, q10 vmul.f32 q9, q11, q11 vsub.f32 q12, q6, q8 vsub.f32 q13, q6, q9 vmul.f32 q12, q12, q8 vmul.f32 q13, q13, q9 vmul.f32 q12, q12, q7 vmul.f32 q13, q13, q7 vsub.f32 q12, q5, q12 vsub.f32 q13, q5, q13 vmul.f32 q10, q10, q12 vmul.f32 q11, q11, q13 #endif vmin.f32 q10, q10, q2 vmin.f32 q11, q11, q2 vmax.f32 q10, q10, q3 vmax.f32 q11, q11, q3 vsub.f32 q10, q10, q11 vmov.f32 q11, q10 vzip.f32 q10, q11 vld1.f32 d16, [r1, :64]! vmov.f32 d17, d16 vmul.f32 q10, q10, q8 vmul.f32 q11, q11, q8 vadd.f32 q14, q14, q10 vadd.f32 q15, q15, q11 # distance++ vadd.f32 s5, s5, s20 vcmpe.f32 s5, s7 vmrs APSR_nzcv, fpscr ble 2f vst1.f32 d28, [r4, :64]! vmov.f32 d28, d29 vmov.f32 d29, d30 vmov.f32 d30, d31 vmov.f32 d31, #0.0 vsub.f32 s5, s5, s6 2: cmp r3, r1 bne 1b 3: vst1.f32 {q14-q15}, [r2, :256] vstr s5, [r2, #32] sub r0, r4, r0 lsr r0, r0, #3 pop {r4} vpop {q4,q5,q6,q7} bx lr .align 4 .globl resampler_CC_upsample_neon .globl _resampler_CC_upsample_neon # size_t resampler_CC_upsample_neon(float *outp, const float *inp, # rarch_CC_resampler_t* re_, size_t input_frames, float ratio); # r0: outp initial (and output_frames return value) # r1: inp initial/current # r2: re_ [r2+0] --> {q14,q15}=buffer , [r2+32] --> s5=distance # r3: input_frames/inp_max # r4: outp current # r5: # r6: # r7: # q0: d0: s0: 1.0 # q4: d8: s16: min(ratio, 1.0) # s1: 0.0 # s17: min(ratio, 1.0) # d1: s2: -1.0 # d9: s18: min(ratio, 1.0) # s3: -2.0 # s19: min(ratio, 1.0) # q1: d2: s4: ratio # q5: d10: s20: 1.0 # s5: distance # s21: 1.0 # d3: s6: (1.0/ratio) # d11: s22: 1.0 # s7: (1.0/ratio)+0.5 # s23: 1.0 # q2: d4: s8: 0.5 # q6: d12: s24: 3.0 # s9: 0.5 # s25: 3.0 # d5: s10: 0.5 # d13: s26: 3.0 # s11: 0.5 # s27: 3.0 # q3: d6: s12: -0.5 # q7: d14: s28: 0.25 # s13: -0.5 # s29: 0.25 # d7: s14: -0.5 # d15: s30: 0.25 # s15: -0.5 # s31: 0.25 # q8: d16: (temp) # q12: d24: (temp) # (temp) # (temp) # d17: (temp) # d25: (temp) # (temp) # (temp) # q9: d18: (temp) # q13: d26: (temp) # (temp) # (temp) # d19: (temp) # d27: (temp) # (temp) # (temp) # q10: d20: (temp) # q14: d28: buffer[0] # (temp) # buffer[1] # d21: (temp) # d29: buffer[2] # (temp) # buffer[3] # q11: d22: (temp) # q15: d30: buffer[4] # (temp) # buffer[5] # d23: (temp) # d31: buffer[6] # (temp) # buffer[7] resampler_CC_upsample_neon: _resampler_CC_upsample_neon: vld1.f32 {q14-q15}, [r2, :256] vldr s4, [sp] vpush {q4,q5,q6,q7} push {r4} mov r4, r0 veor q0, q0, q0 vmov.f32 s0, #1.0 vmov.f32 s2, #-1.0 vmov.f32 s3, #-2.0 vmov.f32 q2, #0.5 vmov.f32 q3, #-0.5 vmov.f32 q5, #1.0 vmov.f32 q6, #3.0 vmov.f32 q7, #0.25 vldr s5, [r2, #32] vdiv.f32 s6, s20, s4 vadd.f32 s7, s6, s8 vdup.f32 q4, d2[0] vmin.f32 q4, q4, q5 lsl r3, #3 add r3, r3, r1 cmp r3, r1 beq 4f 1: vld1.f32 d16, [r1, :64]! vmov.f32 d28, d29 vmov.f32 d29, d30 vmov.f32 d30, d31 vmov.f32 d31, d16 vcmpe.f32 s5, s20 vmrs APSR_nzcv, fpscr bge 3f 2: vdup.f32 q8, d2[1] vadd.f32 q8, q8, q0 vadd.f32 q10, q8, q2 vsub.f32 q11, q8, q2 vmul.f32 q10, q10, q4 vmul.f32 q11, q11, q4 #if (CC_RESAMPLER_PRECISION > 0) vmul.f32 q8, q10, q10 vmul.f32 q9, q11, q11 vsub.f32 q12, q6, q8 vsub.f32 q13, q6, q9 vmul.f32 q12, q12, q8 vmul.f32 q13, q13, q9 vmul.f32 q12, q12, q7 vmul.f32 q13, q13, q7 vsub.f32 q12, q5, q12 vsub.f32 q13, q5, q13 vmul.f32 q10, q10, q12 vmul.f32 q11, q11, q13 #endif vmin.f32 q10, q10, q2 vmin.f32 q11, q11, q2 vmax.f32 q10, q10, q3 vmax.f32 q11, q11, q3 vsub.f32 q10, q10, q11 vmov.f32 q11, q10 vzip.f32 q10, q11 vmul.f32 q10, q10, q14 vmul.f32 q11, q11, q15 vadd.f32 q10, q10, q11 vadd.f32 d20, d20, d21 vst1.f32 d20, [r4, :64]! vadd.f32 s5, s5, s6 vcmpe.f32 s5, s20 vmrs APSR_nzcv, fpscr blt 2b 3: # distance-- vsub.f32 s5, s5, s20 cmp r3, r1 bne 1b 4: vst1.f32 {q14-q15}, [r2, :256] vstr s5, [r2, #32] sub r0, r4, r0 lsr r0, r0, #3 pop {r4} vpop {q4,q5,q6,q7} bx lr #endif gles2rice/src/Config.h000664 001750 001750 00000024757 12655644434 015762 0ustar00sergiosergio000000 000000 /* Copyright (C) 2002 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _RICE_CONFIG_H_ #define _RICE_CONFIG_H_ #include #include "../../libretro/boolean.h" #include "typedefs.h" #ifdef MSB_FIRST #define BYTE_ADDR_XOR 0 #define WORD_ADDR_XOR 0 #define BYTE4_XOR_BE(a) (a) #else #define BYTE_ADDR_XOR 3 #define WORD_ADDR_XOR 1 #define BYTE4_XOR_BE(a) ((a) ^ 3) #endif typedef enum { OGL_DEVICE, OGL_1_1_DEVICE, OGL_1_2_DEVICE, OGL_1_3_DEVICE, OGL_1_4_DEVICE, OGL_1_4_V2_DEVICE, OGL_TNT2_DEVICE, NVIDIA_OGL_DEVICE, OGL_FRAGMENT_PROGRAM, DIRECTX_DEVICE, } SupportedDeviceType; enum DirectXCombinerType { DX_DISABLE_COMBINER, DX_BEST_FIT, DX_LOW_END, DX_HIGH_END, DX_NVIDIA_TNT, DX_2_STAGES, DX_3_STAGES, DX_4_STAGES, DX_PIXEL_SHADER, DX_SEMI_PIXEL_SHADER, }; typedef struct { const char* name; SupportedDeviceType type; } RenderEngineSetting; enum { FRM_BUF_NONE, FRM_BUF_IGNORE, FRM_BUF_BASIC, FRM_BUF_BASIC_AND_WRITEBACK, FRM_BUF_WRITEBACK_AND_RELOAD, FRM_BUF_COMPLETE, FRM_BUF_WITH_EMULATOR, FRM_BUF_BASIC_AND_WITH_EMULATOR, FRM_BUF_WITH_EMULATOR_READ_ONLY, FRM_BUF_WITH_EMULATOR_WRITE_ONLY, }; enum { FRM_BUF_WRITEBACK_NORMAL, FRM_BUF_WRITEBACK_1_2, FRM_BUF_WRITEBACK_1_3, FRM_BUF_WRITEBACK_1_4, FRM_BUF_WRITEBACK_1_5, FRM_BUF_WRITEBACK_1_6, FRM_BUF_WRITEBACK_1_7, FRM_BUF_WRITEBACK_1_8, }; enum { TXT_BUF_NONE, TXT_BUF_IGNORE, TXT_BUF_NORMAL, TXT_BUF_WRITE_BACK, TXT_BUF_WRITE_BACK_AND_RELOAD, }; enum { TXT_QUALITY_DEFAULT, TXT_QUALITY_32BIT, TXT_QUALITY_16BIT, }; enum { FORCE_DEFAULT_FILTER, FORCE_POINT_FILTER, FORCE_LINEAR_FILTER, }; enum { TEXTURE_NO_MIPMAP = 0, TEXTURE_NO_FILTER, TEXTURE_BILINEAR_FILTER, TEXTURE_TRILINEAR_FILTER, }; enum { TEXTURE_NO_ENHANCEMENT, TEXTURE_2X_ENHANCEMENT, TEXTURE_2XSAI_ENHANCEMENT, TEXTURE_HQ2X_ENHANCEMENT, TEXTURE_LQ2X_ENHANCEMENT, TEXTURE_HQ4X_ENHANCEMENT, TEXTURE_SHARPEN_ENHANCEMENT, TEXTURE_SHARPEN_MORE_ENHANCEMENT, TEXTURE_EXTERNAL, TEXTURE_MIRRORED, }; enum { TEXTURE_ENHANCEMENT_NORMAL, TEXTURE_ENHANCEMENT_WITH_SMOOTH_FILTER_1, TEXTURE_ENHANCEMENT_WITH_SMOOTH_FILTER_2, TEXTURE_ENHANCEMENT_WITH_SMOOTH_FILTER_3, TEXTURE_ENHANCEMENT_WITH_SMOOTH_FILTER_4, }; enum { SCREEN_UPDATE_DEFAULT = 0, SCREEN_UPDATE_AT_VI_UPDATE = 1, SCREEN_UPDATE_AT_VI_CHANGE = 2, SCREEN_UPDATE_AT_CI_CHANGE = 3, SCREEN_UPDATE_AT_1ST_CI_CHANGE = 4, SCREEN_UPDATE_AT_1ST_PRIMITIVE = 5, SCREEN_UPDATE_BEFORE_SCREEN_CLEAR = 6, SCREEN_UPDATE_AT_VI_UPDATE_AND_DRAWN = 7, // Update screen at VI origin is updated and the screen has been drawn }; enum { ONSCREEN_DISPLAY_NOTHING = 0, ONSCREEN_DISPLAY_DLIST_PER_SECOND, ONSCREEN_DISPLAY_FRAME_PER_SECOND, ONSCREEN_DISPLAY_DEBUG_INFORMATION_ONLY, ONSCREEN_DISPLAY_TEXT_FROM_CORE_ONLY, ONSCREEN_DISPLAY_DLIST_PER_SECOND_WITH_CORE_MSG, ONSCREEN_DISPLAY_FRAME_PER_SECOND_WITH_CORE_MSG, ONSCREEN_DISPLAY_DEBUG_INFORMATION_WITH_CORE_MSG, }; enum HACK_FOR_GAMES { NO_HACK_FOR_GAME, HACK_FOR_BANJO_TOOIE, HACK_FOR_DR_MARIO, HACK_FOR_ZELDA, HACK_FOR_MARIO_TENNIS, HACK_FOR_BANJO, HACK_FOR_PD, HACK_FOR_GE, HACK_FOR_PILOT_WINGS, HACK_FOR_YOSHI, HACK_FOR_NITRO, HACK_FOR_TONYHAWK, HACK_FOR_NASCAR, HACK_FOR_SUPER_BOWLING, HACK_FOR_CONKER, HACK_FOR_ALL_STAR_BASEBALL, HACK_FOR_TIGER_HONEY_HUNT, HACK_REVERSE_XY_COOR, HACK_REVERSE_Y_COOR, HACK_FOR_GOLDEN_EYE, HACK_FOR_FZERO, HACK_FOR_COMMANDCONQUER, HACK_FOR_RUMBLE, HACK_FOR_SOUTH_PARK_RALLY, HACK_FOR_BUST_A_MOVE, HACK_FOR_OGRE_BATTLE, HACK_FOR_TWINE, HACK_FOR_EXTREME_G2, HACK_FOR_ROGUE_SQUADRON, HACK_FOR_MARIO_GOLF, HACK_FOR_MLB, HACK_FOR_POLARISSNOCROSS, HACK_FOR_TOPGEARRALLY, HACK_FOR_DUKE_NUKEM, HACK_FOR_ZELDA_MM, HACK_FOR_MARIO_KART, }; enum { NOT_USE_CI_WIDTH_AND_RATIO, USE_CI_WIDTH_AND_RATIO_FOR_NTSC, USE_CI_WIDTH_AND_RATIO_FOR_PAL, }; typedef struct { bool bEnableHacks; bool bWinFrameMode; bool bOGLVertexClipper; bool bSkipFrame; bool bFullTMEM; bool bUseFullTMEM; uint32_t mipmapping; uint32_t fogMethod; uint32_t forceTextureFilter; uint32_t textureEnhancement; uint32_t textureEnhancementControl; uint32_t textureQuality; uint32_t anisotropicFiltering; uint32_t multiSampling; bool bTexRectOnly; bool bSmallTextureOnly; bool bDumpTexturesToFiles; bool bLoadHiResTextures; bool bLoadHiResCRCOnly; int OpenglDepthBufferSetting; int OpenglRenderSetting; uint32_t colorQuality; HACK_FOR_GAMES enableHackForGames; } GlobalOptions; typedef struct { bool bUpdateCIInfo; bool bCheckBackBufs; // Check texture again against the recent backbuffer addresses bool bWriteBackBufToRDRAM; // If a recent backbuffer is used, write its content back to RDRAM bool bLoadBackBufFromRDRAM; // Load content from RDRAM and draw into backbuffer bool bIgnore; // Ignore all rendering into texture buffers bool bSupportRenderTextures; // Support render-to-texture bool bCheckRenderTextures; // Check texture again against the the last render_texture addresses bool bRenderTextureWriteBack; // Write back render_texture into RDRAM bool bLoadRDRAMIntoRenderTexture; // Load RDRAM content and render into render_texture bool bAtEachFrameUpdate; // Reload and write back at each frame buffer and CI update bool bProcessCPUWrite; bool bProcessCPURead; bool bFillRectNextTextureBuffer; bool bIgnoreRenderTextureIfHeightUnknown; //bool bFillColor; } FrameBufferOptions; typedef struct { uint32_t N64FrameBufferEmuType; uint32_t N64FrameBufferWriteBackControl; uint32_t N64RenderToTextureEmuType; uint32_t screenUpdateSetting; bool bNormalCombiner; bool bNormalBlender; bool bFastTexCRC; bool bAccurateTextureMapping; bool bInN64Resolution; bool bDoubleSizeForSmallTxtrBuf; bool bSaveVRAM; } RomOptions; typedef struct IniSection { bool bOutput; char crccheck[50]; char name[50]; // Options with changeable default values uint32_t dwNormalCombiner; uint32_t dwNormalBlender; uint32_t dwFastTextureCRC; uint32_t dwAccurateTextureMapping; uint32_t dwFrameBufferOption; uint32_t dwRenderToTextureOption; uint32_t dwScreenUpdateSetting; // Options with FALSE as default values bool bDisableBlender; bool bForceScreenClear; bool bEmulateClear; bool bForceDepthBuffer; // Less useful options bool bDisableObjBG; bool bDisableTextureCRC; bool bIncTexRectEdge; bool bZHack; bool bTextureScaleHack; bool bFastLoadTile; bool bUseSmallerTexture; bool bPrimaryDepthHack; bool bTexture1Hack; bool bDisableCulling; int VIWidth; int VIHeight; uint32_t UseCIWidthAndRatio; uint32_t dwFullTMEM; bool bTxtSizeMethod2; bool bEnableTxtLOD; } section; struct ROMHeader { uint8_t x1, x2, x3, x4; uint32_t dwClockRate; uint32_t dwBootAddressOffset; uint32_t dwRelease; uint32_t dwCRC1; uint32_t dwCRC2; uint64_t qwUnknown1; char szName[20]; uint32_t dwUnknown2; uint16_t wUnknown3; uint8_t nUnknown4; uint8_t nManufacturer; uint16_t wCartID; int8_t nCountryID; uint8_t nUnknown5; }; typedef struct { // Other info from the rom. This is for convenience unsigned char szGameName[50+1]; int8_t nCountryID; // Copy of the ROM header ROMHeader romheader; // With changeable default values uint32_t dwNormalCombiner; uint32_t dwNormalBlender; uint32_t dwAccurateTextureMapping; uint32_t dwFastTextureCRC; uint32_t dwFrameBufferOption; uint32_t dwRenderToTextureOption; uint32_t dwScreenUpdateSetting; // With FALSE as its default values bool bForceScreenClear; bool bEmulateClear; bool bForceDepthBuffer; bool bDisableBlender; // Less useful options bool bDisableObjBG; bool bDisableTextureCRC; bool bIncTexRectEdge; bool bZHack; bool bTextureScaleHack; bool bFastLoadTile; bool bUseSmallerTexture; bool bPrimaryDepthHack; bool bTexture1Hack; bool bDisableCulling; int VIWidth; int VIHeight; uint32_t UseCIWidthAndRatio; uint32_t dwFullTMEM; bool bTxtSizeMethod2; bool bEnableTxtLOD; } GameSetting, *LPGAMESETTING; typedef struct { int8_t nCountryID; char* szName; uint32_t nTvType; } CountryIDInfo; #define TV_SYSTEM_NTSC 1 #define TV_SYSTEM_PAL 0 extern GlobalOptions options; extern FrameBufferOptions frameBufferOptions; extern RomOptions defaultRomOptions; extern RomOptions currentRomOptions; extern const CountryIDInfo g_CountryCodeInfo[]; extern GameSetting g_curRomInfo; extern bool bIniIsChanged; extern char szIniFileName[300]; extern bool InitConfiguration(void); extern bool LoadConfiguration(void); extern void WriteIniFile(); extern bool ReadIniFile(); extern void OutputSectionDetails(uint32_t i, FILE * fh); extern void GenerateCurrentRomOptions(); extern void Ini_GetRomOptions(LPGAMESETTING pGameSetting); extern void Ini_StoreRomOptions(LPGAMESETTING pGameSetting); extern uint32_t CountryCodeToTVSystem(uint32_t countryCode); extern void ROM_GetRomNameFromHeader(unsigned char * szName, ROMHeader * pHdr); #endif gles2rice/src/RSP_GBI_Others.h000664 001750 001750 00000151550 12655644434 017216 0ustar00sergiosergio000000 000000 /* Copyright (C) 2002 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // A few ucode used in DKR and Others Special games #include #include "Render.h" #include "Timing.h" #include "osal_preproc.h" #ifndef min #define min(a,b) ((a) < (b) ? (a) : (b)) #endif #ifndef max #define max(a,b) ((a) > (b) ? (a) : (b)) #endif uint32_t dwConkerVtxZAddr=0; static void RDP_GFX_DumpVtxInfoDKR(uint32_t dwAddr, uint32_t dwV0, uint32_t dwN); void RDP_GFX_DLInMem(Gfx *gfx) { uint32_t dwLimit = ((gfx->words.w0) >> 16) & 0xFF; uint32_t dwPush = RSP_DLIST_PUSH; //((gfx->words.w0) >> 16) & 0xFF; uint32_t dwAddr = 0x00000000 | (gfx->words.w1); //RSPSegmentAddr((gfx->words.w1)); LOG_UCODE(" Address=0x%08x Push: 0x%02x", dwAddr, dwPush); switch (dwPush) { case RSP_DLIST_PUSH: LOG_UCODE(" Pushing DisplayList 0x%08x", dwAddr); gDlistStackPointer++; gDlistStack[gDlistStackPointer].pc = dwAddr; gDlistStack[gDlistStackPointer].countdown = dwLimit; break; case RSP_DLIST_NOPUSH: LOG_UCODE(" Jumping to DisplayList 0x%08x", dwAddr); gDlistStack[gDlistStackPointer].pc = dwAddr; gDlistStack[gDlistStackPointer].countdown = dwLimit; break; } LOG_UCODE(""); LOG_UCODE("\\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/"); LOG_UCODE("#############################################"); } extern Matrix ALIGN(16, dkrMatrixTransposed); void RSP_Mtx_DKR(Gfx *gfx) { uint32_t dwAddr = RSPSegmentAddr((gfx->words.w1)); uint32_t dwCommand = ((gfx->words.w0)>>16)&0xFF; //uint32_t dwLength = ((gfx->words.w0)) &0xFFFF; dwAddr = (gfx->words.w1)+RSPSegmentAddr(gRSP.dwDKRMatrixAddr); //gRSP.DKRCMatrixIndex = ((gfx->words.w0)>>22)&3; bool mul=false; int index = 0; switch( dwCommand ) { case 0xC0: // DKR gRSP.DKRCMatrixIndex = index = 3; break; case 0x80: // DKR gRSP.DKRCMatrixIndex = index = 2; break; case 0x40: // DKR gRSP.DKRCMatrixIndex = index = 1; break; case 0x20: // DKR gRSP.DKRCMatrixIndex = index = 0; break; case 0x00: gRSP.DKRCMatrixIndex = index = 0; break; case 0x01: //mul = true; gRSP.DKRCMatrixIndex = index = 1; break; case 0x02: //mul = true; gRSP.DKRCMatrixIndex = index = 2; break; case 0x03: //mul = true; gRSP.DKRCMatrixIndex = index = 3; break; case 0x81: index = 1; mul = true; break; case 0x82: index = 2; mul = true; break; case 0x83: index = 3; mul = true; break; default: DebuggerAppendMsg("Fix me, mtx DKR, cmd=%08X", dwCommand); break; } // Load matrix from dwAddr Matrix &mat = gRSP.DKRMatrixes[index]; LoadMatrix(dwAddr); if( mul ) { mat = matToLoad*gRSP.DKRMatrixes[0]; } else { mat = matToLoad; } DEBUGGER_IF_DUMP(logMatrix,TRACE3("DKR Matrix: cmd=0x%X, idx = %d, mul=%d", dwCommand, index, mul)); LOG_UCODE(" DKR Loading Mtx: %d, command=%d", index, dwCommand); DEBUGGER_PAUSE_AND_DUMP(NEXT_MATRIX_CMD,{TRACE0("Paused at DKR Matrix Cmd");}); } void RSP_Vtx_DKR(Gfx *gfx) { uint32_t dwAddr = RSPSegmentAddr((gfx->words.w1)); uint32_t dwV0 = (((gfx->words.w0) >> 9 )&0x1F); uint32_t dwN = (((gfx->words.w0) >>19 )&0x1F)+1; if( gfx->words.w0 & 0x00010000 ) { if( gRSP.DKRBillBoard ) gRSP.DKRVtxCount = 1; } else { gRSP.DKRVtxCount = 0; } dwV0 += gRSP.DKRVtxCount; LOG_UCODE(" Address 0x%08x, v0: %d, Num: %d", dwAddr, dwV0, dwN); DEBUGGER_ONLY_IF( (pauseAtNext && (eventToPause==NEXT_VERTEX_CMD||eventToPause==NEXT_MATRIX_CMD)), {DebuggerAppendMsg("DKR Vtx: Cmd0=%08X, Cmd1=%08X", (gfx->words.w0), (gfx->words.w1));}); VTX_DUMP(TRACE2("Vtx_DKR, cmd0=%08X cmd1=%08X", (gfx->words.w0), (gfx->words.w1))); VTX_DUMP(TRACE2("Vtx_DKR, v0=%d n=%d", dwV0, dwN)); if (dwV0 >= 32) dwV0 = 31; if ((dwV0 + dwN) > 32) { WARNING(TRACE0("Warning, attempting to load into invalid vertex positions")); dwN = 32 - dwV0; } //if( dwAddr == 0 || dwAddr < 0x2000) { dwAddr = (gfx->words.w1)+RSPSegmentAddr(gRSP.dwDKRVtxAddr); } // Check that address is valid... if ((dwAddr + (dwN*16)) > g_dwRamSize) { WARNING(TRACE1("ProcessVertexData: Address out of range (0x%08x)", dwAddr)); } else { ProcessVertexDataDKR(dwAddr, dwV0, dwN); status.dwNumVertices += dwN; RDP_GFX_DumpVtxInfoDKR(dwAddr, dwV0, dwN); } } void RSP_Vtx_Gemini(Gfx *gfx) { uint32_t dwAddr = RSPSegmentAddr((gfx->words.w1)); uint32_t dwV0 = (((gfx->words.w0)>>9)&0x1F); uint32_t dwN = (((gfx->words.w0) >>19 )&0x1F); LOG_UCODE(" Address 0x%08x, v0: %d, Num: %d", dwAddr, dwV0, dwN); DEBUGGER_ONLY_IF( (pauseAtNext && (eventToPause==NEXT_VERTEX_CMD||eventToPause==NEXT_MATRIX_CMD)), {DebuggerAppendMsg("DKR Vtx: Cmd0=%08X, Cmd1=%08X", (gfx->words.w0), (gfx->words.w1));}); VTX_DUMP(TRACE2("Vtx_DKR, cmd0=%08X cmd1=%08X", (gfx->words.w0), (gfx->words.w1))); if (dwV0 >= 32) dwV0 = 31; if ((dwV0 + dwN) > 32) { TRACE0("Warning, attempting to load into invalid vertex positions"); dwN = 32 - dwV0; } //if( dwAddr == 0 || dwAddr < 0x2000) { dwAddr = (gfx->words.w1)+RSPSegmentAddr(gRSP.dwDKRVtxAddr); } // Check that address is valid... if ((dwAddr + (dwN*16)) > g_dwRamSize) { TRACE1("ProcessVertexData: Address out of range (0x%08x)", dwAddr); } else { ProcessVertexDataDKR(dwAddr, dwV0, dwN); status.dwNumVertices += dwN; RDP_GFX_DumpVtxInfoDKR(dwAddr, dwV0, dwN); } } // DKR verts are extra 4 bytes void RDP_GFX_DumpVtxInfoDKR(uint32_t dwAddr, uint32_t dwV0, uint32_t dwN) { #ifdef DEBUGGER uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; short * psSrc = (short *)(rdram_u8 + dwAddr); int i = 0; for (uint32_t dwV = dwV0; dwV < dwV0 + dwN; dwV++) { float x = (float)psSrc[(i + 0) ^ 1]; float y = (float)psSrc[(i + 1) ^ 1]; float z = (float)psSrc[(i + 2) ^ 1]; //uint16_t wFlags = CRender::g_pRender->m_dwVecFlags[dwV]; //(uint16_t)psSrc[3^0x1]; uint16_t wA = psSrc[(i + 3) ^ 1]; uint16_t wB = psSrc[(i + 4) ^ 1]; uint8_t a = wA>>8; uint8_t b = (uint8_t)wA; uint8_t c = wB>>8; uint8_t d = (uint8_t)wB; XVECTOR4 & t = g_vecProjected[dwV]; LOG_UCODE(" #%02d Pos: {% 6f,% 6f,% 6f} Extra: %02x %02x %02x %02x (transf: {% 6f,% 6f,% 6f})", dwV, x, y, z, a, b, c, d, t.x, t.y, t.z ); i+=5; } uint16_t * pwSrc = (uint16_t *)(rdram_u8 + dwAddr); i = 0; for (uint32_t dwV = dwV0; dwV < dwV0 + dwN; dwV++) { LOG_UCODE(" #%02d %04x %04x %04x %04x %04x", dwV, pwSrc[(i + 0) ^ 1], pwSrc[(i + 1) ^ 1], pwSrc[(i + 2) ^ 1], pwSrc[(i + 3) ^ 1], pwSrc[(i + 4) ^ 1]); i += 5; } #endif // DEBUGGER } void DLParser_Set_Addr_Ucode6(Gfx *gfx) { gRSP.dwDKRMatrixAddr = (gfx->words.w0)&0x00FFFFFF; gRSP.dwDKRVtxAddr = (gfx->words.w1)&0x00FFFFFF; gRSP.DKRVtxCount=0; } void RSP_Vtx_WRUS(Gfx *gfx) { uint32_t dwAddr = RSPSegmentAddr((gfx->words.w1)); uint32_t dwLength = ((gfx->words.w0))&0xFFFF; uint32_t dwN= (dwLength + 1) / 0x210; //uint32_t dwN= (dwLength >> 9); //uint32_t dwV0 = (((gfx->words.w0)>>16)&0x3f)/5; uint32_t dwV0 = (((gfx->words.w0)>>16)&0xFF)/5; LOG_UCODE(" Address 0x%08x, v0: %d, Num: %d, Length: 0x%04x", dwAddr, dwV0, dwN, dwLength); if (dwV0 >= 32) dwV0 = 31; if ((dwV0 + dwN) > 32) { TRACE0("Warning, attempting to load into invalid vertex positions"); dwN = 32 - dwV0; } ProcessVertexData(dwAddr, dwV0, dwN); status.dwNumVertices += dwN; DisplayVertexInfo(dwAddr, dwV0, dwN); } void RSP_Vtx_ShadowOfEmpire(Gfx *gfx) { uint32_t dwAddr = RSPSegmentAddr((gfx->words.w1)); uint32_t dwLength = ((gfx->words.w0))&0xFFFF; uint32_t dwN= (((gfx->words.w0) >> 4) & 0xFFF) / 33 + 1; uint32_t dwV0 = 0; LOG_UCODE(" Address 0x%08x, v0: %d, Num: %d, Length: 0x%04x", dwAddr, dwV0, dwN, dwLength); if (dwV0 >= 32) dwV0 = 31; if ((dwV0 + dwN) > 32) { TRACE0("Warning, attempting to load into invalid vertex positions"); dwN = 32 - dwV0; } ProcessVertexData(dwAddr, dwV0, dwN); status.dwNumVertices += dwN; DisplayVertexInfo(dwAddr, dwV0, dwN); } void RSP_DL_In_MEM_DKR(Gfx *gfx) { // This cmd is likely to execute number of ucode at the given address uint32_t dwAddr = (gfx->words.w1);//RSPSegmentAddr((gfx->words.w1)); { gDlistStackPointer++; gDlistStack[gDlistStackPointer].pc = dwAddr; gDlistStack[gDlistStackPointer].countdown = (((gfx->words.w0)>>16)&0xFF); } } uint16_t ConvertYUVtoR5G5B5X1(int y, int u, int v) { float r = y + (1.370705f * (v-128)); float g = y - (0.698001f * (v-128)) - (0.337633f * (u-128)); float b = y + (1.732446f * (u-128)); r *= 0.125f; g *= 0.125f; b *= 0.125f; //clipping the result if (r > 32) r = 32; if (g > 32) g = 32; if (b > 32) b = 32; if (r < 0) r = 0; if (g < 0) g = 0; if (b < 0) b = 0; uint16_t c = (uint16_t)(((uint16_t)(r) << 11) | ((uint16_t)(g) << 6) | ((uint16_t)(b) << 1) | 1); return c; } void TexRectToN64FrameBuffer_YUV_16b(uint32_t x0, uint32_t y0, uint32_t width, uint32_t height) { // Convert YUV image at TImg and Copy the texture into the N64 RDRAM framebuffer memory uint32_t n64CIaddr = g_CI.dwAddr; uint32_t n64CIwidth = g_CI.dwWidth; for (uint32_t y = 0; y < height; y++) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; uint32_t* pN64Src = (uint32_t*)(rdram_u8 + (g_TI.dwAddr&(g_dwRamSize-1)))+y*(g_TI.dwWidth>>1); uint16_t* pN64Dst = (uint16_t*)(rdram_u8 + (n64CIaddr&(g_dwRamSize-1)))+(y+y0)*n64CIwidth; for (uint32_t x = 0; x < width; x+=2) { uint32_t val = *pN64Src++; int y0 = (uint8_t)val&0xFF; int v = (uint8_t)(val>>8)&0xFF; int y1 = (uint8_t)(val>>16)&0xFF; int u = (uint8_t)(val>>24)&0xFF; pN64Dst[x+x0] = ConvertYUVtoR5G5B5X1(y0,u,v); pN64Dst[x+x0+1] = ConvertYUVtoR5G5B5X1(y1,u,v); } } } extern uObjMtxReal gObjMtxReal; void DLParser_OgreBatter64BG(Gfx *gfx) { #ifdef DEBUGGER uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; uint32_t dwAddr = RSPSegmentAddr((gfx->words.w1)); uObjTxSprite *ptr = (uObjTxSprite*)(rdram_u8 + dwAddr); #endif PrepareTextures(); CTexture *ptexture = g_textures[0].m_pCTexture; TexRectToN64FrameBuffer_16b( (uint32_t)gObjMtxReal.X, (uint32_t)gObjMtxReal.Y, ptexture->m_dwWidth, ptexture->m_dwHeight, gRSP.curTile); #ifdef DEBUGGER CRender::g_pRender->DrawSpriteR(*ptr, false, 0, 0, 0, 0, 0); DEBUGGER_PAUSE_AT_COND_AND_DUMP_COUNT_N((pauseAtNext && (eventToPause==NEXT_OBJ_TXT_CMD|| eventToPause==NEXT_FLUSH_TRI)), {DebuggerAppendMsg("Ogre Battle 64 BG: Address=%08X\n", dwAddr);}); #endif } void DLParser_Bomberman2TextRect(Gfx *gfx) { // Bomberman 64 - The Second Attack! (U) [!] // The 0x02 cmd, list a TexRect cmd if( options.enableHackForGames == HACK_FOR_OGRE_BATTLE && gRDP.tiles[7].dwFormat == TXT_FMT_YUV ) { TexRectToN64FrameBuffer_YUV_16b( (uint32_t)gObjMtxReal.X, (uint32_t)gObjMtxReal.Y, 16, 16); //DLParser_OgreBatter64BG((gfx->words.w0), (gfx->words.w1)); return; } uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; uint32_t dwAddr = RSPSegmentAddr((gfx->words.w1)); uObjSprite *info = (uObjSprite*)(rdram_u8 + dwAddr); uint32_t dwTile = gRSP.curTile; PrepareTextures(); //CRender::g_pRender->SetCombinerAndBlender(); uObjTxSprite drawinfo; memcpy( &(drawinfo.sprite), info, sizeof(uObjSprite)); CRender::g_pRender->DrawSpriteR(drawinfo, false, dwTile, 0, 0, drawinfo.sprite.imageW/32, drawinfo.sprite.imageH/32); DEBUGGER_PAUSE_AT_COND_AND_DUMP_COUNT_N((pauseAtNext && (eventToPause==NEXT_TRIANGLE|| eventToPause==NEXT_FLUSH_TRI)), { DebuggerAppendMsg("Bomberman 64 - TextRect: Addr=%08X\n", dwAddr); dwAddr &= (g_dwRamSize-1); DebuggerAppendMsg("%08X-%08X-%08X-%08X-%08X-%08X\n", RDRAM_UWORD(dwAddr), RDRAM_UWORD(dwAddr+4), RDRAM_UWORD(dwAddr+8), RDRAM_UWORD(dwAddr+12), RDRAM_UWORD(dwAddr+16), RDRAM_UWORD(dwAddr+20) ); } ); } void RSP_MoveWord_DKR(Gfx *gfx) { SP_Timing(RSP_GBI1_MoveWord); uint32_t dwNumLights; switch ((gfx->words.w0) & 0xFF) { case RSP_MOVE_WORD_NUMLIGHT: dwNumLights = (gfx->words.w1)&0x7; LOG_UCODE(" RSP_MOVE_WORD_NUMLIGHT: Val:%d", dwNumLights); gRSP.ambientLightIndex = dwNumLights; SetNumLights(dwNumLights); //gRSP.DKRBillBoard = (gfx->words.w1)&0x1 ? true : false; gRSP.DKRBillBoard = (gfx->words.w1)&0x7 ? true : false; LOG_UCODE(" gRSP.DKRBillBoard = %d", gRSP.DKRBillBoard); DEBUGGER_PAUSE_AND_DUMP_COUNT_N(NEXT_MATRIX_CMD, {DebuggerAppendMsg("DKR Moveword, select gRSP.DKRBillBoard %s, cmd0=%08X, cmd1=%08X", gRSP.DKRBillBoard?"true":"false", (gfx->words.w0), (gfx->words.w1));}); break; case RSP_MOVE_WORD_LIGHTCOL: gRSP.DKRCMatrixIndex = ((gfx->words.w1)>>6)&7; //gRSP.DKRCMatrixIndex = ((gfx->words.w1)>>6)&3; LOG_UCODE(" gRSP.DKRCMatrixIndex = %d", gRSP.DKRCMatrixIndex); DEBUGGER_PAUSE_AND_DUMP_COUNT_N(NEXT_MATRIX_CMD, {DebuggerAppendMsg("DKR Moveword, select matrix %d, cmd0=%08X, cmd1=%08X", gRSP.DKRCMatrixIndex, (gfx->words.w0), (gfx->words.w1));}); break; default: RSP_GBI1_MoveWord(gfx); break; } } void RSP_DMA_Tri_DKR(Gfx *gfx) { bool bTrisAdded = false; uint32_t *rdram_u32 = (uint32_t*)gfx_info.RDRAM; uint32_t dwAddr = RSPSegmentAddr((gfx->words.w1)); uint32_t flag = ((gfx->words.w0) & 0xFF0000) >> 16; if (flag&1) CRender::g_pRender->SetCullMode(false,true); else CRender::g_pRender->SetCullMode(false,false); uint32_t dwNum = (((gfx->words.w0) & 0xFFF0) >>4 ); uint32_t * pData = (uint32_t*)&rdram_u32[dwAddr/4]; if( dwAddr+16*dwNum >= g_dwRamSize ) { TRACE0("DMATRI invalid memory pointer"); return; } TRI_DUMP(TRACE2("DMATRI, addr=%08X, Cmd0=%08X\n", dwAddr, (gfx->words.w0))); status.primitiveType = PRIM_DMA_TRI; for (uint32_t i = 0; i < dwNum; i++) { LOG_UCODE(" 0x%08x: %08x %08x %08x %08x", dwAddr + i*16, pData[0], pData[1], pData[2], pData[3]); uint32_t dwInfo = pData[0]; uint32_t dwV0 = (dwInfo >> 16) & 0x1F; uint32_t dwV1 = (dwInfo >> 8) & 0x1F; uint32_t dwV2 = (dwInfo ) & 0x1F; TRI_DUMP(TRACE5("DMATRI: %d, %d, %d (%08X-%08X)", dwV0,dwV1,dwV2,(gfx->words.w0),(gfx->words.w1))); //if (IsTriangleVisible(dwV0, dwV1, dwV2)) { DEBUG_DUMP_VERTEXES("DmaTri", dwV0, dwV1, dwV2); LOG_UCODE(" Tri: %d,%d,%d", dwV0, dwV1, dwV2); if (!bTrisAdded )//&& CRender::g_pRender->IsTextureEnabled()) { PrepareTextures(); InitVertexTextureConstants(); } // Generate texture coordinates short s0 = ((short)(pData[1]>>16)); short t0 = ((short)(pData[1]&0xFFFF)); short s1 = ((short)(pData[2]>>16)); short t1 = ((short)(pData[2]&0xFFFF)); short s2 = ((short)(pData[3]>>16)); short t2 = ((short)(pData[3]&0xFFFF)); TRI_DUMP( { DebuggerAppendMsg(" (%d,%d), (%d,%d), (%d,%d)",s0,t0,s1,t1,s2,t2); DebuggerAppendMsg(" (%08X), (%08X), (%08X), (%08X)",pData[0],pData[1],pData[2],pData[3]); }); CRender::g_pRender->SetVtxTextureCoord(dwV0, s0, t0); CRender::g_pRender->SetVtxTextureCoord(dwV1, s1, t1); CRender::g_pRender->SetVtxTextureCoord(dwV2, s2, t2); if( !bTrisAdded ) { CRender::g_pRender->SetCombinerAndBlender(); } bTrisAdded = true; PrepareTriangle(dwV0, dwV1, dwV2); } pData += 4; } if (bTrisAdded) { CRender::g_pRender->DrawTriangles(); } gRSP.DKRVtxCount=0; } uint32_t dwPDCIAddr = 0; void ProcessVertexDataPD(uint32_t dwAddr, uint32_t dwV0, uint32_t dwNum); void RSP_Vtx_PD(Gfx *gfx) { SP_Timing(RSP_GBI0_Vtx); uint32_t dwAddr = RSPSegmentAddr((gfx->words.w1)); uint32_t dwV0 = ((gfx->words.w0)>>16)&0x0F; uint32_t dwN = (((gfx->words.w0)>>20)&0x0F)+1; //uint32_t dwLength = ((gfx->words.w0))&0xFFFF; LOG_UCODE(" Address 0x%08x, v0: %d, Num: %d", dwAddr, dwV0, dwN); ProcessVertexDataPD(dwAddr, dwV0, dwN); status.dwNumVertices += dwN; } void RSP_Set_Vtx_CI_PD(Gfx *gfx) { // Color index buf address dwPDCIAddr = RSPSegmentAddr((gfx->words.w1)); } void RSP_Tri4_PD(Gfx *gfx) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; uint32_t w0 = gfx->words.w0; uint32_t w1 = gfx->words.w1; status.primitiveType = PRIM_TRI2; // While the next command pair is Tri2, add vertices uint32_t dwPC = gDlistStack[gDlistStackPointer].pc; bool bTrisAdded = false; do { uint32_t dwFlag = (w0>>16)&0xFF; LOG_UCODE(" PD Tri4: 0x%08x 0x%08x Flag: 0x%02x", w0, w1, dwFlag); for( uint32_t i=0; i<4; i++) { uint32_t v0 = (w1>>(4+(i<<3))) & 0xF; uint32_t v1 = (w1>>( (i<<3))) & 0xF; uint32_t v2 = (w0>>( (i<<2))) & 0xF; bool bVisible = IsTriangleVisible(v0, v2, v1); LOG_UCODE(" (%d, %d, %d) %s", v0, v1, v2, bVisible ? "": "(clipped)"); if (bVisible) { DEBUG_DUMP_VERTEXES("Tri4_PerfectDark 1/2", v0, v1, v2); if (!bTrisAdded && CRender::g_pRender->IsTextureEnabled()) { PrepareTextures(); InitVertexTextureConstants(); } if( !bTrisAdded ) { CRender::g_pRender->SetCombinerAndBlender(); } bTrisAdded = true; PrepareTriangle(v0, v2, v1); } } w0 = *(uint32_t *)(rdram_u8 + dwPC+0); w1 = *(uint32_t *)(rdram_u8 + dwPC+4); dwPC += 8; #ifdef DEBUGGER } while (!(pauseAtNext && eventToPause==NEXT_TRIANGLE) && (w0>>24) == (uint8_t)RSP_TRI2); #else } while ((w0>>24) == (uint8_t)RSP_TRI2); #endif gDlistStack[gDlistStackPointer].pc = dwPC-8; if (bTrisAdded) { CRender::g_pRender->DrawTriangles(); } DEBUG_TRIANGLE(TRACE0("Pause at PD Tri4")); } void DLParser_Tri4_Conker(Gfx *gfx) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; uint32_t w0 = gfx->words.w0; uint32_t w1 = gfx->words.w1; status.primitiveType = PRIM_TRI2; // While the next command pair is Tri2, add vertices uint32_t dwPC = gDlistStack[gDlistStackPointer].pc; bool bTrisAdded = false; do { LOG_UCODE(" Conker Tri4: 0x%08x 0x%08x", w0, w1); uint32_t idx[12]; idx[0] = (w1 )&0x1F; idx[1] = (w1>> 5)&0x1F; idx[2] = (w1>>10)&0x1F; idx[3] = (w1>>15)&0x1F; idx[4] = (w1>>20)&0x1F; idx[5] = (w1>>25)&0x1F; idx[6] = (w0 )&0x1F; idx[7] = (w0>> 5)&0x1F; idx[8] = (w0>>10)&0x1F; idx[ 9] = (((w0>>15)&0x7)<<2)|(w1>>30); idx[10] = (w0>>18)&0x1F; idx[11] = (w0>>23)&0x1F; for( uint32_t i=0; i<4; i++) { uint32_t v0=idx[i*3 ]; uint32_t v1=idx[i*3+1]; uint32_t v2=idx[i*3+2]; bool bVisible = IsTriangleVisible(v0, v1, v2); LOG_UCODE(" (%d, %d, %d) %s", v0, v1, v2, bVisible ? "": "(clipped)"); if (bVisible) { DEBUG_DUMP_VERTEXES("Tri4 Conker:", v0, v1, v2); if (!bTrisAdded && CRender::g_pRender->IsTextureEnabled()) { PrepareTextures(); InitVertexTextureConstants(); } if( !bTrisAdded ) { CRender::g_pRender->SetCombinerAndBlender(); } bTrisAdded = true; PrepareTriangle(v0, v1, v2); } } w0 = *(uint32_t *)(rdram_u8 + dwPC+0); w1 = *(uint32_t *)(rdram_u8 + dwPC+4); dwPC += 8; #ifdef DEBUGGER } while (!(pauseAtNext && eventToPause==NEXT_TRIANGLE) && (w0>>28) == 1 ); #else } while ((w0>>28) == 1); #endif gDlistStack[gDlistStackPointer].pc = dwPC-8; if (bTrisAdded) { CRender::g_pRender->DrawTriangles(); } DEBUG_TRIANGLE(TRACE0("Pause at Conker Tri4")); } void RDP_GFX_Force_Vertex_Z_Conker(uint32_t dwAddr) { VTX_DUMP( { int8_t *rdram_s8 = (int8_t*)gfx_info.RDRAM; s8 * pcBase = rdram_s8 + (dwAddr&(g_dwRamSize-1)); uint32_t * pdwBase = (uint32_t *)pcBase; for (int i = 0; i < 4; i++) { DebuggerAppendMsg(" %08x %08x %08x %08x", pdwBase[0], pdwBase[1], pdwBase[2], pdwBase[3]); pdwBase+=4; } }); dwConkerVtxZAddr = dwAddr; DEBUGGER_PAUSE_AND_DUMP(NEXT_VERTEX_CMD,{TRACE0("Paused at RDP_GFX_Force_Matrix_Conker Cmd");}); } void DLParser_MoveMem_Conker(Gfx *gfx) { uint32_t dwType = ((gfx->words.w0) ) & 0xFE; uint32_t dwAddr = RSPSegmentAddr((gfx->words.w1)); if( dwType == RSP_GBI2_MV_MEM__MATRIX ) { LOG_UCODE(" DLParser_MoveMem_Conker"); RDP_GFX_Force_Vertex_Z_Conker(dwAddr); } else if( dwType == RSP_GBI2_MV_MEM__LIGHT ) { LOG_UCODE(" MoveMem Light Conker"); uint32_t dwOffset2 = ((gfx->words.w0) >> 5) & 0x3FFF; uint32_t dwLight=0xFF; if( dwOffset2 >= 0x30 ) { dwLight = (dwOffset2 - 0x30)/0x30; LOG_UCODE(" Light %d:", dwLight); RSP_MoveMemLight(dwLight, dwAddr); } else { // fix me //TRACE0("Check me in DLParser_MoveMem_Conker - MoveMem Light"); } DEBUGGER_PAUSE_AND_DUMP_COUNT_N( NEXT_SET_LIGHT, { DebuggerAppendMsg("RSP_MoveMemLight: %d, Addr=%08X, cmd0=%08X", dwLight, dwAddr, (gfx->words.w0)); TRACE0("Pause after MoveMemLight"); }); } else { RSP_GBI2_MoveMem(gfx); } } extern void ProcessVertexDataConker(uint32_t dwAddr, uint32_t dwV0, uint32_t dwNum); void RSP_Vtx_Conker(Gfx *gfx) { uint32_t dwAddr = RSPSegmentAddr((gfx->words.w1)); uint32_t dwVEnd = (((gfx->words.w0) )&0xFFF)/2; uint32_t dwN = (((gfx->words.w0)>>12)&0xFFF); uint32_t dwV0 = dwVEnd - dwN; LOG_UCODE(" Vtx: Address 0x%08x, vEnd: %d, v0: %d, Num: %d", dwAddr, dwVEnd, dwV0, dwN); ProcessVertexDataConker(dwAddr, dwV0, dwN); status.dwNumVertices += dwN; DisplayVertexInfo(dwAddr, dwV0, dwN); } void DLParser_MoveWord_Conker(Gfx *gfx) { uint32_t dwType = ((gfx->words.w0) >> 16) & 0xFF; if( dwType != RSP_MOVE_WORD_NUMLIGHT ) { RSP_GBI2_MoveWord(gfx); } else { uint32_t dwNumLights = ((gfx->words.w1)/48); LOG_UCODE("Conker RSP_MOVE_WORD_NUMLIGHT: %d", dwNumLights); gRSP.ambientLightIndex = dwNumLights+1; SetNumLights(dwNumLights); DEBUGGER_PAUSE_AND_DUMP_COUNT_N( NEXT_SET_LIGHT, { DebuggerAppendMsg("SetNumLights: %d", dwNumLights); TRACE0("Pause after SetNumLights"); }); } } void DLParser_Ucode8_0x0(Gfx *gfx) { LOG_UCODE("DLParser_Ucode8_0x0"); if( (gfx->words.w0) == 0 && (gfx->words.w1) ) { uint32_t newaddr = RSPSegmentAddr((gfx->words.w1)); if( newaddr && newaddr < g_dwRamSize) { if( gDlistStackPointer < MAX_DL_STACK_SIZE-1 ) { gDlistStackPointer++; gDlistStack[gDlistStackPointer].pc = newaddr+8; // Always skip the first 2 entries gDlistStack[gDlistStackPointer].countdown = MAX_DL_COUNT; } else { DebuggerAppendMsg("Error, gDlistStackPointer overflow"); } } } else { LOG_UCODE("DLParser_Ucode8_0x0, skip 0x%08X, 0x%08x", (gfx->words.w0), (gfx->words.w1)); gDlistStack[gDlistStackPointer].pc += 8; } } uint32_t Rogue_Squadron_Vtx_XYZ_Cmd; uint32_t Rogue_Squadron_Vtx_XYZ_Addr; uint32_t Rogue_Squadron_Vtx_Color_Cmd; uint32_t Rogue_Squadron_Vtx_Color_Addr; uint32_t GSBlkAddrSaves[100][2]; void ProcessVertexData_Rogue_Squadron(uint32_t dwXYZAddr, uint32_t dwColorAddr, uint32_t dwXYZCmd, uint32_t dwColorCmd); void DLParser_RS_Color_Buffer(Gfx *gfx) { uint32_t dwPC = gDlistStack[gDlistStackPointer].pc-8; uint32_t dwAddr = RSPSegmentAddr((gfx->words.w1)); if( dwAddr > g_dwRamSize ) { TRACE0("DL, addr is wrong"); dwAddr = (gfx->words.w1)&(g_dwRamSize-1); } Rogue_Squadron_Vtx_Color_Cmd = (gfx->words.w0); Rogue_Squadron_Vtx_Color_Addr = dwAddr; LOG_UCODE("Vtx_Color at PC=%08X: 0x%08x 0x%08x\n", dwPC-8, (gfx->words.w0), (gfx->words.w1)); #ifdef DEBUGGER if( pauseAtNext && (eventToPause == NEXT_VERTEX_CMD ) ) { DebuggerAppendMsg("Vtx_Color at PC=%08X: 0x%08x 0x%08x\n", dwPC-8, (gfx->words.w0), (gfx->words.w1)); if( dwAddr < g_dwRamSize ) { DumpHex(dwAddr, min(64, g_dwRamSize-dwAddr)); } } #endif ProcessVertexData_Rogue_Squadron(Rogue_Squadron_Vtx_XYZ_Addr, Rogue_Squadron_Vtx_Color_Addr, Rogue_Squadron_Vtx_XYZ_Cmd, Rogue_Squadron_Vtx_Color_Cmd); } void DLParser_RS_Vtx_Buffer(Gfx *gfx) { uint32_t dwPC = gDlistStack[gDlistStackPointer].pc-8; uint32_t dwAddr = RSPSegmentAddr((gfx->words.w1)); if( dwAddr > g_dwRamSize ) { TRACE0("DL, addr is wrong"); dwAddr = (gfx->words.w1)&(g_dwRamSize-1); } LOG_UCODE("Vtx_XYZ at PC=%08X: 0x%08x 0x%08x\n", dwPC-8, (gfx->words.w0), (gfx->words.w1)); Rogue_Squadron_Vtx_XYZ_Cmd = (gfx->words.w0); Rogue_Squadron_Vtx_XYZ_Addr = dwAddr; #ifdef DEBUGGER if( pauseAtNext && (eventToPause == NEXT_VERTEX_CMD ) ) { DebuggerAppendMsg("Vtx_XYZ at PC=%08X: 0x%08x 0x%08x\n", dwPC-8, (gfx->words.w0), (gfx->words.w1)); if( dwAddr < g_dwRamSize ) { DumpHex(dwAddr, min(64, g_dwRamSize-dwAddr)); } } #endif } void DLParser_RS_Block(Gfx *gfx) { uint32_t dwPC = gDlistStack[gDlistStackPointer].pc-8; LOG_UCODE("ucode 0x80 at PC=%08X: 0x%08x 0x%08x\n", dwPC, (gfx->words.w0), (gfx->words.w1)); } void DLParser_RS_MoveMem(Gfx *gfx) { //uint32_t dwPC = gDlistStack[gDlistStackPointer].pc; //uint32_t cmd1 = ((dwPC)&0x00FFFFFF)|0x80000000; RSP_GBI1_MoveMem(gfx); gDlistStack[gDlistStackPointer].pc += 16; //DEBUGGER_PAUSE_AND_DUMP(NEXT_SET_MODE_CMD, { // DebuggerAppendMsg("Pause after RS_MoveMem at: %08X\n", dwPC-8); //}); } void DLParser_RS_0xbe(Gfx *gfx) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; uint32_t dwPC = gDlistStack[gDlistStackPointer].pc-8; LOG_UCODE("ucode %02X, skip 1", ((gfx->words.w0)>>24)); LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x", dwPC, (gfx->words.w0), (gfx->words.w1)); dwPC+=8; uint32_t dwCmd2 = *(uint32_t *)(rdram_u8 + dwPC); uint32_t dwCmd3 = *(uint32_t *)(rdram_u8 + dwPC+4); LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x\n", dwPC, dwCmd2, dwCmd3); gDlistStack[gDlistStackPointer].pc += 8; DEBUGGER_PAUSE_AND_DUMP(NEXT_SET_MODE_CMD, { DebuggerAppendMsg("Pause after RS_0xbe at: %08X\n", dwPC-8); DebuggerAppendMsg("\t0x%08x 0x%08x", (gfx->words.w0), (gfx->words.w1)); DebuggerAppendMsg("\t0x%08x 0x%08x", dwCmd2, dwCmd3); }); } void DLParser_Ucode8_EndDL(Gfx *gfx) { #ifdef DEBUGGER uint32_t dwPC = gDlistStack[gDlistStackPointer].pc-8; #endif RDP_GFX_PopDL(); DEBUGGER_PAUSE_AND_DUMP(NEXT_DLIST, DebuggerAppendMsg("PC=%08X: EndDL, return to %08X\n\n", dwPC, gDlistStack[gDlistStackPointer].pc)); } void DLParser_Ucode8_DL(Gfx *gfx) // DL Function Call { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; #ifdef DEBUGGER uint32_t dwPC = gDlistStack[gDlistStackPointer].pc-8; #endif uint32_t dwAddr = RSPSegmentAddr((gfx->words.w1)); uint32_t dwCmd2 = *(uint32_t *)(rdram_u8 + dwAddr); uint32_t dwCmd3 = *(uint32_t *)(rdram_u8 + dwAddr+4); if( dwAddr > g_dwRamSize ) { TRACE0("DL, addr is wrong"); dwAddr = (gfx->words.w1)&(g_dwRamSize-1); } // Detect looping /*if(gDlistStackPointer>0 ) { for( int i=0; i>24) == 0x80 ) { GSBlkAddrSaves[gDlistStackPointer][0] = dwCmd2; GSBlkAddrSaves[gDlistStackPointer][1] = dwCmd3; } DEBUGGER_PAUSE_AND_DUMP(NEXT_DLIST, DebuggerAppendMsg("\nPC=%08X: Call DL at Address %08X - %08X, %08X\n\n", dwPC, dwAddr, dwCmd2, dwCmd3)); } void DLParser_Ucode8_JUMP(Gfx *gfx) // DL Function Call { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; if( ((gfx->words.w0)&0x00FFFFFF) == 0 ) { #ifdef DEBUGGER uint32_t dwPC = gDlistStack[gDlistStackPointer].pc-8; #endif uint32_t dwAddr = RSPSegmentAddr((gfx->words.w1)); if( dwAddr > g_dwRamSize ) { TRACE0("DL, addr is wrong"); dwAddr = (gfx->words.w1)&(g_dwRamSize-1); } #ifdef DEBUGGER uint32_t dwCmd2 = *(uint32_t *)(rdram_u8 + dwAddr); uint32_t dwCmd3 = *(uint32_t *)(rdram_u8 + dwAddr+4); #endif gDlistStack[gDlistStackPointer].pc = dwAddr+8; // Jump to new address DEBUGGER_PAUSE_AND_DUMP(NEXT_DLIST, DebuggerAppendMsg("\nPC=%08X: Jump to Address %08X - %08X, %08X\n\n", dwPC, dwAddr, dwCmd2, dwCmd3)); } else { uint32_t dwPC = gDlistStack[gDlistStackPointer].pc-8; LOG_UCODE("ucode 0x07 at PC=%08X: 0x%08x 0x%08x\n", dwPC, (gfx->words.w0), (gfx->words.w1)); } } void DLParser_Ucode8_Unknown(Gfx *gfx) { uint32_t dwPC = gDlistStack[gDlistStackPointer].pc-8; LOG_UCODE("ucode %02X at PC=%08X: 0x%08x 0x%08x\n", ((gfx->words.w0)>>24), dwPC, (gfx->words.w0), (gfx->words.w1)); } void DLParser_Unknown_Skip1(Gfx *gfx) { uint32_t dwPC = gDlistStack[gDlistStackPointer].pc-8; LOG_UCODE("ucode %02X, skip 1", ((gfx->words.w0)>>24)); gfx++; LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x", dwPC, (gfx->words.w0), (gfx->words.w1)); dwPC+=8; gfx++; LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x\n", dwPC, (gfx->words.w0), (gfx->words.w1)); gDlistStack[gDlistStackPointer].pc += 8; } void DLParser_Unknown_Skip2(Gfx *gfx) { uint32_t dwPC = gDlistStack[gDlistStackPointer].pc-8; LOG_UCODE("ucode %02X, skip 2", ((gfx->words.w0)>>24)); gfx++; LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x", dwPC, (gfx->words.w0), (gfx->words.w1)); dwPC+=8; gfx++; LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x", dwPC, (gfx->words.w0), (gfx->words.w1)); dwPC+=8; gfx++; LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x\n", dwPC, (gfx->words.w0), (gfx->words.w1)); gDlistStack[gDlistStackPointer].pc += 16; } void DLParser_Unknown_Skip3(Gfx *gfx) { uint32_t dwPC = gDlistStack[gDlistStackPointer].pc-8; LOG_UCODE("ucode %02X, skip 3", ((gfx->words.w0)>>24)); gfx++; LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x", dwPC, (gfx->words.w0), (gfx->words.w1)); dwPC+=8; gfx++; LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x", dwPC, (gfx->words.w0), (gfx->words.w1)); dwPC+=8; gfx++; LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x", dwPC, (gfx->words.w0), (gfx->words.w1)); dwPC+=8; gfx++; LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x\n", dwPC, (gfx->words.w0), (gfx->words.w1)); gDlistStack[gDlistStackPointer].pc += 24; } void DLParser_Unknown_Skip4(Gfx *gfx) { uint32_t dwPC = gDlistStack[gDlistStackPointer].pc-8; LOG_UCODE("ucode %02X, skip 4", ((gfx->words.w0)>>24)); gfx++; LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x", dwPC, (gfx->words.w0), (gfx->words.w1)); dwPC+=8; gfx++; LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x", dwPC, (gfx->words.w0), (gfx->words.w1)); dwPC+=8; gfx++; LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x", dwPC, (gfx->words.w0), (gfx->words.w1)); dwPC+=8; gfx++; LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x", dwPC, (gfx->words.w0), (gfx->words.w1)); dwPC+=8; gfx++; LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x\n", dwPC, (gfx->words.w0), (gfx->words.w1)); gDlistStack[gDlistStackPointer].pc += 32; } void DLParser_Ucode8_0x05(Gfx *gfx) { // Be careful, 0x05 is variable length ucode /* 0028E4E0: 05020088, 04D0000F - Reserved1 0028E4E8: 6BDC0306, 00000000 - G_NOTHING 0028E4F0: 05010130, 01B0000F - Reserved1 0028E4F8: 918A01CA, 1EC5FF3B - G_NOTHING 0028E500: 05088C68, F5021809 - Reserved1 0028E508: 04000405, 00000000 - RSP_VTX 0028E510: 102ECE60, 202F2AA0 - G_NOTHING 0028E518: 05088C90, F5021609 - Reserved1 0028E520: 04050405, F0F0F0F0 - RSP_VTX 0028E528: 102ED0C0, 202F2D00 - G_NOTHING 0028E530: B5000000, 00000000 - RSP_LINE3D 0028E538: 8028E640, 8028E430 - G_NOTHING 0028E540: 00000000, 00000000 - RSP_SPNOOP */ if((gfx->words.w1) == 0) return; else DLParser_Unknown_Skip4(gfx); } void DLParser_Ucode8_0xb4(Gfx *gfx) { #ifdef DEBUGGER uint32_t dwPC = gDlistStack[gDlistStackPointer].pc; #endif if(((gfx->words.w0)&0xFF) == 0x06) DLParser_Unknown_Skip3(gfx); else if(((gfx->words.w0)&0xFF) == 0x04) DLParser_Unknown_Skip1(gfx); else if(((gfx->words.w0)&0xFFF) == 0x600) DLParser_Unknown_Skip3(gfx); else { #ifdef DEBUGGER if(pauseAtNext) { DebuggerAppendMsg("ucode 0xb4 at PC=%08X: 0x%08x 0x%08x\n", dwPC-8, (gfx->words.w0), (gfx->words.w1)); } #endif DLParser_Unknown_Skip3(gfx); } } void DLParser_Ucode8_0xb5(Gfx *gfx) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; uint32_t dwPC = gDlistStack[gDlistStackPointer].pc-8; LOG_UCODE("ucode 0xB5 at PC=%08X: 0x%08x 0x%08x\n", dwPC-8, (gfx->words.w0), (gfx->words.w1)); uint32_t dwCmd2 = *(uint32_t *)(rdram_u8 + dwPC+8); uint32_t dwCmd3 = *(uint32_t *)(rdram_u8 + dwPC+12); LOG_UCODE(" : 0x%08x 0x%08x\n", dwCmd2, dwCmd3); //if( dwCmd2 == 0 && dwCmd3 == 0 ) { DLParser_Ucode8_EndDL(gfx); // Check me return; } gDlistStack[gDlistStackPointer].pc += 8; return; if( GSBlkAddrSaves[gDlistStackPointer][0] == 0 || GSBlkAddrSaves[gDlistStackPointer][1] == 0 ) { #ifdef DEBUGGER if( pauseAtNext && eventToPause == NEXT_DLIST) { DebuggerAppendMsg("PC=%08X: 0xB5 - %08X : %08X, %08X, EndDL, no next blk\n", dwPC, (gfx->words.w1), dwCmd2, dwCmd3); } #endif DLParser_Ucode8_EndDL(gfx); // Check me return; } if( ((dwCmd2>>24)!=0x80 && (dwCmd2>>24)!=0x00 ) || ((dwCmd3>>24)!=0x80 && (dwCmd3>>24)!=0x00 ) ) { #ifdef DEBUGGER if( pauseAtNext && eventToPause == NEXT_DLIST) { DebuggerAppendMsg("PC=%08X: 0xB5 - %08X : %08X, %08X, EndDL, Unknown\n", dwPC, (gfx->words.w1), dwCmd2, dwCmd3); } #endif DLParser_Ucode8_EndDL(gfx); // Check me return; } if( (dwCmd2>>24)!= (dwCmd3>>24) ) { #ifdef DEBUGGER if( pauseAtNext && eventToPause == NEXT_DLIST) { DebuggerAppendMsg("PC=%08X: 0xB5 - %08X : %08X, %08X, EndDL, Unknown\n", dwPC, (gfx->words.w1), dwCmd2, dwCmd3); } #endif DLParser_Ucode8_EndDL(gfx); // Check me return; } if( (dwCmd2>>24)==0x80 && (dwCmd3>>24)==0x80 ) { if( dwCmd2 < dwCmd3 ) { // All right, the next block is not ucode, but data #ifdef DEBUGGER if( pauseAtNext && eventToPause == NEXT_DLIST) { DebuggerAppendMsg("PC=%08X: 0xB5 - %08X : %08X, %08X, EndDL, next blk is data\n", dwPC, (gfx->words.w1), dwCmd2, dwCmd3); } #endif DLParser_Ucode8_EndDL(gfx); // Check me return; } uint32_t dwCmd4 = *(uint32_t *)(rdram_u8 + (dwCmd2&0x00FFFFFF)); uint32_t dwCmd5 = *(uint32_t *)(rdram_u8 + (dwCmd2&0x00FFFFFF)+4); uint32_t dwCmd6 = *(uint32_t *)(rdram_u8 + (dwCmd3&0x00FFFFFF)); uint32_t dwCmd7 = *(uint32_t *)(rdram_u8 + (dwCmd3&0x00FFFFFF)+4); if( (dwCmd4>>24) != 0x80 || (dwCmd5>>24) != 0x80 || (dwCmd6>>24) != 0x80 || (dwCmd7>>24) != 0x80 || dwCmd4 < dwCmd5 || dwCmd6 < dwCmd7 ) { // All right, the next block is not ucode, but data #ifdef DEBUGGER if( pauseAtNext && eventToPause == NEXT_DLIST) { DebuggerAppendMsg("PC=%08X: 0xB5 - %08X : %08X, %08X, EndDL, next blk is data\n", dwPC, (gfx->words.w1), dwCmd2, dwCmd3); DebuggerAppendMsg("%08X, %08X %08X,%08X\n", dwCmd4, dwCmd5, dwCmd6, dwCmd7); } #endif DLParser_Ucode8_EndDL(gfx); // Check me return; } gDlistStack[gDlistStackPointer].pc += 8; DEBUGGER_PAUSE_AND_DUMP(NEXT_DLIST, DebuggerAppendMsg("PC=%08X: 0xB5 - %08X : %08X, %08X, continue\n", dwPC, (gfx->words.w1), dwCmd2, dwCmd3); ); return; } else if( (dwCmd2>>24)==0x00 && (dwCmd3>>24)==0x00 ) { #ifdef DEBUGGER if( pauseAtNext && eventToPause == NEXT_DLIST) { DebuggerAppendMsg("PC=%08X: 0xB5 - %08X : %08X, %08X, EndDL, next blk is data\n", dwPC, (gfx->words.w1), dwCmd2, dwCmd3); } #endif DLParser_Ucode8_EndDL(gfx); // Check me return; } else if( (dwCmd2>>24)==0x00 && (dwCmd3>>24)==0x00 ) { dwCmd2 = *(uint32_t *)(rdram_u8 + dwPC+16); dwCmd3 = *(uint32_t *)(rdram_u8 + dwPC+20); if( (dwCmd2>>24)==0x80 && (dwCmd3>>24)==0x80 && dwCmd2 < dwCmd3 ) { // All right, the next block is not ucode, but data #ifdef DEBUGGER if( pauseAtNext && eventToPause == NEXT_DLIST) { DebuggerAppendMsg("PC=%08X: 0xB5 - %08X : %08X, %08X, EndDL, next blk is data\n", dwPC, (gfx->words.w1), dwCmd2, dwCmd3); } #endif DLParser_Ucode8_EndDL(gfx); // Check me return; } else { gDlistStack[gDlistStackPointer].pc += 8; DEBUGGER_PAUSE_AND_DUMP(NEXT_DLIST, DebuggerAppendMsg("PC=%08X: 0xB5 - %08X : %08X, %08X, continue\n", dwPC, (gfx->words.w1), dwCmd2, dwCmd3) ); return; } } #ifdef DEBUGGER uint32_t dwAddr1 = RSPSegmentAddr(dwCmd2); uint32_t dwAddr2 = RSPSegmentAddr(dwCmd3); if( (gfx->words.w1) != 0 ) { DebuggerAppendMsg("!!!! PC=%08X: 0xB5 - %08X : %08X, %08X\n", dwPC, (gfx->words.w1), dwCmd2, dwCmd3); } #endif DEBUGGER_PAUSE_AND_DUMP(NEXT_DLIST, DebuggerAppendMsg("PC=%08X: 0xB5 - %08X : %08X, %08X, continue\n", dwPC, (gfx->words.w1), dwAddr1, dwAddr2) ); return; } void DLParser_Ucode8_0xbc(Gfx *gfx) { if( ((gfx->words.w0)&0xFFF) == 0x58C ) { DLParser_Ucode8_DL(gfx); } else { uint32_t dwPC = gDlistStack[gDlistStackPointer].pc-8; LOG_UCODE("ucode 0xBC at PC=%08X: 0x%08x 0x%08x\n", dwPC, (gfx->words.w0), (gfx->words.w1)); } } void DLParser_Ucode8_0xbd(Gfx *gfx) { /* 00359A68: BD000000, DB5B0077 - RSP_POPMTX 00359A70: C8C0A000, 00240024 - RDP_TriFill 00359A78: 01000100, 00000000 - RSP_MTX 00359A80: BD000501, DB5B0077 - RSP_POPMTX 00359A88: C8C0A000, 00240024 - RDP_TriFill 00359A90: 01000100, 00000000 - RSP_MTX 00359A98: BD000A02, DB5B0077 - RSP_POPMTX 00359AA0: C8C0A000, 00240024 - RDP_TriFill 00359AA8: 01000100, 00000000 - RSP_MTX 00359AB0: BD000F04, EB6F0087 - RSP_POPMTX 00359AB8: C8C0A000, 00280028 - RDP_TriFill 00359AC0: 01000100, 00000000 - RSP_MTX 00359AC8: BD001403, DB5B0077 - RSP_POPMTX 00359AD0: C8C0A000, 00240024 - RDP_TriFill 00359AD8: 01000100, 00000000 - RSP_MTX 00359AE0: B5000000, 00000000 - RSP_LINE3D 00359AE8: 1A000000, 16000200 - G_NOTHING */ if( (gfx->words.w1) != 0 ) { DLParser_Unknown_Skip2(gfx); return; } uint32_t dwPC = gDlistStack[gDlistStackPointer].pc; LOG_UCODE("ucode 0xbd at PC=%08X: 0x%08x 0x%08x\n", dwPC-8, (gfx->words.w0), (gfx->words.w1)); } void DLParser_Ucode8_0xbf(Gfx *gfx) { if( ((gfx->words.w0)&0xFF) == 0x02 ) DLParser_Unknown_Skip3(gfx); else DLParser_Unknown_Skip1(gfx); } void PD_LoadMatrix_0xb4(uint32_t addr) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; const float fRecip = 1.0f / 65536.0f; uint32_t data[16]; data[0] = *(uint32_t*)(rdram_u8 +addr+4+ 0); data[1] = *(uint32_t*)(rdram_u8 +addr+4+ 8); data[2] = *(uint32_t*)(rdram_u8 +addr+4+16); data[3] = *(uint32_t*)(rdram_u8 +addr+4+24); data[8] = *(uint32_t*)(rdram_u8 +addr+4+32); data[9] = *(uint32_t*)(rdram_u8 +addr+4+40); data[10] = *(uint32_t*)(rdram_u8 +addr+4+48); data[11] = *(uint32_t*)(rdram_u8 +addr+4+56); data[4] = *(uint32_t*)(rdram_u8 +addr+4+ 0+64); data[5] = *(uint32_t*)(rdram_u8 +addr+4+ 8+64); data[6] = *(uint32_t*)(rdram_u8 +addr+4+16+64); data[7] = *(uint32_t*)(rdram_u8 +addr+4+24+64); data[12] = *(uint32_t*)(rdram_u8 +addr+4+32+64); data[13] = *(uint32_t*)(rdram_u8 +addr+4+40+64); data[14] = *(uint32_t*)(rdram_u8 +addr+4+48+64); data[15] = *(uint32_t*)(rdram_u8 +addr+4+56+64); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { int hi = *(short *)((unsigned char*)data + (((i<<3)+(j<<1) )^0x2)); int lo = *(uint16_t*)((unsigned char*)data + (((i<<3)+(j<<1) + 32)^0x2)); matToLoad.m[i][j] = (float)((hi<<16) | lo) * fRecip; } } #ifdef DEBUGGER LOG_UCODE( " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\r\n" " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\r\n" " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\r\n" " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\r\n", matToLoad.m[0][0], matToLoad.m[0][1], matToLoad.m[0][2], matToLoad.m[0][3], matToLoad.m[1][0], matToLoad.m[1][1], matToLoad.m[1][2], matToLoad.m[1][3], matToLoad.m[2][0], matToLoad.m[2][1], matToLoad.m[2][2], matToLoad.m[2][3], matToLoad.m[3][0], matToLoad.m[3][1], matToLoad.m[3][2], matToLoad.m[3][3]); #endif // DEBUGGER } void DLParser_RDPHalf_1_0xb4_GoldenEye(Gfx *gfx) { SP_Timing(RSP_GBI1_RDPHalf_1); if( ((gfx->words.w1)>>24) == 0xce ) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; PrepareTextures(); CRender::g_pRender->SetCombinerAndBlender(); uint32_t dwPC = gDlistStack[gDlistStackPointer].pc; // This points to the next instruction //PD_LoadMatrix_0xb4(dwPC + 8*16 - 8); uint32_t dw1 = *(uint32_t *)(rdram_u8 + dwPC+8*0+4); uint32_t dw8 = *(uint32_t *)(rdram_u8 + dwPC+8*7+4); uint32_t dw9 = *(uint32_t *)(rdram_u8 + dwPC+8*8+4); uint32_t r = (dw8>>16)&0xFF; uint32_t g = (dw8 )&0xFF; uint32_t b = (dw9>>16)&0xFF; uint32_t a = (dw9 )&0xFF; uint32_t color = COLOR_RGBA(r, g, b, a); //int x0 = 0; //int x1 = gRDP.scissor.right; int x0 = gRSP.nVPLeftN; int x1 = gRSP.nVPRightN; int y0 = int(dw1&0xFFFF)/4; int y1 = int(dw1>>16)/4; float xscale = g_textures[0].m_pCTexture->m_dwWidth / (float)(x1-x0); float yscale = g_textures[0].m_pCTexture->m_dwHeight / (float)(y1-y0); //float fs0 = (short)(dw3&0xFFFF)/32768.0f*g_textures[0].m_pCTexture->m_dwWidth; //float ft0 = (short)(dw3>>16)/32768.0f*256; CRender::g_pRender->TexRect(x0, y0, x1, y1, 0, 0, xscale, yscale, true, color); gDlistStack[gDlistStackPointer].pc += 312; #ifdef DEBUGGER if (logUcodes) { dwPC -= 8; LOG_UCODE("GoldenEye Sky at PC=%08X: 0x%08x 0x%08x", dwPC, (gfx->words.w0), (gfx->words.w1)); uint32_t *ptr = (uint32_t *)(rdram_u8 + dwPC); for( int i=0; i<21; i++, dwPC+=16,ptr+=4 ) { LOG_UCODE("%08X: %08X %08X %08X %08X", dwPC, ptr[0], ptr[1], ptr[2], ptr[3]); } } #endif DEBUGGER_PAUSE_AND_DUMP_COUNT_N(NEXT_FLUSH_TRI, { TRACE0("Pause after Golden Sky Drawing\n"); }); } } void DLParser_RSP_DL_WorldDriver(Gfx *gfx) { uint32_t dwAddr = RSPSegmentAddr((gfx->words.w1)); if( dwAddr > g_dwRamSize ) { RSP_RDP_NOIMPL("Error: DL addr = %08X out of range, PC=%08X", dwAddr, gDlistStack[gDlistStackPointer].pc ); dwAddr &= (g_dwRamSize-1); DebuggerPauseCountN( NEXT_DLIST ); } LOG_UCODE(" WorldDriver DisplayList 0x%08x", dwAddr); gDlistStackPointer++; gDlistStack[gDlistStackPointer].pc = dwAddr; gDlistStack[gDlistStackPointer].countdown = MAX_DL_COUNT; LOG_UCODE("Level=%d", gDlistStackPointer+1); LOG_UCODE("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"); } void DLParser_RSP_Pop_DL_WorldDriver(Gfx *gfx) { RDP_GFX_PopDL(); } void DLParser_RSP_Last_Legion_0x80(Gfx *gfx) { gDlistStack[gDlistStackPointer].pc += 16; LOG_UCODE("DLParser_RSP_Last_Legion_0x80"); } void DLParser_RSP_Last_Legion_0x00(Gfx *gfx) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; LOG_UCODE("DLParser_RSP_Last_Legion_0x00"); gDlistStack[gDlistStackPointer].pc += 16; if( (gfx->words.w0) == 0 && (gfx->words.w1) ) { uint32_t newaddr = RSPSegmentAddr((gfx->words.w1)); if( newaddr >= g_dwRamSize ) { RDP_GFX_PopDL(); return; } uint32_t pc1 = *(uint32_t *)(rdram_u8 + newaddr+8*1+4); uint32_t pc2 = *(uint32_t *)(rdram_u8 + newaddr+8*4+4); pc1 = RSPSegmentAddr(pc1); pc2 = RSPSegmentAddr(pc2); if( pc1 && pc1 != 0xffffff && pc1 < g_dwRamSize) { // Need to call both DL gDlistStackPointer++; gDlistStack[gDlistStackPointer].pc = pc1; gDlistStack[gDlistStackPointer].countdown = MAX_DL_COUNT; } if( pc2 && pc2 != 0xffffff && pc2 < g_dwRamSize ) { gDlistStackPointer++; gDlistStack[gDlistStackPointer].pc = pc2; gDlistStack[gDlistStackPointer].countdown = MAX_DL_COUNT; } } else if( (gfx->words.w1) == 0 ) { RDP_GFX_PopDL(); } else { // (gfx->words.w0) != 0 RSP_RDP_Nothing(gfx); RDP_GFX_PopDL(); } } void DLParser_TexRect_Last_Legion(Gfx *gfx) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; if( !status.bCIBufferIsRendered ) g_pFrameBufferManager->ActiveTextureBuffer(); status.primitiveType = PRIM_TEXTRECT; // This command used 128bits, and not 64 bits. This means that we have to look one // Command ahead in the buffer, and update the PC. uint32_t dwPC = gDlistStack[gDlistStackPointer].pc; // This points to the next instruction uint32_t dwCmd2 = *(uint32_t *)(rdram_u8 + dwPC); uint32_t dwCmd3 = *(uint32_t *)(rdram_u8 + dwPC+4); gDlistStack[gDlistStackPointer].pc += 8; LOG_UCODE("0x%08x: %08x %08x", dwPC, *(uint32_t *)(rdram_u8 + dwPC+0), *(uint32_t *)(rdram_u8 + dwPC+4)); uint32_t dwXH = (((gfx->words.w0)>>12)&0x0FFF)/4; uint32_t dwYH = (((gfx->words.w0) )&0x0FFF)/4; uint32_t tileno = ((gfx->words.w1)>>24)&0x07; uint32_t dwXL = (((gfx->words.w1)>>12)&0x0FFF)/4; uint32_t dwYL = (((gfx->words.w1) )&0x0FFF)/4; if( (int)dwXL >= gRDP.scissor.right || (int)dwYL >= gRDP.scissor.bottom || (int)dwXH < gRDP.scissor.left || (int)dwYH < gRDP.scissor.top ) { // Clipping return; } uint16_t uS = (uint16_t)( dwCmd2>>16)&0xFFFF; uint16_t uT = (uint16_t)( dwCmd2 )&0xFFFF; short s16S = *(short*)(&uS); short s16T = *(short*)(&uT); uint16_t uDSDX = (uint16_t)(( dwCmd3>>16)&0xFFFF); uint16_t uDTDY = (uint16_t)(( dwCmd3 )&0xFFFF); short s16DSDX = *(short*)(&uDSDX); short s16DTDY = *(short*)(&uDTDY); uint32_t curTile = gRSP.curTile; ForceMainTextureIndex(tileno); float fS0 = s16S / 32.0f; float fT0 = s16T / 32.0f; float fDSDX = s16DSDX / 1024.0f; float fDTDY = s16DTDY / 1024.0f; uint32_t cycletype = gRDP.otherMode.cycle_type; if (cycletype == CYCLE_TYPE_COPY) { fDSDX /= 4.0f; // In copy mode 4 pixels are copied at once. dwXH++; dwYH++; } else if (cycletype == CYCLE_TYPE_FILL) { dwXH++; dwYH++; } if( fDSDX == 0 ) fDSDX = 1; if( fDTDY == 0 ) fDTDY = 1; float fS1 = fS0 + (fDSDX * (dwXH - dwXL)); float fT1 = fT0 + (fDTDY * (dwYH - dwYL)); LOG_UCODE(" Tile:%d Screen(%d,%d) -> (%d,%d)", tileno, dwXL, dwYL, dwXH, dwYH); LOG_UCODE(" Tex:(%#5f,%#5f) -> (%#5f,%#5f) (DSDX:%#5f DTDY:%#5f)", fS0, fT0, fS1, fT1, fDSDX, fDTDY); LOG_UCODE(""); float t0u0 = (fS0-gRDP.tiles[tileno].hilite_sl) * gRDP.tiles[tileno].fShiftScaleS; float t0v0 = (fT0-gRDP.tiles[tileno].hilite_tl) * gRDP.tiles[tileno].fShiftScaleT; float t0u1 = t0u0 + (fDSDX * (dwXH - dwXL))*gRDP.tiles[tileno].fShiftScaleS; float t0v1 = t0v0 + (fDTDY * (dwYH - dwYL))*gRDP.tiles[tileno].fShiftScaleT; if( dwXL==0 && dwYL==0 && dwXH==windowSetting.fViWidth-1 && dwYH==windowSetting.fViHeight-1 && t0u0 == 0 && t0v0==0 && t0u1==0 && t0v1==0 ) { //Using TextRect to clear the screen } else { if( status.bHandleN64RenderTexture && //status.bDirectWriteIntoRDRAM && g_pRenderTextureInfo->CI_Info.dwFormat == gRDP.tiles[tileno].dwFormat && g_pRenderTextureInfo->CI_Info.dwSize == gRDP.tiles[tileno].dwSize && gRDP.tiles[tileno].dwFormat == TXT_FMT_CI && gRDP.tiles[tileno].dwSize == TXT_SIZE_8b ) { if( options.enableHackForGames == HACK_FOR_YOSHI ) { // Hack for Yoshi background image PrepareTextures(); TexRectToFrameBuffer_8b(dwXL, dwYL, dwXH, dwYH, t0u0, t0v0, t0u1, t0v1, tileno); DEBUGGER_PAUSE_AT_COND_AND_DUMP_COUNT_N((eventToPause == NEXT_FLUSH_TRI || eventToPause == NEXT_TEXTRECT), { DebuggerAppendMsg("TexRect: tile=%d, X0=%d, Y0=%d, X1=%d, Y1=%d,\nfS0=%f, fT0=%f, ScaleS=%f, ScaleT=%f\n", gRSP.curTile, dwXL, dwYL, dwXH, dwYH, fS0, fT0, fDSDX, fDTDY); DebuggerAppendMsg("Pause after TexRect for Yoshi\n"); }); } else { if( frameBufferOptions.bUpdateCIInfo ) { PrepareTextures(); TexRectToFrameBuffer_8b(dwXL, dwYL, dwXH, dwYH, t0u0, t0v0, t0u1, t0v1, tileno); } if( !status.bDirectWriteIntoRDRAM ) { CRender::g_pRender->TexRect(dwXL, dwYL, dwXH, dwYH, fS0, fT0, fDSDX, fDTDY, false, 0xFFFFFFFF); status.dwNumTrisRendered += 2; } } } else { CRender::g_pRender->TexRect(dwXL, dwYL, dwXH, dwYH, fS0, fT0, fDSDX, fDTDY, false, 0xFFFFFFFF); status.bFrameBufferDrawnByTriangles = true; status.dwNumTrisRendered += 2; } } if( status.bHandleN64RenderTexture ) g_pRenderTextureInfo->maxUsedHeight = max(g_pRenderTextureInfo->maxUsedHeight,(int)dwYH); ForceMainTextureIndex(curTile); } #undef min #undef max libretro/SDL_mutex.h000664 001750 001750 00000000272 12655644434 015557 0ustar00sergiosergio000000 000000 #ifndef __FAKE_SDL_MUTEX_H__ #define __FAKE_SDL_MUTEX_H__ typedef int SDL_sem; #define SDL_CreateSemaphore(...) ((int*)1) #define SDL_SemTryWait(...) 0 #define SDL_SemPost(...) #endif glide2gl/src/Glide64/ucode00.h000664 001750 001750 00000036137 12655644434 017017 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** #include "GBI.h" static void rsp_vertex(int v0, int n) { uint32_t addr = RSP_SegmentToPhysical(rdp.cmd1); pre_update(); gSPVertex_G64(addr, n, v0); } // // uc0:vertex - loads vertices // static void uc0_vertex(uint32_t w0, uint32_t w1) { int v0 = _SHIFTR(w0, 16, 4); /* Current vertex */ int n = _SHIFTR(w0, 20, 4) + 1; /* Number of vertices to copy */ rsp_vertex(v0, n); } // ** Definitions ** static void modelview_load (float m[4][4]) { CopyMatrix(rdp.model, m, 64); // 4*4*4 (float) g_gdp.flags |= UPDATE_MULT_MAT | UPDATE_LIGHTS; } static void modelview_mul (float m[4][4]) { MulMatrices(m, rdp.model, rdp.model); g_gdp.flags |= UPDATE_MULT_MAT | UPDATE_LIGHTS; } static void modelview_push(void) { if (rdp.model_i == rdp.model_stack_size) return; CopyMatrix(rdp.model_stack[rdp.model_i++], rdp.model, 64); } static void modelview_load_push (float m[4][4]) { modelview_push(); modelview_load(m); } static void modelview_mul_push (float m[4][4]) { modelview_push(); modelview_mul (m); } static void projection_load (float m[4][4]) { CopyMatrix(rdp.proj, m, 64); // 4*4*4 (float) g_gdp.flags |= UPDATE_MULT_MAT; } static void projection_mul (float m[4][4]) { MulMatrices(m, rdp.proj, rdp.proj); g_gdp.flags |= UPDATE_MULT_MAT; } static void load_matrix (float m[4][4], uint32_t addr) { int x,y; // matrix index uint16_t *src = (uint16_t*)gfx_info.RDRAM; addr >>= 1; // Adding 4 instead of one, just to remove mult. later for (x = 0; x < 16; x += 4) { for (y=0; y<4; y++) m[x>>2][y] = (float)((((int32_t)src[(addr+x+y)^1]) << 16) | src[(addr+x+y+16)^1]) / 65536.0f; } } // // uc0:matrix - performs matrix operations // static void uc0_matrix(uint32_t w0, uint32_t w1) { DECLAREALIGN16VAR(m[4][4]); // Use segment offset to get the address uint32_t addr = RSP_SegmentToPhysical(w1); uint8_t command = (uint8_t)((w0 >> 16) & 0xFF); load_matrix(m, addr); switch (command) { case G_MTX_NOPUSH: // modelview mul nopush modelview_mul (m); break; case 1: // projection mul nopush case 5: // projection mul push, can't push projection projection_mul(m); break; case G_MTX_LOAD: // modelview load nopush modelview_load(m); break; case 3: // projection load nopush case 7: // projection load push, can't push projection projection_load(m); break; case 4: // modelview mul push modelview_mul_push(m); break; case 6: // modelview load push modelview_load_push(m); break; #if 0 default: FRDP_E ("Unknown matrix command, %02lx", command); FRDP ("Unknown matrix command, %02lx", command); #endif } } // uc0:movemem - loads a structure with data // static void uc0_movemem(uint32_t w0, uint32_t w1) { // Check the command switch (_SHIFTR( w0, 16, 8)) { case F3D_MV_VIEWPORT: gSPViewport_G64( w1 ); break; case G_MV_MATRIX_1: gSPForceMatrix_G64(w1); /* force matrix takes four commands */ rdp.pc[rdp.pc_i] += 24; break; case G_MV_L0: gSPLight_G64( w1, LIGHT_1 ); break; case G_MV_L1: gSPLight_G64( w1, LIGHT_2 ); break; case G_MV_L2: gSPLight_G64( w1, LIGHT_3 ); break; case G_MV_L3: gSPLight_G64( w1, LIGHT_4 ); break; case G_MV_L4: gSPLight_G64( w1, LIGHT_5 ); break; case G_MV_L5: gSPLight_G64( w1, LIGHT_6 ); break; case G_MV_L6: gSPLight_G64( w1, LIGHT_7 ); break; case G_MV_L7: gSPLight_G64( w1, LIGHT_8 ); break; case G_MV_LOOKATX: gSPLookAt_G64(w1, 0); break; case G_MV_LOOKATY: gSPLookAt_G64(w1, 1); break; } } // // uc0:displaylist - makes a call to another section of code // static void uc0_displaylist(uint32_t w0, uint32_t w1) { uint32_t addr = RSP_SegmentToPhysical(w1); /* This fixes partially Gauntlet: Legends */ if (addr == rdp.pc[rdp.pc_i] - 8) return; switch (_SHIFTR(w0, 16, 8)) { case G_DL_PUSH: if (rdp.pc_i >= 9) return; /* DL stack overflow */ rdp.pc_i++; // go to the next PC in the stack rdp.pc[rdp.pc_i] = addr; // jump to the address break; case G_DL_NOPUSH: rdp.pc[rdp.pc_i] = addr; // jump to the address break; } } // // tri1 - renders a triangle // static void uc0_tri1(uint32_t w0, uint32_t w1) { VERTEX *v[3]; v[0] = &rdp.vtx[_SHIFTR(w1, 16, 8) / 10]; v[1] = &rdp.vtx[_SHIFTR(w1, 8, 8) / 10]; v[2] = &rdp.vtx[_SHIFTR(w1, 0, 8) / 10]; cull_trianglefaces(v, 1, true, true, 0); } static void uc0_tri1_mischief(uint32_t w0, uint32_t w1) { VERTEX *v[3]; v[0] = &rdp.vtx[_SHIFTR(w1, 16, 8) / 10]; v[1] = &rdp.vtx[_SHIFTR(w1, 8, 8) / 10]; v[2] = &rdp.vtx[_SHIFTR(w1, 0, 8) / 10]; { int i; rdp.force_wrap = false; for (i = 0; i < 3; i++) { if (v[i]->ou < 0.0f || v[i]->ov < 0.0f) { rdp.force_wrap = true; break; } } } cull_trianglefaces(v, 1, true, true, 0); } // // uc0:enddl - ends a call made by uc0:displaylist // static void uc0_enddl(uint32_t w0, uint32_t w1) { gSPEndDisplayList_G64(); } static void uc0_culldl(uint32_t w0, uint32_t w1) { gSPCullDisplayList_G64( _SHIFTR( w0, 0, 24 ) / 40, (w1 / 40) - 1 ); } static void uc0_popmatrix(uint32_t w0, uint32_t w1) { gSPPopMatrix_G64( w1 ); } // // uc0:moveword - moves a word to someplace, like the segment pointers // static void uc0_moveword(uint32_t w0, uint32_t w1) { // Find which command this is (lowest byte of cmd0) switch (_SHIFTR( w0, 0, 8)) { case G_MW_MATRIX: break; case G_MW_NUMLIGHT: gSPNumLights_G64( ((w1 - 0x80000000) >> 5) - 1 ); break; case G_MW_CLIP: if (((w0 >> 8)&0xFFFF) == 0x04) { rdp.clip_ratio = (float)vi_integer_sqrt(w1); g_gdp.flags |= UPDATE_VIEWPORT; } break; case G_MW_SEGMENT: if ((w1 & BMASK)> 10) & 0x0F] = w1; break; case G_MW_FOG: gSPFogFactor_G64((int16_t)_SHIFTR(w1, 16, 16), (int16_t)_SHIFTR(w1, 0, 16)); break; case G_MW_LIGHTCOL: switch (_SHIFTR( w0, 8, 16 )) { case F3D_MWO_aLIGHT_1: gSPLightColor_G64( LIGHT_1, w1 ); break; case F3D_MWO_aLIGHT_2: gSPLightColor_G64( LIGHT_2, w1 ); break; case F3D_MWO_aLIGHT_3: gSPLightColor_G64( LIGHT_3, w1 ); break; case F3D_MWO_aLIGHT_4: gSPLightColor_G64( LIGHT_4, w1 ); break; case F3D_MWO_aLIGHT_5: gSPLightColor_G64( LIGHT_5, w1 ); break; case F3D_MWO_aLIGHT_6: gSPLightColor_G64( LIGHT_6, w1 ); break; case F3D_MWO_aLIGHT_7: gSPLightColor_G64( LIGHT_7, w1 ); break; case F3D_MWO_aLIGHT_8: gSPLightColor_G64( LIGHT_8, w1 ); break; } break; case G_MW_POINTS: { const uint32_t val = _SHIFTR(w0, 8, 16); gSPModifyVertex_G64(val / 40, val % 40, w1); } break; case G_MW_PERSPNORM: break; } } static void uc0_texture(uint32_t w0, uint32_t w1) { int tile = (w0 >> 8) & 0x07; if (tile == 7 && (settings.hacks&hack_Supercross)) tile = 0; //fix for supercross 2000 rdp.mipmap_level = (w0 >> 11) & 0x07; rdp.cur_tile = tile; rdp.tiles[tile].on = 0; if ((w0 & 0xFF)) { uint16_t s = (uint16_t)((w1 >> 16) & 0xFFFF); uint16_t t = (uint16_t)(w1 & 0xFFFF); rdp.tiles[tile].on = 1; rdp.tiles[tile].org_s_scale = s; rdp.tiles[tile].org_t_scale = t; rdp.tiles[tile].s_scale = (float)((s+1)/65536.0f) / 32.0f; rdp.tiles[tile].t_scale = (float)((t+1)/65536.0f) / 32.0f; g_gdp.flags |= UPDATE_TEXTURE; } } static void uc0_setothermode_h(uint32_t w0, uint32_t w1) { int i; int len = _SHIFTR(w0, 0, 8); int shift = _SHIFTR(w0, 8, 8); uint32_t mask = 0; if ((settings.ucode == ucode_F3DEX2) || (settings.ucode == ucode_CBFD)) shift = 32 - shift - (++len); i = len; for (; i; i--) mask = (mask << 1) | 1; mask <<= shift; rdp.cmd1 &= mask; rdp.othermode_h = (rdp.othermode_h & ~mask) | rdp.cmd1; if (mask & 0x00003000) // filter mode { rdp.filter_mode = (int)((rdp.othermode_h & 0x00003000) >> 12); g_gdp.flags |= UPDATE_TEXTURE; FRDP ("filter mode: %s\n", str_filter[rdp.filter_mode]); } if (mask & 0x0000C000) // tlut mode { rdp.tlut_mode = (uint8_t)((rdp.othermode_h & 0x0000C000) >> 14); FRDP ("tlut mode: %s\n", str_tlut[rdp.tlut_mode]); } if (mask & 0x00300000) // cycle type g_gdp.flags |= UPDATE_ZBUF_ENABLED; } static void uc0_setothermode_l(uint32_t w0, uint32_t w1) { int i; int len = _SHIFTR(w0, 0, 8); int shift = _SHIFTR(w0, 8, 8); uint32_t mask = 0; if ((settings.ucode == ucode_F3DEX2) || (settings.ucode == ucode_CBFD)) { shift = 32 - shift - (++len); if (shift < 0) shift = 0; } i = len; for (; i; i--) mask = (mask << 1) | 1; mask <<= shift; rdp.cmd1 &= mask; rdp.othermode_l = (rdp.othermode_l & ~mask) | rdp.cmd1; if (mask & RDP_ALPHA_COMPARE) // alpha compare g_gdp.flags |= UPDATE_ALPHA_COMPARE; if (mask & 0xFFFFFFF8) // rendermode / blender bits { g_gdp.flags |= UPDATE_FOG_ENABLED; //if blender has no fog bits, fog must be set off rdp.render_mode_changed |= rdp.rm ^ rdp.othermode_l; rdp.rm = rdp.othermode_l; if (settings.flame_corona && (rdp.rm == 0x00504341)) //hack for flame's corona rdp.othermode_l |= 0x00000010; FRDP ("rendermode: %08lx\n", rdp.othermode_l); // just output whole othermode_l } // there is not one setothermode_l that's not handled :) } static void uc0_setgeometrymode(uint32_t w0, uint32_t w1) { rdp.geom_mode |= w1; //FRDP("uc0:setgeometrymode %08lx; result: %08lx\n", w1, rdp.geom_mode); if (w1 & 0x00000001) // Z-Buffer enable { if (!(rdp.flags & ZBUF_ENABLED)) { rdp.flags |= ZBUF_ENABLED; g_gdp.flags |= UPDATE_ZBUF_ENABLED; } } if (w1 & 0x00001000) // Front culling { if (!(rdp.flags & CULL_FRONT)) { rdp.flags |= CULL_FRONT; g_gdp.flags |= UPDATE_CULL_MODE; } } if (w1 & 0x00002000) // Back culling { if (!(rdp.flags & CULL_BACK)) { rdp.flags |= CULL_BACK; g_gdp.flags |= UPDATE_CULL_MODE; } } //Added by Gonetz if (w1 & 0x00010000) // Fog enable { if (!(rdp.flags & FOG_ENABLED)) { rdp.flags |= FOG_ENABLED; g_gdp.flags |= UPDATE_FOG_ENABLED; } } } static void uc0_cleargeometrymode(uint32_t w0, uint32_t w1) { //FRDP("uc0:cleargeometrymode %08lx\n", w1); rdp.geom_mode &= ~w1; if (w1 & 0x00000001) // Z-Buffer enable { if (rdp.flags & ZBUF_ENABLED) { rdp.flags ^= ZBUF_ENABLED; g_gdp.flags |= UPDATE_ZBUF_ENABLED; } } if (w1 & 0x00001000) // Front culling { if (rdp.flags & CULL_FRONT) { rdp.flags ^= CULL_FRONT; g_gdp.flags |= UPDATE_CULL_MODE; } } if (w1 & 0x00002000) // Back culling { if (rdp.flags & CULL_BACK) { rdp.flags ^= CULL_BACK; g_gdp.flags |= UPDATE_CULL_MODE; } } //Added by Gonetz if (w1 & 0x00010000) // Fog enable { if (rdp.flags & FOG_ENABLED) { rdp.flags ^= FOG_ENABLED; g_gdp.flags |= UPDATE_FOG_ENABLED; } } } static void uc0_line3d(uint32_t w0, uint32_t w1) { VERTEX *v[3]; uint32_t v0 = ((w1 >> 16) & 0xff) / 10; uint32_t v1 = ((w1 >> 8) & 0xff) / 10; uint16_t width = (uint16_t)(w1 & 0xFF) + 3; uint32_t cull_mode = (rdp.flags & CULLMASK) >> CULLSHIFT; v[0] = &rdp.vtx[v1]; v[1] = &rdp.vtx[v0]; v[2] = &rdp.vtx[v0]; rdp.flags |= CULLMASK; g_gdp.flags |= UPDATE_CULL_MODE; cull_trianglefaces(v, 1, true, true, width); rdp.flags ^= CULLMASK; rdp.flags |= cull_mode << CULLSHIFT; g_gdp.flags |= UPDATE_CULL_MODE; } static void uc0_tri4(uint32_t w0, uint32_t w1) { // c0: 0000 0123, c1: 456789ab // becomes: 405 617 829 a3b VERTEX *v[12]; if (rdp.skip_drawing) return; v[0] = &rdp.vtx[_SHIFTR(w1, 28, 4)]; /* v00 */ v[1] = &rdp.vtx[_SHIFTR(w0, 12, 4)]; /* v01 */ v[2] = &rdp.vtx[_SHIFTR(w1, 24, 4)]; /* v02 */ v[3] = &rdp.vtx[_SHIFTR(w1, 20, 4)]; /* v10 */ v[4] = &rdp.vtx[_SHIFTR(w0, 8, 4)]; /* v11 */ v[5] = &rdp.vtx[_SHIFTR(w1, 16, 4)]; /* v12 */ v[6] = &rdp.vtx[_SHIFTR(w1, 12, 4)]; /* v20 */ v[7] = &rdp.vtx[_SHIFTR(w0, 4, 4)]; /* v21 */ v[8] = &rdp.vtx[_SHIFTR(w1, 8, 4)]; /* v22 */ v[9] = &rdp.vtx[_SHIFTR(w1, 4, 4)]; /* v30 */ v[10] = &rdp.vtx[_SHIFTR(w0, 0, 4)]; /* v31 */ v[11] = &rdp.vtx[_SHIFTR(w1, 0, 4)]; /* v32 */ cull_trianglefaces(v, 4, true, true, 0); } mupen64plus-video-gliden64/src/GLES2/UniformSet.cpp000664 001750 001750 00000012613 12655644434 023044 0ustar00sergiosergio000000 000000 #include "UniformSet.h" #include "../Config.h" #include "../Textures.h" #define LocateUniform2(A) \ location.A.loc = glGetUniformLocation(program, #A); void UniformSet::bindWithShaderCombiner(ShaderCombiner * _pCombiner) { const u64 mux = _pCombiner->getMux(); const GLuint program = _pCombiner->m_program; m_uniforms.emplace(mux, program); UniformSetLocation & location = m_uniforms.at(mux); // Texture parameters if (_pCombiner->usesTexture()) { LocateUniform2(uTexScale); LocateUniform2(uTexOffset[0]); LocateUniform2(uTexOffset[1]); LocateUniform2(uCacheScale[0]); LocateUniform2(uCacheScale[1]); LocateUniform2(uCacheOffset[0]); LocateUniform2(uCacheOffset[1]); LocateUniform2(uCacheShiftScale[0]); LocateUniform2(uCacheShiftScale[1]); LocateUniform2(uCacheFrameBuffer); LocateUniform2(uTextureSize[0]); LocateUniform2(uTextureSize[1]); _updateTextureUniforms(location, _pCombiner->usesTile(0), _pCombiner->usesTile(1), true); } // Colors LocateUniform2(uFogColor); LocateUniform2(uCenterColor); LocateUniform2(uScaleColor); LocateUniform2(uBlendColor); LocateUniform2(uEnvColor); LocateUniform2(uPrimColor); LocateUniform2(uPrimLod); LocateUniform2(uK4); LocateUniform2(uK5); _updateColorUniforms(location, true); // Lights if (config.generalEmulation.enableHWLighting != 0 && GBI.isHWLSupported() && _pCombiner->usesShadeColor()) { // locate lights uniforms char buf[32]; for (s32 i = 0; i < 8; ++i) { sprintf(buf, "uLightDirection[%d]", i); location.uLightDirection[i].loc = glGetUniformLocation(program, buf); sprintf(buf, "uLightColor[%d]", i); location.uLightColor[i].loc = glGetUniformLocation(program, buf); } _updateLightUniforms(location, true); } } void UniformSet::_updateColorUniforms(UniformSetLocation & _location, bool _bForce) { _location.uFogColor.set(&gDP.fogColor.r, _bForce); _location.uCenterColor.set(&gDP.key.center.r, _bForce); _location.uScaleColor.set(&gDP.key.scale.r, _bForce); _location.uBlendColor.set(&gDP.blendColor.r, _bForce); _location.uEnvColor.set(&gDP.envColor.r, _bForce); _location.uPrimColor.set(&gDP.primColor.r, _bForce); _location.uPrimLod.set(gDP.primColor.l, _bForce); _location.uK4.set(gDP.convert.k4*0.0039215689f, _bForce); _location.uK5.set(gDP.convert.k5*0.0039215689f, _bForce); } void UniformSet::_updateTextureUniforms(UniformSetLocation & _location, bool _bUsesT0, bool _bUsesT1, bool _bForce) { int nFB[2] = { 0, 0 }; const bool bUsesTile[2] = { _bUsesT0, _bUsesT1 }; TextureCache & cache = textureCache(); for (u32 t = 0; t < 2; ++t) { if (!bUsesTile[t]) continue; if (gSP.textureTile[t] != NULL) { if (gSP.textureTile[t]->textureMode == TEXTUREMODE_BGIMAGE || gSP.textureTile[t]->textureMode == TEXTUREMODE_FRAMEBUFFER_BG) _location.uTexOffset[t].set(0.0f, 0.0f, _bForce); else { float fuls = gSP.textureTile[t]->fuls; float fult = gSP.textureTile[t]->fult; FrameBuffer * pBuffer = gSP.textureTile[t]->frameBuffer; if (pBuffer != NULL) { if (gSP.textureTile[t]->masks > 0 && gSP.textureTile[t]->clamps == 0) fuls = float(gSP.textureTile[t]->uls % (1 << gSP.textureTile[t]->masks)); if (gSP.textureTile[t]->maskt > 0 && gSP.textureTile[t]->clampt == 0) fult = float(gSP.textureTile[t]->ult % (1 << gSP.textureTile[t]->maskt)); } _location.uTexOffset[t].set(fuls, fult, _bForce); } } if (cache.current[t] != NULL) { f32 shiftScaleS = 1.0f; f32 shiftScaleT = 1.0f; getTextureShiftScale(t, cache, shiftScaleS, shiftScaleT); _location.uCacheShiftScale[t].set(shiftScaleS, shiftScaleT, _bForce); _location.uCacheScale[t].set(cache.current[t]->scaleS, cache.current[t]->scaleT, _bForce); _location.uCacheOffset[t].set(cache.current[t]->offsetS, cache.current[t]->offsetT, _bForce); nFB[t] = cache.current[t]->frameBufferTexture; } } _location.uCacheFrameBuffer.set(nFB[0], nFB[1], _bForce); _location.uTexScale.set(gSP.texture.scales, gSP.texture.scalet, _bForce); } void UniformSet::_updateTextureSize(UniformSetLocation & _location, bool _bUsesT0, bool _bUsesT1, bool _bForce) { TextureCache & cache = textureCache(); if (_bUsesT0 && cache.current[0] != NULL) _location.uTextureSize[0].set((float)cache.current[0]->realWidth, (float)cache.current[0]->realHeight, _bForce); if (_bUsesT1 && cache.current[1] != NULL) _location.uTextureSize[1].set((float)cache.current[1]->realWidth, (float)cache.current[1]->realHeight, _bForce); } void UniformSet::_updateLightUniforms(UniformSetLocation & _location, bool _bForce) { for (s32 i = 0; i <= gSP.numLights; ++i) { _location.uLightDirection[i].set(&gSP.lights[i].x, _bForce); _location.uLightColor[i].set(&gSP.lights[i].r, _bForce); } } void UniformSet::updateUniforms(ShaderCombiner * _pCombiner, OGLRender::RENDER_STATE _renderState) { UniformSetLocation & location = m_uniforms.at(_pCombiner->getMux()); _updateColorUniforms(location, false); if ((_renderState == OGLRender::rsTriangle || _renderState == OGLRender::rsLine) && _pCombiner->usesTexture()) _updateTextureUniforms(location, _pCombiner->usesTile(0), _pCombiner->usesTile(1), false); if (_pCombiner->usesTexture()) _updateTextureSize(location, _pCombiner->usesTile(0), _pCombiner->usesTile(1), false); if (config.generalEmulation.enableHWLighting != 0 && GBI.isHWLSupported() && _pCombiner->usesShadeColor()) _updateLightUniforms(location, false); } UniformCollection * createUniformCollection() { return new UniformSet(); } mupen64plus-video-gliden64/licenses/gles2n64/000700 001750 001750 00000000000 12656647145 021777 5ustar00sergiosergio000000 000000 glide2gl/src/Glide64/glide64_3dmath.c000664 001750 001750 00000026771 12655644434 020254 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** #include "Gfx_1.3.h" #include "../../libretro/SDL.h" #include #include "3dmath.h" float DotProductC(float *v0, float *v1) { return v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2]; } void NormalizeVectorC(float *v) { float len = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; if (len == 0.0f) return; len = sqrtf( len ); v[0] /= len; v[1] /= len; v[2] /= len; } static void TransformVectorC(float *src, float *dst, float mat[4][4]) { dst[0] = mat[0][0]*src[0] + mat[1][0]*src[1] + mat[2][0]*src[2]; dst[1] = mat[0][1]*src[0] + mat[1][1]*src[1] + mat[2][1]*src[2]; dst[2] = mat[0][2]*src[0] + mat[1][2]*src[1] + mat[2][2]*src[2]; } void InverseTransformVectorC (float *src, float *dst, float mat[4][4]) { dst[0] = mat[0][0]*src[0] + mat[0][1]*src[1] + mat[0][2]*src[2]; dst[1] = mat[1][0]*src[0] + mat[1][1]*src[1] + mat[1][2]*src[2]; dst[2] = mat[2][0]*src[0] + mat[2][1]*src[1] + mat[2][2]*src[2]; } void MulMatricesC(float m1[4][4], float m2[4][4], float r[4][4]) { float row[4][4]; register unsigned int i, j; for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) row[i][j] = m2[i][j]; for (i = 0; i < 4; i++) { float summand[4][4]; for (j = 0; j < 4; j++) { summand[0][j] = m1[i][0] * row[0][j]; summand[1][j] = m1[i][1] * row[1][j]; summand[2][j] = m1[i][2] * row[2][j]; summand[3][j] = m1[i][3] * row[3][j]; } for (j = 0; j < 4; j++) r[i][j] = summand[0][j] + summand[1][j] + summand[2][j] + summand[3][j] ; } } // 2011-01-03 Balrog - removed because is in NASM format and not 64-bit compatible // This will need fixing. GLIDE64MULMATRIX glide64MulMatrices = MulMatricesC; GLIDE64TRANSFORMVECTOR glide64InverseTransformVector = InverseTransformVectorC; GLIDE64DOTPRODUCT glide64DotProduct = DotProductC; GLIDE64NORMALIZEVECTOR glide64NormalizeVector = NormalizeVectorC; // 2008.03.29 H.Morii - added SSE 3DNOW! 3x3 1x3 matrix multiplication // and 3DNOW! 4x4 4x4 matrix multiplication #if defined(__ARM_NEON__) static void NormalizeVectorNeon(float *v) { asm volatile ( "vld1.32 {d4}, [%0]! \n\t" //d4={x,y} "flds s10, [%0] \n\t" //d5[0] = z "sub %0, %0, #8 \n\t" //d5[0] = z "vmul.f32 d0, d4, d4 \n\t" //d0= d4*d4 "vpadd.f32 d0, d0, d0 \n\t" //d0 = d[0] + d[1] "vmla.f32 d0, d5, d5 \n\t" //d0 = d0 + d5*d5 "vmov.f32 d1, d0 \n\t" //d1 = d0 "vrsqrte.f32 d0, d0 \n\t" //d0 = ~ 1.0 / sqrt(d0) "vmul.f32 d2, d0, d1 \n\t" //d2 = d0 * d1 "vrsqrts.f32 d3, d2, d0 \n\t" //d3 = (3 - d0 * d2) / 2 "vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d3 "vmul.f32 d2, d0, d1 \n\t" //d2 = d0 * d1 "vrsqrts.f32 d3, d2, d0 \n\t" //d3 = (3 - d0 * d3) / 2 "vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d4 "vmul.f32 q2, q2, d0[0] \n\t" //d0= d2*d4 "vst1.32 {d4}, [%0]! \n\t" //d2={x0,y0}, d3={z0, w0} "fsts s10, [%0] \n\t" //d2={x0,y0}, d3={z0, w0} :"+r"(v) : : "d0", "d1", "d2", "d3", "d4", "d5", "memory" ); } static float DotProductNeon(float *v0, float *v1) { float dot; __asm( "vld1.32 {d8}, [%1]! \n\t" //d8={x0,y0} "vld1.32 {d10}, [%2]! \n\t" //d10={x1,y1} "flds s18, [%1, #0] \n\t" //d9[0]={z0} "flds s22, [%2, #0] \n\t" //d11[0]={z1} "vmul.f32 d12, d8, d10 \n\t" //d0= d2*d4 "vpadd.f32 d12, d12, d12 \n\t" //d0 = d[0] + d[1] "vmla.f32 d12, d9, d11 \n\t" //d0 = d0 + d3*d5 "fmrs %0, s24 \n\t" //r0 = s0 : "=r"(dot), "+r"(v0), "+r"(v1): : "d8", "d9", "d10", "d11", "d12" ); return dot; } void MulMatricesNeon(float m0[4][4],float m1[4][4],float dest[4][4]) { asm volatile ( "vld1.32 {d0, d1}, [%1]! \n\t" //q0 = m1 "vld1.32 {d2, d3}, [%1]! \n\t" //q1 = m1+4 "vld1.32 {d4, d5}, [%1]! \n\t" //q2 = m1+8 "vld1.32 {d6, d7}, [%1] \n\t" //q3 = m1+12 "vld1.32 {d16, d17}, [%0]! \n\t" //q8 = m0 "vld1.32 {d18, d19}, [%0]! \n\t" //q9 = m0+4 "vld1.32 {d20, d21}, [%0]! \n\t" //q10 = m0+8 "vld1.32 {d22, d23}, [%0] \n\t" //q11 = m0+12 "vmul.f32 q12, q8, d0[0] \n\t" //q12 = q8 * d0[0] "vmul.f32 q13, q8, d2[0] \n\t" //q13 = q8 * d2[0] "vmul.f32 q14, q8, d4[0] \n\t" //q14 = q8 * d4[0] "vmul.f32 q15, q8, d6[0] \n\t" //q15 = q8 * d6[0] "vmla.f32 q12, q9, d0[1] \n\t" //q12 = q9 * d0[1] "vmla.f32 q13, q9, d2[1] \n\t" //q13 = q9 * d2[1] "vmla.f32 q14, q9, d4[1] \n\t" //q14 = q9 * d4[1] "vmla.f32 q15, q9, d6[1] \n\t" //q15 = q9 * d6[1] "vmla.f32 q12, q10, d1[0] \n\t" //q12 = q10 * d0[0] "vmla.f32 q13, q10, d3[0] \n\t" //q13 = q10 * d2[0] "vmla.f32 q14, q10, d5[0] \n\t" //q14 = q10 * d4[0] "vmla.f32 q15, q10, d7[0] \n\t" //q15 = q10 * d6[0] "vmla.f32 q12, q11, d1[1] \n\t" //q12 = q11 * d0[1] "vmla.f32 q13, q11, d3[1] \n\t" //q13 = q11 * d2[1] "vmla.f32 q14, q11, d5[1] \n\t" //q14 = q11 * d4[1] "vmla.f32 q15, q11, d7[1] \n\t" //q15 = q11 * d6[1] "vst1.32 {d24, d25}, [%2]! \n\t" //d = q12 "vst1.32 {d26, d27}, [%2]! \n\t" //d+4 = q13 "vst1.32 {d28, d29}, [%2]! \n\t" //d+8 = q14 "vst1.32 {d30, d31}, [%2] \n\t" //d+12 = q15 :"+r"(m1), "+r"(m0), "+r"(dest): : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", "memory" ); } #endif void math_init(void) { unsigned cpu = 0; if (perf_get_cpu_features_cb) cpu = perf_get_cpu_features_cb(); #if defined(__ARM_NEON__) if (cpu & RETRO_SIMD_NEON) { glide64NormalizeVector = NormalizeVectorNeon; glide64MulMatrices = MulMatricesNeon; glide64DotProduct = DotProductNeon; if (log_cb) log_cb(RETRO_LOG_INFO, "NEON detected, using (some) optimized math functions.\n"); } #endif } void calc_light (VERTEX *v) { uint32_t i; float color[3]; float light_intensity = 0.0f; color[0] = rdp.light[rdp.num_lights].col[0]; color[1] = rdp.light[rdp.num_lights].col[1]; color[2] = rdp.light[rdp.num_lights].col[2]; for (i = 0; i < rdp.num_lights; i++) { light_intensity = DotProduct (rdp.light_vector[i], v->vec); if (light_intensity > 0.0f) { color[0] += rdp.light[i].col[0] * light_intensity; color[1] += rdp.light[i].col[1] * light_intensity; color[2] += rdp.light[i].col[2] * light_intensity; } } v->r = (uint8_t)(255.0f * get_float_color_clamped(color[0])); v->g = (uint8_t)(255.0f * get_float_color_clamped(color[1])); v->b = (uint8_t)(255.0f * get_float_color_clamped(color[2])); } void calc_linear (VERTEX *v) { DECLAREALIGN16VAR(vec[3]); float x, y; if (settings.force_calc_sphere) { calc_sphere(v); return; } TransformVectorC(v->vec, vec, rdp.model); NormalizeVector (vec); x = vec[0]; y = vec[1]; if (rdp.use_lookat) { x = DotProduct (rdp.lookat[0], vec); y = DotProduct (rdp.lookat[1], vec); } if (x > 1.0f) x = 1.0f; else if (x < -1.0f) x = -1.0f; if (y > 1.0f) y = 1.0f; else if (y < -1.0f) y = -1.0f; if (rdp.cur_cache[0]) { // scale >> 6 is size to map to v->ou = (acosf(x)/3.141592654f) * (rdp.tiles[rdp.cur_tile].org_s_scale >> 6); v->ov = (acosf(y)/3.141592654f) * (rdp.tiles[rdp.cur_tile].org_t_scale >> 6); } v->uv_scaled = 1; #ifdef EXTREME_LOGGING FRDP ("calc linear u: %f, v: %f\n", v->ou, v->ov); #endif } void calc_sphere (VERTEX *v) { DECLAREALIGN16VAR(vec[3]); float x, y; int s_scale, t_scale; s_scale = rdp.tiles[rdp.cur_tile].org_s_scale >> 6; t_scale = rdp.tiles[rdp.cur_tile].org_t_scale >> 6; if (settings.hacks&hack_Chopper) { s_scale = min(rdp.tiles[rdp.cur_tile].org_s_scale >> 6, g_gdp.tile[rdp.cur_tile].sl); t_scale = min(rdp.tiles[rdp.cur_tile].org_t_scale >> 6, g_gdp.tile[rdp.cur_tile].tl); } TransformVectorC(v->vec, vec, rdp.model); NormalizeVector (vec); x = vec[0]; y = vec[1]; if (rdp.use_lookat) { x = DotProduct (rdp.lookat[0], vec); y = DotProduct (rdp.lookat[1], vec); } v->ou = (x * 0.5f + 0.5f) * s_scale; v->ov = (y * 0.5f + 0.5f) * t_scale; v->uv_scaled = 1; #ifdef EXTREME_LOGGING FRDP ("calc sphere u: %f, v: %f\n", v->ou, v->ov); #endif } mupen64plus-video-gliden64/src/GLideNHQ/TxQuantize.h000664 001750 001750 00000005260 12655644434 023251 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __TXQUANTIZE_H__ #define __TXQUANTIZE_H__ #include "TxInternal.h" #include "TxUtil.h" class TxQuantize { private: TxUtil *_txUtil; int _numcore; /* fast optimized... well, sort of. */ void ARGB1555_ARGB8888(uint32* src, uint32* dst, int width, int height); void ARGB4444_ARGB8888(uint32* src, uint32* dst, int width, int height); void RGB565_ARGB8888(uint32* src, uint32* dst, int width, int height); void A8_ARGB8888(uint32* src, uint32* dst, int width, int height); void AI44_ARGB8888(uint32* src, uint32* dst, int width, int height); void AI88_ARGB8888(uint32* src, uint32* dst, int width, int height); void ARGB8888_ARGB1555(uint32* src, uint32* dst, int width, int height); void ARGB8888_ARGB4444(uint32* src, uint32* dst, int width, int height); void ARGB8888_RGB565(uint32* src, uint32* dst, int width, int height); void ARGB8888_A8(uint32* src, uint32* dst, int width, int height); void ARGB8888_AI44(uint32* src, uint32* dst, int width, int height); void ARGB8888_AI88(uint32* src, uint32* dst, int width, int height); /* quality */ void ARGB8888_RGB565_ErrD(uint32* src, uint32* dst, int width, int height); void ARGB8888_ARGB1555_ErrD(uint32* src, uint32* dst, int width, int height); void ARGB8888_ARGB4444_ErrD(uint32* src, uint32* dst, int width, int height); void ARGB8888_AI44_ErrD(uint32* src, uint32* dst, int width, int height); void ARGB8888_AI88_Slow(uint32* src, uint32* dst, int width, int height); void ARGB8888_I8_Slow(uint32* src, uint32* dst, int width, int height); public: TxQuantize(); ~TxQuantize(); /* others */ void P8_16BPP(uint32* src, uint32* dst, int width, int height, uint32* palette); boolean quantize(uint8* src, uint8* dest, int width, int height, uint16 srcformat, uint16 destformat, boolean fastQuantizer = 1); }; #endif /* __TXQUANTIZE_H__ */ mupen64plus-core/src/r4300/000700 001750 001750 00000000000 12656647145 016375 5ustar00sergiosergio000000 000000 mupen64plus-video-gliden64/src/DepthBuffer.h000664 001750 001750 00000003261 12655644434 021777 0ustar00sergiosergio000000 000000 #ifndef DEPTHBUFFER_H #define DEPTHBUFFER_H #include "Types.h" #include "Textures.h" struct DepthBuffer { DepthBuffer(); DepthBuffer(DepthBuffer && _other); ~DepthBuffer(); void initDepthImageTexture(FrameBuffer * _pBuffer); void initDepthBufferTexture(FrameBuffer * _pBuffer); CachedTexture * resolveDepthBufferTexture(FrameBuffer * _pBuffer); void setDepthAttachment(GLenum _target); void activateDepthBufferTexture(FrameBuffer * _pBuffer); void bindDepthImageTexture(); u32 m_address, m_width; u32 m_uly, m_lry; // Top and bottom bounds of fillrect command. GLuint m_FBO; CachedTexture *m_pDepthImageTexture; CachedTexture *m_pDepthBufferTexture; bool m_cleared; // multisampling CachedTexture *m_pResolveDepthBufferTexture; bool m_resolved; private: void _initDepthBufferTexture(FrameBuffer * _pBuffer, CachedTexture *_pTexture, bool _multisample); }; class DepthBufferList { public: void init(); void destroy(); void saveBuffer(u32 _address); void removeBuffer(u32 _address); void clearBuffer(u32 _uly, u32 _lry); void setNotCleared(); DepthBuffer *findBuffer(u32 _address); DepthBuffer * getCurrent() const {return m_pCurrent;} static DepthBufferList & get(); const u16 * const getZLUT() const {return m_pzLUT;} private: DepthBufferList(); DepthBufferList(const DepthBufferList &); ~DepthBufferList(); typedef std::list DepthBuffers; DepthBuffers m_list; DepthBuffer *m_pCurrent; u16 * m_pzLUT; }; inline DepthBufferList & depthBufferList() { return DepthBufferList::get(); } extern const GLuint ZlutImageUnit; extern const GLuint TlutImageUnit; extern const GLuint depthImageUnit; void DepthBuffer_Init(); void DepthBuffer_Destroy(); #endif gles2rice/src/RSP_Parser.cpp000664 001750 001750 00000213330 12655644434 017053 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "ConvertImage.h" #include "GraphicsContext.h" #include "Render.h" #include "RenderTexture.h" #include "Video.h" #include "ucode.h" #include #ifdef _MSC_VER #define strncasecmp _strnicmp #endif ////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////// // uCode Config // ////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////// #define MAX_UCODE_INFO 16 UcodeInfo ucodeInfo[MAX_UCODE_INFO]; RDPInstruction LoadedUcodeMap[256]; char* LoadedUcodeNameMap[256]; OSTask *g_pOSTask = NULL; UcodeInfo lastUcodeInfo; UcodeInfo UsedUcodes[MAX_UCODE_INFO]; const uint32_t maxUsedUcodes = sizeof(UsedUcodes)/sizeof(UcodeInfo); ////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////// // Ucodes // ////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////// UcodeMap *ucodeMaps[] = { &ucodeMap0, // ucode 0 - Mario &ucodeMap1, // ucode 1 - GBI1 NULL, // ucode 2 - Golden Eye &ucodeMap3, // ucode 3 - S2DEX GBI2 NULL, // ucode 4 - Wave Racer &ucodeMap5, // ucode 5 - BGI2 NULL, // ucode 6 - DKR &ucodeMap7, // ucode 7 - S2DEX NULL, // ucode 8 - ucode 0 with sprite2D, for Demo Puzzle Master 64 NULL, // ucode 9 - Perfect Dark NULL, // ucode 10 - Conker NULL, // ucode 11 - Gemini NULL, // ucode 12 - Silicon Valley, Spacestation NULL, // ucode 13 - modified ucode S2DEX NULL, // ucode 14 - OgreBattle Background NULL, // ucode 15 - ucode 0 with sprite2D NULL, // ucode 16 - Star War, Shadow of Empire NULL, // ucode 17 - Star Wars - Rogue Squadron, NULL, // ucode 18 - World Driver Championship NULL, // ucode 19 - Last Legion UX &ucodeMap1, // ucode 20 - ZSortp }; uint32_t vertexMultVals[] = { 10, // ucode 0 - Mario 2, // ucode 1 - GBI1 10, // ucode 2 - Golden Eye 2, // ucode 3 - S2DEX GBI2 5, // ucode 4 - Wave Racer 2, // ucode 5 - BGI2 10, // ucode 6 - DKR 2, // ucode 7 - S2DEX 10, // ucode 8 - ucode 0 with sprite2D, for Demo Puzzle Master 64 10, // ucode 9 - Perfect Dark 2, // ucode 10 - Conker 10, // ucode 11 - Gemini 2, // ucode 12 - Silicon Valley, Spacestation 2, // ucode 13 - modified ucode S2DEX 2, // ucode 14 - OgreBattle Background 10, // ucode 15 - ucode 0 with sprite2D 5, // ucode 16 - Star War, Shadow of Empire 2, // ucode 17 - Star Wars - Rogue Squadron, 2, // ucode 18 - World Driver Championship, check me here 2, // ucode 19 - Last Legion UX, check me here 2, // ucode 20 - ZSortp }; unsigned char gLastMicrocodeString[ 300 ] = ""; //***************************************************************************** // //***************************************************************************** static UcodeData g_UcodeData[] = { //crc_size, crc_800; {0, 0x150c3ce8, 0x150c3ce8, (unsigned char*)"RSP SW Version: 2.0D, 04-01-96",}, // Super Mario 64 {4, 0x2b94276f, 0x2b94276f, (unsigned char*)"RSP SW Version: 2.0D, 04-01-96",}, // Wave Race 64 (v1.0) {16,0xb1870454, 0xb1870454, (unsigned char*)"RSP SW Version: 2.0D, 04-01-96",}, // Star Wars - Shadows of the Empire (v1.0), {0, 0x51671ae4, 0x51671ae4, (unsigned char*)"RSP SW Version: 2.0D, 04-01-96",}, // Pilot Wings 64, {0, 0x67b5ac55, 0x67b5ac55, (unsigned char*)"RSP SW Version: 2.0D, 04-01-96",}, // Wibble, {0, 0x64dc8104, 0x64dc8104, (unsigned char*)"RSP SW Version: 2.0D, 04-01-96",}, // Dark Rift, {0, 0x309f363d, 0x309f363d, (unsigned char*)"RSP SW Version: 2.0D, 04-01-96",}, // Killer Instinct Gold, {0, 0xfcb57e57, 0xfcb57e57, (unsigned char*)"RSP SW Version: 2.0D, 04-01-96",}, // Blast Corps, {0, 0xb420f35a, 0xb420f35a, (unsigned char*)"RSP SW Version: 2.0D, 04-01-96",}, // Blast Corps, {0, 0x6e26c1df, 0x7c98e9c2, (unsigned char*)"RSP SW Version: 2.0D, 04-01-96",}, {2, 0xc02ac7bc, 0xc02ac7bc, (unsigned char*)"RSP SW Version: 2.0G, 09-30-96",}, // GoldenEye 007, {0, 0xe5fee3bc, 0xe5fee3bc, (unsigned char*)"RSP SW Version: 2.0G, 09-30-96",}, // Aero Fighters Assault, {8, 0xe4bb5ad8, 0x80129845, (unsigned char*)"RSP SW Version: 2.0G, 09-30-96",}, // Puzzle Master 64, {0, 0x72109ec6, 0x72109ec6, (unsigned char*)"RSP SW Version: 2.0H, 02-12-97",}, // Duke Nukem 64, {0, 0xf24a9a04, 0xf24a9a04, (unsigned char*)"RSP SW Version: 2.0H, 02-12-97",}, // Tetrisphere, {15,0x700de42e, 0x700de42e, (unsigned char*)"RSP SW Version: 2.0H, 02-12-97",}, // Wipeout 64 (uses GBI1 too!), {15,0x1b304a74, 0x1b304a74, (unsigned char*)"RSP SW Version: 2.0H, 02-12-97",}, // Flying Dragon, {15,0xe4bb5ad8, 0xa7b2f704, (unsigned char*)"RSP SW Version: 2.0H, 02-12-97",}, // Silicon Valley, {15,0xe4bb5ad8, 0x88202781, (unsigned char*)"RSP SW Version: 2.0H, 02-12-97",}, // Glover, {0, 0xe466b5bd, 0xe466b5bd, (unsigned char*)"Unknown 0xe466b5bd, 0xe466b5bd",}, // Dark Rift, {9, 0x7064a163, 0x7064a163, (unsigned char*)"Unknown 0x7064a163, 0x7064a163",}, // Perfect Dark (v1.0), {0, 0x6522df69, 0x71bd078d, (unsigned char*)"Unknown 0x6522df69, 0x71bd078d",}, // Tetris {0, 0x6522df69, 0x1b0c23a8, (unsigned char*)"Unknown 0x6522df69, 0x1b0c23a8",}, // Pachinko Nichi // GBI1 {1, 0x45ca328e, 0x45ca328e, (unsigned char*)"RSP Gfx ucode F3DLX 0.95 Yoshitaka Yasumoto Nintendo.",}, // Mario Kart 64, {1, 0x98e3b909, 0x98e3b909, (unsigned char*)"RSP Gfx ucode F3DEX 0.95 Yoshitaka Yasumoto Nintendo.",}, // Mario Kart 64 {1, 0x5d446090, 0x5d446090, (unsigned char*)"RSP Gfx ucode F3DLP.Rej 0.96 Yoshitaka Yasumoto Nintendo.",0,1}, // Jikkyou J. League Perfect Striker, {1, 0x244f5ca3, 0x244f5ca3, (unsigned char*)"RSP Gfx ucode F3DEX 1.00 Yoshitaka Yasumoto Nintendo.",}, // F-1 Pole Position 64, {1, 0x6a022585, 0x6a022585, (unsigned char*)"RSP Gfx ucode F3DEX.NoN 1.00 Yoshitaka Yasumoto Nintendo.",1}, // Turok - The Dinosaur Hunter (v1.0), {1, 0x150706be, 0x150706be, (unsigned char*)"RSP Gfx ucode F3DLX.NoN 1.00 Yoshitaka Yasumoto Nintendo.",1}, // Extreme-G, {1, 0x503f2c53, 0x503f2c53, (unsigned char*)"RSP Gfx ucode F3DEX.NoN 1.21 Yoshitaka Yasumoto Nintendo.",1}, // Bomberman 64, {1, 0xc705c37c, 0xc705c37c, (unsigned char*)"RSP Gfx ucode F3DLX 1.21 Yoshitaka Yasumoto Nintendo.",}, // Fighting Force 64, Wipeout 64 {1, 0xa2146075, 0xa2146075, (unsigned char*)"RSP Gfx ucode F3DLX.NoN 1.21 Yoshitaka Yasumoto Nintendo.",1}, // San Francisco Rush - Extreme Racing, {1, 0xb65aa2da, 0xb65aa2da, (unsigned char*)"RSP Gfx ucode L3DEX 1.21 Yoshitaka Yasumoto Nintendo.",}, // Wipeout 64, {1, 0x0c8e5ec9, 0x0c8e5ec9, (unsigned char*)"RSP Gfx ucode F3DEX 1.21 Yoshitaka Yasumoto Nintendo.",}, // {1, 0xe30795f2, 0xa53df3c4, (unsigned char*)"RSP Gfx ucode F3DLP.Rej 1.21 Yoshitaka Yasumoto Nintendo.",0,1}, {1, 0xaebeda7d, 0xaebeda7d, (unsigned char*)"RSP Gfx ucode F3DLX.Rej 1.21 Yoshitaka Yasumoto Nintendo.",0,1}, // Jikkyou World Soccer 3, {1, 0x0c8e5ec9, 0x0c8e5ec9, (unsigned char*)"RSP Gfx ucode F3DEX 1.23 Yoshitaka Yasumoto Nintendo" ,}, // Wave Race 64 (Rev. 2) - Shindou Rumble Edition (JAP) {1, 0xc705c37c, 0xc705c37c, (unsigned char*)"RSP Gfx ucode F3DLX 1.23 Yoshitaka Yasumoto Nintendo.",}, // GT {1, 0x2a61350d, 0x2a61350d, (unsigned char*)"RSP Gfx ucode F3DLX 1.23 Yoshitaka Yasumoto Nintendo.",}, // Toy Story2 {1, 0x0c8e5ec9, 0x0c8e5ec9, (unsigned char*)"RSP Gfx ucode F3DEX 1.23 Yoshitaka Yasumoto Nintendo.",}, // Wave Race 64 Shindou Edition {12,0xfc6529aa, 0xfc6529aa, (unsigned char*)"RSP Gfx ucode F3DEX 1.23 Yoshitaka Yasumoto Nintendo.",}, // Superman - The Animated Series, {1, 0xa56cf996, 0xa56cf996, (unsigned char*)"RSP Gfx ucode L3DEX 1.23 Yoshitaka Yasumoto Nintendo.",}, // Flying Dragon, {1, 0xcc83b43f, 0xcc83b43f, (unsigned char*)"RSP Gfx ucode F3DEX.NoN 1.23 Yoshitaka Yasumoto Nintendo.",1}, // AeroGauge, {1, 0xca8927a0, 0xca8927a0, (unsigned char*)"RSP Gfx ucode F3DLX.Rej 1.23 Yoshitaka Yasumoto Nintendo.",0,1}, // Puzzle Bobble 64, {1, 0x25689c75, 0xbe481ae8, (unsigned char*)"RSP Gfx ucode F3DLP.Rej 1.23 Yoshitaka Yasumoto Nintendo.",0,1}, {1, 0xd2d747b7, 0xd2d747b7, (unsigned char*)"RSP Gfx ucode F3DLX.NoN 1.23 Yoshitaka Yasumoto Nintendo.",1}, // Penny Racers, {1, 0xa849c858, 0x5bd32b5a, (unsigned char*)"RSP Gfx ucode F3DTEX/A 1.23 Yoshitaka Yasumoto Nintendo.",}, // Tamagotchi {7, 0xecd8b772, 0xecd8b772, (unsigned char*)"RSP Gfx ucode S2DEX 1.06 Yoshitaka Yasumoto Nintendo.",}, // Yoshi's Story, {7, 0xf59132f5, 0xf59132f5, (unsigned char*)"RSP Gfx ucode S2DEX 1.07 Yoshitaka Yasumoto Nintendo.",}, // Bakuretsu Muteki Bangaioh, {7, 0x961dd811, 0x961dd811, (unsigned char*)"RSP Gfx ucode S2DEX 1.03 Yoshitaka Yasumoto Nintendo.",}, // GT {5, 0x3e083afa, 0x722f97cc, (unsigned char*)"RSP Gfx ucode F3DEX.NoN fifo 2.03 Yoshitaka Yasumoto 1998 Nintendo.",1}, // F-Zero X, {5, 0xa8050bd1, 0xa8050bd1, (unsigned char*)"RSP Gfx ucode F3DEX fifo 2.03 Yoshitaka Yasumoto 1998 Nintendo.",}, // F-Zero X, {5, 0x4e8055f0, 0x4e8055f0, (unsigned char*)"RSP Gfx ucode F3DLX.Rej fifo 2.03 Yoshitaka Yasumoto 1998 Nintendo.",0,1}, // F-Zero X, {5, 0xabf001f5, 0xabf001f5, (unsigned char*)"RSP Gfx ucode F3DFLX.Rej fifo 2.03F Yoshitaka Yasumoto 1998 Nintendo.",0,1}, // F-Zero X, {5, 0xadb4b686, 0xadb4b686, (unsigned char*)"RSP Gfx ucode F3DEX fifo 2.04 Yoshitaka Yasumoto 1998 Nintendo.",}, // Top Gear Rally 2, {5, 0x779e2a9b, 0x779e2a9b, (unsigned char*)"RSP Gfx ucode F3DEX.NoN fifo 2.04 Yoshitaka Yasumoto 1998 Nintendo.",1}, // California Speed, {5, 0xa8cb3e09, 0xa8cb3e09, (unsigned char*)"RSP Gfx ucode L3DEX fifo 2.04 Yoshitaka Yasumoto 1998 Nintendo.",}, // In-Fisherman Bass Hunter 64, {5, 0x2a1341d6, 0x2a1341d6, (unsigned char*)"RSP Gfx ucode F3DEX fifo 2.04H Yoshitaka Yasumoto 1998 Nintendo.",}, // Kirby 64 - The Crystal Shards, {5, 0x3e083afa, 0x89a8e0ed, (unsigned char*)"RSP Gfx ucode F3DEX.NoN fifo 2.05 Yoshitaka Yasumoto 1998 Nintendo.",1}, // Carmageddon 64 (uncensored), {5, 0x4964b75d, 0x4964b75d, (unsigned char*)"RSP Gfx ucode F3DEX.NoN fifo 2.05 Yoshitaka Yasumoto 1998 Nintendo.",1}, {5, 0x39e3e95a, 0x39e3e95a, (unsigned char*)"RSP Gfx ucode F3DEX fifo 2.05 Yoshitaka Yasumoto 1998 Nintendo."}, // Knife Edge - Nose Gunner, {5, 0xd2913522, 0xd2913522, (unsigned char*)"RSP Gfx ucode F3DAM fifo 2.05 Yoshitaka Yasumoto 1998 Nintendo."}, // Hey You, Pikachu!, {5, 0x3e083afa, 0xc998443f, (unsigned char*)"RSP Gfx ucode F3DEX xbus 2.05 Yoshitaka Yasumoto 1998 Nintendo."}, //Triple play {5, 0xf4184a7d, 0xf4184a7d, (unsigned char*)"RSP Gfx ucode F3DEX fifo 2.06 Yoshitaka Yasumoto 1998 Nintendo.",}, // Hey You, Pikachu!, {5, 0x595a88de, 0x595a88de, (unsigned char*)"RSP Gfx ucode F3DEX.Rej fifo 2.06 Yoshitaka Yasumoto 1998 Nintendo.",0,1}, // Bio Hazard 2, {5, 0x0259f764, 0x0259f764, (unsigned char*)"RSP Gfx ucode F3DLX.Rej fifo 2.06 Yoshitaka Yasumoto 1998 Nintendo.",0,1}, // Mario Party, {5, 0xe1a5477a, 0xe1a5477a, (unsigned char*)"RSP Gfx ucode F3DEX.NoN xbus 2.06 Yoshitaka Yasumoto 1998 Nintendo.",1}, // Command & Conquer, {5, 0x4cfa0a19, 0x4cfa0a19, (unsigned char*)"RSP Gfx ucode F3DZEX.NoN fifo 2.06H Yoshitaka Yasumoto 1998 Nintendo.",1}, // The Legend of Zelda - Ocarina of Time (v1.0), {5, 0x2cbd9514, 0x5f40b9f5, (unsigned char*)"RSP Gfx ucode F3DZEX.NoN fifo 2.06H Yoshitaka Yasumoto 1998 Nintendo.",1}, {5, 0x3e083afa, 0x882680f4, (unsigned char*)"RSP Gfx ucode L3DEX fifo 2.07 Yoshitaka Yasumoto 1998 Nintendo."}, // Polaris Sno {5, 0xdeb1cac0, 0xdeb1cac0, (unsigned char*)"RSP Gfx ucode F3DEX.NoN fifo 2.07 Yoshitaka Yasumoto 1998 Nintendo.",1}, // Knockout Kings 2000, {5, 0xf4184a7d, 0xf4184a7d, (unsigned char*)"RSP Gfx ucode F3DEX fifo 2.07 Yoshitaka Yasumoto 1998 Nintendo.",}, // Xena Warrior Princess - Talisman of Fate, Army Men - Air Combat, Destruction Derby {5, 0x4b013e60, 0x4b013e60, (unsigned char*)"RSP Gfx ucode F3DEX xbus 2.07 Yoshitaka Yasumoto 1998 Nintendo.",}, // Lode Runner 3-D, {5, 0xd1a63836, 0xd1a63836, (unsigned char*)"RSP Gfx ucode L3DEX fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // Hey You, Pikachu!, {5, 0x97193667, 0x97193667, (unsigned char*)"RSP Gfx ucode F3DEX fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // Top Gear Hyper-Bike, {5, 0x92149ba8, 0x92149ba8, (unsigned char*)"RSP Gfx ucode F3DEX fifo 2.08 Yoshitaka Yasumoto/Kawasedo 1999.",}, // Paper Mario, {5, 0xae0fb88f, 0xae0fb88f, (unsigned char*)"RSP Gfx ucode F3DEX xbus 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // WWF WrestleMania 2000, {5, 0xc572f368, 0xc572f368, (unsigned char*)"RSP Gfx ucode F3DLX.Rej xbus 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // WWF No Mercy, {5, 0x3e083afa, 0x74252492, (unsigned char*)"RSP Gfx ucode F3DEX.NoN xbus 2.08 Yoshitaka Yasumoto 1999 Nintendo.",1}, {5, 0x9c2edb70, 0xea98e740, (unsigned char*)"RSP Gfx ucode F3DEX.NoN fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",1}, // LEGO Racers, {5, 0x79e004a6, 0x79e004a6, (unsigned char*)"RSP Gfx ucode F3DLX.Rej fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",0,1}, // Mario Party 2, {5, 0xaa6ab3ca, 0xaa6ab3ca, (unsigned char*)"RSP Gfx ucode F3DEX.Rej fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",0,1}, // V-Rally Edition 99, {5, 0x2c597e0f, 0x2c597e0f, (unsigned char*)"RSP Gfx ucode F3DEX fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // Cruis'n Exotica, {10, 0x4e5f3e3b, 0x4e5f3e3b,(unsigned char*)"RSP Gfx ucode F3DEXBG.NoN fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",1}, // Conker The Bad Fur Day {5, 0x61f31862, 0x61f31862, (unsigned char*)"RSP Gfx ucode F3DEX.NoN fifo 2.08H Yoshitaka Yasumoto 1999 Nintendo.",1}, // Pokemon Snap, {5, 0x005f5b71, 0x005f5b71, (unsigned char*)"RSP Gfx ucode F3DZEX.NoN fifo 2.08I Yoshitaka Yasumoto/Kawasedo 1999.",1}, // The Legend of Zelda 2 - Majora's Mask, {3, 0x41839d1e, 0x41839d1e, (unsigned char*)"RSP Gfx ucode S2DEX fifo 2.05 Yoshitaka Yasumoto 1998 Nintendo.",}, // Chou Snobow Kids, {3, 0x2cbd9514, 0xc639dbb9, (unsigned char*)"RSP Gfx ucode S2DEX xbus 2.06 Yoshitaka Yasumoto 1998 Nintendo.",}, {3, 0xec89e273, 0xec89e273, (unsigned char*)"RSP Gfx ucode S2DEX fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // V-Rally Edition 99, {3, 0x9429b7d6, 0x9429b7d6, (unsigned char*)"RSP Gfx ucode S2DEX xbus 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // Star Craft, //{14,0x5a72397b, 0xec89e273, "RSP Gfx ucode S2DEX fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // OgreBattle Background, {3, 0x2cbd9514, 0xec89e273, (unsigned char*)"RSP Gfx ucode S2DEX fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // Zelda MM, {6, 0x6aef74f8, 0x6aef74f8, (unsigned char*)"Unknown 0x6aef74f8, 0x6aef74f8",}, // Diddy Kong Racing (v1.0), {6, 0x4c4eead8, 0x4c4eead8, (unsigned char*)"Unknown 0x4c4eead8, 0x4c4eead8",}, // Diddy Kong Racing (v1.1), {1, 0xed421e9a, 0xed421e9a, (unsigned char*)"Unknown 0xed421e9a, 0xed421e9a",}, // Kuiki Uhabi Suigo, {5, 0x37751932, 0x55c0fd25, (unsigned char*)"Unknown 0x37751932, 0x55c0fd25",}, // Bio Hazard 2, {11,0xbe0b83e7, 0xbe0b83e7,(unsigned char*)"Unknown 0xbe0b83e7, 0xbe0b83e7",}, // Jet Force Gemini, {17, 0x02e882cf, 0x2ad17281, (unsigned char*)"Unknown 0x02e882cf, 0x2ad17281",}, // Indiana Jones, {17, 0x1f7d9118, 0xdab2199b, (unsigned char*)"Unknown 0x1f7d9118, 0xdab2199b",}, // Battle Naboo, {17, 0x74583614, 0x74583614, (unsigned char*)"Unknown 0x74583614, 0x74583614",}, // Star Wars - Rogue Squadron, {17, 0xe37e2f49, 0x1eb63fd8, (unsigned char*)"Unknown 0xe37e2f49, 0x1eb63fd8",}, // Star Wars - Rogue Squadron, {17, 0x8ce1af3d, 0xb2760ea2, (unsigned char*)"Unknown 0x8ce1af3d, 0xb2760ea2",}, // Star Wars - Rogue Squadron, {18, 0x7b685972, 0x57b8095a, (unsigned char*)"Unknown 0x7b685972, 0x57b8095a",}, // World Driver Championship {18, 0xe92dbb9b, 0x57b8095a, (unsigned char*)"Unknown 0xe92dbb9b, 0x57b8095a",}, // World Driver Championship {18, 0xe6c9acc1, 0x65f80845, (unsigned char*)"Unknown 0xe6c9acc1, 0x65f80845",}, // World Driver Championship {18, 0x6522df69, 0x720b88a0, (unsigned char*)"Unknown 0x6522df69, 0x720b88a0",}, // World Driver Championship {18, 0x6522df69, 0xf1e8ba9e, (unsigned char*)"Unknown 0x6522df69, 0xf1e8ba9e",}, // World Driver Championship {19, 0xa486bed3, 0xa486bed3, (unsigned char*)"Unknown 0xa486bed3, 0xa486bed3",}, // Last Legion UX, {19, 0x6b519381, 0xfebacfd8, (unsigned char*)"Unknown in Toukan Road",}, // I don't know which ucode {20, 0x6d2a01b1, 0x6d2a01b1, (unsigned char*)"RSP Gfx ucode ZSortp 0.33 Yoshitaka Yasumoto Nintendo.",}, // Mia Hamm Soccer 64, }; FiddledVtx * g_pVtxBase=NULL; SetImgInfo g_TI = { TXT_FMT_RGBA, TXT_SIZE_16b, 1, 0 }; SetImgInfo g_CI = { TXT_FMT_RGBA, TXT_SIZE_16b, 1, 0 }; SetImgInfo g_ZI = { TXT_FMT_RGBA, TXT_SIZE_16b, 1, 0 }; RenderTextureInfo g_ZI_saves[2]; DListStack gDlistStack[MAX_DL_STACK_SIZE]; int gDlistStackPointer= -1; TMEMLoadMapInfo g_tmemLoadAddrMap[0x200]; // Totally 4KB TMEM TMEMLoadMapInfo g_tmemInfo0; // Info for Tmem=0 TMEMLoadMapInfo g_tmemInfo1; // Info for Tmem=0x100 const char *pszImgSize[4] = {"4", "8", "16", "32"}; const char *textluttype[4] = {"RGB16", "I16?", "RGBA16", "IA16"}; uint16_t g_wRDPTlut[0x200]; uint32_t g_dwRDPPalCrc[16]; #include "FrameBuffer.h" #include "RSP_GBI0.h" #include "RSP_GBI1.h" #include "RSP_GBI2.h" #include "RSP_GBI2_ext.h" #include "RSP_GBI_Others.h" #include "RSP_GBI_Sprite2D.h" #include "RDP_Texture.h" ////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////// // Init and Reset // ////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////// void DLParser_Init() { status.gRDPTime = 0; status.gDlistCount = 0; status.gUcodeCount = 0; status.frameReadByCPU = FALSE; status.frameWriteByCPU = FALSE; status.SPCycleCount = 0; status.DPCycleCount = 0; status.bN64IsDrawingTextureBuffer = false; status.bDirectWriteIntoRDRAM = false; status.bHandleN64RenderTexture = false; status.bUcodeIsKnown = FALSE; status.lastPurgeTimeTime = status.gRDPTime; status.curRenderBuffer = 0; status.curDisplayBuffer = 0; status.curVIOriginReg = 0; status.primitiveType = PRIM_TRI1; status.lastPurgeTimeTime = 0; // Time textures were last purged status.UseLargerTile[0] = false; status.LargerTileRealLeft[0] = status.LargerTileRealLeft[1] = 0; memset(&g_ZI_saves, 0, sizeof(RenderTextureInfo)*2); for( int i=0; i<8; i++ ) { memset(&gRDP.tiles[i], 0, sizeof(Tile)); } memset(g_tmemLoadAddrMap, 0, sizeof(g_tmemLoadAddrMap)); for( int i=0; iCloseRenderTexture(false); } } void RDP_SetUcodeMap(int ucode) { status.bUseModifiedUcodeMap = false; switch( ucode ) { case 0: // Mario and demos break; case 1: // F3DEX GBI1 case 20: break; case 2: // Golden Eye memcpy( &LoadedUcodeMap, &ucodeMap0, sizeof(UcodeMap)); //LoadedUcodeMap[9]=RSP_GBI1_Sprite2DBase; //LoadedUcodeMap[0xaf]=RSP_GBI1_LoadUCode; //LoadedUcodeMap[0xb0]=RSP_GBI1_BranchZ; LoadedUcodeMap[0xb4]=DLParser_RDPHalf_1_0xb4_GoldenEye; status.bUseModifiedUcodeMap = true; break; case 3: // S2DEX GBI2 break; case 4: memcpy( &LoadedUcodeMap, &ucodeMap0, sizeof(UcodeMap)); LoadedUcodeMap[4]=RSP_Vtx_WRUS; LoadedUcodeMap[0xb1]=RSP_GBI1_Tri2; //LoadedUcodeMap[9]=RSP_GBI1_Sprite2DBase; //LoadedUcodeMap[0xaf]=RSP_GBI1_LoadUCode; //LoadedUcodeMap[0xb0]=RSP_GBI1_BranchZ; //LoadedUcodeMap[0xb2]=RSP_GBI1_ModifyVtx; status.bUseModifiedUcodeMap = true; break; case 5: // F3DEX GBI2 break; case 6: // DKR, Jet Force Gemini, Mickey case 11: // DKR, Jet Force Gemini, Mickey memcpy( &LoadedUcodeMap, &ucodeMap0, sizeof(UcodeMap)); LoadedUcodeMap[1]=RSP_Mtx_DKR; LoadedUcodeMap[4]=RSP_Vtx_DKR; if( ucode == 11 ) LoadedUcodeMap[4]=RSP_Vtx_Gemini; LoadedUcodeMap[5]=RSP_DMA_Tri_DKR; LoadedUcodeMap[7]=RSP_DL_In_MEM_DKR; LoadedUcodeMap[0xbc]=RSP_MoveWord_DKR; LoadedUcodeMap[0xbf]=DLParser_Set_Addr_Ucode6; //LoadedUcodeMap[9]=RSP_GBI1_Sprite2DBase; //LoadedUcodeMap[0xb0]=RSP_GBI1_BranchZ; //LoadedUcodeMap[0xb2]=RSP_GBI1_ModifyVtx; status.bUseModifiedUcodeMap = true; break; case 7: // S2DEX GBI1 break; case 8: // Ucode 0 with Sprite2D, Puzzle Master 64 memcpy( &LoadedUcodeMap, &ucodeMap0, sizeof(UcodeMap)); LoadedUcodeMap[RSP_SPRITE2D_BASE] = RSP_GBI_Sprite2D_PuzzleMaster64; LoadedUcodeMap[RSP_SPRITE2D_SCALEFLIP] = RSP_GBI1_Sprite2DScaleFlip; LoadedUcodeMap[RSP_SPRITE2D_DRAW] = RSP_GBI0_Sprite2DDraw; status.bUseModifiedUcodeMap = true; break; case 9: // Perfect Dark memcpy( &LoadedUcodeMap, &ucodeMap0, sizeof(UcodeMap)); LoadedUcodeMap[4]=RSP_Vtx_PD; LoadedUcodeMap[7]=RSP_Set_Vtx_CI_PD; LoadedUcodeMap[0xb1]=RSP_Tri4_PD; LoadedUcodeMap[0xb4]=DLParser_RDPHalf_1_0xb4_GoldenEye; status.bUseModifiedUcodeMap = true; break; case 10: // Conker BFD memcpy( &LoadedUcodeMap, &ucodeMap5, sizeof(UcodeMap)); LoadedUcodeMap[1]=RSP_Vtx_Conker; LoadedUcodeMap[0x10]=DLParser_Tri4_Conker; LoadedUcodeMap[0x11]=DLParser_Tri4_Conker; LoadedUcodeMap[0x12]=DLParser_Tri4_Conker; LoadedUcodeMap[0x13]=DLParser_Tri4_Conker; LoadedUcodeMap[0x14]=DLParser_Tri4_Conker; LoadedUcodeMap[0x15]=DLParser_Tri4_Conker; LoadedUcodeMap[0x16]=DLParser_Tri4_Conker; LoadedUcodeMap[0x17]=DLParser_Tri4_Conker; LoadedUcodeMap[0x18]=DLParser_Tri4_Conker; LoadedUcodeMap[0x19]=DLParser_Tri4_Conker; LoadedUcodeMap[0x1a]=DLParser_Tri4_Conker; LoadedUcodeMap[0x1b]=DLParser_Tri4_Conker; LoadedUcodeMap[0x1c]=DLParser_Tri4_Conker; LoadedUcodeMap[0x1d]=DLParser_Tri4_Conker; LoadedUcodeMap[0x1e]=DLParser_Tri4_Conker; LoadedUcodeMap[0x1f]=DLParser_Tri4_Conker; LoadedUcodeMap[0xdb]=DLParser_MoveWord_Conker; LoadedUcodeMap[0xdc]=DLParser_MoveMem_Conker; status.bUseModifiedUcodeMap = true; break; case 12: // Silicon Velley, Space Station memcpy( &LoadedUcodeMap, &ucodeMap1, sizeof(UcodeMap)); LoadedUcodeMap[0x01]=RSP_GBI0_Mtx; status.bUseModifiedUcodeMap = true; break; case 13: // modified S2DEX memcpy( &LoadedUcodeMap, &ucodeMap7, sizeof(UcodeMap)); //LoadedUcodeMap[S2DEX_BG_1CYC] = ucodeMap1[S2DEX_BG_1CYC]; LoadedUcodeMap[S2DEX_OBJ_RECTANGLE] = ucodeMap1[S2DEX_OBJ_RECTANGLE]; LoadedUcodeMap[S2DEX_OBJ_SPRITE] = ucodeMap1[S2DEX_OBJ_SPRITE]; //LoadedUcodeMap[S2DEX_OBJ_RENDERMODE] = ucodeMap1[S2DEX_OBJ_RENDERMODE]; //LoadedUcodeMap[S2DEX_OBJ_RECTANGLE_R] = ucodeMap1[S2DEX_OBJ_RECTANGLE_R]; LoadedUcodeMap[S2DEX_RDPHALF_0] = ucodeMap1[S2DEX_RDPHALF_0]; status.bUseModifiedUcodeMap = true; break; case 14: // OgreBattle Background memcpy( &LoadedUcodeMap, &ucodeMap5, sizeof(UcodeMap)); LoadedUcodeMap[0xda] = DLParser_OgreBatter64BG; LoadedUcodeMap[0xdc] = RSP_S2DEX_OBJ_MOVEMEM; status.bUseModifiedUcodeMap = true; break; case 15: // Ucode 0 with Sprite2D memcpy( &LoadedUcodeMap, &ucodeMap0, sizeof(UcodeMap)); LoadedUcodeMap[RSP_SPRITE2D_BASE] = RSP_GBI_Sprite2DBase; LoadedUcodeMap[RSP_SPRITE2D_SCALEFLIP] = RSP_GBI1_Sprite2DScaleFlip; LoadedUcodeMap[RSP_SPRITE2D_DRAW] = RSP_GBI0_Sprite2DDraw; status.bUseModifiedUcodeMap = true; break; case 16: // Star War, Shadow Of Empire memcpy( &LoadedUcodeMap, &ucodeMap0, sizeof(UcodeMap)); LoadedUcodeMap[4]=RSP_Vtx_ShadowOfEmpire; status.bUseModifiedUcodeMap = true; break; case 17: //Indiana Jones, does not work anyway memcpy( &LoadedUcodeMap, &ucodeMap1, sizeof(UcodeMap)); LoadedUcodeMap[0]=DLParser_Ucode8_0x0; //LoadedUcodeMap[1]=RSP_RDP_Nothing; LoadedUcodeMap[2]=DLParser_RS_Color_Buffer; LoadedUcodeMap[3]=DLParser_RS_MoveMem; LoadedUcodeMap[4]=DLParser_RS_Vtx_Buffer; LoadedUcodeMap[5]=DLParser_Ucode8_0x05; LoadedUcodeMap[6]=DLParser_Ucode8_DL; LoadedUcodeMap[7]=DLParser_Ucode8_JUMP; LoadedUcodeMap[8]=RSP_RDP_Nothing; LoadedUcodeMap[9]=RSP_RDP_Nothing; LoadedUcodeMap[10]=RSP_RDP_Nothing; LoadedUcodeMap[11]=RSP_RDP_Nothing; LoadedUcodeMap[0x80]=DLParser_RS_Block; LoadedUcodeMap[0xb4]=DLParser_Ucode8_0xb4; LoadedUcodeMap[0xb5]=DLParser_Ucode8_0xb5; LoadedUcodeMap[0xb8]=DLParser_Ucode8_EndDL; LoadedUcodeMap[0xbc]=DLParser_Ucode8_0xbc; LoadedUcodeMap[0xbd]=DLParser_Ucode8_0xbd; LoadedUcodeMap[0xbe]=DLParser_RS_0xbe; LoadedUcodeMap[0xbF]=DLParser_Ucode8_0xbf; LoadedUcodeMap[0xe4]=DLParser_TexRect_Last_Legion; status.bUseModifiedUcodeMap = true; break; case 18: // World Driver Championship memcpy( &LoadedUcodeMap, &ucodeMap1, sizeof(UcodeMap)); LoadedUcodeMap[0xe]=DLParser_RSP_DL_WorldDriver; LoadedUcodeMap[0x2]=DLParser_RSP_Pop_DL_WorldDriver; LoadedUcodeMap[0xdf]=DLParser_RSP_Pop_DL_WorldDriver; LoadedUcodeMap[0x6]=RSP_RDP_Nothing; status.bUseModifiedUcodeMap = true; break; case 19: // Last Legion UX memcpy( &LoadedUcodeMap, &ucodeMap1, sizeof(UcodeMap)); LoadedUcodeMap[0x80]=DLParser_RSP_Last_Legion_0x80; LoadedUcodeMap[0x00]=DLParser_RSP_Last_Legion_0x00; LoadedUcodeMap[0xe4]=DLParser_TexRect_Last_Legion; status.bUseModifiedUcodeMap = true; break; default: memcpy( &LoadedUcodeMap, &ucodeMap5, sizeof(UcodeMap)); status.bUseModifiedUcodeMap = true; break; } #ifdef DEBUGGER if( logMicrocode ) TRACE1("Using ucode %d", ucode); #endif } void RSP_SetUcode(int ucode, uint32_t ucStart, uint32_t ucDStart, uint32_t ucSize) { if( status.ucodeHasBeenSet && gRSP.ucode == ucode ) return; status.ucodeHasBeenSet = true; if( ucode < 0 ) ucode = 5; RDP_SetUcodeMap(ucode); if( status.bUseModifiedUcodeMap ) { currentUcodeMap = &LoadedUcodeMap[0]; } else { currentUcodeMap = *ucodeMaps[ucode]; } gRSP.vertexMult = vertexMultVals[ucode]; //if( gRSP.ucode != ucode ) DebuggerAppendMsg("Set to ucode: %d", ucode); gRSP.ucode = ucode; lastUcodeInfo.used = true; if( ucStart == 0 ) { lastUcodeInfo.ucStart = g_pOSTask->t.ucode; lastUcodeInfo.ucDStart = g_pOSTask->t.ucode_data; lastUcodeInfo.ucSize = g_pOSTask->t.ucode_size; } else { lastUcodeInfo.ucStart = ucStart; lastUcodeInfo.ucDStart = ucDStart; lastUcodeInfo.ucSize = ucSize; } } //***************************************************************************** // //***************************************************************************** static uint32_t DLParser_IdentifyUcodeFromString( const unsigned char * str_ucode ) { const unsigned char str_ucode0[] = "RSP SW Version: 2.0"; const unsigned char str_ucode1[] = "RSP Gfx ucode "; if ( strncasecmp( (char*)str_ucode, (char*)str_ucode0, strlen((char*)str_ucode0) ) == 0 ) { return 0; } if ( strncasecmp( (char*)str_ucode, (char*)str_ucode1, strlen((char*)str_ucode1) ) == 0 ) { if( strstr((char*)str_ucode,"1.") != 0 ) { if( strstr((char*)str_ucode,"S2DEX") != 0 ) { return 7; } else return 1; } else if( strstr((char*)str_ucode,"2.") != 0 ) { if( strstr((char*)str_ucode,"S2DEX") != 0 ) { return 3; } else return 5; } } return 5; } //***************************************************************************** // //***************************************************************************** static uint32_t DLParser_IdentifyUcode( uint32_t crc_size, uint32_t crc_800, char* str ) { for ( uint32_t i = 0; i < sizeof(g_UcodeData)/sizeof(UcodeData); i++ ) { #ifdef DEBUGGER if ( crc_800 == g_UcodeData[i].crc_800 ) { if( strlen(str)==0 || strcmp((const char *) g_UcodeData[i].ucode_name, str) == 0 ) { TRACE0((const char *) g_UcodeData[i].ucode_name); } else { DebuggerAppendMsg("Incorrect description for this ucode:\n%x, %x, %s",crc_800, crc_size, str); } status.bUcodeIsKnown = TRUE; gRSP.bNearClip = !g_UcodeData[i].non_nearclip; gRSP.bRejectVtx = g_UcodeData[i].reject; DebuggerAppendMsg("Identify ucode = %d, crc = %08X, %s", g_UcodeData[i].ucode, crc_800, str); return g_UcodeData[i].ucode; } #else if ( crc_800 == g_UcodeData[i].crc_800 ) { status.bUcodeIsKnown = TRUE; gRSP.bNearClip = !g_UcodeData[i].non_nearclip; gRSP.bRejectVtx = g_UcodeData[i].reject; return g_UcodeData[i].ucode; } #endif } #ifdef DEBUGGER { static bool warned = false; if( warned == false ) { warned = true; TRACE0("Can not identify ucode for this game"); } } #endif gRSP.bNearClip = false; gRSP.bRejectVtx = false; status.bUcodeIsKnown = FALSE; return ~0; } uint32_t DLParser_CheckUcode(uint32_t ucStart, uint32_t ucDStart, uint32_t ucSize, uint32_t ucDSize) { if( options.enableHackForGames == HACK_FOR_ROGUE_SQUADRON ) { return 17; } // Check the used ucode table first int usedUcodeIndex = 0; for( usedUcodeIndex=0; (unsigned int)usedUcodeIndex= ' ') { *p++ = rdram_s8[ base + BYTE4_XOR_BE(i) ]; i++; } *p++ = 0; break; } } } //if ( strcmp( str, gLastMicrocodeString ) != 0 ) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; //uint32_t size = ucDSize; base = ucStart & 0x1fffffff; uint32_t crc_size = ComputeCRC32( 0, &rdram_u8[ base ], 8);//size ); uint32_t crc_800 = ComputeCRC32( 0, &rdram_u8[ base ], 0x800 ); uint32_t ucode; ucode = DLParser_IdentifyUcode( crc_size, crc_800, (char*)str ); if ( (int)ucode == ~0 ) { #ifdef DEBUGGER static bool warned=false; //if( warned == false ) { char message[300]; sprintf(message, "Unable to find ucode to use for '%s' CRCSize: 0x%08x CRC800: 0x%08x", str, crc_size, crc_800); TRACE0(message); DebugMessage(M64MSG_ERROR, message); warned = true; } #endif ucode = DLParser_IdentifyUcodeFromString(str); if ( (int)ucode == ~0 ) { ucode=5; } } //DLParser_SetuCode( ucode ); #ifdef DEBUGGER { static bool warned=false; if( warned == false ) { warned = true; if( strlen((char *) str) == 0 ) DebuggerAppendMsg("Can not find RSP string in the DLIST, CRC800: 0x%08x, CRCSize: 0x%08x", crc_800, crc_size); else TRACE0((char *) str); } } #endif strcpy( (char*)gLastMicrocodeString, (char*)str ); if( usedUcodeIndex >= MAX_UCODE_INFO ) { usedUcodeIndex = rand()%MAX_UCODE_INFO; } UsedUcodes[usedUcodeIndex].ucStart = ucStart; UsedUcodes[usedUcodeIndex].ucSize = ucSize; UsedUcodes[usedUcodeIndex].ucDStart = ucDStart; UsedUcodes[usedUcodeIndex].ucDSize = ucDSize; UsedUcodes[usedUcodeIndex].ucode = ucode; UsedUcodes[usedUcodeIndex].crc_800 = crc_800; UsedUcodes[usedUcodeIndex].crc_size = crc_size; UsedUcodes[usedUcodeIndex].used = true; strcpy( UsedUcodes[usedUcodeIndex].rspstr, (char*)str ); TRACE2("New ucode has been detected:\n%s, ucode=%d", str, ucode); return ucode; } } extern int dlistMtxCount; extern bool bHalfTxtScale; void DLParser_Process(OSTask * pTask) { uint32_t *rdram_u32 = (uint32_t*)gfx_info.RDRAM; dlistMtxCount = 0; bHalfTxtScale = false; if ( CRender::g_pRender == NULL) { TriggerDPInterrupt(); TriggerSPInterrupt(); return; } status.bScreenIsDrawn = true; if( currentRomOptions.N64RenderToTextureEmuType != TXT_BUF_NONE && defaultRomOptions.bSaveVRAM ) { g_pFrameBufferManager->CheckRenderTextureCRCInRDRAM(); } g_pOSTask = pTask; DebuggerPauseCountN( NEXT_DLIST ); status.gRDPTime = (uint32_t) SDL_GetTicks(); status.gDlistCount++; if ( lastUcodeInfo.ucStart != (uint32_t)(pTask->t.ucode) ) { uint32_t ucode = DLParser_CheckUcode(pTask->t.ucode, pTask->t.ucode_data, pTask->t.ucode_size, pTask->t.ucode_data_size); RSP_SetUcode(ucode, pTask->t.ucode, pTask->t.ucode_data, pTask->t.ucode_size); DEBUGGER_PAUSE_AND_DUMP(NEXT_SWITCH_UCODE,{DebuggerAppendMsg("Pause at switching ucode");}); } // Initialize stack status.bN64FrameBufferIsUsed = false; gDlistStackPointer=0; gDlistStack[gDlistStackPointer].pc = (uint32_t)pTask->t.data_ptr; gDlistStack[gDlistStackPointer].countdown = MAX_DL_COUNT; DEBUGGER_PAUSE_AT_COND_AND_DUMP_COUNT_N((gDlistStack[gDlistStackPointer].pc == 0 && pauseAtNext && eventToPause==NEXT_UNKNOWN_OP), {DebuggerAppendMsg("Start Task without DLIST: ucode=%08X, data=%08X", (uint32_t)pTask->t.ucode, (uint32_t)pTask->t.ucode_data);}); // Check if we need to purge (every 5 milliseconds) if (status.gRDPTime - status.lastPurgeTimeTime > 5) { gTextureManager.PurgeOldTextures(); status.lastPurgeTimeTime = status.gRDPTime; } status.dwNumDListsCulled = 0; status.dwNumTrisRendered = 0; status.dwNumTrisClipped = 0; status.dwNumVertices = 0; status.dwBiggestVertexIndex = 0; if( g_curRomInfo.bForceScreenClear && CGraphicsContext::needCleanScene ) { CRender::g_pRender->ClearBuffer(true,true); CGraphicsContext::needCleanScene = false; } SetVIScales(); CRender::g_pRender->RenderReset(); CRender::g_pRender->BeginRendering(); CRender::g_pRender->SetViewport(0, 0, windowSetting.uViWidth, windowSetting.uViHeight, 0x3FF); CRender::g_pRender->SetFillMode(options.bWinFrameMode? RICE_FILLMODE_WINFRAME : RICE_FILLMODE_SOLID); { // The main loop while( gDlistStackPointer >= 0 ) { #ifdef DEBUGGER DEBUGGER_PAUSE_COUNT_N(NEXT_UCODE); if( debuggerPause ) { DebuggerPause(); CRender::g_pRender->SetFillMode(options.bWinFrameMode? RICE_FILLMODE_WINFRAME : RICE_FILLMODE_SOLID); } if (gDlistStack[gDlistStackPointer].pc > g_dwRamSize) { DebuggerAppendMsg("Error: dwPC is %08X", gDlistStack[gDlistStackPointer].pc ); break; } #endif status.gUcodeCount++; Gfx *pgfx = (Gfx*)&rdram_u32[(gDlistStack[gDlistStackPointer].pc>>2)]; #ifdef DEBUGGER LOG_UCODE("0x%08x: %08x %08x %-10s", gDlistStack[gDlistStackPointer].pc, pgfx->words.w0, pgfx->words.w1, (gRSP.ucode!=5&&gRSP.ucode!=10)?ucodeNames_GBI1[(pgfx->words.w0>>24)]:ucodeNames_GBI2[(pgfx->words.w0>>24)]); #endif gDlistStack[gDlistStackPointer].pc += 8; currentUcodeMap[pgfx->words.w0 >>24](pgfx); if ( gDlistStackPointer >= 0 && --gDlistStack[gDlistStackPointer].countdown < 0 ) { LOG_UCODE("**EndDLInMem"); gDlistStackPointer--; } } } CRender::g_pRender->EndRendering(); if( gRSP.ucode >= 17) TriggerDPInterrupt(); TriggerSPInterrupt(); } ////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////// // Util Functions // ////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////// void RDP_NOIMPL_Real(const char* op, uint32_t word0, uint32_t word1) { #ifdef DEBUGGER if( logWarning ) { TRACE0("Stack Trace"); for( int i=0; iSetCullMode(bCullFront, bCullBack); bool bShade = (gRDP.geometryMode & G_SHADE) ? true : false; bool bShadeSmooth = (gRDP.geometryMode & G_SHADING_SMOOTH) ? true : false; if (bShade && bShadeSmooth) CRender::g_pRender->SetShadeMode( SHADE_SMOOTH ); else CRender::g_pRender->SetShadeMode( SHADE_FLAT ); CRender::g_pRender->SetFogEnable( gRDP.geometryMode & G_FOG ? true : false ); SetTextureGen((gRDP.geometryMode & G_TEXTURE_GEN) ? true : false ); SetLighting( (gRDP.geometryMode & G_LIGHTING ) ? true : false ); CRender::g_pRender->ZBufferEnable( gRDP.geometryMode & G_ZBUFFER ); } ////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////// // DP Ucodes // ////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////// void DLParser_SetKeyGB(Gfx *gfx) { DP_Timing(DLParser_SetKeyGB); gRDP.keyB = ((gfx->words.w1)>>8)&0xFF; gRDP.keyG = ((gfx->words.w1)>>24)&0xFF; gRDP.keyA = (gRDP.keyR+gRDP.keyG+gRDP.keyB)/3; gRDP.fKeyA = gRDP.keyA/255.0f; } void DLParser_SetKeyR(Gfx *gfx) { DP_Timing(DLParser_SetKeyR); gRDP.keyR = ((gfx->words.w1)>>8)&0xFF; gRDP.keyA = (gRDP.keyR+gRDP.keyG+gRDP.keyB)/3; gRDP.fKeyA = gRDP.keyA/255.0f; } int g_convk0,g_convk1,g_convk2,g_convk3,g_convk4,g_convk5; float g_convc0,g_convc1,g_convc2,g_convc3,g_convc4,g_convc5; void DLParser_SetConvert(Gfx *gfx) { DP_Timing(DLParser_SetConvert); int temp; temp = ((gfx->words.w0)>>13)&0x1FF; g_convk0 = temp>0xFF ? -(temp-0x100) : temp; temp = ((gfx->words.w0)>>4)&0x1FF; g_convk1 = temp>0xFF ? -(temp-0x100) : temp; temp = (gfx->words.w0)&0xF; temp = (temp<<5)|(((gfx->words.w1)>>27)&0x1F); g_convk2 = temp>0xFF ? -(temp-0x100) : temp; temp = ((gfx->words.w1)>>18)&0x1FF; g_convk3 = temp>0xFF ? -(temp-0x100) : temp; temp = ((gfx->words.w1)>>9)&0x1FF; g_convk4 = temp>0xFF ? -(temp-0x100) : temp; temp = (gfx->words.w1)&0x1FF; g_convk5 = temp>0xFF ? -(temp-0x100) : temp; g_convc0 = g_convk5/255.0f+1.0f; g_convc1 = g_convk0/255.0f*g_convc0; g_convc2 = g_convk1/255.0f*g_convc0; g_convc3 = g_convk2/255.0f*g_convc0; g_convc4 = g_convk3/255.0f*g_convc0; } void DLParser_SetPrimDepth(Gfx *gfx) { DP_Timing(DLParser_SetPrimDepth); uint32_t dwZ = ((gfx->words.w1) >> 16) & 0xFFFF; uint32_t dwDZ = ((gfx->words.w1) ) & 0xFFFF; LOG_UCODE("SetPrimDepth: 0x%08x 0x%08x - z: 0x%04x dz: 0x%04x", gfx->words.w0, gfx->words.w1, dwZ, dwDZ); SetPrimitiveDepth(dwZ, dwDZ); DEBUGGER_PAUSE(NEXT_SET_PRIM_COLOR); } void DLParser_RDPSetOtherMode(Gfx *gfx) { DP_Timing(DLParser_RDPSetOtherMode); gRDP.otherMode._u32[1] = (gfx->words.w0); // High gRDP.otherMode._u32[0] = (gfx->words.w1); // Low if( gRDP.otherModeH != ((gfx->words.w0) & 0x0FFFFFFF) ) { gRDP.otherModeH = ((gfx->words.w0) & 0x0FFFFFFF); uint32_t dwTextFilt = (gRDP.otherModeH>>RSP_SETOTHERMODE_SHIFT_TEXTFILT)&0x3; CRender::g_pRender->SetTextureFilter(dwTextFilt<words.w1) ) { if( (gRDP.otherModeL&ZMODE_DEC) != ((gfx->words.w1)&ZMODE_DEC) ) { if( ((gfx->words.w1)&ZMODE_DEC) == ZMODE_DEC ) CRender::g_pRender->SetZBias( 2 ); else CRender::g_pRender->SetZBias( 0 ); } gRDP.otherModeL = (gfx->words.w1); bool bZCompare = (gRDP.otherModeL & Z_COMPARE) ? TRUE : FALSE; bool bZUpdate = (gRDP.otherModeL & Z_UPDATE) ? TRUE : FALSE; CRender::g_pRender->SetZCompare( bZCompare ); CRender::g_pRender->SetZUpdate( bZUpdate ); uint32_t dwAlphaTestMode = (gRDP.otherModeL >> RSP_SETOTHERMODE_SHIFT_ALPHACOMPARE) & 0x3; if ((dwAlphaTestMode) != 0) CRender::g_pRender->SetAlphaTestEnable( TRUE ); else CRender::g_pRender->SetAlphaTestEnable( FALSE ); } uint16_t blender = gRDP.otherMode.blender; RDP_BlenderSetting &bl = *(RDP_BlenderSetting*)(&(blender)); if( bl.c1_m1a==3 || bl.c1_m2a == 3 || bl.c2_m1a == 3 || bl.c2_m2a == 3 ) { gRDP.bFogEnableInBlender = true; } else { gRDP.bFogEnableInBlender = false; } } void DLParser_RDPLoadSync(Gfx *gfx) { DP_Timing(DLParser_RDPLoadSync); LOG_UCODE("LoadSync: (Ignored)"); } void DLParser_RDPPipeSync(Gfx *gfx) { DP_Timing(DLParser_RDPPipeSync); LOG_UCODE("PipeSync: (Ignored)"); } void DLParser_RDPTileSync(Gfx *gfx) { DP_Timing(DLParser_RDPTileSync); LOG_UCODE("TileSync: (Ignored)"); } void DLParser_RDPFullSync(Gfx *gfx) { DP_Timing(DLParser_RDPFullSync); TriggerDPInterrupt(); } void DLParser_SetScissor(Gfx *gfx) { DP_Timing(DLParser_SetScissor); ScissorType tempScissor; // The coords are all in 8:2 fixed point tempScissor.x0 = ((gfx->words.w0)>>12)&0xFFF; tempScissor.y0 = ((gfx->words.w0)>>0 )&0xFFF; tempScissor.mode = ((gfx->words.w1)>>24)&0x03; tempScissor.x1 = ((gfx->words.w1)>>12)&0xFFF; tempScissor.y1 = ((gfx->words.w1)>>0 )&0xFFF; tempScissor.left = tempScissor.x0/4; tempScissor.top = tempScissor.y0/4; tempScissor.right = tempScissor.x1/4; tempScissor.bottom = tempScissor.y1/4; if( options.bEnableHacks ) { if( g_CI.dwWidth == 0x200 && tempScissor.right == 0x200 ) { uint32_t width = *gfx_info.VI_WIDTH_REG & 0xFFF; if( width != 0x200 ) { // Hack for RE2 tempScissor.bottom = tempScissor.right*tempScissor.bottom/width; tempScissor.right = width; } } } if( gRDP.scissor.left != tempScissor.left || gRDP.scissor.top != tempScissor.top || gRDP.scissor.right != tempScissor.right || gRDP.scissor.bottom != tempScissor.bottom || gRSP.real_clip_scissor_left != tempScissor.left || gRSP.real_clip_scissor_top != tempScissor.top || gRSP.real_clip_scissor_right != tempScissor.right || gRSP.real_clip_scissor_bottom != tempScissor.bottom) { memcpy(&(gRDP.scissor), &tempScissor, sizeof(ScissorType) ); if( !status.bHandleN64RenderTexture ) SetVIScales(); if( options.enableHackForGames == HACK_FOR_SUPER_BOWLING && g_CI.dwAddr%0x100 != 0 ) { // right half screen gRDP.scissor.left += 160; gRDP.scissor.right += 160; CRender::g_pRender->SetViewport(160, 0, 320, 240, 0xFFFF); } CRender::g_pRender->UpdateClipRectangle(); CRender::g_pRender->UpdateScissor(); CRender::g_pRender->SetViewportRender(); } LOG_UCODE("SetScissor: x0=%d y0=%d x1=%d y1=%d mode=%d", gRDP.scissor.left, gRDP.scissor.top, gRDP.scissor.right, gRDP.scissor.bottom, gRDP.scissor.mode); ///TXTRBUF_DETAIL_DUMP(DebuggerAppendMsg("SetScissor: x0=%d y0=%d x1=%d y1=%d mode=%d", gRDP.scissor.left, gRDP.scissor.top, //gRDP.scissor.right, gRDP.scissor.bottom, gRDP.scissor.mode);); } void DLParser_FillRect(Gfx *gfx) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; DP_Timing(DLParser_FillRect); // fix me status.primitiveType = PRIM_FILLRECT; if( status.bN64IsDrawingTextureBuffer && frameBufferOptions.bIgnore ) { return; } if( options.enableHackForGames == HACK_FOR_MARIO_TENNIS ) { uint32_t dwPC = gDlistStack[gDlistStackPointer].pc; // This points to the next instruction uint32_t w2 = *(uint32_t *)(rdram_u8 + dwPC); if( (w2>>24) == RDP_FILLRECT ) { // Mario Tennis, a lot of FillRect ucodes, skip all of them while( (w2>>24) == RDP_FILLRECT ) { dwPC += 8; w2 = *(uint32_t *)(rdram_u8 + dwPC); } gDlistStack[gDlistStackPointer].pc = dwPC; return; } } uint32_t x0 = (((gfx->words.w1)>>12)&0xFFF)/4; uint32_t y0 = (((gfx->words.w1)>>0 )&0xFFF)/4; uint32_t x1 = (((gfx->words.w0)>>12)&0xFFF)/4; uint32_t y1 = (((gfx->words.w0)>>0 )&0xFFF)/4; // Note, in some modes, the right/bottom lines aren't drawn LOG_UCODE(" (%d,%d) (%d,%d)", x0, y0, x1, y1); if( gRDP.otherMode.cycle_type >= CYCLE_TYPE_COPY ) { x1++; y1++; } //TXTRBUF_DETAIL_DUMP(DebuggerAppendMsg("FillRect: X0=%d, Y0=%d, X1=%d, Y1=%d, Color=0x%08X", x0, y0, x1, y1, gRDP.originalFillColor);); if( status.bHandleN64RenderTexture && options.enableHackForGames == HACK_FOR_BANJO_TOOIE ) { // Skip this return; } if (IsUsedAsDI(g_CI.dwAddr)) { // Clear the Z Buffer if( x0!=0 || y0!=0 || windowSetting.uViWidth-x1>1 || windowSetting.uViHeight-y1>1) { if( options.enableHackForGames == HACK_FOR_GOLDEN_EYE ) { // GoldenEye is using double zbuffer if( g_CI.dwAddr == g_ZI.dwAddr ) { // The zbuffer is the upper screen COORDRECT rect={int(x0*windowSetting.fMultX),int(y0*windowSetting.fMultY),int(x1*windowSetting.fMultX),int(y1*windowSetting.fMultY)}; CRender::g_pRender->ClearBuffer(false,true,rect); //Check me LOG_UCODE(" Clearing ZBuffer"); } else { // The zbuffer is the lower screen int h = (g_CI.dwAddr-g_ZI.dwAddr)/g_CI.dwWidth/2; COORDRECT rect={int(x0*windowSetting.fMultX),int((y0+h)*windowSetting.fMultY),int(x1*windowSetting.fMultX),int((y1+h)*windowSetting.fMultY)}; CRender::g_pRender->ClearBuffer(false,true,rect); //Check me LOG_UCODE(" Clearing ZBuffer"); } } else { COORDRECT rect={int(x0*windowSetting.fMultX),int(y0*windowSetting.fMultY),int(x1*windowSetting.fMultX),int(y1*windowSetting.fMultY)}; CRender::g_pRender->ClearBuffer(false,true,rect); //Check me LOG_UCODE(" Clearing ZBuffer"); } } else { CRender::g_pRender->ClearBuffer(false,true); //Check me LOG_UCODE(" Clearing ZBuffer"); } DEBUGGER_PAUSE_AND_DUMP_COUNT_N( NEXT_FLUSH_TRI,{TRACE0("Pause after FillRect: ClearZbuffer\n");}); DEBUGGER_PAUSE_AND_DUMP_COUNT_N( NEXT_FILLRECT, {DebuggerAppendMsg("ClearZbuffer: X0=%d, Y0=%d, X1=%d, Y1=%d, Color=0x%08X", x0, y0, x1, y1, gRDP.originalFillColor); DebuggerAppendMsg("Pause after ClearZbuffer: Color=%08X\n", gRDP.originalFillColor);}); if( g_curRomInfo.bEmulateClear ) { // Emulating Clear, by write the memory in RDRAM uint16_t color = (uint16_t)gRDP.originalFillColor; uint32_t pitch = g_CI.dwWidth<<1; long long base = (long long) (rdram_u8 + g_CI.dwAddr); for( uint32_t i =y0; iActiveTextureBuffer(); int cond1 = (((int)x0 < status.leftRendered) ? ((int)x0) : (status.leftRendered)); int cond2 = (((int)y0 < status.topRendered) ? ((int)y0) : (status.topRendered)); int cond3 = ((status.rightRendered > ((int)x1)) ? ((int)x1) : (status.rightRendered)); int cond4 = ((status.bottomRendered > ((int)y1)) ? ((int)y1) : (status.bottomRendered)); int cond5 = ((g_pRenderTextureInfo->maxUsedHeight > ((int)y1)) ? ((int)y1) : (g_pRenderTextureInfo->maxUsedHeight)); status.leftRendered = status.leftRendered < 0 ? x0 : cond1; status.topRendered = status.topRendered<0 ? y0 : cond2; status.rightRendered = status.rightRendered<0 ? x1 : cond3; status.bottomRendered = status.bottomRendered<0 ? y1 : cond4; g_pRenderTextureInfo->maxUsedHeight = cond5; if( status.bDirectWriteIntoRDRAM || ( x0==0 && y0==0 && (x1 == g_pRenderTextureInfo->N64Width || x1 == g_pRenderTextureInfo->N64Width-1 ) ) ) { if( g_pRenderTextureInfo->CI_Info.dwSize == TXT_SIZE_16b ) { uint16_t color = (uint16_t)gRDP.originalFillColor; uint32_t pitch = g_pRenderTextureInfo->N64Width<<1; long long base = (long long) (rdram_u8 + g_pRenderTextureInfo->CI_Info.dwAddr); for( uint32_t i =y0; iN64Width; long long base = (long long) (rdram_u8 + g_pRenderTextureInfo->CI_Info.dwAddr); for( uint32_t i=y0; iN64Width || x1 == g_pRenderTextureInfo->N64Width-1 ) && gRDP.fillColor == 0) //{ // CRender::g_pRender->ClearBuffer(true,false); //} //else { if( gRDP.otherMode.cycle_type == CYCLE_TYPE_FILL ) { CRender::g_pRender->FillRect(x0, y0, x1, y1, gRDP.fillColor); } else { COLOR primColor = GetPrimitiveColor(); CRender::g_pRender->FillRect(x0, y0, x1, y1, primColor); } } } DEBUGGER_PAUSE_AND_DUMP_COUNT_N( NEXT_FLUSH_TRI,{TRACE0("Pause after FillRect\n");}); DEBUGGER_PAUSE_AND_DUMP_COUNT_N( NEXT_FILLRECT, {DebuggerAppendMsg("FillRect: X0=%d, Y0=%d, X1=%d, Y1=%d, Color=0x%08X", x0, y0, x1, y1, gRDP.originalFillColor); DebuggerAppendMsg("Pause after FillRect: Color=%08X\n", gRDP.originalFillColor);}); } else { LOG_UCODE(" Filling Rectangle"); if( frameBufferOptions.bSupportRenderTextures || frameBufferOptions.bCheckBackBufs ) { int cond1 = (((int)x0 < status.leftRendered) ? ((int)x0) : (status.leftRendered)); int cond2 = (((int)y0 < status.topRendered) ? ((int)y0) : (status.topRendered)); int cond3 = ((status.rightRendered > ((int)x1)) ? ((int)x1) : (status.rightRendered)); int cond4 = ((status.bottomRendered > ((int)y1)) ? ((int)y1) : (status.bottomRendered)); int cond5 = ((g_pRenderTextureInfo->maxUsedHeight > ((int)y1)) ? ((int)y1) : (g_pRenderTextureInfo->maxUsedHeight)); if( !status.bCIBufferIsRendered ) g_pFrameBufferManager->ActiveTextureBuffer(); status.leftRendered = status.leftRendered<0 ? x0 : cond1; status.topRendered = status.topRendered<0 ? y0 : cond2; status.rightRendered = status.rightRendered<0 ? x1 : cond3; status.bottomRendered = status.bottomRendered<0 ? y1 : cond4; } if( gRDP.otherMode.cycle_type == CYCLE_TYPE_FILL ) { if( !status.bHandleN64RenderTexture || g_pRenderTextureInfo->CI_Info.dwSize == TXT_SIZE_16b ) { CRender::g_pRender->FillRect(x0, y0, x1, y1, gRDP.fillColor); } } else { COLOR primColor = GetPrimitiveColor(); //if( RGBA_GETALPHA(primColor) != 0 ) { CRender::g_pRender->FillRect(x0, y0, x1, y1, primColor); } } DEBUGGER_PAUSE_AND_DUMP_COUNT_N( NEXT_FLUSH_TRI,{TRACE0("Pause after FillRect\n");}); DEBUGGER_PAUSE_AND_DUMP_COUNT_N( NEXT_FILLRECT, {DebuggerAppendMsg("FillRect: X0=%d, Y0=%d, X1=%d, Y1=%d, Color=0x%08X", x0, y0, x1, y1, gRDP.originalFillColor); DebuggerAppendMsg("Pause after FillRect: Color=%08X\n", gRDP.originalFillColor);}); } } #define STORE_CI {g_CI.dwAddr = dwNewAddr;g_CI.dwFormat = dwFmt;g_CI.dwSize = dwSiz;g_CI.dwWidth = dwWidth;g_CI.bpl=dwBpl;} void DLParser_SetCImg(Gfx *gfx) { uint32_t dwFmt = gfx->setimg.fmt; uint32_t dwSiz = gfx->setimg.siz; uint32_t dwWidth = gfx->setimg.width + 1; uint32_t dwNewAddr = RSPSegmentAddr((gfx->setimg.addr)) & 0x00FFFFFF ; uint32_t dwBpl = dwWidth << dwSiz >> 1; TXTRBUF_DETAIL_DUMP(DebuggerAppendMsg("SetCImg: Addr=0x%08X, Fmt:%s-%sb, Width=%d\n", dwNewAddr, pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth);); if( dwFmt == TXT_FMT_YUV || dwFmt == TXT_FMT_IA ) { WARNING(TRACE4("Check me: SetCImg Addr=0x%08X, Fmt:%s-%sb, Width=%d\n", g_CI.dwAddr, pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth)); } LOG_UCODE(" Image: 0x%08x", RSPSegmentAddr(gfx->words.w1)); LOG_UCODE(" Fmt: %s Size: %s Width: %d", pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth); if( g_CI.dwAddr == dwNewAddr && g_CI.dwFormat == dwFmt && g_CI.dwSize == dwSiz && g_CI.dwWidth == dwWidth ) { TXTRBUF_OR_CI_DETAIL_DUMP({ TRACE0("Set CIMG to the same address, no change, skipped"); DebuggerAppendMsg("Pause after SetCImg: Addr=0x%08X, Fmt:%s-%sb, Width=%d\n", g_CI.dwAddr, pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth); }); return; } if( status.bVIOriginIsUpdated == true && currentRomOptions.screenUpdateSetting==SCREEN_UPDATE_AT_1ST_CI_CHANGE ) { status.bVIOriginIsUpdated=false; CGraphicsContext::Get()->UpdateFrame(false); TXTRBUF_OR_CI_DETAIL_DUMP(TRACE0("Screen Update at 1st CI change");); } if( options.enableHackForGames == HACK_FOR_SUPER_BOWLING ) { if( dwNewAddr%0x100 == 0 ) { if( dwWidth < 320 ) { // Left half screen gRDP.scissor.left = 0; gRDP.scissor.right = 160; CRender::g_pRender->SetViewport(0, 0, 160, 240, 0xFFFF); CRender::g_pRender->UpdateClipRectangle(); CRender::g_pRender->UpdateScissor(); } else { gRDP.scissor.left = 0; gRDP.scissor.right = 320; CRender::g_pRender->SetViewport(0, 0, 320, 240, 0xFFFF); CRender::g_pRender->UpdateClipRectangle(); CRender::g_pRender->UpdateScissor(); } } else { // right half screen gRDP.scissor.left = 160; gRDP.scissor.right = 320; gRSP.nVPLeftN = 160; gRSP.nVPRightN = 320; CRender::g_pRender->UpdateClipRectangle(); CRender::g_pRender->UpdateScissor(); CRender::g_pRender->SetViewport(160, 0, 320, 240, 0xFFFF); } } if( !frameBufferOptions.bUpdateCIInfo ) { STORE_CI; status.bCIBufferIsRendered = false; status.bN64IsDrawingTextureBuffer = false; TXTRBUF_DUMP(TRACE4("SetCImg : Addr=0x%08X, Fmt:%s-%sb, Width=%d\n", g_CI.dwAddr, pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth)); DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_SET_CIMG, { DebuggerAppendMsg("Pause after SetCImg: Addr=0x%08X, Fmt:%s-%sb, Width=%d\n", dwNewAddr, pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth); } ); return; } SetImgInfo newCI; newCI.bpl = dwBpl; newCI.dwAddr = dwNewAddr; newCI.dwFormat = dwFmt; newCI.dwSize = dwSiz; newCI.dwWidth = dwWidth; g_pFrameBufferManager->Set_CI_addr(newCI); } void DLParser_SetZImg(Gfx *gfx) { DP_Timing(DLParser_SetZImg); LOG_UCODE(" Image: 0x%08x", RSPSegmentAddr(gfx->words.w1)); uint32_t dwFmt = gfx->setimg.fmt; uint32_t dwSiz = gfx->setimg.siz; uint32_t dwWidth = gfx->setimg.width + 1; uint32_t dwAddr = RSPSegmentAddr((gfx->setimg.addr)); if( dwAddr != g_ZI_saves[0].CI_Info.dwAddr ) { g_ZI_saves[1].CI_Info.dwAddr = g_ZI.dwAddr; g_ZI_saves[1].CI_Info.dwFormat = g_ZI.dwFormat; g_ZI_saves[1].CI_Info.dwSize = g_ZI.dwSize; g_ZI_saves[1].CI_Info.dwWidth = g_ZI.dwWidth; g_ZI_saves[1].updateAtFrame = g_ZI_saves[0].updateAtFrame; g_ZI_saves[0].CI_Info.dwAddr = g_ZI.dwAddr = dwAddr; g_ZI_saves[0].CI_Info.dwFormat = g_ZI.dwFormat = dwFmt; g_ZI_saves[0].CI_Info.dwSize = g_ZI.dwSize = dwSiz; g_ZI_saves[0].CI_Info.dwWidth = g_ZI.dwWidth = dwWidth; g_ZI_saves[0].updateAtFrame = status.gDlistCount; } else { g_ZI.dwAddr = dwAddr; g_ZI.dwFormat = dwFmt; g_ZI.dwSize = dwSiz; g_ZI.dwWidth = dwWidth; } DEBUGGER_IF_DUMP((pauseAtNext) , {DebuggerAppendMsg("SetZImg: Addr=0x%08X, Fmt:%s-%sb, Width=%d\n", g_ZI.dwAddr, pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth);} ); DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_SET_CIMG, { DebuggerAppendMsg("Pause after SetZImg: Addr=0x%08X, Fmt:%s-%sb, Width=%d\n", g_ZI.dwAddr, pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth); } ); } bool IsUsedAsDI(uint32_t addr) { if( addr == g_ZI_saves[0].CI_Info.dwAddr ) return true; else if( addr == g_ZI_saves[1].CI_Info.dwAddr && status.gDlistCount - g_ZI_saves[1].updateAtFrame < 10 && g_ZI_saves[1].CI_Info.dwAddr != 0 ) return true; else return false; } void DLParser_SetCombine(Gfx *gfx) { DP_Timing(DLParser_SetCombine); uint32_t dwMux0 = (gfx->words.w0)&0x00FFFFFF; uint32_t dwMux1 = (gfx->words.w1); CRender::g_pRender->SetMux(dwMux0, dwMux1); } void DLParser_SetFillColor(Gfx *gfx) { DP_Timing(DLParser_SetFillColor); gRDP.fillColor = Convert555ToRGBA(gfx->setcolor.fillcolor); gRDP.originalFillColor = (gfx->setcolor.color); LOG_UCODE(" Color5551=0x%04x = 0x%08x", (uint16_t)gfx->words.w1, gRDP.fillColor); } void DLParser_SetFogColor(Gfx *gfx) { DP_Timing(DLParser_SetFogColor); CRender::g_pRender->SetFogColor( gfx->setcolor.r, gfx->setcolor.g, gfx->setcolor.b, gfx->setcolor.a ); FOG_DUMP(TRACE1("Set Fog color: %08X", gfx->setcolor.color)); } void DLParser_SetBlendColor(Gfx *gfx) { DP_Timing(DLParser_SetBlendColor); CRender::g_pRender->SetAlphaRef(gfx->setcolor.a); } void DLParser_SetPrimColor(Gfx *gfx) { DP_Timing(DLParser_SetPrimColor); SetPrimitiveColor( COLOR_RGBA(gfx->setcolor.r, gfx->setcolor.g, gfx->setcolor.b, gfx->setcolor.a), gfx->setcolor.prim_min_level, gfx->setcolor.prim_level); } void DLParser_SetEnvColor(Gfx *gfx) { DP_Timing(DLParser_SetEnvColor); SetEnvColor( COLOR_RGBA(gfx->setcolor.r, gfx->setcolor.g, gfx->setcolor.b, gfx->setcolor.a) ); } void RDP_DLParser_Process(void) { status.gRDPTime = (uint32_t) SDL_GetTicks(); status.gDlistCount++; uint32_t start = *(gfx_info.DPC_START_REG); uint32_t end = *(gfx_info.DPC_END_REG); uint32_t *rdram_u32 = (uint32_t*)gfx_info.RDRAM; gDlistStackPointer=0; gDlistStack[gDlistStackPointer].pc = start; gDlistStack[gDlistStackPointer].countdown = MAX_DL_COUNT; // Check if we need to purge (every 5 milliseconds) if (status.gRDPTime - status.lastPurgeTimeTime > 5) { gTextureManager.PurgeOldTextures(); status.lastPurgeTimeTime = status.gRDPTime; } // Lock the graphics context here. CRender::g_pRender->SetFillMode(RICE_FILLMODE_SOLID); SetVIScales(); CRender::g_pRender->RenderReset(); CRender::g_pRender->BeginRendering(); CRender::g_pRender->SetViewport(0, 0, windowSetting.uViWidth, windowSetting.uViHeight, 0x3FF); while( gDlistStack[gDlistStackPointer].pc < end ) { Gfx *pgfx = (Gfx*)&rdram_u32[(gDlistStack[gDlistStackPointer].pc>>2)]; gDlistStack[gDlistStackPointer].pc += 8; currentUcodeMap[pgfx->words.w0 >>24](pgfx); } CRender::g_pRender->EndRendering(); } void RDP_TriFill(Gfx *gfx) { } void RDP_TriFillZ(Gfx *gfx) { } void RDP_TriTxtr(Gfx *gfx) { } void RDP_TriTxtrZ(Gfx *gfx) { } void RDP_TriShade(Gfx *gfx) { } void RDP_TriShadeZ(Gfx *gfx) { } void RDP_TriShadeTxtr(Gfx *gfx) { } void RDP_TriShadeTxtrZ(Gfx *gfx) { } static int crc_table_empty = 1; static unsigned int crc_table[256]; static void make_crc_table(void); static void make_crc_table() { /* terms of polynomial defining this crc (except x^32): */ static const uint8_t p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; /* make exclusive-or pattern from polynomial (0xedb88320L) */ unsigned int poly = 0L; for (unsigned int n = 0; n < sizeof(p)/sizeof(uint8_t); n++) poly |= 1L << (31 - p[n]); for (unsigned int n = 0; n < 256; n++) { unsigned int c = n; for (int k = 0; k < 8; k++) { c = (c & 1) ? (poly ^ (c >> 1)) : c >> 1; } crc_table[n] = c; } crc_table_empty = 0; } /* ========================================================================= */ #define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); #define DO2(buf) DO1(buf); DO1(buf); #define DO4(buf) DO2(buf); DO2(buf); #define DO8(buf) DO4(buf); DO4(buf); /* ========================================================================= */ unsigned int ComputeCRC32(unsigned int crc, const uint8_t *buf, unsigned int len) { if (buf == NULL) return 0L; if (crc_table_empty) make_crc_table(); crc = crc ^ 0xffffffffL; while (len >= 8) { DO8(buf); len -= 8; } if (len) { do { DO1(buf); } while (--len); } return crc ^ 0xffffffffL; } Matrix matToLoad; void LoadMatrix(uint32_t addr) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; const float fRecip = 1.0f / 65536.0f; if (addr + 64 > g_dwRamSize) { TRACE1("Mtx: Address invalid (0x%08x)", addr); return; } for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { int hi = *(short *)(rdram_u8 + ((addr+(i<<3)+(j<<1) )^0x2)); int lo = *(unsigned short *)(rdram_u8 + ((addr+(i<<3)+(j<<1) + 32)^0x2)); matToLoad.m[i][j] = (float)((hi<<16) | lo) * fRecip; } } #ifdef DEBUGGER LOG_UCODE( " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\r\n" " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\r\n" " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\r\n" " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\r\n", matToLoad.m[0][0], matToLoad.m[0][1], matToLoad.m[0][2], matToLoad.m[0][3], matToLoad.m[1][0], matToLoad.m[1][1], matToLoad.m[1][2], matToLoad.m[1][3], matToLoad.m[2][0], matToLoad.m[2][1], matToLoad.m[2][2], matToLoad.m[2][3], matToLoad.m[3][0], matToLoad.m[3][1], matToLoad.m[3][2], matToLoad.m[3][3]); #endif // DEBUGGER } mupen64plus-video-gliden64/src/GLideNHQ/README.txt000664 001750 001750 00000010655 12655644434 022466 0ustar00sergiosergio000000 000000 /* * GlideHQ (Texture enhancer library for Glide64) * Version: 1.5 * * Copyright (C) 2007 Hiroshi Morii aka KoolSmoky All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ About: This is a realtime texture enhancer library with hi-resolution texture pack support for Glide64 (http://glide64.emuxhaven.net). Traditional and non-traditional techniques have been used to achieve speed and high image quality even on a 9 year old 3Dfx Voodoo2. Although the 3Dfx Glide3x texture format naming conventions are used, the library can be expanded for generic use. Supported: OS: 32bit Linux and MS Windows Enhancers: Hq4x, Hq2x, Hq2xS, Lq2x, Lq2xS, Super2xSai, x2 Filters: Smooth (1,2,3,4), Sharp (1,2) Compressors: FXT1, S3TC Input formats: GR_TEXFMT_ALPHA_8, GR_TEXFMT_RGB_565, GR_TEXFMT_ARGB_1555, GR_TEXFMT_ARGB_4444, GR_TEXFMT_ARGB_8888, GR_TEXFMT_ALPHA_INTENSITY_44, GR_TEXFMT_ALPHA_INTENSITY_88 Output formats: Same as input unless compression or hires packs are used. Hires texture packs: Rice format (Jabo and GlideHQ format coming later) Acknowledgments: I hope you enjoy GlideHQ (texture enhancer library for Glide64). Greatest thanks to Gonetz for making this happen in his busy time. We've rushed everything to share the eye-candy with all of you N64 emulation fans. I would also like to thank a great friend of mine, Daniel Borca for providing the texture compression code, Maxim Stepin (hq2x 4x), and Derek Liauw Kie Fa (2xSaI) for the filtering engines, Rice for his N64 graphics plugin source code, and Mudlord for the hq2xS lq2xS code. GlideHQ also uses the boost C++ libraries, zlib general purpose compression library, and the Portable Network Graphics library. Thanks to all the developers for making them available. And special thanks to the Glide64 beta testing crew. Without their feedbacks this library would not have seen daylight. Thank you all. The source code for GlideHQ is released in hopes that it will be improved. I know the coding is not on par after so much late night caffeine boosts. If you have suggestions or modifications, please feel free to post them on the Glide64 forum at emuxhaven. Porting the library to other platforms should not be so hard. The coding is done with cross platform compatibility in mind and will build with GCC and GNU make. Currently supported are 32bit Linux and MS Windows. If you are looking for driver updates for your 3Dfx Interactive Inc. gfx card, grab them from the forums at http://www.3dfxzone.it/enboard/ Unbelievable as it seems, drivers are still being updated after 6 years from 3Dfx's demise. I know N64 rules, anyone up for PSX? :)) -KoolSmoky References: [1] R.W. Floyd & L. Steinberg, An adaptive algorithm for spatial grey scale, Proceedings of the Society of Information Display 17, pp75-77, 1976 [2] Ken Turkowski, Filters for Common Resampling Tasks, Apple Computer 1990 http://www.worldserver.com/turk/computergraphics/ResamplingFilters.pdf [3] Don P. Mitchell and Arun N. Netravali, Reconstruction Filters in Computer Graphics, SIGGRAPH '88, Proceedings of the 15th annual conference on Computer graphics and interactive techniques, pp221-228, 1988 [4] J. F. Kaiser and W. A. Reed, Data smoothing using low-pass digital filters, Rev. Sci. instrum. 48 (11), pp1447-1457, 1977 [5] Maxim Stepin, hq4x Magnification Filter, http://www.hiend3d.com/hq4x.html [6] Derek Liauw Kie Fa, 2xSaI, http://elektron.its.tudelft.nl/~dalikifa [7] Dirk Stevens, Eagle engine http://www.retrofx.com/rfxtech.html [8] 3DFX_texture_compression_FXT1 and EXT_texture_compression_s3tc extension specs from the OpenGL Extension Registry. http://oss.sgi.com/projects/ ogl-sample/registry/ libretro-common/include/000700 001750 001750 00000000000 12656647145 016441 5ustar00sergiosergio000000 000000 mupen64plus-rsp-hle/src/audio.h000664 001750 001750 00000003714 12655644434 017537 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-rsp-hle - audio.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef AUDIO_H #define AUDIO_H #include #include extern const int16_t RESAMPLE_LUT[64 * 4]; int32_t rdot(size_t n, const int16_t *x, const int16_t *y); #define adpcm_predict_sample(byte, mask, lshift, rshift) (((int16_t)(((uint16_t)((byte) & (mask)) << (lshift))) >> (rshift))) void adpcm_compute_residuals(int16_t* dst, const int16_t* src, const int16_t* cb_entry, const int16_t* last_samples, size_t count); #endif mupen64plus-rsp-hle/src/audio.c000664 001750 001750 00000015507 12655644434 017535 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-rsp-hle - audio.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include "arithmetics.h" const int16_t RESAMPLE_LUT[64 * 4] = { (int16_t)0x0c39, (int16_t)0x66ad, (int16_t)0x0d46, (int16_t)0xffdf, (int16_t)0x0b39, (int16_t)0x6696, (int16_t)0x0e5f, (int16_t)0xffd8, (int16_t)0x0a44, (int16_t)0x6669, (int16_t)0x0f83, (int16_t)0xffd0, (int16_t)0x095a, (int16_t)0x6626, (int16_t)0x10b4, (int16_t)0xffc8, (int16_t)0x087d, (int16_t)0x65cd, (int16_t)0x11f0, (int16_t)0xffbf, (int16_t)0x07ab, (int16_t)0x655e, (int16_t)0x1338, (int16_t)0xffb6, (int16_t)0x06e4, (int16_t)0x64d9, (int16_t)0x148c, (int16_t)0xffac, (int16_t)0x0628, (int16_t)0x643f, (int16_t)0x15eb, (int16_t)0xffa1, (int16_t)0x0577, (int16_t)0x638f, (int16_t)0x1756, (int16_t)0xff96, (int16_t)0x04d1, (int16_t)0x62cb, (int16_t)0x18cb, (int16_t)0xff8a, (int16_t)0x0435, (int16_t)0x61f3, (int16_t)0x1a4c, (int16_t)0xff7e, (int16_t)0x03a4, (int16_t)0x6106, (int16_t)0x1bd7, (int16_t)0xff71, (int16_t)0x031c, (int16_t)0x6007, (int16_t)0x1d6c, (int16_t)0xff64, (int16_t)0x029f, (int16_t)0x5ef5, (int16_t)0x1f0b, (int16_t)0xff56, (int16_t)0x022a, (int16_t)0x5dd0, (int16_t)0x20b3, (int16_t)0xff48, (int16_t)0x01be, (int16_t)0x5c9a, (int16_t)0x2264, (int16_t)0xff3a, (int16_t)0x015b, (int16_t)0x5b53, (int16_t)0x241e, (int16_t)0xff2c, (int16_t)0x0101, (int16_t)0x59fc, (int16_t)0x25e0, (int16_t)0xff1e, (int16_t)0x00ae, (int16_t)0x5896, (int16_t)0x27a9, (int16_t)0xff10, (int16_t)0x0063, (int16_t)0x5720, (int16_t)0x297a, (int16_t)0xff02, (int16_t)0x001f, (int16_t)0x559d, (int16_t)0x2b50, (int16_t)0xfef4, (int16_t)0xffe2, (int16_t)0x540d, (int16_t)0x2d2c, (int16_t)0xfee8, (int16_t)0xffac, (int16_t)0x5270, (int16_t)0x2f0d, (int16_t)0xfedb, (int16_t)0xff7c, (int16_t)0x50c7, (int16_t)0x30f3, (int16_t)0xfed0, (int16_t)0xff53, (int16_t)0x4f14, (int16_t)0x32dc, (int16_t)0xfec6, (int16_t)0xff2e, (int16_t)0x4d57, (int16_t)0x34c8, (int16_t)0xfebd, (int16_t)0xff0f, (int16_t)0x4b91, (int16_t)0x36b6, (int16_t)0xfeb6, (int16_t)0xfef5, (int16_t)0x49c2, (int16_t)0x38a5, (int16_t)0xfeb0, (int16_t)0xfedf, (int16_t)0x47ed, (int16_t)0x3a95, (int16_t)0xfeac, (int16_t)0xfece, (int16_t)0x4611, (int16_t)0x3c85, (int16_t)0xfeab, (int16_t)0xfec0, (int16_t)0x4430, (int16_t)0x3e74, (int16_t)0xfeac, (int16_t)0xfeb6, (int16_t)0x424a, (int16_t)0x4060, (int16_t)0xfeaf, (int16_t)0xfeaf, (int16_t)0x4060, (int16_t)0x424a, (int16_t)0xfeb6, (int16_t)0xfeac, (int16_t)0x3e74, (int16_t)0x4430, (int16_t)0xfec0, (int16_t)0xfeab, (int16_t)0x3c85, (int16_t)0x4611, (int16_t)0xfece, (int16_t)0xfeac, (int16_t)0x3a95, (int16_t)0x47ed, (int16_t)0xfedf, (int16_t)0xfeb0, (int16_t)0x38a5, (int16_t)0x49c2, (int16_t)0xfef5, (int16_t)0xfeb6, (int16_t)0x36b6, (int16_t)0x4b91, (int16_t)0xff0f, (int16_t)0xfebd, (int16_t)0x34c8, (int16_t)0x4d57, (int16_t)0xff2e, (int16_t)0xfec6, (int16_t)0x32dc, (int16_t)0x4f14, (int16_t)0xff53, (int16_t)0xfed0, (int16_t)0x30f3, (int16_t)0x50c7, (int16_t)0xff7c, (int16_t)0xfedb, (int16_t)0x2f0d, (int16_t)0x5270, (int16_t)0xffac, (int16_t)0xfee8, (int16_t)0x2d2c, (int16_t)0x540d, (int16_t)0xffe2, (int16_t)0xfef4, (int16_t)0x2b50, (int16_t)0x559d, (int16_t)0x001f, (int16_t)0xff02, (int16_t)0x297a, (int16_t)0x5720, (int16_t)0x0063, (int16_t)0xff10, (int16_t)0x27a9, (int16_t)0x5896, (int16_t)0x00ae, (int16_t)0xff1e, (int16_t)0x25e0, (int16_t)0x59fc, (int16_t)0x0101, (int16_t)0xff2c, (int16_t)0x241e, (int16_t)0x5b53, (int16_t)0x015b, (int16_t)0xff3a, (int16_t)0x2264, (int16_t)0x5c9a, (int16_t)0x01be, (int16_t)0xff48, (int16_t)0x20b3, (int16_t)0x5dd0, (int16_t)0x022a, (int16_t)0xff56, (int16_t)0x1f0b, (int16_t)0x5ef5, (int16_t)0x029f, (int16_t)0xff64, (int16_t)0x1d6c, (int16_t)0x6007, (int16_t)0x031c, (int16_t)0xff71, (int16_t)0x1bd7, (int16_t)0x6106, (int16_t)0x03a4, (int16_t)0xff7e, (int16_t)0x1a4c, (int16_t)0x61f3, (int16_t)0x0435, (int16_t)0xff8a, (int16_t)0x18cb, (int16_t)0x62cb, (int16_t)0x04d1, (int16_t)0xff96, (int16_t)0x1756, (int16_t)0x638f, (int16_t)0x0577, (int16_t)0xffa1, (int16_t)0x15eb, (int16_t)0x643f, (int16_t)0x0628, (int16_t)0xffac, (int16_t)0x148c, (int16_t)0x64d9, (int16_t)0x06e4, (int16_t)0xffb6, (int16_t)0x1338, (int16_t)0x655e, (int16_t)0x07ab, (int16_t)0xffbf, (int16_t)0x11f0, (int16_t)0x65cd, (int16_t)0x087d, (int16_t)0xffc8, (int16_t)0x10b4, (int16_t)0x6626, (int16_t)0x095a, (int16_t)0xffd0, (int16_t)0x0f83, (int16_t)0x6669, (int16_t)0x0a44, (int16_t)0xffd8, (int16_t)0x0e5f, (int16_t)0x6696, (int16_t)0x0b39, (int16_t)0xffdf, (int16_t)0x0d46, (int16_t)0x66ad, (int16_t)0x0c39 }; int32_t rdot(size_t n, const int16_t *x, const int16_t *y) { int32_t accu = 0; while (n-- != 0) accu += *(x++) * *(--y); return accu; } void adpcm_compute_residuals(int16_t* dst, const int16_t* src, const int16_t* cb_entry, const int16_t* last_samples, size_t count) { size_t i; const int16_t* const book1 = cb_entry; const int16_t* const book2 = cb_entry + 8; const int16_t l1 = last_samples[0]; const int16_t l2 = last_samples[1]; for(i = 0; i < count; ++i) { int32_t accu = (int32_t)src[i] << 11; accu += book1[i]*l1 + book2[i]*l2 + rdot(i, book2, src + i); dst[i] = clamp_s16(accu >> 11); } } mupen64plus-core/src/plugin/audio_libretro/drivers_resampler/000700 001750 001750 00000000000 12656647145 025656 5ustar00sergiosergio000000 000000 mupen64plus-rsp-cxd4/vu/shuffle.h000664 001750 001750 00000017133 12655644434 020027 0ustar00sergiosergio000000 000000 /******************************************************************************\ * Authors: Iconoclast * * Release: 2013.12.04 * * License: CC0 Public Domain Dedication * * * * To the extent possible under law, the author(s) have dedicated all copyright * * and related and neighboring rights to this software to the public domain * * worldwide. This software is distributed without any warranty. * * * * You should have received a copy of the CC0 Public Domain Dedication along * * with this software. * * If not, see . * \******************************************************************************/ #ifndef _SHUFFLE_H #define _SHUFFLE_H #ifndef ARCH_MIN_SSE2 /* * vector-scalar element decoding * Obsolete. Consider using at least the SSE2 algorithms instead. */ static const int ei[16][8] = { { 00, 01, 02, 03, 04, 05, 06, 07 }, /* none (vector-only operand) */ { 00, 01, 02, 03, 04, 05, 06, 07 }, { 00, 00, 02, 02, 04, 04, 06, 06 }, /* 0Q */ { 01, 01, 03, 03, 05, 05, 07, 07 }, /* 1Q */ { 00, 00, 00, 00, 04, 04, 04, 04 }, /* 0H */ { 01, 01, 01, 01, 05, 05, 05, 05 }, /* 1H */ { 02, 02, 02, 02, 06, 06, 06, 06 }, /* 2H */ { 03, 03, 03, 03, 07, 07, 07, 07 }, /* 3H */ { 00, 00, 00, 00, 00, 00, 00, 00 }, /* 0 */ { 01, 01, 01, 01, 01, 01, 01, 01 }, /* 1 */ { 02, 02, 02, 02, 02, 02, 02, 02 }, /* 2 */ { 03, 03, 03, 03, 03, 03, 03, 03 }, /* 3 */ { 04, 04, 04, 04, 04, 04, 04, 04 }, /* 4 */ { 05, 05, 05, 05, 05, 05, 05, 05 }, /* 5 */ { 06, 06, 06, 06, 06, 06, 06, 06 }, /* 6 */ { 07, 07, 07, 07, 07, 07, 07, 07 } /* 7 */ }; int sub_mask[16] = { 0x0, 0x0, 0x1, 0x1, 0x3, 0x3, 0x3, 0x3, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7 }; static INLINE void SHUFFLE_VECTOR(short* VD, short* VT, const int e) { short SV[8]; register int i, j; #if (0 == 0) j = sub_mask[e]; for (i = 0; i < N; i++) SV[i] = VT[(i & ~j) | (e & j)]; #else if (e & 0x8) for (i = 0; i < N; i++) SV[i] = VT[(i & 0x0) | (e & 0x7)]; else if (e & 0x4) for (i = 0; i < N; i++) SV[i] = VT[(i & 0xC) | (e & 0x3)]; else if (e & 0x2) for (i = 0; i < N; i++) SV[i] = VT[(i & 0xE) | (e & 0x1)]; else /* if ((e == 0b0000) || (e == 0b0001)) */ for (i = 0; i < N; i++) SV[i] = VT[(i & 0x7) | (e & 0x0)]; #endif for (i = 0; i < N; i++) *(VD + i) = *(SV + i); } #else #ifdef ARCH_MIN_SSSE3 static const unsigned char smask[16][16] = { {0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF}, {0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF}, {0x0,0x1,0x0,0x1,0x4,0x5,0x4,0x5,0x8,0x9,0x8,0x9,0xC,0xD,0xC,0xD}, {0x2,0x3,0x2,0x3,0x6,0x7,0x6,0x7,0xA,0xB,0xA,0xB,0xE,0xF,0xE,0xF}, {0x0,0x1,0x0,0x1,0x0,0x1,0x0,0x1,0x8,0x9,0x8,0x9,0x8,0x9,0x8,0x9}, {0x2,0x3,0x2,0x3,0x2,0x3,0x2,0x3,0xA,0xB,0xA,0xB,0xA,0xB,0xA,0xB}, {0x4,0x5,0x4,0x5,0x4,0x5,0x4,0x5,0xC,0xD,0xC,0xD,0xC,0xD,0xC,0xD}, {0x6,0x7,0x6,0x7,0x6,0x7,0x6,0x7,0xE,0xF,0xE,0xF,0xE,0xF,0xE,0xF}, {0x0,0x1,0x0,0x1,0x0,0x1,0x0,0x1,0x0,0x1,0x0,0x1,0x0,0x1,0x0,0x1}, {0x2,0x3,0x2,0x3,0x2,0x3,0x2,0x3,0x2,0x3,0x2,0x3,0x2,0x3,0x2,0x3}, {0x4,0x5,0x4,0x5,0x4,0x5,0x4,0x5,0x4,0x5,0x4,0x5,0x4,0x5,0x4,0x5}, {0x6,0x7,0x6,0x7,0x6,0x7,0x6,0x7,0x6,0x7,0x6,0x7,0x6,0x7,0x6,0x7}, {0x8,0x9,0x8,0x9,0x8,0x9,0x8,0x9,0x8,0x9,0x8,0x9,0x8,0x9,0x8,0x9}, {0xA,0xB,0xA,0xB,0xA,0xB,0xA,0xB,0xA,0xB,0xA,0xB,0xA,0xB,0xA,0xB}, {0xC,0xD,0xC,0xD,0xC,0xD,0xC,0xD,0xC,0xD,0xC,0xD,0xC,0xD,0xC,0xD}, {0xE,0xF,0xE,0xF,0xE,0xF,0xE,0xF,0xE,0xF,0xE,0xF,0xE,0xF,0xE,0xF} }; static INLINE void SHUFFLE_VECTOR(short* VD, short* VT, const int e) { /* SSSE3 shuffling method was written entirely by CEN64 author MarathonMan. */ __m128i xmm; __m128i key; xmm = _mm_load_si128((__m128i *)VT); key = _mm_load_si128((__m128i *)(smask[e])); xmm = _mm_shuffle_epi8(xmm, key); _mm_store_si128((__m128i *)VD, xmm); } #else #define B(x) ((x) & 3) /* * Here, the SSE2 implementation is mostly written to be readable, not fast. * * Probably it would be fastest yet to not use SSE instructions to shuffle * at this point, but currently I think the algorithm is a bigger concern. */ #define SHUFFLE(a,b,c,d) ((B(d)<<6) | (B(c)<<4) | (B(b)<<2) | (B(a)<<0)) static __m128i shuffle_none(__m128i xmm) { /* xmm = _mm_shufflehi_epi16(xmm, SHUFFLE(0, 1, 2, 3)); xmm = _mm_shufflelo_epi16(xmm, SHUFFLE(4, 5, 6, 7)); */ return (xmm); } static __m128i shuffle_0q(__m128i xmm) { xmm = _mm_shufflehi_epi16(xmm, SHUFFLE(0, 0, 2, 2)); xmm = _mm_shufflelo_epi16(xmm, SHUFFLE(4, 4, 6, 6)); return (xmm); } static __m128i shuffle_1q(__m128i xmm) { xmm = _mm_shufflehi_epi16(xmm, SHUFFLE(1, 1, 3, 3)); xmm = _mm_shufflelo_epi16(xmm, SHUFFLE(5, 5, 7, 7)); return (xmm); } static __m128i shuffle_0h(__m128i xmm) { xmm = _mm_shufflehi_epi16(xmm, SHUFFLE(0, 0, 0, 0)); xmm = _mm_shufflelo_epi16(xmm, SHUFFLE(4, 4, 4, 4)); return (xmm); } static __m128i shuffle_1h(__m128i xmm) { xmm = _mm_shufflehi_epi16(xmm, SHUFFLE(1, 1, 1, 1)); xmm = _mm_shufflelo_epi16(xmm, SHUFFLE(5, 5, 5, 5)); return (xmm); } static __m128i shuffle_2h(__m128i xmm) { xmm = _mm_shufflehi_epi16(xmm, SHUFFLE(2, 2, 2, 2)); xmm = _mm_shufflelo_epi16(xmm, SHUFFLE(6, 6, 6, 6)); return (xmm); } static __m128i shuffle_3h(__m128i xmm) { xmm = _mm_shufflehi_epi16(xmm, SHUFFLE(3, 3, 3, 3)); xmm = _mm_shufflelo_epi16(xmm, SHUFFLE(7, 7, 7, 7)); return (xmm); } static __m128i shuffle_0w(__m128i xmm) { xmm = _mm_shufflelo_epi16(xmm, SHUFFLE(0, 0, 0, 0)); xmm = _mm_unpacklo_epi16(xmm, xmm); return (xmm); } static __m128i shuffle_1w(__m128i xmm) { xmm = _mm_shufflelo_epi16(xmm, SHUFFLE(1, 1, 1, 1)); xmm = _mm_unpacklo_epi16(xmm, xmm); return (xmm); } static __m128i shuffle_2w(__m128i xmm) { xmm = _mm_shufflelo_epi16(xmm, SHUFFLE(2, 2, 2, 2)); xmm = _mm_unpacklo_epi16(xmm, xmm); return (xmm); } static __m128i shuffle_3w(__m128i xmm) { xmm = _mm_shufflelo_epi16(xmm, SHUFFLE(3, 3, 3, 3)); xmm = _mm_unpacklo_epi16(xmm, xmm); return (xmm); } static __m128i shuffle_4w(__m128i xmm) { xmm = _mm_shufflehi_epi16(xmm, SHUFFLE(4, 4, 4, 4)); xmm = _mm_unpackhi_epi16(xmm, xmm); return (xmm); } static __m128i shuffle_5w(__m128i xmm) { xmm = _mm_shufflehi_epi16(xmm, SHUFFLE(5, 5, 5, 5)); xmm = _mm_unpackhi_epi16(xmm, xmm); return (xmm); } static __m128i shuffle_6w(__m128i xmm) { xmm = _mm_shufflehi_epi16(xmm, SHUFFLE(6, 6, 6, 6)); xmm = _mm_unpackhi_epi16(xmm, xmm); return (xmm); } static __m128i shuffle_7w(__m128i xmm) { xmm = _mm_shufflehi_epi16(xmm, SHUFFLE(7, 7, 7, 7)); xmm = _mm_unpackhi_epi16(xmm, xmm); return (xmm); } static __m128i (*SSE2_SHUFFLE_16[16])(__m128i) = { shuffle_none, shuffle_none, shuffle_0q, shuffle_1q, shuffle_0h, shuffle_1h, shuffle_2h, shuffle_3h, shuffle_0w, shuffle_1w, shuffle_2w, shuffle_3w, shuffle_4w, shuffle_5w, shuffle_6w, shuffle_7w }; INLINE static void SHUFFLE_VECTOR(short* VD, short* VT, const int e) { __m128i xmm; xmm = _mm_load_si128((__m128i *)VT); xmm = SSE2_SHUFFLE_16[e](xmm); _mm_store_si128((__m128i *)VD, xmm); return; } #endif #endif #endif mupen64plus-core/src/rdp/fb.h000664 001750 001750 00000004146 12655644434 017170 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - fb.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_RDP_FB_H #define M64P_RDP_FB_H #include #include "../api/m64p_plugin.h" struct rdp_core; enum { FB_INFOS_COUNT = 6 }; enum { FB_DIRTY_PAGES_COUNT = 0x800 }; struct fb { unsigned char dirty_page[FB_DIRTY_PAGES_COUNT]; FrameBufferInfo infos[FB_INFOS_COUNT]; unsigned int once; }; void init_fb(struct fb* fb); int read_rdram_fb(void* opaque, uint32_t address, uint32_t* value); int write_rdram_fb(void* opaque, uint32_t address, uint32_t value, uint32_t mask); void protect_framebuffers(struct rdp_core* dp); void unprotect_framebuffers(struct rdp_core* dp); #endif gles2n64/src/F3DSWSE.h000664 001750 001750 00000000112 12655644434 015273 0ustar00sergiosergio000000 000000 #ifndef F3DSWSE_H #define F3DSWSE_H void F3DSWSE_Init(); #endif mupen64plus-video-gliden64/src/convert.h000664 001750 001750 00000012575 12655644434 021271 0ustar00sergiosergio000000 000000 #ifndef CONVERT_H #define CONVERT_H #include "Types.h" const volatile unsigned char Five2Eight[32] = { 0, // 00000 = 00000000 8, // 00001 = 00001000 16, // 00010 = 00010000 25, // 00011 = 00011001 33, // 00100 = 00100001 41, // 00101 = 00101001 49, // 00110 = 00110001 58, // 00111 = 00111010 66, // 01000 = 01000010 74, // 01001 = 01001010 82, // 01010 = 01010010 90, // 01011 = 01011010 99, // 01100 = 01100011 107, // 01101 = 01101011 115, // 01110 = 01110011 123, // 01111 = 01111011 132, // 10000 = 10000100 140, // 10001 = 10001100 148, // 10010 = 10010100 156, // 10011 = 10011100 165, // 10100 = 10100101 173, // 10101 = 10101101 181, // 10110 = 10110101 189, // 10111 = 10111101 197, // 11000 = 11000101 206, // 11001 = 11001110 214, // 11010 = 11010110 222, // 11011 = 11011110 230, // 11100 = 11100110 239, // 11101 = 11101111 247, // 11110 = 11110111 255 // 11111 = 11111111 }; const volatile unsigned char Four2Eight[16] = { 0, // 0000 = 00000000 17, // 0001 = 00010001 34, // 0010 = 00100010 51, // 0011 = 00110011 68, // 0100 = 01000100 85, // 0101 = 01010101 102, // 0110 = 01100110 119, // 0111 = 01110111 136, // 1000 = 10001000 153, // 1001 = 10011001 170, // 1010 = 10101010 187, // 1011 = 10111011 204, // 1100 = 11001100 221, // 1101 = 11011101 238, // 1110 = 11101110 255 // 1111 = 11111111 }; const volatile unsigned char Three2Four[8] = { 0, // 000 = 0000 2, // 001 = 0010 4, // 010 = 0100 6, // 011 = 0110 9, // 100 = 1001 11, // 101 = 1011 13, // 110 = 1101 15, // 111 = 1111 }; const volatile unsigned char Three2Eight[8] = { 0, // 000 = 00000000 36, // 001 = 00100100 73, // 010 = 01001001 109, // 011 = 01101101 146, // 100 = 10010010 182, // 101 = 10110110 219, // 110 = 11011011 255, // 111 = 11111111 }; const volatile unsigned char Two2Eight[4] = { 0, // 00 = 00000000 85, // 01 = 01010101 170, // 10 = 10101010 255 // 11 = 11111111 }; const volatile unsigned char One2Four[2] = { 0, // 0 = 0000 15, // 1 = 1111 }; const volatile unsigned char One2Eight[2] = { 0, // 0 = 00000000 255, // 1 = 11111111 }; static INLINE void UnswapCopyWrap(const u8 *src, u32 srcIdx, u8 *dest, u32 destIdx, u32 destMask, u32 numBytes) { // copy leading bytes u32 leadingBytes = srcIdx & 3; if (leadingBytes != 0) { leadingBytes = 4 - leadingBytes; if ((u32)leadingBytes > numBytes) leadingBytes = numBytes; numBytes -= leadingBytes; srcIdx ^= 3; for (int i = 0; i < leadingBytes; i++) { dest[destIdx&destMask] = src[srcIdx]; ++destIdx; --srcIdx; } srcIdx += 5; } // copy dwords int numDWords = numBytes >> 2; while (numDWords--) { dest[(destIdx + 3) & destMask] = src[srcIdx++]; dest[(destIdx + 2) & destMask] = src[srcIdx++]; dest[(destIdx + 1) & destMask] = src[srcIdx++]; dest[(destIdx + 0) & destMask] = src[srcIdx++]; destIdx += 4; } // copy trailing bytes int trailingBytes = numBytes & 3; if (trailingBytes) { srcIdx ^= 3; for (int i = 0; i < trailingBytes; i++) { dest[destIdx&destMask] = src[srcIdx]; ++destIdx; --srcIdx; } } } static INLINE void DWordInterleaveWrap(u32 *src, u32 srcIdx, u32 srcMask, u32 numQWords) { u32 tmp; while (numQWords--) { tmp = src[srcIdx & srcMask]; src[srcIdx & srcMask] = src[(srcIdx + 1) & srcMask]; ++srcIdx; src[srcIdx & srcMask] = tmp; ++srcIdx; } } static INLINE u16 swapword( u16 value ) { #ifdef ARM_ASM asm("rev16 %0, %0" : "+r"(value)::); return value; #else return (value << 8) | (value >> 8); #endif // ARM_ASM } inline u16 RGBA8888_RGBA4444( u32 color ) { return ((color & 0x000000f0) << 8) | // r ((color & 0x0000f000) >> 4) | // g ((color & 0x00f00000) >> 16) | // b ((color & 0xf0000000) >> 28); // a } inline u32 RGBA5551_RGBA8888( u16 color ) { color = swapword( color ); u8 r, g, b, a; r = Five2Eight[color >> 11]; g = Five2Eight[(color >> 6) & 0x001f]; b = Five2Eight[(color >> 1) & 0x001f]; a = One2Eight [(color ) & 0x0001]; return (a << 24) | (b << 16) | (g << 8) | r; } // Just swaps the word inline u16 RGBA5551_RGBA5551( u16 color ) { return swapword( color ); } inline u32 IA88_RGBA8888( u16 color ) { // ok u8 a = color >> 8; u8 i = color & 0x00FF; return (a << 24) | (i << 16) | (i << 8) | i; } inline u16 IA88_RGBA4444( u16 color ) { u8 i = color >> 12; u8 a = (color >> 4) & 0x000F; return (i << 12) | (i << 8) | (i << 4) | a; } inline u16 IA44_RGBA4444( u8 color ) { return ((color & 0xf0) << 8) | ((color & 0xf0) << 4) | (color); } inline u32 IA44_RGBA8888( u8 color ) { u8 i = Four2Eight[color >> 4]; u8 a = Four2Eight[color & 0x0F]; return (a << 24) | (i << 16) | (i << 8) | i; } inline u16 IA31_RGBA4444( u8 color ) { u8 i = Three2Four[color >> 1]; u8 a = One2Four[color & 0x01]; return (i << 12) | (i << 8) | (i << 4) | a; } inline u32 IA31_RGBA8888( u8 color ) { u8 i = Three2Eight[color >> 1]; u8 a = One2Eight[color & 0x01]; return (i << 24) | (i << 16) | (i << 8) | a; } inline u16 I8_RGBA4444( u8 color ) { u8 c = color >> 4; return (c << 12) | (c << 8) | (c << 4) | c; } inline u32 I8_RGBA8888( u8 color ) { return (color << 24) | (color << 16) | (color << 8) | color; } inline u16 I4_RGBA4444( u8 color ) { u16 ret = color & 0x0f; ret |= ret << 4; ret |= ret << 8; return ret; } inline u32 I4_RGBA8888( u8 color ) { u8 c = Four2Eight[color]; c |= c << 4; return (c << 24) | (c << 16) | (c << 8) | c; } #endif // CONVERT_H mupen64plus-core/src/api/000700 001750 001750 00000000000 12656647145 016376 5ustar00sergiosergio000000 000000 gles2rice/src/OGLExtRender.h000664 001750 001750 00000003036 12655644434 017002 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _OGL_EXT_RENDER_H_ #define _OGL_EXT_RENDER_H_ #include "OGLRender.h" class COGLExtRender : public OGLRender { public: void Initialize(void); void BindTexture(GLuint texture, int unitno); void DisBindTexture(GLuint texture, int unitno); void TexCoord2f(float u, float v); void TexCoord(TLITVERTEX &vtxInfo); void SetTextureUFlag(TextureUVFlag dwFlag, uint32_t tile); void SetTextureVFlag(TextureUVFlag dwFlag, uint32_t tile); void EnableTexUnit(int unitno, bool flag); void SetTexWrapS(int unitno,GLuint flag); void SetTexWrapT(int unitno,GLuint flag); void ApplyTextureFilter(); void SetTextureToTextureUnitMap(int tex, int unit); protected: friend class OGLDeviceBuilder; COGLExtRender() {}; ~COGLExtRender() {}; GLint m_maxTexUnits; int m_textureUnitMap[8]; }; #endif mupen64plus-core/src/rdp/fb.c000664 001750 001750 00000013574 12655644434 017170 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - fb.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "fb.h" #include "rdp_core.h" #include "../memory/memory.h" #include "../plugin/plugin.h" #include "../r4300/r4300_core.h" #include "../ri/ri_controller.h" extern int fast_memory; #include void init_fb(struct fb* fb) { memset(fb, 0, sizeof(*fb)); fb->once = 1; } static void pre_framebuffer_read(struct fb* fb, uint32_t address) { size_t i; for(i = 0; i < FB_INFOS_COUNT; ++i) { if (fb->infos[i].addr) { unsigned int start = fb->infos[i].addr & 0x7FFFFF; unsigned int end = start + fb->infos[i].width* fb->infos[i].height* fb->infos[i].size - 1; if ((address & 0x7FFFFF) >= start && (address & 0x7FFFFF) <= end && fb->dirty_page[(address & 0x7FFFFF)>>12]) { gfx.fBRead(address); fb->dirty_page[(address & 0x7FFFFF)>>12] = 0; } } } } static void pre_framebuffer_write(struct fb* fb, uint32_t address) { size_t i; for(i = 0; i < FB_INFOS_COUNT; ++i) { if (fb->infos[i].addr) { unsigned int start = fb->infos[i].addr & 0x7FFFFF; unsigned int end = start + fb->infos[i].width* fb->infos[i].height* fb->infos[i].size - 1; if ((address & 0x7FFFFF) >= start && (address & 0x7FFFFF) <= end) gfx.fBWrite(address, 4); } } } int read_rdram_fb(void* opaque, uint32_t address, uint32_t* value) { struct rdp_core* dp = (struct rdp_core*)opaque; pre_framebuffer_read(&dp->fb, address); return read_rdram_dram(dp->ri, address, value); } int write_rdram_fb(void* opaque, uint32_t address, uint32_t value, uint32_t mask) { struct rdp_core* dp = (struct rdp_core*)opaque; pre_framebuffer_write(&dp->fb, address); return write_rdram_dram(dp->ri, address, value, mask); } #define R(x) read_ ## x ## b, read_ ## x ## h, read_ ## x, read_ ## x ## d #define W(x) write_ ## x ## b, write_ ## x ## h, write_ ## x, write_ ## x ## d #define RW(x) R(x), W(x) void protect_framebuffers(struct rdp_core* dp) { struct fb* fb = &dp->fb; if (gfx.fBGetFrameBufferInfo && gfx.fBRead && gfx.fBWrite) gfx.fBGetFrameBufferInfo(fb->infos); if (!gfx.fBGetFrameBufferInfo) return; if (!gfx.fBRead && gfx.fBWrite) return; if (fb->infos[0].addr) { size_t i; for(i = 0; i < FB_INFOS_COUNT; ++i) { if (fb->infos[i].addr) { int j; int start = fb->infos[i].addr & 0x7FFFFF; int end = start + fb->infos[i].width* fb->infos[i].height* fb->infos[i].size - 1; int start1 = start; int end1 = end; start >>= 16; end >>= 16; for (j = start; j <= end; j++) { map_region(0x8000+j, M64P_MEM_RDRAM, RW(rdramFB)); map_region(0xa000+j, M64P_MEM_RDRAM, RW(rdramFB)); } start <<= 4; end <<= 4; for (j=start; j<=end; j++) { if (j >= start1 && j <= end1) fb->dirty_page[j] = 1; else fb->dirty_page[j] = 0; } if (fb->once != 0) { fb->once = 0; fast_memory = 0; invalidate_r4300_cached_code(0, 0); } } } } } void unprotect_framebuffers(struct rdp_core* dp) { struct fb* fb = &dp->fb; if (!gfx.fBGetFrameBufferInfo) return; if (!gfx.fBRead && gfx.fBWrite) return; if (fb->infos[0].addr) { size_t i; for(i = 0; i < FB_INFOS_COUNT; ++i) { if (fb->infos[i].addr) { int j; int start = fb->infos[i].addr & 0x7FFFFF; int end = start + fb->infos[i].width * fb->infos[i].height* fb->infos[i].size - 1; start = start >> 16; end = end >> 16; for (j = start; j <= end; j++) { map_region(0x8000+j, M64P_MEM_RDRAM, RW(rdram)); map_region(0xa000+j, M64P_MEM_RDRAM, RW(rdram)); } } } } } gles2rice/RELEASE000664 001750 001750 00000011525 12655644434 014605 0ustar00sergiosergio000000 000000 Mupen64Plus-Video-Rice RELEASE ------------------------------ Mupen64Plus-Video-Rice v2.0 - July 4, 2013 ------------------------------------------ - support for resizable video window - add support to build and run with OpenGL ES 2.0 - improve hi-resolution texture loading support - fix texture CRC calculation for non-x86 (or NO_ASM) platforms - support to build against SDL2 - Project files for Visual Studio 2012 - Makefile changes - add support for PowerPC and MinGW32 builds - add cross-compiling support to build Win32 executables (MXE) under Linux Mupen64Plus-Video-Rice v1.99.5 - March 10, 2012 ----------------------------------------------- - Hires texture loading: support for 8-bit PNG images - New config option for forcing vertical sync - Check OpenGL attributes after creating video window and report any that failed to set - Updated video plugin for new Mupen64plus 2.0 API versioning scheme - Update to Video API version 2.1.0. - Bugfix: hi-res textures: Scale highres textures by precalculated scaleShift exponent - Bugfix: dont call CoreVideo_Init() inside of the InitializeGFX() function. This will fix some front-end use cases - Bugfix: Fix z coordinate in 3d line rendering - Bugfix: double infinite loop in GetValidTmemInfoIndex - Bugfix: Perfect Dark randomly crashes due to divide-by-zero error - Bugfix: crash in loading Celda 2009 hi-res texture pack for Zelda Ocarina of Time - makefile fixes, improvements, and code cleanups Mupen64Plus-Video-Rice v1.99.4 - November 22, 2010 -------------------------------------------------- - new feature: anisotropic filtering - new feature: trilinear filtering - new feature: mipmaps - cleaned up FindScaleFactor function based upon r45 of the 1964 repo - bugfix: buffer overrun (and crash) when reading vendor string info on some opengl implementations - API change for reading the video buffer: new interface is more flexible and avoids some potential problems - support for anti-aliasing (GL_MULTISAMPLE) - makefile fixes, improvements, and code cleanups Mupen64Plus-Video-Rice v1.99.3 - February 13, 2010 -------------------------------------------------- - sync with core<-->plugin API change for RomOpen() - Changed default ScreenUpdateSetting to 1 for Linux, and 4 for Windows - use custom opengl extension function pointer typedefs, to avoid compilation errors with some drivers including hosed gl.h headers - merged some changes from Tillin9 commits in r1142-rice-video-gtk-refactor branch, to be more lenient in hi-res texture loading - bugfix: hi-res textures did not work in Windows - bugfix: #329: remove some deprecated types and a function call to prevent build errors with libpng 1.4 - bugfix: fixed mirroring bugs in Rice Video hi-resolution texture loading, based on Tillin9 rev 1337 in r1142-rice-video-gtk-refactor branch - bugfix: in ConvertImage.cpp none of the 4-bit conversion functions could handle 1-pixel wide textures - Makefile improvements: - added OS type GNU/kFreeBSD Mupen64Plus-Video-Rice v1.99.2 - January 6, 2010 -------------------------------------------------- - bugfix: fix fragment program combiner for Intel drivers in Win32, by ensuring that program does not allocate unused temp vars or call TEX commands for texture units that are not enabled - new feature: compile-time option for opengl debugging by calling glGetError after each opengl command (except inside of glBegin/glEnd) - portability: use ALIGN() for aligned data member declarations in header files as well as the definitions in CPP files - portability: refactor opengl code to use VidExt_GL_GetProc() for all opengl functions newer than v1.1, so that this will work in Windows - portability: Abstracted directory-handling code with new osal_files* source code - portability: replaced unix gettimeofday() function calls with SDL_GetTicks() - new feature: added MSVC8 project file, fixed minor incompatibilities with VC compiler - Makefile improvements: - throw error if OS/CPU not supported - use DESTDIR in install/uninstall paths - Allow user-specified CC/CXX/LD paths - use C++ compiler to link instead of LD, because the compiler knows where the standard C++ libs are - OSX hack for inline assembly code: mismatch between function names with-w/o preceding underscores Mupen64Plus-Video-Rice v1.99.1 - December 14, 2009 -------------------------------------------------- - Converted to new Mupen64Plus 2.0 API - Major code cleanup, removed all non-standard data types - Refactored build system to separate source and object files - added NO_ASM build option - removed some unused configuration parameters - bugfix: handle fullscreen video mode properly: start up in this mode instead of always starting in windowed and needing the core to switch to fullscreen - bugfix #209: setjmp/longjmp fixes in the BMP writer and PNG reader - bugfix: eliminated duplicate 'Found ROM ...' messages mupen64plus-rsp-cxd4/vu/divide.h000664 001750 001750 00000041712 12655644434 017637 0ustar00sergiosergio000000 000000 /******************************************************************************\ * Authors: Iconoclast * * Release: 2013.11.26 * * License: CC0 Public Domain Dedication * * * * To the extent possible under law, the author(s) have dedicated all copyright * * and related and neighboring rights to this software to the public domain * * worldwide. This software is distributed without any warranty. * * * * You should have received a copy of the CC0 Public Domain Dedication along * * with this software. * * If not, see . * \******************************************************************************/ static int DivIn = 0; /* buffered numerator of division read from vector file */ static int DivOut = 0; /* global division result set by VRCP/VRCPL/VRSQ/VRSQH */ #if (0) static int MovIn; /* We do not emulate this register (obsolete, for VMOV). */ #endif static int DPH; /* * Boolean flag: Double-precision high was the last vector divide op? * * if (lastDivideOp == VRCP, VRCPL, VRSQ, VRSQL) * DPH = false; // single-precision or double-precision low, not high * else if (lastDivideOp == VRCPH, VRSQH) * DPH = true; // double-precision high * else if (lastDivideOp == VMOV, VNOP) * DPH = DPH; // no change, divide-group ops but not real divides */ /* * 11-bit vector divide result look-up table * Thanks to MooglyGuy @ MESS for organizing. */ static const unsigned short div_ROM[1024] = { 0xFFFF, 0xFF00, 0xFE01, 0xFD04, 0xFC07, 0xFB0C, 0xFA11, 0xF918, 0xF81F, 0xF727, 0xF631, 0xF53B, 0xF446, 0xF352, 0xF25F, 0xF16D, 0xF07C, 0xEF8B, 0xEE9C, 0xEDAE, 0xECC0, 0xEBD3, 0xEAE8, 0xE9FD, 0xE913, 0xE829, 0xE741, 0xE65A, 0xE573, 0xE48D, 0xE3A9, 0xE2C5, 0xE1E1, 0xE0FF, 0xE01E, 0xDF3D, 0xDE5D, 0xDD7E, 0xDCA0, 0xDBC2, 0xDAE6, 0xDA0A, 0xD92F, 0xD854, 0xD77B, 0xD6A2, 0xD5CA, 0xD4F3, 0xD41D, 0xD347, 0xD272, 0xD19E, 0xD0CB, 0xCFF8, 0xCF26, 0xCE55, 0xCD85, 0xCCB5, 0xCBE6, 0xCB18, 0xCA4B, 0xC97E, 0xC8B2, 0xC7E7, 0xC71C, 0xC652, 0xC589, 0xC4C0, 0xC3F8, 0xC331, 0xC26B, 0xC1A5, 0xC0E0, 0xC01C, 0xBF58, 0xBE95, 0xBDD2, 0xBD10, 0xBC4F, 0xBB8F, 0xBACF, 0xBA10, 0xB951, 0xB894, 0xB7D6, 0xB71A, 0xB65E, 0xB5A2, 0xB4E8, 0xB42E, 0xB374, 0xB2BB, 0xB203, 0xB14B, 0xB094, 0xAFDE, 0xAF28, 0xAE73, 0xADBE, 0xAD0A, 0xAC57, 0xABA4, 0xAAF1, 0xAA40, 0xA98E, 0xA8DE, 0xA82E, 0xA77E, 0xA6D0, 0xA621, 0xA574, 0xA4C6, 0xA41A, 0xA36E, 0xA2C2, 0xA217, 0xA16D, 0xA0C3, 0xA01A, 0x9F71, 0x9EC8, 0x9E21, 0x9D79, 0x9CD3, 0x9C2D, 0x9B87, 0x9AE2, 0x9A3D, 0x9999, 0x98F6, 0x9852, 0x97B0, 0x970E, 0x966C, 0x95CB, 0x952B, 0x948B, 0x93EB, 0x934C, 0x92AD, 0x920F, 0x9172, 0x90D4, 0x9038, 0x8F9C, 0x8F00, 0x8E65, 0x8DCA, 0x8D30, 0x8C96, 0x8BFC, 0x8B64, 0x8ACB, 0x8A33, 0x899C, 0x8904, 0x886E, 0x87D8, 0x8742, 0x86AD, 0x8618, 0x8583, 0x84F0, 0x845C, 0x83C9, 0x8336, 0x82A4, 0x8212, 0x8181, 0x80F0, 0x8060, 0x7FD0, 0x7F40, 0x7EB1, 0x7E22, 0x7D93, 0x7D05, 0x7C78, 0x7BEB, 0x7B5E, 0x7AD2, 0x7A46, 0x79BA, 0x792F, 0x78A4, 0x781A, 0x7790, 0x7706, 0x767D, 0x75F5, 0x756C, 0x74E4, 0x745D, 0x73D5, 0x734F, 0x72C8, 0x7242, 0x71BC, 0x7137, 0x70B2, 0x702E, 0x6FA9, 0x6F26, 0x6EA2, 0x6E1F, 0x6D9C, 0x6D1A, 0x6C98, 0x6C16, 0x6B95, 0x6B14, 0x6A94, 0x6A13, 0x6993, 0x6914, 0x6895, 0x6816, 0x6798, 0x6719, 0x669C, 0x661E, 0x65A1, 0x6524, 0x64A8, 0x642C, 0x63B0, 0x6335, 0x62BA, 0x623F, 0x61C5, 0x614B, 0x60D1, 0x6058, 0x5FDF, 0x5F66, 0x5EED, 0x5E75, 0x5DFD, 0x5D86, 0x5D0F, 0x5C98, 0x5C22, 0x5BAB, 0x5B35, 0x5AC0, 0x5A4B, 0x59D6, 0x5961, 0x58ED, 0x5879, 0x5805, 0x5791, 0x571E, 0x56AC, 0x5639, 0x55C7, 0x5555, 0x54E3, 0x5472, 0x5401, 0x5390, 0x5320, 0x52AF, 0x5240, 0x51D0, 0x5161, 0x50F2, 0x5083, 0x5015, 0x4FA6, 0x4F38, 0x4ECB, 0x4E5E, 0x4DF1, 0x4D84, 0x4D17, 0x4CAB, 0x4C3F, 0x4BD3, 0x4B68, 0x4AFD, 0x4A92, 0x4A27, 0x49BD, 0x4953, 0x48E9, 0x4880, 0x4817, 0x47AE, 0x4745, 0x46DC, 0x4674, 0x460C, 0x45A5, 0x453D, 0x44D6, 0x446F, 0x4408, 0x43A2, 0x433C, 0x42D6, 0x4270, 0x420B, 0x41A6, 0x4141, 0x40DC, 0x4078, 0x4014, 0x3FB0, 0x3F4C, 0x3EE8, 0x3E85, 0x3E22, 0x3DC0, 0x3D5D, 0x3CFB, 0x3C99, 0x3C37, 0x3BD6, 0x3B74, 0x3B13, 0x3AB2, 0x3A52, 0x39F1, 0x3991, 0x3931, 0x38D2, 0x3872, 0x3813, 0x37B4, 0x3755, 0x36F7, 0x3698, 0x363A, 0x35DC, 0x357F, 0x3521, 0x34C4, 0x3467, 0x340A, 0x33AE, 0x3351, 0x32F5, 0x3299, 0x323E, 0x31E2, 0x3187, 0x312C, 0x30D1, 0x3076, 0x301C, 0x2FC2, 0x2F68, 0x2F0E, 0x2EB4, 0x2E5B, 0x2E02, 0x2DA9, 0x2D50, 0x2CF8, 0x2C9F, 0x2C47, 0x2BEF, 0x2B97, 0x2B40, 0x2AE8, 0x2A91, 0x2A3A, 0x29E4, 0x298D, 0x2937, 0x28E0, 0x288B, 0x2835, 0x27DF, 0x278A, 0x2735, 0x26E0, 0x268B, 0x2636, 0x25E2, 0x258D, 0x2539, 0x24E5, 0x2492, 0x243E, 0x23EB, 0x2398, 0x2345, 0x22F2, 0x22A0, 0x224D, 0x21FB, 0x21A9, 0x2157, 0x2105, 0x20B4, 0x2063, 0x2012, 0x1FC1, 0x1F70, 0x1F1F, 0x1ECF, 0x1E7F, 0x1E2E, 0x1DDF, 0x1D8F, 0x1D3F, 0x1CF0, 0x1CA1, 0x1C52, 0x1C03, 0x1BB4, 0x1B66, 0x1B17, 0x1AC9, 0x1A7B, 0x1A2D, 0x19E0, 0x1992, 0x1945, 0x18F8, 0x18AB, 0x185E, 0x1811, 0x17C4, 0x1778, 0x172C, 0x16E0, 0x1694, 0x1648, 0x15FD, 0x15B1, 0x1566, 0x151B, 0x14D0, 0x1485, 0x143B, 0x13F0, 0x13A6, 0x135C, 0x1312, 0x12C8, 0x127F, 0x1235, 0x11EC, 0x11A3, 0x1159, 0x1111, 0x10C8, 0x107F, 0x1037, 0x0FEF, 0x0FA6, 0x0F5E, 0x0F17, 0x0ECF, 0x0E87, 0x0E40, 0x0DF9, 0x0DB2, 0x0D6B, 0x0D24, 0x0CDD, 0x0C97, 0x0C50, 0x0C0A, 0x0BC4, 0x0B7E, 0x0B38, 0x0AF2, 0x0AAD, 0x0A68, 0x0A22, 0x09DD, 0x0998, 0x0953, 0x090F, 0x08CA, 0x0886, 0x0842, 0x07FD, 0x07B9, 0x0776, 0x0732, 0x06EE, 0x06AB, 0x0668, 0x0624, 0x05E1, 0x059E, 0x055C, 0x0519, 0x04D6, 0x0494, 0x0452, 0x0410, 0x03CE, 0x038C, 0x034A, 0x0309, 0x02C7, 0x0286, 0x0245, 0x0204, 0x01C3, 0x0182, 0x0141, 0x0101, 0x00C0, 0x0080, 0x0040, 0x6A09, 0xFFFF, 0x6955, 0xFF00, 0x68A1, 0xFE02, 0x67EF, 0xFD06, 0x673E, 0xFC0B, 0x668D, 0xFB12, 0x65DE, 0xFA1A, 0x6530, 0xF923, 0x6482, 0xF82E, 0x63D6, 0xF73B, 0x632B, 0xF648, 0x6280, 0xF557, 0x61D7, 0xF467, 0x612E, 0xF379, 0x6087, 0xF28C, 0x5FE0, 0xF1A0, 0x5F3A, 0xF0B6, 0x5E95, 0xEFCD, 0x5DF1, 0xEEE5, 0x5D4E, 0xEDFF, 0x5CAC, 0xED19, 0x5C0B, 0xEC35, 0x5B6B, 0xEB52, 0x5ACB, 0xEA71, 0x5A2C, 0xE990, 0x598F, 0xE8B1, 0x58F2, 0xE7D3, 0x5855, 0xE6F6, 0x57BA, 0xE61B, 0x5720, 0xE540, 0x5686, 0xE467, 0x55ED, 0xE38E, 0x5555, 0xE2B7, 0x54BE, 0xE1E1, 0x5427, 0xE10D, 0x5391, 0xE039, 0x52FC, 0xDF66, 0x5268, 0xDE94, 0x51D5, 0xDDC4, 0x5142, 0xDCF4, 0x50B0, 0xDC26, 0x501F, 0xDB59, 0x4F8E, 0xDA8C, 0x4EFE, 0xD9C1, 0x4E6F, 0xD8F7, 0x4DE1, 0xD82D, 0x4D53, 0xD765, 0x4CC6, 0xD69E, 0x4C3A, 0xD5D7, 0x4BAF, 0xD512, 0x4B24, 0xD44E, 0x4A9A, 0xD38A, 0x4A10, 0xD2C8, 0x4987, 0xD206, 0x48FF, 0xD146, 0x4878, 0xD086, 0x47F1, 0xCFC7, 0x476B, 0xCF0A, 0x46E5, 0xCE4D, 0x4660, 0xCD91, 0x45DC, 0xCCD6, 0x4558, 0xCC1B, 0x44D5, 0xCB62, 0x4453, 0xCAA9, 0x43D1, 0xC9F2, 0x434F, 0xC93B, 0x42CF, 0xC885, 0x424F, 0xC7D0, 0x41CF, 0xC71C, 0x4151, 0xC669, 0x40D2, 0xC5B6, 0x4055, 0xC504, 0x3FD8, 0xC453, 0x3F5B, 0xC3A3, 0x3EDF, 0xC2F4, 0x3E64, 0xC245, 0x3DE9, 0xC198, 0x3D6E, 0xC0EB, 0x3CF5, 0xC03F, 0x3C7C, 0xBF93, 0x3C03, 0xBEE9, 0x3B8B, 0xBE3F, 0x3B13, 0xBD96, 0x3A9C, 0xBCED, 0x3A26, 0xBC46, 0x39B0, 0xBB9F, 0x393A, 0xBAF8, 0x38C5, 0xBA53, 0x3851, 0xB9AE, 0x37DD, 0xB90A, 0x3769, 0xB867, 0x36F6, 0xB7C5, 0x3684, 0xB723, 0x3612, 0xB681, 0x35A0, 0xB5E1, 0x352F, 0xB541, 0x34BF, 0xB4A2, 0x344F, 0xB404, 0x33DF, 0xB366, 0x3370, 0xB2C9, 0x3302, 0xB22C, 0x3293, 0xB191, 0x3226, 0xB0F5, 0x31B9, 0xB05B, 0x314C, 0xAFC1, 0x30DF, 0xAF28, 0x3074, 0xAE8F, 0x3008, 0xADF7, 0x2F9D, 0xAD60, 0x2F33, 0xACC9, 0x2EC8, 0xAC33, 0x2E5F, 0xAB9E, 0x2DF6, 0xAB09, 0x2D8D, 0xAA75, 0x2D24, 0xA9E1, 0x2CBC, 0xA94E, 0x2C55, 0xA8BC, 0x2BEE, 0xA82A, 0x2B87, 0xA799, 0x2B21, 0xA708, 0x2ABB, 0xA678, 0x2A55, 0xA5E8, 0x29F0, 0xA559, 0x298B, 0xA4CB, 0x2927, 0xA43D, 0x28C3, 0xA3B0, 0x2860, 0xA323, 0x27FD, 0xA297, 0x279A, 0xA20B, 0x2738, 0xA180, 0x26D6, 0xA0F6, 0x2674, 0xA06C, 0x2613, 0x9FE2, 0x25B2, 0x9F59, 0x2552, 0x9ED1, 0x24F2, 0x9E49, 0x2492, 0x9DC2, 0x2432, 0x9D3B, 0x23D3, 0x9CB4, 0x2375, 0x9C2F, 0x2317, 0x9BA9, 0x22B9, 0x9B25, 0x225B, 0x9AA0, 0x21FE, 0x9A1C, 0x21A1, 0x9999, 0x2145, 0x9916, 0x20E8, 0x9894, 0x208D, 0x9812, 0x2031, 0x9791, 0x1FD6, 0x9710, 0x1F7B, 0x968F, 0x1F21, 0x960F, 0x1EC7, 0x9590, 0x1E6D, 0x9511, 0x1E13, 0x9492, 0x1DBA, 0x9414, 0x1D61, 0x9397, 0x1D09, 0x931A, 0x1CB1, 0x929D, 0x1C59, 0x9221, 0x1C01, 0x91A5, 0x1BAA, 0x9129, 0x1B53, 0x90AF, 0x1AFC, 0x9034, 0x1AA6, 0x8FBA, 0x1A50, 0x8F40, 0x19FA, 0x8EC7, 0x19A5, 0x8E4F, 0x1950, 0x8DD6, 0x18FB, 0x8D5E, 0x18A7, 0x8CE7, 0x1853, 0x8C70, 0x17FF, 0x8BF9, 0x17AB, 0x8B83, 0x1758, 0x8B0D, 0x1705, 0x8A98, 0x16B2, 0x8A23, 0x1660, 0x89AE, 0x160D, 0x893A, 0x15BC, 0x88C6, 0x156A, 0x8853, 0x1519, 0x87E0, 0x14C8, 0x876D, 0x1477, 0x86FB, 0x1426, 0x8689, 0x13D6, 0x8618, 0x1386, 0x85A7, 0x1337, 0x8536, 0x12E7, 0x84C6, 0x1298, 0x8456, 0x1249, 0x83E7, 0x11FB, 0x8377, 0x11AC, 0x8309, 0x115E, 0x829A, 0x1111, 0x822C, 0x10C3, 0x81BF, 0x1076, 0x8151, 0x1029, 0x80E4, 0x0FDC, 0x8078, 0x0F8F, 0x800C, 0x0F43, 0x7FA0, 0x0EF7, 0x7F34, 0x0EAB, 0x7EC9, 0x0E60, 0x7E5E, 0x0E15, 0x7DF4, 0x0DCA, 0x7D8A, 0x0D7F, 0x7D20, 0x0D34, 0x7CB6, 0x0CEA, 0x7C4D, 0x0CA0, 0x7BE5, 0x0C56, 0x7B7C, 0x0C0C, 0x7B14, 0x0BC3, 0x7AAC, 0x0B7A, 0x7A45, 0x0B31, 0x79DE, 0x0AE8, 0x7977, 0x0AA0, 0x7911, 0x0A58, 0x78AB, 0x0A10, 0x7845, 0x09C8, 0x77DF, 0x0981, 0x777A, 0x0939, 0x7715, 0x08F2, 0x76B1, 0x08AB, 0x764D, 0x0865, 0x75E9, 0x081E, 0x7585, 0x07D8, 0x7522, 0x0792, 0x74BF, 0x074D, 0x745D, 0x0707, 0x73FA, 0x06C2, 0x7398, 0x067D, 0x7337, 0x0638, 0x72D5, 0x05F3, 0x7274, 0x05AF, 0x7213, 0x056A, 0x71B3, 0x0526, 0x7152, 0x04E2, 0x70F2, 0x049F, 0x7093, 0x045B, 0x7033, 0x0418, 0x6FD4, 0x03D5, 0x6F76, 0x0392, 0x6F17, 0x0350, 0x6EB9, 0x030D, 0x6E5B, 0x02CB, 0x6DFD, 0x0289, 0x6DA0, 0x0247, 0x6D43, 0x0206, 0x6CE6, 0x01C4, 0x6C8A, 0x0183, 0x6C2D, 0x0142, 0x6BD1, 0x0101, 0x6B76, 0x00C0, 0x6B1A, 0x0080, 0x6ABF, 0x0040, 0x6A64 }; enum { SP_DIV_SQRT_NO, SP_DIV_SQRT_YES }; enum { SP_DIV_PRECISION_SINGLE = 0, SP_DIV_PRECISION_DOUBLE = 1, SP_DIV_PRECISION_CURRENT }; INLINE static void do_div(int data, int sqrt, int precision) { int32_t addr; int fetch; int shift; if (precision == SP_DIV_PRECISION_SINGLE) data = (data < 0) ? -data : +data; if (precision == SP_DIV_PRECISION_DOUBLE && data < 0) data = (data >= -32768) ? -data : ~data; /* * Note, from the code just above, that data cannot be negative. * (data >= 0) is unconditionally forced by the above algorithm. */ addr = data; if (data == 0x00000000) { shift = (precision == SP_DIV_PRECISION_SINGLE) ? 16 : 0; addr = addr << shift; } else for (shift = 0; addr >= 0x00000000; addr <<= 1, shift++); addr = (addr >> 22) & 0x000001FF; if (sqrt == SP_DIV_SQRT_YES) { addr &= 0x000001FE; addr |= 0x00000200 | (shift & 1); } fetch = div_ROM[addr]; shift ^= 31; /* flipping shift direction from left- to right- */ shift >>= (sqrt == SP_DIV_SQRT_YES); DivOut = (0x40000000 | (fetch << 14)) >> shift; if (DivIn == 0) /* corner case: overflow via division by zero */ DivOut = 0x7FFFFFFF; else if (DivIn == -32768) /* corner case: signed underflow barrier */ DivOut = 0xFFFF0000; else DivOut ^= (DivIn < 0) ? ~0 : 0; } static INLINE void VRCP(int vd, int de, int vt, int e) { DivIn = (int)VR[vt][e & 07]; do_div(DivIn, SP_DIV_SQRT_NO, SP_DIV_PRECISION_SINGLE); SHUFFLE_VECTOR(VACC_L, VR[vt], e); VR[vd][de &= 07] = (short)DivOut; DPH = SP_DIV_PRECISION_SINGLE; } static void VRCPL(int vd, int de, int vt, int e) { DivIn &= -DPH; DivIn |= (unsigned short)VR[vt][e & 07]; do_div(DivIn, SP_DIV_SQRT_NO, DPH); SHUFFLE_VECTOR(VACC_L, VR[vt], e); VR[vd][de &= 07] = (short)DivOut; DPH = SP_DIV_PRECISION_SINGLE; } static INLINE void VRCPH(int vd, int de, int vt, int e) { DivIn = VR[vt][e & 07] << 16; SHUFFLE_VECTOR(VACC_L, VR[vt], e); VR[vd][de &= 07] = DivOut >> 16; DPH = SP_DIV_PRECISION_DOUBLE; } static void VMOV(int vd, int de, int vt, int e) { SHUFFLE_VECTOR(VACC_L, VR[vt], e); VR[vd][de &= 07] = VACC_L[e & 07]; } static void VRSQ(int vd, int de, int vt, int e) { /* VRSQ - untested */ DivIn = (int)VR[vt][e & 07]; do_div(DivIn, SP_DIV_SQRT_YES, SP_DIV_PRECISION_SINGLE); SHUFFLE_VECTOR(VACC_L, VR[vt], e); VR[vd][de &= 07] = (short)DivOut; DPH = SP_DIV_PRECISION_SINGLE; } static void VRSQL(int vd, int de, int vt, int e) { DivIn &= -DPH; DivIn |= (unsigned short)VR[vt][e & 07]; do_div(DivIn, SP_DIV_SQRT_YES, DPH); SHUFFLE_VECTOR(VACC_L, VR[vt], e); VR[vd][de &= 07] = (short)DivOut; DPH = SP_DIV_PRECISION_SINGLE; } static INLINE void VRSQH(int vd, int de, int vt, int e) { DivIn = VR[vt][e & 07] << 16; SHUFFLE_VECTOR(VACC_L, VR[vt], e); VR[vd][de &= 07] = DivOut >> 16; DPH = SP_DIV_PRECISION_DOUBLE; } static void VNOP(int vd, int vs, int vt, int e) { #if 0 const int WB_inhibit = vd = vs = vt = e = 1; if (WB_inhibit) return; /* message("VNOP", WB_inhibit); */ #endif } gles2n64/src/F3DSWSE.c000664 001750 001750 00000004462 12655644434 015302 0ustar00sergiosergio000000 000000 #include "Debug.h" #include "F3D.h" #include "F3DEX.h" #include "F3DSWSE.h" #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gSP.h" #include "gDP.h" #include "GBI.h" void F3DSWSE_Vtx( u32 w0, u32 w1 ) { gSPVertex(w1, _SHIFTR(w0, 4, 12) / 33 + 1, 0); } void F3DSWSE_Tri1( u32 w0, u32 w1 ) { gSP1Triangle( _SHIFTR( w1, 16, 8 ) / 5, _SHIFTR( w1, 8, 8 ) / 5, _SHIFTR( w1, 0, 8 ) / 5); } void F3DSWSE_Quad( u32 w0, u32 w1 ) { gSP1Quadrangle( _SHIFTR( w1, 24, 8 ) / 5, _SHIFTR( w1, 16, 8 ) / 5, _SHIFTR( w1, 8, 8 ) / 5, _SHIFTR( w1, 0, 8 ) / 5 ); } void F3DSWSE_Init(void) { gSPSetupFunctions(); // Set GeometryMode flags GBI_InitFlags( F3D ); GBI.PCStackSize = 18; // GBI Command Command Value Command Function GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_MTX, F3D_MTX, F3D_Mtx ); GBI_SetGBI( G_RESERVED0, F3D_RESERVED0, F3D_Reserved0 ); GBI_SetGBI( G_MOVEMEM, F3D_MOVEMEM, F3D_MoveMem ); GBI_SetGBI( G_VTX, F3D_VTX, F3DSWSE_Vtx ); GBI_SetGBI( G_RESERVED1, F3D_RESERVED1, F3D_Reserved1 ); GBI_SetGBI( G_DL, F3D_DL, F3D_DList ); GBI_SetGBI( G_RESERVED2, F3D_RESERVED2, F3D_Reserved2 ); GBI_SetGBI( G_RESERVED3, F3D_RESERVED3, F3D_Reserved3 ); GBI_SetGBI( G_SPRITE2D_BASE, F3D_SPRITE2D_BASE, F3D_Sprite2D_Base ); GBI_SetGBI( G_TRI1, F3D_TRI1, F3DSWSE_Tri1 ); GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3D_CullDL ); GBI_SetGBI( G_POPMTX, F3D_POPMTX, F3D_PopMtx ); GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3D_MoveWord ); GBI_SetGBI( G_TEXTURE, F3D_TEXTURE, F3D_Texture ); GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L ); GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL ); GBI_SetGBI( G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, F3D_SetGeometryMode ); GBI_SetGBI( G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE, F3D_ClearGeometryMode ); GBI_SetGBI( G_QUAD, F3D_QUAD, F3DSWSE_Quad ); GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_RDPHALF_CONT, F3D_RDPHALF_CONT, F3D_RDPHalf_Cont ); GBI_SetGBI( G_TRI4, F3D_TRI4, F3D_Tri4 ); } mupen64plus-rsp-cxd4/Rsp_#1.1.h000664 001750 001750 00000017221 12655644434 017125 0ustar00sergiosergio000000 000000 #ifndef __RSP_1_1_H__ #define __RSP_1_1_H__ #if defined(__cplusplus) extern "C" { #endif #define PLUGIN_TYPE_RSP 1 #define PLUGIN_TYPE_GFX 2 #define PLUGIN_TYPE_AUDIO 3 #define PLUGIN_TYPE_CONTROLLER 4 #if !defined(M64P_PLUGIN_API) /* * slight changes to zilmar's spec file for portability * * The raw plugin spec headers by zilmar required WIN32 definitions. * * Here, the sufficient ANSI approximations are given so that this header * will operate more independently. */ struct HWND__ {int unused;}; typedef struct HWND__ *HWND; struct HINSTANCE__ {int unused;}; typedef struct HINSTANCE__ *HINSTANCE; struct HMENU__ {int unused;}; typedef struct HMENU__ *HMENU; struct HDC__ {int unused;}; typedef struct HDC__ *HDC; #endif #if defined(_STDINT_H) || defined(M64P_PLUGIN_API) typedef uint32_t RCPREG; #elif (0) typedef unsigned long RCPREG; /* necessary for 16-bit targets */ #else typedef unsigned int RCPREG; /* ANSI approximation of 32-bit size */ #endif typedef struct { unsigned short Version; /* Should be set to 0x0101 */ unsigned short Type; /* Set to PLUGIN_TYPE_RSP */ char Name[100]; /* Name of the DLL */ /* If DLL supports memory these memory options then set them to TRUE or FALSE if it does not support it */ int NormalMemory; /* a normal BYTE array */ int MemoryBswaped; /* a normal BYTE array where the memory has been pre- byte-swapped on a DWORD (32 bits) boundary */ } PLUGIN_INFO; #if !defined(M64P_PLUGIN_API) typedef struct { HINSTANCE hInst; int MemoryBswaped; /* If this is set to TRUE, then the memory has been pre-byte-swapped on a DWORD (32 bits) boundary */ unsigned char *RDRAM; unsigned char *DMEM; unsigned char *IMEM; RCPREG *MI_INTR_REG; RCPREG *SP_MEM_ADDR_REG; RCPREG *SP_DRAM_ADDR_REG; RCPREG *SP_RD_LEN_REG; RCPREG *SP_WR_LEN_REG; RCPREG *SP_STATUS_REG; RCPREG *SP_DMA_FULL_REG; RCPREG *SP_DMA_BUSY_REG; RCPREG *SP_PC_REG; /* This was SUPPOSED to be defined after the next. */ RCPREG *SP_SEMAPHORE_REG; /** RCPREG *SP_PC_REG; // CPU-mapped between SP and DP command buffer regs **/ RCPREG *DPC_START_REG; RCPREG *DPC_END_REG; RCPREG *DPC_CURRENT_REG; RCPREG *DPC_STATUS_REG; RCPREG *DPC_CLOCK_REG; RCPREG *DPC_BUFBUSY_REG; RCPREG *DPC_PIPEBUSY_REG; RCPREG *DPC_TMEM_REG; void (*CheckInterrupts)(void); void (*ProcessDList)(void); void (*ProcessAList)(void); void (*ProcessRdpList)(void); void (*ShowCFB)(void); } RSP_INFO; #endif typedef struct { void (*UpdateBreakPoints)(void); void (*UpdateMemory)(void); void (*UpdateR4300iRegisters)(void); void (*Enter_BPoint_Window)(void); void (*Enter_R4300i_Commands_Window)(void); void (*Enter_R4300i_Register_Window)(void); void (*Enter_RSP_Commands_Window)(void); void (*Enter_Memory_Window)(void); } DEBUG_INFO; #if defined(M64P_PLUGIN_API) #define M64P_PLUGIN_PROTOTYPES 1 #include "m64p_types.h" #include "m64p_common.h" #include "m64p_plugin.h" #include "m64p_config.h" #else #if defined(WIN32) #define EXPORT __declspec(dllexport) #define CALL __cdecl #else #define EXPORT __attribute__((visibility("default"))) #define CALL #endif #endif #if !defined(M64P_PLUGIN_API) /****************************************************************** Function: CloseDLL Purpose: This function is called when the emulator is closing down allowing the DLL to de-initialise. input: none output: none *******************************************************************/ EXPORT void CALL CloseDLL(void); /****************************************************************** Function: DllAbout Purpose: This function is optional function that is provided to give further information about the DLL. input: a handle to the window that calls this function output: none *******************************************************************/ EXPORT void CALL DllAbout(HWND hParent); /****************************************************************** Function: DllConfig Purpose: This function is optional function that is provided to allow the user to configure the DLL input: a handle to the window that calls this function output: none *******************************************************************/ EXPORT void CALL DllConfig(HWND hParent); /****************************************************************** Function: DllTest Purpose: This function is optional function that is provided to allow the user to test the DLL input: a handle to the window that calls this function output: none *******************************************************************/ EXPORT void CALL DllTest(HWND hParent); #endif /****************************************************************** Function: DoRspCycles Purpose: This function is to allow the RSP to run in parallel with the r4300 switching control back to the r4300 once the function ends. input: The number of cycles that is meant to be executed output: The number of cycles that was executed. This value can be greater than the number of cycles that the RSP should have performed. (this value is ignored if the RSP is stopped) *******************************************************************/ EXPORT unsigned int CALL DoRspCycles(unsigned int Cycles); /****************************************************************** Function: GetDllInfo Purpose: This function allows the emulator to gather information about the DLL by filling in the PluginInfo structure. input: a pointer to a PLUGIN_INFO structure that needs to be filled by the function. (see def above) output: none *******************************************************************/ EXPORT void CALL GetDllInfo(PLUGIN_INFO *PluginInfo); /* * `GetRspDebugInfo` -- customarily deprecated by cxd4 * * It was extraordinarily easy to re-invent debug facilities without * depending on the Microsoft-Windows-themed debug functions from this spec. * * What's more? No emulators supporting RSP plugins require this function. * It can be safely ignored as a non-portable custom extension to the spec. */ /****************************************************************** Function: InitiateRSP Purpose: This function is called when the DLL is started to give information from the emulator that the n64 RSP interface needs input: Rsp_Info is passed to this function which is defined above. CycleCount is the number of cycles between switching control between the RSP and r4300i core. output: none *******************************************************************/ EXPORT void CALL InitiateRSP(RSP_INFO Rsp_Info, unsigned int *CycleCount); /* * `InitiateRSPDebugger` -- customarily deprecated by cxd4 * * Here, again, nothing about the full features of debugging this RSP * emulator needed to depend on any WIN32 fixations in this plugin spec. * * Also, again, as with the case of `GetRspDebugInfo`, the test of time has * passed the conclusion that no emulators require the RSP plugin to export * this procedure's symbol to be considered a valid RSP plugin. */ /****************************************************************** Function: RomClosed Purpose: This function is called when a rom is closed. input: none output: none *******************************************************************/ EXPORT void CALL RomClosed(void); #if defined(__cplusplus) } #endif #endif mupen64plus-video-gliden64/src/GLideNHQ/TxReSample.h000664 001750 001750 00000002563 12655644434 023164 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __TXRESAMPLE_H__ #define __TXRESAMPLE_H__ #include "TxInternal.h" class TxReSample { private: double tent(double x); double gaussian(double x); double sinc(double x); double lanczos3(double x); double mitchell(double x); double besselI0(double x); double kaiser(double x); public: boolean minify(uint8 **src, int *width, int *height, int ratio); boolean nextPow2(uint8** image, int* width, int* height, int bpp, boolean use_3dfx); int nextPow2(int num); }; #endif /* __TXRESAMPLE_H__ */ gles2rice/data/000700 001750 001750 00000000000 12656647145 014476 5ustar00sergiosergio000000 000000 mupen64plus-core/src/r4300/new_dynarec/new_dynarec.h000664 001750 001750 00000004010 12655644434 023346 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - new_dynarec.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_R4300_NEW_DYNAREC_H #define M64P_R4300_NEW_DYNAREC_H #include #include #define NEW_DYNAREC_X86 1 #define NEW_DYNAREC_AMD64 2 #define NEW_DYNAREC_ARM 3 extern int pcaddr; extern int pending_exception; void invalidate_all_pages(void); void invalidate_block(unsigned int block); void invalidate_cached_code_new_dynarec(uint32_t address, size_t size); void new_dynarec_init(void); void new_dyna_start(void); void new_dynarec_cleanup(void); #endif /* M64P_R4300_NEW_DYNAREC_H */ mupen64plus-rsp-cxd4/rsp.h000664 001750 001750 00000004045 12655644434 016543 0ustar00sergiosergio000000 000000 /******************************************************************************\ * Authors: Iconoclast * * Release: 2013.12.12 * * License: CC0 Public Domain Dedication * * * * To the extent possible under law, the author(s) have dedicated all copyright * * and related and neighboring rights to this software to the public domain * * worldwide. This software is distributed without any warranty. * * * * You should have received a copy of the CC0 Public Domain Dedication along * * with this software. * * If not, see . * \******************************************************************************/ #ifndef _RSP_H_ #define _RSP_H_ RSP_INFO RSP; #ifdef _MSC_VER #define NOINLINE __declspec(noinline) #define ALIGNED _declspec(align(16)) #else #define NOINLINE __attribute__((noinline)) #define ALIGNED __attribute__((aligned(16))) #endif #ifdef USE_SSE_SUPPORT #define ARCH_MIN_SSE2 #endif /* * Streaming SIMD Extensions version import management */ #ifdef ARCH_MIN_SSSE3 #define ARCH_MIN_SSE2 #include #endif #ifdef ARCH_MIN_SSE2 #include #endif typedef uint8_t byte; typedef enum { M_GFXTASK = 1, M_AUDTASK = 2, M_VIDTASK = 3, M_NJPEGTASK = 4, M_NULTASK = 5, M_HVQTASK = 6, M_HVQMTASK = 7 } OSTask_type; /* * This allows us to update the program counter register in the RSP * interpreter in a much faster way overall to the running CPU loop. * * Branch delay slots and such with the MIPS architecture make the * PC register emulation complicate the interpreter switches when * emulated normally. */ #define EMULATE_STATIC_PC #endif gles2n64/src/GBI.h000664 001750 001750 00000055121 12655644434 014630 0ustar00sergiosergio000000 000000 #ifndef GBI_H #define GBI_H #ifdef __cplusplus extern "C" { #endif #include "Types.h" #include // Microcode Types #define F3D 0 #define F3DEX 1 #define F3DEX2 2 #define L3D 3 #define L3DEX 4 #define L3DEX2 5 #define S2DEX 6 #define S2DEX2 7 #define F3DPD 8 #define F3DDKR 9 #define F3DJFG 10 #define F3DSWSE 11 #define F3DWRUS 12 #define F3DEX2CBFD 13 #define Turbo3D 14 #define ZSortp 15 #define NONE 16 #define F3DCBFD_MV_VIEWPORT 8 #define F3DCBFD_MV_LIGHT 10 #define F3DCBFD_MV_NORMAL 14 #ifdef MAINDEF const char *MicrocodeTypes[] = { "Fast3D", "F3DEX", "F3DEX2", "Line3D", "L3DEX", "L3DEX2", "S2DEX", "S2DEX2", "Perfect Dark", "DKR/JFG", "Waverace US", "Conker's Bad Fur Day", "None", }; #else extern const char *MicrocodeTypes[]; #endif static const int numMicrocodeTypes = 11; // Fixed point conversion factors #define FIXED2FLOATRECIP1 0.5f #define FIXED2FLOATRECIP2 0.25f #define FIXED2FLOATRECIP3 0.125f #define FIXED2FLOATRECIP4 0.0625f #define FIXED2FLOATRECIP5 0.03125f #define FIXED2FLOATRECIP6 0.015625f #define FIXED2FLOATRECIP7 0.0078125f #define FIXED2FLOATRECIP8 0.00390625f #define FIXED2FLOATRECIP9 0.001953125f #define FIXED2FLOATRECIP10 0.0009765625f #define FIXED2FLOATRECIP11 0.00048828125f #define FIXED2FLOATRECIP12 0.00024414063f #define FIXED2FLOATRECIP13 0.00012207031f #define FIXED2FLOATRECIP14 6.1035156e-05f #define FIXED2FLOATRECIP15 3.0517578e-05f #define FIXED2FLOATRECIP16 1.5258789e-05f #define _FIXED2FLOAT( v, b ) \ ((f32)v * FIXED2FLOATRECIP##b) // Useful macros for decoding GBI command's parameters #define _SHIFTL( v, s, w ) \ (((u32)v & ((0x01 << w) - 1)) << s) #define _SHIFTR( v, s, w ) \ (((u32)v >> s) & ((0x01 << w) - 1)) // BG flags #define G_BGLT_LOADBLOCK 0x0033 #define G_BGLT_LOADTILE 0xfff4 #define G_BG_FLAG_FLIPS 0x01 #define G_BG_FLAG_FLIPT 0x10 // Sprite object render modes #define G_OBJRM_NOTXCLAMP 0x01 #define G_OBJRM_XLU 0x02 /* Ignored */ #define G_OBJRM_ANTIALIAS 0x04 /* Ignored */ #define G_OBJRM_BILERP 0x08 #define G_OBJRM_SHRINKSIZE_1 0x10 #define G_OBJRM_SHRINKSIZE_2 0x20 #define G_OBJRM_WIDEN 0x40 // Sprite texture loading types #define G_OBJLT_TXTRBLOCK 0x00001033 #define G_OBJLT_TXTRTILE 0x00fc1034 #define G_OBJLT_TLUT 0x00000030 // These are all the constant flags #define G_ZBUFFER 0x00000001 #define G_SHADE 0x00000004 #define G_FOG 0x00010000 #define G_LIGHTING 0x00020000 #define G_TEXTURE_GEN 0x00040000 #define G_TEXTURE_GEN_LINEAR 0x00080000 #define G_LOD 0x00100000 #define G_POINT_LIGHTING 0x00400000 #define G_MV_MMTX 2 #define G_MV_PMTX 6 #define G_MV_LIGHT 10 #define G_MV_POINT 12 #define G_MV_MATRIX 14 #define G_MV_NORMALES 14 #define G_MVO_LOOKATX 0 #define G_MVO_LOOKATY 24 #define G_MVO_L0 48 #define G_MVO_L1 72 #define G_MVO_L2 96 #define G_MVO_L3 120 #define G_MVO_L4 144 #define G_MVO_L5 168 #define G_MVO_L6 192 #define G_MVO_L7 216 #define G_MV_LOOKATY 0x82 #define G_MV_LOOKATX 0x84 #define G_MV_L0 0x86 #define G_MV_L1 0x88 #define G_MV_L2 0x8a #define G_MV_L3 0x8c #define G_MV_L4 0x8e #define G_MV_L5 0x90 #define G_MV_L6 0x92 #define G_MV_L7 0x94 #define G_MV_TXTATT 0x96 #define G_MV_MATRIX_1 0x9E #define G_MV_MATRIX_2 0x98 #define G_MV_MATRIX_3 0x9A #define G_MV_MATRIX_4 0x9C #define G_MW_MATRIX 0x00 #define G_MW_NUMLIGHT 0x02 #define G_MW_CLIP 0x04 #define G_MW_SEGMENT 0x06 #define G_MW_FOG 0x08 #define G_MW_LIGHTCOL 0x0A #define G_MW_FORCEMTX 0x0C #define G_MW_POINTS 0x0C #define G_MW_PERSPNORM 0x0E #define G_MV_COORDMOD 0x10 //Conker Bad Fur Day #define G_MWO_NUMLIGHT 0x00 #define G_MWO_CLIP_RNX 0x04 #define G_MWO_CLIP_RNY 0x0c #define G_MWO_CLIP_RPX 0x14 #define G_MWO_CLIP_RPY 0x1c #define G_MWO_SEGMENT_0 0x00 #define G_MWO_SEGMENT_1 0x01 #define G_MWO_SEGMENT_2 0x02 #define G_MWO_SEGMENT_3 0x03 #define G_MWO_SEGMENT_4 0x04 #define G_MWO_SEGMENT_5 0x05 #define G_MWO_SEGMENT_6 0x06 #define G_MWO_SEGMENT_7 0x07 #define G_MWO_SEGMENT_8 0x08 #define G_MWO_SEGMENT_9 0x09 #define G_MWO_SEGMENT_A 0x0a #define G_MWO_SEGMENT_B 0x0b #define G_MWO_SEGMENT_C 0x0c #define G_MWO_SEGMENT_D 0x0d #define G_MWO_SEGMENT_E 0x0e #define G_MWO_SEGMENT_F 0x0f #define G_MWO_FOG 0x00 #define G_MWO_MATRIX_XX_XY_I 0x00 #define G_MWO_MATRIX_XZ_XW_I 0x04 #define G_MWO_MATRIX_YX_YY_I 0x08 #define G_MWO_MATRIX_YZ_YW_I 0x0C #define G_MWO_MATRIX_ZX_ZY_I 0x10 #define G_MWO_MATRIX_ZZ_ZW_I 0x14 #define G_MWO_MATRIX_WX_WY_I 0x18 #define G_MWO_MATRIX_WZ_WW_I 0x1C #define G_MWO_MATRIX_XX_XY_F 0x20 #define G_MWO_MATRIX_XZ_XW_F 0x24 #define G_MWO_MATRIX_YX_YY_F 0x28 #define G_MWO_MATRIX_YZ_YW_F 0x2C #define G_MWO_MATRIX_ZX_ZY_F 0x30 #define G_MWO_MATRIX_ZZ_ZW_F 0x34 #define G_MWO_MATRIX_WX_WY_F 0x38 #define G_MWO_MATRIX_WZ_WW_F 0x3C #define G_MWO_POINT_RGBA 0x10 #define G_MWO_POINT_ST 0x14 #define G_MWO_POINT_XYSCREEN 0x18 #define G_MWO_POINT_ZSCREEN 0x1C #ifdef DEBUG static const char *MWOPointText[] = { "G_MWO_POINT_RGBA", "G_MWO_POINT_ST", "G_MWO_POINT_XYSCREEN", "G_MWO_POINT_ZSCREEN" }; static const char *MWOMatrixText[] = { "G_MWO_MATRIX_XX_XY_I", "G_MWO_MATRIX_XZ_XW_I", "G_MWO_MATRIX_YX_YY_I", "G_MWO_MATRIX_YZ_YW_I", "G_MWO_MATRIX_ZX_ZY_I", "G_MWO_MATRIX_ZZ_ZW_I", "G_MWO_MATRIX_WX_WY_I", "G_MWO_MATRIX_WZ_WW_I", "G_MWO_MATRIX_XX_XY_F", "G_MWO_MATRIX_XZ_XW_F", "G_MWO_MATRIX_YX_YY_F", "G_MWO_MATRIX_YZ_YW_F", "G_MWO_MATRIX_ZX_ZY_F", "G_MWO_MATRIX_ZZ_ZW_F", "G_MWO_MATRIX_WX_WY_F", "G_MWO_MATRIX_WZ_WW_F" }; #endif // These flags change between ucodes extern u32 G_MTX_STACKSIZE; extern u32 G_MTX_MODELVIEW; extern u32 G_MTX_PROJECTION; extern u32 G_MTX_MUL; extern u32 G_MTX_LOAD; extern u32 G_MTX_NOPUSH; extern u32 G_MTX_PUSH; extern u32 G_TEXTURE_ENABLE; extern u32 G_SHADING_SMOOTH; extern u32 G_CULL_FRONT; extern u32 G_CULL_BACK; extern u32 G_CULL_BOTH; extern u32 G_CLIPPING; extern u32 G_MV_VIEWPORT; extern u32 G_MWO_aLIGHT_1, G_MWO_bLIGHT_1; extern u32 G_MWO_aLIGHT_2, G_MWO_bLIGHT_2; extern u32 G_MWO_aLIGHT_3, G_MWO_bLIGHT_3; extern u32 G_MWO_aLIGHT_4, G_MWO_bLIGHT_4; extern u32 G_MWO_aLIGHT_5, G_MWO_bLIGHT_5; extern u32 G_MWO_aLIGHT_6, G_MWO_bLIGHT_6; extern u32 G_MWO_aLIGHT_7, G_MWO_bLIGHT_7; extern u32 G_MWO_aLIGHT_8, G_MWO_bLIGHT_8; // Image formats #define G_IM_FMT_RGBA 0 #define G_IM_FMT_YUV 1 #define G_IM_FMT_CI 2 #define G_IM_FMT_IA 3 #define G_IM_FMT_I 4 #define G_IM_FMT_CI_IA 5 //not real // Image sizes #define G_IM_SIZ_4b 0 #define G_IM_SIZ_8b 1 #define G_IM_SIZ_16b 2 #define G_IM_SIZ_32b 3 #define G_IM_SIZ_DD 5 #define G_TX_MIRROR 0x1 #define G_TX_CLAMP 0x2 #ifdef DEBUG static const char *ImageFormatText[] = { "G_IM_FMT_RGBA", "G_IM_FMT_YUV", "G_IM_FMT_CI", "G_IM_FMT_IA", "G_IM_FMT_I", "G_IM_FMT_INVALID", "G_IM_FMT_INVALID", "G_IM_FMT_INVALID" }; static const char *ImageSizeText[] = { "G_IM_SIZ_4b", "G_IM_SIZ_8b", "G_IM_SIZ_16b", "G_IM_SIZ_32b" }; static const char *SegmentText[] = { "G_MWO_SEGMENT_0", "G_MWO_SEGMENT_1", "G_MWO_SEGMENT_2", "G_MWO_SEGMENT_3", "G_MWO_SEGMENT_4", "G_MWO_SEGMENT_5", "G_MWO_SEGMENT_6", "G_MWO_SEGMENT_7", "G_MWO_SEGMENT_8", "G_MWO_SEGMENT_9", "G_MWO_SEGMENT_A", "G_MWO_SEGMENT_B", "G_MWO_SEGMENT_C", "G_MWO_SEGMENT_D", "G_MWO_SEGMENT_E", "G_MWO_SEGMENT_F" }; #endif #define G_NOOP 0x00 #define G_IMMFIRST -65 // These GBI commands are common to all ucodes #define G_SETCIMG 0xFF /* -1 */ #define G_SETZIMG 0xFE /* -2 */ #define G_SETTIMG 0xFD /* -3 */ #define G_SETCOMBINE 0xFC /* -4 */ #define G_SETENVCOLOR 0xFB /* -5 */ #define G_SETPRIMCOLOR 0xFA /* -6 */ #define G_SETBLENDCOLOR 0xF9 /* -7 */ #define G_SETFOGCOLOR 0xF8 /* -8 */ #define G_SETFILLCOLOR 0xF7 /* -9 */ #define G_FILLRECT 0xF6 /* -10 */ #define G_SETTILE 0xF5 /* -11 */ #define G_LOADTILE 0xF4 /* -12 */ #define G_LOADBLOCK 0xF3 /* -13 */ #define G_SETTILESIZE 0xF2 /* -14 */ #define G_LOADTLUT 0xF0 /* -16 */ #define G_RDPSETOTHERMODE 0xEF /* -17 */ #define G_SETPRIMDEPTH 0xEE /* -18 */ #define G_SETSCISSOR 0xED /* -19 */ #define G_SETCONVERT 0xEC /* -20 */ #define G_SETKEYR 0xEB /* -21 */ #define G_SETKEYGB 0xEA /* -22 */ #define G_RDPFULLSYNC 0xE9 /* -23 */ #define G_RDPTILESYNC 0xE8 /* -24 */ #define G_RDPPIPESYNC 0xE7 /* -25 */ #define G_RDPLOADSYNC 0xE6 /* -26 */ #define G_TEXRECTFLIP 0xE5 /* -27 */ #define G_TEXRECT 0xE4 /* -28 */ #define G_RDPNOOP 0xC0 #define G_TRI_FILL 0xC8 /* fill triangle: 11001000 */ #define G_TRI_FILL_ZBUFF 0xC9 /* fill, zbuff triangle: 11001001 */ #define G_TRI_TXTR 0xCA /* texture triangle: 11001010 */ #define G_TRI_TXTR_ZBUFF 0xCB /* texture, zbuff triangle: 11001011 */ #define G_TRI_SHADE 0xCC /* shade triangle: 11001100 */ #define G_TRI_SHADE_ZBUFF 0xCD /* shade, zbuff triangle: 11001101 */ #define G_TRI_SHADE_TXTR 0xCE /* shade, texture triangle: 11001110 */ #define G_TRI_SHADE_TXTR_ZBUFF 0xCF /* shade, txtr, zbuff trngl: 11001111 */ /* * G_SETOTHERMODE_L sft: shift count */ #define G_MDSFT_ALPHACOMPARE 0 #define G_MDSFT_ZSRCSEL 2 #define G_MDSFT_RENDERMODE 3 #define G_MDSFT_BLENDER 16 /* * G_SETOTHERMODE_H sft: shift count */ #define G_MDSFT_BLENDMASK 0 /* unsupported */ #define G_MDSFT_ALPHADITHER 4 #define G_MDSFT_RGBDITHER 6 #define G_MDSFT_COMBKEY 8 #define G_MDSFT_TEXTCONV 9 #define G_MDSFT_TEXTFILT 12 #define G_MDSFT_TEXTLUT 14 #define G_MDSFT_TEXTLOD 16 #define G_MDSFT_TEXTDETAIL 17 #define G_MDSFT_TEXTPERSP 19 #define G_MDSFT_CYCLETYPE 20 #define G_MDSFT_COLORDITHER 22 /* unsupported in HW 2.0 */ #define G_MDSFT_PIPELINE 23 /* G_SETOTHERMODE_H gPipelineMode */ #define G_PM_1PRIMITIVE 1 #define G_PM_NPRIMITIVE 0 /* G_SETOTHERMODE_H gSetCycleType */ #define G_CYC_1CYCLE 0 #define G_CYC_2CYCLE 1 #define G_CYC_COPY 2 #define G_CYC_FILL 3 /* G_SETOTHERMODE_H gSetTexturePersp */ #define G_TP_NONE 0 #define G_TP_PERSP 1 /* G_SETOTHERMODE_H gSetTextureDetail */ #define G_TD_CLAMP 0 #define G_TD_SHARPEN 1 #define G_TD_DETAIL 2 /* G_SETOTHERMODE_H gSetTextureLOD */ #define G_TL_TILE 0 #define G_TL_LOD 1 /* G_SETOTHERMODE_H gSetTextureLUT */ #define G_TT_NONE 0 #define G_TT_RGBA16 2 #define G_TT_IA16 3 /* G_SETOTHERMODE_H gSetTextureFilter */ #define G_TF_POINT 0 #define G_TF_AVERAGE 3 #define G_TF_BILERP 2 /* G_SETOTHERMODE_H gSetTextureConvert */ #define G_TC_CONV 0 #define G_TC_FILTCONV 5 #define G_TC_FILT 6 /* G_SETOTHERMODE_H gSetCombineKey */ #define G_CK_NONE 0 #define G_CK_KEY 1 /* G_SETOTHERMODE_H gSetColorDither */ #define G_CD_MAGICSQ 0 #define G_CD_BAYER 1 #define G_CD_NOISE 2 #define G_CD_DISABLE 3 #define G_CD_ENABLE G_CD_NOISE /* HW 1.0 compatibility mode */ /* G_SETOTHERMODE_H gSetAlphaDither */ #define G_AD_PATTERN 0 #define G_AD_NOTPATTERN 1 #define G_AD_NOISE 2 #define G_AD_DISABLE 3 /* G_SETOTHERMODE_L gSetAlphaCompare */ #define G_AC_NONE 0 #define G_AC_THRESHOLD 1 #define G_AC_DITHER 3 /* G_SETOTHERMODE_L gSetDepthSource */ #define G_ZS_PIXEL 0 #define G_ZS_PRIM 1 /* G_SETOTHERMODE_L gSetRenderMode */ #define AA_EN 1 #define Z_CMP 1 #define Z_UPD 1 #define IM_RD 1 #define CLR_ON_CVG 1 #define CVG_DST_CLAMP 0 #define CVG_DST_WRAP 1 #define CVG_DST_FULL 2 #define CVG_DST_SAVE 3 #define ZMODE_OPA 0 #define ZMODE_INTER 1 #define ZMODE_XLU 2 #define ZMODE_DEC 3 #define CVG_X_ALPHA 1 #define ALPHA_CVG_SEL 1 #define FORCE_BL 1 #define TEX_EDGE 0 // not used #define G_SC_NON_INTERLACE 0 #define G_SC_EVEN_INTERLACE 2 #define G_SC_ODD_INTERLACE 3 #ifdef DEBUG static const char *AAEnableText = "AA_EN"; static const char *DepthCompareText = "Z_CMP"; static const char *DepthUpdateText = "Z_UPD"; static const char *ClearOnCvgText = "CLR_ON_CVG"; static const char *CvgXAlphaText = "CVG_X_ALPHA"; static const char *AlphaCvgSelText = "ALPHA_CVG_SEL"; static const char *ForceBlenderText = "FORCE_BL"; static const char *AlphaCompareText[] = { "G_AC_NONE", "G_AC_THRESHOLD", "G_AC_INVALID", "G_AC_DITHER" }; static const char *DepthSourceText[] = { "G_ZS_PIXEL", "G_ZS_PRIM" }; static const char *AlphaDitherText[] = { "G_AD_PATTERN", "G_AD_NOTPATTERN", "G_AD_NOISE", "G_AD_DISABLE" }; static const char *ColorDitherText[] = { "G_CD_MAGICSQ", "G_CD_BAYER", "G_CD_NOISE", "G_CD_DISABLE" }; static const char *CombineKeyText[] = { "G_CK_NONE", "G_CK_KEY" }; static const char *TextureConvertText[] = { "G_TC_CONV", "G_TC_INVALID", "G_TC_INVALID", "G_TC_INVALID", "G_TC_INVALID", "G_TC_FILTCONV", "G_TC_FILT", "G_TC_INVALID" }; static const char *TextureFilterText[] = { "G_TF_POINT", "G_TF_INVALID", "G_TF_BILERP", "G_TF_AVERAGE" }; static const char *TextureLUTText[] = { "G_TT_NONE", "G_TT_INVALID", "G_TT_RGBA16", "G_TT_IA16" }; static const char *TextureLODText[] = { "G_TL_TILE", "G_TL_LOD" }; static const char *TextureDetailText[] = { "G_TD_CLAMP", "G_TD_SHARPEN", "G_TD_DETAIL" }; static const char *TexturePerspText[] = { "G_TP_NONE", "G_TP_PERSP" }; static const char *CycleTypeText[] = { "G_CYC_1CYCLE", "G_CYC_2CYCLE", "G_CYC_COPY", "G_CYC_FILL" }; static const char *PipelineModeText[] = { "G_PM_NPRIMITIVE", "G_PM_1PRIMITIVE" }; static const char *CvgDestText[] = { "CVG_DST_CLAMP", "CVG_DST_WRAP", "CVG_DST_FULL", "CVG_DST_SAVE" }; static const char *DepthModeText[] = { "ZMODE_OPA", "ZMODE_INTER", "ZMODE_XLU", "ZMODE_DEC" }; static const char *ScissorModeText[] = { "G_SC_NON_INTERLACE", "G_SC_INVALID", "G_SC_EVEN_INTERLACE", "G_SC_ODD_INTERLACE" }; #endif /* Color combiner constants: */ #define G_CCMUX_COMBINED 0 #define G_CCMUX_TEXEL0 1 #define G_CCMUX_TEXEL1 2 #define G_CCMUX_PRIMITIVE 3 #define G_CCMUX_SHADE 4 #define G_CCMUX_ENVIRONMENT 5 #define G_CCMUX_CENTER 6 #define G_CCMUX_SCALE 6 #define G_CCMUX_COMBINED_ALPHA 7 #define G_CCMUX_TEXEL0_ALPHA 8 #define G_CCMUX_TEXEL1_ALPHA 9 #define G_CCMUX_PRIMITIVE_ALPHA 10 #define G_CCMUX_SHADE_ALPHA 11 #define G_CCMUX_ENV_ALPHA 12 #define G_CCMUX_LOD_FRACTION 13 #define G_CCMUX_PRIM_LOD_FRAC 14 #define G_CCMUX_NOISE 7 #define G_CCMUX_K4 7 #define G_CCMUX_K5 15 #define G_CCMUX_1 6 #define G_CCMUX_0 31 /* Alpha combiner constants: */ #define G_ACMUX_COMBINED 0 #define G_ACMUX_TEXEL0 1 #define G_ACMUX_TEXEL1 2 #define G_ACMUX_PRIMITIVE 3 #define G_ACMUX_SHADE 4 #define G_ACMUX_ENVIRONMENT 5 #define G_ACMUX_LOD_FRACTION 0 #define G_ACMUX_PRIM_LOD_FRAC 6 #define G_ACMUX_1 6 #define G_ACMUX_0 7 #ifdef DEBUG static const char *saRGBText[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "NOISE", "1", "0", "0", "0", "0", "0", "0", "0", "0" }; static const char *sbRGBText[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "CENTER", "K4", "0", "0", "0", "0", "0", "0", "0", "0" }; static const char *mRGBText[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "SCALE", "COMBINED_ALPHA", "TEXEL0_ALPHA", "TEXEL1_ALPHA", "PRIMITIVE_ALPHA", "SHADE_ALPHA", "ENV_ALPHA", "LOD_FRACTION", "PRIM_LOD_FRAC", "K5", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" }; static const char *aRGBText[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "1", "0", }; static const char *saAText[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "1", "0", }; static const char *sbAText[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "1", "0", }; static const char *mAText[] = { "LOD_FRACTION", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "PRIM_LOD_FRAC", "0", }; static const char *aAText[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "1", "0", }; #endif extern u32 G_RDPHALF_1, G_RDPHALF_2, G_RDPHALF_CONT; extern u32 G_SPNOOP; extern u32 G_SETOTHERMODE_H, G_SETOTHERMODE_L; extern u32 G_DL, G_ENDDL, G_CULLDL, G_BRANCH_Z; extern u32 G_LOAD_UCODE; extern u32 G_MOVEMEM, G_MOVEWORD; extern u32 G_MTX, G_POPMTX; extern u32 G_GEOMETRYMODE, G_SETGEOMETRYMODE, G_CLEARGEOMETRYMODE; extern u32 G_TEXTURE; extern u32 G_DMA_IO, G_DMA_DL, G_DMA_TRI, G_DMA_MTX, G_DMA_VTX, G_DMA_TEX_OFFSET, G_DMA_OFFSETS; extern u32 G_SPECIAL_1, G_SPECIAL_2, G_SPECIAL_3; extern u32 G_VTX, G_MODIFYVTX, G_VTXCOLORBASE; extern u32 G_TRI1, G_TRI2, G_TRI4; extern u32 G_QUAD, G_LINE3D; extern u32 G_RESERVED0, G_RESERVED1, G_RESERVED2, G_RESERVED3; extern u32 G_SPRITE2D_BASE; extern u32 G_BG_1CYC, G_BG_COPY; extern u32 G_OBJ_RECTANGLE, G_OBJ_SPRITE, G_OBJ_MOVEMEM; extern u32 G_SELECT_DL, G_OBJ_RENDERMODE, G_OBJ_RECTANGLE_R; extern u32 G_OBJ_LOADTXTR, G_OBJ_LDTX_SPRITE, G_OBJ_LDTX_RECT, G_OBJ_LDTX_RECT_R; extern u32 G_RDPHALF_0, G_TRI_UNKNOWN; #define LIGHT_1 1 #define LIGHT_2 2 #define LIGHT_3 3 #define LIGHT_4 4 #define LIGHT_5 5 #define LIGHT_6 6 #define LIGHT_7 7 #define LIGHT_8 8 #define G_DL_PUSH 0x00 #define G_DL_NOPUSH 0x01 typedef struct { s16 y; s16 x; u16 flag; s16 z; s16 t; s16 s; union { struct { u8 a; u8 b; u8 g; u8 r; } color; struct { s8 a; s8 z; // b s8 y; //g s8 x; //r } normal; }; } Vertex; typedef struct { s16 y, x; u16 ci; s16 z; s16 t, s; } PDVertex; typedef struct { u8 v2, v1, v0, flag; s16 t0, s0; s16 t1, s1; s16 t2, s2; } DKRTriangle; typedef struct { u8 pad0, b, g, r; u8 pad1, b2, g2, r2; s8 pad2, z, y, x; } Light; // GBI commands typedef void (*GBIFunc)( u32 w0, u32 w1 ); typedef struct { u32 type; u32 NoN; u32 crc; const char *text; } SpecialMicrocodeInfo; typedef struct MicrocodeInfo { u32 address, dataAddress; u16 dataSize; u32 type; u32 NoN; u32 crc; u32 *text; struct MicrocodeInfo *higher, *lower; } MicrocodeInfo; typedef struct { GBIFunc cmd[256]; u32 PCStackSize, numMicrocodes; MicrocodeInfo *current, *top, *bottom; } GBIInfo; extern GBIInfo GBI; u32 GBI_GetCurrentMicrocodeType(void); void GBI_MakeCurrent( MicrocodeInfo *current ); MicrocodeInfo *GBI_DetectMicrocode( u32 uc_start, u32 uc_dstart, u16 uc_dsize ); extern u32 last_good_ucode; void GBI_Init(void); void GBI_Destroy(void); // Allows easier setting of GBI commands #define GBI_SetGBI( command, value, function ) \ command = value; \ GBI.cmd[command] = function #define GBI_InitFlags( ucode ) \ G_MTX_STACKSIZE = ucode##_MTX_STACKSIZE; \ G_MTX_MODELVIEW = ucode##_MTX_MODELVIEW; \ G_MTX_PROJECTION = ucode##_MTX_PROJECTION; \ G_MTX_MUL = ucode##_MTX_MUL; \ G_MTX_LOAD = ucode##_MTX_LOAD; \ G_MTX_NOPUSH = ucode##_MTX_NOPUSH; \ G_MTX_PUSH = ucode##_MTX_PUSH; \ \ G_TEXTURE_ENABLE = ucode##_TEXTURE_ENABLE; \ G_SHADING_SMOOTH = ucode##_SHADING_SMOOTH; \ G_CULL_FRONT = ucode##_CULL_FRONT; \ G_CULL_BACK = ucode##_CULL_BACK; \ G_CULL_BOTH = ucode##_CULL_BOTH; \ G_CLIPPING = ucode##_CLIPPING; \ \ G_MV_VIEWPORT = ucode##_MV_VIEWPORT; \ \ G_MWO_aLIGHT_1 = ucode##_MWO_aLIGHT_1; \ G_MWO_bLIGHT_1 = ucode##_MWO_bLIGHT_1; \ G_MWO_aLIGHT_2 = ucode##_MWO_aLIGHT_2; \ G_MWO_bLIGHT_2 = ucode##_MWO_bLIGHT_2; \ G_MWO_aLIGHT_3 = ucode##_MWO_aLIGHT_3; \ G_MWO_bLIGHT_3 = ucode##_MWO_bLIGHT_3; \ G_MWO_aLIGHT_4 = ucode##_MWO_aLIGHT_4; \ G_MWO_bLIGHT_4 = ucode##_MWO_bLIGHT_4; \ G_MWO_aLIGHT_5 = ucode##_MWO_aLIGHT_5; \ G_MWO_bLIGHT_5 = ucode##_MWO_bLIGHT_5; \ G_MWO_aLIGHT_6 = ucode##_MWO_aLIGHT_6; \ G_MWO_bLIGHT_6 = ucode##_MWO_bLIGHT_6; \ G_MWO_aLIGHT_7 = ucode##_MWO_aLIGHT_7; \ G_MWO_bLIGHT_7 = ucode##_MWO_bLIGHT_7; \ G_MWO_aLIGHT_8 = ucode##_MWO_aLIGHT_8; \ G_MWO_bLIGHT_8 = ucode##_MWO_bLIGHT_8; #ifdef __cplusplus } #endif #endif mupen64plus-core/src/plugin/audio_libretro/audio_plugin.h000664 001750 001750 00000003333 12655644434 024771 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - emulate_speaker_via_audio_plugin.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_PLUGIN_EMULATE_SPEAKER_VIA_LIBRETRO_H #define M64P_PLUGIN_EMULATE_SPEAKER_VIA_LIBRETRO_H #include void init_audio_libretro(unsigned max_frames); void deinit_audio_libretro(void); #endif gles2rice/src/Blender.cpp000664 001750 001750 00000036760 12655644434 016460 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "Render.h" const char * sc_szBlClr[4] = { "In", "Mem", "Bl", "Fog" }; const char * sc_szBlA1[4] = { "AIn", "AFog", "AShade", "0" }; const char * sc_szBlA2[4] = { "1-A", "AMem", "1", "0" }; //======================================================================== void CBlender::InitBlenderMode(void) // Set Alpha Blender mode { // 1. Z_COMPARE -- Enable / Disable Z-Buffer compare // 1 - Enable ZBuffer // 0 - Disable ZBuffer // 2. Z_UPDATE -- Enable / Disable Z-Buffer update // 1 - Enable ZBuffer writeable // 0 - Z-buffer not writeable // 3. AA_EN and IM_RD -- Anti-Alias // AA_EN - Enable anti-aliasing // AA_EN | IM_RD - Reduced anti-aliasing // IM_RD - ?? // - - Disable anti-aliasing // 4. ZMode // #define ZMODE_OPA 0 -- Usually used with Z_COMPARE and Z_UPDATE // or used without neither Z_COMPARE or Z_UPDATE // if used with Z_COMPARE and Z_UPDATE, then this is // the regular ZBuffer mode, with compare and update // // #define ZMODE_INTER 0x400 // #define ZMODE_XLU 0x800 -- Usually used with Z_COMPARE, but not with Z_UPDATE // Do only compare, no Z-buffer update. // Not output if the z value is the same // // #define ZMODE_DEC 0xc00 -- Usually used with Z_COMPARE, but not with Z_UPDATE // Do only compare, no update, but because this is // decal mode, so image should be updated even // the z value is the same as compared. CRender *render = CRender::g_pRender; /* Alpha Blender Modes */ // // 6. FORCE_BL - Alpha blending at blender stage // 1 - Enable alpha blending at blender // 0 - Disable alpha blending at blender // // Alpha blending at blender is usually used to render XLU surface // if enabled, then use the blending setting of C1 and C2 // 7. ALPHA_CVG_SEL - Output full alpha from the color combiner, usually not used together // with FORCE_BL. If it is used together with FORCE_BL, then ignore this // 8. CVG_X_ALPHA - Before output the color from color combiner, mod it with alpha // 9. TEX_EDGE - Ignore this // 10.CLR_ON_CVG - Used with XLU surfaces, ignore it // 11.CVG_DST // #define CVG_DST_CLAMP 0 - Usually used with OPA surface // #define CVG_DST_WRAP 0x100 - Usually used with XLU surface or OPA line // #define CVG_DST_FULL 0x200 - ? // #define CVG_DST_SAVE 0x300 - ? // // Possible Blending Inputs: // // In - Input from color combiner // Mem - Input from current frame buffer // Fog - Fog generator // BL - Blender // // Possible Blending Factors: // A-IN - Alpha from color combiner // A-MEM - Alpha from current frame buffer // (1-A) - // A-FOG - Alpha of fog color // A-SHADE - Alpha of shade // 1 - 1 // 0 - 0 #define BLEND_NOOP 0x0000 #define BLEND_NOOP5 0xcc48 // Fog * 0 + Mem * 1 #define BLEND_NOOP4 0xcc08 // Fog * 0 + In * 1 #define BLEND_FOG_ASHADE 0xc800 #define BLEND_FOG_3 0xc000 // Fog * AIn + In * 1-A #define BLEND_FOG_MEM 0xc440 // Fog * AFog + Mem * 1-A #define BLEND_FOG_APRIM 0xc400 // Fog * AFog + In * 1-A #define BLEND_BLENDCOLOR 0x8c88 #define BLEND_BI_AFOG 0x8400 // Bl * AFog + In * 1-A #define BLEND_BI_AIN 0x8040 // Bl * AIn + Mem * 1-A #define BLEND_MEM 0x4c40 // Mem*0 + Mem*(1-0)?! #define BLEND_FOG_MEM_3 0x44c0 // Mem * AFog + Fog * 1-A #define BLEND_NOOP3 0x0c48 // In * 0 + Mem * 1 #define BLEND_PASS 0x0c08 // In * 0 + In * 1 #define BLEND_FOG_MEM_IN_MEM 0x0440 // In * AFog + Mem * 1-A #define BLEND_FOG_MEM_FOG_MEM 0x04c0 // In * AFog + Fog * 1-A #define BLEND_OPA 0x0044 // In * AIn + Mem * AMem #define BLEND_XLU 0x0040 #define BLEND_MEM_ALPHA_IN 0x4044 // Mem * AIn + Mem * AMem uint32_t blendmode_1 = (uint32_t)( gRDP.otherMode.blender & 0xcccc ); uint32_t blendmode_2 = (uint32_t)( gRDP.otherMode.blender & 0x3333 ); uint32_t cycletype = gRDP.otherMode.cycle_type; switch( cycletype ) { case CYCLE_TYPE_FILL: //BlendFunc(BLEND_ONE, BLEND_ZERO); //Enable(); Disable(); break; case CYCLE_TYPE_COPY: //Disable(); BlendFunc(BLEND_ONE, BLEND_ZERO); Enable(); break; case CYCLE_TYPE_2: if( gRDP.otherMode.force_bl && gRDP.otherMode.z_cmp ) { BlendFunc(BLEND_SRCALPHA, BLEND_INVSRCALPHA); Enable(); break; } /* if( gRDP.otherMode.alpha_cvg_sel && gRDP.otherMode.cvg_x_alpha==0 ) { BlendFunc(BLEND_ONE, BLEND_ZERO); Enable(); break; } */ switch( blendmode_1+blendmode_2 ) { case BLEND_PASS+(BLEND_PASS>>2): // In * 0 + In * 1 case BLEND_FOG_APRIM+(BLEND_PASS>>2): BlendFunc(BLEND_ONE, BLEND_ZERO); if( gRDP.otherMode.alpha_cvg_sel ) { Enable(); } else { Disable(); } render->SetAlphaTestEnable( ((gRDP.otherModeL >> RSP_SETOTHERMODE_SHIFT_ALPHACOMPARE) & 0x3)==1 ? TRUE : FALSE); break; case BLEND_PASS+(BLEND_OPA>>2): // 0x0c19 // Cycle1: In * 0 + In * 1 // Cycle2: In * AIn + Mem * AMem if( gRDP.otherMode.cvg_x_alpha && gRDP.otherMode.alpha_cvg_sel ) { BlendFunc(BLEND_SRCALPHA, BLEND_INVSRCALPHA); Enable(); } else { BlendFunc(BLEND_ONE, BLEND_ZERO); Enable(); } break; case BLEND_PASS + (BLEND_XLU>>2): // 0x0c18 // Cycle1: In * 0 + In * 1 // Cycle2: In * AIn + Mem * 1-A case BLEND_FOG_ASHADE + (BLEND_XLU>>2): //Cycle1: Fog * AShade + In * 1-A //Cycle2: In * AIn + Mem * 1-A case BLEND_FOG_APRIM + (BLEND_XLU>>2): //Cycle1: Fog * AFog + In * 1-A //Cycle2: In * AIn + Mem * 1-A //case BLEND_FOG_MEM_FOG_MEM + (BLEND_OPA>>2): //Cycle1: In * AFog + Fog * 1-A //Cycle2: In * AIn + Mem * AMem case BLEND_FOG_MEM_FOG_MEM + (BLEND_PASS>>2): //Cycle1: In * AFog + Fog * 1-A //Cycle2: In * 0 + In * 1 case BLEND_XLU + (BLEND_XLU>>2): //Cycle1: Fog * AFog + In * 1-A //Cycle2: In * AIn + Mem * 1-A case BLEND_BI_AFOG + (BLEND_XLU>>2): //Cycle1: Bl * AFog + In * 1-A //Cycle2: In * AIn + Mem * 1-A case BLEND_XLU + (BLEND_FOG_MEM_IN_MEM>>2): //Cycle1: In * AIn + Mem * 1-A //Cycle2: In * AFog + Mem * 1-A case BLEND_PASS + (BLEND_FOG_MEM_IN_MEM>>2): //Cycle1: In * 0 + In * 1 //Cycle2: In * AFog + Mem * 1-A BlendFunc(BLEND_SRCALPHA, BLEND_INVSRCALPHA); Enable(); break; case BLEND_FOG_MEM_FOG_MEM + (BLEND_OPA>>2): //Cycle1: In * AFog + Fog * 1-A //Cycle2: In * AIn + Mem * AMem BlendFunc(BLEND_ONE, BLEND_ZERO); Enable(); break; case BLEND_FOG_APRIM + (BLEND_OPA>>2): // For Golden Eye //Cycle1: Fog * AFog + In * 1-A //Cycle2: In * AIn + Mem * AMem case BLEND_FOG_ASHADE + (BLEND_OPA>>2): //Cycle1: Fog * AShade + In * 1-A //Cycle2: In * AIn + Mem * AMem case BLEND_BI_AFOG + (BLEND_OPA>>2): //Cycle1: Bl * AFog + In * 1-A //Cycle2: In * AIn + Mem * 1-AMem case BLEND_FOG_ASHADE + (BLEND_NOOP>>2): //Cycle1: Fog * AShade + In * 1-A //Cycle2: In * AIn + In * 1-A case BLEND_NOOP + (BLEND_OPA>>2): //Cycle1: In * AIn + In * 1-A //Cycle2: In * AIn + Mem * AMem case BLEND_NOOP4 + (BLEND_NOOP>>2): //Cycle1: Fog * AIn + In * 1-A //Cycle2: In * 0 + In * 1 case BLEND_FOG_ASHADE+(BLEND_PASS>>2): //Cycle1: Fog * AShade + In * 1-A //Cycle2: In * 0 + In * 1 case BLEND_FOG_3+(BLEND_PASS>>2): BlendFunc(BLEND_ONE, BLEND_ZERO); Enable(); break; case BLEND_FOG_ASHADE+0x0301: // c800 - Cycle1: Fog * AShade + In * 1-A // 0301 - Cycle2: In * 0 + In * AMem BlendFunc(BLEND_SRCALPHA, BLEND_ZERO); Enable(); break; case 0x0c08+0x1111: // 0c08 - Cycle1: In * 0 + In * 1 // 1111 - Cycle2: Mem * AFog + Mem * AMem BlendFunc(BLEND_ZERO, BLEND_DESTALPHA); Enable(); break; default: #ifdef DEBUGGER if( pauseAtNext ) { uint32_t dwM1A_1 = (gRDP.otherMode.blender>>14) & 0x3; uint32_t dwM1B_1 = (gRDP.otherMode.blender>>10) & 0x3; uint32_t dwM2A_1 = (gRDP.otherMode.blender>>6) & 0x3; uint32_t dwM2B_1 = (gRDP.otherMode.blender>>2) & 0x3; uint32_t dwM1A_2 = (gRDP.otherMode.blender>>12) & 0x3; uint32_t dwM1B_2 = (gRDP.otherMode.blender>>8) & 0x3; uint32_t dwM2A_2 = (gRDP.otherMode.blender>>4) & 0x3; uint32_t dwM2B_2 = (gRDP.otherMode.blender ) & 0x3; TRACE0("Unknown Blender Mode: 2 cycle"); DebuggerAppendMsg( "\tblender:\t\t%04x - Cycle1:\t%s * %s + %s * %s\n\t\t%04x - Cycle2:\t%s * %s + %s * %s", blendmode_1, sc_szBlClr[dwM1A_1], sc_szBlA1[dwM1B_1], sc_szBlClr[dwM2A_1], sc_szBlA2[dwM2B_1], blendmode_2, sc_szBlClr[dwM1A_2], sc_szBlA1[dwM1B_2], sc_szBlClr[dwM2A_2], sc_szBlA2[dwM2B_2]); } #endif if( blendmode_2 == (BLEND_PASS>>2) ) { BlendFunc(BLEND_ONE, BLEND_ZERO); } else { BlendFunc(BLEND_SRCALPHA, BLEND_INVSRCALPHA); } Enable(); break; } break; default: // 1/2 Cycle or Copy if( gRDP.otherMode.force_bl && gRDP.otherMode.z_cmp && blendmode_1 != BLEND_FOG_ASHADE ) { BlendFunc(BLEND_SRCALPHA, BLEND_INVSRCALPHA); Enable(); break; } if( gRDP.otherMode.force_bl && options.enableHackForGames == HACK_FOR_COMMANDCONQUER ) { BlendFunc(BLEND_SRCALPHA, BLEND_INVSRCALPHA); Enable(); break; } #ifdef DEBUGGER //if( (blendmode_1>>2) != blendmode_2 ) //{ // DebuggerAppendMsg("Warning: in 1 cycle mode, blend1!=blend2"); //} #endif switch ( blendmode_1 ) //switch ( blendmode_2<<2 ) { case BLEND_XLU: // IN * A_IN + MEM * (1-A_IN) case BLEND_BI_AIN: // Bl * AIn + Mem * 1-A case BLEND_FOG_MEM: // c440 - Cycle1: Fog * AFog + Mem * 1-A case BLEND_FOG_MEM_IN_MEM: // c440 - Cycle1: In * AFog + Mem * 1-A case BLEND_BLENDCOLOR: //Bl * 0 + Bl * 1 case 0x00c0: //In * AIn + Fog * 1-A BlendFunc(BLEND_SRCALPHA, BLEND_INVSRCALPHA); Enable(); break; case BLEND_MEM_ALPHA_IN: // Mem * AIn + Mem * AMem BlendFunc(BLEND_ZERO, BLEND_DESTALPHA); Enable(); break; case BLEND_PASS: // IN * 0 + IN * 1 BlendFunc(BLEND_ONE, BLEND_ZERO); if( gRDP.otherMode.alpha_cvg_sel ) { Enable(); } else { Disable(); } break; case BLEND_OPA: // IN * A_IN + MEM * A_MEM if( options.enableHackForGames == HACK_FOR_MARIO_TENNIS ) { BlendFunc(BLEND_SRCALPHA, BLEND_INVSRCALPHA); } else { BlendFunc(BLEND_ONE, BLEND_ZERO); } Enable(); break; case BLEND_NOOP: // IN * A_IN + IN * (1 - A_IN) case BLEND_FOG_ASHADE: // Fog * AShade + In * 1-A case BLEND_FOG_MEM_3: // Mem * AFog + Fog * 1-A case BLEND_BI_AFOG: // Bl * AFog + In * 1-A BlendFunc(BLEND_ONE, BLEND_ZERO); Enable(); break; case BLEND_FOG_APRIM: // Fog * AFog + In * 1-A BlendFunc(BLEND_INVSRCALPHA, BLEND_ZERO); Enable(); break; case BLEND_NOOP3: // In * 0 + Mem * 1 case BLEND_NOOP5: // Fog * 0 + Mem * 1 BlendFunc(BLEND_ZERO, BLEND_ONE); Enable(); break; case BLEND_MEM: // Mem * 0 + Mem * 1-A // WaveRace BlendFunc(BLEND_ZERO, BLEND_ONE); Enable(); break; default: #ifdef DEBUGGER if( pauseAtNext ) { uint32_t dwM1A_1 = (gRDP.otherMode.blender>>14) & 0x3; uint32_t dwM1B_1 = (gRDP.otherMode.blender>>10) & 0x3; uint32_t dwM2A_1 = (gRDP.otherMode.blender>>6) & 0x3; uint32_t dwM2B_1 = (gRDP.otherMode.blender>>2) & 0x3; uint32_t dwM1A_2 = (gRDP.otherMode.blender>>12) & 0x3; uint32_t dwM1B_2 = (gRDP.otherMode.blender>>8) & 0x3; uint32_t dwM2A_2 = (gRDP.otherMode.blender>>4) & 0x3; uint32_t dwM2B_2 = (gRDP.otherMode.blender ) & 0x3; TRACE0("Unknown Blender Mode: 1 cycle"); DebuggerAppendMsg( "\tblender:\t\t%04x - Cycle1:\t%s * %s + %s * %s\n\t\t\tCycle2:\t%s * %s + %s * %s", blendmode_1, sc_szBlClr[dwM1A_1], sc_szBlA1[dwM1B_1], sc_szBlClr[dwM2A_1], sc_szBlA2[dwM2B_1], sc_szBlClr[dwM1A_2], sc_szBlA1[dwM1B_2], sc_szBlClr[dwM2A_2], sc_szBlA2[dwM2B_2]); } #endif BlendFunc(BLEND_SRCALPHA, BLEND_INVSRCALPHA); Enable(); render->SetAlphaTestEnable(TRUE); break; } } } mupen64plus-core/src/r4300/new_dynarec/new_dynarec.c000664 001750 001750 00001372263 12655644434 023364 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - new_dynarec.c * * Copyright (C) 2009-2011 Ari64 * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include //include for uint64_t #include #include #if defined(__LIBRETRO__) && (defined(IOS) || defined(__QNX__)) typedef unsigned char u_char; typedef unsigned int u_int; #define MAP_ANONYMOUS MAP_ANON #endif #define EMU_MUPEN64 #include "../recomp.h" #include "../recomph.h" //include for function prototypes #include "../cp0_private.h" #include "../cp1.h" #include "../r4300.h" #include "../ops.h" #include "../tlb.h" #include "../interupt.h" #include "../cached_interp.h" #include "new_dynarec.h" #include "../../memory/memory.h" #include "../../main/main.h" #include "../../main/rom.h" #include "rsp/rsp_core.h" #if NEW_DYNAREC == NEW_DYNAREC_X86 #include "assem_x86.h" #elif NEW_DYNAREC == NEW_DYNAREC_AMD64 #include "assem_x64.h" #elif NEW_DYNAREC == NEW_DYNAREC_ARM #include "assem_arm.h" #else #error Unsupported dynarec architecture #endif #define MAXBLOCK 4096 #define MAX_OUTPUT_BLOCK_SIZE 262144 #define CLOCK_DIVIDER count_per_op void *base_addr; struct regstat { signed char regmap_entry[HOST_REGS]; signed char regmap[HOST_REGS]; uint64_t was32; uint64_t is32; uint64_t wasdirty; uint64_t dirty; uint64_t u; uint64_t uu; u_int wasconst; u_int isconst; uint64_t constmap[HOST_REGS]; }; struct ll_entry { u_int vaddr; u_int reg32; void *addr; struct ll_entry *next; }; static u_int start; static u_int *source; static char insn[MAXBLOCK][10]; static u_char itype[MAXBLOCK]; static u_char opcode[MAXBLOCK]; static u_char opcode2[MAXBLOCK]; static u_char bt[MAXBLOCK]; static u_char rs1[MAXBLOCK]; static u_char rs2[MAXBLOCK]; static u_char rt1[MAXBLOCK]; static u_char rt2[MAXBLOCK]; static u_char us1[MAXBLOCK]; static u_char us2[MAXBLOCK]; static u_char dep1[MAXBLOCK]; static u_char dep2[MAXBLOCK]; static u_char lt1[MAXBLOCK]; static int imm[MAXBLOCK]; static u_int ba[MAXBLOCK]; static char likely[MAXBLOCK]; static char is_ds[MAXBLOCK]; static char ooo[MAXBLOCK]; static uint64_t unneeded_reg[MAXBLOCK]; static uint64_t unneeded_reg_upper[MAXBLOCK]; static uint64_t branch_unneeded_reg[MAXBLOCK]; static uint64_t branch_unneeded_reg_upper[MAXBLOCK]; static uint64_t p32[MAXBLOCK]; static uint64_t pr32[MAXBLOCK]; static signed char regmap_pre[MAXBLOCK][HOST_REGS]; static signed char regmap[MAXBLOCK][HOST_REGS]; static signed char regmap_entry[MAXBLOCK][HOST_REGS]; static uint64_t constmap[MAXBLOCK][HOST_REGS]; static struct regstat regs[MAXBLOCK]; static struct regstat branch_regs[MAXBLOCK]; static signed char minimum_free_regs[MAXBLOCK]; static u_int needed_reg[MAXBLOCK]; static uint64_t requires_32bit[MAXBLOCK]; static u_int wont_dirty[MAXBLOCK]; static u_int will_dirty[MAXBLOCK]; static int ccadj[MAXBLOCK]; static int slen; static uintptr_t instr_addr[MAXBLOCK]; static uintptr_t link_addr[MAXBLOCK][3]; static int linkcount; static uintptr_t stubs[MAXBLOCK*3][8]; static int stubcount; static int literalcount; static int is_delayslot; static int cop1_usable; u_char *out; struct ll_entry *jump_in[4096]; static struct ll_entry *jump_out[4096]; struct ll_entry *jump_dirty[4096]; u_int hash_table[65536][4] __attribute__((aligned(16))); char shadow[2097152] __attribute__((aligned(16))); static void *copy; static int expirep; u_int using_tlb; static u_int stop_after_jal; extern u_char restore_candidate[512]; extern int cycle_count; /* registers that may be allocated */ /* 1-31 gpr */ #define HIREG 32 // hi #define LOREG 33 // lo #define FSREG 34 // FPU status (FCSR) #define CSREG 35 // Coprocessor status #define CCREG 36 // Cycle count #define INVCP 37 // Pointer to invalid_code #define MMREG 38 // Pointer to memory_map #define ROREG 39 // ram offset (if rdram!=0x80000000) #define TEMPREG 40 #define FTEMP 40 // FPU temporary register #define PTEMP 41 // Prefetch temporary register #define TLREG 42 // TLB mapping offset #define RHASH 43 // Return address hash #define RHTBL 44 // Return address hash table address #define RTEMP 45 // JR/JALR address register #define MAXREG 45 #define AGEN1 46 // Address generation temporary register #define AGEN2 47 // Address generation temporary register #define MGEN1 48 // Maptable address generation temporary register #define MGEN2 49 // Maptable address generation temporary register #define BTREG 50 // Branch target temporary register /* instruction types */ #define NOP 0 // No operation #define LOAD 1 // Load #define STORE 2 // Store #define LOADLR 3 // Unaligned load #define STORELR 4 // Unaligned store #define MOV 5 // Move #define ALU 6 // Arithmetic/logic #define MULTDIV 7 // Multiply/divide #define SHIFT 8 // Shift by register #define SHIFTIMM 9// Shift by immediate #define IMM16 10 // 16-bit immediate #define RJUMP 11 // Unconditional jump to register #define UJUMP 12 // Unconditional jump #define CJUMP 13 // Conditional branch (BEQ/BNE/BGTZ/BLEZ) #define SJUMP 14 // Conditional branch (regimm format) #define COP0 15 // Coprocessor 0 #define COP1 16 // Coprocessor 1 #define C1LS 17 // Coprocessor 1 load/store #define FJUMP 18 // Conditional branch (floating point) #define FLOAT 19 // Floating point unit #define FCONV 20 // Convert integer to float #define FCOMP 21 // Floating point compare (sets FSREG) #define SYSCALL 22// SYSCALL #define OTHER 23 // Other #define SPAN 24 // Branch/delay slot spans 2 pages #define NI 25 // Not implemented /* stubs */ #define CC_STUB 1 #define FP_STUB 2 #define LOADB_STUB 3 #define LOADH_STUB 4 #define LOADW_STUB 5 #define LOADD_STUB 6 #define LOADBU_STUB 7 #define LOADHU_STUB 8 #define STOREB_STUB 9 #define STOREH_STUB 10 #define STOREW_STUB 11 #define STORED_STUB 12 #define STORELR_STUB 13 #define INVCODE_STUB 14 /* branch codes */ #define TAKEN 1 #define NOTTAKEN 2 #define NULLDS 3 /* bug-fix to implement __clear_cache (missing in Android; http://code.google.com/p/android/issues/detail?id=1803) */ void __clear_cache_bugfix(char* begin, char *end); #ifdef ANDROID #define __clear_cache __clear_cache_bugfix #endif #ifdef __BLACKBERRY_QNX__ #undef __clear_cache #define __clear_cache(start,end) msync(start, (size_t)((void*)end - (void*)start), MS_SYNC | MS_CACHE_ONLY | MS_INVALIDATE_ICACHE); #elif defined(__MACH__) #include #define __clear_cache mach_clear_cache static void __clear_cache(void *start, void *end) { size_t len = (char *)end - (char *)start; sys_dcache_flush(start, len); sys_icache_invalidate(start, len); } #endif // asm linkage int new_recompile_block(int addr); void *get_addr_ht(u_int vaddr); static void remove_hash(int vaddr); void dyna_linker(); void dyna_linker_ds(); void verify_code(); void verify_code_vm(); void verify_code_ds(); void cc_interrupt(); void fp_exception(); void fp_exception_ds(); void jump_syscall(); void jump_eret(); #if NEW_DYNAREC == NEW_DYNAREC_ARM static void invalidate_addr(u_int addr); #endif // TLB void TLBWI_new(); void TLBWR_new(); void read_nomem_new(); void read_nomemb_new(); void read_nomemh_new(); void read_nomemd_new(); void write_nomem_new(); void write_nomemb_new(); void write_nomemh_new(); void write_nomemd_new(); void write_rdram_new(); void write_rdramb_new(); void write_rdramh_new(); void write_rdramd_new(); extern uintptr_t memory_map[1048576]; // Needed by assembler static void wb_register(signed char r,signed char regmap[],uint64_t dirty,uint64_t is32); static void wb_dirtys(signed char i_regmap[],uint64_t i_is32,uint64_t i_dirty); static void wb_needed_dirtys(signed char i_regmap[],uint64_t i_is32,uint64_t i_dirty,int addr); static void load_all_regs(signed char i_regmap[]); static void load_needed_regs(signed char i_regmap[],signed char next_regmap[]); static void load_regs_entry(int t); static void load_all_consts(signed char regmap[],int is32,u_int dirty,int i); static void add_stub(int type,intptr_t addr,int retaddr,int a,intptr_t b,intptr_t c,int d,int e); static void add_to_linker(intptr_t addr,int target,int ext); static int verify_dirty(void *addr); static int tracedebug=0; //#define DEBUG_CYCLE_COUNT 1 // Uncomment these two lines to generate debug output: //#define ASSEM_DEBUG 1 //#define INV_DEBUG 1 // Uncomment this line to output the number of NOTCOMPILED blocks as they occur: //#define COUNT_NOTCOMPILEDS 1 #if defined (COUNT_NOTCOMPILEDS ) int notcompiledCount = 0; #endif #ifndef __LIBRETRO__ // Quiet the warnings on nullf static void nullf() {} #else #define nullf(...) #endif #if defined( ASSEM_DEBUG ) #define assem_debug(...) DebugMessage(M64MSG_VERBOSE, __VA_ARGS__) #else #define assem_debug nullf #endif #if defined( INV_DEBUG ) #define inv_debug(...) DebugMessage(M64MSG_VERBOSE, __VA_ARGS__) #else #define inv_debug nullf #endif #define log_message(...) DebugMessage(M64MSG_VERBOSE, __VA_ARGS__) #ifndef DISABLE_TLB static void tlb_hacks(void) { // Goldeneye hack if (strncmp((char *) ROM_HEADER.Name, "GOLDENEYE",9) == 0) { u_int addr; int n; switch (ROM_HEADER.destination_code&0xFF) { case 0x45: // U addr=0x34b30; break; case 0x4A: // J addr=0x34b70; break; case 0x50: // E addr=0x329f0; break; default: // Unknown country code addr=0; break; } u_int rom_addr=(u_int)g_rom; #ifdef ROM_COPY // Since memory_map is 32-bit, on 64-bit systems the rom needs to be // in the lower 4G of memory to use this hack. Copy it if necessary. if((void *)g_rom > (void *)0xffffffff) { munmap(ROM_COPY, 67108864); if(mmap(ROM_COPY, 12582912, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) <= 0) {DebugMessage(M64MSG_ERROR, "mmap() failed");} memcpy(ROM_COPY, g_rom, 12582912); rom_addr=(u_int)ROM_COPY; } #endif if(addr) { for(n=0x7F000;n<0x80000;n++) { memory_map[n]=(((u_int)(rom_addr+addr-0x7F000000))>>2)|0x40000000; } } } } #endif static u_int get_page(u_int vaddr) { u_int page=(vaddr^0x80000000)>>12; #ifndef DISABLE_TLB if(page>262143&&tlb_LUT_r[vaddr>>12]) page=(tlb_LUT_r[vaddr>>12]^0x80000000)>>12; #endif if(page>2048) page=2048+(page&2047); return page; } static u_int get_vpage(u_int vaddr) { u_int vpage=(vaddr^0x80000000)>>12; #ifndef DISABLE_TLB if(vpage>262143&&tlb_LUT_r[vaddr>>12]) vpage&=2047; // jump_dirty uses a hash of the virtual address instead #endif if(vpage>2048) vpage=2048+(vpage&2047); return vpage; } // Get address from virtual address // This is called from the recompiled JR/JALR instructions void *get_addr(u_int vaddr) { u_int page = get_page(vaddr); u_int vpage = get_vpage(vaddr); struct ll_entry *head; //DebugMessage(M64MSG_VERBOSE, "TRACE: count=%d next=%d (get_addr %x,page %d)",g_cp0_regs[CP0_COUNT_REG],next_interupt,vaddr,page); head=jump_in[page]; while(head!=NULL) { if(head->vaddr==vaddr&&head->reg32==0) { //DebugMessage(M64MSG_VERBOSE, "TRACE: count=%d next=%d (get_addr match %x: %x)",g_cp0_regs[CP0_COUNT_REG],next_interupt,vaddr,(int)head->addr); u_int *ht_bin=hash_table[((vaddr>>16)^vaddr)&0xFFFF]; ht_bin[3]=ht_bin[1]; ht_bin[2]=ht_bin[0]; ht_bin[1]=(int)head->addr; ht_bin[0]=vaddr; return head->addr; } head=head->next; } head=jump_dirty[vpage]; while(head!=NULL) { if(head->vaddr==vaddr&&head->reg32==0) { //DebugMessage(M64MSG_VERBOSE, "TRACE: count=%d next=%d (get_addr match dirty %x: %x)",g_cp0_regs[CP0_COUNT_REG],next_interupt,vaddr,(int)head->addr); // Don't restore blocks which are about to expire from the cache if((((u_int)head->addr-(u_int)out)<<(32-TARGET_SIZE_2))>0x60000000+(MAX_OUTPUT_BLOCK_SIZE<<(32-TARGET_SIZE_2))) if(verify_dirty(head->addr)) { //DebugMessage(M64MSG_VERBOSE, "restore candidate: %x (%d) d=%d",vaddr,page,invalid_code[vaddr>>12]); invalid_code[vaddr>>12]=0; #ifndef DISABLE_TLB if(sizeof(*memory_map)==8) memory_map[vaddr>>12]|=0x4000000000000000; else memory_map[vaddr>>12]|=0x40000000; #endif if(vpage<2048) { #ifndef DISABLE_TLB if(tlb_LUT_r[vaddr>>12]) { invalid_code[tlb_LUT_r[vaddr>>12]>>12]=0; if(sizeof(*memory_map)==8) memory_map[tlb_LUT_r[vaddr>>12]>>12]|=0x4000000000000000; else memory_map[tlb_LUT_r[vaddr>>12]>>12]|=0x40000000; } #endif restore_candidate[vpage>>3]|=1<<(vpage&7); } else restore_candidate[page>>3]|=1<<(page&7); u_int *ht_bin=hash_table[((vaddr>>16)^vaddr)&0xFFFF]; if(ht_bin[0]==vaddr) ht_bin[1]=(int)head->addr; // Replace existing entry else { ht_bin[3] = ht_bin[1]; ht_bin[2] = ht_bin[0]; ht_bin[1] = (int)head->addr; ht_bin[0] = vaddr; } return head->addr; } } head=head->next; } //DebugMessage(M64MSG_VERBOSE, "TRACE: count=%d next=%d (get_addr no-match %x)",g_cp0_regs[CP0_COUNT_REG],next_interupt,vaddr); int r=new_recompile_block(vaddr); if(r==0) return get_addr(vaddr); // Execute in unmapped page, generate pagefault execption #if defined(EMU_MUPEN64) g_cp0_regs[CP0_STATUS_REG] |=2; g_cp0_regs[CP0_CAUSE_REG] =(vaddr<<31)|0x8; g_cp0_regs[CP0_EPC_REG] = (vaddr&1)?vaddr-5:vaddr; g_cp0_regs[CP0_BADVADDR_REG]=(vaddr&~1); g_cp0_regs[CP0_CONTEXT_REG] = (g_cp0_regs[CP0_CONTEXT_REG]&0xFF80000F)|((g_cp0_regs[CP0_BADVADDR_REG]>>9)&0x007FFFF0); g_cp0_regs[CP0_ENTRYHI_REG] = g_cp0_regs[CP0_BADVADDR_REG]&0xFFFFE000; #elif defined(EMU_PCSXR) Status|=2; Cause=(vaddr<<31)|0x8; EPC=(vaddr&1)?vaddr-5:vaddr; BadVAddr=(vaddr&~1); Context=(Context&0xFF80000F)|((BadVAddr>>9)&0x007FFFF0); EntryHi=BadVAddr&0xFFFFE000; #endif return get_addr_ht(0x80000000); } // Look up address in hash table first void *get_addr_ht(u_int vaddr) { //DebugMessage(M64MSG_VERBOSE, "TRACE: count=%d next=%d (get_addr_ht %x)",g_cp0_regs[CP0_COUNT_REG],next_interupt,vaddr); u_int *ht_bin=hash_table[((vaddr>>16)^vaddr)&0xFFFF]; if(sizeof(void *)==8) { if(ht_bin[0]==vaddr) return (void *)base_addr+((int)ht_bin[1]-(int)base_addr); if(ht_bin[2]==vaddr) return (void *)base_addr+((int)ht_bin[3]-(int)base_addr); } else { if(ht_bin[0]==vaddr) return (void *)ht_bin[1]; if(ht_bin[2]==vaddr) return (void *)ht_bin[3]; } return get_addr(vaddr); } // Some code is optimized by assuming that certain registers only contain // 32-bit values. We can jump to such locations only if all such registers // contain 32-bit values. This matches such blocks, based on a bitmap of // which registers contain values not exceeding the signed 32-bit range. void *get_addr_32(u_int vaddr,u_int flags) { //DebugMessage(M64MSG_VERBOSE, "TRACE: count=%d next=%d (get_addr_32 %x,flags %x)",g_cp0_regs[CP0_COUNT_REG],next_interupt,vaddr,flags); u_int *ht_bin=hash_table[((vaddr>>16)^vaddr)&0xFFFF]; if(sizeof(void *)==8) { if(ht_bin[0]==vaddr) return (void *)base_addr+((int)ht_bin[1]-(int)base_addr); if(ht_bin[2]==vaddr) return (void *)base_addr+((int)ht_bin[3]-(int)base_addr); } else { if(ht_bin[0]==vaddr) return (void *)ht_bin[1]; if(ht_bin[2]==vaddr) return (void *)ht_bin[3]; } u_int page=(vaddr^0x80000000)>>12; u_int vpage=page; if(page>262143&&tlb_LUT_r[vaddr>>12]) page=(tlb_LUT_r[vaddr>>12]^0x80000000)>>12; if(page>2048) page=2048+(page&2047); if(vpage>262143&&tlb_LUT_r[vaddr>>12]) vpage&=2047; // jump_dirty uses a hash of the virtual address instead if(vpage>2048) vpage=2048+(vpage&2047); struct ll_entry *head; head=jump_in[page]; while(head!=NULL) { if(head->vaddr==vaddr&&(head->reg32&flags)==0) { //DebugMessage(M64MSG_VERBOSE, "TRACE: count=%d next=%d (get_addr_32 match %x: %x)",g_cp0_regs[CP0_COUNT_REG],next_interupt,vaddr,(int)head->addr); if(head->reg32==0) { u_int *ht_bin=hash_table[((vaddr>>16)^vaddr)&0xFFFF]; if(ht_bin[0]==-1) { ht_bin[1]=(int)head->addr; ht_bin[0]=vaddr; }else if(ht_bin[2]==-1) { ht_bin[3]=(int)head->addr; ht_bin[2]=vaddr; } //ht_bin[3]=ht_bin[1]; //ht_bin[2]=ht_bin[0]; //ht_bin[1]=(int)head->addr; //ht_bin[0]=vaddr; } return head->addr; } head=head->next; } head=jump_dirty[vpage]; while(head!=NULL) { if(head->vaddr==vaddr&&(head->reg32&flags)==0) { //DebugMessage(M64MSG_VERBOSE, "TRACE: count=%d next=%d (get_addr_32 match dirty %x: %x)",g_cp0_regs[CP0_COUNT_REG],next_interupt,vaddr,(int)head->addr); // Don't restore blocks which are about to expire from the cache if((((u_int)head->addr-(u_int)out)<<(32-TARGET_SIZE_2))>0x60000000+(MAX_OUTPUT_BLOCK_SIZE<<(32-TARGET_SIZE_2))) if(verify_dirty(head->addr)) { //DebugMessage(M64MSG_VERBOSE, "restore candidate: %x (%d) d=%d",vaddr,page,invalid_code[vaddr>>12]); invalid_code[vaddr>>12]=0; if(sizeof(*memory_map)==8) memory_map[vaddr>>12]|=0x4000000000000000; else memory_map[vaddr>>12]|=0x40000000; if(vpage<2048) { if(tlb_LUT_r[vaddr>>12]) { invalid_code[tlb_LUT_r[vaddr>>12]>>12]=0; if(sizeof(*memory_map)==8) memory_map[tlb_LUT_r[vaddr>>12]>>12]|=0x4000000000000000; else memory_map[tlb_LUT_r[vaddr>>12]>>12]|=0x40000000; } restore_candidate[vpage>>3]|=1<<(vpage&7); } else restore_candidate[page>>3]|=1<<(page&7); if(head->reg32==0) { u_int *ht_bin=hash_table[((vaddr>>16)^vaddr)&0xFFFF]; if(ht_bin[0]==-1) { ht_bin[1]=(int)head->addr; ht_bin[0]=vaddr; }else if(ht_bin[2]==-1) { ht_bin[3]=(int)head->addr; ht_bin[2]=vaddr; } //ht_bin[3]=ht_bin[1]; //ht_bin[2]=ht_bin[0]; //ht_bin[1]=(int)head->addr; //ht_bin[0]=vaddr; } return head->addr; } } head=head->next; } //DebugMessage(M64MSG_VERBOSE, "TRACE: count=%d next=%d (get_addr_32 no-match %x,flags %x)",g_cp0_regs[CP0_COUNT_REG],next_interupt,vaddr,flags); int r=new_recompile_block(vaddr); if(r==0) return get_addr(vaddr); // Execute in unmapped page, generate pagefault execption g_cp0_regs[CP0_STATUS_REG] |= 2; g_cp0_regs[CP0_CAUSE_REG] = (vaddr<<31)|0x8; g_cp0_regs[CP0_EPC_REG] = (vaddr&1)?vaddr-5:vaddr; g_cp0_regs[CP0_BADVADDR_REG]=(vaddr&~1); g_cp0_regs[CP0_CONTEXT_REG] = (g_cp0_regs[CP0_CONTEXT_REG]&0xFF80000F)|((g_cp0_regs[CP0_BADVADDR_REG]>>9)&0x007FFFF0); g_cp0_regs[CP0_ENTRYHI_REG] = g_cp0_regs[CP0_BADVADDR_REG]&0xFFFFE000; return get_addr_ht(0x80000000); } static void clear_all_regs(signed char regmap[]) { int hr; for (hr=0;hrregmap[hr]&63)==reg) cur->dirty|=1<dirty>>hr)&1) { reg=cur->regmap[hr]; if(reg>=64) if((cur->is32>>(reg&63))&1) cur->regmap[hr]=-1; } } } static void set_const(struct regstat *cur,signed char reg,uint64_t value) { int hr; if(!reg) return; for (hr=0;hrregmap[hr]==reg) { cur->isconst|=1<constmap[hr]=value; } else if((cur->regmap[hr]^64)==reg) { cur->isconst|=1<constmap[hr]=value>>32; } } } static void clear_const(struct regstat *cur,signed char reg) { int hr; if(!reg) return; for (hr=0;hrregmap[hr]&63)==reg) { cur->isconst&=~(1<regmap[hr]&63)==reg) { return (cur->isconst>>hr)&1; } } return 0; } static uint64_t get_const(struct regstat *cur,signed char reg) { int hr; if(!reg) return 0; for (hr=0;hrregmap[hr]==reg) { return cur->constmap[hr]; } } DebugMessage(M64MSG_ERROR, "Unknown constant in r%d",reg); exit(1); } // Least soon needed registers // Look at the next ten instructions and see which registers // will be used. Try not to reallocate these. static void lsn(u_char hsn[], int i, int *preferred_reg) { int j; int b=-1; for(j=0;j<9;j++) { if(i+j>=slen) { j=slen-i-1; break; } if(itype[i+j]==UJUMP||itype[i+j]==RJUMP||(source[i+j]>>16)==0x1000) { // Don't go past an unconditonal jump j++; break; } } for(;j>=0;j--) { if(rs1[i+j]) hsn[rs1[i+j]]=j; if(rs2[i+j]) hsn[rs2[i+j]]=j; if(rt1[i+j]) hsn[rt1[i+j]]=j; if(rt2[i+j]) hsn[rt2[i+j]]=j; if(itype[i+j]==STORE || itype[i+j]==STORELR) { // Stores can allocate zero hsn[rs1[i+j]]=j; hsn[rs2[i+j]]=j; } // On some architectures stores need invc_ptr #if defined(HOST_IMM8) || defined(NEED_INVC_PTR) if(itype[i+j]==STORE || itype[i+j]==STORELR || (opcode[i+j]&0x3b)==0x39) { hsn[INVCP]=j; } #endif if(i+j>=0&&(itype[i+j]==UJUMP||itype[i+j]==CJUMP||itype[i+j]==SJUMP||itype[i+j]==FJUMP)) { hsn[CCREG]=j; b=j; } } if(b>=0) { if(ba[i+b]>=start && ba[i+b]<(start+slen*4)) { // Follow first branch int t=(ba[i+b]-start)>>2; j=7-b;if(t+j>=slen) j=slen-t-1; for(;j>=0;j--) { if(rs1[t+j]) if(hsn[rs1[t+j]]>j+b+2) hsn[rs1[t+j]]=j+b+2; if(rs2[t+j]) if(hsn[rs2[t+j]]>j+b+2) hsn[rs2[t+j]]=j+b+2; //if(rt1[t+j]) if(hsn[rt1[t+j]]>j+b+2) hsn[rt1[t+j]]=j+b+2; //if(rt2[t+j]) if(hsn[rt2[t+j]]>j+b+2) hsn[rt2[t+j]]=j+b+2; } } // TODO: preferred register based on backward branch } // Delay slot should preferably not overwrite branch conditions or cycle count if(i>0&&(itype[i-1]==RJUMP||itype[i-1]==UJUMP||itype[i-1]==CJUMP||itype[i-1]==SJUMP||itype[i-1]==FJUMP)) { if(rs1[i-1]) if(hsn[rs1[i-1]]>1) hsn[rs1[i-1]]=1; if(rs2[i-1]) if(hsn[rs2[i-1]]>1) hsn[rs2[i-1]]=1; hsn[CCREG]=1; // ...or hash tables hsn[RHASH]=1; hsn[RHTBL]=1; } // Coprocessor load/store needs FTEMP, even if not declared if(itype[i]==C1LS #ifdef EMU_PCSXR || (itype[i] == C2LS) #else #endif ) hsn[FTEMP]=0; // Load L/R also uses FTEMP as a temporary register if(itype[i]==LOADLR) hsn[FTEMP]=0; #ifdef EMU_PCSXR // Also SWL/SWR/SDL/SDR if(opcode[i]==0x2a||opcode[i]==0x2e||opcode[i]==0x2c||opcode[i]==0x2d) #else // Also 64-bit SDL/SDR if(opcode[i]==0x2c||opcode[i]==0x2d) #endif hsn[FTEMP]=0; // Don't remove the TLB registers either if(itype[i]==LOAD || itype[i]==LOADLR || itype[i]==STORE || itype[i]==STORELR || itype[i]==C1LS #ifdef EMU_PCSXR || itype[i]==C2LS #endif ) hsn[TLREG]=0; // Don't remove the miniht registers if(itype[i]==UJUMP||itype[i]==RJUMP) { hsn[RHASH]=0; hsn[RHTBL]=0; } } // We only want to allocate registers if we're going to use them again soon static int needed_again(int r, int i) { int j; /*int b=-1;*/ int rn=10; if(i>0&&(itype[i-1]==UJUMP||itype[i-1]==RJUMP||(source[i-1]>>16)==0x1000)) { if(ba[i-1]start+slen*4-4) return 0; // Don't need any registers if exiting the block } for(j=0;j<9;j++) { if(i+j>=slen) { j=slen-i-1; break; } if(itype[i+j]==UJUMP||itype[i+j]==RJUMP||(source[i+j]>>16)==0x1000) { // Don't go past an unconditonal jump j++; break; } if(itype[i+j]==SYSCALL||((source[i+j]&0xfc00003f)==0x0d)) { break; } } for(;j>=1;j--) { if(rs1[i+j]==r) rn=j; if(rs2[i+j]==r) rn=j; if((unneeded_reg[i+j]>>r)&1) rn=10; if(i+j>=0&&(itype[i+j]==UJUMP||itype[i+j]==CJUMP||itype[i+j]==SJUMP||itype[i+j]==FJUMP)) { /*b=j;*/ } } /* if(b>=0) { if(ba[i+b]>=start && ba[i+b]<(start+slen*4)) { // Follow first branch int o=rn; int t=(ba[i+b]-start)>>2; j=7-b;if(t+j>=slen) j=slen-t-1; for(;j>=0;j--) { if(!((unneeded_reg[t+j]>>r)&1)) { if(rs1[t+j]==r) if(rn>j+b+2) rn=j+b+2; if(rs2[t+j]==r) if(rn>j+b+2) rn=j+b+2; } else rn=o; } } }*/ if(rn<10) return 1; return 0; } // Try to match register allocations at the end of a loop with those // at the beginning static int loop_reg(int i, int r, int hr) { int j,k; for(j=0;j<9;j++) { if(i+j>=slen) { j=slen-i-1; break; } if(itype[i+j]==UJUMP||itype[i+j]==RJUMP||(source[i+j]>>16)==0x1000) { // Don't go past an unconditonal jump j++; break; } } k=0; if(i>0){ if(itype[i-1]==UJUMP||itype[i-1]==CJUMP||itype[i-1]==SJUMP||itype[i-1]==FJUMP) k--; } for(;k>r)&1)) return hr; if(r>64&&((unneeded_reg_upper[i+k]>>r)&1)) return hr; if(i+k>=0&&(itype[i+k]==UJUMP||itype[i+k]==CJUMP||itype[i+k]==SJUMP||itype[i+k]==FJUMP)) { if(ba[i+k]>=start && ba[i+k]<(start+i*4)) { int t=(ba[i+k]-start)>>2; int reg=get_reg(regs[t].regmap_entry,r); if(reg>=0) return reg; //reg=get_reg(regs[t+1].regmap_entry,r); //if(reg>=0) return reg; } } } return hr; } // Allocate every register, preserving source/target regs static void alloc_all(struct regstat *cur,int i) { int hr; for(hr=0;hrregmap[hr]&63)!=rs1[i])&&((cur->regmap[hr]&63)!=rs2[i])&& ((cur->regmap[hr]&63)!=rt1[i])&&((cur->regmap[hr]&63)!=rt2[i])) { cur->regmap[hr]=-1; cur->dirty&=~(1<regmap[hr]&63)==0) { cur->regmap[hr]=-1; cur->dirty&=~(1<>32) // ,(int)reg[LOREG],(int)(reg[LOREG]>>32)); } static void divu64(uint64_t dividend,uint64_t divisor) { lo=dividend/divisor; hi=dividend%divisor; //DebugMessage(M64MSG_VERBOSE, "TRACE: ddivu %8x%8x %8x%8x",(int)reg[HIREG],(int)(reg[HIREG]>>32) // ,(int)reg[LOREG],(int)(reg[LOREG]>>32)); } static void mult64(int64_t m1,uint64_t m2) { unsigned long long int op1, op2, op3, op4; unsigned long long int result1, result2, result3, result4; unsigned long long int temp1, temp2, temp3, temp4; int sign = 0; if (m1 < 0) { op2 = -m1; sign = 1 - sign; } else op2 = m1; if (m2 < 0) { op4 = -m2; sign = 1 - sign; } else op4 = m2; op1 = op2 & 0xFFFFFFFF; op2 = (op2 >> 32) & 0xFFFFFFFF; op3 = op4 & 0xFFFFFFFF; op4 = (op4 >> 32) & 0xFFFFFFFF; temp1 = op1 * op3; temp2 = (temp1 >> 32) + op1 * op4; temp3 = op2 * op3; temp4 = (temp3 >> 32) + op2 * op4; result1 = temp1 & 0xFFFFFFFF; result2 = temp2 + (temp3 & 0xFFFFFFFF); result3 = (result2 >> 32) + temp4; result4 = (result3 >> 32); lo = result1 | (result2 << 32); hi = (result3 & 0xFFFFFFFF) | (result4 << 32); if (sign) { hi = ~hi; if (!lo) hi++; else lo = ~lo + 1; } } static void multu64(uint64_t m1,uint64_t m2) { unsigned long long int op1, op2, op3, op4; unsigned long long int result1, result2, result3, result4; unsigned long long int temp1, temp2, temp3, temp4; op1 = m1 & 0xFFFFFFFF; op2 = (m1 >> 32) & 0xFFFFFFFF; op3 = m2 & 0xFFFFFFFF; op4 = (m2 >> 32) & 0xFFFFFFFF; temp1 = op1 * op3; temp2 = (temp1 >> 32) + op1 * op4; temp3 = op2 * op3; temp4 = (temp3 >> 32) + op2 * op4; result1 = temp1 & 0xFFFFFFFF; result2 = temp2 + (temp3 & 0xFFFFFFFF); result3 = (result2 >> 32) + temp4; result4 = (result3 >> 32); lo = result1 | (result2 << 32); hi = (result3 & 0xFFFFFFFF) | (result4 << 32); //DebugMessage(M64MSG_VERBOSE, "TRACE: dmultu %8x%8x %8x%8x",(int)reg[HIREG],(int)(reg[HIREG]>>32) // ,(int)reg[LOREG],(int)(reg[LOREG]>>32)); } static uint64_t ldl_merge(uint64_t original,uint64_t loaded,u_int bits) { if(bits) { original<<=64-bits; original>>=64-bits; loaded<<=bits; original|=loaded; } else original=loaded; return original; } static uint64_t ldr_merge(uint64_t original,uint64_t loaded,u_int bits) { if(bits^56) { original>>=64-(bits^56); original<<=64-(bits^56); loaded>>=bits^56; original|=loaded; } else original=loaded; return original; } #if NEW_DYNAREC == NEW_DYNAREC_X86 #include "assem_x86.c" #elif NEW_DYNAREC == NEW_DYNAREC_AMD64 #include "assem_x64.c" #elif NEW_DYNAREC == NEW_DYNAREC_ARM #include "assem_arm.c" #else #error Unsupported dynarec architecture #endif // Add virtual address mapping to linked list static void ll_add(struct ll_entry **head,int vaddr,void *addr) { struct ll_entry *new_entry; new_entry=malloc(sizeof(struct ll_entry)); assert(new_entry!=NULL); new_entry->vaddr=vaddr; new_entry->reg32=0; new_entry->addr=addr; new_entry->next=*head; *head=new_entry; } // Add virtual address mapping for 32-bit compiled block static void ll_add_32(struct ll_entry **head,int vaddr,u_int reg32,void *addr) { struct ll_entry *new_entry; new_entry=malloc(sizeof(struct ll_entry)); assert(new_entry!=NULL); new_entry->vaddr=vaddr; new_entry->reg32=reg32; new_entry->addr=addr; new_entry->next=*head; *head=new_entry; } // Check if an address is already compiled // but don't return addresses which are about to expire from the cache static void *check_addr(u_int vaddr) { u_int *ht_bin=hash_table[((vaddr>>16)^vaddr)&0xFFFF]; if(ht_bin[0]==vaddr) { if(((ht_bin[1]-MAX_OUTPUT_BLOCK_SIZE-(u_int)out)<<(32-TARGET_SIZE_2))>0x60000000+(MAX_OUTPUT_BLOCK_SIZE<<(32-TARGET_SIZE_2))) if(isclean(ht_bin[1])) return (void *)ht_bin[1]; } if(ht_bin[2]==vaddr) { if(((ht_bin[3]-MAX_OUTPUT_BLOCK_SIZE-(u_int)out)<<(32-TARGET_SIZE_2))>0x60000000+(MAX_OUTPUT_BLOCK_SIZE<<(32-TARGET_SIZE_2))) if(isclean(ht_bin[3])) return (void *)ht_bin[3]; } u_int page=(vaddr^0x80000000)>>12; if(page>262143&&tlb_LUT_r[vaddr>>12]) page=(tlb_LUT_r[vaddr>>12]^0x80000000)>>12; if(page>2048) page=2048+(page&2047); struct ll_entry *head; head=jump_in[page]; while(head!=NULL) { if(head->vaddr==vaddr&&head->reg32==0) { if((((u_int)head->addr-(u_int)out)<<(32-TARGET_SIZE_2))>0x60000000+(MAX_OUTPUT_BLOCK_SIZE<<(32-TARGET_SIZE_2))) { // Update existing entry with current address if(ht_bin[0]==vaddr) { ht_bin[1]=(int)head->addr; return head->addr; } if(ht_bin[2]==vaddr) { ht_bin[3]=(int)head->addr; return head->addr; } // Insert into hash table with low priority. // Don't evict existing entries, as they are probably // addresses that are being accessed frequently. if(ht_bin[0]==-1) { ht_bin[1]=(int)head->addr; ht_bin[0]=vaddr; }else if(ht_bin[2]==-1) { ht_bin[3]=(int)head->addr; ht_bin[2]=vaddr; } return head->addr; } } head=head->next; } return 0; } static void remove_hash(int vaddr) { //DebugMessage(M64MSG_VERBOSE, "remove hash: %x",vaddr); u_int *ht_bin=hash_table[(((vaddr)>>16)^vaddr)&0xFFFF]; if(ht_bin[2]==vaddr) { ht_bin[2]=ht_bin[3]=-1; } if(ht_bin[0]==vaddr) { ht_bin[0]=ht_bin[2]; ht_bin[1]=ht_bin[3]; ht_bin[2]=ht_bin[3]=-1; } } static void ll_remove_matching_addrs(struct ll_entry **head, u_int addr,int shift) { struct ll_entry *next; while(*head) { if((((u_int)((*head)->addr)-(u_int)base_addr)>>shift)==((addr-(u_int)base_addr)>>shift) || (((u_int)((*head)->addr)-(u_int)base_addr-MAX_OUTPUT_BLOCK_SIZE)>>shift)==((addr-(u_int)base_addr)>>shift)) { inv_debug("EXP: Remove pointer to %x (%x)\n",(int)(*head)->addr,(*head)->vaddr); remove_hash((*head)->vaddr); next=(*head)->next; free(*head); *head=next; } else { head=&((*head)->next); } } } // Remove all entries from linked list static void ll_clear(struct ll_entry **head) { struct ll_entry *cur; struct ll_entry *next; if((cur=*head)) { *head=0; while(cur) { next=cur->next; free(cur); cur=next; } } } // Dereference the pointers and remove if it matches static void ll_kill_pointers(struct ll_entry *head,u_int addr,int shift) { while(head) { u_int ptr=get_pointer(head->addr); inv_debug("EXP: Lookup pointer to %x at %x (%x)\n",(int)ptr,(int)head->addr,head->vaddr); #if 0 printf("EXP: Lookup pointer to %x at %x (%x)\n",(int)ptr,(int)head->addr,head->vaddr); #endif if((((ptr-(u_int)base_addr)>>shift)==((addr-(u_int)base_addr)>>shift)) || (((ptr-(u_int)base_addr-MAX_OUTPUT_BLOCK_SIZE)>>shift)==((addr-(u_int)base_addr)>>shift))) { inv_debug("EXP: Kill pointer at %x (%x)\n",(int)head->addr,head->vaddr); #if 0 printf("EXP: Kill pointer at %x (%x)\n",(int)head->addr,head->vaddr); #endif u_int host_addr=(int)kill_pointer(head->addr); #if NEW_DYNAREC == NEW_DYNAREC_ARM needs_clear_cache[(host_addr-(u_int)base_addr)>>17]|=1<<(((host_addr-(u_int)base_addr)>>12)&31); #else /* avoid unused variable warning */ (void)host_addr; #endif } head=head->next; } fflush(stdout); } // This is called when we write to a compiled block (see do_invstub) static void invalidate_page(u_int page) { struct ll_entry *head; struct ll_entry *next; head=jump_in[page]; jump_in[page]=0; while(head!=NULL) { inv_debug("INVALIDATE: %x\n",head->vaddr); remove_hash(head->vaddr); next=head->next; free(head); head=next; } head=jump_out[page]; jump_out[page]=0; while(head!=NULL) { inv_debug("INVALIDATE: kill pointer to %x (%x)\n",head->vaddr,(int)head->addr); u_int host_addr=(int)kill_pointer(head->addr); #if NEW_DYNAREC == NEW_DYNAREC_ARM needs_clear_cache[(host_addr-(u_int)base_addr)>>17]|=1<<(((host_addr-(u_int)base_addr)>>12)&31); #else /* avoid unused variable warning */ (void)host_addr; #endif next=head->next; free(head); head=next; } } void invalidate_block(u_int block) { u_int page,vpage; page=vpage=block^0x80000; if(page>262143&&tlb_LUT_r[block]) page=(tlb_LUT_r[block]^0x80000000)>>12; if(page>2048) page=2048+(page&2047); if(vpage>262143&&tlb_LUT_r[block]) vpage&=2047; // jump_dirty uses a hash of the virtual address instead if(vpage>2048) vpage=2048+(vpage&2047); inv_debug("INVALIDATE: %x (%d)\n",block<<12,page); //inv_debug("invalid_code[block]=%d\n",invalid_code[block]); u_int first,last; first=last=page; struct ll_entry *head; head=jump_dirty[vpage]; //DebugMessage(M64MSG_VERBOSE, "page=%d vpage=%d",page,vpage); while(head!=NULL) { u_int start,end; if(vpage>2047||(head->vaddr>>12)==block) { // Ignore vaddr hash collision get_bounds((intptr_t)head->addr,&start,&end); //DebugMessage(M64MSG_VERBOSE, "start: %x end: %x",start,end); if(page<2048&&start>=0x80000000&&end<0x80800000) { if(((start-(u_int)g_rdram)>>12)<=page&&((end-1-(u_int)g_rdram)>>12)>=page) { if((((start-(u_int)g_rdram)>>12)&2047)>12)&2047; if((((end-1-(u_int)g_rdram)>>12)&2047)>last) last=((end-1-(u_int)g_rdram)>>12)&2047; } } if(page<2048&&(signed int)start>=(signed int)0xC0000000&&(signed int)end>=(signed int)0xC0000000) { if(((start+memory_map[start>>12]-(u_int)g_rdram)>>12)<=page&&((end-1+memory_map[(end-1)>>12]-(u_int)g_rdram)>>12)>=page) { if((((start+memory_map[start>>12]-(u_int)g_rdram)>>12)&2047)>12]-(u_int)g_rdram)>>12)&2047; if((((end-1+memory_map[(end-1)>>12]-(u_int)g_rdram)>>12)&2047)>last) last=((end-1+memory_map[(end-1)>>12]-(u_int)g_rdram)>>12)&2047; } } } head=head->next; } //DebugMessage(M64MSG_VERBOSE, "first=%d last=%d",first,last); invalidate_page(page); assert(first+5>page); // NB: this assumes MAXBLOCK<=4096 (4 pages) assert(last>2; u_int real_block=tlb_LUT_w[block]>>12; invalid_code[real_block]=1; if(real_block>=0x80000&&real_block<0x80800) memory_map[real_block]=((uintptr_t)g_rdram-0x80000000)>>2; } else if(block>=0x80000&&block<0x80800) memory_map[block]=((uintptr_t)g_rdram-0x80000000)>>2; #ifdef USE_MINI_HT memset(mini_ht,-1,sizeof(mini_ht)); #endif } void invalidate_cached_code_new_dynarec(uint32_t address, size_t size) { size_t i; size_t begin; size_t end; if (size == 0) { begin = 0; end = 0xfffff; } else { begin = address >> 12; end = (address+size-1) >> 12; } for(i = begin; i <= end; ++i) invalidate_block(i); } #if NEW_DYNAREC == NEW_DYNAREC_ARM static void invalidate_addr(u_int addr) { invalidate_block(addr>>12); } #endif // This is called when loading a save state. // Anything could have changed, so invalidate everything. void invalidate_all_pages() { u_int page; for(page=0;page<4096;page++) invalidate_page(page); for(page=0;page<1048576;page++) if(!invalid_code[page]) { restore_candidate[(page&2047)>>3]|=1<<(page&7); restore_candidate[((page&2047)>>3)+256]|=1<<(page&7); } #if NEW_DYNAREC == NEW_DYNAREC_ARM __clear_cache((void *)base_addr,(void *)base_addr+(1<>2; if(!tlb_LUT_w[page]||!invalid_code[page]) { if(sizeof(*memory_map)==8) memory_map[page]|=0x4000000000000000; // Write protect else memory_map[page]|=0x40000000; // Write protect } } else memory_map[page]=-1L; if(page==0x80000) page=0xC0000; } tlb_hacks(); #endif } // Add an entry to jump_out after making a link void add_link(u_int vaddr,void *src) { u_int page=(vaddr^0x80000000)>>12; if(page>262143&&tlb_LUT_r[vaddr>>12]) page=(tlb_LUT_r[vaddr>>12]^0x80000000)>>12; if(page>4095) page=2048+(page&2047); inv_debug("add_link: %x -> %x (%d)\n",(int)src,vaddr,page); ll_add(jump_out+page,vaddr,src); //int ptr=get_pointer(src); //inv_debug("add_link: Pointer is to %x\n",(int)ptr); } // If a code block was found to be unmodified (bit was set in // restore_candidate) and it remains unmodified (bit is clear // in invalid_code) then move the entries for that 4K page from // the dirty list to the clean list. void clean_blocks(u_int page) { struct ll_entry *head; inv_debug("INV: clean_blocks page=%d\n",page); head=jump_dirty[page]; while(head!=NULL) { if(!invalid_code[head->vaddr>>12]) { // Don't restore blocks which are about to expire from the cache if((((u_int)head->addr-(u_int)out)<<(32-TARGET_SIZE_2))>0x60000000+(MAX_OUTPUT_BLOCK_SIZE<<(32-TARGET_SIZE_2))) { u_int start,end; if(verify_dirty(head->addr)) { //DebugMessage(M64MSG_VERBOSE, "Possibly Restore %x (%x)",head->vaddr, (int)head->addr); u_int i; u_int inv=0; get_bounds((intptr_t)head->addr,&start,&end); if(start-(u_int)g_rdram<0x800000) { for(i=(start-(u_int)g_rdram+0x80000000)>>12;i<=(end-1-(u_int)g_rdram+0x80000000)>>12;i++) { inv|=invalid_code[i]; } } if((signed int)head->vaddr>=(signed int)0xC0000000) { u_int addr = (head->vaddr+(memory_map[head->vaddr>>12]<<2)); //DebugMessage(M64MSG_VERBOSE, "addr=%x start=%x end=%x",addr,start,end); if(addr=end) inv=1; } else if((signed int)head->vaddr>=(signed int)0x80800000) { inv=1; } if(!inv) { void * clean_addr=(void *)get_clean_addr((intptr_t)head->addr); if((((u_int)clean_addr-(u_int)out)<<(32-TARGET_SIZE_2))>0x60000000+(MAX_OUTPUT_BLOCK_SIZE<<(32-TARGET_SIZE_2))) { u_int ppage=page; if(page<2048&&tlb_LUT_r[head->vaddr>>12]) ppage=(tlb_LUT_r[head->vaddr>>12]^0x80000000)>>12; inv_debug("INV: Restored %x (%x/%x)\n",head->vaddr, (int)head->addr, (int)clean_addr); //DebugMessage(M64MSG_VERBOSE, "page=%x, addr=%x",page,head->vaddr); //assert(head->vaddr>>12==(page|0x80000)); ll_add_32(jump_in+ppage,head->vaddr,head->reg32,clean_addr); u_int *ht_bin=hash_table[((head->vaddr>>16)^head->vaddr)&0xFFFF]; if(!head->reg32) { if(ht_bin[0]==head->vaddr) { ht_bin[1]=(int)clean_addr; // Replace existing entry } if(ht_bin[2]==head->vaddr) { ht_bin[3]=(int)clean_addr; // Replace existing entry } } } } } } } head=head->next; } } static void mov_alloc(struct regstat *current,int i) { // Note: Don't need to actually alloc the source registers if((~current->is32>>rs1[i])&1) { //alloc_reg64(current,i,rs1[i]); alloc_reg64(current,i,rt1[i]); current->is32&=~(1LL<is32|=(1LL<is32|=1LL<=0x38&&opcode2[i]<=0x3b) // DSLL/DSRL/DSRA { if(rt1[i]) { if(rs1[i]) alloc_reg64(current,i,rs1[i]); alloc_reg64(current,i,rt1[i]); current->is32&=~(1LL<is32&=~(1LL<is32&=~(1LL<is32|=1LL<is32|=1LL<is32|=1LL<is32&=~(1LL<=0x20&&opcode2[i]<=0x23) { // ADD/ADDU/SUB/SUBU if(rt1[i]) { if(rs1[i]&&rs2[i]) { alloc_reg(current,i,rs1[i]); alloc_reg(current,i,rs2[i]); } else { if(rs1[i]&&needed_again(rs1[i],i)) alloc_reg(current,i,rs1[i]); if(rs2[i]&&needed_again(rs2[i],i)) alloc_reg(current,i,rs2[i]); } alloc_reg(current,i,rt1[i]); } current->is32|=1LL<is32>>rs1[i])&(current->is32>>rs2[i])&1)) { alloc_reg64(current,i,rs1[i]); alloc_reg64(current,i,rs2[i]); alloc_reg(current,i,rt1[i]); } else { alloc_reg(current,i,rs1[i]); alloc_reg(current,i,rs2[i]); alloc_reg(current,i,rt1[i]); } } current->is32|=1LL<=0x24&&opcode2[i]<=0x27) { // AND/OR/XOR/NOR if(rt1[i]) { if(rs1[i]&&rs2[i]) { alloc_reg(current,i,rs1[i]); alloc_reg(current,i,rs2[i]); } else { if(rs1[i]&&needed_again(rs1[i],i)) alloc_reg(current,i,rs1[i]); if(rs2[i]&&needed_again(rs2[i],i)) alloc_reg(current,i,rs2[i]); } alloc_reg(current,i,rt1[i]); if(!((current->is32>>rs1[i])&(current->is32>>rs2[i])&1)) { if(!((current->uu>>rt1[i])&1)) { alloc_reg64(current,i,rt1[i]); } if(get_reg(current->regmap,rt1[i]|64)>=0) { if(rs1[i]&&rs2[i]) { alloc_reg64(current,i,rs1[i]); alloc_reg64(current,i,rs2[i]); } else { // Is is really worth it to keep 64-bit values in registers? #ifdef NATIVE_64BIT if(rs1[i]&&needed_again(rs1[i],i)) alloc_reg64(current,i,rs1[i]); if(rs2[i]&&needed_again(rs2[i],i)) alloc_reg64(current,i,rs2[i]); #endif } } current->is32&=~(1LL<is32|=1LL<=0x2c&&opcode2[i]<=0x2f) { // DADD/DADDU/DSUB/DSUBU if(rt1[i]) { if(rs1[i]&&rs2[i]) { if(!((current->uu>>rt1[i])&1)||get_reg(current->regmap,rt1[i]|64)>=0) { alloc_reg64(current,i,rs1[i]); alloc_reg64(current,i,rs2[i]); alloc_reg64(current,i,rt1[i]); } else { alloc_reg(current,i,rs1[i]); alloc_reg(current,i,rs2[i]); alloc_reg(current,i,rt1[i]); } } else { alloc_reg(current,i,rt1[i]); if(!((current->uu>>rt1[i])&1)||get_reg(current->regmap,rt1[i]|64)>=0) { // DADD used as move, or zeroing // If we have a 64-bit source, then make the target 64 bits too if(rs1[i]&&!((current->is32>>rs1[i])&1)) { if(get_reg(current->regmap,rs1[i])>=0) alloc_reg64(current,i,rs1[i]); alloc_reg64(current,i,rt1[i]); } else if(rs2[i]&&!((current->is32>>rs2[i])&1)) { if(get_reg(current->regmap,rs2[i])>=0) alloc_reg64(current,i,rs2[i]); alloc_reg64(current,i,rt1[i]); } if(opcode2[i]>=0x2e&&rs2[i]) { // DSUB used as negation - 64-bit result // If we have a 32-bit register, extend it to 64 bits if(get_reg(current->regmap,rs2[i])>=0) alloc_reg64(current,i,rs2[i]); alloc_reg64(current,i,rt1[i]); } } } if(rs1[i]&&rs2[i]) { current->is32&=~(1LL<is32&=~(1LL<is32>>rs1[i])&1) current->is32|=1LL<is32&=~(1LL<is32>>rs2[i])&1) current->is32|=1LL<is32|=1LL<is32&=~(1LL<uu>>rt1[i])&1)||get_reg(current->regmap,rt1[i]|64)>=0) { // TODO: Could preserve the 32-bit flag if the immediate is zero alloc_reg64(current,i,rt1[i]); alloc_reg64(current,i,rs1[i]); } clear_const(current,rs1[i]); clear_const(current,rt1[i]); } else if(opcode[i]==0x0a||opcode[i]==0x0b) { // SLTI/SLTIU if((~current->is32>>rs1[i])&1) alloc_reg64(current,i,rs1[i]); current->is32|=1LL<=0x0c&&opcode[i]<=0x0e) { // ANDI/ORI/XORI if(((~current->is32>>rs1[i])&1)&&opcode[i]>0x0c) { if(rs1[i]!=rt1[i]) { if(needed_again(rs1[i],i)) alloc_reg64(current,i,rs1[i]); alloc_reg64(current,i,rt1[i]); current->is32&=~(1LL<is32|=1LL<is32|=1LL<is32|=1LL<u&=~1LL; // Allow allocating r0 if it's the source register if(needed_again(rs1[i],i)) alloc_reg(current,i,rs1[i]); if(rt1[i]&&!((current->u>>rt1[i])&1)) { alloc_reg(current,i,rt1[i]); assert(get_reg(current->regmap,rt1[i])>=0); if(opcode[i]==0x27||opcode[i]==0x37) // LWU/LD { current->is32&=~(1LL<is32&=~(1LL<is32|=1LL<u&=~1LL; // Allow allocating r0 if necessary if(needed_again(rs1[i],i)) alloc_reg(current,i,rs1[i]); alloc_reg(current,i,rs2[i]); if(opcode[i]==0x2c||opcode[i]==0x2d||opcode[i]==0x3f) { // 64-bit SDL/SDR/SD alloc_reg64(current,i,rs2[i]); if(rs2[i]) alloc_reg(current,i,FTEMP); } // If using TLB, need a register for pointer to the mapping table if(using_tlb) alloc_reg(current,i,TLREG); #if defined(HOST_IMM8) || defined(NEED_INVC_PTR) // On CPUs without 32-bit immediates we need a pointer to invalid_code else alloc_reg(current,i,INVCP); #endif if(opcode[i]==0x2c||opcode[i]==0x2d) { // 64-bit SDL/SDR alloc_reg(current,i,FTEMP); } // We need a temporary register for address generation alloc_reg_temp(current,i,-1); minimum_free_regs[i]=1; } static void c1ls_alloc(struct regstat *current,int i) { //clear_const(current,rs1[i]); // FIXME clear_const(current,rt1[i]); if(needed_again(rs1[i],i)) alloc_reg(current,i,rs1[i]); alloc_reg(current,i,CSREG); // Status alloc_reg(current,i,FTEMP); if(opcode[i]==0x35||opcode[i]==0x3d) { // 64-bit LDC1/SDC1 alloc_reg64(current,i,FTEMP); } // If using TLB, need a register for pointer to the mapping table if(using_tlb) alloc_reg(current,i,TLREG); #if defined(HOST_IMM8) || defined(NEED_INVC_PTR) // On CPUs without 32-bit immediates we need a pointer to invalid_code else if((opcode[i]&0x3b)==0x39) // SWC1/SDC1 alloc_reg(current,i,INVCP); #endif // We need a temporary register for address generation alloc_reg_temp(current,i,-1); minimum_free_regs[i]=1; } #ifndef multdiv_alloc void multdiv_alloc(struct regstat *current,int i) { // case 0x18: MULT // case 0x19: MULTU // case 0x1A: DIV // case 0x1B: DIVU // case 0x1C: DMULT // case 0x1D: DMULTU // case 0x1E: DDIV // case 0x1F: DDIVU clear_const(current,rs1[i]); clear_const(current,rs2[i]); if(rs1[i]&&rs2[i]) { if((opcode2[i]&4)==0) // 32-bit { current->u&=~(1LL<u&=~(1LL<is32|=1LL<is32|=1LL<u&=~(1LL<u&=~(1LL<uu&=~(1LL<uu&=~(1LL<10) alloc_reg64(current,i,LOREG); alloc_reg64(current,i,rs1[i]); alloc_reg64(current,i,rs2[i]); alloc_all(current,i); current->is32&=~(1LL<is32&=~(1LL<is32|=1LL<is32|=1LL<is32|=1LL<u&=~1LL; alloc_reg(current,i,0); } } else { // TLBR/TLBWI/TLBWR/TLBP/ERET assert(opcode2[i]==0x10); alloc_all(current,i); } minimum_free_regs[i]=HOST_REGS; } static void cop1_alloc(struct regstat *current,int i) { alloc_reg(current,i,CSREG); // Load status if(opcode2[i]<3) // MFC1/DMFC1/CFC1 { assert(rt1[i]); clear_const(current,rt1[i]); if(opcode2[i]==1) { alloc_reg64(current,i,rt1[i]); // DMFC1 current->is32&=~(1LL<is32|=1LL<3) // MTC1/DMTC1/CTC1 { if(rs1[i]){ clear_const(current,rs1[i]); if(opcode2[i]==5) alloc_reg64(current,i,rs1[i]); // DMTC1 else alloc_reg(current,i,rs1[i]); // MTC1/CTC1 alloc_reg_temp(current,i,-1); } else { current->u&=~1LL; alloc_reg(current,i,0); alloc_reg_temp(current,i,-1); } } minimum_free_regs[i]=1; } static void fconv_alloc(struct regstat *current,int i) { alloc_reg(current,i,CSREG); // Load status alloc_reg_temp(current,i,-1); minimum_free_regs[i]=1; } static void float_alloc(struct regstat *current,int i) { alloc_reg(current,i,CSREG); // Load status alloc_reg_temp(current,i,-1); minimum_free_regs[i]=1; } static void fcomp_alloc(struct regstat *current,int i) { alloc_reg(current,i,CSREG); // Load status alloc_reg(current,i,FSREG); // Load flags dirty_reg(current,FSREG); // Flag will be modified alloc_reg_temp(current,i,-1); minimum_free_regs[i]=1; } static void syscall_alloc(struct regstat *current,int i) { alloc_cc(current,i); dirty_reg(current,CCREG); alloc_all(current,i); minimum_free_regs[i]=HOST_REGS; current->isconst=0; } static void delayslot_alloc(struct regstat *current,int i) { switch(itype[i]) { case UJUMP: case CJUMP: case SJUMP: case RJUMP: case FJUMP: case SYSCALL: case SPAN: assem_debug("jump in the delay slot. this shouldn't happen.");//exit(1); DebugMessage(M64MSG_VERBOSE, "Disabled speculative precompilation"); stop_after_jal=1; break; case IMM16: imm16_alloc(current,i); break; case LOAD: case LOADLR: load_alloc(current,i); break; case STORE: case STORELR: store_alloc(current,i); break; case ALU: alu_alloc(current,i); break; case SHIFT: shift_alloc(current,i); break; case MULTDIV: multdiv_alloc(current,i); break; case SHIFTIMM: shiftimm_alloc(current,i); break; case MOV: mov_alloc(current,i); break; case COP0: cop0_alloc(current,i); break; case COP1: cop1_alloc(current,i); break; case C1LS: c1ls_alloc(current,i); break; case FCONV: fconv_alloc(current,i); break; case FLOAT: float_alloc(current,i); break; case FCOMP: fcomp_alloc(current,i); break; } } // Special case where a branch and delay slot span two pages in virtual memory static void pagespan_alloc(struct regstat *current,int i) { current->isconst=0; current->wasconst=0; regs[i].wasconst=0; minimum_free_regs[i]=HOST_REGS; alloc_all(current,i); alloc_cc(current,i); dirty_reg(current,CCREG); if(opcode[i]==3) // JAL { alloc_reg(current,i,31); dirty_reg(current,31); } if(opcode[i]==0&&(opcode2[i]&0x3E)==8) // JR/JALR { alloc_reg(current,i,rs1[i]); if (rt1[i]!=0) { alloc_reg(current,i,rt1[i]); dirty_reg(current,rt1[i]); } } if((opcode[i]&0x2E)==4) // BEQ/BNE/BEQL/BNEL { if(rs1[i]) alloc_reg(current,i,rs1[i]); if(rs2[i]) alloc_reg(current,i,rs2[i]); if(!((current->is32>>rs1[i])&(current->is32>>rs2[i])&1)) { if(rs1[i]) alloc_reg64(current,i,rs1[i]); if(rs2[i]) alloc_reg64(current,i,rs2[i]); } } else if((opcode[i]&0x2E)==6) // BLEZ/BGTZ/BLEZL/BGTZL { if(rs1[i]) alloc_reg(current,i,rs1[i]); if(!((current->is32>>rs1[i])&1)) { if(rs1[i]) alloc_reg64(current,i,rs1[i]); } } else if(opcode[i]==0x11) // BC1 { alloc_reg(current,i,FSREG); alloc_reg(current,i,CSREG); } //else ... } static void add_stub(int type,intptr_t addr,int retaddr,int a,intptr_t b,intptr_t c,int d,int e) { stubs[stubcount][0]=type; stubs[stubcount][1]=addr; stubs[stubcount][2]=retaddr; stubs[stubcount][3]=a; stubs[stubcount][4]=b; stubs[stubcount][5]=c; stubs[stubcount][6]=d; stubs[stubcount][7]=e; stubcount++; } // Write out a single register static void wb_register(signed char r,signed char regmap[],uint64_t dirty,uint64_t is32) { int hr; for(hr=0;hr>hr)&1) { if(regmap[hr]<64) { emit_storereg(r,hr); if((is32>>regmap[hr])&1) { emit_sarimm(hr,31,hr); emit_storereg(r|64,hr); } }else{ emit_storereg(r|64,hr); } } } } } } #if 0 int mchecksum() { //if(!tracedebug) return 0; int i; int sum=0; for(i=0;i<2097152;i++) { unsigned int temp=sum; sum<<=1; sum|=(~temp)>>31; sum^=((u_int *)g_rdram)[i]; } return sum; } static int rchecksum() { int i; int sum=0; for(i=0;i<64;i++) sum^=((u_int *)reg)[i]; return sum; } static void rlist() { int i; DebugMessage(M64MSG_VERBOSE, "TRACE: "); for(i=0;i<32;i++) DebugMessage(M64MSG_VERBOSE, "r%d:%8x%8x ",i,((int *)(reg+i))[1],((int *)(reg+i))[0]); DebugMessage(M64MSG_VERBOSE, "TRACE: "); for(i=0;i<32;i++) DebugMessage(M64MSG_VERBOSE, "f%d:%8x%8x ",i,((int*)reg_cop1_simple[i])[1],*((int*)reg_cop1_simple[i])); } static void enabletrace() { tracedebug=1; } void memdebug(int i) { //DebugMessage(M64MSG_VERBOSE, "TRACE: count=%d next=%d (checksum %x) lo=%8x%8x",g_cp0_regs[CP0_COUNT_REG],next_interupt,mchecksum(),(int)(reg[LOREG]>>32),(int)reg[LOREG]); //DebugMessage(M64MSG_VERBOSE, "TRACE: count=%d next=%d (rchecksum %x)",g_cp0_regs[CP0_COUNT_REG],next_interupt,rchecksum()); //rlist(); //if(tracedebug) { //if(g_cp0_regs[CP0_COUNT_REG]>=-2084597794) { if((signed int)g_cp0_regs[CP0_COUNT_REG]>=-2084597794&&(signed int)g_cp0_regs[CP0_COUNT_REG]<0) { //if(0) { DebugMessage(M64MSG_VERBOSE, "TRACE: count=%d next=%d (checksum %x)",g_cp0_regs[CP0_COUNT_REG],next_interupt,mchecksum()); //DebugMessage(M64MSG_VERBOSE, "TRACE: count=%d next=%d (checksum %x) Status=%x",g_cp0_regs[CP0_COUNT_REG],next_interupt,mchecksum(),g_cp0_regs[CP0_STATUS_REG]); //DebugMessage(M64MSG_VERBOSE, "TRACE: count=%d next=%d (checksum %x) hi=%8x%8x",g_cp0_regs[CP0_COUNT_REG],next_interupt,mchecksum(),(int)(reg[HIREG]>>32),(int)reg[HIREG]); rlist(); #if NEW_DYNAREC == NEW_DYNAREC_X86 DebugMessage(M64MSG_VERBOSE, "TRACE: %x",(&i)[-1]); #endif #if NEW_DYNAREC == NEW_DYNAREC_ARM int j; DebugMessage(M64MSG_VERBOSE, "TRACE: %x ",(&j)[10]); DebugMessage(M64MSG_VERBOSE, "TRACE: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",(&j)[1],(&j)[2],(&j)[3],(&j)[4],(&j)[5],(&j)[6],(&j)[7],(&j)[8],(&j)[9],(&j)[10],(&j)[11],(&j)[12],(&j)[13],(&j)[14],(&j)[15],(&j)[16],(&j)[17],(&j)[18],(&j)[19],(&j)[20]); #endif //fflush(stdout); } //DebugMessage(M64MSG_VERBOSE, "TRACE: %x",(&i)[-1]); } #endif /* Debug: static void tlb_debug(u_int cause, u_int addr, u_int iaddr) { DebugMessage(M64MSG_VERBOSE, "TLB Exception: instruction=%x addr=%x cause=%x",iaddr, addr, cause); } end debug */ static void alu_assemble(int i,struct regstat *i_regs) { if(opcode2[i]>=0x20&&opcode2[i]<=0x23) { // ADD/ADDU/SUB/SUBU if(rt1[i]) { signed char s1,s2,t; t=get_reg(i_regs->regmap,rt1[i]); if(t>=0) { s1=get_reg(i_regs->regmap,rs1[i]); s2=get_reg(i_regs->regmap,rs2[i]); if(rs1[i]&&rs2[i]) { assert(s1>=0); assert(s2>=0); if(opcode2[i]&2) emit_sub(s1,s2,t); else emit_add(s1,s2,t); } else if(rs1[i]) { if(s1>=0) emit_mov(s1,t); else emit_loadreg(rs1[i],t); } else if(rs2[i]) { if(s2>=0) { if(opcode2[i]&2) emit_neg(s2,t); else emit_mov(s2,t); } else { emit_loadreg(rs2[i],t); if(opcode2[i]&2) emit_neg(t,t); } } else emit_zeroreg(t); } } } if(opcode2[i]>=0x2c&&opcode2[i]<=0x2f) { // DADD/DADDU/DSUB/DSUBU if(rt1[i]) { signed char s1l,s2l,s1h,s2h,tl,th; tl=get_reg(i_regs->regmap,rt1[i]); th=get_reg(i_regs->regmap,rt1[i]|64); if(tl>=0) { s1l=get_reg(i_regs->regmap,rs1[i]); s2l=get_reg(i_regs->regmap,rs2[i]); s1h=get_reg(i_regs->regmap,rs1[i]|64); s2h=get_reg(i_regs->regmap,rs2[i]|64); if(rs1[i]&&rs2[i]) { assert(s1l>=0); assert(s2l>=0); if(opcode2[i]&2) emit_subs(s1l,s2l,tl); else emit_adds(s1l,s2l,tl); if(th>=0) { if(opcode2[i]&2) emit_sbc(s1h,s2h,th); else emit_adc(s1h,s2h,th); } } else if(rs1[i]) { if(s1l>=0) emit_mov(s1l,tl); else emit_loadreg(rs1[i],tl); if(th>=0) { if(s1h>=0) emit_mov(s1h,th); else emit_loadreg(rs1[i]|64,th); } } else if(rs2[i]) { if(s2l>=0) { if(opcode2[i]&2) emit_negs(s2l,tl); else emit_mov(s2l,tl); } else { emit_loadreg(rs2[i],tl); if(opcode2[i]&2) emit_negs(tl,tl); } if(th>=0) { #ifdef INVERTED_CARRY if(s2h>=0) emit_mov(s2h,th); else emit_loadreg(rs2[i]|64,th); if(opcode2[i]&2) { emit_adcimm(-1,th); // x86 has inverted carry flag emit_not(th,th); } #else if(opcode2[i]&2) { if(s2h>=0) emit_rscimm(s2h,0,th); else { emit_loadreg(rs2[i]|64,th); emit_rscimm(th,0,th); } }else{ if(s2h>=0) emit_mov(s2h,th); else emit_loadreg(rs2[i]|64,th); } #endif } } else { emit_zeroreg(tl); if(th>=0) emit_zeroreg(th); } } } } if(opcode2[i]==0x2a||opcode2[i]==0x2b) { // SLT/SLTU if(rt1[i]) { signed char s1l,s1h,s2l,s2h,t; if(!((i_regs->was32>>rs1[i])&(i_regs->was32>>rs2[i])&1)) { t=get_reg(i_regs->regmap,rt1[i]); //assert(t>=0); if(t>=0) { s1l=get_reg(i_regs->regmap,rs1[i]); s1h=get_reg(i_regs->regmap,rs1[i]|64); s2l=get_reg(i_regs->regmap,rs2[i]); s2h=get_reg(i_regs->regmap,rs2[i]|64); if(rs2[i]==0) // rx=0); if(opcode2[i]==0x2a) // SLT emit_shrimm(s1h,31,t); else // SLTU (unsigned can not be less than zero) emit_zeroreg(t); } else if(rs1[i]==0) // r0=0); if(opcode2[i]==0x2a) // SLT emit_set_gz64_32(s2h,s2l,t); else // SLTU (set if not zero) emit_set_nz64_32(s2h,s2l,t); } else { assert(s1l>=0);assert(s1h>=0); assert(s2l>=0);assert(s2h>=0); if(opcode2[i]==0x2a) // SLT emit_set_if_less64_32(s1h,s1l,s2h,s2l,t); else // SLTU emit_set_if_carry64_32(s1h,s1l,s2h,s2l,t); } } } else { t=get_reg(i_regs->regmap,rt1[i]); //assert(t>=0); if(t>=0) { s1l=get_reg(i_regs->regmap,rs1[i]); s2l=get_reg(i_regs->regmap,rs2[i]); if(rs2[i]==0) // rx=0); if(opcode2[i]==0x2a) // SLT emit_shrimm(s1l,31,t); else // SLTU (unsigned can not be less than zero) emit_zeroreg(t); } else if(rs1[i]==0) // r0=0); if(opcode2[i]==0x2a) // SLT emit_set_gz32(s2l,t); else // SLTU (set if not zero) emit_set_nz32(s2l,t); } else{ assert(s1l>=0);assert(s2l>=0); if(opcode2[i]==0x2a) // SLT emit_set_if_less32(s1l,s2l,t); else // SLTU emit_set_if_carry32(s1l,s2l,t); } } } } } if(opcode2[i]>=0x24&&opcode2[i]<=0x27) { // AND/OR/XOR/NOR if(rt1[i]) { signed char s1l,s1h,s2l,s2h,th,tl; tl=get_reg(i_regs->regmap,rt1[i]); th=get_reg(i_regs->regmap,rt1[i]|64); if(!((i_regs->was32>>rs1[i])&(i_regs->was32>>rs2[i])&1)&&th>=0) { assert(tl>=0); if(tl>=0) { s1l=get_reg(i_regs->regmap,rs1[i]); s1h=get_reg(i_regs->regmap,rs1[i]|64); s2l=get_reg(i_regs->regmap,rs2[i]); s2h=get_reg(i_regs->regmap,rs2[i]|64); if(rs1[i]&&rs2[i]) { assert(s1l>=0);assert(s1h>=0); assert(s2l>=0);assert(s2h>=0); if(opcode2[i]==0x24) { // AND emit_and(s1l,s2l,tl); emit_and(s1h,s2h,th); } else if(opcode2[i]==0x25) { // OR emit_or(s1l,s2l,tl); emit_or(s1h,s2h,th); } else if(opcode2[i]==0x26) { // XOR emit_xor(s1l,s2l,tl); emit_xor(s1h,s2h,th); } else if(opcode2[i]==0x27) { // NOR emit_or(s1l,s2l,tl); emit_or(s1h,s2h,th); emit_not(tl,tl); emit_not(th,th); } } else { if(opcode2[i]==0x24) { // AND emit_zeroreg(tl); emit_zeroreg(th); } else if(opcode2[i]==0x25||opcode2[i]==0x26) { // OR/XOR if(rs1[i]){ if(s1l>=0) emit_mov(s1l,tl); else emit_loadreg(rs1[i],tl); if(s1h>=0) emit_mov(s1h,th); else emit_loadreg(rs1[i]|64,th); } else if(rs2[i]){ if(s2l>=0) emit_mov(s2l,tl); else emit_loadreg(rs2[i],tl); if(s2h>=0) emit_mov(s2h,th); else emit_loadreg(rs2[i]|64,th); } else{ emit_zeroreg(tl); emit_zeroreg(th); } } else if(opcode2[i]==0x27) { // NOR if(rs1[i]){ if(s1l>=0) emit_not(s1l,tl); else{ emit_loadreg(rs1[i],tl); emit_not(tl,tl); } if(s1h>=0) emit_not(s1h,th); else{ emit_loadreg(rs1[i]|64,th); emit_not(th,th); } } else if(rs2[i]){ if(s2l>=0) emit_not(s2l,tl); else{ emit_loadreg(rs2[i],tl); emit_not(tl,tl); } if(s2h>=0) emit_not(s2h,th); else{ emit_loadreg(rs2[i]|64,th); emit_not(th,th); } } else { emit_movimm(-1,tl); emit_movimm(-1,th); } } } } } else { // 32 bit if(tl>=0) { s1l=get_reg(i_regs->regmap,rs1[i]); s2l=get_reg(i_regs->regmap,rs2[i]); if(rs1[i]&&rs2[i]) { assert(s1l>=0); assert(s2l>=0); if(opcode2[i]==0x24) { // AND emit_and(s1l,s2l,tl); } else if(opcode2[i]==0x25) { // OR emit_or(s1l,s2l,tl); } else if(opcode2[i]==0x26) { // XOR emit_xor(s1l,s2l,tl); } else if(opcode2[i]==0x27) { // NOR emit_or(s1l,s2l,tl); emit_not(tl,tl); } } else { if(opcode2[i]==0x24) { // AND emit_zeroreg(tl); } else if(opcode2[i]==0x25||opcode2[i]==0x26) { // OR/XOR if(rs1[i]){ if(s1l>=0) emit_mov(s1l,tl); else emit_loadreg(rs1[i],tl); // CHECK: regmap_entry? } else if(rs2[i]){ if(s2l>=0) emit_mov(s2l,tl); else emit_loadreg(rs2[i],tl); // CHECK: regmap_entry? } else emit_zeroreg(tl); } else if(opcode2[i]==0x27) { // NOR if(rs1[i]){ if(s1l>=0) emit_not(s1l,tl); else { emit_loadreg(rs1[i],tl); emit_not(tl,tl); } } else if(rs2[i]){ if(s2l>=0) emit_not(s2l,tl); else { emit_loadreg(rs2[i],tl); emit_not(tl,tl); } } else emit_movimm(-1,tl); } } } } } } } static void imm16_assemble(int i,struct regstat *i_regs) { if (opcode[i]==0x0f) { // LUI if(rt1[i]) { signed char t; t=get_reg(i_regs->regmap,rt1[i]); //assert(t>=0); if(t>=0) { if(!((i_regs->isconst>>t)&1)) emit_movimm(imm[i]<<16,t); } } } if(opcode[i]==0x08||opcode[i]==0x09) { // ADDI/ADDIU if(rt1[i]) { signed char s,t; t=get_reg(i_regs->regmap,rt1[i]); s=get_reg(i_regs->regmap,rs1[i]); if(rs1[i]) { //assert(t>=0); //assert(s>=0); if(t>=0) { if(!((i_regs->isconst>>t)&1)) { if(s<0) { if(i_regs->regmap_entry[t]!=rs1[i]) emit_loadreg(rs1[i],t); emit_addimm(t,imm[i],t); }else{ if(!((i_regs->wasconst>>s)&1)) emit_addimm(s,imm[i],t); else emit_movimm(constmap[i][s]+imm[i],t); } } } } else { if(t>=0) { if(!((i_regs->isconst>>t)&1)) emit_movimm(imm[i],t); } } } } if(opcode[i]==0x18||opcode[i]==0x19) { // DADDI/DADDIU if(rt1[i]) { signed char sh,sl,th,tl; th=get_reg(i_regs->regmap,rt1[i]|64); tl=get_reg(i_regs->regmap,rt1[i]); sh=get_reg(i_regs->regmap,rs1[i]|64); sl=get_reg(i_regs->regmap,rs1[i]); if(tl>=0) { if(rs1[i]) { assert(sh>=0); assert(sl>=0); if(th>=0) { emit_addimm64_32(sh,sl,imm[i],th,tl); } else { emit_addimm(sl,imm[i],tl); } } else { emit_movimm(imm[i],tl); if(th>=0) emit_movimm(((signed int)imm[i])>>31,th); } } } } else if(opcode[i]==0x0a||opcode[i]==0x0b) { // SLTI/SLTIU if(rt1[i]) { //assert(rs1[i]!=0); // r0 might be valid, but it's probably a bug signed char sh,sl,t; t=get_reg(i_regs->regmap,rt1[i]); sh=get_reg(i_regs->regmap,rs1[i]|64); sl=get_reg(i_regs->regmap,rs1[i]); //assert(t>=0); if(t>=0) { if(rs1[i]>0) { if(sh<0) assert((i_regs->was32>>rs1[i])&1); if(sh<0||((i_regs->was32>>rs1[i])&1)) { if(opcode[i]==0x0a) { // SLTI if(sl<0) { if(i_regs->regmap_entry[t]!=rs1[i]) emit_loadreg(rs1[i],t); emit_slti32(t,imm[i],t); }else{ emit_slti32(sl,imm[i],t); } } else { // SLTIU if(sl<0) { if(i_regs->regmap_entry[t]!=rs1[i]) emit_loadreg(rs1[i],t); emit_sltiu32(t,imm[i],t); }else{ emit_sltiu32(sl,imm[i],t); } } }else{ // 64-bit assert(sl>=0); if(opcode[i]==0x0a) // SLTI emit_slti64_32(sh,sl,imm[i],t); else // SLTIU emit_sltiu64_32(sh,sl,imm[i],t); } }else{ // SLTI(U) with r0 is just stupid, // nonetheless examples can be found if(opcode[i]==0x0a) // SLTI if(0=0x0c&&opcode[i]<=0x0e) { // ANDI/ORI/XORI if(rt1[i]) { signed char sh,sl,th,tl; th=get_reg(i_regs->regmap,rt1[i]|64); tl=get_reg(i_regs->regmap,rt1[i]); sh=get_reg(i_regs->regmap,rs1[i]|64); sl=get_reg(i_regs->regmap,rs1[i]); if(tl>=0 && !((i_regs->isconst>>tl)&1)) { if(opcode[i]==0x0c) //ANDI { if(rs1[i]) { if(sl<0) { if(i_regs->regmap_entry[tl]!=rs1[i]) emit_loadreg(rs1[i],tl); emit_andimm(tl,imm[i],tl); }else{ if(!((i_regs->wasconst>>sl)&1)) emit_andimm(sl,imm[i],tl); else emit_movimm(constmap[i][sl]&imm[i],tl); } } else emit_zeroreg(tl); if(th>=0) emit_zeroreg(th); } else { if(rs1[i]) { if(sl<0) { if(i_regs->regmap_entry[tl]!=rs1[i]) emit_loadreg(rs1[i],tl); } if(th>=0) { if(sh<0) { emit_loadreg(rs1[i]|64,th); }else{ emit_mov(sh,th); } } if(opcode[i]==0x0d) { //ORI if(sl<0) { emit_orimm(tl,imm[i],tl); }else{ if(!((i_regs->wasconst>>sl)&1)) emit_orimm(sl,imm[i],tl); else emit_movimm(constmap[i][sl]|imm[i],tl); } } if(opcode[i]==0x0e) { //XORI if(sl<0) { emit_xorimm(tl,imm[i],tl); }else{ if(!((i_regs->wasconst>>sl)&1)) emit_xorimm(sl,imm[i],tl); else emit_movimm(constmap[i][sl]^imm[i],tl); } } } else { emit_movimm(imm[i],tl); if(th>=0) emit_zeroreg(th); } } } } } } static void shiftimm_assemble(int i,struct regstat *i_regs) { if(opcode2[i]<=0x3) // SLL/SRL/SRA { if(rt1[i]) { signed char s,t; t=get_reg(i_regs->regmap,rt1[i]); s=get_reg(i_regs->regmap,rs1[i]); //assert(t>=0); if(t>=0){ if(rs1[i]==0) { emit_zeroreg(t); } else { if(s<0&&i_regs->regmap_entry[t]!=rs1[i]) emit_loadreg(rs1[i],t); if(imm[i]) { if(opcode2[i]==0) // SLL { emit_shlimm(s<0?t:s,imm[i],t); } if(opcode2[i]==2) // SRL { emit_shrimm(s<0?t:s,imm[i],t); } if(opcode2[i]==3) // SRA { emit_sarimm(s<0?t:s,imm[i],t); } }else{ // Shift by zero if(s>=0 && s!=t) emit_mov(s,t); } } } //emit_storereg(rt1[i],t); //DEBUG } } if(opcode2[i]>=0x38&&opcode2[i]<=0x3b) // DSLL/DSRL/DSRA { if(rt1[i]) { signed char sh,sl,th,tl; th=get_reg(i_regs->regmap,rt1[i]|64); tl=get_reg(i_regs->regmap,rt1[i]); sh=get_reg(i_regs->regmap,rs1[i]|64); sl=get_reg(i_regs->regmap,rs1[i]); if(tl>=0) { if(rs1[i]==0) { emit_zeroreg(tl); if(th>=0) emit_zeroreg(th); } else { assert(sl>=0); assert(sh>=0); if(imm[i]) { if(opcode2[i]==0x38) // DSLL { if(th>=0) emit_shldimm(sh,sl,imm[i],th); emit_shlimm(sl,imm[i],tl); } if(opcode2[i]==0x3a) // DSRL { emit_shrdimm(sl,sh,imm[i],tl); if(th>=0) emit_shrimm(sh,imm[i],th); } if(opcode2[i]==0x3b) // DSRA { emit_shrdimm(sl,sh,imm[i],tl); if(th>=0) emit_sarimm(sh,imm[i],th); } }else{ // Shift by zero if(sl!=tl) emit_mov(sl,tl); if(th>=0&&sh!=th) emit_mov(sh,th); } } } } } if(opcode2[i]==0x3c) // DSLL32 { if(rt1[i]) { signed char sl,tl,th; tl=get_reg(i_regs->regmap,rt1[i]); th=get_reg(i_regs->regmap,rt1[i]|64); sl=get_reg(i_regs->regmap,rs1[i]); if(th>=0||tl>=0){ assert(tl>=0); assert(th>=0); assert(sl>=0); emit_mov(sl,th); emit_zeroreg(tl); if(imm[i]>32) { emit_shlimm(th,imm[i]&31,th); } } } } if(opcode2[i]==0x3e) // DSRL32 { if(rt1[i]) { signed char sh,tl,th; tl=get_reg(i_regs->regmap,rt1[i]); th=get_reg(i_regs->regmap,rt1[i]|64); sh=get_reg(i_regs->regmap,rs1[i]|64); if(tl>=0){ assert(sh>=0); emit_mov(sh,tl); if(th>=0) emit_zeroreg(th); if(imm[i]>32) { emit_shrimm(tl,imm[i]&31,tl); } } } } if(opcode2[i]==0x3f) // DSRA32 { if(rt1[i]) { signed char sh,tl; tl=get_reg(i_regs->regmap,rt1[i]); sh=get_reg(i_regs->regmap,rs1[i]|64); if(tl>=0){ assert(sh>=0); emit_mov(sh,tl); if(imm[i]>32) { emit_sarimm(tl,imm[i]&31,tl); } } } } } #ifndef shift_assemble void shift_assemble(int i,struct regstat *i_regs) { DebugMessage(M64MSG_ERROR, "Need shift_assemble for this architecture."); exit(1); } #endif static void load_assemble(int i,struct regstat *i_regs) { int s,th,tl,addr,map=-1,cache=-1; int offset; intptr_t jaddr=0; int memtarget,c=0; u_int hr,reglist=0; th=get_reg(i_regs->regmap,rt1[i]|64); tl=get_reg(i_regs->regmap,rt1[i]); s=get_reg(i_regs->regmap,rs1[i]); offset=imm[i]; for(hr=0;hrregmap[hr]>=0) reglist|=1<regmap[HOST_CCREG]==CCREG) reglist&=~(1<=0) { c=(i_regs->wasconst>>s)&1; memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80800000; if(using_tlb&&((signed int)(constmap[i][s]+offset))>=(signed int)0xC0000000) memtarget=1; } if(tl<0) tl=get_reg(i_regs->regmap,-1); if(offset||s<0||c) addr=tl; else addr=s; //DebugMessage(M64MSG_VERBOSE, "load_assemble: c=%d",c); //if(c) DebugMessage(M64MSG_VERBOSE, "load_assemble: const=%x",(int)constmap[i][s]+offset); assert(tl>=0); // Even if the load is a NOP, we must check for pagefaults and I/O reglist&=~(1<=0) reglist&=~(1<regmap,rt1[i])); // ignore loads to r0 and unneeded reg if(!using_tlb) { if(!c) { #ifdef RAM_OFFSET map=get_reg(i_regs->regmap,ROREG); #ifdef HOST_TEMPREG if(map<0) if(!dummy) emit_loadreg(ROREG,map=HOST_TEMPREG); #else if(!dummy) { if(map<0) { map=get_reg(i_regs->regmap,-1); if(map>=0) emit_loadreg(ROREG,map); } } #endif #endif //#define R29_HACK 1 #ifdef R29_HACK // Strmnnrmn's speed hack if(rs1[i]!=29||start<0x80001000||start>=0x80800000) #endif { emit_cmpimm(addr,0x800000); jaddr=(intptr_t)out; #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK // Hint to branch predictor that the branch is unlikely to be taken if(rs1[i]>=28) emit_jno_unlikely(0); else #endif emit_jno(0); } } }else{ // using tlb int x=0; if (opcode[i]==0x20||opcode[i]==0x24) x=3; // LB/LBU if (opcode[i]==0x21||opcode[i]==0x25) x=2; // LH/LHU map=get_reg(i_regs->regmap,TLREG); cache=get_reg(i_regs->regmap,MMREG); assert(map>=0); reglist&=~(1<regmap,rt1[i],ccadj[i],reglist); } if (opcode[i]==0x21) { // LH if(!c||memtarget) { if(!dummy) { #ifdef HOST_IMM_ADDR32 if(c) emit_movswl_tlb((constmap[i][s]+offset)^2,map,tl); else #endif { int x=0; if(!c) emit_xorimm(addr,2,tl); else x=((constmap[i][s]+offset)^2)-(constmap[i][s]+offset); //#ifdef //emit_movswl_indexed_tlb(x,tl,map,tl); //else if(map>=0) { gen_tlb_addr_r(tl,map); emit_movswl_indexed(x,tl,tl); }else{ #ifdef RAM_OFFSET if(!c) gen_tlb_addr_r(tl,-1); emit_movswl_indexed(x,tl,tl); #else emit_movswl_indexed((int)g_rdram-0x80000000+x,tl,tl); #endif } } } if(jaddr) add_stub(LOADH_STUB,jaddr,(int)out,i,addr,(intptr_t)i_regs,ccadj[i],reglist); } else inline_readstub(LOADH_STUB,i,constmap[i][s]+offset,i_regs->regmap,rt1[i],ccadj[i],reglist); } if (opcode[i]==0x23) { // LW if(!c||memtarget) { if(!dummy) { //emit_readword_indexed((int)g_rdram-0x80000000,addr,tl); #ifdef HOST_IMM_ADDR32 if(c) emit_readword_tlb(constmap[i][s]+offset,map,tl); else #endif emit_readword_indexed_tlb(0,addr,map,tl); } if(jaddr) add_stub(LOADW_STUB,jaddr,(int)out,i,addr,(int)i_regs,ccadj[i],reglist); } else inline_readstub(LOADW_STUB,i,constmap[i][s]+offset,i_regs->regmap,rt1[i],ccadj[i],reglist); } if (opcode[i]==0x24) { // LBU if(!c||memtarget) { if(!dummy) { #ifdef HOST_IMM_ADDR32 if(c) emit_movzbl_tlb((constmap[i][s]+offset)^3,map,tl); else #endif { //emit_xorimm(addr,3,tl); //gen_tlb_addr_r(tl,map); //emit_movzbl_indexed((int)g_rdram-0x80000000,tl,tl); int x=0; if(!c) emit_xorimm(addr,3,tl); else x=((constmap[i][s]+offset)^3)-(constmap[i][s]+offset); emit_movzbl_indexed_tlb(x,tl,map,tl); } } if(jaddr) add_stub(LOADBU_STUB,jaddr,(int)out,i,addr,(int)i_regs,ccadj[i],reglist); } else inline_readstub(LOADBU_STUB,i,constmap[i][s]+offset,i_regs->regmap,rt1[i],ccadj[i],reglist); } if (opcode[i]==0x25) { // LHU if(!c||memtarget) { if(!dummy) { #ifdef HOST_IMM_ADDR32 if(c) emit_movzwl_tlb((constmap[i][s]+offset)^2,map,tl); else #endif { int x=0; if(!c) emit_xorimm(addr,2,tl); else x=((constmap[i][s]+offset)^2)-(constmap[i][s]+offset); //#ifdef //emit_movzwl_indexed_tlb(x,tl,map,tl); //#else if(map>=0) { gen_tlb_addr_r(tl,map); emit_movzwl_indexed(x,tl,tl); }else{ #ifdef RAM_OFFSET emit_movzwl_indexed(x,tl,tl); #else emit_movzwl_indexed((int)g_rdram-0x80000000+x,tl,tl); #endif } } } if(jaddr) add_stub(LOADHU_STUB,jaddr,(int)out,i,addr,(int)i_regs,ccadj[i],reglist); } else inline_readstub(LOADHU_STUB,i,constmap[i][s]+offset,i_regs->regmap,rt1[i],ccadj[i],reglist); } if (opcode[i]==0x27) { // LWU assert(th>=0); if(!c||memtarget) { if(!dummy) { //emit_readword_indexed((int)g_rdram-0x80000000,addr,tl); #ifdef HOST_IMM_ADDR32 if(c) emit_readword_tlb(constmap[i][s]+offset,map,tl); else #endif emit_readword_indexed_tlb(0,addr,map,tl); } if(jaddr) add_stub(LOADW_STUB,jaddr,(int)out,i,addr,(int)i_regs,ccadj[i],reglist); } else { inline_readstub(LOADW_STUB,i,constmap[i][s]+offset,i_regs->regmap,rt1[i],ccadj[i],reglist); } emit_zeroreg(th); } if (opcode[i]==0x37) { // LD if(!c||memtarget) { if(!dummy) { //gen_tlb_addr_r(tl,map); //if(th>=0) emit_readword_indexed((int)g_rdram-0x80000000,addr,th); //emit_readword_indexed((int)g_rdram-0x7FFFFFFC,addr,tl); #ifdef HOST_IMM_ADDR32 if(c) emit_readdword_tlb(constmap[i][s]+offset,map,th,tl); else #endif emit_readdword_indexed_tlb(0,addr,map,th,tl); } if(jaddr) add_stub(LOADD_STUB,jaddr,(int)out,i,addr,(int)i_regs,ccadj[i],reglist); } else inline_readstub(LOADD_STUB,i,constmap[i][s]+offset,i_regs->regmap,rt1[i],ccadj[i],reglist); } //emit_storereg(rt1[i],tl); // DEBUG //if(opcode[i]==0x23) //if(opcode[i]==0x24) //if(opcode[i]==0x23||opcode[i]==0x24) /*if(opcode[i]==0x21||opcode[i]==0x23||opcode[i]==0x24) { //emit_pusha(); save_regs(0x100f); emit_readword((int)&last_count,ECX); #if NEW_DYNAREC == NEW_DYNAREC_X86 if(get_reg(i_regs->regmap,CCREG)<0) emit_loadreg(CCREG,HOST_CCREG); emit_add(HOST_CCREG,ECX,HOST_CCREG); emit_addimm(HOST_CCREG,2*ccadj[i],HOST_CCREG); emit_writeword(HOST_CCREG,(int)&g_cp0_regs[CP0_COUNT_REG]); #endif #if NEW_DYNAREC == NEW_DYNAREC_ARM if(get_reg(i_regs->regmap,CCREG)<0) emit_loadreg(CCREG,0); else emit_mov(HOST_CCREG,0); emit_add(0,ECX,0); emit_addimm(0,2*ccadj[i],0); emit_writeword(0,(int)&g_cp0_regs[CP0_COUNT_REG]); #endif emit_call((int)memdebug); //emit_popa(); restore_regs(0x100f); }*/ } #ifndef loadlr_assemble static void loadlr_assemble(int i,struct regstat *i_regs) { DebugMessage(M64MSG_ERROR, "Need loadlr_assemble for this architecture."); exit(1); } #endif static void store_assemble(int i,struct regstat *i_regs) { int s,th,tl,map=-1,cache=-1; int addr,temp; int offset; int type; intptr_t jaddr = 0; intptr_t jaddr2; int memtarget,c=0; int agr=AGEN1+(i&1); u_int hr,reglist=0; th=get_reg(i_regs->regmap,rs2[i]|64); tl=get_reg(i_regs->regmap,rs2[i]); s=get_reg(i_regs->regmap,rs1[i]); temp=get_reg(i_regs->regmap,agr); if(temp<0) temp=get_reg(i_regs->regmap,-1); offset=imm[i]; if(s>=0) { c=(i_regs->wasconst>>s)&1; memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80800000; if(using_tlb&&((signed int)(constmap[i][s]+offset))>=(signed int)0xC0000000) memtarget=1; } assert(tl>=0); assert(temp>=0); for(hr=0;hrregmap[hr]>=0) reglist|=1<regmap[HOST_CCREG]==CCREG) reglist&=~(1<regmap,ROREG); if(map<0) emit_loadreg(ROREG,map=HOST_TEMPREG); #endif if(!c) { #ifdef R29_HACK // Strmnnrmn's speed hack memtarget=1; if(rs1[i]!=29||start<0x80001000||start>=0x80800000) #endif emit_cmpimm(addr,0x800000); #ifdef DESTRUCTIVE_SHIFT if(s==addr) emit_mov(s,temp); #endif #ifdef R29_HACK if(rs1[i]!=29||start<0x80001000||start>=0x80800000) #endif { jaddr=(intptr_t)out; #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK // Hint to branch predictor that the branch is unlikely to be taken if(rs1[i]>=28) emit_jno_unlikely(0); else #endif emit_jno(0); } } }else{ // using tlb int x=0; if (opcode[i]==0x28) x=3; // SB if (opcode[i]==0x29) x=2; // SH map=get_reg(i_regs->regmap,TLREG); cache=get_reg(i_regs->regmap,MMREG); assert(map>=0); reglist&=~(1<=0) { gen_tlb_addr_w(temp,map); emit_writehword_indexed(tl,x,temp); }else emit_writehword_indexed(tl,(int)g_rdram-0x80000000+x,temp); } type=STOREH_STUB; } if (opcode[i]==0x2B) { // SW if(!c||memtarget) //emit_writeword_indexed(tl,(int)g_rdram-0x80000000,addr); emit_writeword_indexed_tlb(tl,0,addr,map,temp); type=STOREW_STUB; } if (opcode[i]==0x3F) { // SD if(!c||memtarget) { if(rs2[i]) { assert(th>=0); //emit_writeword_indexed(th,(int)g_rdram-0x80000000,addr); //emit_writeword_indexed(tl,(int)g_rdram-0x7FFFFFFC,addr); emit_writedword_indexed_tlb(th,tl,0,addr,map,temp); }else{ // Store zero //emit_writeword_indexed(tl,(int)g_rdram-0x80000000,temp); //emit_writeword_indexed(tl,(int)g_rdram-0x7FFFFFFC,temp); emit_writedword_indexed_tlb(tl,tl,0,addr,map,temp); } } type=STORED_STUB; } if(!using_tlb) { if(!c||memtarget) { #ifdef DESTRUCTIVE_SHIFT // The x86 shift operation is 'destructive'; it overwrites the // source register, so we need to make a copy first and use that. addr=temp; #endif #if defined(HOST_IMM8) int ir=get_reg(i_regs->regmap,INVCP); assert(ir>=0); emit_cmpmem_indexedsr12_reg(ir,addr,1); #else emit_cmpmem_indexedsr12_imm((int)invalid_code,addr,1); #endif #if defined(HAVE_CONDITIONAL_CALL) && !defined(DESTRUCTIVE_SHIFT) emit_callne(invalidate_addr_reg[addr]); #else jaddr2=(intptr_t)out; emit_jne(0); add_stub(INVCODE_STUB,jaddr2,(int)out,reglist|(1<regmap,rs2[i],ccadj[i],reglist); } //if(opcode[i]==0x2B || opcode[i]==0x3F) //if(opcode[i]==0x2B || opcode[i]==0x28) //if(opcode[i]==0x2B || opcode[i]==0x29) //if(opcode[i]==0x2B) // Uncomment for extra debug output: /* if(opcode[i]==0x2B || opcode[i]==0x28 || opcode[i]==0x29 || opcode[i]==0x3F) { #if NEW_DYNAREC == NEW_DYNAREC_X86 emit_pusha(); #endif #if NEW_DYNAREC == NEW_DYNAREC_ARM save_regs(0x100f); #endif emit_readword((int)&last_count,ECX); #if NEW_DYNAREC == NEW_DYNAREC_X86 if(get_reg(i_regs->regmap,CCREG)<0) emit_loadreg(CCREG,HOST_CCREG); emit_add(HOST_CCREG,ECX,HOST_CCREG); emit_addimm(HOST_CCREG,2*ccadj[i],HOST_CCREG); emit_writeword(HOST_CCREG,(int)&g_cp0_regs[CP0_COUNT_REG]); #endif #if NEW_DYNAREC == NEW_DYNAREC_ARM if(get_reg(i_regs->regmap,CCREG)<0) emit_loadreg(CCREG,0); else emit_mov(HOST_CCREG,0); emit_add(0,ECX,0); emit_addimm(0,2*ccadj[i],0); emit_writeword(0,(int)&g_cp0_regs[CP0_COUNT_REG]); #endif emit_call((int)memdebug); #if NEW_DYNAREC == NEW_DYNAREC_X86 emit_popa(); #endif #if NEW_DYNAREC == NEW_DYNAREC_ARM restore_regs(0x100f); #endif } */ } static void storelr_assemble(int i,struct regstat *i_regs) { int s,th,tl; int temp; int temp2; int offset; intptr_t jaddr2; intptr_t jaddr = 0; int case1,case2,case3; int done0,done1,done2; int memtarget,c=0; int agr=AGEN1+(i&1); u_int hr,reglist=0; th=get_reg(i_regs->regmap,rs2[i]|64); tl=get_reg(i_regs->regmap,rs2[i]); s=get_reg(i_regs->regmap,rs1[i]); temp=get_reg(i_regs->regmap,agr); if(temp<0) temp=get_reg(i_regs->regmap,-1); offset=imm[i]; if(s>=0) { c=(i_regs->isconst>>s)&1; memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80800000; if(using_tlb&&((signed int)(constmap[i][s]+offset))>=(signed int)0xC0000000) memtarget=1; } assert(tl>=0); for(hr=0;hrregmap[hr]>=0) reglist|=1<=0); if(!using_tlb) { if(!c) { emit_cmpimm(s<0||offset?temp:s,0x800000); if(!offset&&s!=temp) emit_mov(s,temp); jaddr=(intptr_t)out; emit_jno(0); } else { if(!memtarget||!rs1[i]) { jaddr=(intptr_t)out; emit_jmp(0); } } #ifdef RAM_OFFSET int map=get_reg(i_regs->regmap,ROREG); if(map<0) emit_loadreg(ROREG,map=HOST_TEMPREG); gen_tlb_addr_w(temp,map); #else if((u_int)g_rdram!=0x80000000) emit_addimm_no_flags((u_int)g_rdram-(u_int)0x80000000,temp); #endif }else{ // using tlb int map=get_reg(i_regs->regmap,TLREG); int cache=get_reg(i_regs->regmap,MMREG); assert(map>=0); reglist&=~(1<=0) emit_mov(s,temp); do_tlb_w_branch(map,c,constmap[i][s]+offset,&jaddr); if(!jaddr&&!memtarget) { jaddr=(intptr_t)out; emit_jmp(0); } gen_tlb_addr_w(temp,map); } if (opcode[i]==0x2C||opcode[i]==0x2D) { // SDL/SDR temp2=get_reg(i_regs->regmap,FTEMP); if(!rs2[i]) temp2=th=tl; } emit_testimm(temp,2); case2=(int)out; emit_jne(0); emit_testimm(temp,1); case1=(int)out; emit_jne(0); // 0 if (opcode[i]==0x2A) { // SWL emit_writeword_indexed(tl,0,temp); } if (opcode[i]==0x2E) { // SWR emit_writebyte_indexed(tl,3,temp); } if (opcode[i]==0x2C) { // SDL emit_writeword_indexed(th,0,temp); if(rs2[i]) emit_mov(tl,temp2); } if (opcode[i]==0x2D) { // SDR emit_writebyte_indexed(tl,3,temp); if(rs2[i]) emit_shldimm(th,tl,24,temp2); } done0=(int)out; emit_jmp(0); // 1 set_jump_target(case1,(int)out); if (opcode[i]==0x2A) { // SWL // Write 3 msb into three least significant bytes if(rs2[i]) emit_rorimm(tl,8,tl); emit_writehword_indexed(tl,-1,temp); if(rs2[i]) emit_rorimm(tl,16,tl); emit_writebyte_indexed(tl,1,temp); if(rs2[i]) emit_rorimm(tl,8,tl); } if (opcode[i]==0x2E) { // SWR // Write two lsb into two most significant bytes emit_writehword_indexed(tl,1,temp); } if (opcode[i]==0x2C) { // SDL if(rs2[i]) emit_shrdimm(tl,th,8,temp2); // Write 3 msb into three least significant bytes if(rs2[i]) emit_rorimm(th,8,th); emit_writehword_indexed(th,-1,temp); if(rs2[i]) emit_rorimm(th,16,th); emit_writebyte_indexed(th,1,temp); if(rs2[i]) emit_rorimm(th,8,th); } if (opcode[i]==0x2D) { // SDR if(rs2[i]) emit_shldimm(th,tl,16,temp2); // Write two lsb into two most significant bytes emit_writehword_indexed(tl,1,temp); } done1=(int)out; emit_jmp(0); // 2 set_jump_target(case2,(int)out); emit_testimm(temp,1); case3=(int)out; emit_jne(0); if (opcode[i]==0x2A) { // SWL // Write two msb into two least significant bytes if(rs2[i]) emit_rorimm(tl,16,tl); emit_writehword_indexed(tl,-2,temp); if(rs2[i]) emit_rorimm(tl,16,tl); } if (opcode[i]==0x2E) { // SWR // Write 3 lsb into three most significant bytes emit_writebyte_indexed(tl,-1,temp); if(rs2[i]) emit_rorimm(tl,8,tl); emit_writehword_indexed(tl,0,temp); if(rs2[i]) emit_rorimm(tl,24,tl); } if (opcode[i]==0x2C) { // SDL if(rs2[i]) emit_shrdimm(tl,th,16,temp2); // Write two msb into two least significant bytes if(rs2[i]) emit_rorimm(th,16,th); emit_writehword_indexed(th,-2,temp); if(rs2[i]) emit_rorimm(th,16,th); } if (opcode[i]==0x2D) { // SDR if(rs2[i]) emit_shldimm(th,tl,8,temp2); // Write 3 lsb into three most significant bytes emit_writebyte_indexed(tl,-1,temp); if(rs2[i]) emit_rorimm(tl,8,tl); emit_writehword_indexed(tl,0,temp); if(rs2[i]) emit_rorimm(tl,24,tl); } done2=(int)out; emit_jmp(0); // 3 set_jump_target(case3,(int)out); if (opcode[i]==0x2A) { // SWL // Write msb into least significant byte if(rs2[i]) emit_rorimm(tl,24,tl); emit_writebyte_indexed(tl,-3,temp); if(rs2[i]) emit_rorimm(tl,8,tl); } if (opcode[i]==0x2E) { // SWR // Write entire word emit_writeword_indexed(tl,-3,temp); } if (opcode[i]==0x2C) { // SDL if(rs2[i]) emit_shrdimm(tl,th,24,temp2); // Write msb into least significant byte if(rs2[i]) emit_rorimm(th,24,th); emit_writebyte_indexed(th,-3,temp); if(rs2[i]) emit_rorimm(th,8,th); } if (opcode[i]==0x2D) { // SDR if(rs2[i]) emit_mov(th,temp2); // Write entire word emit_writeword_indexed(tl,-3,temp); } set_jump_target(done0,(int)out); set_jump_target(done1,(int)out); set_jump_target(done2,(int)out); if (opcode[i]==0x2C) { // SDL emit_testimm(temp,4); done0=(int)out; emit_jne(0); emit_andimm(temp,~3,temp); emit_writeword_indexed(temp2,4,temp); set_jump_target(done0,(int)out); } if (opcode[i]==0x2D) { // SDR emit_testimm(temp,4); done0=(int)out; emit_jeq(0); emit_andimm(temp,~3,temp); emit_writeword_indexed(temp2,-4,temp); set_jump_target(done0,(int)out); } if(!c||!memtarget) add_stub(STORELR_STUB,jaddr,(int)out,0,(int)i_regs,rs2[i],ccadj[i],reglist); if(!using_tlb) { #ifdef RAM_OFFSET int map=get_reg(i_regs->regmap,ROREG); if(map<0) map=HOST_TEMPREG; gen_orig_addr_w(temp,map); #else emit_addimm_no_flags((u_int)0x80000000-(u_int)g_rdram,temp); #endif #if defined(HOST_IMM8) int ir=get_reg(i_regs->regmap,INVCP); assert(ir>=0); emit_cmpmem_indexedsr12_reg(ir,temp,1); #else emit_cmpmem_indexedsr12_imm((int)invalid_code,temp,1); #endif #if defined(HAVE_CONDITIONAL_CALL) && !defined(DESTRUCTIVE_SHIFT) emit_callne(invalidate_addr_reg[temp]); #else jaddr2=(intptr_t)out; emit_jne(0); add_stub(INVCODE_STUB,jaddr2,(int)out,reglist|(1<regmap,CCREG)<0) emit_loadreg(CCREG,HOST_CCREG); emit_add(HOST_CCREG,ECX,HOST_CCREG); emit_addimm(HOST_CCREG,2*ccadj[i],HOST_CCREG); emit_writeword(HOST_CCREG,(int)&g_cp0_regs[CP0_COUNT_REG]); emit_call((int)memdebug); emit_popa(); //restore_regs(0x100f); */ } static void c1ls_assemble(int i,struct regstat *i_regs) { int s,th,tl; int temp,ar; int map=-1; int offset; int c=0; int jaddr,jaddr3,type; intptr_t jaddr2 = 0; int agr=AGEN1+(i&1); u_int hr,reglist=0; th=get_reg(i_regs->regmap,FTEMP|64); tl=get_reg(i_regs->regmap,FTEMP); s=get_reg(i_regs->regmap,rs1[i]); temp=get_reg(i_regs->regmap,agr); if(temp<0) temp=get_reg(i_regs->regmap,-1); offset=imm[i]; assert(tl>=0); assert(rs1[i]>0); assert(temp>=0); for(hr=0;hrregmap[hr]>=0) reglist|=1<regmap[HOST_CCREG]==CCREG) reglist&=~(1<wasconst>>s)&1; if(s>=0) c=(i_regs->wasconst>>s)&1; // Check cop1 unusable if(!cop1_usable) { signed char rs=get_reg(i_regs->regmap,CSREG); assert(rs>=0); emit_testimm(rs,0x20000000); jaddr=(int)out; emit_jeq(0); add_stub(FP_STUB,jaddr,(int)out,i,rs,(int)i_regs,is_delayslot,0); cop1_usable=1; } if (opcode[i]==0x39) { // SWC1 (get float address) emit_readword((int)®_cop1_simple[(source[i]>>16)&0x1f],tl); } if (opcode[i]==0x3D) { // SDC1 (get double address) emit_readword((int)®_cop1_double[(source[i]>>16)&0x1f],tl); } // Generate address + offset if(!using_tlb) { #ifdef RAM_OFFSET if (!c||opcode[i]==0x39||opcode[i]==0x3D) // SWC1/SDC1 { map=get_reg(i_regs->regmap,ROREG); if(map<0) emit_loadreg(ROREG,map=HOST_TEMPREG); } #endif if(!c) emit_cmpimm(offset||c||s<0?ar:s,0x800000); } else { map=get_reg(i_regs->regmap,TLREG); int cache=get_reg(i_regs->regmap,MMREG); assert(map>=0); reglist&=~(1<>16)&0x1f],temp); } if (opcode[i]==0x35) { // LDC1 (get target address) emit_readword((int)®_cop1_double[(source[i]>>16)&0x1f],temp); } if(!using_tlb) { if(!c) { jaddr2=(intptr_t)out; emit_jno(0); } else if(((signed int)(constmap[i][s]+offset))>=(signed int)0x80800000) { jaddr2=(intptr_t)out; emit_jmp(0); // inline_readstub/inline_writestub? Very rare case } #ifdef DESTRUCTIVE_SHIFT if (opcode[i]==0x39||opcode[i]==0x3D) { // SWC1/SDC1 if(!offset&&!c&&s>=0) emit_mov(s,ar); } #endif }else{ if (opcode[i]==0x31||opcode[i]==0x35) { // LWC1/LDC1 do_tlb_r_branch(map,c,constmap[i][s]+offset,&jaddr2); } if (opcode[i]==0x39||opcode[i]==0x3D) { // SWC1/SDC1 do_tlb_w_branch(map,c,constmap[i][s]+offset,&jaddr2); } } if (opcode[i]==0x31) { // LWC1 //if(s>=0&&!c&&!offset) emit_mov(s,tl); //gen_tlb_addr_r(ar,map); //emit_readword_indexed((int)g_rdram-0x80000000,tl,tl); #ifdef HOST_IMM_ADDR32 if(c) emit_readword_tlb(constmap[i][s]+offset,map,tl); else #endif emit_readword_indexed_tlb(0,offset||c||s<0?tl:s,map,tl); type=LOADW_STUB; } if (opcode[i]==0x35) { // LDC1 assert(th>=0); //if(s>=0&&!c&&!offset) emit_mov(s,tl); //gen_tlb_addr_r(ar,map); //emit_readword_indexed((int)g_rdram-0x80000000,tl,th); //emit_readword_indexed((int)g_rdram-0x7FFFFFFC,tl,tl); #ifdef HOST_IMM_ADDR32 if(c) emit_readdword_tlb(constmap[i][s]+offset,map,th,tl); else #endif emit_readdword_indexed_tlb(0,offset||c||s<0?tl:s,map,th,tl); type=LOADD_STUB; } if (opcode[i]==0x39) { // SWC1 //emit_writeword_indexed(tl,(int)g_rdram-0x80000000,temp); emit_writeword_indexed_tlb(tl,0,offset||c||s<0?temp:s,map,temp); type=STOREW_STUB; } if (opcode[i]==0x3D) { // SDC1 assert(th>=0); //emit_writeword_indexed(th,(int)g_rdram-0x80000000,temp); //emit_writeword_indexed(tl,(int)g_rdram-0x7FFFFFFC,temp); emit_writedword_indexed_tlb(th,tl,0,offset||c||s<0?temp:s,map,temp); type=STORED_STUB; } if(!using_tlb) { if (opcode[i]==0x39||opcode[i]==0x3D) { // SWC1/SDC1 #ifndef DESTRUCTIVE_SHIFT temp=offset||c||s<0?ar:s; #endif #if defined(HOST_IMM8) int ir=get_reg(i_regs->regmap,INVCP); assert(ir>=0); emit_cmpmem_indexedsr12_reg(ir,temp,1); #else emit_cmpmem_indexedsr12_imm((int)invalid_code,temp,1); #endif #if defined(HAVE_CONDITIONAL_CALL) && !defined(DESTRUCTIVE_SHIFT) emit_callne(invalidate_addr_reg[temp]); #else jaddr3=(int)out; emit_jne(0); add_stub(INVCODE_STUB,jaddr3,(int)out,reglist|(1<regmap,CCREG)<0) emit_loadreg(CCREG,HOST_CCREG); emit_add(HOST_CCREG,ECX,HOST_CCREG); emit_addimm(HOST_CCREG,2*ccadj[i],HOST_CCREG); emit_writeword(HOST_CCREG,(int)&g_cp0_regs[CP0_COUNT_REG]); emit_call((int)memdebug); emit_popa(); }*/ } #ifndef multdiv_assemble void multdiv_assemble(int i,struct regstat *i_regs) { DebugMessage(M64MSG_ERROR, "Need multdiv_assemble for this architecture."); exit(1); } #endif static void mov_assemble(int i,struct regstat *i_regs) { //if(opcode2[i]==0x10||opcode2[i]==0x12) { // MFHI/MFLO //if(opcode2[i]==0x11||opcode2[i]==0x13) { // MTHI/MTLO if(rt1[i]) { signed char sh,sl,th,tl; th=get_reg(i_regs->regmap,rt1[i]|64); tl=get_reg(i_regs->regmap,rt1[i]); //assert(tl>=0); if(tl>=0) { sh=get_reg(i_regs->regmap,rs1[i]|64); sl=get_reg(i_regs->regmap,rs1[i]); if(sl>=0) emit_mov(sl,tl); else emit_loadreg(rs1[i],tl); if(th>=0) { if(sh>=0) emit_mov(sh,th); else emit_loadreg(rs1[i]|64,th); } } } } #ifndef fconv_assemble void fconv_assemble(int i,struct regstat *i_regs) { DebugMessage(M64MSG_ERROR, "Need fconv_assemble for this architecture."); exit(1); } #endif #if 0 static void float_assemble(int i,struct regstat *i_regs) { DebugMessage(M64MSG_ERROR, "Need float_assemble for this architecture."); exit(1); } #endif static void syscall_assemble(int i,struct regstat *i_regs) { signed char ccreg=get_reg(i_regs->regmap,CCREG); assert(ccreg==HOST_CCREG); assert(!is_delayslot); emit_movimm(start+i*4,EAX); // Get PC emit_addimm(HOST_CCREG,CLOCK_DIVIDER*ccadj[i],HOST_CCREG); // CHECK: is this right? There should probably be an extra cycle... emit_jmp((int)jump_syscall); } static void ds_assemble(int i,struct regstat *i_regs) { is_delayslot=1; switch(itype[i]) { case ALU: alu_assemble(i,i_regs);break; case IMM16: imm16_assemble(i,i_regs);break; case SHIFT: shift_assemble(i,i_regs);break; case SHIFTIMM: shiftimm_assemble(i,i_regs);break; case LOAD: load_assemble(i,i_regs);break; case LOADLR: loadlr_assemble(i,i_regs);break; case STORE: store_assemble(i,i_regs);break; case STORELR: storelr_assemble(i,i_regs);break; case COP0: cop0_assemble(i,i_regs);break; case COP1: cop1_assemble(i,i_regs);break; case C1LS: c1ls_assemble(i,i_regs);break; case FCONV: fconv_assemble(i,i_regs);break; case FLOAT: float_assemble(i,i_regs);break; case FCOMP: fcomp_assemble(i,i_regs);break; case MULTDIV: multdiv_assemble(i,i_regs);break; case MOV: mov_assemble(i,i_regs);break; case SYSCALL: case SPAN: case UJUMP: case RJUMP: case CJUMP: case SJUMP: case FJUMP: DebugMessage(M64MSG_VERBOSE, "Jump in the delay slot. This is probably a bug."); } is_delayslot=0; } // Is the branch target a valid internal jump? static int internal_branch(uint64_t i_is32,int addr) { if(addr&1) return 0; // Indirect (register) jump if(addr>=start && addr>2; // Delay slots are not valid branch targets //if(t>0&&(itype[t-1]==RJUMP||itype[t-1]==UJUMP||itype[t-1]==CJUMP||itype[t-1]==SJUMP||itype[t-1]==FJUMP)) return 0; // 64 -> 32 bit transition requires a recompile /*if(is32[t]&~unneeded_reg_upper[t]&~i_is32) { if(requires_32bit[t]&~i_is32) DebugMessage(M64MSG_VERBOSE, "optimizable: no"); else DebugMessage(M64MSG_VERBOSE, "optimizable: yes"); }*/ //if(is32[t]&~unneeded_reg_upper[t]&~i_is32) return 0; if(requires_32bit[t]&~i_is32) return 0; else return 1; } return 0; } #ifndef wb_invalidate static void wb_invalidate(signed char pre[],signed char entry[],uint64_t dirty,uint64_t is32, uint64_t u,uint64_t uu) { int hr; for(hr=0;hr=0) { if((dirty>>hr)&1) { if(get_reg(entry,pre[hr])<0) { if(pre[hr]<64) { if(!((u>>pre[hr])&1)) { emit_storereg(pre[hr],hr); if( ((is32>>pre[hr])&1) && !((uu>>pre[hr])&1) ) { emit_sarimm(hr,31,hr); emit_storereg(pre[hr]|64,hr); } } }else{ if(!((uu>>(pre[hr]&63))&1) && !((is32>>(pre[hr]&63))&1)) { emit_storereg(pre[hr],hr); } } } } } } } } // Move from one register to another (no writeback) for(hr=0;hr=0&&(pre[hr]&63)=0) { emit_mov(hr,nr); } } } } } } #endif // Load the specified registers // This only loads the registers given as arguments because // we don't want to load things that will be overwritten static void load_regs(signed char entry[],signed char regmap[],int is32,int rs1,int rs2) { int hr; // Load 32-bit regs for(hr=0;hr=0) { if(entry[hr]!=regmap[hr]) { if(regmap[hr]==rs1||regmap[hr]==rs2) { if(regmap[hr]==0) { emit_zeroreg(hr); } else { emit_loadreg(regmap[hr],hr); } } } } } //Load 64-bit regs for(hr=0;hr=0) { if(entry[hr]!=regmap[hr]) { if(regmap[hr]-64==rs1||regmap[hr]-64==rs2) { assert(regmap[hr]!=64); if((is32>>(regmap[hr]&63))&1) { int lr=get_reg(regmap,regmap[hr]-64); if(lr>=0) emit_sarimm(lr,31,hr); else emit_loadreg(regmap[hr],hr); } else { emit_loadreg(regmap[hr],hr); } } } } } } // Load registers prior to the start of a loop // so that they are not loaded within the loop static void loop_preload(signed char pre[],signed char entry[]) { int hr; for(hr=0;hr=0) { if(get_reg(pre,entry[hr])<0) { assem_debug("loop preload:"); //DebugMessage(M64MSG_VERBOSE, "loop preload: %d",hr); if(entry[hr]==0) { emit_zeroreg(hr); } else if(entry[hr]regmap,rt1[i]); if(ra<0) ra=get_reg(i_regs->regmap,-1); assert(ra>=0); } if(itype[i]==LOADLR) { ra=get_reg(i_regs->regmap,FTEMP); } if(itype[i]==STORE||itype[i]==STORELR) { ra=get_reg(i_regs->regmap,agr); if(ra<0) ra=get_reg(i_regs->regmap,-1); } if(itype[i]==C1LS) { if (opcode[i]==0x31||opcode[i]==0x35) // LWC1/LDC1 ra=get_reg(i_regs->regmap,FTEMP); else { // SWC1/SDC1 ra=get_reg(i_regs->regmap,agr); if(ra<0) ra=get_reg(i_regs->regmap,-1); } } int rs=get_reg(i_regs->regmap,rs1[i]); int rm=get_reg(i_regs->regmap,TLREG); if(ra>=0) { int offset=imm[i]; int c=(i_regs->wasconst>>rs)&1; if(rs1[i]==0) { // Using r0 as a base address /*if(rm>=0) { if(!entry||entry[rm]!=mgr) { generate_map_const(offset,rm); } // else did it in the previous cycle }*/ if(!entry||entry[ra]!=agr) { if (opcode[i]==0x22||opcode[i]==0x26) { emit_movimm(offset&0xFFFFFFFC,ra); // LWL/LWR }else if (opcode[i]==0x1a||opcode[i]==0x1b) { emit_movimm(offset&0xFFFFFFF8,ra); // LDL/LDR }else{ emit_movimm(offset,ra); } } // else did it in the previous cycle } else if(rs<0) { if(!entry||entry[ra]!=rs1[i]) emit_loadreg(rs1[i],ra); //if(!entry||entry[ra]!=rs1[i]) // DebugMessage(M64MSG_VERBOSE, "poor load scheduling!"); } else if(c) { if(rm>=0) { if(!entry||entry[rm]!=mgr) { if(itype[i]==STORE||itype[i]==STORELR||opcode[i]==0x39||opcode[i]==0x3D) { // Stores to memory go thru the mapper to detect self-modifying // code, loads don't. if((unsigned int)(constmap[i][rs]+offset)>=0xC0000000 || (unsigned int)(constmap[i][rs]+offset)<0x80800000 ) generate_map_const(constmap[i][rs]+offset,rm); }else{ if((signed int)(constmap[i][rs]+offset)>=(signed int)0xC0000000) generate_map_const(constmap[i][rs]+offset,rm); } } } if(rs1[i]!=rt1[i]||itype[i]!=LOAD) { if(!entry||entry[ra]!=agr) { if (opcode[i]==0x22||opcode[i]==0x26) { // LWL/LWR #ifdef RAM_OFFSET if((signed int)constmap[i][rs]+offset<(signed int)0x80800000) emit_movimm(((constmap[i][rs]+offset)&0xFFFFFFFC)+(int)g_rdram-0x80000000,ra); else #endif emit_movimm((constmap[i][rs]+offset)&0xFFFFFFFC,ra); }else if (opcode[i]==0x1a||opcode[i]==0x1b) { // LDL/LDR #ifdef RAM_OFFSET if((signed int)constmap[i][rs]+offset<(signed int)0x80800000) emit_movimm(((constmap[i][rs]+offset)&0xFFFFFFF8)+(int)g_rdram-0x80000000,ra); else #endif emit_movimm((constmap[i][rs]+offset)&0xFFFFFFF8,ra); }else{ #ifdef HOST_IMM_ADDR32 if((itype[i]!=LOAD&&opcode[i]!=0x31&&opcode[i]!=0x35) || (using_tlb&&((signed int)constmap[i][rs]+offset)>=(signed int)0xC0000000)) #endif #ifdef RAM_OFFSET if((itype[i]==LOAD||opcode[i]==0x31||opcode[i]==0x35)&&(signed int)constmap[i][rs]+offset<(signed int)0x80800000) emit_movimm(constmap[i][rs]+offset+(int)g_rdram-0x80000000,ra); else #endif emit_movimm(constmap[i][rs]+offset,ra); } } // else did it in the previous cycle } // else load_consts already did it } if(offset&&!c&&rs1[i]) { if(rs>=0) { emit_addimm(rs,offset,ra); }else{ emit_addimm(ra,offset,ra); } } } } // Preload constants for next instruction if(itype[i+1]==LOAD||itype[i+1]==LOADLR||itype[i+1]==STORE||itype[i+1]==STORELR||itype[i+1]==C1LS) { int agr,ra; #ifndef HOST_IMM_ADDR32 // Mapper entry agr=MGEN1+((i+1)&1); ra=get_reg(i_regs->regmap,agr); if(ra>=0) { int rs=get_reg(regs[i+1].regmap,rs1[i+1]); int offset=imm[i+1]; int c=(regs[i+1].wasconst>>rs)&1; if(c) { if(itype[i+1]==STORE||itype[i+1]==STORELR||opcode[i+1]==0x39||opcode[i+1]==0x3D) { // Stores to memory go thru the mapper to detect self-modifying // code, loads don't. if((unsigned int)(constmap[i+1][rs]+offset)>=0xC0000000 || (unsigned int)(constmap[i+1][rs]+offset)<0x80800000 ) generate_map_const(constmap[i+1][rs]+offset,ra); }else{ if((signed int)(constmap[i+1][rs]+offset)>=(signed int)0xC0000000) generate_map_const(constmap[i+1][rs]+offset,ra); } } /*else if(rs1[i]==0) { generate_map_const(offset,ra); }*/ } #endif // Actual address agr=AGEN1+((i+1)&1); ra=get_reg(i_regs->regmap,agr); if(ra>=0) { int rs=get_reg(regs[i+1].regmap,rs1[i+1]); int offset=imm[i+1]; int c=(regs[i+1].wasconst>>rs)&1; if(c&&(rs1[i+1]!=rt1[i+1]||itype[i+1]!=LOAD)) { if (opcode[i+1]==0x22||opcode[i+1]==0x26) { // LWL/LWR #ifdef RAM_OFFSET if((signed int)constmap[i+1][rs]+offset<(signed int)0x80800000) emit_movimm(((constmap[i+1][rs]+offset)&0xFFFFFFFC)+(int)g_rdram-0x80000000,ra); else #endif emit_movimm((constmap[i+1][rs]+offset)&0xFFFFFFFC,ra); }else if (opcode[i+1]==0x1a||opcode[i+1]==0x1b) { // LDL/LDR #ifdef RAM_OFFSET if((signed int)constmap[i+1][rs]+offset<(signed int)0x80800000) emit_movimm(((constmap[i+1][rs]+offset)&0xFFFFFFF8)+(int)g_rdram-0x80000000,ra); else #endif emit_movimm((constmap[i+1][rs]+offset)&0xFFFFFFF8,ra); }else{ #ifdef HOST_IMM_ADDR32 if((itype[i+1]!=LOAD&&opcode[i+1]!=0x31&&opcode[i+1]!=0x35) || (using_tlb&&((signed int)constmap[i+1][rs]+offset)>=(signed int)0xC0000000)) #endif #ifdef RAM_OFFSET if((itype[i+1]==LOAD||opcode[i+1]==0x31||opcode[i+1]==0x35)&&(signed int)constmap[i+1][rs]+offset<(signed int)0x80800000) emit_movimm(constmap[i+1][rs]+offset+(int)g_rdram-0x80000000,ra); else #endif emit_movimm(constmap[i+1][rs]+offset,ra); } } else if(rs1[i+1]==0) { // Using r0 as a base address if (opcode[i+1]==0x22||opcode[i+1]==0x26) { emit_movimm(offset&0xFFFFFFFC,ra); // LWL/LWR }else if (opcode[i+1]==0x1a||opcode[i+1]==0x1b) { emit_movimm(offset&0xFFFFFFF8,ra); // LDL/LDR }else{ emit_movimm(offset,ra); } } } } } static int get_final_value(int hr, int i, int *value) { int reg=regs[i].regmap[hr]; while(i>hr)&1)) break; if(bt[i+1]) break; i++; } if(i>hr)&1)) { #ifdef HOST_IMM_ADDR32 if(!using_tlb||((signed int)constmap[i][hr]+imm[i+2])<(signed int)0xC0000000) return 0; #endif #ifdef RAM_OFFSET if((signed int)constmap[i][hr]+imm[i+2]<(signed int)0x80800000) *value=constmap[i][hr]+imm[i+2]+(int)g_rdram-0x80000000; else #endif // Precompute load address *value=constmap[i][hr]+imm[i+2]; return 1; } } if(itype[i+1]==LOAD&&rs1[i+1]==reg&&rt1[i+1]==reg) { #ifdef HOST_IMM_ADDR32 if(!using_tlb||((signed int)constmap[i][hr]+imm[i+1])<(signed int)0xC0000000) return 0; #endif #ifdef RAM_OFFSET if((signed int)constmap[i][hr]+imm[i+1]<(signed int)0x80800000) *value=constmap[i][hr]+imm[i+1]+(int)g_rdram-0x80000000; else #endif // Precompute load address *value=constmap[i][hr]+imm[i+1]; //DebugMessage(M64MSG_VERBOSE, "c=%x imm=%x",(int)constmap[i][hr],imm[i+1]); return 1; } } } *value=constmap[i][hr]; //DebugMessage(M64MSG_VERBOSE, "c=%x",(int)constmap[i][hr]); if(i==slen-1) return 1; if(reg<64) { return !((unneeded_reg[i+1]>>reg)&1); }else{ return !((unneeded_reg_upper[i+1]>>reg)&1); } } // Load registers with known constants static void load_consts(signed char pre[],signed char regmap[],int is32,int i) { int hr; // Load 32-bit regs for(hr=0;hr=0) { //if(entry[hr]!=regmap[hr]) { if(i==0||!((regs[i-1].isconst>>hr)&1)||pre[hr]!=regmap[hr]||bt[i]) { if(((regs[i].isconst>>hr)&1)&®map[hr]<64&®map[hr]>0) { int value; if(get_final_value(hr,i,&value)) { if(value==0) { emit_zeroreg(hr); } else { emit_movimm(value,hr); } } } } } } // Load 64-bit regs for(hr=0;hr=0) { //if(entry[hr]!=regmap[hr]) { if(i==0||!((regs[i-1].isconst>>hr)&1)||pre[hr]!=regmap[hr]||bt[i]) { if(((regs[i].isconst>>hr)&1)&®map[hr]>64) { if((is32>>(regmap[hr]&63))&1) { int lr=get_reg(regmap,regmap[hr]-64); assert(lr>=0); emit_sarimm(lr,31,hr); } else { int value; if(get_final_value(hr,i,&value)) { if(value==0) { emit_zeroreg(hr); } else { emit_movimm(value,hr); } } } } } } } } static void load_all_consts(signed char regmap[],int is32,u_int dirty,int i) { int hr; // Load 32-bit regs for(hr=0;hr=0&&((dirty>>hr)&1)) { if(((regs[i].isconst>>hr)&1)&®map[hr]<64&®map[hr]>0) { int value=constmap[i][hr]; if(value==0) { emit_zeroreg(hr); } else { emit_movimm(value,hr); } } } } // Load 64-bit regs for(hr=0;hr=0&&((dirty>>hr)&1)) { if(((regs[i].isconst>>hr)&1)&®map[hr]>64) { if((is32>>(regmap[hr]&63))&1) { int lr=get_reg(regmap,regmap[hr]-64); assert(lr>=0); emit_sarimm(lr,31,hr); } else { int value=constmap[i][hr]; if(value==0) { emit_zeroreg(hr); } else { emit_movimm(value,hr); } } } } } } // Write out all dirty registers (except cycle count) static void wb_dirtys(signed char i_regmap[],uint64_t i_is32,uint64_t i_dirty) { int hr; for(hr=0;hr0) { if(i_regmap[hr]!=CCREG) { if((i_dirty>>hr)&1) { if(i_regmap[hr]<64) { emit_storereg(i_regmap[hr],hr); if( ((i_is32>>i_regmap[hr])&1) ) { #ifdef DESTRUCTIVE_WRITEBACK emit_sarimm(hr,31,hr); emit_storereg(i_regmap[hr]|64,hr); #else emit_sarimm(hr,31,HOST_TEMPREG); emit_storereg(i_regmap[hr]|64,HOST_TEMPREG); #endif } }else{ if( !((i_is32>>(i_regmap[hr]&63))&1) ) { emit_storereg(i_regmap[hr],hr); } } } } } } } } // Write out dirty registers that we need to reload (pair with load_needed_regs) // This writes the registers not written by store_regs_bt static void wb_needed_dirtys(signed char i_regmap[],uint64_t i_is32,uint64_t i_dirty,int addr) { int hr; int t=(addr-start)>>2; for(hr=0;hr0) { if(i_regmap[hr]!=CCREG) { if(i_regmap[hr]==regs[t].regmap_entry[hr] && ((regs[t].dirty>>hr)&1) && !(((i_is32&~regs[t].was32&~unneeded_reg_upper[t])>>(i_regmap[hr]&63))&1)) { if((i_dirty>>hr)&1) { if(i_regmap[hr]<64) { emit_storereg(i_regmap[hr],hr); if( ((i_is32>>i_regmap[hr])&1) ) { #ifdef DESTRUCTIVE_WRITEBACK emit_sarimm(hr,31,hr); emit_storereg(i_regmap[hr]|64,hr); #else emit_sarimm(hr,31,HOST_TEMPREG); emit_storereg(i_regmap[hr]|64,HOST_TEMPREG); #endif } }else{ if( !((i_is32>>(i_regmap[hr]&63))&1) ) { emit_storereg(i_regmap[hr],hr); } } } } } } } } } // Load all registers (except cycle count) static void load_all_regs(signed char i_regmap[]) { int hr; for(hr=0;hr0 && (i_regmap[hr]&63)=0) { if(i_regmap[hr]==0) { emit_zeroreg(hr); } else if(i_regmap[hr]>0 && (i_regmap[hr]&63)=0&®s[t].regmap_entry[hr]=64&®s[t].regmap_entry[hr]>(regs[t].regmap_entry[hr]&63))&1) { int lr=get_reg(regs[t].regmap_entry,regs[t].regmap_entry[hr]-64); if(lr<0) { emit_loadreg(regs[t].regmap_entry[hr],hr); } else { emit_sarimm(lr,31,hr); } } else { emit_loadreg(regs[t].regmap_entry[hr],hr); } } } } // Store dirty registers prior to branch static void store_regs_bt(signed char i_regmap[],uint64_t i_is32,uint64_t i_dirty,int addr) { if(internal_branch(i_is32,addr)) { int t=(addr-start)>>2; int hr; for(hr=0;hr0 && i_regmap[hr]!=CCREG) { if(i_regmap[hr]!=regs[t].regmap_entry[hr] || !((regs[t].dirty>>hr)&1) || (((i_is32&~regs[t].was32&~unneeded_reg_upper[t])>>(i_regmap[hr]&63))&1)) { if((i_dirty>>hr)&1) { if(i_regmap[hr]<64) { if(!((unneeded_reg[t]>>i_regmap[hr])&1)) { emit_storereg(i_regmap[hr],hr); if( ((i_is32>>i_regmap[hr])&1) && !((unneeded_reg_upper[t]>>i_regmap[hr])&1) ) { #ifdef DESTRUCTIVE_WRITEBACK emit_sarimm(hr,31,hr); emit_storereg(i_regmap[hr]|64,hr); #else emit_sarimm(hr,31,HOST_TEMPREG); emit_storereg(i_regmap[hr]|64,HOST_TEMPREG); #endif } } }else{ if( !((i_is32>>(i_regmap[hr]&63))&1) && !((unneeded_reg_upper[t]>>(i_regmap[hr]&63))&1) ) { emit_storereg(i_regmap[hr],hr); } } } } } } } } else { // Branch out of this block, write out all dirty regs wb_dirtys(i_regmap,i_is32,i_dirty); } } // Load all needed registers for branch target static void load_regs_bt(signed char i_regmap[],uint64_t i_is32,uint64_t i_dirty,int addr) { //if(addr>=start && addr<(start+slen*4)) if(internal_branch(i_is32,addr)) { int t=(addr-start)>>2; int hr; // Store the cycle count before loading something else if(i_regmap[HOST_CCREG]!=CCREG) { assert(i_regmap[HOST_CCREG]==-1); } if(regs[t].regmap_entry[HOST_CCREG]!=CCREG) { emit_storereg(CCREG,HOST_CCREG); } // Load 32-bit regs for(hr=0;hr=0&®s[t].regmap_entry[hr]>hr)&1) && ((i_dirty>>hr)&1) && (((i_is32&~unneeded_reg_upper[t])>>i_regmap[hr])&1) ) || (((i_is32&~regs[t].was32&~unneeded_reg_upper[t])>>(i_regmap[hr]&63))&1)) { #else if(i_regmap[hr]!=regs[t].regmap_entry[hr] ) { #endif if(regs[t].regmap_entry[hr]==0) { emit_zeroreg(hr); } else if(regs[t].regmap_entry[hr]!=CCREG) { emit_loadreg(regs[t].regmap_entry[hr],hr); } } } } //Load 64-bit regs for(hr=0;hr=64&®s[t].regmap_entry[hr]>(regs[t].regmap_entry[hr]&63))&1) { int lr=get_reg(regs[t].regmap_entry,regs[t].regmap_entry[hr]-64); if(lr<0) { emit_loadreg(regs[t].regmap_entry[hr],hr); } else { emit_sarimm(lr,31,hr); } } else { emit_loadreg(regs[t].regmap_entry[hr],hr); } } else if((i_is32>>(regs[t].regmap_entry[hr]&63))&1) { int lr=get_reg(regs[t].regmap_entry,regs[t].regmap_entry[hr]-64); assert(lr>=0); emit_sarimm(lr,31,hr); } } } } } static int match_bt(signed char i_regmap[],uint64_t i_is32,uint64_t i_dirty,int addr) { if(addr>=start && addr>2; int hr; if(regs[t].regmap_entry[HOST_CCREG]!=CCREG) return 0; for(hr=0;hr=0&&(regs[t].regmap_entry[hr]|64)>hr)&1) { if(i_regmap[hr]>i_regmap[hr])&1)) return 0; } else if(i_regmap[hr]>=64&&i_regmap[hr]>(i_regmap[hr]&63))&1)) return 0; } } } else // Same register but is it 32-bit or dirty? if(i_regmap[hr]>=0) { if(!((regs[t].dirty>>hr)&1)) { if((i_dirty>>hr)&1) { if(!((unneeded_reg[t]>>i_regmap[hr])&1)) { //DebugMessage(M64MSG_VERBOSE, "%x: dirty no match",addr); return 0; } } } if((((regs[t].was32^i_is32)&~unneeded_reg_upper[t])>>(i_regmap[hr]&63))&1) { //DebugMessage(M64MSG_VERBOSE, "%x: is32 no match",addr); return 0; } } } } //if(is32[t]&~unneeded_reg_upper[t]&~i_is32) return 0; if(requires_32bit[t]&~i_is32) return 0; // Delay slots are not valid branch targets //if(t>0&&(itype[t-1]==RJUMP||itype[t-1]==UJUMP||itype[t-1]==CJUMP||itype[t-1]==SJUMP||itype[t-1]==FJUMP)) return 0; // Delay slots require additional processing, so do not match if(is_ds[t]) return 0; } else { int hr; for(hr=0;hr=0) { if(hr!=HOST_CCREG||i_regmap[hr]!=CCREG) { if((i_dirty>>hr)&1) { return 0; } } } } } } return 1; } // Used when a branch jumps into the delay slot of another branch static void ds_assemble_entry(int i) { int t=(ba[i]-start)>>2; if(!instr_addr[t]) instr_addr[t]=(u_int)out; assem_debug("Assemble delay slot at %x",ba[i]); assem_debug("<->"); if(regs[t].regmap_entry[HOST_CCREG]==CCREG&®s[t].regmap[HOST_CCREG]!=CCREG) wb_register(CCREG,regs[t].regmap_entry,regs[t].wasdirty,regs[t].was32); load_regs(regs[t].regmap_entry,regs[t].regmap,regs[t].was32,rs1[t],rs2[t]); address_generation(t,®s[t],regs[t].regmap_entry); if(itype[t]==LOAD||itype[t]==LOADLR||itype[t]==STORE||itype[t]==STORELR||itype[t]==C1LS) load_regs(regs[t].regmap_entry,regs[t].regmap,regs[t].was32,MMREG,ROREG); if(itype[t]==STORE||itype[t]==STORELR||(opcode[t]&0x3b)==0x39) load_regs(regs[t].regmap_entry,regs[t].regmap,regs[t].was32,INVCP,INVCP); cop1_usable=0; is_delayslot=0; switch(itype[t]) { case ALU: alu_assemble(t,®s[t]);break; case IMM16: imm16_assemble(t,®s[t]);break; case SHIFT: shift_assemble(t,®s[t]);break; case SHIFTIMM: shiftimm_assemble(t,®s[t]);break; case LOAD: load_assemble(t,®s[t]);break; case LOADLR: loadlr_assemble(t,®s[t]);break; case STORE: store_assemble(t,®s[t]);break; case STORELR: storelr_assemble(t,®s[t]);break; case COP0: cop0_assemble(t,®s[t]);break; case COP1: cop1_assemble(t,®s[t]);break; case C1LS: c1ls_assemble(t,®s[t]);break; case FCONV: fconv_assemble(t,®s[t]);break; case FLOAT: float_assemble(t,®s[t]);break; case FCOMP: fcomp_assemble(t,®s[t]);break; case MULTDIV: multdiv_assemble(t,®s[t]);break; case MOV: mov_assemble(t,®s[t]);break; case SYSCALL: case SPAN: case UJUMP: case RJUMP: case CJUMP: case SJUMP: case FJUMP: DebugMessage(M64MSG_VERBOSE, "Jump in the delay slot. This is probably a bug."); } store_regs_bt(regs[t].regmap,regs[t].is32,regs[t].dirty,ba[i]+4); load_regs_bt(regs[t].regmap,regs[t].is32,regs[t].dirty,ba[i]+4); if(internal_branch(regs[t].is32,ba[i]+4)) assem_debug("branch: internal"); else assem_debug("branch: external"); assert(internal_branch(regs[t].is32,ba[i]+4)); add_to_linker((intptr_t)out,ba[i]+4,internal_branch(regs[t].is32,ba[i]+4)); emit_jmp(0); } static void do_cc(int i,signed char i_regmap[],int *adj,int addr,int taken,int invert) { int count; int jaddr; int idle=0; if(itype[i]==RJUMP) { *adj=0; } //if(ba[i]>=start && ba[i]<(start+slen*4)) if(internal_branch(branch_regs[i].is32,ba[i])) { int t=(ba[i]-start)>>2; if(is_ds[t]) *adj=-1; // Branch into delay slot adds an extra cycle else *adj=ccadj[t]; } else { *adj=0; } count=ccadj[i]; if(taken==TAKEN && i==(ba[i]-start)>>2 && source[i+1]==0) { // Idle loop if(count&1) emit_addimm_and_set_flags(2*(count+2),HOST_CCREG); idle=(int)out; //emit_subfrommem(&idlecount,HOST_CCREG); // Count idle cycles emit_andimm(HOST_CCREG,3,HOST_CCREG); jaddr=(int)out; emit_jmp(0); } else if(*adj==0||invert) { emit_addimm_and_set_flags(CLOCK_DIVIDER*(count+2),HOST_CCREG); jaddr=(int)out; emit_jns(0); } else { emit_cmpimm(HOST_CCREG,-CLOCK_DIVIDER*(count+2)); jaddr=(int)out; emit_jns(0); } add_stub(CC_STUB,jaddr,idle?idle:(int)out,(*adj==0||invert||idle)?0:(count+2),i,addr,taken,0); } static void do_ccstub(int n) { literal_pool(256); assem_debug("do_ccstub %x",start+stubs[n][4]*4); set_jump_target(stubs[n][1],(int)out); int i=stubs[n][4]; if(stubs[n][6]==NULLDS) { // Delay slot instruction is nullified ("likely" branch) wb_dirtys(regs[i].regmap,regs[i].is32,regs[i].dirty); } else if(stubs[n][6]!=TAKEN) { wb_dirtys(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty); } else { if(internal_branch(branch_regs[i].is32,ba[i])) wb_needed_dirtys(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]); } if(stubs[n][5]!=-1) { // Save PC as return address emit_movimm(stubs[n][5],EAX); emit_writeword(EAX,(int)&pcaddr); } else { // Return address depends on which way the branch goes if(itype[i]==CJUMP||itype[i]==SJUMP||itype[i]==FJUMP) { int s1l=get_reg(branch_regs[i].regmap,rs1[i]); int s1h=get_reg(branch_regs[i].regmap,rs1[i]|64); int s2l=get_reg(branch_regs[i].regmap,rs2[i]); int s2h=get_reg(branch_regs[i].regmap,rs2[i]|64); if(rs1[i]==0) { s1l=s2l;s1h=s2h; s2l=s2h=-1; } else if(rs2[i]==0) { s2l=s2h=-1; } if((branch_regs[i].is32>>rs1[i])&(branch_regs[i].is32>>rs2[i])&1) { s1h=s2h=-1; } assert(s1l>=0); #ifdef DESTRUCTIVE_WRITEBACK if(rs1[i]) { if((branch_regs[i].dirty>>s1l)&(branch_regs[i].is32>>rs1[i])&1) emit_loadreg(rs1[i],s1l); } else { if((branch_regs[i].dirty>>s1l)&(branch_regs[i].is32>>rs2[i])&1) emit_loadreg(rs2[i],s1l); } if(s2l>=0) if((branch_regs[i].dirty>>s2l)&(branch_regs[i].is32>>rs2[i])&1) emit_loadreg(rs2[i],s2l); #endif int hr=0; int addr,alt,ntaddr; while(hr=0) emit_cmp(s1l,s2l); else emit_test(s1l,s1l); emit_cmov2imm_e_ne_compact(ba[i],start+i*4+8,addr); } else #endif { emit_mov2imm_compact(ba[i],addr,start+i*4+8,alt); if(s1h>=0) { if(s2h>=0) emit_cmp(s1h,s2h); else emit_test(s1h,s1h); emit_cmovne_reg(alt,addr); } if(s2l>=0) emit_cmp(s1l,s2l); else emit_test(s1l,s1l); emit_cmovne_reg(alt,addr); } } if((opcode[i]&0x2f)==5) // BNE { #ifdef HAVE_CMOV_IMM if(s1h<0) { if(s2l>=0) emit_cmp(s1l,s2l); else emit_test(s1l,s1l); emit_cmov2imm_e_ne_compact(start+i*4+8,ba[i],addr); } else #endif { emit_mov2imm_compact(start+i*4+8,addr,ba[i],alt); if(s1h>=0) { if(s2h>=0) emit_cmp(s1h,s2h); else emit_test(s1h,s1h); emit_cmovne_reg(alt,addr); } if(s2l>=0) emit_cmp(s1l,s2l); else emit_test(s1l,s1l); emit_cmovne_reg(alt,addr); } } if((opcode[i]&0x2f)==6) // BLEZ { //emit_movimm(ba[i],alt); //emit_movimm(start+i*4+8,addr); emit_mov2imm_compact(ba[i],alt,start+i*4+8,addr); emit_cmpimm(s1l,1); if(s1h>=0) emit_mov(addr,ntaddr); emit_cmovl_reg(alt,addr); if(s1h>=0) { emit_test(s1h,s1h); emit_cmovne_reg(ntaddr,addr); emit_cmovs_reg(alt,addr); } } if((opcode[i]&0x2f)==7) // BGTZ { //emit_movimm(ba[i],addr); //emit_movimm(start+i*4+8,ntaddr); emit_mov2imm_compact(ba[i],addr,start+i*4+8,ntaddr); emit_cmpimm(s1l,1); if(s1h>=0) emit_mov(addr,alt); emit_cmovl_reg(ntaddr,addr); if(s1h>=0) { emit_test(s1h,s1h); emit_cmovne_reg(alt,addr); emit_cmovs_reg(ntaddr,addr); } } if((opcode[i]==1)&&(opcode2[i]&0x2D)==0) // BLTZ { //emit_movimm(ba[i],alt); //emit_movimm(start+i*4+8,addr); emit_mov2imm_compact(ba[i],alt,start+i*4+8,addr); if(s1h>=0) emit_test(s1h,s1h); else emit_test(s1l,s1l); emit_cmovs_reg(alt,addr); } if((opcode[i]==1)&&(opcode2[i]&0x2D)==1) // BGEZ { //emit_movimm(ba[i],addr); //emit_movimm(start+i*4+8,alt); emit_mov2imm_compact(ba[i],addr,start+i*4+8,alt); if(s1h>=0) emit_test(s1h,s1h); else emit_test(s1l,s1l); emit_cmovs_reg(alt,addr); } if(opcode[i]==0x11 && opcode2[i]==0x08 ) { if(source[i]&0x10000) // BC1T { //emit_movimm(ba[i],alt); //emit_movimm(start+i*4+8,addr); emit_mov2imm_compact(ba[i],alt,start+i*4+8,addr); emit_testimm(s1l,0x800000); emit_cmovne_reg(alt,addr); } else // BC1F { //emit_movimm(ba[i],addr); //emit_movimm(start+i*4+8,alt); emit_mov2imm_compact(ba[i],addr,start+i*4+8,alt); emit_testimm(s1l,0x800000); emit_cmovne_reg(alt,addr); } } emit_writeword(addr,(int)&pcaddr); } else if(itype[i]==RJUMP) { int r=get_reg(branch_regs[i].regmap,rs1[i]); if(rs1[i]==rt1[i+1]||rs1[i]==rt2[i+1]) { r=get_reg(branch_regs[i].regmap,RTEMP); } emit_writeword(r,(int)&pcaddr); } else {DebugMessage(M64MSG_ERROR, "Unknown branch type in do_ccstub");exit(1);} } // Update cycle count assert(branch_regs[i].regmap[HOST_CCREG]==CCREG||branch_regs[i].regmap[HOST_CCREG]==-1); if(stubs[n][3]) emit_addimm(HOST_CCREG,CLOCK_DIVIDER*stubs[n][3],HOST_CCREG); emit_call((int)cc_interrupt); if(stubs[n][3]) emit_addimm(HOST_CCREG,-CLOCK_DIVIDER*stubs[n][3],HOST_CCREG); if(stubs[n][6]==TAKEN) { if(internal_branch(branch_regs[i].is32,ba[i])) load_needed_regs(branch_regs[i].regmap,regs[(ba[i]-start)>>2].regmap_entry); else if(itype[i]==RJUMP) { if(get_reg(branch_regs[i].regmap,RTEMP)>=0) emit_readword((int)&pcaddr,get_reg(branch_regs[i].regmap,RTEMP)); else emit_loadreg(rs1[i],get_reg(branch_regs[i].regmap,rs1[i])); } }else if(stubs[n][6]==NOTTAKEN) { if(iregmap; #endif if(i==(ba[i]-start)>>2) assem_debug("idle loop"); address_generation(i+1,i_regs,regs[i].regmap_entry); #ifdef REG_PREFETCH int temp=get_reg(branch_regs[i].regmap,PTEMP); if(rt1[i]==31&&temp>=0) { int return_address=start+i*4+8; if(get_reg(branch_regs[i].regmap,31)>0) if(i_regmap[temp]==PTEMP) emit_movimm((int)hash_table[((return_address>>16)^return_address)&0xFFFF],temp); } #endif ds_assemble(i+1,i_regs); uint64_t bc_unneeded=branch_regs[i].u; uint64_t bc_unneeded_upper=branch_regs[i].uu; bc_unneeded|=1|(1LL<=0); return_address=start+i*4+8; if(rt>=0) { #ifdef USE_MINI_HT if(internal_branch(branch_regs[i].is32,return_address)) { int temp=rt+1; if(temp==EXCLUDE_REG||temp>=HOST_REGS|| branch_regs[i].regmap[temp]>=0) { temp=get_reg(branch_regs[i].regmap,-1); } #ifdef HOST_TEMPREG if(temp<0) temp=HOST_TEMPREG; #endif if(temp>=0) do_miniht_insert(return_address,rt,temp); else emit_movimm(return_address,rt); } else #endif { #ifdef REG_PREFETCH if(temp>=0) { if(i_regmap[temp]!=PTEMP) emit_movimm((int)hash_table[((return_address>>16)^return_address)&0xFFFF],temp); } #endif emit_movimm(return_address,rt); // PC into link register #ifdef IMM_PREFETCH emit_prefetch(hash_table[((return_address>>16)^return_address)&0xFFFF]); #endif } } } int cc,adj; cc=get_reg(branch_regs[i].regmap,CCREG); assert(cc==HOST_CCREG); store_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]); #ifdef REG_PREFETCH if(rt1[i]==31&&temp>=0) emit_prefetchreg(temp); #endif do_cc(i,branch_regs[i].regmap,&adj,ba[i],TAKEN,0); if(adj) emit_addimm(cc,CLOCK_DIVIDER*(ccadj[i]+2-adj),cc); load_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]); if(internal_branch(branch_regs[i].is32,ba[i])) assem_debug("branch: internal"); else assem_debug("branch: external"); if(internal_branch(branch_regs[i].is32,ba[i])&&is_ds[(ba[i]-start)>>2]) { ds_assemble_entry(i); } else { add_to_linker((intptr_t)out,ba[i],internal_branch(branch_regs[i].is32,ba[i])); emit_jmp(0); } } static void rjump_assemble(int i,struct regstat *i_regs) { #ifdef REG_PREFETCH signed char *i_regmap=i_regs->regmap; #endif int temp; int rs,cc; rs=get_reg(branch_regs[i].regmap,rs1[i]); assert(rs>=0); if(rs1[i]==rt1[i+1]||rs1[i]==rt2[i+1]) { // Delay slot abuse, make a copy of the branch address register temp=get_reg(branch_regs[i].regmap,RTEMP); assert(temp>=0); assert(regs[i].regmap[temp]==RTEMP); emit_mov(rs,temp); rs=temp; } address_generation(i+1,i_regs,regs[i].regmap_entry); #ifdef REG_PREFETCH if(rt1[i]==31) { if((temp=get_reg(branch_regs[i].regmap,PTEMP))>=0) { int return_address=start+i*4+8; if(i_regmap[temp]==PTEMP) emit_movimm((int)hash_table[((return_address>>16)^return_address)&0xFFFF],temp); } } #endif #ifdef USE_MINI_HT if(rs1[i]==31) { int rh=get_reg(regs[i].regmap,RHASH); if(rh>=0) do_preload_rhash(rh); } #endif ds_assemble(i+1,i_regs); uint64_t bc_unneeded=branch_regs[i].u; uint64_t bc_unneeded_upper=branch_regs[i].uu; bc_unneeded|=1|(1LL<=0); return_address=start+i*4+8; #ifdef REG_PREFETCH if(temp>=0) { if(i_regmap[temp]!=PTEMP) emit_movimm((int)hash_table[((return_address>>16)^return_address)&0xFFFF],temp); } #endif emit_movimm(return_address,rt); // PC into link register #ifdef IMM_PREFETCH emit_prefetch(hash_table[((return_address>>16)^return_address)&0xFFFF]); #endif } cc=get_reg(branch_regs[i].regmap,CCREG); assert(cc==HOST_CCREG); #ifdef USE_MINI_HT int rh=get_reg(branch_regs[i].regmap,RHASH); int ht=get_reg(branch_regs[i].regmap,RHTBL); if(rs1[i]==31) { if(regs[i].regmap[rh]!=RHASH) do_preload_rhash(rh); do_preload_rhtbl(ht); do_rhash(rs,rh); } #endif store_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,-1); #ifdef DESTRUCTIVE_WRITEBACK if((branch_regs[i].dirty>>rs)&(branch_regs[i].is32>>rs1[i])&1) { if(rs1[i]!=rt1[i+1]&&rs1[i]!=rt2[i+1]) { emit_loadreg(rs1[i],rs); } } #endif #ifdef REG_PREFETCH if(rt1[i]==31&&temp>=0) emit_prefetchreg(temp); #endif #ifdef USE_MINI_HT if(rs1[i]==31) { do_miniht_load(ht,rh); } #endif //do_cc(i,branch_regs[i].regmap,&adj,-1,TAKEN); //if(adj) emit_addimm(cc,2*(ccadj[i]+2-adj),cc); // ??? - Shouldn't happen //assert(adj==0); emit_addimm_and_set_flags(CLOCK_DIVIDER*(ccadj[i]+2),HOST_CCREG); add_stub(CC_STUB,(int)out,jump_vaddr_reg[rs],0,i,-1,TAKEN,0); emit_jns(0); //load_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,-1); #ifdef USE_MINI_HT if(rs1[i]==31) { do_miniht_jump(rs,rh,ht); } else #endif { //if(rs!=EAX) emit_mov(rs,EAX); //emit_jmp((int)jump_vaddr_eax); emit_jmp(jump_vaddr_reg[rs]); } /* Check hash table temp=!rs; emit_mov(rs,temp); emit_shrimm(rs,16,rs); emit_xor(temp,rs,rs); emit_movzwl_reg(rs,rs); emit_shlimm(rs,4,rs); emit_cmpmem_indexed((int)hash_table,rs,temp); emit_jne((int)out+14); emit_readword_indexed((int)hash_table+4,rs,rs); emit_jmpreg(rs); emit_cmpmem_indexed((int)hash_table+8,rs,temp); emit_addimm_no_flags(8,rs); emit_jeq((int)out-17); // No hit on hash table, call compiler emit_pushreg(temp); //DEBUG > #ifdef DEBUG_CYCLE_COUNT emit_readword((int)&last_count,ECX); emit_add(HOST_CCREG,ECX,HOST_CCREG); emit_readword((int)&next_interupt,ECX); emit_writeword(HOST_CCREG,(int)&g_cp0_regs[CP0_COUNT_REG]); emit_sub(HOST_CCREG,ECX,HOST_CCREG); emit_writeword(ECX,(int)&last_count); #endif //DEBUG < emit_storereg(CCREG,HOST_CCREG); emit_call((int)get_addr); emit_loadreg(CCREG,HOST_CCREG); emit_addimm(ESP,4,ESP); emit_jmpreg(EAX);*/ #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK if(rt1[i]!=31&&iregmap; int cc; int match; match=match_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]); assem_debug("match=%d",match); int s1h,s1l,s2h,s2l; int prev_cop1_usable=cop1_usable; int unconditional=0,nop=0; int only32=0; int invert=0; int internal=internal_branch(branch_regs[i].is32,ba[i]); if(i==(ba[i]-start)>>2) assem_debug("idle loop"); if(!match) invert=1; #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK if(i>(ba[i]-start)>>2) invert=1; #endif if(ooo[i]) { s1l=get_reg(branch_regs[i].regmap,rs1[i]); s1h=get_reg(branch_regs[i].regmap,rs1[i]|64); s2l=get_reg(branch_regs[i].regmap,rs2[i]); s2h=get_reg(branch_regs[i].regmap,rs2[i]|64); } else { s1l=get_reg(i_regmap,rs1[i]); s1h=get_reg(i_regmap,rs1[i]|64); s2l=get_reg(i_regmap,rs2[i]); s2h=get_reg(i_regmap,rs2[i]|64); } if(rs1[i]==0&&rs2[i]==0) { if(opcode[i]&1) nop=1; else unconditional=1; //assert(opcode[i]!=5); //assert(opcode[i]!=7); //assert(opcode[i]!=0x15); //assert(opcode[i]!=0x17); } else if(rs1[i]==0) { s1l=s2l;s1h=s2h; s2l=s2h=-1; only32=(regs[i].was32>>rs2[i])&1; } else if(rs2[i]==0) { s2l=s2h=-1; only32=(regs[i].was32>>rs1[i])&1; } else { only32=(regs[i].was32>>rs1[i])&(regs[i].was32>>rs2[i])&1; } if(ooo[i]) { // Out of order execution (delay slot first) //DebugMessage(M64MSG_VERBOSE, "OOOE"); address_generation(i+1,i_regs,regs[i].regmap_entry); ds_assemble(i+1,i_regs); int adj; uint64_t bc_unneeded=branch_regs[i].u; uint64_t bc_unneeded_upper=branch_regs[i].uu; bc_unneeded&=~((1LL<>2 || source[i+1]!=0) { if(adj) emit_addimm(cc,CLOCK_DIVIDER*(ccadj[i]+2-adj),cc); load_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]); if(internal) assem_debug("branch: internal"); else assem_debug("branch: external"); if(internal&&is_ds[(ba[i]-start)>>2]) { ds_assemble_entry(i); } else { add_to_linker((intptr_t)out,ba[i],internal); emit_jmp(0); } #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK if(((u_int)out)&7) emit_addnop(0); #endif } } else if(nop) { emit_addimm_and_set_flags(CLOCK_DIVIDER*(ccadj[i]+2),cc); int jaddr=(int)out; emit_jns(0); add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,NOTTAKEN,0); } else { int taken=0,nottaken=0,nottaken1=0; do_cc(i,branch_regs[i].regmap,&adj,-1,0,invert); if(adj&&!invert) emit_addimm(cc,CLOCK_DIVIDER*(ccadj[i]+2-adj),cc); if(!only32) { assert(s1h>=0); if(opcode[i]==4) // BEQ { if(s2h>=0) emit_cmp(s1h,s2h); else emit_test(s1h,s1h); nottaken1=(int)out; emit_jne(1); } if(opcode[i]==5) // BNE { if(s2h>=0) emit_cmp(s1h,s2h); else emit_test(s1h,s1h); if(invert) taken=(int)out; else add_to_linker((intptr_t)out,ba[i],internal); emit_jne(0); } if(opcode[i]==6) // BLEZ { emit_test(s1h,s1h); if(invert) taken=(int)out; else add_to_linker((intptr_t)out,ba[i],internal); emit_js(0); nottaken1=(int)out; emit_jne(1); } if(opcode[i]==7) // BGTZ { emit_test(s1h,s1h); nottaken1=(int)out; emit_js(1); if(invert) taken=(int)out; else add_to_linker((intptr_t)out,ba[i],internal); emit_jne(0); } } // if(!only32) //DebugMessage(M64MSG_VERBOSE, "branch(%d): eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d",i,branch_regs[i].regmap[0],branch_regs[i].regmap[1],branch_regs[i].regmap[2],branch_regs[i].regmap[3],branch_regs[i].regmap[5],branch_regs[i].regmap[6],branch_regs[i].regmap[7]); assert(s1l>=0); if(opcode[i]==4) // BEQ { if(s2l>=0) emit_cmp(s1l,s2l); else emit_test(s1l,s1l); if(invert){ nottaken=(int)out; emit_jne(1); }else{ add_to_linker((intptr_t)out,ba[i],internal); emit_jeq(0); } } if(opcode[i]==5) // BNE { if(s2l>=0) emit_cmp(s1l,s2l); else emit_test(s1l,s1l); if(invert){ nottaken=(int)out; emit_jeq(1); }else{ add_to_linker((int)out,ba[i],internal); emit_jne(0); } } if(opcode[i]==6) // BLEZ { emit_cmpimm(s1l,1); if(invert){ nottaken=(int)out; if(only32) emit_jge(1); else emit_jae(1); }else{ add_to_linker((int)out,ba[i],internal); if(only32) emit_jl(0); else emit_jb(0); } } if(opcode[i]==7) // BGTZ { emit_cmpimm(s1l,1); if(invert){ nottaken=(int)out; if(only32) emit_jl(1); else emit_jb(1); }else{ add_to_linker((int)out,ba[i],internal); emit_jae(0); } } if(invert) { if(taken) set_jump_target(taken,(int)out); #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK if(match&&(!internal||!is_ds[(ba[i]-start)>>2])) { if(adj) { emit_addimm(cc,-CLOCK_DIVIDER*adj,cc); add_to_linker((int)out,ba[i],internal); }else{ emit_addnop(13); add_to_linker((int)out,ba[i],internal*2); } emit_jmp(0); }else #endif { if(adj) emit_addimm(cc,-CLOCK_DIVIDER*adj,cc); store_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]); load_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]); if(internal) assem_debug("branch: internal"); else assem_debug("branch: external"); if(internal&&is_ds[(ba[i]-start)>>2]) { ds_assemble_entry(i); } else { add_to_linker((int)out,ba[i],internal); emit_jmp(0); } } set_jump_target(nottaken,(int)out); } if(nottaken1) set_jump_target(nottaken1,(int)out); if(adj) { if(!invert) emit_addimm(cc,CLOCK_DIVIDER*adj,cc); } } // (!unconditional) } // if(ooo) else { // In-order execution (branch first) //if(likely[i]) DebugMessage(M64MSG_VERBOSE, "IOL"); //else //DebugMessage(M64MSG_VERBOSE, "IOE"); int taken=0,nottaken=0,nottaken1=0; if(!unconditional&&!nop) { if(!only32) { assert(s1h>=0); if((opcode[i]&0x2f)==4) // BEQ { if(s2h>=0) emit_cmp(s1h,s2h); else emit_test(s1h,s1h); nottaken1=(int)out; emit_jne(2); } if((opcode[i]&0x2f)==5) // BNE { if(s2h>=0) emit_cmp(s1h,s2h); else emit_test(s1h,s1h); taken=(int)out; emit_jne(1); } if((opcode[i]&0x2f)==6) // BLEZ { emit_test(s1h,s1h); taken=(int)out; emit_js(1); nottaken1=(int)out; emit_jne(2); } if((opcode[i]&0x2f)==7) // BGTZ { emit_test(s1h,s1h); nottaken1=(int)out; emit_js(2); taken=(int)out; emit_jne(1); } } // if(!only32) //DebugMessage(M64MSG_VERBOSE, "branch(%d): eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d",i,branch_regs[i].regmap[0],branch_regs[i].regmap[1],branch_regs[i].regmap[2],branch_regs[i].regmap[3],branch_regs[i].regmap[5],branch_regs[i].regmap[6],branch_regs[i].regmap[7]); assert(s1l>=0); if((opcode[i]&0x2f)==4) // BEQ { if(s2l>=0) emit_cmp(s1l,s2l); else emit_test(s1l,s1l); nottaken=(int)out; emit_jne(2); } if((opcode[i]&0x2f)==5) // BNE { if(s2l>=0) emit_cmp(s1l,s2l); else emit_test(s1l,s1l); nottaken=(int)out; emit_jeq(2); } if((opcode[i]&0x2f)==6) // BLEZ { emit_cmpimm(s1l,1); nottaken=(int)out; if(only32) emit_jge(2); else emit_jae(2); } if((opcode[i]&0x2f)==7) // BGTZ { emit_cmpimm(s1l,1); nottaken=(int)out; if(only32) emit_jl(2); else emit_jb(2); } } // if(!unconditional) int adj; uint64_t ds_unneeded=branch_regs[i].u; uint64_t ds_unneeded_upper=branch_regs[i].uu; ds_unneeded&=~((1LL<>rt1[i+1])&1) ds_unneeded_upper&=~((1LL<>2]) { ds_assemble_entry(i); } else { add_to_linker((int)out,ba[i],internal); emit_jmp(0); } } // branch not taken cop1_usable=prev_cop1_usable; if(!unconditional) { if(nottaken1) set_jump_target(nottaken1,(int)out); set_jump_target(nottaken,(int)out); assem_debug("2:"); if(!likely[i]) { wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,regs[i].is32, ds_unneeded,ds_unneeded_upper); load_regs(regs[i].regmap,branch_regs[i].regmap,regs[i].was32,rs1[i+1],rs2[i+1]); address_generation(i+1,&branch_regs[i],0); load_regs(regs[i].regmap,branch_regs[i].regmap,regs[i].was32,CCREG,CCREG); ds_assemble(i+1,&branch_regs[i]); } cc=get_reg(branch_regs[i].regmap,CCREG); if(cc==-1&&!likely[i]) { // Cycle count isn't in a register, temporarily load it then write it out emit_loadreg(CCREG,HOST_CCREG); emit_addimm_and_set_flags(CLOCK_DIVIDER*(ccadj[i]+2),HOST_CCREG); int jaddr=(int)out; emit_jns(0); add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,NOTTAKEN,0); emit_storereg(CCREG,HOST_CCREG); } else{ cc=get_reg(i_regmap,CCREG); assert(cc==HOST_CCREG); emit_addimm_and_set_flags(CLOCK_DIVIDER*(ccadj[i]+2),cc); int jaddr=(int)out; emit_jns(0); add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,likely[i]?NULLDS:NOTTAKEN,0); } } } } static void sjump_assemble(int i,struct regstat *i_regs) { signed char *i_regmap=i_regs->regmap; int cc; int match; match=match_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]); assem_debug("smatch=%d",match); int s1h,s1l; int prev_cop1_usable=cop1_usable; int unconditional=0,nevertaken=0; int only32=0; int invert=0; int internal=internal_branch(branch_regs[i].is32,ba[i]); if(i==(ba[i]-start)>>2) assem_debug("idle loop"); if(!match) invert=1; #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK if(i>(ba[i]-start)>>2) invert=1; #endif //if(opcode2[i]>=0x10) return; // FIXME (BxxZAL) assert(opcode2[i]<0x10||rs1[i]==0); // FIXME (BxxZAL) if(ooo[i]) { s1l=get_reg(branch_regs[i].regmap,rs1[i]); s1h=get_reg(branch_regs[i].regmap,rs1[i]|64); } else { s1l=get_reg(i_regmap,rs1[i]); s1h=get_reg(i_regmap,rs1[i]|64); } if(rs1[i]==0) { if(opcode2[i]&1) unconditional=1; else nevertaken=1; // These are never taken (r0 is never less than zero) //assert(opcode2[i]!=0); //assert(opcode2[i]!=2); //assert(opcode2[i]!=0x10); //assert(opcode2[i]!=0x12); } else { only32=(regs[i].was32>>rs1[i])&1; } if(ooo[i]) { // Out of order execution (delay slot first) //DebugMessage(M64MSG_VERBOSE, "OOOE"); address_generation(i+1,i_regs,regs[i].regmap_entry); ds_assemble(i+1,i_regs); int adj; uint64_t bc_unneeded=branch_regs[i].u; uint64_t bc_unneeded_upper=branch_regs[i].uu; bc_unneeded&=~((1LL<=0) { // Save the PC even if the branch is not taken return_address=start+i*4+8; emit_movimm(return_address,rt); // PC into link register #ifdef IMM_PREFETCH if(!nevertaken) emit_prefetch(hash_table[((return_address>>16)^return_address)&0xFFFF]); #endif } } cc=get_reg(branch_regs[i].regmap,CCREG); assert(cc==HOST_CCREG); if(unconditional) store_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]); //do_cc(i,branch_regs[i].regmap,&adj,unconditional?ba[i]:-1,unconditional); assem_debug("cycle count (adj)"); if(unconditional) { do_cc(i,branch_regs[i].regmap,&adj,ba[i],TAKEN,0); if(i!=(ba[i]-start)>>2 || source[i+1]!=0) { if(adj) emit_addimm(cc,CLOCK_DIVIDER*(ccadj[i]+2-adj),cc); load_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]); if(internal) assem_debug("branch: internal"); else assem_debug("branch: external"); if(internal&&is_ds[(ba[i]-start)>>2]) { ds_assemble_entry(i); } else { add_to_linker((int)out,ba[i],internal); emit_jmp(0); } #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK if(((u_int)out)&7) emit_addnop(0); #endif } } else if(nevertaken) { emit_addimm_and_set_flags(CLOCK_DIVIDER*(ccadj[i]+2),cc); int jaddr=(int)out; emit_jns(0); add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,NOTTAKEN,0); } else { int nottaken=0; do_cc(i,branch_regs[i].regmap,&adj,-1,0,invert); if(adj&&!invert) emit_addimm(cc,CLOCK_DIVIDER*(ccadj[i]+2-adj),cc); if(!only32) { assert(s1h>=0); if(opcode2[i]==0) // BLTZ { emit_test(s1h,s1h); if(invert){ nottaken=(int)out; emit_jns(1); }else{ add_to_linker((int)out,ba[i],internal); emit_js(0); } } if(opcode2[i]==1) // BGEZ { emit_test(s1h,s1h); if(invert){ nottaken=(int)out; emit_js(1); }else{ add_to_linker((int)out,ba[i],internal); emit_jns(0); } } } // if(!only32) else { assert(s1l>=0); if(opcode2[i]==0) // BLTZ { emit_test(s1l,s1l); if(invert){ nottaken=(int)out; emit_jns(1); }else{ add_to_linker((int)out,ba[i],internal); emit_js(0); } } if(opcode2[i]==1) // BGEZ { emit_test(s1l,s1l); if(invert){ nottaken=(int)out; emit_js(1); }else{ add_to_linker((int)out,ba[i],internal); emit_jns(0); } } } // if(!only32) if(invert) { #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK if(match&&(!internal||!is_ds[(ba[i]-start)>>2])) { if(adj) { emit_addimm(cc,-CLOCK_DIVIDER*adj,cc); add_to_linker((int)out,ba[i],internal); }else{ emit_addnop(13); add_to_linker((int)out,ba[i],internal*2); } emit_jmp(0); }else #endif { if(adj) emit_addimm(cc,-CLOCK_DIVIDER*adj,cc); store_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]); load_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]); if(internal) assem_debug("branch: internal"); else assem_debug("branch: external"); if(internal&&is_ds[(ba[i]-start)>>2]) { ds_assemble_entry(i); } else { add_to_linker((int)out,ba[i],internal); emit_jmp(0); } } set_jump_target(nottaken,(int)out); } if(adj) { if(!invert) emit_addimm(cc,CLOCK_DIVIDER*adj,cc); } } // (!unconditional) } // if(ooo) else { // In-order execution (branch first) //DebugMessage(M64MSG_VERBOSE, "IOE"); int nottaken=0; if(!unconditional) { //DebugMessage(M64MSG_VERBOSE, "branch(%d): eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d",i,branch_regs[i].regmap[0],branch_regs[i].regmap[1],branch_regs[i].regmap[2],branch_regs[i].regmap[3],branch_regs[i].regmap[5],branch_regs[i].regmap[6],branch_regs[i].regmap[7]); if(!only32) { assert(s1h>=0); if((opcode2[i]&0x1d)==0) // BLTZ/BLTZL { emit_test(s1h,s1h); nottaken=(int)out; emit_jns(1); } if((opcode2[i]&0x1d)==1) // BGEZ/BGEZL { emit_test(s1h,s1h); nottaken=(int)out; emit_js(1); } } // if(!only32) else { assert(s1l>=0); if((opcode2[i]&0x1d)==0) // BLTZ/BLTZL { emit_test(s1l,s1l); nottaken=(int)out; emit_jns(1); } if((opcode2[i]&0x1d)==1) // BGEZ/BGEZL { emit_test(s1l,s1l); nottaken=(int)out; emit_js(1); } } } // if(!unconditional) int adj; uint64_t ds_unneeded=branch_regs[i].u; uint64_t ds_unneeded_upper=branch_regs[i].uu; ds_unneeded&=~((1LL<>rt1[i+1])&1) ds_unneeded_upper&=~((1LL<>2]) { ds_assemble_entry(i); } else { add_to_linker((int)out,ba[i],internal); emit_jmp(0); } } // branch not taken cop1_usable=prev_cop1_usable; if(!unconditional) { set_jump_target(nottaken,(int)out); assem_debug("1:"); if(!likely[i]) { wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,regs[i].is32, ds_unneeded,ds_unneeded_upper); load_regs(regs[i].regmap,branch_regs[i].regmap,regs[i].was32,rs1[i+1],rs2[i+1]); address_generation(i+1,&branch_regs[i],0); load_regs(regs[i].regmap,branch_regs[i].regmap,regs[i].was32,CCREG,CCREG); ds_assemble(i+1,&branch_regs[i]); } cc=get_reg(branch_regs[i].regmap,CCREG); if(cc==-1&&!likely[i]) { // Cycle count isn't in a register, temporarily load it then write it out emit_loadreg(CCREG,HOST_CCREG); emit_addimm_and_set_flags(CLOCK_DIVIDER*(ccadj[i]+2),HOST_CCREG); int jaddr=(int)out; emit_jns(0); add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,NOTTAKEN,0); emit_storereg(CCREG,HOST_CCREG); } else{ cc=get_reg(i_regmap,CCREG); assert(cc==HOST_CCREG); emit_addimm_and_set_flags(CLOCK_DIVIDER*(ccadj[i]+2),cc); int jaddr=(int)out; emit_jns(0); add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,likely[i]?NULLDS:NOTTAKEN,0); } } } } static void fjump_assemble(int i,struct regstat *i_regs) { signed char *i_regmap=i_regs->regmap; int cc; int match; match=match_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]); assem_debug("fmatch=%d",match); int fs,cs; int eaddr; int invert=0; int internal=internal_branch(branch_regs[i].is32,ba[i]); if(i==(ba[i]-start)>>2) assem_debug("idle loop"); if(!match) invert=1; #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK if(i>(ba[i]-start)>>2) invert=1; #endif if(ooo[i]) { fs=get_reg(branch_regs[i].regmap,FSREG); address_generation(i+1,i_regs,regs[i].regmap_entry); // Is this okay? } else { fs=get_reg(i_regmap,FSREG); } // Check cop1 unusable if(!cop1_usable) { cs=get_reg(i_regmap,CSREG); assert(cs>=0); emit_testimm(cs,0x20000000); eaddr=(int)out; emit_jeq(0); add_stub(FP_STUB,eaddr,(int)out,i,cs,(int)i_regs,0,0); cop1_usable=1; } if(ooo[i]) { // Out of order execution (delay slot first) //DebugMessage(M64MSG_VERBOSE, "OOOE"); ds_assemble(i+1,i_regs); int adj; uint64_t bc_unneeded=branch_regs[i].u; uint64_t bc_unneeded_upper=branch_regs[i].uu; bc_unneeded&=~((1LL<=0); emit_testimm(fs,0x800000); if(source[i]&0x10000) // BC1T { if(invert){ nottaken=(int)out; emit_jeq(1); }else{ add_to_linker((int)out,ba[i],internal); emit_jne(0); } } else // BC1F if(invert){ nottaken=(int)out; emit_jne(1); }else{ add_to_linker((int)out,ba[i],internal); emit_jeq(0); } { } } // if(!only32) if(invert) { if(adj) emit_addimm(cc,-CLOCK_DIVIDER*adj,cc); #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK else if(match) emit_addnop(13); #endif store_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]); load_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]); if(internal) assem_debug("branch: internal"); else assem_debug("branch: external"); if(internal&&is_ds[(ba[i]-start)>>2]) { ds_assemble_entry(i); } else { add_to_linker((int)out,ba[i],internal); emit_jmp(0); } set_jump_target(nottaken,(int)out); } if(adj) { if(!invert) emit_addimm(cc,CLOCK_DIVIDER*adj,cc); } } // (!unconditional) } // if(ooo) else { // In-order execution (branch first) //DebugMessage(M64MSG_VERBOSE, "IOE"); int nottaken=0; if(1) { //DebugMessage(M64MSG_VERBOSE, "branch(%d): eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d",i,branch_regs[i].regmap[0],branch_regs[i].regmap[1],branch_regs[i].regmap[2],branch_regs[i].regmap[3],branch_regs[i].regmap[5],branch_regs[i].regmap[6],branch_regs[i].regmap[7]); if(1) { assert(fs>=0); emit_testimm(fs,0x800000); if(source[i]&0x10000) // BC1T { nottaken=(int)out; emit_jeq(1); } else // BC1F { nottaken=(int)out; emit_jne(1); } } } // if(!unconditional) int adj; uint64_t ds_unneeded=branch_regs[i].u; uint64_t ds_unneeded_upper=branch_regs[i].uu; ds_unneeded&=~((1LL<>rt1[i+1])&1) ds_unneeded_upper&=~((1LL<>2]) { ds_assemble_entry(i); } else { add_to_linker((int)out,ba[i],internal); emit_jmp(0); } // branch not taken if(1) { // <- FIXME (don't need this) set_jump_target(nottaken,(int)out); assem_debug("1:"); if(!likely[i]) { wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,regs[i].is32, ds_unneeded,ds_unneeded_upper); load_regs(regs[i].regmap,branch_regs[i].regmap,regs[i].was32,rs1[i+1],rs2[i+1]); address_generation(i+1,&branch_regs[i],0); load_regs(regs[i].regmap,branch_regs[i].regmap,regs[i].was32,CCREG,CCREG); ds_assemble(i+1,&branch_regs[i]); } cc=get_reg(branch_regs[i].regmap,CCREG); if(cc==-1&&!likely[i]) { // Cycle count isn't in a register, temporarily load it then write it out emit_loadreg(CCREG,HOST_CCREG); emit_addimm_and_set_flags(CLOCK_DIVIDER*(ccadj[i]+2),HOST_CCREG); int jaddr=(int)out; emit_jns(0); add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,NOTTAKEN,0); emit_storereg(CCREG,HOST_CCREG); } else{ cc=get_reg(i_regmap,CCREG); assert(cc==HOST_CCREG); emit_addimm_and_set_flags(CLOCK_DIVIDER*(ccadj[i]+2),cc); int jaddr=(int)out; emit_jns(0); add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,likely[i]?NULLDS:NOTTAKEN,0); } } } } static void pagespan_assemble(int i,struct regstat *i_regs) { int s1l=get_reg(i_regs->regmap,rs1[i]); int s1h=get_reg(i_regs->regmap,rs1[i]|64); int s2l=get_reg(i_regs->regmap,rs2[i]); int s2h=get_reg(i_regs->regmap,rs2[i]|64); int taken=0; int nottaken=0; int unconditional=0; if(rs1[i]==0) { s1l=s2l;s1h=s2h; s2l=s2h=-1; } else if(rs2[i]==0) { s2l=s2h=-1; } if((i_regs->is32>>rs1[i])&(i_regs->is32>>rs2[i])&1) { s1h=s2h=-1; } int hr=0; int addr,alt,ntaddr; if(i_regs->regmap[HOST_BTREG]<0) {addr=HOST_BTREG;} else { while(hrregmap[hr]&63)!=rs1[i] && (i_regs->regmap[hr]&63)!=rs2[i] ) { addr=hr++;break; } hr++; } } while(hrregmap[hr]&63)!=rs1[i] && (i_regs->regmap[hr]&63)!=rs2[i] ) { alt=hr++;break; } hr++; } if((opcode[i]&0x2E)==6) // BLEZ/BGTZ needs another register { while(hrregmap[hr]&63)!=rs1[i] && (i_regs->regmap[hr]&63)!=rs2[i] ) { ntaddr=hr;break; } hr++; } } assert(hrregmap,31); emit_movimm(start+i*4+8,rt); unconditional=1; } if(opcode[i]==0&&(opcode2[i]&0x3E)==8) // JR/JALR { emit_mov(s1l,addr); if(opcode2[i]==9) // JALR { int rt=get_reg(i_regs->regmap,rt1[i]); emit_movimm(start+i*4+8,rt); } } if((opcode[i]&0x3f)==4) // BEQ { if(rs1[i]==rs2[i]) { unconditional=1; } else #ifdef HAVE_CMOV_IMM if(s1h<0) { if(s2l>=0) emit_cmp(s1l,s2l); else emit_test(s1l,s1l); emit_cmov2imm_e_ne_compact(ba[i],start+i*4+8,addr); } else #endif { assert(s1l>=0); emit_mov2imm_compact(ba[i],addr,start+i*4+8,alt); if(s1h>=0) { if(s2h>=0) emit_cmp(s1h,s2h); else emit_test(s1h,s1h); emit_cmovne_reg(alt,addr); } if(s2l>=0) emit_cmp(s1l,s2l); else emit_test(s1l,s1l); emit_cmovne_reg(alt,addr); } } if((opcode[i]&0x3f)==5) // BNE { #ifdef HAVE_CMOV_IMM if(s1h<0) { if(s2l>=0) emit_cmp(s1l,s2l); else emit_test(s1l,s1l); emit_cmov2imm_e_ne_compact(start+i*4+8,ba[i],addr); } else #endif { assert(s1l>=0); emit_mov2imm_compact(start+i*4+8,addr,ba[i],alt); if(s1h>=0) { if(s2h>=0) emit_cmp(s1h,s2h); else emit_test(s1h,s1h); emit_cmovne_reg(alt,addr); } if(s2l>=0) emit_cmp(s1l,s2l); else emit_test(s1l,s1l); emit_cmovne_reg(alt,addr); } } if((opcode[i]&0x3f)==0x14) // BEQL { if(s1h>=0) { if(s2h>=0) emit_cmp(s1h,s2h); else emit_test(s1h,s1h); nottaken=(int)out; emit_jne(0); } if(s2l>=0) emit_cmp(s1l,s2l); else emit_test(s1l,s1l); if(nottaken) set_jump_target(nottaken,(int)out); nottaken=(int)out; emit_jne(0); } if((opcode[i]&0x3f)==0x15) // BNEL { if(s1h>=0) { if(s2h>=0) emit_cmp(s1h,s2h); else emit_test(s1h,s1h); taken=(int)out; emit_jne(0); } if(s2l>=0) emit_cmp(s1l,s2l); else emit_test(s1l,s1l); nottaken=(int)out; emit_jeq(0); if(taken) set_jump_target(taken,(int)out); } if((opcode[i]&0x3f)==6) // BLEZ { emit_mov2imm_compact(ba[i],alt,start+i*4+8,addr); emit_cmpimm(s1l,1); if(s1h>=0) emit_mov(addr,ntaddr); emit_cmovl_reg(alt,addr); if(s1h>=0) { emit_test(s1h,s1h); emit_cmovne_reg(ntaddr,addr); emit_cmovs_reg(alt,addr); } } if((opcode[i]&0x3f)==7) // BGTZ { emit_mov2imm_compact(ba[i],addr,start+i*4+8,ntaddr); emit_cmpimm(s1l,1); if(s1h>=0) emit_mov(addr,alt); emit_cmovl_reg(ntaddr,addr); if(s1h>=0) { emit_test(s1h,s1h); emit_cmovne_reg(alt,addr); emit_cmovs_reg(ntaddr,addr); } } if((opcode[i]&0x3f)==0x16) // BLEZL { assert((opcode[i]&0x3f)!=0x16); } if((opcode[i]&0x3f)==0x17) // BGTZL { assert((opcode[i]&0x3f)!=0x17); } assert(opcode[i]!=1); // BLTZ/BGEZ //FIXME: Check CSREG if(opcode[i]==0x11 && opcode2[i]==0x08 ) { if((source[i]&0x30000)==0) // BC1F { emit_mov2imm_compact(ba[i],addr,start+i*4+8,alt); emit_testimm(s1l,0x800000); emit_cmovne_reg(alt,addr); } if((source[i]&0x30000)==0x10000) // BC1T { emit_mov2imm_compact(ba[i],alt,start+i*4+8,addr); emit_testimm(s1l,0x800000); emit_cmovne_reg(alt,addr); } if((source[i]&0x30000)==0x20000) // BC1FL { emit_testimm(s1l,0x800000); nottaken=(int)out; emit_jne(0); } if((source[i]&0x30000)==0x30000) // BC1TL { emit_testimm(s1l,0x800000); nottaken=(int)out; emit_jeq(0); } } assert(i_regs->regmap[HOST_CCREG]==CCREG); wb_dirtys(regs[i].regmap,regs[i].is32,regs[i].dirty); if(likely[i]||unconditional) { emit_movimm(ba[i],HOST_BTREG); } else if(addr!=HOST_BTREG) { emit_mov(addr,HOST_BTREG); } void *branch_addr=out; emit_jmp(0); int target_addr=start+i*4+5; void *stub=out; void *compiled_target_addr=check_addr(target_addr); emit_extjump_ds((int)branch_addr,target_addr); if(compiled_target_addr) { set_jump_target((int)branch_addr,(int)compiled_target_addr); add_link(target_addr,stub); } else set_jump_target((int)branch_addr,(int)stub); if(likely[i]) { // Not-taken path set_jump_target((int)nottaken,(int)out); wb_dirtys(regs[i].regmap,regs[i].is32,regs[i].dirty); void *branch_addr=out; emit_jmp(0); int target_addr=start+i*4+8; void *stub=out; void *compiled_target_addr=check_addr(target_addr); emit_extjump_ds((int)branch_addr,target_addr); if(compiled_target_addr) { set_jump_target((int)branch_addr,(int)compiled_target_addr); add_link(target_addr,stub); } else set_jump_target((int)branch_addr,(int)stub); } } // Assemble the delay slot for the above static void pagespan_ds() { assem_debug("initial delay slot:"); u_int vaddr=start+1; u_int page=(0x80000000^vaddr)>>12; u_int vpage=page; if(page>262143&&tlb_LUT_r[vaddr>>12]) page=(tlb_LUT_r[page^0x80000]^0x80000000)>>12; if(page>2048) page=2048+(page&2047); if(vpage>262143&&tlb_LUT_r[vaddr>>12]) vpage&=2047; // jump_dirty uses a hash of the virtual address instead if(vpage>2048) vpage=2048+(vpage&2047); ll_add(jump_dirty+vpage,vaddr,(void *)out); do_dirty_stub_ds(); ll_add(jump_in+page,vaddr,(void *)out); assert(regs[0].regmap_entry[HOST_CCREG]==CCREG); if(regs[0].regmap[HOST_CCREG]!=CCREG) wb_register(CCREG,regs[0].regmap_entry,regs[0].wasdirty,regs[0].was32); if(regs[0].regmap[HOST_BTREG]!=BTREG) emit_writeword(HOST_BTREG,(int)&branch_target); load_regs(regs[0].regmap_entry,regs[0].regmap,regs[0].was32,rs1[0],rs2[0]); address_generation(0,®s[0],regs[0].regmap_entry); if(itype[0]==LOAD||itype[0]==LOADLR||itype[0]==STORE||itype[0]==STORELR||itype[0]==C1LS) load_regs(regs[0].regmap_entry,regs[0].regmap,regs[0].was32,MMREG,ROREG); if(itype[0]==STORE||itype[0]==STORELR||(opcode[0]&0x3b)==0x39) load_regs(regs[0].regmap_entry,regs[0].regmap,regs[0].was32,INVCP,INVCP); cop1_usable=0; is_delayslot=0; switch(itype[0]) { case ALU: alu_assemble(0,®s[0]);break; case IMM16: imm16_assemble(0,®s[0]);break; case SHIFT: shift_assemble(0,®s[0]);break; case SHIFTIMM: shiftimm_assemble(0,®s[0]);break; case LOAD: load_assemble(0,®s[0]);break; case LOADLR: loadlr_assemble(0,®s[0]);break; case STORE: store_assemble(0,®s[0]);break; case STORELR: storelr_assemble(0,®s[0]);break; case COP0: cop0_assemble(0,®s[0]);break; case COP1: cop1_assemble(0,®s[0]);break; case C1LS: c1ls_assemble(0,®s[0]);break; case FCONV: fconv_assemble(0,®s[0]);break; case FLOAT: float_assemble(0,®s[0]);break; case FCOMP: fcomp_assemble(0,®s[0]);break; case MULTDIV: multdiv_assemble(0,®s[0]);break; case MOV: mov_assemble(0,®s[0]);break; case SYSCALL: case SPAN: case UJUMP: case RJUMP: case CJUMP: case SJUMP: case FJUMP: DebugMessage(M64MSG_VERBOSE, "Jump in the delay slot. This is probably a bug."); } int btaddr=get_reg(regs[0].regmap,BTREG); if(btaddr<0) { btaddr=get_reg(regs[0].regmap,-1); emit_readword((int)&branch_target,btaddr); } assert(btaddr!=HOST_CCREG); if(regs[0].regmap[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG); #ifdef HOST_IMM8 emit_movimm(start+4,HOST_TEMPREG); emit_cmp(btaddr,HOST_TEMPREG); #else emit_cmpimm(btaddr,start+4); #endif int branch=(int)out; emit_jeq(0); store_regs_bt(regs[0].regmap,regs[0].is32,regs[0].dirty,-1); emit_jmp(jump_vaddr_reg[btaddr]); set_jump_target(branch,(int)out); store_regs_bt(regs[0].regmap,regs[0].is32,regs[0].dirty,start+4); load_regs_bt(regs[0].regmap,regs[0].is32,regs[0].dirty,start+4); } // Basic liveness analysis for MIPS registers static void unneeded_registers(int istart,int iend,int r) { int i; uint64_t u,uu,b,bu; uint64_t temp_u,temp_uu; uint64_t tdep; if(iend==slen-1) { u=1;uu=1; }else{ u=unneeded_reg[iend+1]; uu=unneeded_reg_upper[iend+1]; u=1;uu=1; } for (i=iend;i>=istart;i--) { //DebugMessage(M64MSG_VERBOSE, "unneeded registers i=%d (%d,%d) r=%d",i,istart,iend,r); if(itype[i]==RJUMP||itype[i]==UJUMP||itype[i]==CJUMP||itype[i]==SJUMP||itype[i]==FJUMP) { // If subroutine call, flag return address as a possible branch target if(rt1[i]==31 && i=(start+slen*4)) { // Branch out of this block, flush all regs u=1; uu=1; /* Hexagon hack if(itype[i]==UJUMP&&rt1[i]==31) { uu=u=0x300C00F; // Discard at, v0-v1, t6-t9 } if(itype[i]==RJUMP&&rs1[i]==31) { uu=u=0x300C0F3; // Discard at, a0-a3, t6-t9 } if(start>0x80000400&&start<0x80800000) { if(itype[i]==UJUMP&&rt1[i]==31) { //uu=u=0x30300FF0FLL; // Discard at, v0-v1, t0-t9, lo, hi uu=u=0x300FF0F; // Discard at, v0-v1, t0-t9 } if(itype[i]==RJUMP&&rs1[i]==31) { //uu=u=0x30300FFF3LL; // Discard at, a0-a3, t0-t9, lo, hi uu=u=0x300FFF3; // Discard at, a0-a3, t0-t9 } }*/ branch_unneeded_reg[i]=u; branch_unneeded_reg_upper[i]=uu; // Merge in delay slot tdep=(~uu>>rt1[i+1])&1; u|=(1LL<>2]=1; if(ba[i]<=start+i*4) { // Backward branch if(itype[i]==RJUMP||itype[i]==UJUMP||(source[i]>>16)==0x1000) { // Unconditional branch temp_u=1;temp_uu=1; } else { // Conditional branch (not taken case) temp_u=unneeded_reg[i+2]; temp_uu=unneeded_reg_upper[i+2]; } // Merge in delay slot tdep=(~temp_uu>>rt1[i+1])&1; temp_u|=(1LL<>rt1[i])&1; temp_u|=(1LL<>2,i-1,r+1); }else{ unneeded_reg[(ba[i]-start)>>2]=1; unneeded_reg_upper[(ba[i]-start)>>2]=1; } } /*else*/ if(1) { if(itype[i]==RJUMP||itype[i]==UJUMP||(source[i]>>16)==0x1000) { // Unconditional branch u=unneeded_reg[(ba[i]-start)>>2]; uu=unneeded_reg_upper[(ba[i]-start)>>2]; branch_unneeded_reg[i]=u; branch_unneeded_reg_upper[i]=uu; //u=1; //uu=1; //branch_unneeded_reg[i]=u; //branch_unneeded_reg_upper[i]=uu; // Merge in delay slot tdep=(~uu>>rt1[i+1])&1; u|=(1LL<>2]; bu=unneeded_reg_upper[(ba[i]-start)>>2]; branch_unneeded_reg[i]=b; branch_unneeded_reg_upper[i]=bu; //b=1; //bu=1; //branch_unneeded_reg[i]=b; //branch_unneeded_reg_upper[i]=bu; // Branch delay slot tdep=(~uu>>rt1[i+1])&1; b|=(1LL<>rt1[i])&1; // Written registers are unneeded u|=1LL<>r)&1) { if(r==HIREG) DebugMessage(M64MSG_VERBOSE, " HI"); else if(r==LOREG) DebugMessage(M64MSG_VERBOSE, " LO"); else DebugMessage(M64MSG_VERBOSE, " r%d",r); } } DebugMessage(M64MSG_VERBOSE, " UU:"); for(r=1;r<=CCREG;r++) { if(((unneeded_reg_upper[i]&~unneeded_reg[i])>>r)&1) { if(r==HIREG) DebugMessage(M64MSG_VERBOSE, " HI"); else if(r==LOREG) DebugMessage(M64MSG_VERBOSE, " LO"); else DebugMessage(M64MSG_VERBOSE, " r%d",r); } }*/ } } // Identify registers which are likely to contain 32-bit values // This is used to predict whether any branches will jump to a // location with 64-bit values in registers. static void provisional_32bit() { int i,j; uint64_t is32=1; uint64_t lastbranch=1; for(i=0;i0) { if(itype[i-1]==CJUMP||itype[i-1]==SJUMP||itype[i-1]==FJUMP) { if(i>1) is32=lastbranch; else is32=1; } } if(i>1) { if(itype[i-2]==CJUMP||itype[i-2]==SJUMP||itype[i-2]==FJUMP) { if(likely[i-2]) { if(i>2) is32=lastbranch; else is32=1; } } if((opcode[i-2]&0x2f)==0x05) // BNE/BNEL { if(rs1[i-2]==0||rs2[i-2]==0) { if(rs1[i-2]) { is32|=1LL<=0;j--) { if(ba[j]==start+i*4) //temp_is32&=branch_regs[j].is32; temp_is32&=p32[j]; } for(j=i;j>s1)&1LL)<>s1)&1LL); is32&=~(1LL<=0x20&&op2<=0x23) { // ADD/ADDU/SUB/SUBU is32|=1LL<=0x24&&op2<=0x27) { // AND/OR/XOR/NOR uint64_t sr=((is32>>s1)&(is32>>s2)&1LL); is32&=~(1LL<=0x2c&&op2<=0x2d) { // DADD/DADDU if(s1==0&&s2==0) { is32|=1LL<>s1)&1LL); is32&=~(1LL<>s2)&1LL); is32&=~(1LL<=0x2e&&op2<=0x2f) { // DSUB/DSUBU if(s1==0&&s2==0) { is32|=1LL<>s1)&1LL); is32&=~(1LL<=0x1c&&op2<=0x1f) { // DMULT/DMULTU/DDIV/DDIVU is32&=~((1LL<>s1)&1LL); is32&=~(1LL<=0x14&&op2<=0x17) is32&=~(1LL<=0x38&&op2<0x3f) is32&=~(1LL<0) { if(itype[i-1]==UJUMP||itype[i-1]==RJUMP||(source[i-1]>>16)==0x1000) { if(rt1[i-1]==31) // JAL/JALR { // Subroutine call will return here, don't alloc any registers is32=1; } else if(i+1=0;i--) { int hr; if(itype[i]==RJUMP||itype[i]==UJUMP||itype[i]==CJUMP||itype[i]==SJUMP||itype[i]==FJUMP) { if(ba[i]=(start+slen*4)) { // Branch out of this block, don't need anything r32=0; } else { // Internal branch // Need whatever matches the target // (and doesn't get overwritten by the delay slot instruction) r32=0; int t=(ba[i]-start)>>2; if(ba[i]>start+i*4) { // Forward branch //if(!(requires_32bit[t]&~regs[i].was32)) // r32|=requires_32bit[t]&(~(1LL<>16)!=0x1000) { if(i0) { if((regs[i].was32>>us1[i+1])&1) r32|=1LL<0) { if((regs[i].was32>>us2[i+1])&1) r32|=1LL<>dep1[i+1])&1)) { if((regs[i].was32>>dep1[i+1])&1) r32|=1LL<>dep2[i+1])&1)) { if((regs[i].was32>>dep2[i+1])&1) r32|=1LL<0) { if((regs[i].was32>>us1[i])&1) r32|=1LL<0) { if((regs[i].was32>>us2[i])&1) r32|=1LL<>dep1[i])&1)) { if((regs[i].was32>>dep1[i])&1) r32|=1LL<>dep2[i])&1)) { if((regs[i].was32>>dep2[i])&1) r32|=1LL<0&®s[i].regmap_entry[hr]<64) { if((regs[i].was32>>regs[i].regmap_entry[hr])&(regs[i].wasdirty>>hr)&1) { if(!((unneeded_reg_upper[i]>>regs[i].regmap_entry[hr])&1)) pr32[i]|=1LL<=istart;i--) { if(itype[i]==RJUMP||itype[i]==UJUMP||itype[i]==CJUMP||itype[i]==SJUMP||itype[i]==FJUMP) { if(ba[i]=(start+slen*4)) { // Branch out of this block, flush all regs if(itype[i]==RJUMP||itype[i]==UJUMP||(source[i]>>16)==0x1000) { // Unconditional branch will_dirty_i=0; wont_dirty_i=0; // Merge in delay slot (will dirty) for(r=0;r33) will_dirty_i&=~(1<33) will_dirty_i&=~(1<33) will_dirty_i&=~(1<33) will_dirty_i&=~(1<>16)==0x1000) { // Unconditional branch temp_will_dirty=0; temp_wont_dirty=0; // Merge in delay slot (will dirty) for(r=0;r33) temp_will_dirty&=~(1<33) temp_will_dirty&=~(1<33) temp_will_dirty&=~(1<33) temp_will_dirty&=~(1<0 && (regmap_pre[i][r]&63)<34) { temp_will_dirty|=((unneeded_reg[i]>>(regmap_pre[i][r]&63))&1)<>(regmap_pre[i][r]&63))&1)<>2,i-1,0); }else{ // Limit recursion. It can take an excessive amount // of time if there are a lot of nested loops. will_dirty[(ba[i]-start)>>2]=0; wont_dirty[(ba[i]-start)>>2]=-1; } } /*else*/ if(1) { if(itype[i]==RJUMP||itype[i]==UJUMP||(source[i]>>16)==0x1000) { // Unconditional branch will_dirty_i=0; wont_dirty_i=0; //if(ba[i]>start+i*4) { // Disable recursion (for debugging) for(r=0;r>2].regmap_entry[r]) { will_dirty_i|=will_dirty[(ba[i]-start)>>2]&(1<>2]&(1<=0) { will_dirty_i|=((unneeded_reg[(ba[i]-start)>>2]>>(branch_regs[i].regmap[r]&63))&1)<>2]>>(branch_regs[i].regmap[r]&63))&1)<33) will_dirty_i&=~(1<33) will_dirty_i&=~(1<start+i*4) { // Disable recursion (for debugging) for(r=0;r>2].regmap_entry[r]) { will_dirty_i&=will_dirty[(ba[i]-start)>>2]&(1<>2]&(1<=0) { will_dirty_i&=((unneeded_reg[(ba[i]-start)>>2]>>(target_reg&63))&1)<>2]>>(target_reg&63))&1)<>2].regmap_entry[r]) { will_dirty[i+1]&=will_dirty[(ba[i]-start)>>2]&(1<>2]&(1<33) will_dirty_i&=~(1<33) will_dirty_i&=~(1<33) will_dirty_i&=~(1<istart) { if(itype[i]!=RJUMP&&itype[i]!=UJUMP&&itype[i]!=CJUMP&&itype[i]!=SJUMP&&itype[i]!=FJUMP) { // Don't store a register immediately after writing it, // may prevent dual-issue. if((regs[i].regmap[r]&63)==rt1[i-1]) wont_dirty_i|=1<>r)&1) { DebugMessage(M64MSG_VERBOSE, " r%d",r); } }*/ //if(i==istart||(itype[i-1]!=RJUMP&&itype[i-1]!=UJUMP&&itype[i-1]!=CJUMP&&itype[i-1]!=SJUMP&&itype[i-1]!=FJUMP)) { regs[i].dirty|=will_dirty_i; #ifndef DESTRUCTIVE_WRITEBACK regs[i].dirty&=wont_dirty_i; if(itype[i]==RJUMP||itype[i]==UJUMP||itype[i]==CJUMP||itype[i]==SJUMP||itype[i]==FJUMP) { if(i>16)!=0x1000) { for(r=0;r>r)&1));*/} } } } } else { if(i>r)&1));*/} } } } } #endif //} } // Deal with changed mappings temp_will_dirty=will_dirty_i; temp_wont_dirty=wont_dirty_i; for(r=0;r=0) { // Register moved to a different register will_dirty_i&=~(1<>nr)&1)<>nr)&1)<0 && (regmap_pre[i][r]&63)<34) { will_dirty_i|=((unneeded_reg[i]>>(regmap_pre[i][r]&63))&1)<>(regmap_pre[i][r]&63))&1)<>r)&1));*/ } } } } } } #ifdef ASSEM_DEBUG /* disassembly */ static void disassemble_inst(int i) { if (bt[i]) DebugMessage(M64MSG_VERBOSE, "*"); else DebugMessage(M64MSG_VERBOSE, " "); switch(itype[i]) { case UJUMP: printf (" %x: %s %8x",start+i*4,insn[i],ba[i]);break; case CJUMP: printf (" %x: %s r%d,r%d,%8x",start+i*4,insn[i],rs1[i],rs2[i],i?start+i*4+4+((signed int)((unsigned int)source[i]<<16)>>14):*ba);break; case SJUMP: printf (" %x: %s r%d,%8x",start+i*4,insn[i],rs1[i],start+i*4+4+((signed int)((unsigned int)source[i]<<16)>>14));break; case FJUMP: printf (" %x: %s %8x",start+i*4,insn[i],ba[i]);break; case RJUMP: if ((opcode2[i]&1)&&rt1[i]!=31) printf (" %x: %s r%d,r%d",start+i*4,insn[i],rt1[i],rs1[i]); else printf (" %x: %s r%d",start+i*4,insn[i],rs1[i]); break; case SPAN: printf (" %x: %s (pagespan) r%d,r%d,%8x",start+i*4,insn[i],rs1[i],rs2[i],ba[i]);break; case IMM16: if(opcode[i]==0xf) //LUI printf (" %x: %s r%d,%4x0000",start+i*4,insn[i],rt1[i],imm[i]&0xffff); else printf (" %x: %s r%d,r%d,%d",start+i*4,insn[i],rt1[i],rs1[i],imm[i]); break; case LOAD: case LOADLR: printf (" %x: %s r%d,r%d+%x",start+i*4,insn[i],rt1[i],rs1[i],imm[i]); break; case STORE: case STORELR: printf (" %x: %s r%d,r%d+%x",start+i*4,insn[i],rs2[i],rs1[i],imm[i]); break; case ALU: case SHIFT: printf (" %x: %s r%d,r%d,r%d",start+i*4,insn[i],rt1[i],rs1[i],rs2[i]); break; case MULTDIV: printf (" %x: %s r%d,r%d",start+i*4,insn[i],rs1[i],rs2[i]); break; case SHIFTIMM: printf (" %x: %s r%d,r%d,%d",start+i*4,insn[i],rt1[i],rs1[i],imm[i]); break; case MOV: if((opcode2[i]&0x1d)==0x10) printf (" %x: %s r%d",start+i*4,insn[i],rt1[i]); else if((opcode2[i]&0x1d)==0x11) printf (" %x: %s r%d",start+i*4,insn[i],rs1[i]); else printf (" %x: %s",start+i*4,insn[i]); break; case COP0: if(opcode2[i]==0) printf (" %x: %s r%d,cpr0[%d]",start+i*4,insn[i],rt1[i],(source[i]>>11)&0x1f); // MFC0 else if(opcode2[i]==4) printf (" %x: %s r%d,cpr0[%d]",start+i*4,insn[i],rs1[i],(source[i]>>11)&0x1f); // MTC0 else printf (" %x: %s",start+i*4,insn[i]); break; case COP1: if(opcode2[i]<3) printf (" %x: %s r%d,cpr1[%d]",start+i*4,insn[i],rt1[i],(source[i]>>11)&0x1f); // MFC1 else if(opcode2[i]>3) printf (" %x: %s r%d,cpr1[%d]",start+i*4,insn[i],rs1[i],(source[i]>>11)&0x1f); // MTC1 else printf (" %x: %s",start+i*4,insn[i]); break; case C1LS: printf (" %x: %s cpr1[%d],r%d+%x",start+i*4,insn[i],(source[i]>>16)&0x1f,rs1[i],imm[i]); break; default: //printf (" %s %8x",insn[i],source[i]); printf (" %x: %s",start+i*4,insn[i]); } } #endif // Fix crash with Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn) and ARM // Do not make this static #ifdef __clang__ __attribute__ ((noinline)) void new_dynarec_init_mem_map(u_int rdrami) { int n; for(n=0;n<524288;n++) // 0 .. 0x7FFFFFFF memory_map[n]=-1; for(n=524288;n<526336;n++) // 0x80000000 .. 0x807FFFFF memory_map[n]=(rdrami-0x80000000)>>2; for(n=526336;n<1048576;n++) // 0x80800000 .. 0xFFFFFFFF memory_map[n]=-1; } #endif void new_dynarec_init() { int n; printf("Init new dynarec\n"); #if NEW_DYNAREC == NEW_DYNAREC_ARM if ((base_addr = mmap ((u_char *)BASE_ADDR, 1<>2; for(n=526336;n<1048576;n++) // 0x80800000 .. 0xFFFFFFFF memory_map[n]=-1; #else new_dynarec_init_mem_map((u_int)g_rdram); #endif for(n=0;n<0x8000;n++) { // 0 .. 0x7FFFFFFF writemem[n] = write_nomem_new; writememb[n] = write_nomemb_new; writememh[n] = write_nomemh_new; writememd[n] = write_nomemd_new; readmem[n] = read_nomem_new; readmemb[n] = read_nomemb_new; readmemh[n] = read_nomemh_new; readmemd[n] = read_nomemd_new; } for(n=0x8000;n<0x8080;n++) { // 0x80000000 .. 0x807FFFFF writemem[n] = write_rdram_new; writememb[n] = write_rdramb_new; writememh[n] = write_rdramh_new; writememd[n] = write_rdramd_new; } for(n=0xC000;n<0x10000;n++) { // 0xC0000000 .. 0xFFFFFFFF writemem[n] = write_nomem_new; writememb[n] = write_nomemb_new; writememh[n] = write_nomemh_new; writememd[n] = write_nomemd_new; readmem[n] = read_nomem_new; readmemb[n] = read_nomemb_new; readmemh[n] = read_nomemh_new; readmemd[n] = read_nomemd_new; } #ifndef DISABLE_TLB tlb_hacks(); #endif arch_init(); } void new_dynarec_cleanup(void) { int n; if (munmap (base_addr, 1< %x", (int)addr, (int)out); #if defined (COUNT_NOTCOMPILEDS ) notcompiledCount++; log_message( "notcompiledCount=%i", notcompiledCount ); #endif //DebugMessage(M64MSG_VERBOSE, "NOTCOMPILED: addr = %x -> %x", (int)addr, (int)out); //DebugMessage(M64MSG_VERBOSE, "TRACE: count=%d next=%d (compile %x)",g_cp0_regs[CP0_COUNT_REG],next_interupt,addr); //if(debug) //DebugMessage(M64MSG_VERBOSE, "TRACE: count=%d next=%d (checksum %x)",g_cp0_regs[CP0_COUNT_REG],next_interupt,mchecksum()); //DebugMessage(M64MSG_VERBOSE, "fpu mapping=%x enabled=%x",(g_cp0_regs[CP0_STATUS_REG] & 0x04000000)>>26,(g_cp0_regs[CP0_STATUS_REG] & 0x20000000)>>29); /*if(g_cp0_regs[CP0_COUNT_REG]>=312978186) { rlist(); }*/ //rlist(); start = (u_int)addr&~3; //assert(((u_int)addr&1)==0); if ((int)addr >= 0xa4000000 && (int)addr < 0xa4001000) { source = (u_int *)((u_int)g_sp.mem + start-0xa4000000); pagelimit = 0xa4001000; } else if ((int)addr >= 0x80000000 && (int)addr < 0x80800000) { source = (u_int *)((u_int)g_rdram+start-0x80000000); pagelimit = 0x80800000; } else if ((signed int)addr >= (signed int)0xC0000000) { //DebugMessage(M64MSG_VERBOSE, "addr=%x mm=%x",(u_int)addr,(memory_map[start>>12]<<2)); //if(tlb_LUT_r[start>>12]) //source = (u_int *)(((int)g_rdram)+(tlb_LUT_r[start>>12]&0xFFFFF000)+(((int)addr)&0xFFF)-0x80000000); if((signed int)memory_map[start>>12]>=0) { source = (u_int *)((u_int)(start+(memory_map[start>>12]<<2))); pagelimit=(start+4096)&0xFFFFF000; int map=memory_map[start>>12]; int i; for(i=0;i<5;i++) { //DebugMessage(M64MSG_VERBOSE, "start: %x next: %x",map,memory_map[pagelimit>>12]); if((map&0xBFFFFFFF)==(memory_map[pagelimit>>12]&0xBFFFFFFF)) pagelimit+=4096; } assem_debug("pagelimit=%x",pagelimit); assem_debug("mapping=%x (%x)",memory_map[start>>12],(memory_map[start>>12]<<2)+start); } else { assem_debug("Compile at unmapped memory address: %x ", (int)addr); //assem_debug("start: %x next: %x",memory_map[start>>12],memory_map[(start+4096)>>12]); return 1; // Caller will invoke exception handler } //DebugMessage(M64MSG_VERBOSE, "source= %x",(int)source); } else { //DebugMessage(M64MSG_VERBOSE, "Compile at bogus memory address: %x ", (int)addr); log_message("Compile at bogus memory address: %x", (int)addr); exit(1); } /* Pass 1: disassemble */ /* Pass 2: register dependencies, branch targets */ /* Pass 3: register allocation */ /* Pass 4: branch dependencies */ /* Pass 5: pre-alloc */ /* Pass 6: optimize clean/dirty state */ /* Pass 7: flag 32-bit registers */ /* Pass 8: assembly */ /* Pass 9: linker */ /* Pass 10: garbage collection / free memory */ //printf("addr = %x source = %x %x", addr,source,source[0]); /* Pass 1 disassembly */ for(i=0;!done;i++) { bt[i]=0;likely[i]=0;ooo[i]=0;op2=0; minimum_free_regs[i]=0; opcode[i]=op=source[i]>>26; switch(op) { case 0x00: strcpy(insn[i],"special"); type=NI; op2=source[i]&0x3f; switch(op2) { case 0x00: strcpy(insn[i],"SLL"); type=SHIFTIMM; break; case 0x02: strcpy(insn[i],"SRL"); type=SHIFTIMM; break; case 0x03: strcpy(insn[i],"SRA"); type=SHIFTIMM; break; case 0x04: strcpy(insn[i],"SLLV"); type=SHIFT; break; case 0x06: strcpy(insn[i],"SRLV"); type=SHIFT; break; case 0x07: strcpy(insn[i],"SRAV"); type=SHIFT; break; case 0x08: strcpy(insn[i],"JR"); type=RJUMP; break; case 0x09: strcpy(insn[i],"JALR"); type=RJUMP; break; case 0x0C: strcpy(insn[i],"SYSCALL"); type=SYSCALL; break; case 0x0D: strcpy(insn[i],"BREAK"); type=OTHER; break; case 0x0F: strcpy(insn[i],"SYNC"); type=OTHER; break; case 0x10: strcpy(insn[i],"MFHI"); type=MOV; break; case 0x11: strcpy(insn[i],"MTHI"); type=MOV; break; case 0x12: strcpy(insn[i],"MFLO"); type=MOV; break; case 0x13: strcpy(insn[i],"MTLO"); type=MOV; break; case 0x14: strcpy(insn[i],"DSLLV"); type=SHIFT; break; case 0x16: strcpy(insn[i],"DSRLV"); type=SHIFT; break; case 0x17: strcpy(insn[i],"DSRAV"); type=SHIFT; break; case 0x18: strcpy(insn[i],"MULT"); type=MULTDIV; break; case 0x19: strcpy(insn[i],"MULTU"); type=MULTDIV; break; case 0x1A: strcpy(insn[i],"DIV"); type=MULTDIV; break; case 0x1B: strcpy(insn[i],"DIVU"); type=MULTDIV; break; case 0x1C: strcpy(insn[i],"DMULT"); type=MULTDIV; break; case 0x1D: strcpy(insn[i],"DMULTU"); type=MULTDIV; break; case 0x1E: strcpy(insn[i],"DDIV"); type=MULTDIV; break; case 0x1F: strcpy(insn[i],"DDIVU"); type=MULTDIV; break; case 0x20: strcpy(insn[i],"ADD"); type=ALU; break; case 0x21: strcpy(insn[i],"ADDU"); type=ALU; break; case 0x22: strcpy(insn[i],"SUB"); type=ALU; break; case 0x23: strcpy(insn[i],"SUBU"); type=ALU; break; case 0x24: strcpy(insn[i],"AND"); type=ALU; break; case 0x25: strcpy(insn[i],"OR"); type=ALU; break; case 0x26: strcpy(insn[i],"XOR"); type=ALU; break; case 0x27: strcpy(insn[i],"NOR"); type=ALU; break; case 0x2A: strcpy(insn[i],"SLT"); type=ALU; break; case 0x2B: strcpy(insn[i],"SLTU"); type=ALU; break; case 0x2C: strcpy(insn[i],"DADD"); type=ALU; break; case 0x2D: strcpy(insn[i],"DADDU"); type=ALU; break; case 0x2E: strcpy(insn[i],"DSUB"); type=ALU; break; case 0x2F: strcpy(insn[i],"DSUBU"); type=ALU; break; case 0x30: strcpy(insn[i],"TGE"); type=NI; break; case 0x31: strcpy(insn[i],"TGEU"); type=NI; break; case 0x32: strcpy(insn[i],"TLT"); type=NI; break; case 0x33: strcpy(insn[i],"TLTU"); type=NI; break; case 0x34: strcpy(insn[i],"TEQ"); type=NI; break; case 0x36: strcpy(insn[i],"TNE"); type=NI; break; case 0x38: strcpy(insn[i],"DSLL"); type=SHIFTIMM; break; case 0x3A: strcpy(insn[i],"DSRL"); type=SHIFTIMM; break; case 0x3B: strcpy(insn[i],"DSRA"); type=SHIFTIMM; break; case 0x3C: strcpy(insn[i],"DSLL32"); type=SHIFTIMM; break; case 0x3E: strcpy(insn[i],"DSRL32"); type=SHIFTIMM; break; case 0x3F: strcpy(insn[i],"DSRA32"); type=SHIFTIMM; break; } break; case 0x01: strcpy(insn[i],"regimm"); type=NI; op2=(source[i]>>16)&0x1f; switch(op2) { case 0x00: strcpy(insn[i],"BLTZ"); type=SJUMP; break; case 0x01: strcpy(insn[i],"BGEZ"); type=SJUMP; break; case 0x02: strcpy(insn[i],"BLTZL"); type=SJUMP; break; case 0x03: strcpy(insn[i],"BGEZL"); type=SJUMP; break; case 0x08: strcpy(insn[i],"TGEI"); type=NI; break; case 0x09: strcpy(insn[i],"TGEIU"); type=NI; break; case 0x0A: strcpy(insn[i],"TLTI"); type=NI; break; case 0x0B: strcpy(insn[i],"TLTIU"); type=NI; break; case 0x0C: strcpy(insn[i],"TEQI"); type=NI; break; case 0x0E: strcpy(insn[i],"TNEI"); type=NI; break; case 0x10: strcpy(insn[i],"BLTZAL"); type=SJUMP; break; case 0x11: strcpy(insn[i],"BGEZAL"); type=SJUMP; break; case 0x12: strcpy(insn[i],"BLTZALL"); type=SJUMP; break; case 0x13: strcpy(insn[i],"BGEZALL"); type=SJUMP; break; } break; case 0x02: strcpy(insn[i],"J"); type=UJUMP; break; case 0x03: strcpy(insn[i],"JAL"); type=UJUMP; break; case 0x04: strcpy(insn[i],"BEQ"); type=CJUMP; break; case 0x05: strcpy(insn[i],"BNE"); type=CJUMP; break; case 0x06: strcpy(insn[i],"BLEZ"); type=CJUMP; break; case 0x07: strcpy(insn[i],"BGTZ"); type=CJUMP; break; case 0x08: strcpy(insn[i],"ADDI"); type=IMM16; break; case 0x09: strcpy(insn[i],"ADDIU"); type=IMM16; break; case 0x0A: strcpy(insn[i],"SLTI"); type=IMM16; break; case 0x0B: strcpy(insn[i],"SLTIU"); type=IMM16; break; case 0x0C: strcpy(insn[i],"ANDI"); type=IMM16; break; case 0x0D: strcpy(insn[i],"ORI"); type=IMM16; break; case 0x0E: strcpy(insn[i],"XORI"); type=IMM16; break; case 0x0F: strcpy(insn[i],"LUI"); type=IMM16; break; case 0x10: strcpy(insn[i],"cop0"); type=NI; op2=(source[i]>>21)&0x1f; switch(op2) { case 0x00: strcpy(insn[i],"MFC0"); type=COP0; break; case 0x04: strcpy(insn[i],"MTC0"); type=COP0; break; case 0x10: strcpy(insn[i],"tlb"); type=NI; switch(source[i]&0x3f) { case 0x01: strcpy(insn[i],"TLBR"); type=COP0; break; case 0x02: strcpy(insn[i],"TLBWI"); type=COP0; break; case 0x06: strcpy(insn[i],"TLBWR"); type=COP0; break; case 0x08: strcpy(insn[i],"TLBP"); type=COP0; break; case 0x18: strcpy(insn[i],"ERET"); type=COP0; break; } } break; case 0x11: strcpy(insn[i],"cop1"); type=NI; op2=(source[i]>>21)&0x1f; switch(op2) { case 0x00: strcpy(insn[i],"MFC1"); type=COP1; break; case 0x01: strcpy(insn[i],"DMFC1"); type=COP1; break; case 0x02: strcpy(insn[i],"CFC1"); type=COP1; break; case 0x04: strcpy(insn[i],"MTC1"); type=COP1; break; case 0x05: strcpy(insn[i],"DMTC1"); type=COP1; break; case 0x06: strcpy(insn[i],"CTC1"); type=COP1; break; case 0x08: strcpy(insn[i],"BC1"); type=FJUMP; switch((source[i]>>16)&0x3) { case 0x00: strcpy(insn[i],"BC1F"); break; case 0x01: strcpy(insn[i],"BC1T"); break; case 0x02: strcpy(insn[i],"BC1FL"); break; case 0x03: strcpy(insn[i],"BC1TL"); break; } break; case 0x10: strcpy(insn[i],"C1.S"); type=NI; switch(source[i]&0x3f) { case 0x00: strcpy(insn[i],"ADD.S"); type=FLOAT; break; case 0x01: strcpy(insn[i],"SUB.S"); type=FLOAT; break; case 0x02: strcpy(insn[i],"MUL.S"); type=FLOAT; break; case 0x03: strcpy(insn[i],"DIV.S"); type=FLOAT; break; case 0x04: strcpy(insn[i],"SQRT.S"); type=FLOAT; break; case 0x05: strcpy(insn[i],"ABS.S"); type=FLOAT; break; case 0x06: strcpy(insn[i],"MOV.S"); type=FLOAT; break; case 0x07: strcpy(insn[i],"NEG.S"); type=FLOAT; break; case 0x08: strcpy(insn[i],"ROUND.L.S"); type=FCONV; break; case 0x09: strcpy(insn[i],"TRUNC.L.S"); type=FCONV; break; case 0x0A: strcpy(insn[i],"CEIL.L.S"); type=FCONV; break; case 0x0B: strcpy(insn[i],"FLOOR.L.S"); type=FCONV; break; case 0x0C: strcpy(insn[i],"ROUND.W.S"); type=FCONV; break; case 0x0D: strcpy(insn[i],"TRUNC.W.S"); type=FCONV; break; case 0x0E: strcpy(insn[i],"CEIL.W.S"); type=FCONV; break; case 0x0F: strcpy(insn[i],"FLOOR.W.S"); type=FCONV; break; case 0x21: strcpy(insn[i],"CVT.D.S"); type=FCONV; break; case 0x24: strcpy(insn[i],"CVT.W.S"); type=FCONV; break; case 0x25: strcpy(insn[i],"CVT.L.S"); type=FCONV; break; case 0x30: strcpy(insn[i],"C.F.S"); type=FCOMP; break; case 0x31: strcpy(insn[i],"C.UN.S"); type=FCOMP; break; case 0x32: strcpy(insn[i],"C.EQ.S"); type=FCOMP; break; case 0x33: strcpy(insn[i],"C.UEQ.S"); type=FCOMP; break; case 0x34: strcpy(insn[i],"C.OLT.S"); type=FCOMP; break; case 0x35: strcpy(insn[i],"C.ULT.S"); type=FCOMP; break; case 0x36: strcpy(insn[i],"C.OLE.S"); type=FCOMP; break; case 0x37: strcpy(insn[i],"C.ULE.S"); type=FCOMP; break; case 0x38: strcpy(insn[i],"C.SF.S"); type=FCOMP; break; case 0x39: strcpy(insn[i],"C.NGLE.S"); type=FCOMP; break; case 0x3A: strcpy(insn[i],"C.SEQ.S"); type=FCOMP; break; case 0x3B: strcpy(insn[i],"C.NGL.S"); type=FCOMP; break; case 0x3C: strcpy(insn[i],"C.LT.S"); type=FCOMP; break; case 0x3D: strcpy(insn[i],"C.NGE.S"); type=FCOMP; break; case 0x3E: strcpy(insn[i],"C.LE.S"); type=FCOMP; break; case 0x3F: strcpy(insn[i],"C.NGT.S"); type=FCOMP; break; } break; case 0x11: strcpy(insn[i],"C1.D"); type=NI; switch(source[i]&0x3f) { case 0x00: strcpy(insn[i],"ADD.D"); type=FLOAT; break; case 0x01: strcpy(insn[i],"SUB.D"); type=FLOAT; break; case 0x02: strcpy(insn[i],"MUL.D"); type=FLOAT; break; case 0x03: strcpy(insn[i],"DIV.D"); type=FLOAT; break; case 0x04: strcpy(insn[i],"SQRT.D"); type=FLOAT; break; case 0x05: strcpy(insn[i],"ABS.D"); type=FLOAT; break; case 0x06: strcpy(insn[i],"MOV.D"); type=FLOAT; break; case 0x07: strcpy(insn[i],"NEG.D"); type=FLOAT; break; case 0x08: strcpy(insn[i],"ROUND.L.D"); type=FCONV; break; case 0x09: strcpy(insn[i],"TRUNC.L.D"); type=FCONV; break; case 0x0A: strcpy(insn[i],"CEIL.L.D"); type=FCONV; break; case 0x0B: strcpy(insn[i],"FLOOR.L.D"); type=FCONV; break; case 0x0C: strcpy(insn[i],"ROUND.W.D"); type=FCONV; break; case 0x0D: strcpy(insn[i],"TRUNC.W.D"); type=FCONV; break; case 0x0E: strcpy(insn[i],"CEIL.W.D"); type=FCONV; break; case 0x0F: strcpy(insn[i],"FLOOR.W.D"); type=FCONV; break; case 0x20: strcpy(insn[i],"CVT.S.D"); type=FCONV; break; case 0x24: strcpy(insn[i],"CVT.W.D"); type=FCONV; break; case 0x25: strcpy(insn[i],"CVT.L.D"); type=FCONV; break; case 0x30: strcpy(insn[i],"C.F.D"); type=FCOMP; break; case 0x31: strcpy(insn[i],"C.UN.D"); type=FCOMP; break; case 0x32: strcpy(insn[i],"C.EQ.D"); type=FCOMP; break; case 0x33: strcpy(insn[i],"C.UEQ.D"); type=FCOMP; break; case 0x34: strcpy(insn[i],"C.OLT.D"); type=FCOMP; break; case 0x35: strcpy(insn[i],"C.ULT.D"); type=FCOMP; break; case 0x36: strcpy(insn[i],"C.OLE.D"); type=FCOMP; break; case 0x37: strcpy(insn[i],"C.ULE.D"); type=FCOMP; break; case 0x38: strcpy(insn[i],"C.SF.D"); type=FCOMP; break; case 0x39: strcpy(insn[i],"C.NGLE.D"); type=FCOMP; break; case 0x3A: strcpy(insn[i],"C.SEQ.D"); type=FCOMP; break; case 0x3B: strcpy(insn[i],"C.NGL.D"); type=FCOMP; break; case 0x3C: strcpy(insn[i],"C.LT.D"); type=FCOMP; break; case 0x3D: strcpy(insn[i],"C.NGE.D"); type=FCOMP; break; case 0x3E: strcpy(insn[i],"C.LE.D"); type=FCOMP; break; case 0x3F: strcpy(insn[i],"C.NGT.D"); type=FCOMP; break; } break; case 0x14: strcpy(insn[i],"C1.W"); type=NI; switch(source[i]&0x3f) { case 0x20: strcpy(insn[i],"CVT.S.W"); type=FCONV; break; case 0x21: strcpy(insn[i],"CVT.D.W"); type=FCONV; break; } break; case 0x15: strcpy(insn[i],"C1.L"); type=NI; switch(source[i]&0x3f) { case 0x20: strcpy(insn[i],"CVT.S.L"); type=FCONV; break; case 0x21: strcpy(insn[i],"CVT.D.L"); type=FCONV; break; } break; } break; case 0x14: strcpy(insn[i],"BEQL"); type=CJUMP; break; case 0x15: strcpy(insn[i],"BNEL"); type=CJUMP; break; case 0x16: strcpy(insn[i],"BLEZL"); type=CJUMP; break; case 0x17: strcpy(insn[i],"BGTZL"); type=CJUMP; break; case 0x18: strcpy(insn[i],"DADDI"); type=IMM16; break; case 0x19: strcpy(insn[i],"DADDIU"); type=IMM16; break; case 0x1A: strcpy(insn[i],"LDL"); type=LOADLR; break; case 0x1B: strcpy(insn[i],"LDR"); type=LOADLR; break; case 0x20: strcpy(insn[i],"LB"); type=LOAD; break; case 0x21: strcpy(insn[i],"LH"); type=LOAD; break; case 0x22: strcpy(insn[i],"LWL"); type=LOADLR; break; case 0x23: strcpy(insn[i],"LW"); type=LOAD; break; case 0x24: strcpy(insn[i],"LBU"); type=LOAD; break; case 0x25: strcpy(insn[i],"LHU"); type=LOAD; break; case 0x26: strcpy(insn[i],"LWR"); type=LOADLR; break; case 0x27: strcpy(insn[i],"LWU"); type=LOAD; break; case 0x28: strcpy(insn[i],"SB"); type=STORE; break; case 0x29: strcpy(insn[i],"SH"); type=STORE; break; case 0x2A: strcpy(insn[i],"SWL"); type=STORELR; break; case 0x2B: strcpy(insn[i],"SW"); type=STORE; break; case 0x2C: strcpy(insn[i],"SDL"); type=STORELR; break; case 0x2D: strcpy(insn[i],"SDR"); type=STORELR; break; case 0x2E: strcpy(insn[i],"SWR"); type=STORELR; break; case 0x2F: strcpy(insn[i],"CACHE"); type=NOP; break; case 0x30: strcpy(insn[i],"LL"); type=NI; break; case 0x31: strcpy(insn[i],"LWC1"); type=C1LS; break; case 0x34: strcpy(insn[i],"LLD"); type=NI; break; case 0x35: strcpy(insn[i],"LDC1"); type=C1LS; break; case 0x37: strcpy(insn[i],"LD"); type=LOAD; break; case 0x38: strcpy(insn[i],"SC"); type=NI; break; case 0x39: strcpy(insn[i],"SWC1"); type=C1LS; break; case 0x3C: strcpy(insn[i],"SCD"); type=NI; break; case 0x3D: strcpy(insn[i],"SDC1"); type=C1LS; break; case 0x3F: strcpy(insn[i],"SD"); type=STORE; break; default: strcpy(insn[i],"???"); type=NI; break; } itype[i]=type; opcode2[i]=op2; /* Get registers/immediates */ lt1[i]=0; us1[i]=0; us2[i]=0; dep1[i]=0; dep2[i]=0; switch(type) { case LOAD: rs1[i]=(source[i]>>21)&0x1f; rs2[i]=0; rt1[i]=(source[i]>>16)&0x1f; rt2[i]=0; imm[i]=(short)source[i]; break; case STORE: case STORELR: rs1[i]=(source[i]>>21)&0x1f; rs2[i]=(source[i]>>16)&0x1f; rt1[i]=0; rt2[i]=0; imm[i]=(short)source[i]; if(op==0x2c||op==0x2d||op==0x3f) us1[i]=rs2[i]; // 64-bit SDL/SDR/SD break; case LOADLR: // LWL/LWR only load part of the register, // therefore the target register must be treated as a source too rs1[i]=(source[i]>>21)&0x1f; rs2[i]=(source[i]>>16)&0x1f; rt1[i]=(source[i]>>16)&0x1f; rt2[i]=0; imm[i]=(short)source[i]; if(op==0x1a||op==0x1b) us1[i]=rs2[i]; // LDR/LDL if(op==0x26) dep1[i]=rt1[i]; // LWR break; case IMM16: if (op==0x0f) rs1[i]=0; // LUI instruction has no source register else rs1[i]=(source[i]>>21)&0x1f; rs2[i]=0; rt1[i]=(source[i]>>16)&0x1f; rt2[i]=0; if(op>=0x0c&&op<=0x0e) { // ANDI/ORI/XORI imm[i]=(unsigned short)source[i]; }else{ imm[i]=(short)source[i]; } if(op==0x18||op==0x19) us1[i]=rs1[i]; // DADDI/DADDIU if(op==0x0a||op==0x0b) us1[i]=rs1[i]; // SLTI/SLTIU if(op==0x0d||op==0x0e) dep1[i]=rs1[i]; // ORI/XORI break; case UJUMP: rs1[i]=0; rs2[i]=0; rt1[i]=0; rt2[i]=0; // The JAL instruction writes to r31. if (op&1) rt1[i]=31; rs2[i]=CCREG; break; case RJUMP: rs1[i]=(source[i]>>21)&0x1f; rs2[i]=0; rt1[i]=0; rt2[i]=0; // The JALR instruction writes to rd. if (op2&1) { rt1[i]=(source[i]>>11)&0x1f; } rs2[i]=CCREG; break; case CJUMP: rs1[i]=(source[i]>>21)&0x1f; rs2[i]=(source[i]>>16)&0x1f; rt1[i]=0; rt2[i]=0; if(op&2) { // BGTZ/BLEZ rs2[i]=0; } us1[i]=rs1[i]; us2[i]=rs2[i]; likely[i]=op>>4; break; case SJUMP: rs1[i]=(source[i]>>21)&0x1f; rs2[i]=CCREG; rt1[i]=0; rt2[i]=0; us1[i]=rs1[i]; if(op2&0x10) { // BxxAL rt1[i]=31; // NOTE: If the branch is not taken, r31 is still overwritten } likely[i]=(op2&2)>>1; break; case FJUMP: rs1[i]=FSREG; rs2[i]=CSREG; rt1[i]=0; rt2[i]=0; likely[i]=((source[i])>>17)&1; break; case ALU: rs1[i]=(source[i]>>21)&0x1f; // source rs2[i]=(source[i]>>16)&0x1f; // subtract amount rt1[i]=(source[i]>>11)&0x1f; // destination rt2[i]=0; if(op2==0x2a||op2==0x2b) { // SLT/SLTU us1[i]=rs1[i];us2[i]=rs2[i]; } else if(op2>=0x24&&op2<=0x27) { // AND/OR/XOR/NOR dep1[i]=rs1[i];dep2[i]=rs2[i]; } else if(op2>=0x2c&&op2<=0x2f) { // DADD/DSUB dep1[i]=rs1[i];dep2[i]=rs2[i]; } break; case MULTDIV: rs1[i]=(source[i]>>21)&0x1f; // source rs2[i]=(source[i]>>16)&0x1f; // divisor rt1[i]=HIREG; rt2[i]=LOREG; if (op2>=0x1c&&op2<=0x1f) { // DMULT/DMULTU/DDIV/DDIVU us1[i]=rs1[i];us2[i]=rs2[i]; } break; case MOV: rs1[i]=0; rs2[i]=0; rt1[i]=0; rt2[i]=0; if(op2==0x10) rs1[i]=HIREG; // MFHI if(op2==0x11) rt1[i]=HIREG; // MTHI if(op2==0x12) rs1[i]=LOREG; // MFLO if(op2==0x13) rt1[i]=LOREG; // MTLO if((op2&0x1d)==0x10) rt1[i]=(source[i]>>11)&0x1f; // MFxx if((op2&0x1d)==0x11) rs1[i]=(source[i]>>21)&0x1f; // MTxx dep1[i]=rs1[i]; break; case SHIFT: rs1[i]=(source[i]>>16)&0x1f; // target of shift rs2[i]=(source[i]>>21)&0x1f; // shift amount rt1[i]=(source[i]>>11)&0x1f; // destination rt2[i]=0; // DSLLV/DSRLV/DSRAV are 64-bit if(op2>=0x14&&op2<=0x17) us1[i]=rs1[i]; break; case SHIFTIMM: rs1[i]=(source[i]>>16)&0x1f; rs2[i]=0; rt1[i]=(source[i]>>11)&0x1f; rt2[i]=0; imm[i]=(source[i]>>6)&0x1f; // DSxx32 instructions if(op2>=0x3c) imm[i]|=0x20; // DSLL/DSRL/DSRA/DSRA32/DSRL32 but not DSLL32 require 64-bit source if(op2>=0x38&&op2!=0x3c) us1[i]=rs1[i]; break; case COP0: rs1[i]=0; rs2[i]=0; rt1[i]=0; rt2[i]=0; if(op2==0) rt1[i]=(source[i]>>16)&0x1F; // MFC0 if(op2==4) rs1[i]=(source[i]>>16)&0x1F; // MTC0 if(op2==4&&((source[i]>>11)&0x1f)==12) rt2[i]=CSREG; // Status if(op2==16) if((source[i]&0x3f)==0x18) rs2[i]=CCREG; // ERET break; case COP1: rs1[i]=0; rs2[i]=0; rt1[i]=0; rt2[i]=0; if(op2<3) rt1[i]=(source[i]>>16)&0x1F; // MFC1/DMFC1/CFC1 if(op2>3) rs1[i]=(source[i]>>16)&0x1F; // MTC1/DMTC1/CTC1 if(op2==5) us1[i]=rs1[i]; // DMTC1 rs2[i]=CSREG; break; case C1LS: rs1[i]=(source[i]>>21)&0x1F; rs2[i]=CSREG; rt1[i]=0; rt2[i]=0; imm[i]=(short)source[i]; break; case FLOAT: case FCONV: rs1[i]=0; rs2[i]=CSREG; rt1[i]=0; rt2[i]=0; break; case FCOMP: rs1[i]=FSREG; rs2[i]=CSREG; rt1[i]=FSREG; rt2[i]=0; break; case SYSCALL: rs1[i]=CCREG; rs2[i]=0; rt1[i]=0; rt2[i]=0; break; default: rs1[i]=0; rs2[i]=0; rt1[i]=0; rt2[i]=0; } /* Calculate branch target addresses */ if(type==UJUMP) ba[i]=((start+i*4+4)&0xF0000000)|(((unsigned int)source[i]<<6)>>4); else if(type==CJUMP&&rs1[i]==rs2[i]&&(op&1)) ba[i]=start+i*4+8; // Ignore never taken branch else if(type==SJUMP&&rs1[i]==0&&!(op2&1)) ba[i]=start+i*4+8; // Ignore never taken branch else if(type==CJUMP||type==SJUMP||type==FJUMP) ba[i]=start+i*4+4+((signed int)((unsigned int)source[i]<<16)>>14); else ba[i]=-1; /* Is this the end of the block? */ if(i>0&&(itype[i-1]==UJUMP||itype[i-1]==RJUMP||(source[i-1]>>16)==0x1000)) { if(rt1[i-1]==0) /* Continue past subroutine call (JAL) */ { done=1; // Does the block continue due to a branch? for(j=i-1;j>=0;j--) { if(ba[j]==start+i*4) done=j=0; // Branch into delay slot if(ba[j]==start+i*4+4) done=j=0; if(ba[j]==start+i*4+8) done=j=0; } } else { if(stop_after_jal) done=1; // Stop on BREAK if((source[i+1]&0xfc00003f)==0x0d) done=1; } /* Don't recompile stuff that's already compiled */ if(check_addr(start+i*4+4)) done=1; /* Don't get too close to the limit */ if(i>MAXBLOCK/2) done=1; } if(i>0&&itype[i-1]==SYSCALL&&stop_after_jal) done=1; assert(i0); /* Pass 2 - Register dependencies and branch targets */ unneeded_registers(0,slen-1,0); /* Pass 3 - Register allocation */ struct regstat current; // Current register allocations/status current.is32=1; current.dirty=0; current.u=unneeded_reg[0]; current.uu=unneeded_reg_upper[0]; clear_all_regs(current.regmap); alloc_reg(¤t,0,CCREG); dirty_reg(¤t,CCREG); current.isconst=0; current.wasconst=0; int ds=0; int cc=0; int hr; #ifndef FORCE32 provisional_32bit(); #endif if((u_int)addr&1) { // First instruction is delay slot cc=-1; bt[1]=1; ds=1; unneeded_reg[0]=1; unneeded_reg_upper[0]=1; current.regmap[HOST_BTREG]=BTREG; } for(i=0;i1) { if((opcode[i-2]&0x2f)==0x05) // BNE/BNEL { if(rs1[i-2]==0||rs2[i-2]==0) { if(rs1[i-2]) { current.is32|=1LL<=0) current.regmap[hr]=-1; } if(rs2[i-2]) { current.is32|=1LL<=0) current.regmap[hr]=-1; } } } } #ifndef FORCE32 // If something jumps here with 64-bit values // then promote those registers to 64 bits if(bt[i]) { uint64_t temp_is32=current.is32; for(j=i-1;j>=0;j--) { if(ba[j]==start+i*4) temp_is32&=branch_regs[j].is32; } for(j=i;j0&&r<64) { if((current.dirty>>hr)&((current.is32&~temp_is32)>>r)&1) { temp_is32|=1LL<=0;j--) { if(ba[j]==start+i*4+4) temp_is32&=branch_regs[j].is32; } for(j=i;j0) { if((current.dirty>>hr)&((current.is32&~temp_is32)>>(r&63))&1) { if(itype[i]!=UJUMP&&itype[i]!=CJUMP&&itype[i]!=SJUMP&&itype[i]!=RJUMP&&itype[i]!=FJUMP) { if(rs1[i]!=(r&63)&&rs2[i]!=(r&63)) { //DebugMessage(M64MSG_VERBOSE, "dump %d/r%d",hr,r); current.regmap[hr]=-1; if(get_reg(current.regmap,r|64)>=0) current.regmap[get_reg(current.regmap,r|64)]=-1; } } } } } } } else if(i>16)!=0x1000&&(itype[i]==CJUMP||itype[i]==SJUMP||itype[i]==FJUMP)) { uint64_t temp_is32=current.is32; for(j=i-1;j>=0;j--) { if(ba[j]==start+i*4+8) temp_is32&=branch_regs[j].is32; } for(j=i;j0) { if((current.dirty>>hr)&((current.is32&~temp_is32)>>(r&63))&1) { if(rs1[i]!=(r&63)&&rs2[i]!=(r&63)&&rs1[i+1]!=(r&63)&&rs2[i+1]!=(r&63)) { //DebugMessage(M64MSG_VERBOSE, "dump %d/r%d",hr,r); current.regmap[hr]=-1; if(get_reg(current.regmap,r|64)>=0) current.regmap[get_reg(current.regmap,r|64)]=-1; } } } } } } #endif if(itype[i]!=UJUMP&&itype[i]!=CJUMP&&itype[i]!=SJUMP&&itype[i]!=RJUMP&&itype[i]!=FJUMP) { if(i+1>rt1[i])&1) current.uu&=~((1LL<>rt1[i+1])&1) current.uu&=~((1LL<>rt1[i])&1) current.uu&=~((1LL<=0) { if(r!=regmap_pre[i][hr]) { regs[i].regmap_entry[hr]=-1; } else { if(r<64){ if((current.u>>r)&1) { regs[i].regmap_entry[hr]=-1; regs[i].regmap[hr]=-1; //Don't clear regs in the delay slot as the branch might need them //current.regmap[hr]=-1; }else regs[i].regmap_entry[hr]=r; } else { if((current.uu>>(r&63))&1) { regs[i].regmap_entry[hr]=-1; regs[i].regmap[hr]=-1; //Don't clear regs in the delay slot as the branch might need them //current.regmap[hr]=-1; }else regs[i].regmap_entry[hr]=r; } } } else { // First instruction expects CCREG to be allocated if(i==0&&hr==HOST_CCREG) regs[i].regmap_entry[hr]=CCREG; else regs[i].regmap_entry[hr]=-1; } } } else { // Not delay slot switch(itype[i]) { case UJUMP: //current.isconst=0; // DEBUG //current.wasconst=0; // DEBUG //regs[i].wasconst=0; // DEBUG clear_const(¤t,rt1[i]); alloc_cc(¤t,i); dirty_reg(¤t,CCREG); if (rt1[i]==31) { alloc_reg(¤t,i,31); dirty_reg(¤t,31); assert(rs1[i+1]!=31&&rs2[i+1]!=31); #ifdef REG_PREFETCH alloc_reg(¤t,i,PTEMP); #endif //current.is32|=1LL<>rs1[i])&(current.is32>>rs2[i])&1)) { if(rs1[i]) alloc_reg64(¤t,i,rs1[i]); if(rs2[i]) alloc_reg64(¤t,i,rs2[i]); } if((rs1[i]&&(rs1[i]==rt1[i+1]||rs1[i]==rt2[i+1]))|| (rs2[i]&&(rs2[i]==rt1[i+1]||rs2[i]==rt2[i+1]))) { // The delay slot overwrites one of our conditions. // Allocate the branch condition registers instead. current.isconst=0; current.wasconst=0; regs[i].wasconst=0; if(rs1[i]) alloc_reg(¤t,i,rs1[i]); if(rs2[i]) alloc_reg(¤t,i,rs2[i]); if(!((current.is32>>rs1[i])&(current.is32>>rs2[i])&1)) { if(rs1[i]) alloc_reg64(¤t,i,rs1[i]); if(rs2[i]) alloc_reg64(¤t,i,rs2[i]); } } else { ooo[i]=1; delayslot_alloc(¤t,i+1); } } else if((opcode[i]&0x3E)==6) // BLEZ/BGTZ { alloc_cc(¤t,i); dirty_reg(¤t,CCREG); alloc_reg(¤t,i,rs1[i]); if(!(current.is32>>rs1[i]&1)) { alloc_reg64(¤t,i,rs1[i]); } if(rs1[i]&&(rs1[i]==rt1[i+1]||rs1[i]==rt2[i+1])) { // The delay slot overwrites one of our conditions. // Allocate the branch condition registers instead. current.isconst=0; current.wasconst=0; regs[i].wasconst=0; if(rs1[i]) alloc_reg(¤t,i,rs1[i]); if(!((current.is32>>rs1[i])&1)) { if(rs1[i]) alloc_reg64(¤t,i,rs1[i]); } } else { ooo[i]=1; delayslot_alloc(¤t,i+1); } } else // Don't alloc the delay slot yet because we might not execute it if((opcode[i]&0x3E)==0x14) // BEQL/BNEL { current.isconst=0; current.wasconst=0; regs[i].wasconst=0; alloc_cc(¤t,i); dirty_reg(¤t,CCREG); alloc_reg(¤t,i,rs1[i]); alloc_reg(¤t,i,rs2[i]); if(!((current.is32>>rs1[i])&(current.is32>>rs2[i])&1)) { alloc_reg64(¤t,i,rs1[i]); alloc_reg64(¤t,i,rs2[i]); } } else if((opcode[i]&0x3E)==0x16) // BLEZL/BGTZL { current.isconst=0; current.wasconst=0; regs[i].wasconst=0; alloc_cc(¤t,i); dirty_reg(¤t,CCREG); alloc_reg(¤t,i,rs1[i]); if(!(current.is32>>rs1[i]&1)) { alloc_reg64(¤t,i,rs1[i]); } } ds=1; //current.isconst=0; break; case SJUMP: //current.isconst=0; //current.wasconst=0; //regs[i].wasconst=0; clear_const(¤t,rs1[i]); clear_const(¤t,rt1[i]); //if((opcode2[i]&0x1E)==0x0) // BLTZ/BGEZ if((opcode2[i]&0x0E)==0x0) // BLTZ/BGEZ { alloc_cc(¤t,i); dirty_reg(¤t,CCREG); alloc_reg(¤t,i,rs1[i]); if(!(current.is32>>rs1[i]&1)) { alloc_reg64(¤t,i,rs1[i]); } if (rt1[i]==31) { // BLTZAL/BGEZAL alloc_reg(¤t,i,31); dirty_reg(¤t,31); assert(rs1[i+1]!=31&&rs2[i+1]!=31); //#ifdef REG_PREFETCH //alloc_reg(¤t,i,PTEMP); //#endif //current.is32|=1LL<>rs1[i])&1)) { if(rs1[i]) alloc_reg64(¤t,i,rs1[i]); } } else { ooo[i]=1; delayslot_alloc(¤t,i+1); } } else // Don't alloc the delay slot yet because we might not execute it if((opcode2[i]&0x1E)==0x2) // BLTZL/BGEZL { current.isconst=0; current.wasconst=0; regs[i].wasconst=0; alloc_cc(¤t,i); dirty_reg(¤t,CCREG); alloc_reg(¤t,i,rs1[i]); if(!(current.is32>>rs1[i]&1)) { alloc_reg64(¤t,i,rs1[i]); } } ds=1; //current.isconst=0; break; case FJUMP: current.isconst=0; current.wasconst=0; regs[i].wasconst=0; if(likely[i]==0) // BC1F/BC1T { // TODO: Theoretically we can run out of registers here on x86. // The delay slot can allocate up to six, and we need to check // CSREG before executing the delay slot. Possibly we can drop // the cycle count and then reload it after checking that the // FPU is in a usable state, or don't do out-of-order execution. alloc_cc(¤t,i); dirty_reg(¤t,CCREG); alloc_reg(¤t,i,FSREG); alloc_reg(¤t,i,CSREG); if(itype[i+1]==FCOMP) { // The delay slot overwrites the branch condition. // Allocate the branch condition registers instead. alloc_cc(¤t,i); dirty_reg(¤t,CCREG); alloc_reg(¤t,i,CSREG); alloc_reg(¤t,i,FSREG); } else { ooo[i]=1; delayslot_alloc(¤t,i+1); alloc_reg(¤t,i+1,CSREG); } } else // Don't alloc the delay slot yet because we might not execute it if(likely[i]) // BC1FL/BC1TL { alloc_cc(¤t,i); dirty_reg(¤t,CCREG); alloc_reg(¤t,i,CSREG); alloc_reg(¤t,i,FSREG); } ds=1; current.isconst=0; break; case IMM16: imm16_alloc(¤t,i); break; case LOAD: case LOADLR: load_alloc(¤t,i); break; case STORE: case STORELR: store_alloc(¤t,i); break; case ALU: alu_alloc(¤t,i); break; case SHIFT: shift_alloc(¤t,i); break; case MULTDIV: multdiv_alloc(¤t,i); break; case SHIFTIMM: shiftimm_alloc(¤t,i); break; case MOV: mov_alloc(¤t,i); break; case COP0: cop0_alloc(¤t,i); break; case COP1: cop1_alloc(¤t,i); break; case C1LS: c1ls_alloc(¤t,i); break; case FCONV: fconv_alloc(¤t,i); break; case FLOAT: float_alloc(¤t,i); break; case FCOMP: fcomp_alloc(¤t,i); break; case SYSCALL: syscall_alloc(¤t,i); break; case SPAN: pagespan_alloc(¤t,i); break; } // Drop the upper half of registers that have become 32-bit current.uu|=current.is32&((1LL<>rt1[i])&1) current.uu&=~((1LL<>rt1[i+1])&1) current.uu&=~((1LL<=0) { if(r!=regmap_pre[i][hr]) { // TODO: delay slot (?) or=get_reg(regmap_pre[i],r); // Get old mapping for this register if(or<0||(r&63)>=TEMPREG){ regs[i].regmap_entry[hr]=-1; } else { // Just move it to a different register regs[i].regmap_entry[hr]=r; // If it was dirty before, it's still dirty if((regs[i].wasdirty>>or)&1) dirty_reg(¤t,r&63); } } else { // Unneeded if(r==0){ regs[i].regmap_entry[hr]=0; } else if(r<64){ if((current.u>>r)&1) { regs[i].regmap_entry[hr]=-1; //regs[i].regmap[hr]=-1; current.regmap[hr]=-1; }else regs[i].regmap_entry[hr]=r; } else { if((current.uu>>(r&63))&1) { regs[i].regmap_entry[hr]=-1; //regs[i].regmap[hr]=-1; current.regmap[hr]=-1; }else regs[i].regmap_entry[hr]=r; } } } else { // Branches expect CCREG to be allocated at the target if(regmap_pre[i][hr]==CCREG) regs[i].regmap_entry[hr]=CCREG; else regs[i].regmap_entry[hr]=-1; } } memcpy(regs[i].regmap,current.regmap,sizeof(current.regmap)); } /* Branch post-alloc */ if(i>0) { current.was32=current.is32; current.wasdirty=current.dirty; switch(itype[i-1]) { case UJUMP: memcpy(&branch_regs[i-1],¤t,sizeof(current)); branch_regs[i-1].isconst=0; branch_regs[i-1].wasconst=0; branch_regs[i-1].u=branch_unneeded_reg[i-1]&~((1LL<>rt1[i])&1) current.uu&=~((1LL<>rs1[i-1])&(current.is32>>rs2[i-1])&1)) { if(rs1[i-1]) alloc_reg64(¤t,i-1,rs1[i-1]); if(rs2[i-1]) alloc_reg64(¤t,i-1,rs2[i-1]); } } memcpy(&branch_regs[i-1],¤t,sizeof(current)); branch_regs[i-1].isconst=0; branch_regs[i-1].wasconst=0; memcpy(&branch_regs[i-1].regmap_entry,¤t.regmap,sizeof(current.regmap)); memcpy(constmap[i],constmap[i-1],sizeof(current.constmap)); } else if((opcode[i-1]&0x3E)==6) // BLEZ/BGTZ { alloc_cc(¤t,i-1); dirty_reg(¤t,CCREG); if(rs1[i-1]==rt1[i]||rs1[i-1]==rt2[i]) { // The delay slot overwrote the branch condition // Delay slot goes after the test (in order) current.u=branch_unneeded_reg[i-1]&~((1LL<>rt1[i])&1) current.uu&=~((1LL<>rs1[i-1]&1)) { alloc_reg64(¤t,i-1,rs1[i-1]); } } memcpy(&branch_regs[i-1],¤t,sizeof(current)); branch_regs[i-1].isconst=0; branch_regs[i-1].wasconst=0; memcpy(&branch_regs[i-1].regmap_entry,¤t.regmap,sizeof(current.regmap)); memcpy(constmap[i],constmap[i-1],sizeof(current.constmap)); } else // Alloc the delay slot in case the branch is taken if((opcode[i-1]&0x3E)==0x14) // BEQL/BNEL { memcpy(&branch_regs[i-1],¤t,sizeof(current)); branch_regs[i-1].u=(branch_unneeded_reg[i-1]&~((1LL<>rt1[i])&1) branch_regs[i-1].uu&=~((1LL<>rt1[i])&1) branch_regs[i-1].uu&=~((1LL<>rt1[i])&1) current.uu&=~((1LL<>rs1[i-1]&1)) { alloc_reg64(¤t,i-1,rs1[i-1]); } } memcpy(&branch_regs[i-1],¤t,sizeof(current)); branch_regs[i-1].isconst=0; branch_regs[i-1].wasconst=0; memcpy(&branch_regs[i-1].regmap_entry,¤t.regmap,sizeof(current.regmap)); memcpy(constmap[i],constmap[i-1],sizeof(current.constmap)); } else // Alloc the delay slot in case the branch is taken if((opcode2[i-1]&0x1E)==2) // BLTZL/BGEZL { memcpy(&branch_regs[i-1],¤t,sizeof(current)); branch_regs[i-1].u=(branch_unneeded_reg[i-1]&~((1LL<>rt1[i])&1) branch_regs[i-1].uu&=~((1LL<>rt1[i])&1) branch_regs[i-1].uu&=~((1LL<>16)==0x1000) { if(rt1[i-1]==31) // JAL/JALR { // Subroutine call will return here, don't alloc any registers current.is32=1; current.dirty=0; clear_all_regs(current.regmap); alloc_reg(¤t,i,CCREG); dirty_reg(¤t,CCREG); } else if(i+1=0;j--) { if(ba[j]==start+i*4+4) { memcpy(current.regmap,branch_regs[j].regmap,sizeof(current.regmap)); current.is32=branch_regs[j].is32; current.dirty=branch_regs[j].dirty; break; } } while(j>=0) { if(ba[j]==start+i*4+4) { for(hr=0;hr0&&(itype[i-1]==RJUMP||itype[i-1]==UJUMP||itype[i-1]==CJUMP||itype[i-1]==SJUMP||itype[i-1]==FJUMP||itype[i]==SYSCALL)) { cc=0; } else { cc++; } flush_dirty_uppers(¤t); if(!is_ds[i]) { regs[i].is32=current.is32; regs[i].dirty=current.dirty; regs[i].isconst=current.isconst; memcpy(constmap[i],current.constmap,sizeof(current.constmap)); } for(hr=0;hr=0) { if(regmap_pre[i][hr]!=regs[i].regmap[hr]) { regs[i].wasconst&=~(1<=0;i--) { int hr; if(itype[i]==RJUMP||itype[i]==UJUMP||itype[i]==CJUMP||itype[i]==SJUMP||itype[i]==FJUMP) { if(ba[i]=(start+slen*4)) { // Branch out of this block, don't need anything nr=0; } else { // Internal branch // Need whatever matches the target nr=0; int t=(ba[i]-start)>>2; for(hr=0;hr=0) { if(regs[i].regmap_entry[hr]==regs[t].regmap_entry[hr]) nr|=1<>16)!=0x1000) { if(i=0&&get_reg(regs[i+2].regmap_entry,regmap_pre[i+2][hr])<0) nr&=~(1<=0) if(!((nr>>hr)&1)) DebugMessage(M64MSG_VERBOSE, "%x-bogus(%d=%d)",start+i*4,hr,regmap_entry[i+2][hr]); } } } // Don't need stuff which is overwritten if(regs[i].regmap[hr]!=regmap_pre[i][hr]) nr&=~(1<>dep1[i+1])&1)) { if(dep1[i+1]==(regmap_pre[i][hr]&63)) nr|=1<>dep2[i+1])&1)) { if(dep1[i+1]==(regs[i].regmap_entry[hr]&63)) nr|=1<=0&&get_reg(regs[i+1].regmap_entry,regmap_pre[i+1][hr])<0) nr&=~(1<>dep1[i])&1)) { if(dep1[i]==(regmap_pre[i][hr]&63)) nr|=1<>dep2[i])&1)) { if(dep2[i]==(regmap_pre[i][hr]&63)) nr|=1<0&&!bt[i]&&((regs[i].wasdirty>>hr)&1)) { if((regmap_pre[i][hr]>0&®map_pre[i][hr]<64&&!((unneeded_reg[i]>>regmap_pre[i][hr])&1)) || (regmap_pre[i][hr]>64&&!((unneeded_reg_upper[i]>>(regmap_pre[i][hr]&63))&1)) ) { if(rt1[i-1]==(regmap_pre[i][hr]&63)) nr|=1<0&®s[i].regmap_entry[hr]<64&&!((unneeded_reg[i]>>regs[i].regmap_entry[hr])&1)) || (regs[i].regmap_entry[hr]>64&&!((unneeded_reg_upper[i]>>(regs[i].regmap_entry[hr]&63))&1)) ) { if(rt1[i-1]==(regs[i].regmap_entry[hr]&63)) nr|=1<>hr)&1)) { if(regs[i].regmap_entry[hr]!=CCREG) regs[i].regmap_entry[hr]=-1; if((regs[i].regmap[hr]&63)!=rs1[i] && (regs[i].regmap[hr]&63)!=rs2[i] && (regs[i].regmap[hr]&63)!=rt1[i] && (regs[i].regmap[hr]&63)!=rt2[i] && (regs[i].regmap[hr]&63)!=PTEMP && (regs[i].regmap[hr]&63)!=CCREG) { if(itype[i]!=RJUMP&&itype[i]!=UJUMP&&(source[i]>>16)!=0x1000) { if(likely[i]) { regs[i].regmap[hr]=-1; regs[i].isconst&=~(1<=0||get_reg(branch_regs[i].regmap,rt1[i+1]|64)>=0) { d1=dep1[i+1]; d2=dep2[i+1]; } if(using_tlb) { if(itype[i+1]==LOAD || itype[i+1]==LOADLR || itype[i+1]==STORE || itype[i+1]==STORELR || itype[i+1]==C1LS ) map=TLREG; } else if(itype[i+1]==STORE || itype[i+1]==STORELR || (opcode[i+1]&0x3b)==0x39) { map=INVCP; } if(itype[i+1]==LOADLR || itype[i+1]==STORELR || itype[i+1]==C1LS ) temp=FTEMP; if((regs[i].regmap[hr]&63)!=rs1[i] && (regs[i].regmap[hr]&63)!=rs2[i] && (regs[i].regmap[hr]&63)!=rt1[i] && (regs[i].regmap[hr]&63)!=rt2[i] && (regs[i].regmap[hr]&63)!=rt1[i+1] && (regs[i].regmap[hr]&63)!=rt2[i+1] && (regs[i].regmap[hr]^64)!=us1[i+1] && (regs[i].regmap[hr]^64)!=us2[i+1] && (regs[i].regmap[hr]^64)!=d1 && (regs[i].regmap[hr]^64)!=d2 && regs[i].regmap[hr]!=rs1[i+1] && regs[i].regmap[hr]!=rs2[i+1] && (regs[i].regmap[hr]&63)!=temp && regs[i].regmap[hr]!=PTEMP && regs[i].regmap[hr]!=RHASH && regs[i].regmap[hr]!=RHTBL && regs[i].regmap[hr]!=RTEMP && regs[i].regmap[hr]!=CCREG && regs[i].regmap[hr]!=map ) { regs[i].regmap[hr]=-1; regs[i].isconst&=~(1<>16)!=0x1000) { if(!likely[i]&&i0) { int d1=0,d2=0,map=-1,temp=-1; if(get_reg(regs[i].regmap,rt1[i]|64)>=0) { d1=dep1[i]; d2=dep2[i]; } if(using_tlb) { if(itype[i]==LOAD || itype[i]==LOADLR || itype[i]==STORE || itype[i]==STORELR || itype[i]==C1LS ) map=TLREG; } else if(itype[i]==STORE || itype[i]==STORELR || (opcode[i]&0x3b)==0x39) { map=INVCP; } if(itype[i]==LOADLR || itype[i]==STORELR || itype[i]==C1LS ) temp=FTEMP; if((regs[i].regmap[hr]&63)!=rt1[i] && (regs[i].regmap[hr]&63)!=rt2[i] && (regs[i].regmap[hr]^64)!=us1[i] && (regs[i].regmap[hr]^64)!=us2[i] && (regs[i].regmap[hr]^64)!=d1 && (regs[i].regmap[hr]^64)!=d2 && regs[i].regmap[hr]!=rs1[i] && regs[i].regmap[hr]!=rs2[i] && (regs[i].regmap[hr]&63)!=temp && regs[i].regmap[hr]!=map && (itype[i]!=SPAN||regs[i].regmap[hr]!=CCREG)) { if(i>(regs[i].regmap[hr]&63))&1)) { DebugMessage(M64MSG_VERBOSE, "fail: %x (%d %d!=%d)",start+i*4,hr,regmap_pre[i+1][hr],regs[i].regmap[hr]); assert(regmap_pre[i+1][hr]==regs[i].regmap[hr]); } regmap_pre[i+1][hr]=-1; if(regs[i+1].regmap_entry[hr]==CCREG) regs[i+1].regmap_entry[hr]=-1; regs[i+1].wasconst&=~(1<=start && ba[i]<(start+i*4)) if(itype[i+1]==NOP||itype[i+1]==MOV||itype[i+1]==ALU ||itype[i+1]==SHIFTIMM||itype[i+1]==IMM16||itype[i+1]==LOAD ||itype[i+1]==STORE||itype[i+1]==STORELR||itype[i+1]==C1LS ||itype[i+1]==SHIFT||itype[i+1]==COP1||itype[i+1]==FLOAT ||itype[i+1]==FCOMP||itype[i+1]==FCONV) { int t=(ba[i]-start)>>2; if(t>0&&(itype[t-1]!=UJUMP&&itype[t-1]!=RJUMP&&itype[t-1]!=CJUMP&&itype[t-1]!=SJUMP&&itype[t-1]!=FJUMP)) // loop_preload can't handle jumps into delay slots if(t<2||(itype[t-2]!=UJUMP&&itype[t-2]!=RJUMP)||rt1[t-2]!=31) // call/ret assumes no registers allocated for(hr=0;hr64) { if(!((regs[i].dirty>>hr)&1)) f_regmap[hr]=regs[i].regmap[hr]; else f_regmap[hr]=-1; } else if(regs[i].regmap[hr]>=0) { if(f_regmap[hr]!=regs[i].regmap[hr]) { // dealloc old register int n; for(n=0;n64) { if(!((branch_regs[i].dirty>>hr)&1)) f_regmap[hr]=branch_regs[i].regmap[hr]; else f_regmap[hr]=-1; } else if(branch_regs[i].regmap[hr]>=0) { if(f_regmap[hr]!=branch_regs[i].regmap[hr]) { // dealloc old register int n; for(n=0;nclean transition #ifdef DESTRUCTIVE_WRITEBACK if(t>0) if(get_reg(regmap_pre[t],f_regmap[hr])>=0) if((regs[t].wasdirty>>get_reg(regmap_pre[t],f_regmap[hr]))&1) f_regmap[hr]=-1; #endif // This check is only strictly required in the DESTRUCTIVE_WRITEBACK // case above, however it's always a good idea. We can't hoist the // load if the register was already allocated, so there's no point // wasting time analyzing most of these cases. It only "succeeds" // when the mapping was different and the load can be replaced with // a mov, which is of negligible benefit. So such cases are // skipped below. if(f_regmap[hr]>0) { if(regs[t].regmap[hr]==f_regmap[hr]||(regs[t].regmap_entry[hr]<0&&get_reg(regmap_pre[t],f_regmap[hr])<0)) { int r=f_regmap[hr]; for(j=t;j<=i;j++) { //DebugMessage(M64MSG_VERBOSE, "Test %x -> %x, %x %d/%d",start+i*4,ba[i],start+j*4,hr,r); if(r<34&&((unneeded_reg[j]>>r)&1)) break; if(r>63&&((unneeded_reg_upper[j]>>(r&63))&1)) break; if(r>63) { // NB This can exclude the case where the upper-half // register is lower numbered than the lower-half // register. Not sure if it's worth fixing... if(get_reg(regs[j].regmap,r&63)<0) break; if(get_reg(regs[j].regmap_entry,r&63)<0) break; if(regs[j].is32&(1LL<<(r&63))) break; } if(regs[j].regmap[hr]==f_regmap[hr]&&(f_regmap[hr]&63) %x, %x %d/%d",start+i*4,ba[i],start+j*4,hr,r); int k; if(regs[i].regmap[hr]==-1&&branch_regs[i].regmap[hr]==-1) { if(get_reg(regs[i+2].regmap,f_regmap[hr])>=0) break; if(r>63) { if(get_reg(regs[i].regmap,r&63)<0) break; if(get_reg(branch_regs[i].regmap,r&63)<0) break; } k=i; while(k>1&®s[k-1].regmap[hr]==-1) { if(count_free_regs(regs[k-1].regmap)<=minimum_free_regs[k-1]) { //DebugMessage(M64MSG_VERBOSE, "no free regs for store %x",start+(k-1)*4); break; } if(get_reg(regs[k-1].regmap,f_regmap[hr])>=0) { //DebugMessage(M64MSG_VERBOSE, "no-match due to different register"); break; } if(itype[k-2]==UJUMP||itype[k-2]==RJUMP||itype[k-2]==CJUMP||itype[k-2]==SJUMP||itype[k-2]==FJUMP) { //DebugMessage(M64MSG_VERBOSE, "no-match due to branch"); break; } // call/ret fast path assumes no registers allocated if(k>2&&(itype[k-3]==UJUMP||itype[k-3]==RJUMP)&&rt1[k-3]==31) { break; } if(r>63) { // NB This can exclude the case where the upper-half // register is lower numbered than the lower-half // register. Not sure if it's worth fixing... if(get_reg(regs[k-1].regmap,r&63)<0) break; if(regs[k-1].is32&(1LL<<(r&63))) break; } k--; } if(i",hr,start+k*4); while(k",hr,start+k*4); break; } assert(regs[i-1].regmap[hr]==f_regmap[hr]); if(regs[i-1].regmap[hr]==f_regmap[hr]&®map_pre[i][hr]==f_regmap[hr]) { //DebugMessage(M64MSG_VERBOSE, "OK fill %x (r%d)",start+i*4,hr); regs[i].regmap_entry[hr]=f_regmap[hr]; regs[i].regmap[hr]=f_regmap[hr]; regs[i].wasdirty&=~(1<>16)!=0x1000) { regmap_pre[i+2][hr]=f_regmap[hr]; regs[i+2].wasdirty&=~(1<>16)!=0x1000) { regmap_pre[k+2][hr]=f_regmap[hr]; regs[k+2].wasdirty&=~(1<=0) break; if(get_reg(regs[j].regmap,f_regmap[hr])>=0) { //DebugMessage(M64MSG_VERBOSE, "no-match due to different register"); break; } if((regs[j+1].is32&(1LL<>16)==0x1000) { // Stop on unconditional branch break; } if(itype[j]==CJUMP||itype[j]==SJUMP||itype[j]==FJUMP) { if(ooo[j]) { if(count_free_regs(regs[j].regmap)<=minimum_free_regs[j+1]) break; }else{ if(count_free_regs(branch_regs[j].regmap)<=minimum_free_regs[j+1]) break; } if(get_reg(branch_regs[j].regmap,f_regmap[hr])>=0) { //DebugMessage(M64MSG_VERBOSE, "no-match due to different register (branch)"); break; } } if(count_free_regs(regs[j].regmap)<=minimum_free_regs[j]) { //DebugMessage(M64MSG_VERBOSE, "No free regs for store %x",start+j*4); break; } if(f_regmap[hr]>=64) { if(regs[j].is32&(1LL<<(f_regmap[hr]&63))) { break; } else { if(get_reg(regs[j].regmap,f_regmap[hr]&63)<0) { break; } } } } } } } } }else{ // Non branch or undetermined branch target for(hr=0;hr64) { if(!((regs[i].dirty>>hr)&1)) f_regmap[hr]=regs[i].regmap[hr]; } else if(regs[i].regmap[hr]>=0) { if(f_regmap[hr]!=regs[i].regmap[hr]) { // dealloc old register int n; for(n=0;n %x",start+k*4,start+j*4); while(ki&&f_regmap[HOST_CCREG]==CCREG) { //DebugMessage(M64MSG_VERBOSE, "Extend backwards"); int k; k=i; while(regs[k-1].regmap[HOST_CCREG]==-1) { if(count_free_regs(regs[k-1].regmap)<=minimum_free_regs[k-1]) { //DebugMessage(M64MSG_VERBOSE, "no free regs for store %x",start+(k-1)*4); break; } k--; } if(regs[k-1].regmap[HOST_CCREG]==CCREG) { //DebugMessage(M64MSG_VERBOSE, "Extend CC, %x ->",start+k*4); while(k<=i) { regs[k].regmap_entry[HOST_CCREG]=CCREG; regs[k].regmap[HOST_CCREG]=CCREG; regmap_pre[k+1][HOST_CCREG]=CCREG; regs[k+1].wasdirty|=1<",start+k*4); } } } if(itype[i]!=STORE&&itype[i]!=STORELR&&itype[i]!=C1LS&&itype[i]!=SHIFT&& itype[i]!=NOP&&itype[i]!=MOV&&itype[i]!=ALU&&itype[i]!=SHIFTIMM&& itype[i]!=IMM16&&itype[i]!=LOAD&&itype[i]!=COP1&&itype[i]!=FLOAT&& itype[i]!=FCONV&&itype[i]!=FCOMP) { memcpy(f_regmap,regs[i].regmap,sizeof(f_regmap)); } } } // Cache memory offset or tlb map pointer if a register is available #ifndef HOST_IMM_ADDR32 #ifndef RAM_OFFSET if(using_tlb) #endif { int earliest_available[HOST_REGS]; int loop_start[HOST_REGS]; int score[HOST_REGS]; int end[HOST_REGS]; int reg=using_tlb?MMREG:ROREG; // Init for(hr=0;hr=0) { score[hr]=0;earliest_available[hr]=i+1; loop_start[hr]=MAXBLOCK; } if(itype[i]==UJUMP||itype[i]==RJUMP||itype[i]==CJUMP||itype[i]==SJUMP||itype[i]==FJUMP) { if(branch_regs[i].regmap[hr]>=0) { score[hr]=0;earliest_available[hr]=i+2; loop_start[hr]=MAXBLOCK; } } } // No register allocations after unconditional jumps if(itype[i]==UJUMP||itype[i]==RJUMP||(source[i]>>16)==0x1000) { for(hr=0;hr=0) break; if(itype[j]==UJUMP||itype[j]==RJUMP||itype[j]==CJUMP||itype[j]==SJUMP||itype[j]==FJUMP) { if(branch_regs[j].regmap[hr]>=0) break; if(ooo[j]) { if(count_free_regs(regs[j].regmap)<=minimum_free_regs[j+1]) break; }else{ if(count_free_regs(branch_regs[j].regmap)<=minimum_free_regs[j+1]) break; } } else if(count_free_regs(regs[j].regmap)<=minimum_free_regs[j]) break; if(itype[j]==UJUMP||itype[j]==RJUMP||itype[j]==CJUMP||itype[j]==SJUMP||itype[j]==FJUMP) { int t=(ba[j]-start)>>2; if(t=earliest_available[hr]) { if(t==1||(t>1&&itype[t-2]!=UJUMP&&itype[t-2]!=RJUMP)||(t>1&&rt1[t-2]!=31)) { // call/ret assumes no registers allocated // Score a point for hoisting loop invariant if(t>16)==0x1000) { // Stop on unconditional branch break; } else if(itype[j]==LOAD||itype[j]==LOADLR|| itype[j]==STORE||itype[j]==STORELR||itype[j]==C1LS) { score[hr]++; end[hr]=j; } } } } // Find highest score and allocate that register int maxscore=0; for(hr=0;hrscore[maxscore]) { maxscore=hr; //DebugMessage(M64MSG_VERBOSE, "highest score: %d %d (%x->%x)",score[hr],hr,start+i*4,start+end[hr]*4); } } } if(score[maxscore]>1) { if(i=0) {DebugMessage(M64MSG_ERROR, "oops: %x %x was %d=%d",loop_start[maxscore]*4+start,j*4+start,maxscore,regs[j].regmap[maxscore]);} assert(regs[j].regmap[maxscore]<0); if(j>loop_start[maxscore]) regs[j].regmap_entry[maxscore]=reg; regs[j].regmap[maxscore]=reg; regs[j].dirty&=~(1<>16)!=0x1000) { regmap_pre[j+2][maxscore]=reg; regs[j+2].wasdirty&=~(1<>2; if(t==loop_start[maxscore]) { if(t==1||(t>1&&itype[t-2]!=UJUMP&&itype[t-2]!=RJUMP)||(t>1&&rt1[t-2]!=31)) // call/ret assumes no registers allocated regs[t].regmap_entry[maxscore]=reg; } } else { if(j<1||(itype[j-1]!=RJUMP&&itype[j-1]!=UJUMP&&itype[j-1]!=CJUMP&&itype[j-1]!=SJUMP&&itype[j-1]!=FJUMP)) { regmap_pre[j+1][maxscore]=reg; regs[j+1].wasdirty&=~(1<=0) { if(regs[i].regmap[hr]<0&®s[i+1].regmap_entry[hr]<0) { regs[i].regmap[hr]=regs[i+1].regmap[hr]; regmap_pre[i+1][hr]=regs[i+1].regmap[hr]; regs[i+1].regmap_entry[hr]=regs[i+1].regmap[hr]; regs[i].isconst&=~(1<=0) { if(regs[i].regmap[hr]<0&®s[i+1].regmap_entry[hr]<0) { regs[i].regmap[hr]=regs[i+1].regmap[hr]; regmap_pre[i+1][hr]=regs[i+1].regmap[hr]; regs[i+1].regmap_entry[hr]=regs[i+1].regmap[hr]; regs[i].isconst&=~(1<=0) { if(regs[i].regmap[hr]<0&®s[i+1].regmap_entry[hr]<0) { regs[i].regmap[hr]=rs1[i+1]; regmap_pre[i+1][hr]=rs1[i+1]; regs[i+1].regmap_entry[hr]=rs1[i+1]; regs[i].isconst&=~(1<=0) { if(regs[i].regmap[hr]<0&®s[i+1].regmap_entry[hr]<0) { regs[i].regmap[hr]=rs1[i+1]; regmap_pre[i+1][hr]=rs1[i+1]; regs[i+1].regmap_entry[hr]=rs1[i+1]; regs[i].isconst&=~(1<=0) { int sr=get_reg(regs[i+1].regmap,rs1[i+1]); if(sr>=0&&((regs[i+1].wasconst>>sr)&1)) { int nr; if(regs[i].regmap[hr]<0&®s[i+1].regmap_entry[hr]<0) { regs[i].regmap[hr]=MGEN1+((i+1)&1); regmap_pre[i+1][hr]=MGEN1+((i+1)&1); regs[i+1].regmap_entry[hr]=MGEN1+((i+1)&1); regs[i].isconst&=~(1<=0) { // move it to another register regs[i+1].regmap[hr]=-1; regmap_pre[i+2][hr]=-1; regs[i+1].regmap[nr]=TLREG; regmap_pre[i+2][nr]=TLREG; regs[i].regmap[nr]=MGEN1+((i+1)&1); regmap_pre[i+1][nr]=MGEN1+((i+1)&1); regs[i+1].regmap_entry[nr]=MGEN1+((i+1)&1); regs[i].isconst&=~(1<=0); if(regs[i].regmap[hr]<0&®s[i+1].regmap_entry[hr]<0) { regs[i].regmap[hr]=rs1[i+1]; regmap_pre[i+1][hr]=rs1[i+1]; regs[i+1].regmap_entry[hr]=rs1[i+1]; regs[i].isconst&=~(1<=0); if(regs[i].regmap[hr]<0&®s[i+1].regmap_entry[hr]<0) { regs[i].regmap[hr]=rs1[i+1]; regmap_pre[i+1][hr]=rs1[i+1]; regs[i+1].regmap_entry[hr]=rs1[i+1]; regs[i].isconst&=~(1<=0) { // move it to another register regs[i+1].regmap[hr]=-1; regmap_pre[i+2][hr]=-1; regs[i+1].regmap[nr]=FTEMP; regmap_pre[i+2][nr]=FTEMP; regs[i].regmap[nr]=rs1[i+1]; regmap_pre[i+1][nr]=rs1[i+1]; regs[i+1].regmap_entry[nr]=rs1[i+1]; regs[i].isconst&=~(1<=0&®s[i].regmap[hr]<0) { int rs=get_reg(regs[i+1].regmap,rs1[i+1]); if(rs>=0&&((regs[i+1].wasconst>>rs)&1)) { regs[i].regmap[hr]=AGEN1+((i+1)&1); regmap_pre[i+1][hr]=AGEN1+((i+1)&1); regs[i+1].regmap_entry[hr]=AGEN1+((i+1)&1); regs[i].isconst&=~(1<=0;i--) { int hr; if(itype[i]==RJUMP||itype[i]==UJUMP||itype[i]==CJUMP||itype[i]==SJUMP||itype[i]==FJUMP) { if(ba[i]=(start+slen*4)) { // Branch out of this block, don't need anything r32=0; } else { // Internal branch // Need whatever matches the target // (and doesn't get overwritten by the delay slot instruction) r32=0; int t=(ba[i]-start)>>2; if(ba[i]>start+i*4) { // Forward branch if(!(requires_32bit[t]&~regs[i].was32)) r32|=requires_32bit[t]&(~(1LL<>16)!=0x1000) { if(i0) { if((regs[i].was32>>us1[i+1])&1) r32|=1LL<0) { if((regs[i].was32>>us2[i+1])&1) r32|=1LL<>dep1[i+1])&1)) { if((regs[i].was32>>dep1[i+1])&1) r32|=1LL<>dep2[i+1])&1)) { if((regs[i].was32>>dep2[i+1])&1) r32|=1LL<0) { if((regs[i].was32>>us1[i])&1) r32|=1LL<0) { if((regs[i].was32>>us2[i])&1) r32|=1LL<>dep1[i])&1)) { if((regs[i].was32>>dep1[i])&1) r32|=1LL<>dep2[i])&1)) { if((regs[i].was32>>dep2[i])&1) r32|=1LL<0&®s[i].regmap_entry[hr]<64) { if((regs[i].was32>>regs[i].regmap_entry[hr])&(regs[i].wasdirty>>hr)&1) { if(!((unneeded_reg_upper[i]>>regs[i].regmap_entry[hr])&1)) requires_32bit[i]|=1LL<>r)&1) { if(r==HIREG) DebugMessage(M64MSG_VERBOSE, " HI"); else if(r==LOREG) DebugMessage(M64MSG_VERBOSE, " LO"); else DebugMessage(M64MSG_VERBOSE, " r%d",r); } } DebugMessage(M64MSG_VERBOSE, " UU:"); for(r=1;r<=CCREG;r++) { if(((unneeded_reg_upper[i]&~unneeded_reg[i])>>r)&1) { if(r==HIREG) DebugMessage(M64MSG_VERBOSE, " HI"); else if(r==LOREG) DebugMessage(M64MSG_VERBOSE, " LO"); else DebugMessage(M64MSG_VERBOSE, " r%d",r); } } DebugMessage(M64MSG_VERBOSE, " 32:"); for(r=0;r<=CCREG;r++) { //if(((is32[i]>>r)&(~unneeded_reg[i]>>r))&1) { if((regs[i].was32>>r)&1) { if(r==CCREG) DebugMessage(M64MSG_VERBOSE, " CC"); else if(r==HIREG) DebugMessage(M64MSG_VERBOSE, " HI"); else if(r==LOREG) DebugMessage(M64MSG_VERBOSE, " LO"); else DebugMessage(M64MSG_VERBOSE, " r%d",r); } } #if NEW_DYNAREC == NEW_DYNAREC_X86 DebugMessage(M64MSG_VERBOSE, "pre: eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d",regmap_pre[i][0],regmap_pre[i][1],regmap_pre[i][2],regmap_pre[i][3],regmap_pre[i][5],regmap_pre[i][6],regmap_pre[i][7]); #endif #if NEW_DYNAREC == NEW_DYNAREC_ARM DebugMessage(M64MSG_VERBOSE, "pre: r0=%d r1=%d r2=%d r3=%d r4=%d r5=%d r6=%d r7=%d r8=%d r9=%d r10=%d r12=%d",regmap_pre[i][0],regmap_pre[i][1],regmap_pre[i][2],regmap_pre[i][3],regmap_pre[i][4],regmap_pre[i][5],regmap_pre[i][6],regmap_pre[i][7],regmap_pre[i][8],regmap_pre[i][9],regmap_pre[i][10],regmap_pre[i][12]); #endif DebugMessage(M64MSG_VERBOSE, "needs: "); if(needed_reg[i]&1) DebugMessage(M64MSG_VERBOSE, "eax "); if((needed_reg[i]>>1)&1) DebugMessage(M64MSG_VERBOSE, "ecx "); if((needed_reg[i]>>2)&1) DebugMessage(M64MSG_VERBOSE, "edx "); if((needed_reg[i]>>3)&1) DebugMessage(M64MSG_VERBOSE, "ebx "); if((needed_reg[i]>>5)&1) DebugMessage(M64MSG_VERBOSE, "ebp "); if((needed_reg[i]>>6)&1) DebugMessage(M64MSG_VERBOSE, "esi "); if((needed_reg[i]>>7)&1) DebugMessage(M64MSG_VERBOSE, "edi "); DebugMessage(M64MSG_VERBOSE, "r:"); for(r=0;r<=CCREG;r++) { //if(((requires_32bit[i]>>r)&(~unneeded_reg[i]>>r))&1) { if((requires_32bit[i]>>r)&1) { if(r==CCREG) DebugMessage(M64MSG_VERBOSE, " CC"); else if(r==HIREG) DebugMessage(M64MSG_VERBOSE, " HI"); else if(r==LOREG) DebugMessage(M64MSG_VERBOSE, " LO"); else DebugMessage(M64MSG_VERBOSE, " r%d",r); } } /*DebugMessage(M64MSG_VERBOSE, "pr:"); for(r=0;r<=CCREG;r++) { //if(((requires_32bit[i]>>r)&(~unneeded_reg[i]>>r))&1) { if((pr32[i]>>r)&1) { if(r==CCREG) DebugMessage(M64MSG_VERBOSE, " CC"); else if(r==HIREG) DebugMessage(M64MSG_VERBOSE, " HI"); else if(r==LOREG) DebugMessage(M64MSG_VERBOSE, " LO"); else DebugMessage(M64MSG_VERBOSE, " r%d",r); } } if(pr32[i]!=requires_32bit[i]) DebugMessage(M64MSG_ERROR, " OOPS");*/ #if NEW_DYNAREC == NEW_DYNAREC_X86 DebugMessage(M64MSG_VERBOSE, "entry: eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d",regs[i].regmap_entry[0],regs[i].regmap_entry[1],regs[i].regmap_entry[2],regs[i].regmap_entry[3],regs[i].regmap_entry[5],regs[i].regmap_entry[6],regs[i].regmap_entry[7]); DebugMessage(M64MSG_VERBOSE, "dirty: "); if(regs[i].wasdirty&1) DebugMessage(M64MSG_VERBOSE, "eax "); if((regs[i].wasdirty>>1)&1) DebugMessage(M64MSG_VERBOSE, "ecx "); if((regs[i].wasdirty>>2)&1) DebugMessage(M64MSG_VERBOSE, "edx "); if((regs[i].wasdirty>>3)&1) DebugMessage(M64MSG_VERBOSE, "ebx "); if((regs[i].wasdirty>>5)&1) DebugMessage(M64MSG_VERBOSE, "ebp "); if((regs[i].wasdirty>>6)&1) DebugMessage(M64MSG_VERBOSE, "esi "); if((regs[i].wasdirty>>7)&1) DebugMessage(M64MSG_VERBOSE, "edi "); #endif #if NEW_DYNAREC == NEW_DYNAREC_ARM DebugMessage(M64MSG_VERBOSE, "entry: r0=%d r1=%d r2=%d r3=%d r4=%d r5=%d r6=%d r7=%d r8=%d r9=%d r10=%d r12=%d",regs[i].regmap_entry[0],regs[i].regmap_entry[1],regs[i].regmap_entry[2],regs[i].regmap_entry[3],regs[i].regmap_entry[4],regs[i].regmap_entry[5],regs[i].regmap_entry[6],regs[i].regmap_entry[7],regs[i].regmap_entry[8],regs[i].regmap_entry[9],regs[i].regmap_entry[10],regs[i].regmap_entry[12]); DebugMessage(M64MSG_VERBOSE, "dirty: "); if(regs[i].wasdirty&1) DebugMessage(M64MSG_VERBOSE, "r0 "); if((regs[i].wasdirty>>1)&1) DebugMessage(M64MSG_VERBOSE, "r1 "); if((regs[i].wasdirty>>2)&1) DebugMessage(M64MSG_VERBOSE, "r2 "); if((regs[i].wasdirty>>3)&1) DebugMessage(M64MSG_VERBOSE, "r3 "); if((regs[i].wasdirty>>4)&1) DebugMessage(M64MSG_VERBOSE, "r4 "); if((regs[i].wasdirty>>5)&1) DebugMessage(M64MSG_VERBOSE, "r5 "); if((regs[i].wasdirty>>6)&1) DebugMessage(M64MSG_VERBOSE, "r6 "); if((regs[i].wasdirty>>7)&1) DebugMessage(M64MSG_VERBOSE, "r7 "); if((regs[i].wasdirty>>8)&1) DebugMessage(M64MSG_VERBOSE, "r8 "); if((regs[i].wasdirty>>9)&1) DebugMessage(M64MSG_VERBOSE, "r9 "); if((regs[i].wasdirty>>10)&1) DebugMessage(M64MSG_VERBOSE, "r10 "); if((regs[i].wasdirty>>12)&1) DebugMessage(M64MSG_VERBOSE, "r12 "); #endif disassemble_inst(i); //printf ("ccadj[%d] = %d",i,ccadj[i]); #if NEW_DYNAREC == NEW_DYNAREC_X86 DebugMessage(M64MSG_VERBOSE, "eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d dirty: ",regs[i].regmap[0],regs[i].regmap[1],regs[i].regmap[2],regs[i].regmap[3],regs[i].regmap[5],regs[i].regmap[6],regs[i].regmap[7]); if(regs[i].dirty&1) DebugMessage(M64MSG_VERBOSE, "eax "); if((regs[i].dirty>>1)&1) DebugMessage(M64MSG_VERBOSE, "ecx "); if((regs[i].dirty>>2)&1) DebugMessage(M64MSG_VERBOSE, "edx "); if((regs[i].dirty>>3)&1) DebugMessage(M64MSG_VERBOSE, "ebx "); if((regs[i].dirty>>5)&1) DebugMessage(M64MSG_VERBOSE, "ebp "); if((regs[i].dirty>>6)&1) DebugMessage(M64MSG_VERBOSE, "esi "); if((regs[i].dirty>>7)&1) DebugMessage(M64MSG_VERBOSE, "edi "); #endif #if NEW_DYNAREC == NEW_DYNAREC_ARM DebugMessage(M64MSG_VERBOSE, "r0=%d r1=%d r2=%d r3=%d r4=%d r5=%d r6=%d r7=%d r8=%d r9=%d r10=%d r12=%d dirty: ",regs[i].regmap[0],regs[i].regmap[1],regs[i].regmap[2],regs[i].regmap[3],regs[i].regmap[4],regs[i].regmap[5],regs[i].regmap[6],regs[i].regmap[7],regs[i].regmap[8],regs[i].regmap[9],regs[i].regmap[10],regs[i].regmap[12]); if(regs[i].dirty&1) DebugMessage(M64MSG_VERBOSE, "r0 "); if((regs[i].dirty>>1)&1) DebugMessage(M64MSG_VERBOSE, "r1 "); if((regs[i].dirty>>2)&1) DebugMessage(M64MSG_VERBOSE, "r2 "); if((regs[i].dirty>>3)&1) DebugMessage(M64MSG_VERBOSE, "r3 "); if((regs[i].dirty>>4)&1) DebugMessage(M64MSG_VERBOSE, "r4 "); if((regs[i].dirty>>5)&1) DebugMessage(M64MSG_VERBOSE, "r5 "); if((regs[i].dirty>>6)&1) DebugMessage(M64MSG_VERBOSE, "r6 "); if((regs[i].dirty>>7)&1) DebugMessage(M64MSG_VERBOSE, "r7 "); if((regs[i].dirty>>8)&1) DebugMessage(M64MSG_VERBOSE, "r8 "); if((regs[i].dirty>>9)&1) DebugMessage(M64MSG_VERBOSE, "r9 "); if((regs[i].dirty>>10)&1) DebugMessage(M64MSG_VERBOSE, "r10 "); if((regs[i].dirty>>12)&1) DebugMessage(M64MSG_VERBOSE, "r12 "); #endif if(regs[i].isconst) { DebugMessage(M64MSG_VERBOSE, "constants: "); #if NEW_DYNAREC == NEW_DYNAREC_X86 if(regs[i].isconst&1) DebugMessage(M64MSG_VERBOSE, "eax=%x ",(int)constmap[i][0]); if((regs[i].isconst>>1)&1) DebugMessage(M64MSG_VERBOSE, "ecx=%x ",(int)constmap[i][1]); if((regs[i].isconst>>2)&1) DebugMessage(M64MSG_VERBOSE, "edx=%x ",(int)constmap[i][2]); if((regs[i].isconst>>3)&1) DebugMessage(M64MSG_VERBOSE, "ebx=%x ",(int)constmap[i][3]); if((regs[i].isconst>>5)&1) DebugMessage(M64MSG_VERBOSE, "ebp=%x ",(int)constmap[i][5]); if((regs[i].isconst>>6)&1) DebugMessage(M64MSG_VERBOSE, "esi=%x ",(int)constmap[i][6]); if((regs[i].isconst>>7)&1) DebugMessage(M64MSG_VERBOSE, "edi=%x ",(int)constmap[i][7]); #endif #if NEW_DYNAREC == NEW_DYNAREC_ARM if(regs[i].isconst&1) DebugMessage(M64MSG_VERBOSE, "r0=%x ",(int)constmap[i][0]); if((regs[i].isconst>>1)&1) DebugMessage(M64MSG_VERBOSE, "r1=%x ",(int)constmap[i][1]); if((regs[i].isconst>>2)&1) DebugMessage(M64MSG_VERBOSE, "r2=%x ",(int)constmap[i][2]); if((regs[i].isconst>>3)&1) DebugMessage(M64MSG_VERBOSE, "r3=%x ",(int)constmap[i][3]); if((regs[i].isconst>>4)&1) DebugMessage(M64MSG_VERBOSE, "r4=%x ",(int)constmap[i][4]); if((regs[i].isconst>>5)&1) DebugMessage(M64MSG_VERBOSE, "r5=%x ",(int)constmap[i][5]); if((regs[i].isconst>>6)&1) DebugMessage(M64MSG_VERBOSE, "r6=%x ",(int)constmap[i][6]); if((regs[i].isconst>>7)&1) DebugMessage(M64MSG_VERBOSE, "r7=%x ",(int)constmap[i][7]); if((regs[i].isconst>>8)&1) DebugMessage(M64MSG_VERBOSE, "r8=%x ",(int)constmap[i][8]); if((regs[i].isconst>>9)&1) DebugMessage(M64MSG_VERBOSE, "r9=%x ",(int)constmap[i][9]); if((regs[i].isconst>>10)&1) DebugMessage(M64MSG_VERBOSE, "r10=%x ",(int)constmap[i][10]); if((regs[i].isconst>>12)&1) DebugMessage(M64MSG_VERBOSE, "r12=%x ",(int)constmap[i][12]); #endif } DebugMessage(M64MSG_VERBOSE, " 32:"); for(r=0;r<=CCREG;r++) { if((regs[i].is32>>r)&1) { if(r==CCREG) DebugMessage(M64MSG_VERBOSE, " CC"); else if(r==HIREG) DebugMessage(M64MSG_VERBOSE, " HI"); else if(r==LOREG) DebugMessage(M64MSG_VERBOSE, " LO"); else DebugMessage(M64MSG_VERBOSE, " r%d",r); } } /*DebugMessage(M64MSG_VERBOSE, " p32:"); for(r=0;r<=CCREG;r++) { if((p32[i]>>r)&1) { if(r==CCREG) DebugMessage(M64MSG_VERBOSE, " CC"); else if(r==HIREG) DebugMessage(M64MSG_VERBOSE, " HI"); else if(r==LOREG) DebugMessage(M64MSG_VERBOSE, " LO"); else DebugMessage(M64MSG_VERBOSE, " r%d",r); } } if(p32[i]!=regs[i].is32) DebugMessage(M64MSG_VERBOSE, " NO MATCH");*/ if(itype[i]==RJUMP||itype[i]==UJUMP||itype[i]==CJUMP||itype[i]==SJUMP||itype[i]==FJUMP) { #if NEW_DYNAREC == NEW_DYNAREC_X86 DebugMessage(M64MSG_VERBOSE, "branch(%d): eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d dirty: ",i,branch_regs[i].regmap[0],branch_regs[i].regmap[1],branch_regs[i].regmap[2],branch_regs[i].regmap[3],branch_regs[i].regmap[5],branch_regs[i].regmap[6],branch_regs[i].regmap[7]); if(branch_regs[i].dirty&1) DebugMessage(M64MSG_VERBOSE, "eax "); if((branch_regs[i].dirty>>1)&1) DebugMessage(M64MSG_VERBOSE, "ecx "); if((branch_regs[i].dirty>>2)&1) DebugMessage(M64MSG_VERBOSE, "edx "); if((branch_regs[i].dirty>>3)&1) DebugMessage(M64MSG_VERBOSE, "ebx "); if((branch_regs[i].dirty>>5)&1) DebugMessage(M64MSG_VERBOSE, "ebp "); if((branch_regs[i].dirty>>6)&1) DebugMessage(M64MSG_VERBOSE, "esi "); if((branch_regs[i].dirty>>7)&1) DebugMessage(M64MSG_VERBOSE, "edi "); #endif #if NEW_DYNAREC == NEW_DYNAREC_ARM DebugMessage(M64MSG_VERBOSE, "branch(%d): r0=%d r1=%d r2=%d r3=%d r4=%d r5=%d r6=%d r7=%d r8=%d r9=%d r10=%d r12=%d dirty: ",i,branch_regs[i].regmap[0],branch_regs[i].regmap[1],branch_regs[i].regmap[2],branch_regs[i].regmap[3],branch_regs[i].regmap[4],branch_regs[i].regmap[5],branch_regs[i].regmap[6],branch_regs[i].regmap[7],branch_regs[i].regmap[8],branch_regs[i].regmap[9],branch_regs[i].regmap[10],branch_regs[i].regmap[12]); if(branch_regs[i].dirty&1) DebugMessage(M64MSG_VERBOSE, "r0 "); if((branch_regs[i].dirty>>1)&1) DebugMessage(M64MSG_VERBOSE, "r1 "); if((branch_regs[i].dirty>>2)&1) DebugMessage(M64MSG_VERBOSE, "r2 "); if((branch_regs[i].dirty>>3)&1) DebugMessage(M64MSG_VERBOSE, "r3 "); if((branch_regs[i].dirty>>4)&1) DebugMessage(M64MSG_VERBOSE, "r4 "); if((branch_regs[i].dirty>>5)&1) DebugMessage(M64MSG_VERBOSE, "r5 "); if((branch_regs[i].dirty>>6)&1) DebugMessage(M64MSG_VERBOSE, "r6 "); if((branch_regs[i].dirty>>7)&1) DebugMessage(M64MSG_VERBOSE, "r7 "); if((branch_regs[i].dirty>>8)&1) DebugMessage(M64MSG_VERBOSE, "r8 "); if((branch_regs[i].dirty>>9)&1) DebugMessage(M64MSG_VERBOSE, "r9 "); if((branch_regs[i].dirty>>10)&1) DebugMessage(M64MSG_VERBOSE, "r10 "); if((branch_regs[i].dirty>>12)&1) DebugMessage(M64MSG_VERBOSE, "r12 "); #endif DebugMessage(M64MSG_VERBOSE, " 32:"); for(r=0;r<=CCREG;r++) { if((branch_regs[i].is32>>r)&1) { if(r==CCREG) DebugMessage(M64MSG_VERBOSE, " CC"); else if(r==HIREG) DebugMessage(M64MSG_VERBOSE, " HI"); else if(r==LOREG) DebugMessage(M64MSG_VERBOSE, " LO"); else DebugMessage(M64MSG_VERBOSE, " r%d",r); } } } } #endif /* Pass 8 - Assembly */ linkcount=0;stubcount=0; ds=0;is_delayslot=0; cop1_usable=0; #ifndef DESTRUCTIVE_WRITEBACK uint64_t is32_pre=0; u_int dirty_pre=0; #endif u_int beginning=(u_int)out; if((u_int)addr&1) { ds=1; pagespan_ds(); } for(i=0;i>16)!=0x1000)) { wb_sx(regmap_pre[i],regs[i].regmap_entry,regs[i].wasdirty,is32_pre,regs[i].was32, unneeded_reg[i],unneeded_reg_upper[i]); wb_valid(regmap_pre[i],regs[i].regmap_entry,dirty_pre,regs[i].wasdirty,is32_pre, unneeded_reg[i],unneeded_reg_upper[i]); } is32_pre=regs[i].is32; dirty_pre=regs[i].dirty; #endif // write back if(i<2||(itype[i-2]!=UJUMP&&itype[i-2]!=RJUMP&&(source[i-2]>>16)!=0x1000)) { wb_invalidate(regmap_pre[i],regs[i].regmap_entry,regs[i].wasdirty,regs[i].was32, unneeded_reg[i],unneeded_reg_upper[i]); loop_preload(regmap_pre[i],regs[i].regmap_entry); } // branch target entry point instr_addr[i]=(u_int)out; assem_debug("<->"); // load regs if(regs[i].regmap_entry[HOST_CCREG]==CCREG&®s[i].regmap[HOST_CCREG]!=CCREG) wb_register(CCREG,regs[i].regmap_entry,regs[i].wasdirty,regs[i].was32); load_regs(regs[i].regmap_entry,regs[i].regmap,regs[i].was32,rs1[i],rs2[i]); address_generation(i,®s[i],regs[i].regmap_entry); load_consts(regmap_pre[i],regs[i].regmap,regs[i].was32,i); if(itype[i]==RJUMP||itype[i]==UJUMP||itype[i]==CJUMP||itype[i]==SJUMP||itype[i]==FJUMP) { // Load the delay slot registers if necessary if(rs1[i+1]!=rs1[i]&&rs1[i+1]!=rs2[i]) load_regs(regs[i].regmap_entry,regs[i].regmap,regs[i].was32,rs1[i+1],rs1[i+1]); if(rs2[i+1]!=rs1[i+1]&&rs2[i+1]!=rs1[i]&&rs2[i+1]!=rs2[i]) load_regs(regs[i].regmap_entry,regs[i].regmap,regs[i].was32,rs2[i+1],rs2[i+1]); if(itype[i+1]==STORE||itype[i+1]==STORELR||(opcode[i+1]&0x3b)==0x39) load_regs(regs[i].regmap_entry,regs[i].regmap,regs[i].was32,INVCP,INVCP); } else if(i+1>16)==0x1000) literal_pool(1024); else literal_pool_jumpover(256); } } //assert(itype[i-2]==UJUMP||itype[i-2]==RJUMP||(source[i-2]>>16)==0x1000); // If the block did not end with an unconditional branch, // add a jump to the next instruction. if(i>1) { if(itype[i-2]!=UJUMP&&itype[i-2]!=RJUMP&&(source[i-2]>>16)!=0x1000&&itype[i-1]!=SPAN) { assert(itype[i-1]!=UJUMP&&itype[i-1]!=CJUMP&&itype[i-1]!=SJUMP&&itype[i-1]!=RJUMP&&itype[i-1]!=FJUMP); assert(i==slen); if(itype[i-2]!=CJUMP&&itype[i-2]!=SJUMP&&itype[i-2]!=FJUMP) { store_regs_bt(regs[i-1].regmap,regs[i-1].is32,regs[i-1].dirty,start+i*4); if(regs[i-1].regmap[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG); emit_addimm(HOST_CCREG,CLOCK_DIVIDER*(ccadj[i-1]+1),HOST_CCREG); } else if(!likely[i-2]) { store_regs_bt(branch_regs[i-2].regmap,branch_regs[i-2].is32,branch_regs[i-2].dirty,start+i*4); assert(branch_regs[i-2].regmap[HOST_CCREG]==CCREG); } else { store_regs_bt(regs[i-2].regmap,regs[i-2].is32,regs[i-2].dirty,start+i*4); assert(regs[i-2].regmap[HOST_CCREG]==CCREG); } add_to_linker((intptr_t)out,start+i*4,0); emit_jmp(0); } } else { assert(i>0); assert(itype[i-1]!=UJUMP&&itype[i-1]!=CJUMP&&itype[i-1]!=SJUMP&&itype[i-1]!=RJUMP&&itype[i-1]!=FJUMP); store_regs_bt(regs[i-1].regmap,regs[i-1].is32,regs[i-1].dirty,start+i*4); if(regs[i-1].regmap[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG); emit_addimm(HOST_CCREG,CLOCK_DIVIDER*(ccadj[i-1]+1),HOST_CCREG); add_to_linker((intptr_t)out,start+i*4,0); emit_jmp(0); } // TODO: delay slot stubs? // Stubs for(i=0;i %8x",link_addr[i][0],link_addr[i][1]); literal_pool(64); if(!link_addr[i][2]) { void *stub=out; void *addr=check_addr(link_addr[i][1]); emit_extjump(link_addr[i][0],link_addr[i][1]); if(addr) { set_jump_target(link_addr[i][0],(int)addr); add_link(link_addr[i][1],stub); } else set_jump_target(link_addr[i][0],(int)stub); } else { // Internal branch int target=(link_addr[i][1]-start)>>2; assert(target>=0&&target>1); //#else set_jump_target(link_addr[i][0],instr_addr[target]); //#endif } } // External Branch Targets (jump_in) if(copy+slen*4>(void *)shadow+sizeof(shadow)) copy=shadow; for(i=0;i>12; u_int vpage=page; if(page>262143&&tlb_LUT_r[vaddr>>12]) page=(tlb_LUT_r[page^0x80000]^0x80000000)>>12; if(page>2048) page=2048+(page&2047); if(vpage>262143&&tlb_LUT_r[vaddr>>12]) vpage&=2047; // jump_dirty uses a hash of the virtual address instead if(vpage>2048) vpage=2048+(vpage&2047); literal_pool(256); //if(!(is32[i]&(~unneeded_reg_upper[i])&~(1LL<>16)^vaddr)&0xFFFF]; if(ht_bin[0]==vaddr) { ht_bin[1]=entry_point; } if(ht_bin[2]==vaddr) { ht_bin[3]=entry_point; } } else { u_int r=requires_32bit[i]|!!(requires_32bit[i]>>32); assem_debug("%8x (%d) <- %8x",instr_addr[i],i,start+i*4); assem_debug("jump_in: %x (restricted - %x)",start+i*4,r); //int entry_point=(int)out; ////assem_debug("entry_point: %x",entry_point); //load_regs_entry(i); //if(entry_point==(int)out) // entry_point=instr_addr[i]; //else // emit_jmp(instr_addr[i]); //ll_add_32(jump_in+page,vaddr,r,(void *)entry_point); ll_add_32(jump_dirty+vpage,vaddr,r,(void *)out); int entry_point=do_dirty_stub(i); ll_add_32(jump_in+page,vaddr,r,(void *)entry_point); } } } } // Write out the literal pool if necessary literal_pool(0); #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK // Align code if(((u_int)out)&7) emit_addnop(13); #endif assert((u_int)out-beginning (u_char *)(base_addr+(1<>12;i<=(start+slen*4)>>12;i++) { invalid_code[i]=0; memory_map[i]|=0x40000000; if((signed int)start>=(signed int)0xC0000000) { assert(using_tlb); j=(((u_int)i<<12)+(memory_map[i]<<2)-(u_int)g_rdram+(u_int)0x80000000)>>12; invalid_code[j]=0; memory_map[j]|=0x40000000; //DebugMessage(M64MSG_VERBOSE, "write protect physical page: %x (virtual %x)",j<<12,start); } } /* Pass 10 - Free memory by expiring oldest blocks */ int end=((((intptr_t)out-(intptr_t)base_addr)>>(TARGET_SIZE_2-16))+16384)&65535; while(expirep!=end) { int shift=TARGET_SIZE_2-3; // Divide into 8 blocks int base=(int)base_addr+((expirep>>13)<>11)&3) { case 0: // Clear jump_in and jump_dirty ll_remove_matching_addrs(jump_in+(expirep&2047),base,shift); ll_remove_matching_addrs(jump_dirty+(expirep&2047),base,shift); ll_remove_matching_addrs(jump_in+2048+(expirep&2047),base,shift); ll_remove_matching_addrs(jump_dirty+2048+(expirep&2047),base,shift); break; case 1: // Clear pointers ll_kill_pointers(jump_out[expirep&2047],base,shift); ll_kill_pointers(jump_out[(expirep&2047)+2048],base,shift); break; case 2: // Clear hash table for(i=0;i<32;i++) { u_int *ht_bin=hash_table[((expirep&2047)<<5)+i]; if(((ht_bin[3]-(u_int)base_addr)>>shift)==((base-(u_int)base_addr)>>shift) || ((ht_bin[3]-(u_int)base_addr-MAX_OUTPUT_BLOCK_SIZE)>>shift)==((base-(u_int)base_addr)>>shift)) { inv_debug("EXP: Remove hash %x -> %x\n",ht_bin[2],ht_bin[3]); ht_bin[2]=ht_bin[3]=-1; } if(((ht_bin[1]-(u_int)base_addr)>>shift)==((base-(u_int)base_addr)>>shift) || ((ht_bin[1]-(u_int)base_addr-MAX_OUTPUT_BLOCK_SIZE)>>shift)==((base-(u_int)base_addr)>>shift)) { inv_debug("EXP: Remove hash %x -> %x\n",ht_bin[0],ht_bin[1]); ht_bin[0]=ht_bin[2]; ht_bin[1]=ht_bin[3]; ht_bin[2]=ht_bin[3]=-1; } } break; case 3: // Clear jump_out #if NEW_DYNAREC == NEW_DYNAREC_ARM if((expirep&2047)==0) do_clear_cache(); #endif ll_remove_matching_addrs(jump_out+(expirep&2047),base,shift); ll_remove_matching_addrs(jump_out+2048+(expirep&2047),base,shift); break; } expirep=(expirep+1)&65535; } return 0; } void TLBWI_new(void) { unsigned int i; /* Remove old entries */ unsigned int old_start_even=tlb_e[g_cp0_regs[CP0_INDEX_REG] & 0x3F].start_even; unsigned int old_end_even=tlb_e[g_cp0_regs[CP0_INDEX_REG] & 0x3F].end_even; unsigned int old_start_odd=tlb_e[g_cp0_regs[CP0_INDEX_REG] & 0x3F].start_odd; unsigned int old_end_odd=tlb_e[g_cp0_regs[CP0_INDEX_REG] & 0x3F].end_odd; for (i=old_start_even>>12; i<=old_end_even>>12; i++) { if(i<0x80000||i>0xBFFFF) { invalidate_block(i); memory_map[i]=-1; } } for (i=old_start_odd>>12; i<=old_end_odd>>12; i++) { if(i<0x80000||i>0xBFFFF) { invalidate_block(i); memory_map[i]=-1; } } cached_interpreter_table.TLBWI(); //DebugMessage(M64MSG_VERBOSE, "TLBWI: index=%d",g_cp0_regs[CP0_INDEX_REG]); //DebugMessage(M64MSG_VERBOSE, "TLBWI: start_even=%x end_even=%x phys_even=%x v=%d d=%d",tlb_e[g_cp0_regs[CP0_INDEX_REG] & 0x3F].start_even,tlb_e[g_cp0_regs[CP0_INDEX_REG] & 0x3F].end_even,tlb_e[g_cp0_regs[CP0_INDEX_REG] & 0x3F].phys_even,tlb_e[g_cp0_regs[CP0_INDEX_REG]&0x3F].v_even,tlb_e[g_cp0_regs[CP0_INDEX_REG]&0x3F].d_even); //DebugMessage(M64MSG_VERBOSE, "TLBWI: start_odd=%x end_odd=%x phys_odd=%x v=%d d=%d",tlb_e[g_cp0_regs[CP0_INDEX_REG]&0x3F].start_odd,tlb_e[g_cp0_regs[CP0_INDEX_REG]&0x3F].end_odd,tlb_e[g_cp0_regs[CP0_INDEX_REG]&0x3F].phys_odd,tlb_e[g_cp0_regs[CP0_INDEX_REG]&0x3F].v_odd,tlb_e[g_cp0_regs[CP0_INDEX_REG]&0x3F].d_odd); /* Combine tlb_LUT_r, tlb_LUT_w, and invalid_code into a single table for fast look up. */ for (i=tlb_e[g_cp0_regs[CP0_INDEX_REG] & 0x3F].start_even>>12; i<=tlb_e[g_cp0_regs[CP0_INDEX_REG] & 0x3F].end_even>>12; i++) { //DebugMessage(M64MSG_VERBOSE, "%x: r:%8x w:%8x",i,tlb_LUT_r[i],tlb_LUT_w[i]); if(i<0x80000||i>0xBFFFF) { if(tlb_LUT_r[i]) { memory_map[i]=((tlb_LUT_r[i]&0xFFFFF000)-(i<<12)+(unsigned int)g_rdram-0x80000000)>>2; // FIXME: should make sure the physical page is invalid too if(!tlb_LUT_w[i]||!invalid_code[i]) { memory_map[i]|=0x40000000; // Write protect }else{ assert(tlb_LUT_r[i]==tlb_LUT_w[i]); } if(!using_tlb) DebugMessage(M64MSG_VERBOSE, "Enabled TLB"); // Tell the dynamic recompiler to generate tlb lookup code using_tlb=1; } else memory_map[i]=-1; } //DebugMessage(M64MSG_VERBOSE, "memory_map[%x]: %8x (+%8x)",i,memory_map[i],memory_map[i]<<2); } for (i=tlb_e[g_cp0_regs[CP0_INDEX_REG] & 0x3F].start_odd>>12; i<=tlb_e[g_cp0_regs[CP0_INDEX_REG] & 0x3F].end_odd>>12; i++) { //DebugMessage(M64MSG_VERBOSE, "%x: r:%8x w:%8x",i,tlb_LUT_r[i],tlb_LUT_w[i]); if(i<0x80000||i>0xBFFFF) { if(tlb_LUT_r[i]) { memory_map[i]=((tlb_LUT_r[i]&0xFFFFF000)-(i<<12)+(unsigned int)g_rdram-0x80000000)>>2; // FIXME: should make sure the physical page is invalid too if(!tlb_LUT_w[i]||!invalid_code[i]) { memory_map[i]|=0x40000000; // Write protect }else{ assert(tlb_LUT_r[i]==tlb_LUT_w[i]); } if(!using_tlb) DebugMessage(M64MSG_VERBOSE, "Enabled TLB"); // Tell the dynamic recompiler to generate tlb lookup code using_tlb=1; } else memory_map[i]=-1; } //DebugMessage(M64MSG_VERBOSE, "memory_map[%x]: %8x (+%8x)",i,memory_map[i],memory_map[i]<<2); } } void TLBWR_new(void) { unsigned int i; g_cp0_regs[CP0_RANDOM_REG] = (g_cp0_regs[CP0_COUNT_REG]/2 % (32 - g_cp0_regs[CP0_WIRED_REG])) + g_cp0_regs[CP0_WIRED_REG]; /* Remove old entries */ unsigned int old_start_even=tlb_e[g_cp0_regs[CP0_RANDOM_REG]&0x3F].start_even; unsigned int old_end_even=tlb_e[g_cp0_regs[CP0_RANDOM_REG]&0x3F].end_even; unsigned int old_start_odd=tlb_e[g_cp0_regs[CP0_RANDOM_REG]&0x3F].start_odd; unsigned int old_end_odd=tlb_e[g_cp0_regs[CP0_RANDOM_REG]&0x3F].end_odd; for (i=old_start_even>>12; i<=old_end_even>>12; i++) { if(i<0x80000||i>0xBFFFF) { invalidate_block(i); memory_map[i]=-1; } } for (i=old_start_odd>>12; i<=old_end_odd>>12; i++) { if(i<0x80000||i>0xBFFFF) { invalidate_block(i); memory_map[i]=-1; } } cached_interpreter_table.TLBWR(); /* Combine tlb_LUT_r, tlb_LUT_w, and invalid_code into a single table for fast look up. */ for (i=tlb_e[g_cp0_regs[CP0_RANDOM_REG]&0x3F].start_even>>12; i<=tlb_e[g_cp0_regs[CP0_RANDOM_REG]&0x3F].end_even>>12; i++) { //DebugMessage(M64MSG_VERBOSE, "%x: r:%8x w:%8x",i,tlb_LUT_r[i],tlb_LUT_w[i]); if(i<0x80000||i>0xBFFFF) { if(tlb_LUT_r[i]) { memory_map[i]=((tlb_LUT_r[i]&0xFFFFF000)-(i<<12)+(unsigned int)g_rdram-0x80000000)>>2; // FIXME: should make sure the physical page is invalid too if(!tlb_LUT_w[i]||!invalid_code[i]) { memory_map[i]|=0x40000000; // Write protect }else{ assert(tlb_LUT_r[i]==tlb_LUT_w[i]); } if(!using_tlb) DebugMessage(M64MSG_VERBOSE, "Enabled TLB"); // Tell the dynamic recompiler to generate tlb lookup code using_tlb=1; } else memory_map[i]=-1; } //DebugMessage(M64MSG_VERBOSE, "memory_map[%x]: %8x (+%8x)",i,memory_map[i],memory_map[i]<<2); } for (i= tlb_e[g_cp0_regs[CP0_RANDOM_REG] & 0x3F].start_odd >> 12; i<= tlb_e[g_cp0_regs[CP0_RANDOM_REG]&0x3F].end_odd>>12; i++) { //DebugMessage(M64MSG_VERBOSE, "%x: r:%8x w:%8x",i,tlb_LUT_r[i],tlb_LUT_w[i]); if(i<0x80000||i>0xBFFFF) { if(tlb_LUT_r[i]) { memory_map[i]=((tlb_LUT_r[i]&0xFFFFF000)-(i<<12)+(unsigned int)g_rdram-0x80000000)>>2; // FIXME: should make sure the physical page is invalid too if(!tlb_LUT_w[i]||!invalid_code[i]) { memory_map[i]|=0x40000000; // Write protect }else{ assert(tlb_LUT_r[i]==tlb_LUT_w[i]); } if(!using_tlb) DebugMessage(M64MSG_VERBOSE, "Enabled TLB"); // Tell the dynamic recompiler to generate tlb lookup code using_tlb=1; } else memory_map[i]=-1; } //DebugMessage(M64MSG_VERBOSE, "memory_map[%x]: %8x (+%8x)",i,memory_map[i],memory_map[i]<<2); } } gles2rice/src/GraphicsContext.h000664 001750 001750 00000004123 12655644434 017643 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef GFXCONTEXT_H #define GFXCONTEXT_H #include "typedefs.h" enum ClearFlag { CLEAR_COLOR_BUFFER = 0x01, CLEAR_DEPTH_BUFFER = 0x02, CLEAR_COLOR_AND_DEPTH_BUFFER = 0x03, }; typedef struct { uint32_t addr; //N64 RDRAM address uint32_t size; //N64 buffer size uint32_t format; //N64 format uint32_t width; uint32_t height; } TextureBufferShortInfo; // This class basically provides an extra level of security for our // multi-threaded code. Threads can Grab the CGraphicsContext to prevent // other threads from changing/releasing any of the pointers while it is // running. class CGraphicsContext { friend class CDeviceBuilder; public: virtual bool Initialize(uint32_t dwWidth, uint32_t dwHeight); virtual bool ResizeInitialize(uint32_t dwWidth, uint32_t dwHeight); virtual void CleanUp(); virtual void Clear(ClearFlag flags, uint32_t color, float depth) = 0; virtual void UpdateFrame(bool swapOnly) = 0; static void InitWindowInfo(); static void InitDeviceParameters(); public: protected: char m_strDeviceStats[256]; virtual ~CGraphicsContext(); CGraphicsContext(); public: static CGraphicsContext *g_pGraphicsContext; static CGraphicsContext * Get(void); inline const char* GetDeviceStr() {return m_strDeviceStats;} static bool needCleanScene; }; #endif gles2n64/src/GBI.c000664 001750 001750 00000023653 12655644434 014630 0ustar00sergiosergio000000 000000 #include #ifdef _MSC_VER #include #else #include #endif #include #include "gles2N64.h" #include "GBI.h" #include "RDP.h" #include "RSP.h" #include "F3D.h" #include "F3DEX.h" #include "F3DEX2.h" #include "L3D.h" #include "L3DEX.h" #include "L3DEX2.h" #include "S2DEX.h" #include "S2DEX2.h" #include "F3DDKR.h" #include "F3DSWSE.h" #include "F3DWRUS.h" #include "F3DPD.h" #include "F3DEX2CBFD.h" #include "ZSort.h" #include "Types.h" # include # include # include "convert.h" #include "Common.h" #include "CRC.h" #include "Debug.h" #ifdef __LIBRETRO__ // Prefix symbol #define uc_crc gln64uc_crc #endif u32 uc_crc, uc_dcrc; char uc_str[256]; SpecialMicrocodeInfo specialMicrocodes[] = { { F3D, FALSE, 0xe62a706d, "Fast3D" }, { F3D, FALSE, 0x7d372819, "Fast3D" }, { F3D, FALSE, 0x2edee7be, "Fast3D" }, { F3D, FALSE, 0xe01e14be, "Fast3D" }, { F3D, FALSE, 0x4AED6B3B, "Fast3D" }, /* Vivid Dolls [ALECK64] */ { F3DWRUS, FALSE, 0xd17906e2, "RSP SW Version: 2.0D, 04-01-96" }, { F3DSWSE, FALSE, 0x94c4c833, "RSP SW Version: 2.0D, 04-01-96" }, { F3DEX, TRUE, 0x637b4b58, "RSP SW Version: 2.0D, 04-01-96" }, { F3D, TRUE, 0x54c558ba, "RSP SW Version: 2.0D, 04-01-96" }, // Pilot Wings { F3D, TRUE, 0x302bca09, "RSP SW Version: 2.0G, 09-30-96" }, // GoldenEye { S2DEX, FALSE, 0x9df31081, "RSP Gfx ucode S2DEX 1.06 Yoshitaka Yasumoto Nintendo." }, { F3DDKR, FALSE, 0x8d91244f, "Diddy Kong Racing" }, { F3DDKR, FALSE, 0x6e6fc893, "Diddy Kong Racing" }, { F3DJFG, FALSE, 0xbde9d1fb, "Jet Force Gemini" }, { F3DPD, TRUE, 0x1c4f7869, "Perfect Dark" }, { Turbo3D, FALSE, 0x2bdcfc8a, "Turbo3D" }, { F3DEX2CBFD, TRUE, 0x1b4ace88, "Conker's Bad Fur Day" } }; u32 G_RDPHALF_1, G_RDPHALF_2, G_RDPHALF_CONT; u32 G_SPNOOP; u32 G_SETOTHERMODE_H, G_SETOTHERMODE_L; u32 G_DL, G_ENDDL, G_CULLDL, G_BRANCH_Z; u32 G_LOAD_UCODE; u32 G_MOVEMEM, G_MOVEWORD; u32 G_MTX, G_POPMTX; u32 G_GEOMETRYMODE, G_SETGEOMETRYMODE, G_CLEARGEOMETRYMODE; u32 G_TEXTURE; u32 G_DMA_IO, G_DMA_DL, G_DMA_TRI, G_DMA_MTX, G_DMA_VTX, G_DMA_TEX_OFFSET, G_DMA_OFFSETS; u32 G_SPECIAL_1, G_SPECIAL_2, G_SPECIAL_3; u32 G_VTX, G_MODIFYVTX, G_VTXCOLORBASE; u32 G_TRI1, G_TRI2, G_TRI4; u32 G_QUAD, G_LINE3D; u32 G_RESERVED0, G_RESERVED1, G_RESERVED2, G_RESERVED3; u32 G_SPRITE2D_BASE; u32 G_BG_1CYC, G_BG_COPY; u32 G_OBJ_RECTANGLE, G_OBJ_SPRITE, G_OBJ_MOVEMEM; u32 G_SELECT_DL, G_OBJ_RENDERMODE, G_OBJ_RECTANGLE_R; u32 G_OBJ_LOADTXTR, G_OBJ_LDTX_SPRITE, G_OBJ_LDTX_RECT, G_OBJ_LDTX_RECT_R; u32 G_RDPHALF_0; /* TODO/FIXME - remove? */ u32 G_TRI_UNKNOWN; u32 G_MTX_STACKSIZE; u32 G_MTX_MODELVIEW; u32 G_MTX_PROJECTION; u32 G_MTX_MUL; u32 G_MTX_LOAD; u32 G_MTX_NOPUSH; u32 G_MTX_PUSH; u32 G_TEXTURE_ENABLE; u32 G_SHADING_SMOOTH; u32 G_CULL_FRONT; u32 G_CULL_BACK; u32 G_CULL_BOTH; u32 G_CLIPPING; u32 G_MV_VIEWPORT; u32 G_MWO_aLIGHT_1, G_MWO_bLIGHT_1; u32 G_MWO_aLIGHT_2, G_MWO_bLIGHT_2; u32 G_MWO_aLIGHT_3, G_MWO_bLIGHT_3; u32 G_MWO_aLIGHT_4, G_MWO_bLIGHT_4; u32 G_MWO_aLIGHT_5, G_MWO_bLIGHT_5; u32 G_MWO_aLIGHT_6, G_MWO_bLIGHT_6; u32 G_MWO_aLIGHT_7, G_MWO_bLIGHT_7; u32 G_MWO_aLIGHT_8, G_MWO_bLIGHT_8; GBIInfo GBI; static u32 current_type; u32 GBI_GetCurrentMicrocodeType(void) { return current_type; } void GBI_Unknown( u32 w0, u32 w1 ) { #ifdef DEBUG if (Debug.level == DEBUG_LOW) DebugMsg( DEBUG_LOW | DEBUG_UNKNOWN, "UNKNOWN GBI COMMAND 0x%02X", _SHIFTR( w0, 24, 8 ) ); if (Debug.level == DEBUG_MEDIUM) DebugMsg( DEBUG_MEDIUM | DEBUG_UNKNOWN, "Unknown GBI Command 0x%02X", _SHIFTR( w0, 24, 8 ) ); else if (Debug.level == DEBUG_HIGH) DebugMsg( DEBUG_HIGH | DEBUG_UNKNOWN, "// Unknown GBI Command 0x%02X", _SHIFTR( w0, 24, 8 ) ); #endif } static int MicrocodeDialog(void) { return 0; } MicrocodeInfo *GBI_AddMicrocode(void) { MicrocodeInfo *newtop = (MicrocodeInfo*)malloc( sizeof( MicrocodeInfo ) ); newtop->lower = GBI.top; newtop->higher = NULL; if (GBI.top) GBI.top->higher = newtop; if (!GBI.bottom) GBI.bottom = newtop; GBI.top = newtop; GBI.numMicrocodes++; return newtop; } void GBI_Init(void) { u32 i; GBI.top = NULL; GBI.bottom = NULL; GBI.current = NULL; GBI.numMicrocodes = 0; for (i = 0; i <= 0xFF; i++) GBI.cmd[i] = GBI_Unknown; } void GBI_Destroy(void) { while (GBI.bottom) { MicrocodeInfo *newBottom = GBI.bottom->higher; if (GBI.bottom == GBI.top) GBI.top = NULL; free( GBI.bottom ); GBI.bottom = newBottom; if (GBI.bottom) GBI.bottom->lower = NULL; GBI.numMicrocodes--; } } static INLINE bool _isDigit(char _c) { return _c >= '0' && _c <= '9'; } MicrocodeInfo *GBI_DetectMicrocode( u32 uc_start, u32 uc_dstart, u16 uc_dsize ) { unsigned i; char uc_data[2048]; MicrocodeInfo *current; for (i = 0; i < GBI.numMicrocodes; i++) { current = GBI.top; while (current) { if ((current->address == uc_start) && (current->dataAddress == uc_dstart) && (current->dataSize == uc_dsize)) return current; current = current->lower; } } current = GBI_AddMicrocode(); current->address = uc_start; current->dataAddress = uc_dstart; current->dataSize = uc_dsize; current->NoN = FALSE; current->type = NONE; // See if we can identify it by CRC uc_crc = CRC_Calculate(&gfx_info.RDRAM[uc_start & 0x1FFFFFFF], 4096); LOG(LOG_MINIMAL, "UCODE CRC=0x%x\n", uc_crc); for (i = 0; i < sizeof( specialMicrocodes ) / sizeof( SpecialMicrocodeInfo ); i++) { if (uc_crc == specialMicrocodes[i].crc) { current->type = specialMicrocodes[i].type; current_type = current->type; return current; } } // See if we can identify it by text UnswapCopyWrap(gfx_info.RDRAM, uc_dstart & 0x1FFFFFFF, (u8*)uc_data, 0, 0x7FF, 2048); strcpy( uc_str, "Not Found" ); for (i = 0; i < 2048; i++) { if ((uc_data[i] == 'R') && (uc_data[i+1] == 'S') && (uc_data[i+2] == 'P')) { u32 j = 0; int type = NONE; while (uc_data[i+j] > 0x0A) { uc_str[j] = uc_data[i+j]; j++; } uc_str[j] = 0x00; if (strncmp( &uc_str[4], "SW", 2 ) == 0) type = F3D; else if (strncmp( &uc_str[4], "Gfx", 3 ) == 0) { current->NoN = (strncmp( &uc_str[20], ".NoN", 4 ) == 0); if (strncmp( &uc_str[14], "F3D", 3 ) == 0) { if (uc_str[28] == '1' || strncmp(&uc_str[28], "0.95", 4) == 0 || strncmp(&uc_str[28], "0.96", 4) == 0) type = F3DEX; else if (uc_str[31] == '2') type = F3DEX2; } else if (strncmp( &uc_str[14], "L3D", 3 ) == 0) { u32 t = 22; while (!_isDigit(uc_str[t]) && t++ < j); if (uc_str[t] == '1') type = L3DEX; else if (uc_str[t] == '2') type = L3DEX2; } else if (strncmp( &uc_str[14], "S2D", 3 ) == 0) { u32 t = 20; while (!_isDigit(uc_str[t]) && t++ < j); if (uc_str[t] == '1') type = S2DEX; else if (uc_str[t] == '2') type = S2DEX2; } else if (strncmp(&uc_str[14], "ZSortp", 6) == 0) type = ZSortp; } LOG(LOG_VERBOSE, "UCODE STRING=%s\n", uc_str); if (type != NONE) { current->type = type; current_type = type; return current; } break; } } for (i = 0; i < sizeof( specialMicrocodes ) / sizeof( SpecialMicrocodeInfo ); i++) { if (strcmp( uc_str, specialMicrocodes[i].text ) == 0) { current->type = specialMicrocodes[i].type; current_type = current->type; return current; } } // Let the user choose the microcode LOG(LOG_ERROR, "[gles2n64]: Warning - unknown ucode!!!\n"); if(last_good_ucode != (u32)-1) current->type=last_good_ucode; else current->type = MicrocodeDialog(); current_type = current->type; return current; } void GBI_MakeCurrent( MicrocodeInfo *current ) { int i; if (current != GBI.top) { if (current == GBI.bottom) { GBI.bottom = current->higher; GBI.bottom->lower = NULL; } else { current->higher->lower = current->lower; current->lower->higher = current->higher; } current->higher = NULL; current->lower = GBI.top; GBI.top->higher = current; GBI.top = current; } if (!GBI.current || (GBI.current->type != current->type)) { for (i = 0; i <= 0xFF; i++) GBI.cmd[i] = GBI_Unknown; RDP_Init(); switch (current->type) { case F3D: F3D_Init(); break; case F3DEX: F3DEX_Init(); break; case F3DEX2: F3DEX2_Init(); break; case L3D: L3D_Init(); break; case L3DEX: L3DEX_Init(); break; case L3DEX2: L3DEX2_Init(); break; case S2DEX: S2DEX_Init(); break; case S2DEX2: S2DEX2_Init(); break; case F3DDKR: F3DDKR_Init(); break; case F3DJFG: F3DJFG_Init(); break; case F3DSWSE: F3DSWSE_Init(); break; case F3DWRUS: F3DWRUS_Init(); break; case F3DPD: F3DPD_Init(); break; case Turbo3D: F3D_Init(); break; case ZSortp: ZSort_Init(); break; case F3DEX2CBFD:F3DEX2CBFD_Init(); break; } #ifdef NEW if (current->NoN) { // Disable near and far plane clipping glEnable(GL_DEPTH_CLAMP); // Enable Far clipping plane in vertex shader glEnable(GL_CLIP_DISTANCE0); } else { glDisable(GL_DEPTH_CLAMP); glDisable(GL_CLIP_DISTANCE0); } #endif } #ifdef NEW else if (current->NoN != current->NoN) { if (current->NoN) { // Disable near and far plane clipping glEnable(GL_DEPTH_CLAMP); // Enable Far clipping plane in vertex shader glEnable(GL_CLIP_DISTANCE0); } else { glDisable(GL_DEPTH_CLAMP); glDisable(GL_CLIP_DISTANCE0); } } #endif GBI.current = current; } mupen64plus-video-gliden64/src/L3DEX.h000664 001750 001750 00000000164 12655644434 020417 0ustar00sergiosergio000000 000000 #ifndef L3DEX_H #define L3DEX_H #include "Types.h" void L3DEX_Line3D( u32 w0, u32 w1 ); void L3DEX_Init(); #endif mupen64plus-rsp-cxd4/rsp.c000664 001750 001750 00000255620 12655644434 016545 0ustar00sergiosergio000000 000000 /******************************************************************************\ * Authors: Iconoclast * * Release: 2013.12.12 * * License: CC0 Public Domain Dedication * * * * To the extent possible under law, the author(s) have dedicated all copyright * * and related and neighboring rights to this software to the public domain * * worldwide. This software is distributed without any warranty. * * * * You should have received a copy of the CC0 Public Domain Dedication along * * with this software. * * If not, see . * \******************************************************************************/ #include #include #include #include #include #define MINIMUM_MESSAGE_PRIORITY 1 #define EXTERN_COMMAND_LIST_GBI #define EXTERN_COMMAND_LIST_ABI #define SEMAPHORE_LOCK_CORRECTIONS #define WAIT_FOR_CPU_HOST #define EMULATE_STATIC_PC #include "config.h" #include "Rsp_#1.1.h" #include "rsp.h" #include "m64p_plugin.h" /* N: number of processor elements in SIMD processor */ #define N 8 /* * Illegal, unaligned LWC2 operations on the RSP may write past the terminal * byte of a vector, while SWC2 operations may have to wrap around stores * from the end to the start of a vector. Both of these risk out-of-bounds * memory access, but by doubling the number of bytes allocated (shift left) * per each vector register, we could stabilize and probably optimize this. */ #if 0 #define VR_STATIC_WRAPAROUND 0 #else #define VR_STATIC_WRAPAROUND 1 #endif /* * RSP virtual registers (of vector unit) * The most important are the 32 general-purpose vector registers. * The correct way to accurately store these is using big-endian vectors. * * For ?WC2 we may need to do byte-precision access just as directly. * This is amended by using the `VU_S` and `VU_B` macros defined in `rsp.h`. */ static ALIGNED short VR[32][N << VR_STATIC_WRAPAROUND]; static ALIGNED short VACC[3][N]; #if defined(ARCH_MIN_SSE2) #include #define _mm_cmple_epu16(dst, src) _mm_cmpeq_epi16(_mm_subs_epu16(dst, src), _mm_setzero_si128()) #define _mm_cmpgt_epu16(dst, src) _mm_andnot_si128(_mm_cmpeq_epi16(dst, src), _mm_cmple_epu16(src, dst)) #define _mm_cmplt_epu16(dst, src) _mm_cmpgt_epu16(src, dst) #define _mm_mullo_epu16(dst, src) _mm_mullo_epi16(dst, src) #endif /* * accumulator-indexing macros (inverted access dimensions, suited for SSE) */ #define HI 00 #define MD 01 #define LO 02 #define VACC_L (VACC[LO]) #define VACC_M (VACC[MD]) #define VACC_H (VACC[HI]) #define ACC_L(i) (VACC_L[i]) #define ACC_M(i) (VACC_M[i]) #define ACC_H(i) (VACC_H[i]) #include "vu/shuffle.h" #include "vu/clamp.h" #include "vu/cf.h" static void res_V(int vd, int vs, int vt, int e) { register int i; vs = vt = e = 0; if (vs != vt || vt != e) return; /* C2, RESERVED */ /* uncertain how to handle reserved, untested */ for (i = 0; i < N; i++) VR[vd][i] = 0x0000; /* override behavior (bpoint) */ } static void res_M(int vd, int vs, int vt, int e) { /* VMUL IQ */ res_V(vd, vs, vt, e); /* Ultra64 OS did have these, so one could implement this ext. */ } #include "vu/add.h" #include "vu/logical.h" #include "vu/divide.h" #include "vu/select.h" #include "vu/multiply.h" static void (*COP2_C2[64])(int, int, int, int) = { VMULF ,VMULU ,res_M ,res_M ,VMUDL ,VMUDM ,VMUDN ,VMUDH , /* 000 */ VMACF ,VMACU ,res_M ,res_M ,VMADL ,VMADM ,VMADN ,VMADH , /* 001 */ VADD ,VSUB ,res_V ,VABS ,VADDC ,VSUBC ,res_V ,res_V , /* 010 */ res_V ,res_V ,res_V ,res_V ,res_V ,VSAW ,res_V ,res_V , /* 011 */ VLT ,VEQ ,VNE ,VGE ,VCL ,VCH ,VCR ,VMRG , /* 100 */ VAND ,VNAND ,VOR ,VNOR ,VXOR ,VNXOR ,res_V ,res_V , /* 101 */ VRCP ,VRCPL ,VRCPH ,VMOV ,VRSQ ,VRSQL ,VRSQH ,VNOP , /* 110 */ res_V ,res_V ,res_V ,res_V ,res_V ,res_V ,res_V ,res_V , /* 111 */ }; /* 000 001 010 011 100 101 110 111 */ #include "matrix.h" unsigned char conf[32]; #ifndef EMULATE_STATIC_PC static int stage; #endif static int temp_PC; #ifdef WAIT_FOR_CPU_HOST static short MFC0_count[32]; /* Keep one C0 MF status read count for each scalar register. */ #endif static RCPREG* CR[16]; #if (0) #define SP_EXECUTE_LOG #define VU_EMULATE_SCALAR_ACCUMULATOR_READ #endif /* * Most of the point behind this config system is to let users use HLE video * or audio plug-ins. The other task types are used less than 1% of the time * and only in a few games. They require simulation from within the RSP * internally, which I have no intention to ever support. Some good research * on a few of these special task types was done by Hacktarux in the MUPEN64 * HLE RSP plug-in, so consider using that instead for complete HLE. */ /* * Schedule binary dump exports to the DllConfig schedule delay queue. */ #define CFG_QUEUE_E_DRAM (*(int *)(conf + 0x04)) #define CFG_QUEUE_E_DMEM (*(int *)(conf + 0x08)) #define CFG_QUEUE_E_IMEM (*(int *)(conf + 0x0C)) /* * Note: This never actually made it into the configuration system. * Instead, DMEM and IMEM are always exported on every call to DllConfig(). */ /* * Special switches. * (generally for correcting RSP clock behavior on Project64 2.x) * Also includes RSP register states debugger. */ #define CFG_WAIT_FOR_CPU_HOST (*(int *)(conf + 0x10)) #define CFG_MEND_SEMAPHORE_LOCK (*(int *)(conf + 0x14)) #define CFG_TRACE_RSP_REGISTERS (*(int *)(conf + 0x18)) #define RSP_CXD4_VERSION 0x0101 #define RSP_PLUGIN_API_VERSION 0x020000 #define CONFIG_API_VERSION 0x020100 #define CONFIG_PARAM_VERSION 1.00 static int l_PluginInit = 0; static m64p_handle l_ConfigRsp; extern RSP_INFO rsp_info; #define VERSION_PRINTF_SPLIT(x) (((x) >> 16) & 0xffff), (((x) >> 8) & 0xff), ((x) & 0xff) NOINLINE void update_conf(void) { memset(conf, 0, sizeof(conf)); CFG_HLE_GFX = ConfigGetParamBool(l_ConfigRsp, "DisplayListToGraphicsPlugin"); CFG_HLE_AUD = ConfigGetParamBool(l_ConfigRsp, "AudioListToAudioPlugin"); CFG_WAIT_FOR_CPU_HOST = ConfigGetParamBool(l_ConfigRsp, "WaitForCPUHost"); CFG_MEND_SEMAPHORE_LOCK = ConfigGetParamBool(l_ConfigRsp, "SupportCPUSemaphoreLock"); } EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context, void (*DebugCallback)(void *, int, const char *)) { float fConfigParamsVersion = 0.0f; if (l_PluginInit) return M64ERR_ALREADY_INIT; /* first thing is to set the callback function for debug info */ /* set the default values for this plugin */ ConfigSetDefaultFloat(l_ConfigRsp, "Version", CONFIG_PARAM_VERSION, "Mupen64Plus cxd4 RSP Plugin config parameter version number"); ConfigSetDefaultBool(l_ConfigRsp, "DisplayListToGraphicsPlugin", 0, "Send display lists to the graphics plugin"); ConfigSetDefaultBool(l_ConfigRsp, "AudioListToAudioPlugin", 0, "Send audio lists to the audio plugin"); ConfigSetDefaultBool(l_ConfigRsp, "WaitForCPUHost", 0, "Force CPU-RSP signals synchronization"); ConfigSetDefaultBool(l_ConfigRsp, "SupportCPUSemaphoreLock", 0, "Support CPU-RSP semaphore lock"); l_PluginInit = 1; return M64ERR_SUCCESS; } EXPORT m64p_error CALL PluginShutdown(void) { if (!l_PluginInit) return M64ERR_NOT_INIT; l_PluginInit = 0; return M64ERR_SUCCESS; } EXPORT m64p_error CALL cxd4PluginGetVersion(m64p_plugin_type *PluginType, int *PluginVersion, int *APIVersion, const char **PluginNamePtr, int *Capabilities) { /* set version info */ if (PluginType != NULL) *PluginType = M64PLUGIN_RSP; if (PluginVersion != NULL) *PluginVersion = RSP_CXD4_VERSION; if (APIVersion != NULL) *APIVersion = RSP_PLUGIN_API_VERSION; if (Capabilities != NULL) *Capabilities = 0; return M64ERR_SUCCESS; } EXPORT int CALL RomOpen(void) { if (!l_PluginInit) return 0; update_conf(); return 1; } EXPORT void CALL cxd4InitiateRSP(RSP_INFO Rsp_Info, unsigned int *CycleCount) { if (CycleCount != NULL) /* cycle-accuracy not doable with today's hosts */ *CycleCount = 0x00000000; if (Rsp_Info.DMEM == Rsp_Info.IMEM) /* usually dummy RSP data for testing */ return; /* DMA is not executed just because plugin initiates. */ #if 0 while (Rsp_Info.IMEM != Rsp_Info.DMEM + 4096) message("Virtual host map noncontiguity.", 3); #endif RSP = Rsp_Info; *RSP.SP_PC_REG = 0x04001000 & 0x00000FFF; /* task init bug on Mupen64 */ CR[0x0] = RSP.SP_MEM_ADDR_REG; CR[0x1] = RSP.SP_DRAM_ADDR_REG; CR[0x2] = RSP.SP_RD_LEN_REG; CR[0x3] = RSP.SP_WR_LEN_REG; CR[0x4] = RSP.SP_STATUS_REG; CR[0x5] = RSP.SP_DMA_FULL_REG; CR[0x6] = RSP.SP_DMA_BUSY_REG; CR[0x7] = RSP.SP_SEMAPHORE_REG; CR[0x8] = RSP.DPC_START_REG; CR[0x9] = RSP.DPC_END_REG; CR[0xA] = RSP.DPC_CURRENT_REG; CR[0xB] = RSP.DPC_STATUS_REG; CR[0xC] = RSP.DPC_CLOCK_REG; CR[0xD] = RSP.DPC_BUFBUSY_REG; CR[0xE] = RSP.DPC_PIPEBUSY_REG; CR[0xF] = RSP.DPC_TMEM_REG; } EXPORT void CALL cxd4RomClosed(void) { *RSP.SP_PC_REG = 0x00000000; return; } /* * RSP virtual registers (of scalar unit) * The most important are the 32 general-purpose scalar registers. * We have the convenience of using a 32-bit machine (Win32) to emulate * another 32-bit machine (MIPS/N64), so the most natural way to accurately * emulate the scalar GPRs is to use the standard `int` type. Situations * specifically requiring sign-extension or lack thereof are forcibly * applied as defined in the MIPS quick reference card and user manuals. * Remember that these are not the same "GPRs" as in the MIPS ISA and totally * abandon their designated purposes on the master CPU host (the VR4300), * hence most of the MIPS names "k0, k1, t0, t1, v0, v1 ..." no longer apply. */ static int SR[32]; #include "rsp.h" NOINLINE static void res_S(void) { } #ifdef EMULATE_STATIC_PC #define BASE_OFF 0x000 #else #define BASE_OFF 0x004 #endif #define SLOT_OFF (BASE_OFF + 0x000) #define LINK_OFF (BASE_OFF + 0x004) #define MF_SP_STATUS_TIMEOUT 8192 void set_PC(int address) { temp_PC = 0x04001000 + (address & 0xFFC); #ifndef EMULATE_STATIC_PC stage = 1; #endif } /* * If the client CPU's shift amount is exactly 5 bits for a 32-bit source, * then omit emulating (sa & 31) in the SLL/SRL/SRA interpreter steps. * (Additionally, omit doing (GPR[rs] & 31) in SLLV/SRLV/SRAV.) * * As C pre-processor logic seems incapable of interpreting type storage, * stuff like #if (1U << 31 == 1U << ~0U) will generally just fail. */ #if defined(ARCH_MIN_SSE2) #define MASK_SA(sa) (sa) #else #define MASK_SA(sa) ((sa) & 31) #endif #if (0) #define ENDIAN 0 #else #define ENDIAN ~0 #endif #define BES(address) ((address) ^ ((ENDIAN) & 03)) #define HES(address) ((address) ^ ((ENDIAN) & 02)) #define MES(address) ((address) ^ ((ENDIAN) & 01)) #define WES(address) ((address) ^ ((ENDIAN) & 00)) #define SR_B(s, i) (*(byte *)(((byte *)(SR + s)) + BES(i))) #define SR_S(s, i) (*(short *)(((byte *)(SR + s)) + HES(i))) #define SE(x, b) (-(x & (1 << b)) | (x & ~(~0 << b))) #define ZE(x, b) (+(x & (1 << b)) | (x & ~(~0 << b))) static union { unsigned char B[4]; signed char SB[4]; unsigned short H[2]; signed short SH[2]; unsigned W: 32; } SR_temp; static void ULW(int rd, uint32_t addr); static void USW(int rs, uint32_t addr); /* * All other behaviors defined below this point in the file are specific to * the SGI N64 extension to the MIPS R4000 and are not entirely implemented. */ /*** Scalar, Coprocessor Operations (system control) ***/ static void SP_DMA_READ(void); static void SP_DMA_WRITE(void); static void MFC0(int rt, int rd) { SR[rt] = *(CR[rd]); SR[0] = 0x00000000; if (rd == 0x7) /* SP_SEMAPHORE_REG */ { if (CFG_MEND_SEMAPHORE_LOCK == 0) return; *RSP.SP_SEMAPHORE_REG = 0x00000001; *RSP.SP_STATUS_REG |= 0x00000001; /* temporary bit to break CPU */ return; } #ifdef WAIT_FOR_CPU_HOST if (rd == 0x4) /* SP_STATUS_REG */ { ++MFC0_count[rt]; if (MFC0_count[rt] >= MF_SP_STATUS_TIMEOUT) *RSP.SP_STATUS_REG |= 0x00000001; /* Let OS restart the task. */ } #endif } static void MT_DMA_CACHE(int rt) { *RSP.SP_MEM_ADDR_REG = SR[rt] & 0xFFFFFFF8; /* & 0x00001FF8 */ /* Reserved upper bits are ignored during DMA R/W. */ } static void MT_DMA_DRAM(int rt) { *RSP.SP_DRAM_ADDR_REG = SR[rt] & 0xFFFFFFF8; /* & 0x00FFFFF8 */ /* Let the reserved bits get sent, but the pointer is 24-bit. */ } static void MT_DMA_READ_LENGTH(int rt) { *RSP.SP_RD_LEN_REG = SR[rt] | 07; SP_DMA_READ(); } static void MT_DMA_WRITE_LENGTH(int rt) { *RSP.SP_WR_LEN_REG = SR[rt] | 07; SP_DMA_WRITE(); } static void MT_SP_STATUS(int rt) { #if 0 if (SR[rt] & 0xFE000040) message("MTC0\nSP_STATUS", 2); #endif *RSP.SP_STATUS_REG &= ~(!!(SR[rt] & 0x00000001) << 0); *RSP.SP_STATUS_REG |= (!!(SR[rt] & 0x00000002) << 0); *RSP.SP_STATUS_REG &= ~(!!(SR[rt] & 0x00000004) << 1); *RSP.MI_INTR_REG &= ~((SR[rt] & 0x00000008) >> 3); /* SP_CLR_INTR */ *RSP.MI_INTR_REG |= ((SR[rt] & 0x00000010) >> 4); /* SP_SET_INTR */ *RSP.SP_STATUS_REG |= (SR[rt] & 0x00000010) >> 4; /* int set halt */ *RSP.SP_STATUS_REG &= ~(!!(SR[rt] & 0x00000020) << 5); /* *RSP.SP_STATUS_REG |= (!!(SR[rt] & 0x00000040) << 5); */ *RSP.SP_STATUS_REG &= ~(!!(SR[rt] & 0x00000080) << 6); *RSP.SP_STATUS_REG |= (!!(SR[rt] & 0x00000100) << 6); *RSP.SP_STATUS_REG &= ~(!!(SR[rt] & 0x00000200) << 7); *RSP.SP_STATUS_REG |= (!!(SR[rt] & 0x00000400) << 7); *RSP.SP_STATUS_REG &= ~(!!(SR[rt] & 0x00000800) << 8); *RSP.SP_STATUS_REG |= (!!(SR[rt] & 0x00001000) << 8); *RSP.SP_STATUS_REG &= ~(!!(SR[rt] & 0x00002000) << 9); *RSP.SP_STATUS_REG |= (!!(SR[rt] & 0x00004000) << 9); *RSP.SP_STATUS_REG &= ~(!!(SR[rt] & 0x00008000) << 10); *RSP.SP_STATUS_REG |= (!!(SR[rt] & 0x00010000) << 10); *RSP.SP_STATUS_REG &= ~(!!(SR[rt] & 0x00020000) << 11); *RSP.SP_STATUS_REG |= (!!(SR[rt] & 0x00040000) << 11); *RSP.SP_STATUS_REG &= ~(!!(SR[rt] & 0x00080000) << 12); *RSP.SP_STATUS_REG |= (!!(SR[rt] & 0x00100000) << 12); *RSP.SP_STATUS_REG &= ~(!!(SR[rt] & 0x00200000) << 13); *RSP.SP_STATUS_REG |= (!!(SR[rt] & 0x00400000) << 13); *RSP.SP_STATUS_REG &= ~(!!(SR[rt] & 0x00800000) << 14); *RSP.SP_STATUS_REG |= (!!(SR[rt] & 0x01000000) << 14); } static void MT_SP_RESERVED(int rt) { const uint32_t source = SR[rt] & 0x00000000; /* forced (zilmar, dox) */ *RSP.SP_SEMAPHORE_REG = source; } static void MT_CMD_START(int rt) { const uint32_t source = SR[rt] & 0xFFFFFFF8; /* Funnelcube demo */ #if 0 if (*RSP.DPC_BUFBUSY_REG) /* lock hazards not implemented */ message("MTC0\nCMD_START", 0); #endif *RSP.DPC_END_REG = *RSP.DPC_CURRENT_REG = *RSP.DPC_START_REG = source; } static void MT_CMD_END(int rt) { #if 0 if (*RSP.DPC_BUFBUSY_REG) message("MTC0\nCMD_END", 0); /* This is just CA-related. */ #endif *RSP.DPC_END_REG = SR[rt] & 0xFFFFFFF8; if (RSP.ProcessRdpList == NULL) /* zilmar GFX #1.2 */ return; RSP.ProcessRdpList(); } static void MT_CMD_STATUS(int rt) { #if 0 if (SR[rt] & 0xFFFFFD80) /* unsupported or reserved bits */ message("MTC0\nCMD_STATUS", 2); #endif *RSP.DPC_STATUS_REG &= ~(!!(SR[rt] & 0x00000001) << 0); *RSP.DPC_STATUS_REG |= (!!(SR[rt] & 0x00000002) << 0); *RSP.DPC_STATUS_REG &= ~(!!(SR[rt] & 0x00000004) << 1); *RSP.DPC_STATUS_REG |= (!!(SR[rt] & 0x00000008) << 1); *RSP.DPC_STATUS_REG &= ~(!!(SR[rt] & 0x00000010) << 2); *RSP.DPC_STATUS_REG |= (!!(SR[rt] & 0x00000020) << 2); /* Some NUS-CIC-6105 SP tasks try to clear some zeroed DPC registers. */ *RSP.DPC_TMEM_REG &= !(SR[rt] & 0x00000040) * -1; /* *RSP.DPC_PIPEBUSY_REG &= !(SR[rt] & 0x00000080) * -1; */ /* *RSP.DPC_BUFBUSY_REG &= !(SR[rt] & 0x00000100) * -1; */ *RSP.DPC_CLOCK_REG &= !(SR[rt] & 0x00000200) * -1; } static void MT_CMD_CLOCK(int rt) { #if 0 message("MTC0\nCMD_CLOCK", 1); /* read-only?? */ #endif *RSP.DPC_CLOCK_REG = SR[rt]; /* Appendix says this is RW; elsewhere it says R. */ } static void MT_READ_ONLY(int rt) { #if 0 char text[64]; sprintf(text, "MTC0\nInvalid write attempt.\nSR[%i] = 0x%08X", rt, SR[rt]); message(text, 2); #endif } static void (*MTC0[16])(int) = { MT_DMA_CACHE ,MT_DMA_DRAM ,MT_DMA_READ_LENGTH ,MT_DMA_WRITE_LENGTH, MT_SP_STATUS ,MT_READ_ONLY ,MT_READ_ONLY ,MT_SP_RESERVED, MT_CMD_START ,MT_CMD_END ,MT_READ_ONLY ,MT_CMD_STATUS, MT_CMD_CLOCK ,MT_READ_ONLY ,MT_READ_ONLY ,MT_READ_ONLY }; static void SP_DMA_READ(void) { register unsigned int length = ((*RSP.SP_RD_LEN_REG & 0x00000FFF) >> 0) + 1; register unsigned int count = ((*RSP.SP_RD_LEN_REG & 0x000FF000) >> 12) + 1; register unsigned int skip = ((*RSP.SP_RD_LEN_REG & 0xFFF00000) >> 20) + length; do { /* `count` always starts > 0, so we begin with `do` instead of `while`. */ register unsigned int i = 0; --count; do { unsigned int offC = (count*length + *RSP.SP_MEM_ADDR_REG + i) & 0x00001FF8; /* SP cache and dynamic DMA pointers */ unsigned int offD = (count*skip + *RSP.SP_DRAM_ADDR_REG + i) & 0x00FFFFF8; memcpy(RSP.DMEM + offC, RSP.RDRAM + offD, 8); i += 0x008; } while (i < length); } while (count); *RSP.SP_DMA_BUSY_REG = 0x00000000; *RSP.SP_STATUS_REG &= ~0x00000004; /* SP_STATUS_DMABUSY */ } static void SP_DMA_WRITE(void) { register unsigned int length = ((*RSP.SP_WR_LEN_REG & 0x00000FFF) >> 0) + 1; register unsigned int count = ((*RSP.SP_WR_LEN_REG & 0x000FF000) >> 12) + 1; register unsigned int skip = ((*RSP.SP_WR_LEN_REG & 0xFFF00000) >> 20) + length; do { /* `count` always starts > 0, so we begin with `do` instead of `while`. */ register unsigned int i = 0; --count; do { /* SP cache and dynamic DMA pointers */ unsigned int offC = (count*length + *RSP.SP_MEM_ADDR_REG + i) & 0x00001FF8; unsigned int offD = (count*skip + *RSP.SP_DRAM_ADDR_REG + i) & 0x00FFFFF8; memcpy(RSP.RDRAM + offD, RSP.DMEM + offC, 8); i += 0x000008; } while (i < length); } while (count); *RSP.SP_DMA_BUSY_REG = 0x00000000; *RSP.SP_STATUS_REG &= ~0x00000004; /* SP_STATUS_DMABUSY */ } /*** Scalar, Coprocessor Operations (vector unit) ***/ /* * Since RSP vectors are stored 100% accurately as big-endian arrays for the * proper vector operation math to be done, LWC2 and SWC2 emulation code will * have to look a little different. zilmar's method is to distort the endian * using an array of unions, permitting hacked byte- and halfword-precision. */ /* * Universal byte-access macro for 16*8 halfword vectors. * Use this macro if you are not sure whether the element is odd or even. */ #define VR_B(vt,element) (*(byte *)((byte *)(VR[vt]) + MES(element))) /* * Optimized byte-access macros for the vector registers. * Use these ONLY if you know the element is even (or odd in the second). */ #define VR_A(vt,element) (*(byte *)((byte *)(VR[vt]) + element + MES(0x0))) #define VR_U(vt,element) (*(byte *)((byte *)(VR[vt]) + element - MES(0x0))) /* * Optimized halfword-access macro for indexing eight-element vectors. * Use this ONLY if you know the element is even, not odd. * * If the four-bit element is odd, then there is no solution in one hit. */ #define VR_S(vt,element) (*(short *)((byte *)(VR[vt]) + element)) extern unsigned short get_VCO(void); extern unsigned short get_VCC(void); extern unsigned char get_VCE(void); extern void set_VCO(unsigned short VCO); extern void set_VCC(unsigned short VCC); extern void set_VCE(unsigned char VCE); extern short vce[8]; unsigned short rwR_VCE(void) { /* never saw a game try to read VCE out to a scalar GPR yet */ register unsigned short ret_slot = 0x00 | (unsigned short)get_VCE(); return (ret_slot); } void rwW_VCE(unsigned short VCE) { /* never saw a game try to write VCE using a scalar GPR yet */ register int i; VCE = 0x00 | (VCE & 0xFF); for (i = 0; i < 8; i++) vce[i] = (VCE >> i) & 1; } static unsigned short (*R_VCF[32])(void) = { get_VCO,get_VCC,rwR_VCE,rwR_VCE, /* Hazard reaction barrier: RD = (UINT16)(inst) >> 11, without &= 3. */ get_VCO,get_VCC,rwR_VCE,rwR_VCE, get_VCO,get_VCC,rwR_VCE,rwR_VCE, get_VCO,get_VCC,rwR_VCE,rwR_VCE, get_VCO,get_VCC,rwR_VCE,rwR_VCE, get_VCO,get_VCC,rwR_VCE,rwR_VCE, get_VCO,get_VCC,rwR_VCE,rwR_VCE, get_VCO,get_VCC,rwR_VCE,rwR_VCE }; static void (*W_VCF[32])(unsigned short) = { set_VCO,set_VCC,rwW_VCE,rwW_VCE, /* Hazard reaction barrier: RD = (UINT16)(inst) >> 11, without &= 3. */ set_VCO,set_VCC,rwW_VCE,rwW_VCE, set_VCO,set_VCC,rwW_VCE,rwW_VCE, set_VCO,set_VCC,rwW_VCE,rwW_VCE, set_VCO,set_VCC,rwW_VCE,rwW_VCE, set_VCO,set_VCC,rwW_VCE,rwW_VCE, set_VCO,set_VCC,rwW_VCE,rwW_VCE, set_VCO,set_VCC,rwW_VCE,rwW_VCE }; static void MFC2(int rt, int vs, int e) { SR_B(rt, 2) = VR_B(vs, e); e = (e + 0x1) & 0xF; SR_B(rt, 3) = VR_B(vs, e); SR[rt] = (signed short)(SR[rt]); SR[0] = 0x00000000; } static void MTC2(int rt, int vd, int e) { VR_B(vd, e+0x0) = SR_B(rt, 2); VR_B(vd, e+0x1) = SR_B(rt, 3); /* If element == 0xF, it does not matter; loads do not wrap over. */ } static void CFC2(int rt, int rd) { SR[rt] = (signed short)R_VCF[rd](); SR[0] = 0x00000000; } static void CTC2(int rt, int rd) { W_VCF[rd](SR[rt] & 0x0000FFFF); } /*** Scalar, Coprocessor Operations (vector unit, scalar cache transfers) ***/ static void LBV(int vt, int element, int offset, int base) { const int e = element; register uint32_t addr = (SR[base] + 1*offset) & 0x00000FFF; VR_B(vt, e) = RSP.DMEM[BES(addr)]; } static void LSV(int vt, int element, int offset, int base) { int correction; register uint32_t addr; const int e = element; if (e & 0x1) /* LSV, illegal element */ return; addr = (SR[base] + 2*offset) & 0x00000FFF; correction = addr % 0x004; if (correction == 0x003) /* LSV, weird address */ return; VR_S(vt, e) = *(short *)(RSP.DMEM + addr - HES(0x000)*(correction - 1)); } static void LLV(int vt, int element, int offset, int base) { int correction; register uint32_t addr; const int e = element; if (e & 0x1) /* LLV, Odd element */ return; /* Illegal (but still even) elements are used by Boss Game Studios. */ addr = (SR[base] + 4*offset) & 0x00000FFF; if (addr & 0x00000001) /* LLV, Odd address */ { /* branch very unlikely: "Star Wars: Battle for Naboo" unaligned addr */ VR_A(vt, e+0x0) = RSP.DMEM[BES(addr)]; addr = (addr + 0x00000001) & 0x00000FFF; VR_U(vt, e+0x1) = RSP.DMEM[BES(addr)]; addr = (addr + 0x00000001) & 0x00000FFF; VR_A(vt, e+0x2) = RSP.DMEM[BES(addr)]; addr = (addr + 0x00000001) & 0x00000FFF; VR_U(vt, e+0x3) = RSP.DMEM[BES(addr)]; return; } correction = HES(0x000)*(addr%0x004 - 1); VR_S(vt, e+0x0) = *(short *)(RSP.DMEM + addr - correction); addr = (addr + 0x00000002) & 0x00000FFF; /* F3DLX 1.23: addr%4 is 0x002. */ VR_S(vt, e+0x2) = *(short *)(RSP.DMEM + addr + correction); } static void LDV(int vt, int element, int offset, int base) { register uint32_t addr; const int e = element; if (e & 0x1) /* LDV, Odd element */ return; /* Illegal (but still even) elements are used by Boss Game Studios. */ addr = (SR[base] + 8*offset) & 0x00000FFF; switch (addr & 07) { case 00: VR_S(vt, e+0x0) = *(short *)(RSP.DMEM + addr + HES(0x000)); VR_S(vt, e+0x2) = *(short *)(RSP.DMEM + addr + HES(0x002)); VR_S(vt, e+0x4) = *(short *)(RSP.DMEM + addr + HES(0x004)); VR_S(vt, e+0x6) = *(short *)(RSP.DMEM + addr + HES(0x006)); break; case 01: /* standard ABI ucodes (unlike e.g. MusyX w/ even addresses) */ VR_S(vt, e+0x0) = *(short *)(RSP.DMEM + addr + 0x000); VR_A(vt, e+0x2) = RSP.DMEM[addr + 0x002 - BES(0x000)]; VR_U(vt, e+0x3) = RSP.DMEM[addr + 0x003 + BES(0x000)]; VR_S(vt, e+0x4) = *(short *)(RSP.DMEM + addr + 0x004); VR_A(vt, e+0x6) = RSP.DMEM[addr + 0x006 - BES(0x000)]; addr += 0x007 + BES(00); addr &= 0x00000FFF; VR_U(vt, e+0x7) = RSP.DMEM[addr]; break; case 02: VR_S(vt, e+0x0) = *(short *)(RSP.DMEM + addr + 0x000 - HES(0x000)); VR_S(vt, e+0x2) = *(short *)(RSP.DMEM + addr + 0x002 + HES(0x000)); VR_S(vt, e+0x4) = *(short *)(RSP.DMEM + addr + 0x004 - HES(0x000)); addr += 0x006 + HES(00); addr &= 0x00000FFF; VR_S(vt, e+0x6) = *(short *)(RSP.DMEM + addr); break; case 03: /* standard ABI ucodes (unlike e.g. MusyX w/ even addresses) */ VR_A(vt, e+0x0) = RSP.DMEM[addr + 0x000 - BES(0x000)]; VR_U(vt, e+0x1) = RSP.DMEM[addr + 0x001 + BES(0x000)]; VR_S(vt, e+0x2) = *(short *)(RSP.DMEM + addr + 0x002); VR_A(vt, e+0x4) = RSP.DMEM[addr + 0x004 - BES(0x000)]; addr += 0x005 + BES(00); addr &= 0x00000FFF; VR_U(vt, e+0x5) = RSP.DMEM[addr]; VR_S(vt, e+0x6) = *(short *)(RSP.DMEM + addr + 0x001 - BES(0x000)); break; case 04: VR_S(vt, e+0x0) = *(short *)(RSP.DMEM + addr + HES(0x000)); VR_S(vt, e+0x2) = *(short *)(RSP.DMEM + addr + HES(0x002)); addr += 0x004 + WES(00); addr &= 0x00000FFF; VR_S(vt, e+0x4) = *(short *)(RSP.DMEM + addr + HES(0x000)); VR_S(vt, e+0x6) = *(short *)(RSP.DMEM + addr + HES(0x002)); break; case 05: /* standard ABI ucodes (unlike e.g. MusyX w/ even addresses) */ VR_S(vt, e+0x0) = *(short *)(RSP.DMEM + addr + 0x000); VR_A(vt, e+0x2) = RSP.DMEM[addr + 0x002 - BES(0x000)]; addr += 0x003; addr &= 0x00000FFF; VR_U(vt, e+0x3) = RSP.DMEM[addr + BES(0x000)]; VR_S(vt, e+0x4) = *(short *)(RSP.DMEM + addr + 0x001); VR_A(vt, e+0x6) = RSP.DMEM[addr + BES(0x003)]; VR_U(vt, e+0x7) = RSP.DMEM[addr + BES(0x004)]; break; case 06: VR_S(vt, e+0x0) = *(short *)(RSP.DMEM + addr - HES(0x000)); addr += 0x002; addr &= 0x00000FFF; VR_S(vt, e+0x2) = *(short *)(RSP.DMEM + addr + HES(0x000)); VR_S(vt, e+0x4) = *(short *)(RSP.DMEM + addr + HES(0x002)); VR_S(vt, e+0x6) = *(short *)(RSP.DMEM + addr + HES(0x004)); break; case 07: /* standard ABI ucodes (unlike e.g. MusyX w/ even addresses) */ VR_A(vt, e+0x0) = RSP.DMEM[addr - BES(0x000)]; addr += 0x001; addr &= 0x00000FFF; VR_U(vt, e+0x1) = RSP.DMEM[addr + BES(0x000)]; VR_S(vt, e+0x2) = *(short *)(RSP.DMEM + addr + 0x001); VR_A(vt, e+0x4) = RSP.DMEM[addr + BES(0x003)]; VR_U(vt, e+0x5) = RSP.DMEM[addr + BES(0x004)]; VR_S(vt, e+0x6) = *(short *)(RSP.DMEM + addr + 0x005); break; } } static void SBV(int vt, int element, int offset, int base) { const int e = element; register uint32_t addr = (SR[base] + 1*offset) & 0x00000FFF; RSP.DMEM[BES(addr)] = VR_B(vt, e); } static void SSV(int vt, int element, int offset, int base) { const int e = element; register uint32_t addr = (SR[base] + 2*offset) & 0x00000FFF; RSP.DMEM[BES(addr)] = VR_B(vt, (e + 0x0)); addr = (addr + 0x00000001) & 0x00000FFF; RSP.DMEM[BES(addr)] = VR_B(vt, (e + 0x1) & 0xF); } static void SLV(int vt, int element, int offset, int base) { int correction; register uint32_t addr; const int e = element; if ((e & 0x1) || e > 0xC) /* must support illegal even elements in F3DEX2 */ return; addr = (SR[base] + 4*offset) & 0x00000FFF; if (addr & 0x00000001) /* SLV, Odd address */ return; correction = HES(0x000)*(addr%0x004 - 1); *(short *)(RSP.DMEM + addr - correction) = VR_S(vt, e+0x0); addr = (addr + 0x00000002) & 0x00000FFF; /* F3DLX 0.95: "Mario Kart 64" */ *(short *)(RSP.DMEM + addr + correction) = VR_S(vt, e+0x2); } static void SDV(int vt, int element, int offset, int base) { register uint32_t addr; const unsigned int e = element; addr = (SR[base] + 8*offset) & 0x00000FFF; if (e > 0x8 || (e & 0x1)) { /* Illegal elements with Boss Game Studios publications. */ register unsigned int i; #if (VR_STATIC_WRAPAROUND == 1) vector_copy(VR[vt] + N, VR[vt]); for (i = 0; i < 8; i++) RSP.DMEM[BES(addr++ & 0x00000FFF)] = VR_B(vt, e + i); #else for (i = 0; i < 8; i++) RSP.DMEM[BES(addr++ & 0x00000FFF)] = VR_B(vt, (e+i)&0xF); #endif return; } switch (addr & 07) { case 00: *(short *)(RSP.DMEM + addr + HES(0x000)) = VR_S(vt, e+0x0); *(short *)(RSP.DMEM + addr + HES(0x002)) = VR_S(vt, e+0x2); *(short *)(RSP.DMEM + addr + HES(0x004)) = VR_S(vt, e+0x4); *(short *)(RSP.DMEM + addr + HES(0x006)) = VR_S(vt, e+0x6); break; case 01: /* "Tetrisphere" audio ucode */ *(short *)(RSP.DMEM + addr + 0x000) = VR_S(vt, e+0x0); RSP.DMEM[addr + 0x002 - BES(0x000)] = VR_A(vt, e+0x2); RSP.DMEM[addr + 0x003 + BES(0x000)] = VR_U(vt, e+0x3); *(short *)(RSP.DMEM + addr + 0x004) = VR_S(vt, e+0x4); RSP.DMEM[addr + 0x006 - BES(0x000)] = VR_A(vt, e+0x6); addr += 0x007 + BES(0x000); addr &= 0x00000FFF; RSP.DMEM[addr] = VR_U(vt, e+0x7); break; case 02: *(short *)(RSP.DMEM + addr + 0x000 - HES(0x000)) = VR_S(vt, e+0x0); *(short *)(RSP.DMEM + addr + 0x002 + HES(0x000)) = VR_S(vt, e+0x2); *(short *)(RSP.DMEM + addr + 0x004 - HES(0x000)) = VR_S(vt, e+0x4); addr += 0x006 + HES(0x000); addr &= 0x00000FFF; *(short *)(RSP.DMEM + addr) = VR_S(vt, e+0x6); break; case 03: /* "Tetrisphere" audio ucode */ RSP.DMEM[addr + 0x000 - BES(0x000)] = VR_A(vt, e+0x0); RSP.DMEM[addr + 0x001 + BES(0x000)] = VR_U(vt, e+0x1); *(short *)(RSP.DMEM + addr + 0x002) = VR_S(vt, e+0x2); RSP.DMEM[addr + 0x004 - BES(0x000)] = VR_A(vt, e+0x4); addr += 0x005 + BES(0x000); addr &= 0x00000FFF; RSP.DMEM[addr] = VR_U(vt, e+0x5); *(short *)(RSP.DMEM + addr + 0x001 - BES(0x000)) = VR_S(vt, 0x6); break; case 04: *(short *)(RSP.DMEM + addr + HES(0x000)) = VR_S(vt, e+0x0); *(short *)(RSP.DMEM + addr + HES(0x002)) = VR_S(vt, e+0x2); addr = (addr + 0x004) & 0x00000FFF; *(short *)(RSP.DMEM + addr + HES(0x000)) = VR_S(vt, e+0x4); *(short *)(RSP.DMEM + addr + HES(0x002)) = VR_S(vt, e+0x6); break; case 05: /* "Tetrisphere" audio ucode */ *(short *)(RSP.DMEM + addr + 0x000) = VR_S(vt, e+0x0); RSP.DMEM[addr + 0x002 - BES(0x000)] = VR_A(vt, e+0x2); addr = (addr + 0x003) & 0x00000FFF; RSP.DMEM[addr + BES(0x000)] = VR_U(vt, e+0x3); *(short *)(RSP.DMEM + addr + 0x001) = VR_S(vt, e+0x4); RSP.DMEM[addr + BES(0x003)] = VR_A(vt, e+0x6); RSP.DMEM[addr + BES(0x004)] = VR_U(vt, e+0x7); break; case 06: *(short *)(RSP.DMEM + addr - HES(0x000)) = VR_S(vt, e+0x0); addr = (addr + 0x002) & 0x00000FFF; *(short *)(RSP.DMEM + addr + HES(0x000)) = VR_S(vt, e+0x2); *(short *)(RSP.DMEM + addr + HES(0x002)) = VR_S(vt, e+0x4); *(short *)(RSP.DMEM + addr + HES(0x004)) = VR_S(vt, e+0x6); break; case 07: /* "Tetrisphere" audio ucode */ RSP.DMEM[addr - BES(0x000)] = VR_A(vt, e+0x0); addr = (addr + 0x001) & 0x00000FFF; RSP.DMEM[addr + BES(0x000)] = VR_U(vt, e+0x1); *(short *)(RSP.DMEM + addr + 0x001) = VR_S(vt, e+0x2); RSP.DMEM[addr + BES(0x003)] = VR_A(vt, e+0x4); RSP.DMEM[addr + BES(0x004)] = VR_U(vt, e+0x5); *(short *)(RSP.DMEM + addr + 0x005) = VR_S(vt, e+0x6); break; } } /* * Group II vector loads and stores: * PV and UV (As of RCP implementation, XV and ZV are reserved opcodes.) */ static void LPV(int vt, int element, int offset, int base) { register uint32_t addr; register int b; const int e = element; if (e != 0x0) /* Illegal element */ return; addr = (SR[base] + 8*offset) & 0x00000FFF; b = addr & 07; addr &= ~07; switch (b) { case 00: VR[vt][07] = RSP.DMEM[addr + BES(0x007)] << 8; VR[vt][06] = RSP.DMEM[addr + BES(0x006)] << 8; VR[vt][05] = RSP.DMEM[addr + BES(0x005)] << 8; VR[vt][04] = RSP.DMEM[addr + BES(0x004)] << 8; VR[vt][03] = RSP.DMEM[addr + BES(0x003)] << 8; VR[vt][02] = RSP.DMEM[addr + BES(0x002)] << 8; VR[vt][01] = RSP.DMEM[addr + BES(0x001)] << 8; VR[vt][00] = RSP.DMEM[addr + BES(0x000)] << 8; break; case 01: /* F3DZEX 2.08J "Doubutsu no Mori" (Animal Forest) CFB layer */ VR[vt][00] = RSP.DMEM[addr + BES(0x001)] << 8; VR[vt][01] = RSP.DMEM[addr + BES(0x002)] << 8; VR[vt][02] = RSP.DMEM[addr + BES(0x003)] << 8; VR[vt][03] = RSP.DMEM[addr + BES(0x004)] << 8; VR[vt][04] = RSP.DMEM[addr + BES(0x005)] << 8; VR[vt][05] = RSP.DMEM[addr + BES(0x006)] << 8; VR[vt][06] = RSP.DMEM[addr + BES(0x007)] << 8; addr += BES(0x008); addr &= 0x00000FFF; VR[vt][07] = RSP.DMEM[addr] << 8; break; case 02: /* F3DZEX 2.08J "Doubutsu no Mori" (Animal Forest) CFB layer */ VR[vt][00] = RSP.DMEM[addr + BES(0x002)] << 8; VR[vt][01] = RSP.DMEM[addr + BES(0x003)] << 8; VR[vt][02] = RSP.DMEM[addr + BES(0x004)] << 8; VR[vt][03] = RSP.DMEM[addr + BES(0x005)] << 8; VR[vt][04] = RSP.DMEM[addr + BES(0x006)] << 8; VR[vt][05] = RSP.DMEM[addr + BES(0x007)] << 8; addr += 0x008; addr &= 0x00000FFF; VR[vt][06] = RSP.DMEM[addr + BES(0x000)] << 8; VR[vt][07] = RSP.DMEM[addr + BES(0x001)] << 8; break; case 03: /* F3DZEX 2.08J "Doubutsu no Mori" (Animal Forest) CFB layer */ VR[vt][00] = RSP.DMEM[addr + BES(0x003)] << 8; VR[vt][01] = RSP.DMEM[addr + BES(0x004)] << 8; VR[vt][02] = RSP.DMEM[addr + BES(0x005)] << 8; VR[vt][03] = RSP.DMEM[addr + BES(0x006)] << 8; VR[vt][04] = RSP.DMEM[addr + BES(0x007)] << 8; addr += 0x008; addr &= 0x00000FFF; VR[vt][05] = RSP.DMEM[addr + BES(0x000)] << 8; VR[vt][06] = RSP.DMEM[addr + BES(0x001)] << 8; VR[vt][07] = RSP.DMEM[addr + BES(0x002)] << 8; break; case 04: /* "Resident Evil 2" in-game 3-D, F3DLX 2.08--"WWF No Mercy" */ VR[vt][00] = RSP.DMEM[addr + BES(0x004)] << 8; VR[vt][01] = RSP.DMEM[addr + BES(0x005)] << 8; VR[vt][02] = RSP.DMEM[addr + BES(0x006)] << 8; VR[vt][03] = RSP.DMEM[addr + BES(0x007)] << 8; addr += 0x008; addr &= 0x00000FFF; VR[vt][04] = RSP.DMEM[addr + BES(0x000)] << 8; VR[vt][05] = RSP.DMEM[addr + BES(0x001)] << 8; VR[vt][06] = RSP.DMEM[addr + BES(0x002)] << 8; VR[vt][07] = RSP.DMEM[addr + BES(0x003)] << 8; break; case 05: /* F3DZEX 2.08J "Doubutsu no Mori" (Animal Forest) CFB layer */ VR[vt][00] = RSP.DMEM[addr + BES(0x005)] << 8; VR[vt][01] = RSP.DMEM[addr + BES(0x006)] << 8; VR[vt][02] = RSP.DMEM[addr + BES(0x007)] << 8; addr += 0x008; addr &= 0x00000FFF; VR[vt][03] = RSP.DMEM[addr + BES(0x000)] << 8; VR[vt][04] = RSP.DMEM[addr + BES(0x001)] << 8; VR[vt][05] = RSP.DMEM[addr + BES(0x002)] << 8; VR[vt][06] = RSP.DMEM[addr + BES(0x003)] << 8; VR[vt][07] = RSP.DMEM[addr + BES(0x004)] << 8; break; case 06: /* F3DZEX 2.08J "Doubutsu no Mori" (Animal Forest) CFB layer */ VR[vt][00] = RSP.DMEM[addr + BES(0x006)] << 8; VR[vt][01] = RSP.DMEM[addr + BES(0x007)] << 8; addr += 0x008; addr &= 0x00000FFF; VR[vt][02] = RSP.DMEM[addr + BES(0x000)] << 8; VR[vt][03] = RSP.DMEM[addr + BES(0x001)] << 8; VR[vt][04] = RSP.DMEM[addr + BES(0x002)] << 8; VR[vt][05] = RSP.DMEM[addr + BES(0x003)] << 8; VR[vt][06] = RSP.DMEM[addr + BES(0x004)] << 8; VR[vt][07] = RSP.DMEM[addr + BES(0x005)] << 8; break; case 07: /* F3DZEX 2.08J "Doubutsu no Mori" (Animal Forest) CFB layer */ VR[vt][00] = RSP.DMEM[addr + BES(0x007)] << 8; addr += 0x008; addr &= 0x00000FFF; VR[vt][01] = RSP.DMEM[addr + BES(0x000)] << 8; VR[vt][02] = RSP.DMEM[addr + BES(0x001)] << 8; VR[vt][03] = RSP.DMEM[addr + BES(0x002)] << 8; VR[vt][04] = RSP.DMEM[addr + BES(0x003)] << 8; VR[vt][05] = RSP.DMEM[addr + BES(0x004)] << 8; VR[vt][06] = RSP.DMEM[addr + BES(0x005)] << 8; VR[vt][07] = RSP.DMEM[addr + BES(0x006)] << 8; break; } } static void LUV(int vt, int element, int offset, int base) { register int b; int e = element; register uint32_t addr = (SR[base] + 8*offset) & 0x00000FFF; if (e != 0x0) { /* "Mia Hamm Soccer 64" SP exception override (zilmar) */ addr += -e & 0xF; for (b = 0; b < 8; b++) { VR[vt][b] = RSP.DMEM[BES(addr &= 0x00000FFF)] << 7; --e; addr -= 16 * (e == 0x0); ++addr; } return; } b = addr & 07; addr &= ~07; switch (b) { case 00: VR[vt][07] = RSP.DMEM[addr + BES(0x007)] << 7; VR[vt][06] = RSP.DMEM[addr + BES(0x006)] << 7; VR[vt][05] = RSP.DMEM[addr + BES(0x005)] << 7; VR[vt][04] = RSP.DMEM[addr + BES(0x004)] << 7; VR[vt][03] = RSP.DMEM[addr + BES(0x003)] << 7; VR[vt][02] = RSP.DMEM[addr + BES(0x002)] << 7; VR[vt][01] = RSP.DMEM[addr + BES(0x001)] << 7; VR[vt][00] = RSP.DMEM[addr + BES(0x000)] << 7; break; case 01: /* PKMN Puzzle League HVQM decoder */ VR[vt][00] = RSP.DMEM[addr + BES(0x001)] << 7; VR[vt][01] = RSP.DMEM[addr + BES(0x002)] << 7; VR[vt][02] = RSP.DMEM[addr + BES(0x003)] << 7; VR[vt][03] = RSP.DMEM[addr + BES(0x004)] << 7; VR[vt][04] = RSP.DMEM[addr + BES(0x005)] << 7; VR[vt][05] = RSP.DMEM[addr + BES(0x006)] << 7; VR[vt][06] = RSP.DMEM[addr + BES(0x007)] << 7; addr += BES(0x008); addr &= 0x00000FFF; VR[vt][07] = RSP.DMEM[addr] << 7; break; case 02: /* PKMN Puzzle League HVQM decoder */ VR[vt][00] = RSP.DMEM[addr + BES(0x002)] << 7; VR[vt][01] = RSP.DMEM[addr + BES(0x003)] << 7; VR[vt][02] = RSP.DMEM[addr + BES(0x004)] << 7; VR[vt][03] = RSP.DMEM[addr + BES(0x005)] << 7; VR[vt][04] = RSP.DMEM[addr + BES(0x006)] << 7; VR[vt][05] = RSP.DMEM[addr + BES(0x007)] << 7; addr += 0x008; addr &= 0x00000FFF; VR[vt][06] = RSP.DMEM[addr + BES(0x000)] << 7; VR[vt][07] = RSP.DMEM[addr + BES(0x001)] << 7; break; case 03: /* PKMN Puzzle League HVQM decoder */ VR[vt][00] = RSP.DMEM[addr + BES(0x003)] << 7; VR[vt][01] = RSP.DMEM[addr + BES(0x004)] << 7; VR[vt][02] = RSP.DMEM[addr + BES(0x005)] << 7; VR[vt][03] = RSP.DMEM[addr + BES(0x006)] << 7; VR[vt][04] = RSP.DMEM[addr + BES(0x007)] << 7; addr += 0x008; addr &= 0x00000FFF; VR[vt][05] = RSP.DMEM[addr + BES(0x000)] << 7; VR[vt][06] = RSP.DMEM[addr + BES(0x001)] << 7; VR[vt][07] = RSP.DMEM[addr + BES(0x002)] << 7; break; case 04: /* PKMN Puzzle League HVQM decoder */ VR[vt][00] = RSP.DMEM[addr + BES(0x004)] << 7; VR[vt][01] = RSP.DMEM[addr + BES(0x005)] << 7; VR[vt][02] = RSP.DMEM[addr + BES(0x006)] << 7; VR[vt][03] = RSP.DMEM[addr + BES(0x007)] << 7; addr += 0x008; addr &= 0x00000FFF; VR[vt][04] = RSP.DMEM[addr + BES(0x000)] << 7; VR[vt][05] = RSP.DMEM[addr + BES(0x001)] << 7; VR[vt][06] = RSP.DMEM[addr + BES(0x002)] << 7; VR[vt][07] = RSP.DMEM[addr + BES(0x003)] << 7; break; case 05: /* PKMN Puzzle League HVQM decoder */ VR[vt][00] = RSP.DMEM[addr + BES(0x005)] << 7; VR[vt][01] = RSP.DMEM[addr + BES(0x006)] << 7; VR[vt][02] = RSP.DMEM[addr + BES(0x007)] << 7; addr += 0x008; addr &= 0x00000FFF; VR[vt][03] = RSP.DMEM[addr + BES(0x000)] << 7; VR[vt][04] = RSP.DMEM[addr + BES(0x001)] << 7; VR[vt][05] = RSP.DMEM[addr + BES(0x002)] << 7; VR[vt][06] = RSP.DMEM[addr + BES(0x003)] << 7; VR[vt][07] = RSP.DMEM[addr + BES(0x004)] << 7; break; case 06: /* PKMN Puzzle League HVQM decoder */ VR[vt][00] = RSP.DMEM[addr + BES(0x006)] << 7; VR[vt][01] = RSP.DMEM[addr + BES(0x007)] << 7; addr += 0x008; addr &= 0x00000FFF; VR[vt][02] = RSP.DMEM[addr + BES(0x000)] << 7; VR[vt][03] = RSP.DMEM[addr + BES(0x001)] << 7; VR[vt][04] = RSP.DMEM[addr + BES(0x002)] << 7; VR[vt][05] = RSP.DMEM[addr + BES(0x003)] << 7; VR[vt][06] = RSP.DMEM[addr + BES(0x004)] << 7; VR[vt][07] = RSP.DMEM[addr + BES(0x005)] << 7; break; case 07: /* PKMN Puzzle League HVQM decoder */ VR[vt][00] = RSP.DMEM[addr + BES(0x007)] << 7; addr += 0x008; addr &= 0x00000FFF; VR[vt][01] = RSP.DMEM[addr + BES(0x000)] << 7; VR[vt][02] = RSP.DMEM[addr + BES(0x001)] << 7; VR[vt][03] = RSP.DMEM[addr + BES(0x002)] << 7; VR[vt][04] = RSP.DMEM[addr + BES(0x003)] << 7; VR[vt][05] = RSP.DMEM[addr + BES(0x004)] << 7; VR[vt][06] = RSP.DMEM[addr + BES(0x005)] << 7; VR[vt][07] = RSP.DMEM[addr + BES(0x006)] << 7; break; } } static void SPV(int vt, int element, int offset, int base) { register int b; register uint32_t addr; const int e = element; if (e != 0x0) /* SPV, illegal element */ return; addr = (SR[base] + 8*offset) & 0x00000FFF; b = addr & 07; addr &= ~07; switch (b) { case 00: RSP.DMEM[addr + BES(0x007)] = (unsigned char)(VR[vt][07] >> 8); RSP.DMEM[addr + BES(0x006)] = (unsigned char)(VR[vt][06] >> 8); RSP.DMEM[addr + BES(0x005)] = (unsigned char)(VR[vt][05] >> 8); RSP.DMEM[addr + BES(0x004)] = (unsigned char)(VR[vt][04] >> 8); RSP.DMEM[addr + BES(0x003)] = (unsigned char)(VR[vt][03] >> 8); RSP.DMEM[addr + BES(0x002)] = (unsigned char)(VR[vt][02] >> 8); RSP.DMEM[addr + BES(0x001)] = (unsigned char)(VR[vt][01] >> 8); RSP.DMEM[addr + BES(0x000)] = (unsigned char)(VR[vt][00] >> 8); return; case 01: /* F3DZEX 2.08J "Doubutsu no Mori" (Animal Forest) CFB layer */ RSP.DMEM[addr + BES(0x001)] = (unsigned char)(VR[vt][00] >> 8); RSP.DMEM[addr + BES(0x002)] = (unsigned char)(VR[vt][01] >> 8); RSP.DMEM[addr + BES(0x003)] = (unsigned char)(VR[vt][02] >> 8); RSP.DMEM[addr + BES(0x004)] = (unsigned char)(VR[vt][03] >> 8); RSP.DMEM[addr + BES(0x005)] = (unsigned char)(VR[vt][04] >> 8); RSP.DMEM[addr + BES(0x006)] = (unsigned char)(VR[vt][05] >> 8); RSP.DMEM[addr + BES(0x007)] = (unsigned char)(VR[vt][06] >> 8); addr += BES(0x008); addr &= 0x00000FFF; RSP.DMEM[addr] = (unsigned char)(VR[vt][07] >> 8); return; case 02: /* F3DZEX 2.08J "Doubutsu no Mori" (Animal Forest) CFB layer */ RSP.DMEM[addr + BES(0x002)] = (unsigned char)(VR[vt][00] >> 8); RSP.DMEM[addr + BES(0x003)] = (unsigned char)(VR[vt][01] >> 8); RSP.DMEM[addr + BES(0x004)] = (unsigned char)(VR[vt][02] >> 8); RSP.DMEM[addr + BES(0x005)] = (unsigned char)(VR[vt][03] >> 8); RSP.DMEM[addr + BES(0x006)] = (unsigned char)(VR[vt][04] >> 8); RSP.DMEM[addr + BES(0x007)] = (unsigned char)(VR[vt][05] >> 8); addr += 0x008; addr &= 0x00000FFF; RSP.DMEM[addr + BES(0x000)] = (unsigned char)(VR[vt][06] >> 8); RSP.DMEM[addr + BES(0x001)] = (unsigned char)(VR[vt][07] >> 8); return; case 03: /* F3DZEX 2.08J "Doubutsu no Mori" (Animal Forest) CFB layer */ RSP.DMEM[addr + BES(0x003)] = (unsigned char)(VR[vt][00] >> 8); RSP.DMEM[addr + BES(0x004)] = (unsigned char)(VR[vt][01] >> 8); RSP.DMEM[addr + BES(0x005)] = (unsigned char)(VR[vt][02] >> 8); RSP.DMEM[addr + BES(0x006)] = (unsigned char)(VR[vt][03] >> 8); RSP.DMEM[addr + BES(0x007)] = (unsigned char)(VR[vt][04] >> 8); addr += 0x008; addr &= 0x00000FFF; RSP.DMEM[addr + BES(0x000)] = (unsigned char)(VR[vt][05] >> 8); RSP.DMEM[addr + BES(0x001)] = (unsigned char)(VR[vt][06] >> 8); RSP.DMEM[addr + BES(0x002)] = (unsigned char)(VR[vt][07] >> 8); return; case 04: /* F3DZEX 2.08J "Doubutsu no Mori" (Animal Forest) CFB layer */ RSP.DMEM[addr + BES(0x004)] = (unsigned char)(VR[vt][00] >> 8); RSP.DMEM[addr + BES(0x005)] = (unsigned char)(VR[vt][01] >> 8); RSP.DMEM[addr + BES(0x006)] = (unsigned char)(VR[vt][02] >> 8); RSP.DMEM[addr + BES(0x007)] = (unsigned char)(VR[vt][03] >> 8); addr += 0x008; addr &= 0x00000FFF; RSP.DMEM[addr + BES(0x000)] = (unsigned char)(VR[vt][04] >> 8); RSP.DMEM[addr + BES(0x001)] = (unsigned char)(VR[vt][05] >> 8); RSP.DMEM[addr + BES(0x002)] = (unsigned char)(VR[vt][06] >> 8); RSP.DMEM[addr + BES(0x003)] = (unsigned char)(VR[vt][07] >> 8); return; case 05: /* F3DZEX 2.08J "Doubutsu no Mori" (Animal Forest) CFB layer */ RSP.DMEM[addr + BES(0x005)] = (unsigned char)(VR[vt][00] >> 8); RSP.DMEM[addr + BES(0x006)] = (unsigned char)(VR[vt][01] >> 8); RSP.DMEM[addr + BES(0x007)] = (unsigned char)(VR[vt][02] >> 8); addr += 0x008; addr &= 0x00000FFF; RSP.DMEM[addr + BES(0x000)] = (unsigned char)(VR[vt][03] >> 8); RSP.DMEM[addr + BES(0x001)] = (unsigned char)(VR[vt][04] >> 8); RSP.DMEM[addr + BES(0x002)] = (unsigned char)(VR[vt][05] >> 8); RSP.DMEM[addr + BES(0x003)] = (unsigned char)(VR[vt][06] >> 8); RSP.DMEM[addr + BES(0x004)] = (unsigned char)(VR[vt][07] >> 8); return; case 06: /* F3DZEX 2.08J "Doubutsu no Mori" (Animal Forest) CFB layer */ RSP.DMEM[addr + BES(0x006)] = (unsigned char)(VR[vt][00] >> 8); RSP.DMEM[addr + BES(0x007)] = (unsigned char)(VR[vt][01] >> 8); addr += 0x008; addr &= 0x00000FFF; RSP.DMEM[addr + BES(0x000)] = (unsigned char)(VR[vt][02] >> 8); RSP.DMEM[addr + BES(0x001)] = (unsigned char)(VR[vt][03] >> 8); RSP.DMEM[addr + BES(0x002)] = (unsigned char)(VR[vt][04] >> 8); RSP.DMEM[addr + BES(0x003)] = (unsigned char)(VR[vt][05] >> 8); RSP.DMEM[addr + BES(0x004)] = (unsigned char)(VR[vt][06] >> 8); RSP.DMEM[addr + BES(0x005)] = (unsigned char)(VR[vt][07] >> 8); return; case 07: /* F3DZEX 2.08J "Doubutsu no Mori" (Animal Forest) CFB layer */ RSP.DMEM[addr + BES(0x007)] = (unsigned char)(VR[vt][00] >> 8); addr += 0x008; addr &= 0x00000FFF; RSP.DMEM[addr + BES(0x000)] = (unsigned char)(VR[vt][01] >> 8); RSP.DMEM[addr + BES(0x001)] = (unsigned char)(VR[vt][02] >> 8); RSP.DMEM[addr + BES(0x002)] = (unsigned char)(VR[vt][03] >> 8); RSP.DMEM[addr + BES(0x003)] = (unsigned char)(VR[vt][04] >> 8); RSP.DMEM[addr + BES(0x004)] = (unsigned char)(VR[vt][05] >> 8); RSP.DMEM[addr + BES(0x005)] = (unsigned char)(VR[vt][06] >> 8); RSP.DMEM[addr + BES(0x006)] = (unsigned char)(VR[vt][07] >> 8); return; } } static void SUV(int vt, int element, int offset, int base) { register int b; register uint32_t addr; const int e = element; if (e != 0x0) /* SUV, Illegal element */ return; addr = (SR[base] + 8*offset) & 0x00000FFF; b = addr & 07; addr &= ~07; switch (b) { case 00: RSP.DMEM[addr + BES(0x007)] = (unsigned char)(VR[vt][07] >> 7); RSP.DMEM[addr + BES(0x006)] = (unsigned char)(VR[vt][06] >> 7); RSP.DMEM[addr + BES(0x005)] = (unsigned char)(VR[vt][05] >> 7); RSP.DMEM[addr + BES(0x004)] = (unsigned char)(VR[vt][04] >> 7); RSP.DMEM[addr + BES(0x003)] = (unsigned char)(VR[vt][03] >> 7); RSP.DMEM[addr + BES(0x002)] = (unsigned char)(VR[vt][02] >> 7); RSP.DMEM[addr + BES(0x001)] = (unsigned char)(VR[vt][01] >> 7); RSP.DMEM[addr + BES(0x000)] = (unsigned char)(VR[vt][00] >> 7); return; case 04: /* "Indiana Jones and the Infernal Machine" in-game */ RSP.DMEM[addr + BES(0x004)] = (unsigned char)(VR[vt][00] >> 7); RSP.DMEM[addr + BES(0x005)] = (unsigned char)(VR[vt][01] >> 7); RSP.DMEM[addr + BES(0x006)] = (unsigned char)(VR[vt][02] >> 7); RSP.DMEM[addr + BES(0x007)] = (unsigned char)(VR[vt][03] >> 7); addr += 0x008; addr &= 0x00000FFF; RSP.DMEM[addr + BES(0x000)] = (unsigned char)(VR[vt][04] >> 7); RSP.DMEM[addr + BES(0x001)] = (unsigned char)(VR[vt][05] >> 7); RSP.DMEM[addr + BES(0x002)] = (unsigned char)(VR[vt][06] >> 7); RSP.DMEM[addr + BES(0x003)] = (unsigned char)(VR[vt][07] >> 7); return; default: /* Completely legal, just never seen it be done. */ /* SUV, weird address */ return; } } /* * Group III vector loads and stores: * HV, FV, and AV (As of RCP implementation, AV opcodes are reserved.) */ static void LHV(int vt, int element, int offset, int base) { register uint32_t addr; const int e = element; if (e != 0x0) /* LHV, illegal element */ return; addr = (SR[base] + 16*offset) & 0x00000FFF; if (addr & 0x0000000E) /* LHV, illegal address */ return; addr ^= MES(00); VR[vt][07] = RSP.DMEM[addr + HES(0x00E)] << 7; VR[vt][06] = RSP.DMEM[addr + HES(0x00C)] << 7; VR[vt][05] = RSP.DMEM[addr + HES(0x00A)] << 7; VR[vt][04] = RSP.DMEM[addr + HES(0x008)] << 7; VR[vt][03] = RSP.DMEM[addr + HES(0x006)] << 7; VR[vt][02] = RSP.DMEM[addr + HES(0x004)] << 7; VR[vt][01] = RSP.DMEM[addr + HES(0x002)] << 7; VR[vt][00] = RSP.DMEM[addr + HES(0x000)] << 7; return; } static void SHV(int vt, int element, int offset, int base) { register uint32_t addr; const int e = element; if (e != 0x0) /* SHV, illegal element */ return; addr = (SR[base] + 16*offset) & 0x00000FFF; if (addr & 0x0000000E) /* SHV, illegal address */ return; addr ^= MES(00); RSP.DMEM[addr + HES(0x00E)] = (unsigned char)(VR[vt][07] >> 7); RSP.DMEM[addr + HES(0x00C)] = (unsigned char)(VR[vt][06] >> 7); RSP.DMEM[addr + HES(0x00A)] = (unsigned char)(VR[vt][05] >> 7); RSP.DMEM[addr + HES(0x008)] = (unsigned char)(VR[vt][04] >> 7); RSP.DMEM[addr + HES(0x006)] = (unsigned char)(VR[vt][03] >> 7); RSP.DMEM[addr + HES(0x004)] = (unsigned char)(VR[vt][02] >> 7); RSP.DMEM[addr + HES(0x002)] = (unsigned char)(VR[vt][01] >> 7); RSP.DMEM[addr + HES(0x000)] = (unsigned char)(VR[vt][00] >> 7); } static void SFV(int vt, int element, int offset, int base) { const int e = element; register uint32_t addr = ((SR[base] + 16*offset) & 0x00000FFF) & 0x00000FF3; addr ^= BES(00); switch (e) { case 0x0: RSP.DMEM[addr + 0x000] = (unsigned char)(VR[vt][00] >> 7); RSP.DMEM[addr + 0x004] = (unsigned char)(VR[vt][01] >> 7); RSP.DMEM[addr + 0x008] = (unsigned char)(VR[vt][02] >> 7); RSP.DMEM[addr + 0x00C] = (unsigned char)(VR[vt][03] >> 7); break; case 0x8: RSP.DMEM[addr + 0x000] = (unsigned char)(VR[vt][04] >> 7); RSP.DMEM[addr + 0x004] = (unsigned char)(VR[vt][05] >> 7); RSP.DMEM[addr + 0x008] = (unsigned char)(VR[vt][06] >> 7); RSP.DMEM[addr + 0x00C] = (unsigned char)(VR[vt][07] >> 7); break; default: /* SFV, illegal element */ break; } } /* * Group IV vector loads and stores: * QV and RV */ static void LQV(int vt, int element, int offset, int base) { register uint32_t addr; register int b; const int e = element; /* Boss Game Studios illegal elements */ if (e & 0x1) /* LQV, odd element */ return; addr = (SR[base] + 16*offset) & 0x00000FFF; if (addr & 0x00000001) /* LQV, odd address */ return; b = addr & 0x0000000F; addr &= ~0x0000000F; switch (b/2) /* mistake in SGI patent regarding LQV */ { case 0x0/2: VR_S(vt,e+0x0) = *(short *)(RSP.DMEM + addr + HES(0x000)); VR_S(vt,e+0x2) = *(short *)(RSP.DMEM + addr + HES(0x002)); VR_S(vt,e+0x4) = *(short *)(RSP.DMEM + addr + HES(0x004)); VR_S(vt,e+0x6) = *(short *)(RSP.DMEM + addr + HES(0x006)); VR_S(vt,e+0x8) = *(short *)(RSP.DMEM + addr + HES(0x008)); VR_S(vt,e+0xA) = *(short *)(RSP.DMEM + addr + HES(0x00A)); VR_S(vt,e+0xC) = *(short *)(RSP.DMEM + addr + HES(0x00C)); VR_S(vt,e+0xE) = *(short *)(RSP.DMEM + addr + HES(0x00E)); break; case 0x2/2: VR_S(vt,e+0x0) = *(short *)(RSP.DMEM + addr + HES(0x002)); VR_S(vt,e+0x2) = *(short *)(RSP.DMEM + addr + HES(0x004)); VR_S(vt,e+0x4) = *(short *)(RSP.DMEM + addr + HES(0x006)); VR_S(vt,e+0x6) = *(short *)(RSP.DMEM + addr + HES(0x008)); VR_S(vt,e+0x8) = *(short *)(RSP.DMEM + addr + HES(0x00A)); VR_S(vt,e+0xA) = *(short *)(RSP.DMEM + addr + HES(0x00C)); VR_S(vt,e+0xC) = *(short *)(RSP.DMEM + addr + HES(0x00E)); break; case 0x4/2: VR_S(vt,e+0x0) = *(short *)(RSP.DMEM + addr + HES(0x004)); VR_S(vt,e+0x2) = *(short *)(RSP.DMEM + addr + HES(0x006)); VR_S(vt,e+0x4) = *(short *)(RSP.DMEM + addr + HES(0x008)); VR_S(vt,e+0x6) = *(short *)(RSP.DMEM + addr + HES(0x00A)); VR_S(vt,e+0x8) = *(short *)(RSP.DMEM + addr + HES(0x00C)); VR_S(vt,e+0xA) = *(short *)(RSP.DMEM + addr + HES(0x00E)); break; case 0x6/2: VR_S(vt,e+0x0) = *(short *)(RSP.DMEM + addr + HES(0x006)); VR_S(vt,e+0x2) = *(short *)(RSP.DMEM + addr + HES(0x008)); VR_S(vt,e+0x4) = *(short *)(RSP.DMEM + addr + HES(0x00A)); VR_S(vt,e+0x6) = *(short *)(RSP.DMEM + addr + HES(0x00C)); VR_S(vt,e+0x8) = *(short *)(RSP.DMEM + addr + HES(0x00E)); break; case 0x8/2: /* "Resident Evil 2" cinematics and Boss Game Studios */ VR_S(vt,e+0x0) = *(short *)(RSP.DMEM + addr + HES(0x008)); VR_S(vt,e+0x2) = *(short *)(RSP.DMEM + addr + HES(0x00A)); VR_S(vt,e+0x4) = *(short *)(RSP.DMEM + addr + HES(0x00C)); VR_S(vt,e+0x6) = *(short *)(RSP.DMEM + addr + HES(0x00E)); break; case 0xA/2: /* "Conker's Bad Fur Day" audio microcode by Rareware */ VR_S(vt,e+0x0) = *(short *)(RSP.DMEM + addr + HES(0x00A)); VR_S(vt,e+0x2) = *(short *)(RSP.DMEM + addr + HES(0x00C)); VR_S(vt,e+0x4) = *(short *)(RSP.DMEM + addr + HES(0x00E)); break; case 0xC/2: /* "Conker's Bad Fur Day" audio microcode by Rareware */ VR_S(vt,e+0x0) = *(short *)(RSP.DMEM + addr + HES(0x00C)); VR_S(vt,e+0x2) = *(short *)(RSP.DMEM + addr + HES(0x00E)); break; case 0xE/2: /* "Conker's Bad Fur Day" audio microcode by Rareware */ VR_S(vt,e+0x0) = *(short *)(RSP.DMEM + addr + HES(0x00E)); break; } } static void LRV(int vt, int element, int offset, int base) { register uint32_t addr; register int b; const int e = element; if (e != 0x0) /* LVR, illegal element */ return; addr = (SR[base] + 16*offset) & 0x00000FFF; if (addr & 0x00000001) /* LRV, odd address */ return; b = addr & 0x0000000F; addr &= ~0x0000000F; switch (b/2) { case 0xE/2: VR[vt][01] = *(short *)(RSP.DMEM + addr + HES(0x000)); VR[vt][02] = *(short *)(RSP.DMEM + addr + HES(0x002)); VR[vt][03] = *(short *)(RSP.DMEM + addr + HES(0x004)); VR[vt][04] = *(short *)(RSP.DMEM + addr + HES(0x006)); VR[vt][05] = *(short *)(RSP.DMEM + addr + HES(0x008)); VR[vt][06] = *(short *)(RSP.DMEM + addr + HES(0x00A)); VR[vt][07] = *(short *)(RSP.DMEM + addr + HES(0x00C)); return; case 0xC/2: VR[vt][02] = *(short *)(RSP.DMEM + addr + HES(0x000)); VR[vt][03] = *(short *)(RSP.DMEM + addr + HES(0x002)); VR[vt][04] = *(short *)(RSP.DMEM + addr + HES(0x004)); VR[vt][05] = *(short *)(RSP.DMEM + addr + HES(0x006)); VR[vt][06] = *(short *)(RSP.DMEM + addr + HES(0x008)); VR[vt][07] = *(short *)(RSP.DMEM + addr + HES(0x00A)); return; case 0xA/2: VR[vt][03] = *(short *)(RSP.DMEM + addr + HES(0x000)); VR[vt][04] = *(short *)(RSP.DMEM + addr + HES(0x002)); VR[vt][05] = *(short *)(RSP.DMEM + addr + HES(0x004)); VR[vt][06] = *(short *)(RSP.DMEM + addr + HES(0x006)); VR[vt][07] = *(short *)(RSP.DMEM + addr + HES(0x008)); return; case 0x8/2: VR[vt][04] = *(short *)(RSP.DMEM + addr + HES(0x000)); VR[vt][05] = *(short *)(RSP.DMEM + addr + HES(0x002)); VR[vt][06] = *(short *)(RSP.DMEM + addr + HES(0x004)); VR[vt][07] = *(short *)(RSP.DMEM + addr + HES(0x006)); return; case 0x6/2: VR[vt][05] = *(short *)(RSP.DMEM + addr + HES(0x000)); VR[vt][06] = *(short *)(RSP.DMEM + addr + HES(0x002)); VR[vt][07] = *(short *)(RSP.DMEM + addr + HES(0x004)); return; case 0x4/2: VR[vt][06] = *(short *)(RSP.DMEM + addr + HES(0x000)); VR[vt][07] = *(short *)(RSP.DMEM + addr + HES(0x002)); return; case 0x2/2: VR[vt][07] = *(short *)(RSP.DMEM + addr + HES(0x000)); return; case 0x0/2: return; } } static void SQV(int vt, int element, int offset, int base) { register int b; const unsigned int e = element; register uint32_t addr = (SR[base] + 16*offset) & 0x00000FFF; if (e != 0x0) { /* illegal SQV, happens with "Mia Hamm Soccer 64" */ register unsigned int i; #if (VR_STATIC_WRAPAROUND == 1) vector_copy(VR[vt] + N, VR[vt]); for (i = 0; i < 16 - addr%16; i++) RSP.DMEM[BES((addr + i) & 0xFFF)] = VR_B(vt, e + i); #else for (i = 0; i < 16 - addr%16; i++) RSP.DMEM[BES((addr + i) & 0xFFF)] = VR_B(vt, (e + i) & 0xF); #endif return; } b = addr & 0x0000000F; addr &= ~0x0000000F; switch (b) { case 00: *(short *)(RSP.DMEM + addr + HES(0x000)) = VR[vt][00]; *(short *)(RSP.DMEM + addr + HES(0x002)) = VR[vt][01]; *(short *)(RSP.DMEM + addr + HES(0x004)) = VR[vt][02]; *(short *)(RSP.DMEM + addr + HES(0x006)) = VR[vt][03]; *(short *)(RSP.DMEM + addr + HES(0x008)) = VR[vt][04]; *(short *)(RSP.DMEM + addr + HES(0x00A)) = VR[vt][05]; *(short *)(RSP.DMEM + addr + HES(0x00C)) = VR[vt][06]; *(short *)(RSP.DMEM + addr + HES(0x00E)) = VR[vt][07]; break; case 02: *(short *)(RSP.DMEM + addr + HES(0x002)) = VR[vt][00]; *(short *)(RSP.DMEM + addr + HES(0x004)) = VR[vt][01]; *(short *)(RSP.DMEM + addr + HES(0x006)) = VR[vt][02]; *(short *)(RSP.DMEM + addr + HES(0x008)) = VR[vt][03]; *(short *)(RSP.DMEM + addr + HES(0x00A)) = VR[vt][04]; *(short *)(RSP.DMEM + addr + HES(0x00C)) = VR[vt][05]; *(short *)(RSP.DMEM + addr + HES(0x00E)) = VR[vt][06]; break; case 04: *(short *)(RSP.DMEM + addr + HES(0x004)) = VR[vt][00]; *(short *)(RSP.DMEM + addr + HES(0x006)) = VR[vt][01]; *(short *)(RSP.DMEM + addr + HES(0x008)) = VR[vt][02]; *(short *)(RSP.DMEM + addr + HES(0x00A)) = VR[vt][03]; *(short *)(RSP.DMEM + addr + HES(0x00C)) = VR[vt][04]; *(short *)(RSP.DMEM + addr + HES(0x00E)) = VR[vt][05]; break; case 06: *(short *)(RSP.DMEM + addr + HES(0x006)) = VR[vt][00]; *(short *)(RSP.DMEM + addr + HES(0x008)) = VR[vt][01]; *(short *)(RSP.DMEM + addr + HES(0x00A)) = VR[vt][02]; *(short *)(RSP.DMEM + addr + HES(0x00C)) = VR[vt][03]; *(short *)(RSP.DMEM + addr + HES(0x00E)) = VR[vt][04]; break; default: /* SQV, weird address */ break; } } static void SRV(int vt, int element, int offset, int base) { register uint32_t addr; register int b; const int e = element; if (e != 0x0) /* SRV, illegal element */ return; addr = (SR[base] + 16*offset) & 0x00000FFF; if (addr & 0x00000001) /* SRV, odd address */ return; b = addr & 0x0000000F; addr &= ~0x0000000F; switch (b/2) { case 0xE/2: *(short *)(RSP.DMEM + addr + HES(0x000)) = VR[vt][01]; *(short *)(RSP.DMEM + addr + HES(0x002)) = VR[vt][02]; *(short *)(RSP.DMEM + addr + HES(0x004)) = VR[vt][03]; *(short *)(RSP.DMEM + addr + HES(0x006)) = VR[vt][04]; *(short *)(RSP.DMEM + addr + HES(0x008)) = VR[vt][05]; *(short *)(RSP.DMEM + addr + HES(0x00A)) = VR[vt][06]; *(short *)(RSP.DMEM + addr + HES(0x00C)) = VR[vt][07]; break; case 0xC/2: *(short *)(RSP.DMEM + addr + HES(0x000)) = VR[vt][02]; *(short *)(RSP.DMEM + addr + HES(0x002)) = VR[vt][03]; *(short *)(RSP.DMEM + addr + HES(0x004)) = VR[vt][04]; *(short *)(RSP.DMEM + addr + HES(0x006)) = VR[vt][05]; *(short *)(RSP.DMEM + addr + HES(0x008)) = VR[vt][06]; *(short *)(RSP.DMEM + addr + HES(0x00A)) = VR[vt][07]; break; case 0xA/2: *(short *)(RSP.DMEM + addr + HES(0x000)) = VR[vt][03]; *(short *)(RSP.DMEM + addr + HES(0x002)) = VR[vt][04]; *(short *)(RSP.DMEM + addr + HES(0x004)) = VR[vt][05]; *(short *)(RSP.DMEM + addr + HES(0x006)) = VR[vt][06]; *(short *)(RSP.DMEM + addr + HES(0x008)) = VR[vt][07]; break; case 0x8/2: *(short *)(RSP.DMEM + addr + HES(0x000)) = VR[vt][04]; *(short *)(RSP.DMEM + addr + HES(0x002)) = VR[vt][05]; *(short *)(RSP.DMEM + addr + HES(0x004)) = VR[vt][06]; *(short *)(RSP.DMEM + addr + HES(0x006)) = VR[vt][07]; break; case 0x6/2: *(short *)(RSP.DMEM + addr + HES(0x000)) = VR[vt][05]; *(short *)(RSP.DMEM + addr + HES(0x002)) = VR[vt][06]; *(short *)(RSP.DMEM + addr + HES(0x004)) = VR[vt][07]; break; case 0x4/2: *(short *)(RSP.DMEM + addr + HES(0x000)) = VR[vt][06]; *(short *)(RSP.DMEM + addr + HES(0x002)) = VR[vt][07]; break; case 0x2/2: *(short *)(RSP.DMEM + addr + HES(0x000)) = VR[vt][07]; break; case 0x0/2: break; } } /* * Group V vector loads and stores * TV and SWV (As of RCP implementation, LTWV opcode was undesired.) */ static void LTV(int vt, int element, int offset, int base) { register int i; register uint32_t addr; const int e = element; if (e & 1) /* LTV, illegal element */ return; if (vt & 07) /* LTV, uncertain case */ return; /* For LTV I am not sure; for STV I have an idea. */ addr = (SR[base] + 16*offset) & 0x00000FFF; if (addr & 0x0000000F) /* LTV, illegal address */ return; for (i = 0; i < 8; i++) /* SGI screwed LTV up on N64. See STV instead. */ VR[vt+i][(i - e/2) & 07] = *(int16_t*)(RSP.DMEM + addr + HES(2*i)); } static void STV(int vt, int element, int offset, int base) { register int i; register uint32_t addr; const int e = element; if (e & 1) /* STV, illegal element */ return; if (vt & 07) /* STV, uncertain case */ return; /* vt &= 030; */ addr = (SR[base] + 16*offset) & 0x00000FFF; if (addr & 0x0000000F) /* STV, illegal address */ return; for (i = 0; i < 8; i++) *(short *)(RSP.DMEM + addr + HES(2*i)) = VR[vt + (e/2 + i)%8][i]; } /* * unused SGI opcodes for LWC2 on the RCP: * LAV, LXV, LZV, LTWV */ NOINLINE static void lwc_res(int vt, int element, signed offset, int base) { #if 0 static char disasm[32]; sprintf( disasm, "%cWC2 $v%d[0x%X], %i($%d)", 'L', vt, element &= 0xF, offset, base ); #endif } /* * unused SGI opcodes for SWC2 on the RCP: * SAV, SXV, SZV */ NOINLINE static void swc_res(int vt, int element, signed offset, int base) { #if 0 static char disasm[32]; sprintf( disasm, "%cWC2 $v%d[0x%X], %i($%d)", 'S', vt, element &= 0xF, offset, base ); #endif } static void LFV(int vt, int element, int offset, int base) { /* Dummy implementation only: Do any games execute this? */ lwc_res(vt, element, offset, base); } static void SWV(int vt, int element, int offset, int base) { /* Dummy implementation only: Do any games execute this? */ swc_res(vt, element, offset, base); } static void (*LWC2_op[1 << 5])(int, int, signed, int) = { LBV ,LSV ,LLV ,LDV ,LQV ,LRV ,LPV ,LUV , LHV ,LFV ,lwc_res,LTV ,lwc_res,lwc_res,lwc_res,lwc_res, lwc_res,lwc_res,lwc_res,lwc_res,lwc_res,lwc_res,lwc_res,lwc_res, lwc_res,lwc_res,lwc_res,lwc_res,lwc_res,lwc_res,lwc_res,lwc_res, }; /* 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 */ static void (*SWC2_op[1 << 5])(int, int, signed, int) = { SBV ,SSV ,SLV ,SDV ,SQV ,SRV ,SPV ,SUV , SHV ,SFV ,SWV ,STV ,swc_res,swc_res,swc_res,swc_res, swc_res,swc_res,swc_res,swc_res,swc_res,swc_res,swc_res,swc_res, swc_res,swc_res,swc_res,swc_res,swc_res,swc_res,swc_res,swc_res, }; /* 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 */ /*** Modern pseudo-operations (not real instructions, but nice shortcuts) ***/ static void ULW(int rd, uint32_t addr) { /* "Unaligned Load Word" */ if (addr & 0x00000001) { SR_temp.B[03] = RSP.DMEM[BES(addr)]; addr = (addr + 0x001) & 0xFFF; SR_temp.B[02] = RSP.DMEM[BES(addr)]; addr = (addr + 0x001) & 0xFFF; SR_temp.B[01] = RSP.DMEM[BES(addr)]; addr = (addr + 0x001) & 0xFFF; SR_temp.B[00] = RSP.DMEM[BES(addr)]; } else /* addr & 0x00000002 */ { SR_temp.H[01] = *(short *)(RSP.DMEM + addr - HES(0x000)); addr = (addr + 0x002) & 0xFFF; SR_temp.H[00] = *(short *)(RSP.DMEM + addr + HES(0x000)); } SR[rd] = SR_temp.W; /* SR[0] = 0x00000000; */ } static void USW(int rs, uint32_t addr) { /* "Unaligned Store Word" */ SR_temp.W = SR[rs]; if (addr & 0x00000001) { RSP.DMEM[BES(addr)] = SR_temp.B[03]; addr = (addr + 0x001) & 0xFFF; RSP.DMEM[BES(addr)] = SR_temp.B[02]; addr = (addr + 0x001) & 0xFFF; RSP.DMEM[BES(addr)] = SR_temp.B[01]; addr = (addr + 0x001) & 0xFFF; RSP.DMEM[BES(addr)] = SR_temp.B[00]; } else /* addr & 0x00000002 */ { *(short *)(RSP.DMEM + addr - HES(0x000)) = SR_temp.H[01]; addr = (addr + 0x002) & 0xFFF; *(short *)(RSP.DMEM + addr + HES(0x000)) = SR_temp.H[00]; } } /* Allocate the RSP CPU loop to its own functional space. */ #define FIT_IMEM(PC) (PC & 0xFFF & 0xFFC) NOINLINE void run_task(void) { register uint32_t PC; register unsigned int i; #ifdef WAIT_FOR_CPU_HOST for (i = 0; i < 32; i++) MFC0_count[i] = 0; #endif PC = FIT_IMEM(*RSP.SP_PC_REG); while ((*RSP.SP_STATUS_REG & 0x00000001) == 0x00000000) { register uint32_t inst; register int rd, rs, rt; register int base; inst = *(uint32_t *)(RSP.IMEM + FIT_IMEM(PC)); #ifdef EMULATE_STATIC_PC PC = (PC + 0x004); EX: #endif #ifdef SP_EXECUTE_LOG step_SP_commands(inst); #endif if (inst >> 25 == 0x25) /* is a VU instruction */ { const int opcode = inst % 64; /* inst.R.func */ const int vd = (inst & 0x000007FF) >> 6; /* inst.R.sa */ const int vs = (unsigned short)(inst) >> 11; /* inst.R.rd */ const int vt = (inst >> 16) & 31; /* inst.R.rt */ const int e = (inst >> 21) & 0xF; /* rs & 0xF */ COP2_C2[opcode](vd, vs, vt, e); } else { const int op = inst >> 26; const int element = (inst & 0x000007FF) >> 7; switch (op) { int16_t offset; register uint32_t addr; case 000: /* SPECIAL */ #if (1u >> 1 == 0) rd = (inst & 0x0000FFFFu) >> 11; /* rs = inst >> 21; // Primary op is 0, so we don't need &= 31. */ #else rd = (inst >> 11) % 32; /* rs = (inst >> 21) % 32; */ #endif rt = (inst >> 16) % (1 << 5); switch (inst % 64) { case 000: /* SLL */ SR[rd] = SR[rt] << MASK_SA(inst >> 6); SR[0] = 0x00000000; continue; case 002: /* SRL */ SR[rd] = (unsigned)(SR[rt]) >> MASK_SA(inst >> 6); SR[0] = 0x00000000; continue; case 003: /* SRA */ SR[rd] = (signed)(SR[rt]) >> MASK_SA(inst >> 6); SR[0] = 0x00000000; continue; case 004: /* SLLV */ SR[rd] = SR[rt] << MASK_SA(SR[rs = inst >> 21]); SR[0] = 0x00000000; continue; case 006: /* SRLV */ SR[rd] = (unsigned)(SR[rt]) >> MASK_SA(SR[rs = inst >> 21]); SR[0] = 0x00000000; continue; case 007: /* SRAV */ SR[rd] = (signed)(SR[rt]) >> MASK_SA(SR[rs = inst >> 21]); SR[0] = 0x00000000; continue; case 011: /* JALR */ SR[rd] = (PC + LINK_OFF) & 0x00000FFC; SR[0] = 0x00000000; case 010: /* JR */ set_PC(SR[rs = inst >> 21]); goto BRANCH; case 015: /* BREAK */ *RSP.SP_STATUS_REG |= 0x00000003; /* BROKE | HALT */ if (*RSP.SP_STATUS_REG & 0x00000040) { /* SP_STATUS_INTR_BREAK */ *RSP.MI_INTR_REG |= 0x00000001; RSP.CheckInterrupts(); } continue; case 040: /* ADD */ case 041: /* ADDU */ rs = inst >> 21; SR[rd] = SR[rs] + SR[rt]; SR[0] = 0x00000000; /* needed for Rareware ucodes */ continue; case 042: /* SUB */ case 043: /* SUBU */ rs = inst >> 21; SR[rd] = SR[rs] - SR[rt]; SR[0] = 0x00000000; continue; case 044: /* AND */ rs = inst >> 21; SR[rd] = SR[rs] & SR[rt]; SR[0] = 0x00000000; /* needed for Rareware ucodes */ continue; case 045: /* OR */ rs = inst >> 21; SR[rd] = SR[rs] | SR[rt]; SR[0] = 0x00000000; continue; case 046: /* XOR */ rs = inst >> 21; SR[rd] = SR[rs] ^ SR[rt]; SR[0] = 0x00000000; continue; case 047: /* NOR */ rs = inst >> 21; SR[rd] = ~(SR[rs] | SR[rt]); SR[0] = 0x00000000; continue; case 052: /* SLT */ rs = inst >> 21; SR[rd] = ((signed)(SR[rs]) < (signed)(SR[rt])); SR[0] = 0x00000000; continue; case 053: /* SLTU */ rs = inst >> 21; SR[rd] = ((unsigned)(SR[rs]) < (unsigned)(SR[rt])); SR[0] = 0x00000000; continue; default: res_S(); continue; } continue; case 001: /* REGIMM */ rs = (inst >> 21) & 31; rt = (inst >> 16) & 31; switch (rt) { case 020: /* BLTZAL */ SR[31] = (PC + LINK_OFF) & 0x00000FFC; case 000: /* BLTZ */ if (!(SR[rs] < 0)) continue; set_PC(PC + 4*inst + SLOT_OFF); goto BRANCH; case 021: /* BGEZAL */ SR[31] = (PC + LINK_OFF) & 0x00000FFC; case 001: /* BGEZ */ if (!(SR[rs] >= 0)) continue; set_PC(PC + 4*inst + SLOT_OFF); goto BRANCH; default: res_S(); continue; } continue; case 003: /* JAL */ SR[31] = (PC + LINK_OFF) & 0x00000FFC; case 002: /* J */ set_PC(4*inst); goto BRANCH; case 004: /* BEQ */ rs = (inst >> 21) & 31; rt = (inst >> 16) & 31; if (!(SR[rs] == SR[rt])) continue; set_PC(PC + 4*inst + SLOT_OFF); goto BRANCH; case 005: /* BNE */ rs = (inst >> 21) & 31; rt = (inst >> 16) & 31; if (!(SR[rs] != SR[rt])) continue; set_PC(PC + 4*inst + SLOT_OFF); goto BRANCH; case 006: /* BLEZ */ if (!((signed)SR[rs = (inst >> 21) & 31] <= 0x00000000)) continue; set_PC(PC + 4*inst + SLOT_OFF); goto BRANCH; case 007: /* BGTZ */ if (!((signed)SR[rs = (inst >> 21) & 31] > 0x00000000)) continue; set_PC(PC + 4*inst + SLOT_OFF); goto BRANCH; case 010: /* ADDI */ case 011: /* ADDIU */ rs = (inst >> 21) & 31; rt = (inst >> 16) & 31; SR[rt] = SR[rs] + (signed short)(inst); SR[0] = 0x00000000; continue; case 012: /* SLTI */ rs = (inst >> 21) & 31; rt = (inst >> 16) & 31; SR[rt] = ((signed)(SR[rs]) < (signed short)(inst)); SR[0] = 0x00000000; continue; case 013: /* SLTIU */ rs = (inst >> 21) & 31; rt = (inst >> 16) & 31; SR[rt] = ((unsigned)(SR[rs]) < (unsigned short)(inst)); SR[0] = 0x00000000; continue; case 014: /* ANDI */ rs = (inst >> 21) & 31; rt = (inst >> 16) & 31; SR[rt] = SR[rs] & (unsigned short)(inst); SR[0] = 0x00000000; continue; case 015: /* ORI */ rs = (inst >> 21) & 31; rt = (inst >> 16) & 31; SR[rt] = SR[rs] | (unsigned short)(inst); SR[0] = 0x00000000; continue; case 016: /* XORI */ rs = (inst >> 21) & 31; rt = (inst >> 16) & 31; SR[rt] = SR[rs] ^ (unsigned short)(inst); SR[0] = 0x00000000; continue; case 017: /* LUI */ SR[rt = (inst >> 16) & 31] = inst << 16; SR[0] = 0x00000000; continue; case 020: /* COP0 */ rd = (inst & 0x0000F800u) >> 11; rs = (inst >> 21) & 31; rt = (inst >> 16) & 31; switch (rs) { case 000: /* MFC0 */ MFC0(rt, rd & 0xF); continue; case 004: /* MTC0 */ MTC0[rd & 0xF](rt); continue; default: res_S(); continue; } continue; case 022: /* COP2 */ rd = (inst & 0x0000F800u) >> 11; rs = (inst >> 21) & 31; rt = (inst >> 16) & 31; switch (rs) { case 000: /* MFC2 */ MFC2(rt, rd, element); continue; case 002: /* CFC2 */ CFC2(rt, rd); continue; case 004: /* MTC2 */ MTC2(rt, rd, element); continue; case 006: /* CTC2 */ CTC2(rt, rd); continue; default: res_S(); continue; } continue; case 040: /* LB */ rt = (inst >> 16) % (1 << 5); offset = (signed short)(inst); addr = (SR[base = (inst >> 21) & 31] + offset) & 0x00000FFF; SR[rt] = RSP.DMEM[BES(addr)]; SR[rt] = (signed char)(SR[rt]); SR[0] = 0x00000000; continue; case 041: /* LH */ rt = (inst >> 16) % (1 << 5); offset = (signed short)(inst); addr = (SR[base = (inst >> 21) & 31] + offset) & 0x00000FFF; if (addr%0x004 == 0x003) { SR_B(rt, 2) = RSP.DMEM[addr - BES(0x000)]; addr = (addr + 0x00000001) & 0x00000FFF; SR_B(rt, 3) = RSP.DMEM[addr + BES(0x000)]; SR[rt] = (signed short)(SR[rt]); } else { addr -= HES(0x000)*(addr%0x004 - 1); SR[rt] = *(signed short *)(RSP.DMEM + addr); } SR[0] = 0x00000000; continue; case 043: /* LW */ rt = (inst >> 16) % (1 << 5); offset = (signed short)(inst); addr = (SR[base = (inst >> 21) & 31] + offset) & 0x00000FFF; if (addr%0x004 != 0x000) ULW(rt, addr); else SR[rt] = *(int32_t *)(RSP.DMEM + addr); SR[0] = 0x00000000; continue; case 044: /* LBU */ rt = (inst >> 16) % (1 << 5); offset = (signed short)(inst); addr = (SR[base = (inst >> 21) & 31] + offset) & 0x00000FFF; SR[rt] = RSP.DMEM[BES(addr)]; SR[rt] = (unsigned char)(SR[rt]); SR[0] = 0x00000000; continue; case 045: /* LHU */ rt = (inst >> 16) % (1 << 5); offset = (signed short)(inst); addr = (SR[base = (inst >> 21) & 31] + offset) & 0x00000FFF; if (addr%0x004 == 0x003) { SR_B(rt, 2) = RSP.DMEM[addr - BES(0x000)]; addr = (addr + 0x00000001) & 0x00000FFF; SR_B(rt, 3) = RSP.DMEM[addr + BES(0x000)]; SR[rt] = (unsigned short)(SR[rt]); } else { addr -= HES(0x000)*(addr%0x004 - 1); SR[rt] = *(unsigned short *)(RSP.DMEM + addr); } SR[0] = 0x00000000; continue; case 050: /* SB */ rt = (inst >> 16) % (1 << 5); offset = (signed short)(inst); addr = (SR[base = (inst >> 21) & 31] + offset) & 0x00000FFF; RSP.DMEM[BES(addr)] = (unsigned char)(SR[rt]); continue; case 051: /* SH */ rt = (inst >> 16) % (1 << 5); offset = (signed short)(inst); addr = (SR[base = (inst >> 21) & 31] + offset) & 0x00000FFF; if (addr%0x004 == 0x003) { RSP.DMEM[addr - BES(0x000)] = SR_B(rt, 2); addr = (addr + 0x00000001) & 0x00000FFF; RSP.DMEM[addr + BES(0x000)] = SR_B(rt, 3); continue; } addr -= HES(0x000)*(addr%0x004 - 1); *(short *)(RSP.DMEM + addr) = (short)(SR[rt]); continue; case 053: /* SW */ rt = (inst >> 16) % (1 << 5); offset = (signed short)(inst); addr = (SR[base = (inst >> 21) & 31] + offset) & 0x00000FFF; if (addr%0x004 != 0x000) USW(rt, addr); else *(int32_t *)(RSP.DMEM + addr) = SR[rt]; continue; case 062: /* LWC2 */ rt = (inst >> 16) % (1 << 5); offset = (signed short)(inst & 0x0000FFFFu); #if defined(ARCH_MIN_SSE2) offset <<= 5 + 4; /* safe on x86, skips 5-bit rd, 4-bit element */ offset >>= 5 + 4; #else offset = SE(offset, 6); #endif base = (inst >> 21) & 31; LWC2_op[rd = (inst & 0xF800u) >> 11](rt, element, offset, base); continue; case 072: /* SWC2 */ rt = (inst >> 16) % (1 << 5); offset = (signed short)(inst & 0x0000FFFFu); #if defined(ARCH_MIN_SSE2) offset <<= 5 + 4; /* safe on x86, skips 5-bit rd, 4-bit element */ offset >>= 5 + 4; #else offset = SE(offset, 6); #endif base = (inst >> 21) & 31; SWC2_op[rd = (inst & 0xF800u) >> 11](rt, element, offset, base); continue; default: res_S(); continue; } } #ifndef EMULATE_STATIC_PC if (stage == 2) /* branch phase of scheduler */ { stage = 0*stage; PC = temp_PC & 0x00000FFC; *RSP.SP_PC_REG = temp_PC; } else { stage = 2*stage; /* next IW in branch delay slot? */ PC = (PC + 0x004) & 0xFFC; *RSP.SP_PC_REG = 0x04001000 + PC; } continue; #else continue; BRANCH: inst = *(uint32_t *)(RSP.IMEM + FIT_IMEM(PC)); PC = temp_PC & 0x00000FFC; goto EX; #endif } *RSP.SP_PC_REG = 0x04001000 | FIT_IMEM(PC); if (*RSP.SP_STATUS_REG & 0x00000002) /* normal exit, from executing BREAK */ return; else if (*RSP.MI_INTR_REG & 0x00000001) /* interrupt set by MTC0 to break */ RSP.CheckInterrupts(); else if (*RSP.SP_SEMAPHORE_REG != 0x00000000) /* semaphore lock fixes */ {} #ifndef WAIT_FOR_CPU_HOST else /* ??? unknown, possibly external intervention from CPU memory map */ return; /* SP_SET_HALT */ #endif *RSP.SP_STATUS_REG &= ~0x00000001; /* CPU restarts with the correct SIGs. */ } EXPORT unsigned int CALL cxd4DoRspCycles(unsigned int cycles) { OSTask_type task_type; if (*RSP.SP_STATUS_REG & 0x00000003) /* SP_STATUS_HALT */ return 0x00000000; task_type = 0x00000000 #ifdef MSB_FIRST | (uint32_t)RSP.DMEM[0xFC0] << 24 | (uint32_t)RSP.DMEM[0xFC1] << 16 | (uint32_t)RSP.DMEM[0xFC2] << 8 | (uint32_t)RSP.DMEM[0xFC3] << 0; #else | *((int32_t*)(RSP.DMEM + 0x000FC0U)); #endif switch (task_type) { /* Simulation barrier to redirect processing externally. */ #ifdef EXTERN_COMMAND_LIST_GBI case M_GFXTASK: if (CFG_HLE_GFX == 0) break; if (*(int32_t*)(RSP.DMEM + 0xFF0) == 0x00000000) break; /* Resident Evil 2, null task pointers */ if (rsp_info.ProcessDlistList != NULL) rsp_info.ProcessDlistList(); *RSP.SP_STATUS_REG |= 0x00000203; if (*RSP.SP_STATUS_REG & 0x00000040) /* SP_STATUS_INTR_BREAK */ { *RSP.MI_INTR_REG |= 0x00000001; /* VR4300 SP interrupt */ rsp_info.CheckInterrupts(); } if (*RSP.DPC_STATUS_REG & 0x00000002) /* DPC_STATUS_FREEZE */ { /* DPC_CLR_FREEZE */ *RSP.DPC_STATUS_REG &= ~0x00000002; } return 0; #endif #ifdef EXTERN_COMMAND_LIST_ABI case M_AUDTASK: if (CFG_HLE_AUD == 0) break; if (rsp_info.ProcessAlistList != 0) rsp_info.ProcessAlistList(); *RSP.SP_STATUS_REG |= 0x00000203; if (*RSP.SP_STATUS_REG & 0x00000040) /* SP_STATUS_INTR_BREAK */ { *RSP.MI_INTR_REG |= 0x00000001; /* VR4300 SP interrupt */ rsp_info.CheckInterrupts(); } return 0; #endif case M_VIDTASK: /* stub */ break; case M_NJPEGTASK: /* Zelda, Pokemon, others */ break; case M_NULTASK: break; case M_HVQMTASK: if (rsp_info.ShowCFB != 0) rsp_info.ShowCFB(); /* forced FB refresh in case gfx plugin skip */ break; } run_task(); /* * An optional EMMS when compiling with Intel SIMD or MMX support. * * Whether or not MMX has been executed in this emulator, here is a good time * to finally empty the MM state, at the end of a long interpreter loop. */ #ifdef ARCH_MIN_SSE2 _mm_empty(); #endif return (cycles); } mupen64plus-video-gliden64/src/GLideNHQ/TxCache.cpp000664 001750 001750 00000025714 12655644434 023015 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef __MSC__ #pragma warning(disable: 4786) #endif #include "TxCache.h" #include "TxDbg.h" #include #include #include #include TxCache::~TxCache() { /* free memory, clean up, etc */ clear(); delete _txUtil; } TxCache::TxCache(int options, int cachesize, const wchar_t *path, const wchar_t *ident, dispInfoFuncExt callback) { _txUtil = new TxUtil(); _options = options; _cacheSize = cachesize; _callback = callback; _totalSize = 0; /* save path name */ if (path) _path.assign(path); /* save ROM name */ if (ident) _ident.assign(ident); /* zlib memory buffers to (de)compress hires textures */ if (_options & (GZ_TEXCACHE|GZ_HIRESTEXCACHE)) { _gzdest0 = TxMemBuf::getInstance()->get(0); _gzdest1 = TxMemBuf::getInstance()->get(1); _gzdestLen = (TxMemBuf::getInstance()->size_of(0) < TxMemBuf::getInstance()->size_of(1)) ? TxMemBuf::getInstance()->size_of(0) : TxMemBuf::getInstance()->size_of(1); if (!_gzdest0 || !_gzdest1 || !_gzdestLen) { _options &= ~(GZ_TEXCACHE|GZ_HIRESTEXCACHE); _gzdest0 = NULL; _gzdest1 = NULL; _gzdestLen = 0; } } } boolean TxCache::add(uint64 checksum, GHQTexInfo *info, int dataSize) { /* NOTE: dataSize must be provided if info->data is zlib compressed. */ if (!checksum || !info->data) return 0; uint8 *dest = info->data; uint32 format = info->format; if (!dataSize) { dataSize = _txUtil->sizeofTx(info->width, info->height, info->format); if (!dataSize) return 0; if (_options & (GZ_TEXCACHE|GZ_HIRESTEXCACHE)) { /* zlib compress it. compression level:1 (best speed) */ uint32 destLen = _gzdestLen; dest = (dest == _gzdest0) ? _gzdest1 : _gzdest0; if (compress2(dest, &destLen, info->data, dataSize, 1) != Z_OK) { dest = info->data; DBG_INFO(80, wst("Error: zlib compression failed!\n")); } else { DBG_INFO(80, wst("zlib compressed: %.02fkb->%.02fkb\n"), (float)dataSize/1000, (float)destLen/1000); dataSize = destLen; format |= GL_TEXFMT_GZ; } } } /* if cache size exceeds limit, remove old cache */ if (_cacheSize > 0) { _totalSize += dataSize; if ((_totalSize > _cacheSize) && !_cachelist.empty()) { /* _cachelist is arranged so that frequently used textures are in the back */ std::list::iterator itList = _cachelist.begin(); while (itList != _cachelist.end()) { /* find it in _cache */ std::map::iterator itMap = _cache.find(*itList); if (itMap != _cache.end()) { /* yep we have it. remove it. */ _totalSize -= (*itMap).second->size; free((*itMap).second->info.data); delete (*itMap).second; _cache.erase(itMap); } itList++; /* check if memory cache has enough space */ if (_totalSize <= _cacheSize) break; } /* remove from _cachelist */ _cachelist.erase(_cachelist.begin(), itList); DBG_INFO(80, wst("+++++++++\n")); } _totalSize -= dataSize; } /* cache it */ uint8 *tmpdata = (uint8*)malloc(dataSize); if (tmpdata) { TXCACHE *txCache = new TXCACHE; if (txCache) { /* we can directly write as we filter, but for now we get away * with doing memcpy after all the filtering is done. */ memcpy(tmpdata, dest, dataSize); /* copy it */ memcpy(&txCache->info, info, sizeof(GHQTexInfo)); txCache->info.data = tmpdata; txCache->info.format = format; txCache->size = dataSize; /* add to cache */ if (_cacheSize > 0) { _cachelist.push_back(checksum); txCache->it = --(_cachelist.end()); } /* _cache[checksum] = txCache; */ _cache.insert(std::map::value_type(checksum, txCache)); #ifdef DEBUG DBG_INFO(80, wst("[%5d] added!! crc:%08X %08X %d x %d gfmt:%x total:%.02fmb\n"), _cache.size(), (uint32)(checksum >> 32), (uint32)(checksum & 0xffffffff), info->width, info->height, info->format & 0xffff, (float)_totalSize/1000000); if (_cacheSize > 0) { DBG_INFO(80, wst("cache max config:%.02fmb\n"), (float)_cacheSize/1000000); if (_cache.size() != _cachelist.size()) { DBG_INFO(80, wst("Error: cache/cachelist mismatch! (%d/%d)\n"), _cache.size(), _cachelist.size()); } } #endif /* total cache size */ _totalSize += dataSize; return 1; } free(tmpdata); } return 0; } boolean TxCache::get(uint64 checksum, GHQTexInfo *info) { if (!checksum || _cache.empty()) return 0; /* find a match in cache */ std::map::iterator itMap = _cache.find(checksum); if (itMap != _cache.end()) { /* yep, we've got it. */ memcpy(info, &(((*itMap).second)->info), sizeof(GHQTexInfo)); /* push it to the back of the list */ if (_cacheSize > 0) { _cachelist.erase(((*itMap).second)->it); _cachelist.push_back(checksum); ((*itMap).second)->it = --(_cachelist.end()); } /* zlib decompress it */ if (info->format & GL_TEXFMT_GZ) { uint32 destLen = _gzdestLen; uint8 *dest = (_gzdest0 == info->data) ? _gzdest1 : _gzdest0; if (uncompress(dest, &destLen, info->data, ((*itMap).second)->size) != Z_OK) { DBG_INFO(80, wst("Error: zlib decompression failed!\n")); return 0; } info->data = dest; info->format &= ~GL_TEXFMT_GZ; DBG_INFO(80, wst("zlib decompressed: %.02fkb->%.02fkb\n"), (float)(((*itMap).second)->size)/1000, (float)destLen/1000); } return 1; } return 0; } boolean TxCache::save(const wchar_t *path, const wchar_t *filename, int config) { if (_cache.empty()) return true; /* dump cache to disk */ char cbuf[MAX_PATH]; osal_mkdirp(path); /* Ugly hack to enable fopen/gzopen in Win9x */ #ifdef WIN32 wchar_t curpath[MAX_PATH]; GETCWD(MAX_PATH, curpath); CHDIR(path); #else char curpath[MAX_PATH]; GETCWD(MAX_PATH, curpath); wcstombs(cbuf, path, MAX_PATH); CHDIR(cbuf); #endif wcstombs(cbuf, filename, MAX_PATH); gzFile gzfp = gzopen(cbuf, "wb1"); DBG_INFO(80, wst("gzfp:%x file:%ls\n"), gzfp, filename); if (gzfp) { /* write header to determine config match */ gzwrite(gzfp, &config, 4); std::map::iterator itMap = _cache.begin(); int total = 0; while (itMap != _cache.end()) { uint8 *dest = (*itMap).second->info.data; uint32 destLen = (*itMap).second->size; uint32 format = (*itMap).second->info.format; /* to keep things simple, we save the texture data in a zlib uncompressed state. */ /* sigh... for those who cannot wait the extra few seconds. changed to keep * texture data in a zlib compressed state. if the GZ_TEXCACHE or GZ_HIRESTEXCACHE * option is toggled, the cache will need to be rebuilt. */ /*if (format & GL_TEXFMT_GZ) { dest = _gzdest0; destLen = _gzdestLen; if (dest && destLen) { if (uncompress(dest, &destLen, (*itMap).second->info.data, (*itMap).second->size) != Z_OK) { dest = NULL; destLen = 0; } format &= ~GL_TEXFMT_GZ; } }*/ if (dest && destLen) { /* texture checksum */ gzwrite(gzfp, &((*itMap).first), 8); /* other texture info */ gzwrite(gzfp, &((*itMap).second->info.width), 4); gzwrite(gzfp, &((*itMap).second->info.height), 4); gzwrite(gzfp, &format, 4); gzwrite(gzfp, &((*itMap).second->info.texture_format), 2); gzwrite(gzfp, &((*itMap).second->info.pixel_type), 2); gzwrite(gzfp, &((*itMap).second->info.is_hires_tex), 1); gzwrite(gzfp, &destLen, 4); gzwrite(gzfp, dest, destLen); } itMap++; if (_callback) (*_callback)(wst("Total textures saved to HDD: %d\n"), ++total); } gzclose(gzfp); } CHDIR(curpath); return _cache.empty(); } boolean TxCache::load(const wchar_t *path, const wchar_t *filename, int config) { /* find it on disk */ char cbuf[MAX_PATH]; #ifdef WIN32 wchar_t curpath[MAX_PATH]; GETCWD(MAX_PATH, curpath); CHDIR(path); #else char curpath[MAX_PATH]; GETCWD(MAX_PATH, curpath); wcstombs(cbuf, path, MAX_PATH); CHDIR(cbuf); #endif wcstombs(cbuf, filename, MAX_PATH); gzFile gzfp = gzopen(cbuf, "rb"); DBG_INFO(80, wst("gzfp:%x file:%ls\n"), gzfp, filename); if (gzfp) { /* yep, we have it. load it into memory cache. */ int dataSize; uint64 checksum; int tmpconfig; /* read header to determine config match */ gzread(gzfp, &tmpconfig, 4); if (tmpconfig == config) { do { GHQTexInfo tmpInfo; gzread(gzfp, &checksum, 8); gzread(gzfp, &tmpInfo.width, 4); gzread(gzfp, &tmpInfo.height, 4); gzread(gzfp, &tmpInfo.format, 4); gzread(gzfp, &tmpInfo.texture_format, 2); gzread(gzfp, &tmpInfo.pixel_type, 2); gzread(gzfp, &tmpInfo.is_hires_tex, 1); gzread(gzfp, &dataSize, 4); tmpInfo.data = (uint8*)malloc(dataSize); if (tmpInfo.data) { gzread(gzfp, tmpInfo.data, dataSize); /* add to memory cache */ add(checksum, &tmpInfo, (tmpInfo.format & GL_TEXFMT_GZ) ? dataSize : 0); free(tmpInfo.data); } else { gzseek(gzfp, dataSize, SEEK_CUR); } /* skip in between to prevent the loop from being tied down to vsync */ if (_callback && (!(_cache.size() % 100) || gzeof(gzfp))) (*_callback)(wst("[%d] total mem:%.02fmb - %ls\n"), _cache.size(), (float)_totalSize/1000000, filename); } while (!gzeof(gzfp)); gzclose(gzfp); } } CHDIR(curpath); return !_cache.empty(); } boolean TxCache::del(uint64 checksum) { if (!checksum || _cache.empty()) return 0; std::map::iterator itMap = _cache.find(checksum); if (itMap != _cache.end()) { /* for texture cache (not hi-res cache) */ if (!_cachelist.empty()) _cachelist.erase(((*itMap).second)->it); /* remove from cache */ free((*itMap).second->info.data); _totalSize -= (*itMap).second->size; delete (*itMap).second; _cache.erase(itMap); DBG_INFO(80, wst("removed from cache: checksum = %08X %08X\n"), (uint32)(checksum & 0xffffffff), (uint32)(checksum >> 32)); return 1; } return 0; } boolean TxCache::is_cached(uint64 checksum) { std::map::iterator itMap = _cache.find(checksum); if (itMap != _cache.end()) return 1; return 0; } void TxCache::clear() { if (!_cache.empty()) { std::map::iterator itMap = _cache.begin(); while (itMap != _cache.end()) { free((*itMap).second->info.data); delete (*itMap).second; itMap++; } _cache.clear(); } if (!_cachelist.empty()) _cachelist.clear(); _totalSize = 0; } glide2gl/src/Glitch64/glitch64_textures.c000664 001750 001750 00000033337 12655644434 021327 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "glide.h" #include "glitchmain.h" #include "uthash.h" /* Napalm extensions to GrTextureFormat_t */ #define GR_TEXFMT_ARGB_8888 0x12 #define GR_TEXFMT_YUYV_422 0x13 #define GR_TEXFMT_UYVY_422 0x14 #define GR_TEXFMT_AYUV_444 0x15 #define GR_TEXTFMT_RGB_888 0xFF int packed_pixels_support = -1; #ifndef GL_TEXTURE_MAX_ANISOTROPY_EXT #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE #endif int tex_width[2], tex_height[2]; int tex_exactWidth[2],tex_exactHeight[2]; int three_point_filter[2]; float lambda; static int min_filter[2] = { GL_NEAREST, GL_NEAREST }, mag_filter[2] = { GL_NEAREST, GL_NEAREST }, wrap_s[2] = { GL_REPEAT, GL_REPEAT }, wrap_t[2] = { GL_REPEAT, GL_REPEAT }; unsigned char *filter(unsigned char *source, int width, int height, int *width2, int *height2); typedef struct _texlist { unsigned int id; GLuint tex_id; UT_hash_handle hh; } texlist; static texlist *list = NULL; //#define LOG_TEXTUREMEM 1 static void remove_tex(unsigned int idmin, unsigned int idmax) { GLuint *t; unsigned int n = 0; texlist *current, *tmp; unsigned count = HASH_COUNT(list); if (!count) return; t = (GLuint*)malloc(count * sizeof(GLuint)); HASH_ITER(hh, list, current, tmp) { if (current->id >= idmin && current->id < idmax) { t[n++] = current->tex_id; HASH_DEL(list, current); free(current); } } glDeleteTextures(n, t); free(t); #ifdef LOG_TEXTUREMEM if (log_cb) log_cb(RETRO_LOG_DEBUG, "RMVTEX nbtex is now %d (%06x - %06x)\n", HASH_COUNT(list), idmin, idmax); #endif } static void add_tex(unsigned int id) { texlist *entry; HASH_FIND_INT(list, &id, entry); if (!entry) { entry = malloc(sizeof(texlist)); entry->id = id; glGenTextures(1, &entry->tex_id); HASH_ADD_INT(list, id, entry); } #ifdef LOG_TEXTUREMEM if (log_cb) log_cb(RETRO_LOG_DEBUG, "ADDTEX nbtex is now %d (%06x)\n", HASH_COUNT(list), id); #endif } static GLuint get_tex_id(unsigned int id) { texlist *entry; HASH_FIND_INT(list, &id, entry); if (!entry) { #ifdef LOG_TEXTUREMEM if (log_cb) log_cb(RETRO_LOG_ERROR, "get_tex_id for %08x failed!\n", id); #endif return 0; } return entry->tex_id; } void init_textures(void) { list = NULL; } void free_textures(void) { remove_tex(0x00000000, 0xFFFFFFFF); } uint32_t grTexCalcMemRequired(int32_t lodmax, int32_t aspect, int32_t fmt) { int width = 1 << lodmax; int height = 1 << lodmax; if (aspect < 0) width = height >> -aspect; else height = width >> aspect; switch(fmt) { case GR_TEXFMT_ALPHA_8: case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii case GR_TEXFMT_ALPHA_INTENSITY_44: return width*height; break; case GR_TEXFMT_ARGB_1555: case GR_TEXFMT_ARGB_4444: case GR_TEXFMT_ALPHA_INTENSITY_88: case GR_TEXFMT_RGB_565: return (width*height)<<1; break; case GR_TEXFMT_ARGB_8888: return (width*height)<<2; break; } return 0; } static int grTexFormat2GLPackedFmt(GrTexInfo *info, int fmt, int * gltexfmt, int * glpixfmt, int * glpackfmt) { unsigned size_tex; int factor; factor = -1; size_tex = width * height; if (fmt == GR_TEXFMT_ALPHA_INTENSITY_44) { uint16_t *texture_ptr = &((uint16_t*)info->data)[size_tex]; uint8_t *texture_ptr8 = &((uint8_t*)info->data)[size_tex]; //FIXME - still CPU software color conversion do{ uint16_t texel = (uint16_t)*texture_ptr8--; // Replicate glide's ALPHA_INTENSITY_44 to match gl's LUMINANCE_ALPHA texel = (texel & 0x00F0) << 4 | (texel & 0x000F); *texture_ptr-- = (texel << 4) | texel; }while(size_tex--); factor = 1; *gltexfmt = GL_LUMINANCE_ALPHA; *glpixfmt = GL_LUMINANCE_ALPHA; *glpackfmt = GL_UNSIGNED_BYTE; } #ifndef HAVE_OPENGLES2 else if (packed_pixels_support) { switch(fmt) { case GR_TEXFMT_ALPHA_8: factor = 1; *gltexfmt = GL_INTENSITY8; *glpixfmt = GL_LUMINANCE; *glpackfmt = GL_UNSIGNED_BYTE; break; case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii factor = 1; *gltexfmt = GL_LUMINANCE8; *glpixfmt = GL_LUMINANCE; *glpackfmt = GL_UNSIGNED_BYTE; break; case GR_TEXFMT_RGB_565: factor = 2; *gltexfmt = GL_RGB; *glpixfmt = GL_RGB; *glpackfmt = GL_UNSIGNED_SHORT_5_6_5; break; case GR_TEXFMT_ARGB_1555: factor = 2; *gltexfmt = GL_RGB5_A1; *glpixfmt = GL_BGRA; *glpackfmt = GL_UNSIGNED_SHORT_1_5_5_5_REV; break; case GR_TEXFMT_ALPHA_INTENSITY_88: factor = 2; *gltexfmt = GL_LUMINANCE8_ALPHA8; *glpixfmt = GL_LUMINANCE_ALPHA; *glpackfmt = GL_UNSIGNED_BYTE; break; case GR_TEXFMT_ARGB_4444: factor = 2; *gltexfmt = GL_RGBA4; *glpixfmt = GL_BGRA; *glpackfmt = GL_UNSIGNED_SHORT_4_4_4_4_REV; break; case GR_TEXFMT_ARGB_8888: factor = 4; *gltexfmt = GL_RGBA8; *glpixfmt = GL_BGRA; *glpackfmt = GL_UNSIGNED_INT_8_8_8_8_REV; break; } } #endif else { // VP fixed the texture conversions to be more accurate, also swapped // the for i/j loops so that is is less likely to break the memory cache unsigned size_tex = width * height; switch(info->format) { case GR_TEXFMT_ALPHA_8: do { uint16_t texel = (uint16_t)((uint8_t*)info->data)[size_tex]; // Replicate glide's ALPHA_8 to match gl's LUMINANCE_ALPHA // This is to make up for the lack of INTENSITY in gles ((uint16_t*)info->data)[size_tex] = texel | (texel << 8); }while(size_tex--); factor = 1; *glpixfmt = GL_LUMINANCE_ALPHA; *gltexfmt = GL_LUMINANCE_ALPHA; *glpackfmt = GL_UNSIGNED_BYTE; break; case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii do { unsigned int texel = (unsigned int)((uint8_t*)info->data)[size_tex]; texel |= (0xFF000000 | (texel << 16) | (texel << 8)); ((unsigned int*)info->data)[size_tex] = texel; }while(size_tex--); factor = 1; *glpixfmt = GL_RGBA; *gltexfmt = GL_RGBA; *glpackfmt = GL_UNSIGNED_BYTE; break; case GR_TEXFMT_RGB_565: do { unsigned int texel = (unsigned int)((uint16_t*)info->data)[size_tex]; unsigned int B = texel & 0x0000F800; unsigned int G = texel & 0x000007E0; unsigned int R = texel & 0x0000001F; ((unsigned int*)info->data)[size_tex] = 0xFF000000 | (R << 19) | (G << 5) | (B >> 8); }while(size_tex--); factor = 2; *glpixfmt = GL_RGBA; *gltexfmt = GL_RGBA; *glpackfmt = GL_UNSIGNED_BYTE; break; case GR_TEXFMT_ARGB_1555: do { uint16_t texel = ((uint16_t*)info->data)[size_tex]; // Shift-rotate glide's ARGB_1555 to match gl's RGB5_A1 ((uint16_t*)info->data)[size_tex] = (texel << 1) | (texel >> 15); }while(size_tex--); factor = 2; *glpixfmt = GL_RGBA; *gltexfmt = GL_RGBA; *glpackfmt = GL_UNSIGNED_SHORT_5_5_5_1; break; case GR_TEXFMT_ALPHA_INTENSITY_88: do { unsigned int AI = (unsigned int)((uint16_t*)info->data)[size_tex]; unsigned int I = (unsigned int)(AI & 0x000000FF); ((unsigned int*)info->data)[size_tex] = (AI << 16) | (I << 8) | I; }while(size_tex--); factor = 2; *glpixfmt = GL_RGBA; *gltexfmt = GL_RGBA; *glpackfmt = GL_UNSIGNED_BYTE; break; case GR_TEXFMT_ARGB_4444: do { unsigned int texel = (unsigned int)((uint16_t*)info->data)[size_tex]; unsigned int A = texel & 0x0000F000; unsigned int B = texel & 0x00000F00; unsigned int G = texel & 0x000000F0; unsigned int R = texel & 0x0000000F; ((unsigned int*)info->data)[size_tex] = (A << 16) | (R << 20) | (G << 8) | (B >> 4); }while(size_tex--); factor = 2; *glpixfmt = GL_RGBA; *gltexfmt = GL_RGBA; *glpackfmt = GL_UNSIGNED_BYTE; break; case GR_TEXFMT_ARGB_8888: #ifdef HAVE_OPENGLES2 if (bgra8888_support) { factor = 4; *gltexfmt = GL_BGRA_EXT; *glpixfmt = GL_BGRA_EXT; *glpackfmt = GL_UNSIGNED_BYTE; break; } #endif do { unsigned int texel = ((unsigned int*)info->data)[size_tex]; unsigned int A = texel & 0xFF000000; unsigned int B = texel & 0x00FF0000; unsigned int G = texel & 0x0000FF00; unsigned int R = texel & 0x000000FF; ((unsigned int*)info->data)[size_tex] = A | (R << 16) | G | (B >> 16); }while(size_tex--); factor = 4; *glpixfmt = GL_RGBA; *gltexfmt = GL_RGBA; *glpackfmt = GL_UNSIGNED_BYTE; break; default: factor = 0; } } return factor; } void grTexSource( int32_t tmu, uint32_t startAddress, uint32_t evenOdd, GrTexInfo *info, int do_download) { int width, height; int factor; int gltexfmt, glpixfmt, glpackfmt; unsigned index = (tmu == GR_TMU1) ? 0 : 1; glActiveTexture((tmu == GR_TMU1) ? GL_TEXTURE0 : GL_TEXTURE1); if (!do_download) goto grtexsource; height = 1 << info->largeLodLog2; width = 1 << info->largeLodLog2; if (info->aspectRatioLog2 < 0) width = height >> -info->aspectRatioLog2; else height = width >> info->aspectRatioLog2; factor = grTexFormat2GLPackedFmt(info, info->format, &gltexfmt, &glpixfmt, &glpackfmt); remove_tex(startAddress+1, startAddress+1+(width * height * factor)); add_tex(startAddress+1); glBindTexture(GL_TEXTURE_2D, get_tex_id(startAddress+1)); glTexImage2D(GL_TEXTURE_2D, 0, gltexfmt, width, height, 0, glpixfmt, glpackfmt, info->data); info->width = width; info->height = height; grtexsource: tex_height[index] = 256; tex_width[index] = 256; if (info->aspectRatioLog2 < 0) tex_width[index] = tex_height[index] >> -info->aspectRatioLog2; else tex_height[index] = tex_width[index] >> info->aspectRatioLog2; if (!do_download) glBindTexture(GL_TEXTURE_2D, get_tex_id(startAddress+1)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter[index]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter[index]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s[index]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t[index]); tex_exactWidth[index] = info->width; tex_exactHeight[index] = info->height; } void grTexDetailControl( int32_t tmu, int lod_bias, uint8_t detail_scale, float detail_max ) { if (lod_bias != 31 && detail_scale != 7) { if (!lod_bias && !detail_scale && !detail_max) return; } lambda = detail_max; if(lambda > 1.0f) lambda = 1.0f - (255.0f - lambda); set_lambda(); } void grTexFilterClampMode( int32_t tmu, int32_t s_clampmode, int32_t t_clampmode, int32_t minfilter_mode, int32_t magfilter_mode ) { unsigned active_texindex = GL_TEXTURE1; unsigned index = 1; if (tmu == GR_TMU1) { index = 0; active_texindex = GL_TEXTURE0; } glActiveTexture(active_texindex); wrap_s[index] = s_clampmode; wrap_t[index] = t_clampmode; min_filter[index] = (minfilter_mode == GR_TEXTUREFILTER_POINT_SAMPLED) ? GL_NEAREST : GL_LINEAR; mag_filter[index] = (magfilter_mode == GR_TEXTUREFILTER_POINT_SAMPLED) ? GL_NEAREST : GL_LINEAR; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s[index]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t[index]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter[index]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter[index]); #ifdef DISABLE_3POINT three_point_filter[index] =false; #else three_point_filter[index] = (magfilter_mode == GR_TEXTUREFILTER_3POINT_LINEAR); #endif need_to_compile = 1; } glide2gl/src/Glide64/3dmath.h000664 001750 001750 00000005426 12655644434 016735 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** void calc_light (VERTEX *v); void calc_linear (VERTEX *v); void calc_sphere (VERTEX *v); #define CopyMatrix(m0, m1, size) memcpy(m0, m1, size) void math_init(void); typedef void (*GLIDE64MULMATRIX)(float m1[4][4],float m2[4][4],float r[4][4]); extern GLIDE64MULMATRIX glide64MulMatrices; typedef void (*GLIDE64TRANSFORMVECTOR)(float *src,float *dst,float mat[4][4]); extern GLIDE64TRANSFORMVECTOR glide64InverseTransformVector; typedef float (*GLIDE64DOTPRODUCT)(register float *v1, register float *v2); extern GLIDE64DOTPRODUCT glide64DotProduct; typedef void (*GLIDE64NORMALIZEVECTOR)(float *v); extern GLIDE64NORMALIZEVECTOR glide64NormalizeVector; #ifndef MulMatrices #define MulMatrices glide64MulMatrices #endif #ifndef InverseTransformVector #define InverseTransformVector glide64InverseTransformVector #endif #ifndef DotProduct #define DotProduct glide64DotProduct #endif #ifndef NormalizeVector #define NormalizeVector glide64NormalizeVector #endif mupen64plus-video-gliden64/src/GLideNHQ/TxTexCache.cpp000664 001750 001750 00000004531 12655644434 023470 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef __MSC__ #pragma warning(disable: 4786) #endif /* dump cache to disk (0:disable, 1:enable) */ #define DUMP_CACHE 1 #include "TxTexCache.h" #include "TxDbg.h" #include #include TxTexCache::~TxTexCache() { #if DUMP_CACHE if (_options & DUMP_TEXCACHE) { /* dump cache to disk */ tx_wstring filename = _ident + wst("_MEMORYCACHE.") + TEXCACHE_EXT; tx_wstring cachepath(_path); cachepath += OSAL_DIR_SEPARATOR_STR; cachepath += wst("cache"); int config = _options & (FILTER_MASK | ENHANCEMENT_MASK | FORCE16BPP_TEX | GZ_TEXCACHE); TxCache::save(cachepath.c_str(), filename.c_str(), config); } #endif } TxTexCache::TxTexCache(int options, int cachesize, const wchar_t *path, const wchar_t *ident, dispInfoFuncExt callback ) : TxCache((options & ~GZ_HIRESTEXCACHE), cachesize, path, ident, callback) { /* assert local options */ if (_path.empty() || _ident.empty() || !_cacheSize) _options &= ~DUMP_TEXCACHE; #if DUMP_CACHE if (_options & DUMP_TEXCACHE) { /* find it on disk */ tx_wstring filename = _ident + wst("_MEMORYCACHE.") + TEXCACHE_EXT; tx_wstring cachepath(_path); cachepath += OSAL_DIR_SEPARATOR_STR; cachepath += wst("cache"); int config = _options & (FILTER_MASK | ENHANCEMENT_MASK | FORCE16BPP_TEX | GZ_TEXCACHE); TxCache::load(cachepath.c_str(), filename.c_str(), config); } #endif } boolean TxTexCache::add(uint64 checksum, GHQTexInfo *info) { if (_cacheSize <= 0) return 0; return TxCache::add(checksum, info); } mupen64plus-core/src/main/util.h000664 001750 001750 00000014476 12655644434 017724 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - util.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2012 CasualJames * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef __UTIL_H__ #define __UTIL_H__ #ifdef __cplusplus extern "C" { #endif #include #include "osal/preproc.h" /********************** Byte swap utilities **********************/ #ifdef _MSC_VER #include #endif #if defined(_MSC_VER) #define BUILTIN_BSWAP16 _byteswap_ushort #define BUILTIN_BSWAP32 _byteswap_ulong #define BUILTIN_BSWAP64 _byteswap_uint64 #endif static osal_inline unsigned short m64p_swap16(unsigned short x) { #ifdef BUILTIN_BSWAP16 return BUILTIN_BSWAP16(x); #else return ((x & 0x00FF) << 8) | ((x & 0xFF00) >> 8); #endif } static osal_inline unsigned int m64p_swap32(unsigned int x) { #ifdef BUILTIN_BSWAP32 return BUILTIN_BSWAP32(x); // long is always 32-bit in Windows #else return ((x & 0x000000FF) << 24) | ((x & 0x0000FF00) << 8) | ((x & 0x00FF0000) >> 8) | ((x & 0xFF000000) >> 24); #endif } static osal_inline unsigned long long int m64p_swap64(unsigned long long int x) { #ifdef BUILTIN_BSWAP64 return BUILTIN_BSWAP64(x); #else return ((x & 0x00000000000000FFULL) << 56) | ((x & 0x000000000000FF00ULL) << 40) | ((x & 0x0000000000FF0000ULL) << 24) | ((x & 0x00000000FF000000ULL) << 8) | ((x & 0x000000FF00000000ULL) >> 8) | ((x & 0x0000FF0000000000ULL) >> 24) | ((x & 0x00FF000000000000ULL) >> 40) | ((x & 0xFF00000000000000ULL) >> 56); #endif } #ifdef MSB_FIRST #define big16(x) (x) #define big32(x) (x) #define big64(x) (x) #define little16(x) m64p_swap16(x) #define little32(x) m64p_swap32(x) #define little64(x) m64p_swap64(x) #else #define big16(x) m64p_swap16(x) #define big32(x) m64p_swap32(x) #define big64(x) m64p_swap64(x) #define little16(x) (x) #define little32(x) (x) #define little64(x) (x) #endif /* Byte swaps, converts to little endian or converts to big endian a buffer, * containing 'count' elements, each of size 'length'. */ void swap_buffer(void *buffer, size_t length, size_t count); void to_little_endian_buffer(void *buffer, size_t length, size_t count); void to_big_endian_buffer(void *buffer, size_t length, size_t count); /********************** GUI utilities **********************/ void countrycodestring(char countrycode, char *string); void imagestring(unsigned char imagetype, char *string); /********************** Path utilities **********************/ /* Extracts the full file name (with extension) from a path string. * Returns the same string, advanced until the file name. */ const char* namefrompath(const char* path); /* Creates a path string by joining two path strings. * The given path strings may or may not start or end with a path separator. * Returns a malloc'd string with the resulting path. */ char* combinepath(const char* first, const char *second); /********************** String utilities **********************/ /** trim * Removes leading and trailing whitespace from str. Function modifies str * and also returns modified string. */ char *trim(char *str); /* Converts an string to an integer. * Returns 1 on success, 0 on failure. 'result' is undefined on failure. * * The following conditions cause this function to fail: * - Empty string * - Leading characters (including whitespace) * - Trailing characters (including whitespace) * - Overflow or underflow. */ int string_to_int(const char *str, int *result); /* Converts an string of hexadecimal characters to a byte array. * 'output_size' is the number of bytes (hex digraphs) to convert. * Returns 1 on success, 0 on failure. 'output' is undefined on failure. */ int parse_hex(const char *str, unsigned char *output, size_t output_size); /* Formats an string, using the same syntax as printf. * Returns the result in a malloc'd string. */ char* formatstr(const char* fmt, ...); typedef enum _ini_line_type { INI_BLANK, INI_COMMENT, INI_SECTION, INI_PROPERTY, INI_TRASH } ini_line_type; typedef struct _ini_line { ini_line_type type; char *name; char *value; } ini_line; /* Parses the INI file line pointer by 'lineptr'. * The first line pointed by 'lineptr' may be modifed. * 'lineptr' will point to the next line after this function runs. * * Returns a ini_line structure with information about the line. * For INI_COMMENT, the value field contains the comment. * For INI_SECTION, the name field contains the section name. * For INI_PROPERTY, the name and value fields contain the property parameters. * The line type is INI_BLANK if the line is blank or invalid. * * The name and value fields (if any) of ini_line point to 'lineptr' * (so their lifetime is associated to that of 'lineptr'). */ ini_line ini_parse_line(char **lineptr); #ifdef __cplusplus } #endif #endif // __UTIL_H__ mupen64plus-core/src/osal/preproc.h000664 001750 001750 00000005345 12655644434 020426 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-core - osal/preproc.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2009 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* this header file is for system-dependent #defines, #includes, and typedefs */ #if !defined (OSAL_PREPROC_H) #define OSAL_PREPROC_H #if defined(WIN32) && !defined(__MINGW32__) /* macros */ #ifdef _WIN64 /* Have not implemented interrupt in x64 on MSVC. */ #define OSAL_BREAKPOINT_INTERRUPT #else #define OSAL_BREAKPOINT_INTERRUPT __asm int 3 #endif #define ALIGN(BYTES,DATA) __declspec(align(BYTES)) DATA #define osal_inline __inline /* string functions */ #define osal_insensitive_strcmp(x, y) _stricmp(x, y) #define snprintf _snprintf #define strdup _strdup /* for isnan() */ #include #define isnan _isnan #define OSAL_DIR_SEPARATORS "\\/" #define PATH_MAX _MAX_PATH #else /* Not WIN32 */ // macros #define OSAL_BREAKPOINT_INTERRUPT __asm__(" int $3; "); #define ALIGN(BYTES,DATA) DATA __attribute__((aligned(BYTES))) #define osal_inline inline // string functions #define osal_insensitive_strcmp(x, y) strcasecmp(x, y) #include // for PATH_MAX #define OSAL_DIR_SEPARATORS "/" /* PATH_MAX only may be defined by limits.h */ #ifndef PATH_MAX #define PATH_MAX 4096 #endif #endif #endif /* OSAL_PREPROC_H */ mupen64plus-core/tools/profiling.txt000664 001750 001750 00000011144 12655644434 020742 0ustar00sergiosergio000000 000000 How to profile R4300 instructions with mupen64plus: Pre-requisites: - either 32-bit (x86) or 64-bit (amd64) Linux system - Lots of memory. It doesn't cause swapping in a machine with 2GB of ram, but it probably would with 1GB - OProfile (http://oprofile.sourceforge.net/) - Mupen64plus source code Procedure: 1. Install OProfile linux tool 2. Build r4300 profile tool with "gcc -o r4300prof r4300prof.c" 3. Build mupen64plus with "make DBGSYM=1 DBG_PROFILE=1" 4. Delete any pre-existing profiling files: "rm instructionaddrs.dat" 5. Clear any residual profiling data in oprofile: "sudo opcontrol --reset" 6. Make profiling run by typing in console: sudo opcontrol --start ; ./mupen64plus --nogui --emumode 2 --audio ./plugins/dummyaudio.so ; sudo opcontrol --stop 7. Exit emulator with Escape key after running for desired time 7. Move data file into tools folder: "mv instructionaddrs.dat tools/" 8. Dump instruction-level profiling data for mupen64plus with oprofile: opreport -d -l ./mupen64plus > ./tools/prof-mupen64-detail.txt 9. Run tool to generate r4300 instruction profile report: cd tools ; ./r4300prof instructionaddrs.dat prof-mupen64-detail.txt Example profile output: Loading instructionaddrs.dat... 283844 r4300 instruction locations read. 247911 non-empty MIPS instructions. Loading prof-mupen64-detail.txt... 118181 lines in sample data file. Found 117905 profile hits. Instruction time (samples): reserved: 00007515 NI: 00000000 J: 00000043 JAL: 00003345 BEQ: 00004498 BNE: 00003424 BLEZ: 00000222 BGTZ: 00000029 ADDI: 00000585 ADDIU: 00017439 SLTI: 00000765 SLTIU: 00000089 ANDI: 00003847 ORI: 00000381 XORI: 00000035 LUI: 00010389 BEQL: 00001873 BNEL: 00002617 BLEZL: 00000013 BGTZL: 00000010 DADDI: 00000000 DADDIU: 00000000 LDL: 00000000 LDR: 00000000 LB: 00002600 LH: 00006653 LW: 00024840 LWL: 00000001 LBU: 00003525 LHU: 00004954 LWU: 00000000 LWR: 00000003 SB: 00003007 SH: 00004133 SW: 00023221 SWL: 00000000 SWR: 00000000 SDL: 00000000 SDR: 00000000 LWC1: 00012405 LDC1: 00001855 LD: 00000815 LL: 00000000 SWC1: 00007671 SDC1: 00001326 SD: 00001233 SC: 00000000 BLTZ: 00000383 BGEZ: 00000331 BLTZL: 00000161 BGEZL: 00000168 BLTZAL: 00000000 BGEZAL: 00000115 BLTZALL: 00000000 BGEZALL: 00000000 SLL: 00003376 SRL: 00000604 SRA: 00000686 SLLV: 00000015 SRLV: 00000039 SRAV: 00000000 JR: 00001358 JALR: 00000004 SYSCALL: 00000000 MFHI: 00000058 MTHI: 00000002 MFLO: 00000277 MTLO: 00000004 DSLLV: 00000000 DSRLV: 00000000 DSRAV: 00000000 MULT: 00000000 MULTU: 00000583 DIV: 00000941 DIVU: 00000000 DMULT: 00000000 DMULTU: 00000000 DDIV: 00000000 DDIVU: 00000000 ADD: 00000170 ADDU: 00001706 SUB: 00000037 SUBU: 00000833 AND: 00000909 OR: 00006360 XOR: 00000079 NOR: 00000004 SLT: 00000925 SLTU: 00001401 DADD: 00000000 DADDU: 00000000 DSUB: 00000000 DSUBU: 00000000 DSLL: 00000000 DSRL: 00000000 DSRA: 00000000 TEQ: 00000000 DSLL32: 00000000 DSRL32: 00000000 DSRA32: 00000000 BC1F: 00000286 BC1T: 00000032 BC1FL: 00000775 BC1TL: 00000077 TLBWI: 00000000 TLBP: 00000000 TLBR: 00000000 TLBWR: 00000000 ERET: 00000036 MFC0: 00000396 MTC0: 00000034 MFC1: 00000929 DMFC1: 00000000 CFC1: 00000141 MTC1: 00003081 DMTC1: 00000000 CTC1: 00000163 f.CVT: 00001113 f.CMP: 00002149 f.ADD: 00001387 f.SUB: 00000947 f.MUL: 00002696 f.DIV: 00000315 f.SQRT: 00000025 f.ABS: 00000000 f.MOV: 00000631 f.NEG: 00000323 f.ROUND: 00000000 f.TRUNC: 00000867 f.CEIL: 00000000 f.FLOOR: 00000000 Special code samples: Regcache flushing: 12371 Jump wrappers: 15520 NOTCOMPILED: 33 block postfix & link samples: 619 Unaccounted samples: 19929 Total accounted instruction samples: 221836 Load: 35.2% (68040) Store: 21.0% (40591) Data move/convert: 03.5% (6829) 32-bit math: 16.0% (30861) 64-bit math: 05.7% (10948) Float Math: 04.5% (8709) Jump: 02.5% (4750) Branch: 07.8% (15014) Exceptions: 00.0% (36) Reserved: 03.9% (7515) Other: 00.0% (0) gles2rice/src/OGLDecodedMux.h000664 001750 001750 00000002056 12655644434 017124 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "DecodedMux.h" #ifndef _OGL_DECODEDMUX_H_ #define _OGL_DECODEDMUX_H_ class COGLDecodedMux : public DecodedMux { protected: virtual void Simplify(void); virtual void Reformat(void); }; class COGLExtDecodedMux : public COGLDecodedMux { protected: virtual void FurtherFormatForOGL2(void); virtual void Simplify(void); }; #endif mupen64plus-core/src/main/util.c000664 001750 001750 00000021744 12655644434 017713 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - util.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2012 CasualJames * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /** * Provides common utilities to the rest of the code: * -String functions */ #include #include #include #include #include #include #include #include #include #include "rom.h" #include "util.h" #include "osal/preproc.h" /********************** Byte swap utilities **********************/ void swap_buffer(void *buffer, size_t length, size_t count) { size_t i; if (length == 2) { uint16_t *pun = (uint16_t*)buffer; for (i = 0; i < count; i++) pun[i] = m64p_swap16(pun[i]); } else if (length == 4) { uint32_t *pun = (uint32_t*)buffer; for (i = 0; i < count; i++) pun[i] = m64p_swap32(pun[i]); } else if (length == 8) { uint64_t *pun = (uint64_t*)buffer; for (i = 0; i < count; i++) pun[i] = m64p_swap64(pun[i]); } } void to_little_endian_buffer(void *buffer, size_t length, size_t count) { #ifdef MSB_FIRST swap_buffer(buffer, length, count); #endif } void to_big_endian_buffer(void *buffer, size_t length, size_t count) { #ifndef MSB_FIRST swap_buffer(buffer, length, count); #endif } /********************** GUI utilities **********************/ void countrycodestring(char countrycode, char *string) { switch (countrycode) { case '\0': /* Demo */ strcpy(string, "Demo"); break; case '7': /* Beta */ strcpy(string, "Beta"); break; case 'A': /* Japan / USA */ strcpy(string, "USA/Japan"); break; case 'D': /* Germany */ strcpy(string, "Germany"); break; case 'E': /* USA */ strcpy(string, "USA"); break; case 'F': /* France */ strcpy(string, "France"); break; case 'I': /* Italy */ strcpy(string, "Italy"); break; case 'J': /* Japan */ strcpy(string, "Japan"); break; case 'S': /* Spain */ strcpy(string, "Spain"); break; case 'U': case 'Y': /* Australia */ sprintf(string, "Australia (%c)", countrycode); break; case 0x50: case 0x58: case 0x20: case 0x21: case 0x38: case 0x70: sprintf(string, "Europe (%c)", countrycode); break; default: sprintf(string, "Unknown (0x%02X)", countrycode); break; } } void imagestring(unsigned char imagetype, char *string) { switch (imagetype) { case Z64IMAGE: strcpy(string, ".z64 (native)"); break; case V64IMAGE: strcpy(string, ".v64 (byteswapped)"); break; case N64IMAGE: strcpy(string, ".n64 (wordswapped)"); break; default: string[0] = '\0'; } } /********************** Path utilities **********************/ /* Looks for an instance of ANY of the characters in 'needles' in 'haystack', * starting from the end of 'haystack'. Returns a pointer to the last position * of some character on 'needles' on 'haystack'. If not found, returns NULL. */ static const char* strpbrk_reverse(const char* needles, const char* haystack) { size_t stringlength = strlen(haystack), counter; for (counter = stringlength; counter > 0; --counter) { if (strchr(needles, haystack[counter-1])) break; } if (counter == 0) return NULL; return haystack + counter - 1; } const char* namefrompath(const char* path) { const char* last_separator_ptr = strpbrk_reverse(OSAL_DIR_SEPARATORS, path); if (last_separator_ptr != NULL) return last_separator_ptr + 1; return path; } static int is_path_separator(char c) { return strchr(OSAL_DIR_SEPARATORS, c) != NULL; } char* combinepath(const char* first, const char *second) { size_t len_first = strlen(first), off_second = 0; if (first == NULL || second == NULL) return NULL; while (is_path_separator(first[len_first-1])) len_first--; while (is_path_separator(second[off_second])) off_second++; return formatstr("%.*s%c%s", (int) len_first, first, OSAL_DIR_SEPARATORS[0], second + off_second); } /********************** String utilities **********************/ char *trim(char *str) { char *start = str, *end = str + strlen(str); while (start < end && isspace(*start)) start++; while (end > start && isspace(*(end-1))) end--; memmove(str, start, end - start); str[end - start] = '\0'; return str; } int string_to_int(const char *str, int *result) { char *endptr; long int n; if (*str == '\0' || isspace(*str)) return 0; errno = 0; n = strtol(str, &endptr, 10); if (*endptr != '\0' || errno != 0 || n < INT_MIN || n > INT_MAX) return 0; *result = (int)n; return 1; } static unsigned char char2hex(char c) { c = tolower(c); if(c >= '0' && c <= '9') return c - '0'; else if(c >= 'a' && c <= 'f') return c - 'a' + 10; return 0xFF; } int parse_hex(const char *str, unsigned char *output, size_t output_size) { size_t i, j; for (i = 0; i < output_size; i++) { output[i] = 0; for (j = 0; j < 2; j++) { unsigned char h = char2hex(*str++); if (h == 0xFF) return 0; output[i] = (output[i] << 4) | h; } } if (*str != '\0') return 0; return 1; } char *formatstr(const char *fmt, ...) { va_list args; int size = 128; char *str = (char *)malloc(size), *newstr; /* There are two implementations of vsnprintf we have to deal with: * C99 version: Returns the number of characters which would have been written * if the buffer had been large enough, and -1 on failure. * Windows version: Returns the number of characters actually written, * and -1 on failure or truncation. * NOTE: An implementation equivalent to the Windows one appears in glibc <2.1. */ while (str != NULL) { int ret; va_start(args, fmt); ret = vsnprintf(str, size, fmt, args); va_end(args); // Successful result? if (ret >= 0 && ret < size) return str; // Increment the capacity of the buffer if (ret >= size) size = ret + 1; // C99 version: We got the needed buffer size else size *= 2; // Windows version: Keep guessing newstr = (char *)realloc(str, size); if (newstr == NULL) free(str); str = newstr; } return NULL; } ini_line ini_parse_line(char **lineptr) { char *line = *lineptr, *endline = strchr(*lineptr, '\n'), *equal; ini_line l; // Null terminate the current line and point to the next line if (endline != NULL) *endline = '\0'; *lineptr = line + strlen(line) + 1; // Parse the line contents trim(line); if (line[0] == '#' || line[0] == ';') { line++; l.type = INI_COMMENT; l.name = NULL; l.value = trim(line); } else if (line[0] == '[' && line[strlen(line)-1] == ']') { line[strlen(line)-1] = '\0'; line++; l.type = INI_SECTION; l.name = trim(line); l.value = NULL; } else if ((equal = strchr(line, '=')) != NULL) { char *name = line, *value = equal + 1; *equal = '\0'; l.type = INI_PROPERTY; l.name = trim(name); l.value = trim(value); } else { l.type = (*line == '\0') ? INI_BLANK : INI_TRASH; l.name = NULL; l.value = NULL; } return l; } libretro/SDL.h000664 001750 001750 00000001021 12655644434 014326 0ustar00sergiosergio000000 000000 #ifndef _FAKE_SDL_H_ #define _FAKE_SDL_H_ #include #include #include "libretro.h" #include "libretro_perf.h" #ifdef __cplusplus extern "C" { #endif extern unsigned int FAKE_SDL_TICKS; extern retro_get_cpu_features_t perf_get_cpu_features_cb; extern retro_perf_get_counter_t perf_get_counter_cb; extern retro_log_printf_t log_cb; extern retro_perf_register_t perf_register_cb; #define SDL_GetTicks() FAKE_SDL_TICKS #ifdef __cplusplus } #endif #ifdef _MSC_VER #define strcasecmp stricmp #endif #endif gles2rice/src/UcodeDefs.h000664 001750 001750 00000015425 12655644434 016406 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _UCODE_DEFS_H_ #define _UCODE_DEFS_H_ typedef struct { union { uint32_t w0; struct { uint32_t arg0:24; uint32_t cmd:8; }; }; uint32_t w1; } Gwords; typedef struct { uint32_t w0; uint32_t v2:8; uint32_t v1:8; uint32_t v0:8; uint32_t flag:8; } GGBI0_Tri1; typedef struct { uint32_t v0:8; uint32_t v1:8; uint32_t v2:8; uint32_t cmd:8; uint32_t pad:24; uint32_t flag:8; } GGBI2_Tri1; typedef struct { uint32_t :1; uint32_t v3:7; uint32_t :1; uint32_t v4:7; uint32_t :1; uint32_t v5:7; uint32_t cmd:8; uint32_t :1; uint32_t v0:7; uint32_t :1; uint32_t v1:7; uint32_t :1; uint32_t v2:7; uint32_t flag:8; } GGBI2_Tri2; typedef struct { uint32_t w0; uint32_t v2:8; uint32_t v1:8; uint32_t v0:8; uint32_t v3:8; } GGBI0_Ln3DTri2; typedef struct { uint32_t v5:8; uint32_t v4:8; uint32_t v3:8; uint32_t cmd:8; uint32_t v2:8; uint32_t v1:8; uint32_t v0:8; uint32_t flag:8; } GGBI1_Tri2; typedef struct { uint32_t v3:8; uint32_t v4:8; uint32_t v5:8; uint32_t cmd:8; uint32_t v0:8; uint32_t v1:8; uint32_t v2:8; uint32_t flag:8; } GGBI2_Line3D; typedef struct { uint32_t len:16; uint32_t v0:4; uint32_t n:4; uint32_t cmd:8; uint32_t addr; } GGBI0_Vtx; typedef struct { uint32_t len:10; uint32_t n:6; uint32_t :1; uint32_t v0:7; uint32_t cmd:8; uint32_t addr; } GGBI1_Vtx; typedef struct { uint32_t vend:8; uint32_t :4; uint32_t n:8; uint32_t :4; uint32_t cmd:8; uint32_t addr; } GGBI2_Vtx; typedef struct { uint32_t width:12; uint32_t :7; uint32_t siz:2; uint32_t fmt:3; uint32_t cmd:8; uint32_t addr; } GSetImg; typedef struct { uint32_t prim_level:8; uint32_t prim_min_level:8; uint32_t pad:8; uint32_t cmd:8; union { uint32_t color; struct { uint32_t fillcolor:16; uint32_t fillcolor2:16; }; struct { uint32_t a:8; uint32_t b:8; uint32_t g:8; uint32_t r:8; }; }; } GSetColor; typedef struct { uint32_t :16; uint32_t param:8; uint32_t cmd:8; uint32_t addr; } GGBI0_Dlist; typedef struct { uint32_t len:16; uint32_t projection:1; uint32_t load:1; uint32_t push:1; uint32_t :5; uint32_t cmd:8; uint32_t addr; } GGBI0_Matrix; typedef struct { uint32_t :24; uint32_t cmd:8; uint32_t projection:1; uint32_t :31; } GGBI0_PopMatrix; typedef struct { union { struct { uint32_t param:8; uint32_t len:16; uint32_t cmd:8; }; struct { uint32_t nopush:1; uint32_t load:1; uint32_t projection:1; uint32_t :5; uint32_t len2:16; uint32_t cmd2:8; }; }; uint32_t addr; } GGBI2_Matrix; typedef struct { uint32_t type:8; uint32_t offset:16; uint32_t cmd:8; uint32_t value; } GGBI0_MoveWord; typedef struct { uint32_t offset:16; uint32_t type:8; uint32_t cmd:8; uint32_t value; } GGBI2_MoveWord; typedef struct { uint32_t enable_gbi0:1; uint32_t enable_gbi2:1; uint32_t :6; uint32_t tile:3; uint32_t level:3; uint32_t :10; uint32_t cmd:8; uint32_t scaleT:16; uint32_t scaleS:16; } GTexture; typedef struct { uint32_t tl:12; uint32_t sl:12; uint32_t cmd:8; uint32_t th:12; uint32_t sh:12; uint32_t tile:3; uint32_t pad:5; } Gloadtile; typedef struct { uint32_t tmem:9; uint32_t line:9; uint32_t pad0:1; uint32_t siz:2; uint32_t fmt:3; uint32_t cmd:8; uint32_t shifts:4; uint32_t masks:4; uint32_t ms:1; uint32_t cs:1; uint32_t shiftt:4; uint32_t maskt:4; uint32_t mt:1; uint32_t ct:1; uint32_t palette:4; uint32_t tile:3; uint32_t pad1:5; } Gsettile; typedef union { Gwords words; GGBI0_Tri1 tri1; GGBI0_Ln3DTri2 ln3dtri2; GGBI1_Tri2 gbi1tri2; GGBI2_Tri1 gbi2tri1; GGBI2_Tri2 gbi2tri2; GGBI2_Line3D gbi2line3d; GGBI0_Vtx gbi0vtx; GGBI1_Vtx gbi1vtx; GGBI2_Vtx gbi2vtx; GSetImg setimg; GSetColor setcolor; GGBI0_Dlist gbi0dlist; GGBI0_Matrix gbi0matrix; GGBI0_PopMatrix gbi0popmatrix; GGBI2_Matrix gbi2matrix; GGBI0_MoveWord gbi0moveword; GGBI2_MoveWord gbi2moveword; GTexture texture; Gloadtile loadtile; Gsettile settile; /* Gdma dma; Gsegment segment; GsetothermodeH setothermodeH; GsetothermodeL setothermodeL; Gtexture texture; Gperspnorm perspnorm; Gsetcombine setcombine; Gfillrect fillrect; Gsettile settile; Gloadtile loadtile; Gsettilesize settilesize; Gloadtlut loadtlut; */ int64_t force_structure_alignment; } Gfx; typedef union { struct { uint32_t w0; uint32_t w1; uint32_t w2; uint32_t w3; }; struct { uint32_t yl:12; /* Y coordinate of upper left */ uint32_t xl:12; /* X coordinate of upper left */ uint32_t cmd:8; /* command */ uint32_t yh:12; /* Y coordinate of lower right */ uint32_t xh:12; /* X coordinate of lower right */ uint32_t tile:3; /* Tile descriptor index */ uint32_t pad1:5; /* Padding */ uint32_t t:16; /* T texture coord at top left */ uint32_t s:16; /* S texture coord at top left */ uint32_t dtdy:16;/* Change in T per change in Y */ uint32_t dsdx:16;/* Change in S per change in X */ }; } Gtexrect; #endif mupen64plus-video-gliden64/src/Combiner.cpp000664 001750 001750 00000031544 12655644434 021677 0ustar00sergiosergio000000 000000 #include #include #include #include "OpenGL.h" #include "Combiner.h" #include "GLSLCombiner.h" #include "UniformCollection.h" #include "Debug.h" #include "gDP.h" #include "Config.h" #include "PluginAPI.h" #include "RSP.h" static int saRGBExpanded[] = { COMBINED, TEXEL0, TEXEL1, PRIMITIVE, SHADE, ENVIRONMENT, ONE, NOISE, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO }; static int sbRGBExpanded[] = { COMBINED, TEXEL0, TEXEL1, PRIMITIVE, SHADE, ENVIRONMENT, CENTER, K4, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO }; static int mRGBExpanded[] = { COMBINED, TEXEL0, TEXEL1, PRIMITIVE, SHADE, ENVIRONMENT, SCALE, COMBINED_ALPHA, TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA, SHADE_ALPHA, ENV_ALPHA, LOD_FRACTION, PRIM_LOD_FRAC, K5, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO }; static int aRGBExpanded[] = { COMBINED, TEXEL0, TEXEL1, PRIMITIVE, SHADE, ENVIRONMENT, ONE, ZERO }; static int saAExpanded[] = { COMBINED, TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA, SHADE_ALPHA, ENV_ALPHA, ONE, ZERO }; static int sbAExpanded[] = { COMBINED, TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA, SHADE_ALPHA, ENV_ALPHA, ONE, ZERO }; static int mAExpanded[] = { LOD_FRACTION, TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA, SHADE_ALPHA, ENV_ALPHA, PRIM_LOD_FRAC, ZERO, }; static int aAExpanded[] = { COMBINED, TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA, SHADE_ALPHA, ENV_ALPHA, ONE, ZERO }; void Combiner_Init() { CombinerInfo & cmbInfo = CombinerInfo::get(); cmbInfo.init(); InitShaderCombiner(); gDP.otherMode.cycleType = G_CYC_1CYCLE; if (cmbInfo.getCombinersNumber() == 0) { cmbInfo.setCombine(EncodeCombineMode(0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0)); cmbInfo.setCombine(EncodeCombineMode(0, 0, 0, TEXEL0, 0, 0, 0, 1, 0, 0, 0, TEXEL0, 0, 0, 0, 1)); } } void Combiner_Destroy() { DestroyShaderCombiner(); CombinerInfo::get().destroy(); } CombinerInfo & CombinerInfo::get() { static CombinerInfo info; return info; } void CombinerInfo::init() { m_pCurrent = NULL; m_pUniformCollection = createUniformCollection(); GLint numBinaryFormats = 0; #ifdef GL_NUM_PROGRAM_BINARY_FORMATS glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &numBinaryFormats); #endif m_bShaderCacheSupported = config.generalEmulation.enableShadersStorage != 0 && OGLVideo::isExtensionSupported(GET_PROGRAM_BINARY_EXTENSION) && numBinaryFormats > 0; m_shadersLoaded = 0; if (m_bShaderCacheSupported && !_loadShadersStorage()) { for (Combiners::iterator cur = m_combiners.begin(); cur != m_combiners.end(); ++cur) delete cur->second; m_combiners.clear(); } } void CombinerInfo::destroy() { delete m_pUniformCollection; m_pUniformCollection = NULL; m_pCurrent = NULL; if (m_bShaderCacheSupported) _saveShadersStorage(); m_shadersLoaded = 0; for (Combiners::iterator cur = m_combiners.begin(); cur != m_combiners.end(); ++cur) delete cur->second; m_combiners.clear(); } static void SimplifyCycle( CombineCycle *cc, CombinerStage *stage ) { // Load the first operand stage->op[0].op = LOAD; stage->op[0].param1 = cc->sa; stage->numOps = 1; // If we're just subtracting zero, skip it if (cc->sb != ZERO) { // Subtracting a number from itself is zero if (cc->sb == stage->op[0].param1) stage->op[0].param1 = ZERO; else { stage->op[1].op = SUB; stage->op[1].param1 = cc->sb; stage->numOps++; } } // If we either subtracted, or didn't load a zero if ((stage->numOps > 1) || (stage->op[0].param1 != ZERO)) { // Multiplying by zero is zero if (cc->m == ZERO) { stage->numOps = 1; stage->op[0].op = LOAD; stage->op[0].param1 = ZERO; } else { // Multiplying by one, so just do a load if ((stage->numOps == 1) && (stage->op[0].param1 == ONE)) stage->op[0].param1 = cc->m; else { stage->op[stage->numOps].op = MUL; stage->op[stage->numOps].param1 = cc->m; stage->numOps++; } } } // Don't bother adding zero if (cc->a != ZERO) { // If all we have so far is zero, then load this instead if ((stage->numOps == 1) && (stage->op[0].param1 == ZERO)) stage->op[0].param1 = cc->a; else { stage->op[stage->numOps].op = ADD; stage->op[stage->numOps].param1 = cc->a; stage->numOps++; } } // Handle interpolation if ((stage->numOps == 4) && (stage->op[1].param1 == stage->op[3].param1)) { stage->numOps = 1; stage->op[0].op = INTER; stage->op[0].param2 = stage->op[1].param1; stage->op[0].param3 = stage->op[2].param1; } } ShaderCombiner * CombinerInfo::_compile(u64 mux) const { gDPCombine combine; combine.mux = mux; int numCycles; Combiner color, alpha; numCycles = gDP.otherMode.cycleType + 1; color.numStages = numCycles; alpha.numStages = numCycles; CombineCycle cc[2]; CombineCycle ac[2]; // Decode and expand the combine mode into a more general form cc[1].sa = saRGBExpanded[combine.saRGB1]; cc[1].sb = sbRGBExpanded[combine.sbRGB1]; cc[1].m = mRGBExpanded[combine.mRGB1]; cc[1].a = aRGBExpanded[combine.aRGB1]; ac[1].sa = saAExpanded[combine.saA1]; ac[1].sb = sbAExpanded[combine.sbA1]; ac[1].m = mAExpanded[combine.mA1]; ac[1].a = aAExpanded[combine.aA1]; // Simplify each RDP combiner cycle into a combiner stage if (gDP.otherMode.cycleType == G_CYC_1CYCLE) { SimplifyCycle(&cc[1], &color.stage[0]); SimplifyCycle(&ac[1], &alpha.stage[0]); } else { cc[0].sa = saRGBExpanded[combine.saRGB0]; cc[0].sb = sbRGBExpanded[combine.sbRGB0]; cc[0].m = mRGBExpanded[combine.mRGB0]; cc[0].a = aRGBExpanded[combine.aRGB0]; ac[0].sa = saAExpanded[combine.saA0]; ac[0].sb = sbAExpanded[combine.sbA0]; ac[0].m = mAExpanded[combine.mA0]; ac[0].a = aAExpanded[combine.aA0]; SimplifyCycle(&cc[0], &color.stage[0]); SimplifyCycle(&ac[0], &alpha.stage[0]); SimplifyCycle(&cc[1], &color.stage[1]); SimplifyCycle(&ac[1], &alpha.stage[1]); } return new ShaderCombiner( color, alpha, combine ); } void CombinerInfo::update() { // TODO: find, why gDP.changed & CHANGED_COMBINE not always works (e.g. Mario Tennis). // if (gDP.changed & CHANGED_COMBINE) { if (gDP.otherMode.cycleType == G_CYC_COPY) setCombine(EncodeCombineMode(0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0)); else if (gDP.otherMode.cycleType == G_CYC_FILL) setCombine(EncodeCombineMode(0, 0, 0, SHADE, 0, 0, 0, SHADE, 0, 0, 0, SHADE, 0, 0, 0, SHADE)); else setCombine(gDP.combine.mux); gDP.changed &= ~CHANGED_COMBINE; // } } void CombinerInfo::setCombine(u64 _mux ) { if (m_pCurrent != NULL && m_pCurrent->getMux() == _mux) { m_bChanged = false; m_pCurrent->update(false); return; } Combiners::const_iterator iter = m_combiners.find(_mux); if (iter != m_combiners.end()) { m_pCurrent = iter->second; m_pCurrent->update(false); } else { m_pCurrent = _compile(_mux); m_pCurrent->update(true); m_pUniformCollection->bindWithShaderCombiner(m_pCurrent); m_combiners[_mux] = m_pCurrent; } m_bChanged = true; } void CombinerInfo::updatePrimColor() { if (m_pUniformCollection != NULL) m_pUniformCollection->setColorData(UniformCollection::cuPrimColor, sizeof(f32)* 5, &gDP.primColor.r); } void CombinerInfo::updateEnvColor() { if (m_pUniformCollection != NULL) m_pUniformCollection->setColorData(UniformCollection::cuEnvColor, sizeof(f32)* 4, &gDP.envColor.r); } void CombinerInfo::updateFogColor() { if (m_pUniformCollection != NULL) m_pUniformCollection->setColorData(UniformCollection::cuFogColor, sizeof(f32)* 4, &gDP.fogColor.r); } void CombinerInfo::updateBlendColor() { if (m_pUniformCollection != NULL) m_pUniformCollection->setColorData(UniformCollection::cuBlendColor, sizeof(f32)* 4, &gDP.blendColor.r); } void CombinerInfo::updateKeyColor() { if (m_pUniformCollection != NULL) m_pUniformCollection->setColorData(UniformCollection::cuCenterColor, sizeof(f32)* 8, &gDP.key.center.r); } void CombinerInfo::updateConvertColor() { if (m_pUniformCollection == NULL) return; f32 convert[2] = { gDP.convert.k4*0.0039215689f, gDP.convert.k5*0.0039215689f }; m_pUniformCollection->setColorData(UniformCollection::cuK4, sizeof(convert), convert); } void CombinerInfo::updateTextureParameters() { if (m_pUniformCollection != NULL) m_pUniformCollection->updateTextureParameters(); } void CombinerInfo::updateLightParameters() { if (m_pUniformCollection != NULL) m_pUniformCollection->updateLightParameters(); gSP.changed &= ~CHANGED_LIGHT; } void CombinerInfo::updateParameters(OGLRender::RENDER_STATE _renderState) { if (m_pUniformCollection != NULL) m_pUniformCollection->updateUniforms(m_pCurrent, _renderState); } #ifndef GLES2 #define SHADER_STORAGE_FOLDER_NAME L"shaders" static void getStorageFileName(wchar_t * _fileName) { wchar_t strCacheFolderPath[PLUGIN_PATH_SIZE]; api().GetUserCachePath(strCacheFolderPath); wchar_t strShaderFolderPath[PLUGIN_PATH_SIZE]; swprintf(strShaderFolderPath, PLUGIN_PATH_SIZE, L"%ls/%ls", strCacheFolderPath, SHADER_STORAGE_FOLDER_NAME); wchar_t * pPath = strShaderFolderPath; if (!osal_path_existsW(strShaderFolderPath) || !osal_is_directory(strShaderFolderPath)) { if (osal_mkdirp(strShaderFolderPath) != 0) pPath = strCacheFolderPath; } swprintf(_fileName, PLUGIN_PATH_SIZE, L"%ls/GLideN64.%08lx.shaders", pPath, std::hash()(__RSP.romname)); } u32 CombinerInfo::_getConfigOptionsBitSet() const { std::vector vecOptions; ShaderCombiner::getShaderCombinerOptionsSet(vecOptions); u32 optionsSet = 0; for (u32 i = 0; i < vecOptions.size(); ++i) optionsSet |= vecOptions[i] << i; return optionsSet; } /* Storage format: uint32 - format version; uint32 - bitset of config options, which may change how shader is created. uint32 - len of renderer string char * - renderer string uint32 - len of GL version string char * - GL version string uint32 - number of shaders shaders in binary form */ static const u32 ShaderStorageFormatVersion = 0x03U; // Shaders changed after rev. c6d37ca void CombinerInfo::_saveShadersStorage() const { if (m_shadersLoaded >= m_combiners.size()) return; wchar_t fileName[PLUGIN_PATH_SIZE]; getStorageFileName(fileName); #ifdef OS_WINDOWS std::ofstream fout(fileName, std::ofstream::binary | std::ofstream::trunc); #else char fileName_c[PATH_MAX]; wcstombs(fileName_c, fileName, PATH_MAX); std::ofstream fout(fileName_c, std::ofstream::binary | std::ofstream::trunc); #endif if (!fout) return; fout.write((char*)&ShaderStorageFormatVersion, sizeof(ShaderStorageFormatVersion)); const u32 optionsSet = _getConfigOptionsBitSet(); fout.write((char*)&optionsSet, sizeof(optionsSet)); const char * strRenderer = reinterpret_cast(glGetString(GL_RENDERER)); u32 len = strlen(strRenderer); fout.write((char*)&len, sizeof(len)); fout.write(strRenderer, len); const char * strGLVersion = reinterpret_cast(glGetString(GL_VERSION)); len = strlen(strGLVersion); fout.write((char*)&len, sizeof(len)); fout.write(strGLVersion, len); len = m_combiners.size(); fout.write((char*)&len, sizeof(len)); for (Combiners::const_iterator cur = m_combiners.begin(); cur != m_combiners.end(); ++cur) fout << *(cur->second); fout.flush(); fout.close(); } bool CombinerInfo::_loadShadersStorage() { wchar_t fileName[PLUGIN_PATH_SIZE]; getStorageFileName(fileName); #ifdef OS_WINDOWS std::ifstream fin(fileName, std::ofstream::binary); #else char fileName_c[PATH_MAX]; wcstombs(fileName_c, fileName, PATH_MAX); std::ifstream fin(fileName_c, std::ofstream::binary); #endif if (!fin) return false; try { u32 version; fin.read((char*)&version, sizeof(version)); if (version != ShaderStorageFormatVersion) return false; u32 optionsSet; fin.read((char*)&optionsSet, sizeof(optionsSet)); if (optionsSet != _getConfigOptionsBitSet()) return false; const char * strRenderer = reinterpret_cast(glGetString(GL_RENDERER)); u32 len; fin.read((char*)&len, sizeof(len)); std::vector strBuf(len); fin.read(strBuf.data(), len); if (strncmp(strRenderer, strBuf.data(), len) != 0) return false; const char * strGLVersion = reinterpret_cast(glGetString(GL_VERSION)); fin.read((char*)&len, sizeof(len)); strBuf.resize(len); fin.read(strBuf.data(), len); if (strncmp(strGLVersion, strBuf.data(), len) != 0) return false; fin.read((char*)&len, sizeof(len)); for (u32 i = 0; i < len; ++i) { m_pCurrent = new ShaderCombiner(); fin >> *m_pCurrent; m_pCurrent->update(true); m_pUniformCollection->bindWithShaderCombiner(m_pCurrent); m_combiners[m_pCurrent->getMux()] = m_pCurrent; } } catch (...) { m_shadersLoaded = 0; return false; } m_shadersLoaded = m_combiners.size(); fin.close(); return !isGLError(); } #else // GLES2 void CombinerInfo::_saveShadersStorage() const {} bool CombinerInfo::_loadShadersStorage() { return true; } #endif //GLES2 mupen64plus-rsp-hle/src/ucodes.h000664 001750 001750 00000010434 12655644434 017715 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-rsp-hle - ucodes.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef UCODES_H #define UCODES_H #include struct hle_t; /* cic_x105 ucode */ void cicx105_ucode(struct hle_t* hle); /* audio list ucodes - audio */ enum { N_SEGMENTS = 16 }; struct alist_audio_t { /* segments */ uint32_t segments[N_SEGMENTS]; /* main buffers */ uint16_t in; uint16_t out; uint16_t count; /* auxiliary buffers */ uint16_t dry_right; uint16_t wet_left; uint16_t wet_right; /* gains */ int16_t dry; int16_t wet; /* envelopes (0:left, 1:right) */ int16_t vol[2]; int16_t target[2]; int32_t rate[2]; /* ADPCM loop point address */ uint32_t loop; /* storage for ADPCM table and polef coefficients */ int16_t table[16 * 8]; }; void alist_process_audio (struct hle_t* hle); void alist_process_audio_ge(struct hle_t* hle); void alist_process_audio_bc(struct hle_t* hle); /* audio list ucodes - naudio */ struct alist_naudio_t { /* gains */ int16_t dry; int16_t wet; /* envelopes (0:left, 1:right) */ int16_t vol[2]; int16_t target[2]; int32_t rate[2]; /* ADPCM loop point address */ uint32_t loop; /* storage for ADPCM table and polef coefficients */ int16_t table[16 * 8]; }; void alist_process_naudio (struct hle_t* hle); void alist_process_naudio_bk (struct hle_t* hle); void alist_process_naudio_dk (struct hle_t* hle); void alist_process_naudio_mp3 (struct hle_t* hle); void alist_process_naudio_cbfd(struct hle_t* hle); /* audio list ucodes - nead */ struct alist_nead_t { /* main buffers */ uint16_t in; uint16_t out; uint16_t count; /* envmixer ramps */ uint16_t env_values[3]; uint16_t env_steps[3]; /* ADPCM loop point address */ uint32_t loop; /* storage for ADPCM table and polef coefficients */ int16_t table[16 * 8]; /* filter audio command state */ uint16_t filter_count; uint32_t filter_lut_address[2]; }; void alist_process_nead_mk (struct hle_t* hle); void alist_process_nead_sfj (struct hle_t* hle); void alist_process_nead_sf (struct hle_t* hle); void alist_process_nead_fz (struct hle_t* hle); void alist_process_nead_wrjb(struct hle_t* hle); void alist_process_nead_ys (struct hle_t* hle); void alist_process_nead_1080(struct hle_t* hle); void alist_process_nead_oot (struct hle_t* hle); void alist_process_nead_mm (struct hle_t* hle); void alist_process_nead_mmb (struct hle_t* hle); void alist_process_nead_ac (struct hle_t* hle); /* mp3 ucode */ void mp3_task(struct hle_t* hle, unsigned int index, uint32_t address); /* musyx ucodes */ void musyx_v1_task(struct hle_t* hle); void musyx_v2_task(struct hle_t* hle); /* jpeg ucodes */ void jpeg_decode_PS0(struct hle_t* hle); void jpeg_decode_PS(struct hle_t* hle); void jpeg_decode_OB(struct hle_t* hle); #endif mupen64plus-core/src/dd/000700 001750 001750 00000000000 12656647145 016214 5ustar00sergiosergio000000 000000 libretro-common/glsym/README.md000664 001750 001750 00000000414 12655644434 017440 0ustar00sergiosergio000000 000000 # Autogenerate GL extension loaders ## OpenGL desktop Use Khronos' recent [header](www.opengl.org/registry/api/glext.h). ./glgen.py /usr/include/GL/glext.h glsym_gl.h glsym_gl.c ## OpenGL ES ./glgen.py /usr/include/GLES2/gl2ext.h glsym_es2.h glsym_es2.c mupen64plus-rsp-hle/000700 001750 001750 00000000000 12656647145 015460 5ustar00sergiosergio000000 000000 gles2rice/src/Combiner.cpp000664 001750 001750 00000026546 12655644434 016644 0ustar00sergiosergio000000 000000 /* Copyright (C) 2002 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "Combiner.h" #include "Config.h" #include "RenderBase.h" #ifdef DEBUGGER const char *constStrs[] = { "MUX_0", "MUX_1", "MUX_COMBINED", "MUX_TEXEL0", "MUX_TEXEL1", "MUX_PRIM", "MUX_SHADE", "MUX_ENV", "MUX_COMBALPHA", "MUX_T0_ALPHA", "MUX_T1_ALPHA", "MUX_PRIM_ALPHA", "MUX_SHADE_ALPHA", "MUX_ENV_ALPHA", "MUX_LODFRAC", "MUX_PRIMLODFRAC", "MUX_K5", "MUX_UNK", }; const char *cycleTypeStrs[] = { "1 Cycle", "2 Cycle", "Copy Mode", "Fill Mode" }; const char* constStr(uint32_t op) { if (op <= MUX_UNK) return constStrs[op]; else return "Invalid-Const"; } #endif void swap(uint8_t &a, uint8_t &b) { uint8_t c=a; a=b; b=c; } //======================================================================== //======================================================================== inline IColor GetIColor(uint8_t flag, uint32_t curCol) { IColor newc; switch(flag & MUX_MASK) { case MUX_0: newc = 0; break; case MUX_1: newc = 0xFFFFFFFF; break; case MUX_PRIM: newc = gRDP.primitiveColor; break; case MUX_ENV: newc = gRDP.envColor; break; case MUX_COMBINED: case MUX_SHADE: newc = curCol; break; case MUX_K5: newc = 0xFFFFFFFF; break; case MUX_UNK: newc = curCol; if (options.enableHackForGames == HACK_FOR_CONKER) newc = 0xFFFFFFFF; break; default: newc = curCol; break; } if (flag&MUX_COMPLEMENT) { newc.Complement(); } if (flag&MUX_ALPHAREPLICATE) { newc.AlphaReplicate(); } return newc; } COLOR CalculateConstFactor(uint32_t colorOp, uint32_t alphaOp, uint32_t curCol) { N64CombinerType m; IColor color(curCol); IColor alpha(curCol); // For color channel *(uint32_t*)&m = colorOp; if (m.c != MUX_0 && m.a != m.b) { if (m.a != MUX_0) color = GetIColor(m.a, curCol); if (m.b != MUX_0) color -= GetIColor(m.b, curCol); if (m.c != MUX_1) color *= GetIColor(m.c, curCol); } if (m.d != MUX_0) color += GetIColor(m.d, curCol); // For alpha channel *(uint32_t*)&m = alphaOp; if (m.c != MUX_0 && m.a != m.b) { if (m.a != MUX_0) alpha = GetIColor(m.a, curCol); if (m.b != MUX_0) alpha -= GetIColor(m.b, curCol); if (m.c != MUX_1) alpha *= GetIColor(m.c, curCol); } if (m.d != MUX_0) alpha += GetIColor(m.d, curCol); return (COLOR)(((uint32_t)color&0x00FFFFFF)|((uint32_t)alpha&0xFF000000)); } COLOR CColorCombiner::GetConstFactor(uint32_t colorFlag, uint32_t alphaFlag, uint32_t defaultColor) { // Allows a combine mode to select what TFACTOR should be uint32_t color = defaultColor; uint32_t alpha = defaultColor; switch (colorFlag & MUX_MASK) { case MUX_0: break; case MUX_FORCE_0: color = 0; break; case MUX_1: color = 0xFFFFFFFF; break; case MUX_PRIM: color = gRDP.primitiveColor; break; case MUX_ENV: color = gRDP.envColor; break; case MUX_LODFRAC: color = COLOR_RGBA(gRDP.LODFrac, gRDP.LODFrac, gRDP.LODFrac, gRDP.LODFrac); break; case MUX_PRIMLODFRAC: color = COLOR_RGBA(gRDP.primLODFrac, gRDP.primLODFrac, gRDP.primLODFrac, gRDP.primLODFrac); break; case MUX_PRIM_ALPHA: { IColor col(gRDP.primitiveColor); col.AlphaReplicate(); color = (COLOR)col; } break; case MUX_ENV_ALPHA: { IColor col(gRDP.envColor); col.AlphaReplicate(); color = (COLOR)col; } break; case MUX_K5: color = 0xFFFFFFFF; break; case MUX_UNK: color = defaultColor; if(options.enableHackForGames == HACK_FOR_CONKER) { color = 0xFFFFFFFF; } break; default: color = defaultColor; break; } if (colorFlag & MUX_COMPLEMENT) { color = 0xFFFFFFFF - color; } if (colorFlag & MUX_ALPHAREPLICATE) { color = color>>24; color = color | (color<<8) | (color <<16) | (color<<24); } color &= 0x00FFFFFF; // For color channel only, not the alpha channel switch (alphaFlag & MUX_MASK) { case MUX_0: break; case MUX_FORCE_0: alpha = 0; break; case MUX_1: alpha = 0xFFFFFFFF; break; case MUX_PRIM: alpha = gRDP.primitiveColor; break; case MUX_ENV: alpha = gRDP.envColor; break; case MUX_LODFRAC: alpha = COLOR_RGBA(gRDP.LODFrac, gRDP.LODFrac, gRDP.LODFrac, gRDP.LODFrac); break; case MUX_PRIMLODFRAC: alpha = COLOR_RGBA(gRDP.primLODFrac, gRDP.primLODFrac, gRDP.primLODFrac, gRDP.primLODFrac); break; case MUX_PRIM_ALPHA: { IColor col(gRDP.primitiveColor); col.AlphaReplicate(); alpha = (COLOR)col; } break; case MUX_ENV_ALPHA: { IColor col(gRDP.envColor); col.AlphaReplicate(); alpha = (COLOR)col; } break; default: alpha = defaultColor; break; } if (alphaFlag & MUX_COMPLEMENT) { alpha = 0xFFFFFFFF - alpha; } alpha &= 0xFF000000; return (color|alpha); } //***************************************************************************** // //***************************************************************************** bool gUsingPrimColour = false; bool gUsingEnvColour = false; int CountTexel1Cycle(N64CombinerType &m) { int hasTexel[2]; uint8_t *p = (uint8_t*)&m; for (int i=0; i<2; i++) { hasTexel[i]=0; for (int j=0; j<4; j++) { if ((p[j]&MUX_MASK) == MUX_TEXEL0+i) { hasTexel[i]=1; break; } } } return hasTexel[0]+hasTexel[1]; } uint32_t GetTexelNumber(N64CombinerType &m) { if ((m.a&MUX_MASK) == MUX_TEXEL1 || (m.b&MUX_MASK) == MUX_TEXEL1 || (m.c&MUX_MASK) == MUX_TEXEL1 || (m.d&MUX_MASK) == MUX_TEXEL1) return TEX_1; else return TEX_0; } bool IsTextureUsed(N64CombinerType &m) { if((m.a&MUX_MASK) == MUX_TEXEL1 || (m.b&MUX_MASK) == MUX_TEXEL1 || (m.c&MUX_MASK) == MUX_TEXEL1 || (m.d&MUX_MASK) == MUX_TEXEL1) return true; if((m.a&MUX_MASK) == MUX_TEXEL0 || (m.b&MUX_MASK) == MUX_TEXEL0 || (m.c&MUX_MASK) == MUX_TEXEL0 || (m.d&MUX_MASK) == MUX_TEXEL0) return true; else return false; } //======================================================================== void CColorCombiner::InitCombinerMode(void) { #ifdef DEBUGGER LOG_UCODE(cycleTypeStrs[gRDP.otherMode.cycle_type]); if (debuggerDropDecodedMux) { UpdateCombiner(m_pDecodedMux->m_dwMux0, m_pDecodedMux->m_dwMux1); } #endif if (currentRomOptions.bNormalCombiner) { DisableCombiner(); } else if (gRDP.otherMode.cycle_type == CYCLE_TYPE_COPY) { InitCombinerCycleCopy(); m_bCycleChanged = true; } else if (gRDP.otherMode.cycle_type == CYCLE_TYPE_FILL) { InitCombinerCycleFill(); m_bCycleChanged = true; } else { InitCombinerCycle12(); m_bCycleChanged = false; } } bool bConkerHideShadow=false; void CColorCombiner::UpdateCombiner(uint32_t dwMux0, uint32_t dwMux1) { #ifdef DEBUGGER if (debuggerDropDecodedMux) { debuggerDropDecodedMux = false; m_pDecodedMux->m_dwMux0 = m_pDecodedMux->m_dwMux1 = 0; m_DecodedMuxList.clear(); } #endif DecodedMux &m_decodedMux = *m_pDecodedMux; if (m_decodedMux.m_dwMux0 != dwMux0 || m_decodedMux.m_dwMux1 != dwMux1) { if (options.enableHackForGames == HACK_FOR_DR_MARIO) { // Hack for Dr. Mario if (dwMux1 == 0xfffcf239 && ((m_decodedMux.m_dwMux0 == dwMux0 && dwMux0 == 0x00ffffff && m_decodedMux.m_dwMux1 != dwMux1 && m_decodedMux.m_dwMux1 == 0xfffcf279) || (m_decodedMux.m_dwMux0 == 0x00ffb3ff && m_decodedMux.m_dwMux1 == 0xff64fe7f && dwMux0 == 0x00ffffff ))) { //dwMux1 = 0xffcf23A; dwMux1 = 0xfffcf438; } } uint64_t mux64 = (((uint64_t)dwMux1)<<32)+dwMux0; int index=m_DecodedMuxList.find(mux64); if (options.enableHackForGames == HACK_FOR_CONKER) { // Conker's shadow, to disable the shadow //Mux=0x00ffe9ff Used in CONKER BFD //Color0: (0 - 0) * 0 + SHADE //Color1: (0 - 0) * 0 + SHADE //Alpha0: (1 - TEXEL0) * SHADE + 0 //Alpha1: (1 - TEXEL0) * SHADE + 0 if (dwMux1 == 0xffd21f0f && dwMux0 == 0x00ffe9ff) { bConkerHideShadow = true; } else { bConkerHideShadow = false; } } if (index >= 0) { m_decodedMux = m_DecodedMuxList[index]; } else { m_decodedMux.Decode(dwMux0, dwMux1); m_decodedMux.splitType[0] = CM_FMT_TYPE_NOT_CHECKED; m_decodedMux.splitType[1] = CM_FMT_TYPE_NOT_CHECKED; m_decodedMux.splitType[2] = CM_FMT_TYPE_NOT_CHECKED; m_decodedMux.splitType[3] = CM_FMT_TYPE_NOT_CHECKED; m_decodedMux.Hack(); m_decodedMux.Simplify(); if (m_supportedStages > 1) m_decodedMux.SplitComplexStages(); m_DecodedMuxList.add(m_decodedMux.m_u64Mux, *m_pDecodedMux); #ifdef DEBUGGER if (logCombiners) { TRACE0("Add a new mux"); DisplayMuxString(); } #endif } m_bTex0Enabled = m_decodedMux.m_bTexel0IsUsed; m_bTex1Enabled = m_decodedMux.m_bTexel1IsUsed; m_bTexelsEnable = m_bTex0Enabled||m_bTex1Enabled; gRSP.bProcessDiffuseColor = (m_decodedMux.m_dwShadeColorChannelFlag != MUX_0 || m_decodedMux.m_dwShadeAlphaChannelFlag != MUX_0); gRSP.bProcessSpecularColor = false; } } #ifdef DEBUGGER void CColorCombiner::DisplayMuxString(void) { if (gRDP.otherMode.cycle_type == CYCLE_TYPE_COPY) { TRACE0("COPY Mode\n"); } else if (gRDP.otherMode.cycle_type == CYCLE_TYPE_FILL) { TRACE0("FILL Mode\n"); } m_pDecodedMux->DisplayMuxString("Used"); } void CColorCombiner::DisplaySimpleMuxString(void) { m_pDecodedMux->DisplaySimpliedMuxString("Used"); } #endif mupen64plus-core/src/memory/memory.h000664 001750 001750 00000010372 12655644434 020632 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - memory.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_MEMORY_MEMORY_H #define M64P_MEMORY_MEMORY_H #include #ifndef MASKED_WRITE #define MASKED_WRITE(dst, value, mask) ((*(dst) & ~(mask)) | ((value) & (mask))) #endif #ifdef __LIBRETRO__ #include "libretro_memory.h" #endif #define AI_STATUS_FIFO_FULL 0x80000000 /* Bit 31: full */ #define AI_STATUS_DMA_BUSY 0x40000000 /* Bit 30: busy */ extern uint32_t VI_REFRESH; #define read_word_in_memory() readmem[address>>16]() #define read_byte_in_memory() readmemb[address>>16]() #define read_hword_in_memory() readmemh[address>>16]() #define read_dword_in_memory() readmemd[address>>16]() #define write_word_in_memory() writemem[address>>16]() #define write_byte_in_memory() writememb[address >>16]() #define write_hword_in_memory() writememh[address >>16]() #define write_dword_in_memory() writememd[address >>16]() extern uint32_t address, word; extern uint8_t cpu_byte; extern uint16_t hword; extern uint64_t dword, *rdword; extern void (*readmem[0x10000])(void); extern void (*readmemb[0x10000])(void); extern void (*readmemh[0x10000])(void); extern void (*readmemd[0x10000])(void); extern void (*writemem[0x10000])(void); extern void (*writememb[0x10000])(void); extern void (*writememh[0x10000])(void); extern void (*writememd[0x10000])(void); #ifdef MSB_FIRST #define sl(mot) mot #define S8 0 #define S16 0 #define Sh16 0 #else #define sl(mot) \ ( \ ((mot & 0x000000FF) << 24) | \ ((mot & 0x0000FF00) << 8) | \ ((mot & 0x00FF0000) >> 8) | \ ((mot & 0xFF000000) >> 24) \ ) #define S8 3 #define S16 2 #define Sh16 1 #endif int init_memory(void); void map_region(uint16_t region, int type, void (*read8)(void), void (*read16)(void), void (*read32)(void), void (*read64)(void), void (*write8)(void), void (*write16)(void), void (*write32)(void), void (*write64)(void)); /* XXX: cannot make them static because of dynarec + rdp fb */ void read_rdram(void); void read_rdramb(void); void read_rdramh(void); void read_rdramd(void); void write_rdram(void); void write_rdramb(void); void write_rdramh(void); void write_rdramd(void); void read_rdramFB(void); void read_rdramFBb(void); void read_rdramFBh(void); void read_rdramFBd(void); void write_rdramFB(void); void write_rdramFBb(void); void write_rdramFBh(void); void write_rdramFBd(void); /* Returns a pointer to a block of contiguous memory * Can access RDRAM, SP_DMEM, SP_IMEM and ROM, using TLB if necessary * Useful for getting fast access to a zone with executable code. */ uint32_t *fast_mem_access(uint32_t address); #ifdef DBG void activate_memory_break_read(uint32_t address); void deactivate_memory_break_read(uint32_t address); void activate_memory_break_write(uint32_t address); void deactivate_memory_break_write(uint32_t address); int get_memory_type(uint32_t address); #endif #endif mupen64plus-video-gliden64/src/mupenplus/CommonAPIImpl_mupenplus.cpp000664 001750 001750 00000003250 12655644434 026676 0ustar00sergiosergio000000 000000 #include "GLideN64_mupenplus.h" #include #include "../PluginAPI.h" #include "../OpenGL.h" #include "../RSP.h" int PluginAPI::InitiateGFX(const GFX_INFO & _gfxInfo) { _initiateGFX(_gfxInfo); return TRUE; } static void _cutLastPathSeparator(wchar_t * _strPath) { #ifdef ANDROID const u32 bufSize = 512; char cbuf[bufSize]; wcstombs(cbuf, _strPath, bufSize); std::string pluginPath(cbuf); std::string::size_type pos = pluginPath.find_last_of("/"); mbstowcs(_strPath, pluginPath.c_str(), PLUGIN_PATH_SIZE); #else std::wstring pluginPath(_strPath); std::replace(pluginPath.begin(), pluginPath.end(), L'\\', L'/'); std::wstring::size_type pos = pluginPath.find_last_of(L"/"); wcscpy(_strPath, pluginPath.substr(0, pos).c_str()); #endif } static void _getWSPath(const char * _path, wchar_t * _strPath) { ::mbstowcs(_strPath, _path, PLUGIN_PATH_SIZE); _cutLastPathSeparator(_strPath); } void PluginAPI::GetUserDataPath(wchar_t * _strPath) { _getWSPath(ConfigGetUserDataPath(), _strPath); } void PluginAPI::GetUserCachePath(wchar_t * _strPath) { _getWSPath(ConfigGetUserCachePath(), _strPath); } void PluginAPI::FindPluginPath(wchar_t * _strPath) { if (_strPath == NULL) return; #ifdef OS_WINDOWS GetModuleFileNameW(NULL, _strPath, PLUGIN_PATH_SIZE); _cutLastPathSeparator(_strPath); #elif defined(OS_LINUX) char path[512]; int res = readlink("/proc/self/exe", path, 510); if (res != -1) { path[res] = 0; _getWSPath(path, _strPath); } #elif defined(OS_MAC_OS_X) char path[MAXPATHLEN]; uint32_t pathLen = MAXPATHLEN * 2; if (_NSGetExecutablePath(path, pathLen) == 0) { _getWSPath(path, _strPath); } #elif defined(ANDROID) GetUserCachePath(_strPath); #endif } mupen64plus-video-gliden64/src/GLES2/UniformSet.h000664 001750 001750 00000004015 12655644434 022506 0ustar00sergiosergio000000 000000 #ifndef UNIFORM_SET_H #define UNIFORM_SET_H #include "../UniformCollection.h" class UniformSet : public UniformCollection { public: UniformSet() {} ~UniformSet() {} virtual void bindWithShaderCombiner(ShaderCombiner * _pCombiner); virtual void setColorData(ColorUniforms _index, u32 _dataSize, const void * _data) {} virtual void updateTextureParameters() {} virtual void updateLightParameters() {} virtual void updateUniforms(ShaderCombiner * _pCombiner, OGLRender::RENDER_STATE _renderState); private: struct fv3Uniform { GLint loc; float val[3]; void set(float * _pVal, bool _force) { const size_t szData = sizeof(float)* 3; if (loc >= 0 && (_force || memcmp(val, _pVal, szData) != 0)) { memcpy(val, _pVal, szData); glUniform3fv(loc, 1, _pVal); } } }; struct fv4Uniform { GLint loc; float val[4]; void set(float * _pVal, bool _force) { const size_t szData = sizeof(float)* 4; if (loc >= 0 && (_force || memcmp(val, _pVal, szData) != 0)) { memcpy(val, _pVal, szData); glUniform4fv(loc, 1, _pVal); } } }; struct UniformSetLocation { UniformSetLocation(GLuint _program) : m_program(_program) {} GLuint m_program; // Texture parameters ShaderCombiner::fv2Uniform uTexScale, uTexOffset[2], uCacheScale[2], uCacheOffset[2], uCacheShiftScale[2], uTextureSize[2]; ShaderCombiner::iv2Uniform uCacheFrameBuffer; // Colors fv4Uniform uFogColor, uCenterColor, uScaleColor, uBlendColor, uEnvColor, uPrimColor; ShaderCombiner::fUniform uPrimLod, uK4, uK5; // Lights fv3Uniform uLightDirection[8], uLightColor[8]; }; void _updateColorUniforms(UniformSetLocation & _location, bool _bForce); void _updateTextureUniforms(UniformSetLocation & _location, bool _bUsesT0, bool _bUsesT1, bool _bForce); void _updateTextureSize(UniformSetLocation & _location, bool _bUsesT0, bool _bUsesT1, bool _bForce); void _updateLightUniforms(UniformSetLocation & _location, bool _bForce); typedef std::map Uniforms; Uniforms m_uniforms; }; #endif // UNIFORM_SET_H mupen64plus-core/src/debugger/000700 001750 001750 00000000000 12656647145 017411 5ustar00sergiosergio000000 000000 mupen64plus-core/doc/emuwiki-api-doc/Mupen64Plus_v2.0_headers.txt000664 001750 001750 00000022524 12655644434 025710 0ustar00sergiosergio000000 000000 [http://mupen64plus.retrouprising.com Project page] == m64p_types.h == /* ----------------------------------------- */ /* Platform-specific stuff */ /* ----------------------------------------- */ /* necessary headers */ #if defined(WIN32) #include #endif /* DLL handles and function declaration specifiers */ #if defined(WIN32) #define IMPORT extern "C" __declspec(dllimport) #define EXPORT __declspec(dllexport) #define CALL __cdecl typedef HMODULE m64p_dynlib_handle; #else #define IMPORT extern "C" #define EXPORT __attribute__((visibility("default"))) #define CALL typedef void * m64p_dynlib_handle; #endif /* ----------------------------------------- */ /* Structures and Types for Core library API */ /* ----------------------------------------- */ typedef void * m64p_handle; typedef void (*m64p_frame_callback)(unsigned int FrameIndex); typedef void (*m64p_input_callback)(void); typedef void (*m64p_audio_callback)(void); typedef void (*m64p_vi_callback)(void); typedef enum { M64TYPE_INT = 1, M64TYPE_FLOAT, M64TYPE_BOOL, M64TYPE_STRING } m64p_type; typedef enum { M64MSG_ERROR = 1, M64MSG_WARNING, M64MSG_INFO, M64MSG_STATUS, M64MSG_VERBOSE } m64p_msg_level; typedef enum { M64ERR_SUCCESS = 0, M64ERR_NOT_INIT, /* Function is disallowed before InitMupen64Plus() is called */ M64ERR_ALREADY_INIT, /* InitMupen64Plus() was called twice */ M64ERR_INCOMPATIBLE, /* API versions between components are incompatible */ M64ERR_INPUT_ASSERT, /* Invalid parameters for function call, such as ParamValue=NULL for GetCoreParameter() */ M64ERR_INPUT_INVALID, /* Invalid input data, such as ParamValue="maybe" for SetCoreParameter() to set a BOOL-type value */ M64ERR_INPUT_NOT_FOUND, /* The input parameter(s) specified a particular item which was not found */ M64ERR_NO_MEMORY, /* Memory allocation failed */ M64ERR_FILES, /* Error opening, creating, reading, or writing to a file */ M64ERR_INTERNAL, /* Internal error (bug) */ M64ERR_INVALID_STATE, /* Current program state does not allow operation */ M64ERR_PLUGIN_FAIL, /* A plugin function returned a fatal error */ M64ERR_SYSTEM_FAIL, /* A system function call, such as an SDL or file operation, failed */ M64ERR_UNSUPPORTED, /* Function call is not supported (ie, core not built with debugger) */ M64ERR_WRONG_TYPE /* A given input type parameter cannot be used for desired operation */ } m64p_error; typedef enum { M64CAPS_DYNAREC = 1, M64CAPS_DEBUGGER = 2, M64CAPS_CORE_COMPARE = 4 } m64p_core_caps; typedef enum { M64PLUGIN_NULL = 0, M64PLUGIN_RSP = 1, M64PLUGIN_GFX, M64PLUGIN_AUDIO, M64PLUGIN_INPUT, M64PLUGIN_CORE } m64p_plugin_type; typedef enum { M64EMU_STOPPED = 1, M64EMU_RUNNING, M64EMU_PAUSED } m64p_emu_state; typedef enum { M64VIDEO_NONE = 1, M64VIDEO_WINDOWED, M64VIDEO_FULLSCREEN } m64p_video_mode; typedef enum { M64VIDEOFLAG_SUPPORT_RESIZING = 1 } m64p_video_flags; typedef enum { M64CORE_EMU_STATE = 1, M64CORE_VIDEO_MODE, M64CORE_SAVESTATE_SLOT, M64CORE_SPEED_FACTOR, M64CORE_SPEED_LIMITER, M64CORE_VIDEO_SIZE, M64CORE_AUDIO_VOLUME, M64CORE_AUDIO_MUTE, M64CORE_INPUT_GAMESHARK, M64CORE_STATE_LOADCOMPLETE, M64CORE_STATE_SAVECOMPLETE } m64p_core_param; typedef enum { M64CMD_NOP = 0, M64CMD_ROM_OPEN, M64CMD_ROM_CLOSE, M64CMD_ROM_GET_HEADER, M64CMD_ROM_GET_SETTINGS, M64CMD_EXECUTE, M64CMD_STOP, M64CMD_PAUSE, M64CMD_RESUME, M64CMD_CORE_STATE_QUERY, M64CMD_STATE_LOAD, M64CMD_STATE_SAVE, M64CMD_STATE_SET_SLOT, M64CMD_SEND_SDL_KEYDOWN, M64CMD_SEND_SDL_KEYUP, M64CMD_SET_FRAME_CALLBACK, M64CMD_TAKE_NEXT_SCREENSHOT, M64CMD_CORE_STATE_SET, M64CMD_READ_SCREEN, M64CMD_RESET, M64CMD_ADVANCE_FRAME } m64p_command; typedef struct { unsigned int address; int value; } m64p_cheat_code; /* ----------------------------------------- */ /* Structures to hold ROM image information */ /* ----------------------------------------- */ typedef enum { SYSTEM_NTSC = 0, SYSTEM_PAL, SYSTEM_MPAL } m64p_system_type; typedef struct { unsigned char init_PI_BSB_DOM1_LAT_REG; /* 0x00 */ unsigned char init_PI_BSB_DOM1_PGS_REG; /* 0x01 */ unsigned char init_PI_BSB_DOM1_PWD_REG; /* 0x02 */ unsigned char init_PI_BSB_DOM1_PGS_REG2; /* 0x03 */ unsigned int ClockRate; /* 0x04 */ unsigned int PC; /* 0x08 */ unsigned int Release; /* 0x0C */ unsigned int CRC1; /* 0x10 */ unsigned int CRC2; /* 0x14 */ unsigned int Unknown[2]; /* 0x18 */ unsigned char Name[20]; /* 0x20 */ unsigned int unknown; /* 0x34 */ unsigned int Manufacturer_ID; /* 0x38 */ unsigned short Cartridge_ID; /* 0x3C - Game serial number */ unsigned short Country_code; /* 0x3E */ } m64p_rom_header; typedef struct { char goodname[256]; char MD5[33]; unsigned char savetype; unsigned char status; /* Rom status on a scale from 0-5. */ unsigned char players; /* Local players 0-4, 2/3/4 way Netplay indicated by 5/6/7. */ unsigned char rumble; /* 0 - No, 1 - Yes boolean for rumble support. */ } m64p_rom_settings; /* ----------------------------------------- */ /* Structures and Types for the Debugger */ /* ----------------------------------------- */ typedef enum { M64P_DBG_RUN_STATE = 1, M64P_DBG_PREVIOUS_PC, M64P_DBG_NUM_BREAKPOINTS, M64P_DBG_CPU_DYNACORE, M64P_DBG_CPU_NEXT_INTERRUPT } m64p_dbg_state; typedef enum { M64P_DBG_MEM_TYPE = 1, M64P_DBG_MEM_FLAGS, M64P_DBG_MEM_HAS_RECOMPILED, M64P_DBG_MEM_NUM_RECOMPILED, M64P_DBG_RECOMP_OPCODE = 16, M64P_DBG_RECOMP_ARGS, M64P_DBG_RECOMP_ADDR } m64p_dbg_mem_info; typedef enum { M64P_MEM_NOMEM = 0, M64P_MEM_NOTHING, M64P_MEM_RDRAM, M64P_MEM_RDRAMREG, M64P_MEM_RSPMEM, M64P_MEM_RSPREG, M64P_MEM_RSP, M64P_MEM_DP, M64P_MEM_DPS, M64P_MEM_VI, M64P_MEM_AI, M64P_MEM_PI, M64P_MEM_RI, M64P_MEM_SI, M64P_MEM_FLASHRAMSTAT, M64P_MEM_ROM, M64P_MEM_PIF, M64P_MEM_MI, M64P_MEM_BREAKPOINT } m64p_dbg_mem_type; typedef enum { M64P_MEM_FLAG_READABLE = 0x01, M64P_MEM_FLAG_WRITABLE = 0x02, M64P_MEM_FLAG_READABLE_EMUONLY = 0x04, // the EMUONLY flags signify that emulated code can read/write here, but debugger cannot M64P_MEM_FLAG_WRITABLE_EMUONLY = 0x08 } m64p_dbg_mem_flags; typedef enum { M64P_DBG_PTR_RDRAM = 1, M64P_DBG_PTR_PI_REG, M64P_DBG_PTR_SI_REG, M64P_DBG_PTR_VI_REG, M64P_DBG_PTR_RI_REG, M64P_DBG_PTR_AI_REG } m64p_dbg_memptr_type; typedef enum { M64P_CPU_PC = 1, M64P_CPU_REG_REG, M64P_CPU_REG_HI, M64P_CPU_REG_LO, M64P_CPU_REG_COP0, M64P_CPU_REG_COP1_DOUBLE_PTR, M64P_CPU_REG_COP1_SIMPLE_PTR, M64P_CPU_REG_COP1_FGR_64, M64P_CPU_TLB } m64p_dbg_cpu_data; typedef enum { M64P_BKP_CMD_ADD_ADDR = 1, M64P_BKP_CMD_ADD_STRUCT, M64P_BKP_CMD_REPLACE, M64P_BKP_CMD_REMOVE_ADDR, M64P_BKP_CMD_REMOVE_IDX, M64P_BKP_CMD_ENABLE, M64P_BKP_CMD_DISABLE, M64P_BKP_CMD_CHECK } m64p_dbg_bkp_command; #define M64P_MEM_INVALID 0xFFFFFFFF // invalid memory read will return this #define BREAKPOINTS_MAX_NUMBER 128 #define BPT_FLAG_ENABLED 0x01 #define BPT_FLAG_CONDITIONAL 0x02 #define BPT_FLAG_COUNTER 0x04 #define BPT_FLAG_READ 0x08 #define BPT_FLAG_WRITE 0x10 #define BPT_FLAG_EXEC 0x20 #define BPT_FLAG_LOG 0x40 //Log to the console when this breakpoint hits. #define BPT_CHECK_FLAG(a, b) ((a.flags & b) == b) #define BPT_SET_FLAG(a, b) a.flags = (a.flags | b); #define BPT_CLEAR_FLAG(a, b) a.flags = (a.flags & (~b)); #define BPT_TOGGLE_FLAG(a, b) a.flags = (a.flags ^ b); typedef struct _breakpoint { unsigned int address; unsigned int endaddr; unsigned int flags; //unsigned int condition; //Placeholder for breakpoint condition } breakpoint; /* ------------------------------------------------- */ /* Structures and Types for Core Video Extension API */ /* ------------------------------------------------- */ typedef struct { unsigned int uiWidth; unsigned int uiHeight; } m64p_2d_size; typedef enum { M64P_GL_DOUBLEBUFFER = 1, M64P_GL_BUFFER_SIZE, M64P_GL_DEPTH_SIZE, M64P_GL_RED_SIZE, M64P_GL_GREEN_SIZE, M64P_GL_BLUE_SIZE, M64P_GL_ALPHA_SIZE, M64P_GL_SWAP_CONTROL, M64P_GL_MULTISAMPLEBUFFERS, M64P_GL_MULTISAMPLESAMPLES } m64p_GLattr; typedef struct { unsigned int Functions; m64p_error (*VidExtFuncInit)(void); m64p_error (*VidExtFuncQuit)(void); m64p_error (*VidExtFuncListModes)(m64p_2d_size *, int *); m64p_error (*VidExtFuncSetMode)(int, int, int, int, int); void * (*VidExtFuncGLGetProc)(const char*); m64p_error (*VidExtFuncGLSetAttr)(m64p_GLattr, int); m64p_error (*VidExtFuncGLGetAttr)(m64p_GLattr, int *); m64p_error (*VidExtFuncGLSwapBuf)(void); m64p_error (*VidExtFuncSetCaption)(const char *); m64p_error (*VidExtFuncToggleFS)(void); m64p_error (*VidExtFuncResizeWindow)(int, int); } m64p_video_extension_functions; libretro/libretro_perf.h000664 001750 001750 00000001211 12655644434 016543 0ustar00sergiosergio000000 000000 #ifndef _LIBRETRO_PERF_H #define _LIBRETRO_PERF_H #include "libretro.h" #ifdef __cplusplus extern "C" { #endif extern struct retro_perf_callback perf_cb; #if 1 #define RETRO_PERFORMANCE_INIT(perf_cb, name) static struct retro_perf_counter name = {#name}; if (!name.registered) perf_cb.perf_register(&(name)) #define RETRO_PERFORMANCE_START(perf_cb, name) perf_cb.perf_start(&(name)) #define RETRO_PERFORMANCE_STOP(perf_cb, name) perf_cb.perf_stop(&(name)) #else #define RETRO_PERFORMANCE_INIT(perf_cb, name) #define RETRO_PERFORMANCE_START(perf_cb, name) #define RETRO_PERFORMANCE_STOP(perf_cb, name) #endif #ifdef __cplusplus } #endif #endif glide2gl/src/Glitch64/glitchmain.h000664 001750 001750 00000007331 12655644434 020057 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef MAIN_H #define MAIN_H #include #include #include #include "boolean.h" extern retro_log_printf_t log_cb; //#define DEBUGLOG //#define TEXTUREMANAGEMENT_LOG //#define LOG_TO_STDERR #define LOG_TO_STDOUT #if defined(LOG_TO_STDERR) #define LOG_TYPE stderr #elif defined(LOG_TO_STDOUT) #define LOG_TYPE stdout #else #define LOG_TYPE stderr #endif //#define DEBUGLOG #ifdef DEBUGLOG #define LOG(...) WriteLog(M64MSG_VERBOSE, __VA_ARGS__) #define LOGINFO(...) WriteLog(M64MSG_INFO, __VA_ARGS__) #else #define LOG(...) #define LOGINFO(...) #endif #ifdef TEXTUREMANAGEMENT_LOG #define TEXLOG(...) fprintf(LOG_TYPE, __VA_ARGS__) #else #define TEXLOG(...) #endif void WriteLog(m64p_msg_level level, const char *msg, ...); #define zscale 1.0f extern int packed_pixels_support; void set_depth_shader(void); #include #define GL_GLEXT_PROTOTYPES #include void init_textures(void); void free_textures(void); void init_geometry(void); void free_geometry(void); void set_lambda(void); void init_combiner(void); void updateCombiner(int i); void updateCombinera(int i); void check_compile(GLuint shader); void check_link(GLuint program); void free_combiners(void); void compile_shader(void); void set_copy_shader(void); //Vertex Attribute Locations #define POSITION_ATTR 0 #define COLOUR_ATTR 1 #define TEXCOORD_0_ATTR 2 #define TEXCOORD_1_ATTR 3 #define FOG_ATTR 4 extern int width, height; extern int tex_width[2], tex_height[2]; extern int tex_exactWidth[2], tex_exactHeight[2]; extern float texture_env_color[4]; extern int fog_enabled; extern float lambda; extern int need_lambda[2]; extern float lambda_color[2][4]; extern int culling_mode; extern int need_to_compile; extern int three_point_filter[2]; extern int bgra8888_support; extern int glsl_support; extern GLuint program_object_default; extern GLuint glitch_vbo; #ifndef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS // TODO: Not present #define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 18283 #endif #define CHECK_FRAMEBUFFER_STATUS() \ {\ GLenum status; \ status = glCheckFramebufferStatus(GL_FRAMEBUFFER); \ /*DISPLAY_WARNING("%x\n", status);*/\ switch(status) { \ case GL_FRAMEBUFFER_COMPLETE: \ /*DISPLAY_WARNING("framebuffer complete!\n");*/\ break; \ case GL_FRAMEBUFFER_UNSUPPORTED: \ DISPLAY_WARNING("framebuffer GL_FRAMEBUFFER_UNSUPPORTED_EXT\n");\ /* you gotta choose different formats */ \ /*assert(0);*/ \ break; \ case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: \ DISPLAY_WARNING("framebuffer INCOMPLETE_ATTACHMENT\n");\ break; \ case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: \ DISPLAY_WARNING("framebuffer FRAMEBUFFER_MISSING_ATTACHMENT\n");\ break; \ case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: \ DISPLAY_WARNING("framebuffer FRAMEBUFFER_DIMENSIONS\n");\ break; \ default: \ break; \ /* programming error; will fail on all hardware */ \ /*assert(0);*/ \ }\ } #endif gles2n64/src/Hash.c000664 001750 001750 00000001363 12655644434 015104 0ustar00sergiosergio000000 000000 #include "Types.h" uint32_t Hash_CalculatePalette(void *buffer, uint32_t count) { unsigned int i; uint16_t *data = (uint16_t *) buffer; uint32_t hash = 0xffffffff; count /= 4; for(i = 0; i < count; ++i) { hash += data[i << 2]; hash += (hash << 10); hash ^= (hash >> 6); } hash += (hash << 3); hash ^= (hash >> 11); hash += (hash << 15); return hash; } uint32_t Hash_Calculate(uint32_t hash, void *buffer, uint32_t count) { unsigned int i; uint32_t *data = (uint32_t *) buffer; count /= 4; for(i = 0; i < count; ++i) { hash += data[i]; hash += (hash << 10); hash ^= (hash >> 6); } hash += (hash << 3); hash ^= (hash >> 11); hash += (hash << 15); return hash; } glide2gl/src/Glide64/glide64_util.c000664 001750 001750 00000121236 12655644434 020041 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** #include #include "Gfx_1.3.h" #include "Util.h" #include "Combine.h" #include "3dmath.h" #include "TexCache.h" #include "DepthBufferRender.h" #include "GBI.h" extern int dzdx; extern int deltaZ; extern VERTEX **org_vtx; typedef struct { float d; float x; float y; } LineEquationType; typedef struct { unsigned int c2_m2b:2; unsigned int c1_m2b:2; unsigned int c2_m2a:2; unsigned int c1_m2a:2; unsigned int c2_m1b:2; unsigned int c1_m1b:2; unsigned int c2_m1a:2; unsigned int c1_m1a:2; } rdp_blender_setting; #define EvaLine(li, x, y) ((li->x) * (x) + (li->y) * (y) + (li->d)) void apply_shade_mods (VERTEX *v) { if (rdp.cmb_flags) { if (v->shade_mod == 0) v->color_backup = *(uint32_t*)(&(v->b)); else *(uint32_t*)(&(v->b)) = v->color_backup; if (rdp.cmb_flags & CMB_SET) { v->r = (uint8_t)(255.0f * get_float_color_clamped(rdp.col[0])); v->g = (uint8_t)(255.0f * get_float_color_clamped(rdp.col[1])); v->b = (uint8_t)(255.0f * get_float_color_clamped(rdp.col[2])); } if (rdp.cmb_flags & CMB_A_SET) v->a = (uint8_t)(255.0f * get_float_color_clamped(rdp.col[3])); if (rdp.cmb_flags & CMB_SETSHADE_SHADEALPHA) v->r = v->g = v->b = v->a; if (rdp.cmb_flags & CMB_MULT_OWN_ALPHA) { float percent = v->a / 255.0f; v->r = (uint8_t)(v->r * percent); v->g = (uint8_t)(v->g * percent); v->b = (uint8_t)(v->b * percent); } if (rdp.cmb_flags & CMB_MULT) { v->r = (uint8_t)(v->r * get_float_color_clamped(rdp.col[0])); v->g = (uint8_t)(v->g * get_float_color_clamped(rdp.col[1])); v->b = (uint8_t)(v->b * get_float_color_clamped(rdp.col[2])); } if (rdp.cmb_flags & CMB_A_MULT) v->a = (uint8_t)(v->a * get_float_color_clamped(rdp.col[3])); if (rdp.cmb_flags & CMB_SUB) { int r = v->r - (int)(255.0f * rdp.coladd[0]); int g = v->g - (int)(255.0f * rdp.coladd[1]); int b = v->b - (int)(255.0f * rdp.coladd[2]); if (r < 0) r = 0; if (g < 0) g = 0; if (b < 0) b = 0; v->r = (uint8_t)r; v->g = (uint8_t)g; v->b = (uint8_t)b; } if (rdp.cmb_flags & CMB_A_SUB) { int a = v->a - (int)(255.0f * rdp.coladd[3]); if (a < 0) a = 0; v->a = (uint8_t)a; } if (rdp.cmb_flags & CMB_ADD) { int r = v->r + (int)(255.0f * rdp.coladd[0]); int g = v->g + (int)(255.0f * rdp.coladd[1]); int b = v->b + (int)(255.0f * rdp.coladd[2]); if (r > 255) r = 255; if (g > 255) g = 255; if (b > 255) b = 255; v->r = (uint8_t)r; v->g = (uint8_t)g; v->b = (uint8_t)b; } if (rdp.cmb_flags & CMB_A_ADD) { int a = v->a + (int)(255.0f * rdp.coladd[3]); if (a > 255) a = 255; v->a = (uint8_t)a; } if (rdp.cmb_flags & CMB_COL_SUB_OWN) { int r = (uint8_t)(255.0f * rdp.coladd[0]) - v->r; int g = (uint8_t)(255.0f * rdp.coladd[1]) - v->g; int b = (uint8_t)(255.0f * rdp.coladd[2]) - v->b; if (r < 0) r = 0; if (g < 0) g = 0; if (b < 0) b = 0; v->r = (uint8_t)r; v->g = (uint8_t)g; v->b = (uint8_t)b; } v->shade_mod = cmb.shade_mod_hash; } if (rdp.cmb_flags_2 & CMB_INTER) { v->r = (uint8_t)(rdp.col_2[0] * rdp.shade_factor * 255.0f + v->r * (1.0f - rdp.shade_factor)); v->g = (uint8_t)(rdp.col_2[1] * rdp.shade_factor * 255.0f + v->g * (1.0f - rdp.shade_factor)); v->b = (uint8_t)(rdp.col_2[2] * rdp.shade_factor * 255.0f + v->b * (1.0f - rdp.shade_factor)); v->shade_mod = cmb.shade_mod_hash; } } static void Create1LineEquation(LineEquationType *l, VERTEX *v1, VERTEX *v2, VERTEX *v3) { float x = v3->sx; float y = v3->sy; // Line between (x1,y1) to (x2,y2) l->x = v2->sy-v1->sy; l->y = v1->sx-v2->sx; l->d = -(l->x * v2->sx+ (l->y) * v2->sy); if (EvaLine(l,x,y) * v3->oow < 0) { l->x = -l->x; l->y = -l->y; l->d = -l->d; } } static INLINE void glide64_interpolate_colors(VERTEX *va, VERTEX *vb, VERTEX *res, float percent, float va_oow, float vb_oow, float w) { float ba = va->b * va_oow; float bb = vb->b * vb_oow; float ga = va->g * va_oow; float gb = vb->g * vb_oow; float ra = va->r * va_oow; float rb = vb->r * vb_oow; float aa = va->a * va_oow; float ab = vb->a * vb_oow; float fa = va->f * va_oow; float fb = vb->f * vb_oow; res->r = (uint8_t)((ra + (rb - ra) * percent) * w); res->g = (uint8_t)((ga + (gb - ga) * percent) * w); res->b = (uint8_t)((ba + (bb - ba) * percent) * w); res->a = (uint8_t)((aa + (ab - aa) * percent) * w); res->f = (fa + (fb - fa) * percent) * w; } #define interp3p(a, b, c, r1, r2) ((a)+(((b)+((c)-(b))*(r2))-(a))*(r1)) static void InterpolateColors3(VERTEX *v1, VERTEX *v2, VERTEX *v3, VERTEX *out) { LineEquationType line; float aDot, bDot, scale1, tx, ty, s1, s2, den, w; Create1LineEquation(&line, v2, v3, v1); aDot = (out->x * line.x + out->y * line.y); bDot = (v1->sx * line.x + v1->sy * line.y); scale1 = ( -line.d - aDot) / ( bDot - aDot ); tx = out->x + scale1 * (v1->sx - out->x); ty = out->y + scale1 * (v1->sy - out->y); s1 = 101.0; s2 = 101.0; den = tx - v1->sx; if (fabs(den) > 1.0) s1 = (out->x-v1->sx)/den; if (s1 > 100.0f) s1 = (out->y-v1->sy)/(ty-v1->sy); den = v3->sx - v2->sx; if (fabs(den) > 1.0) s2 = (tx-v2->sx)/den; if (s2 > 100.0f) s2 =(ty-v2->sy)/(v3->sy-v2->sy); w = 1.0f / interp3p(v1->oow,v2->oow,v3->oow,s1,s2); out->r = (uint8_t) (w * interp3p(v1->r*v1->oow,v2->r*v2->oow,v3->r*v3->oow,s1,s2)); out->g = (uint8_t) (w * interp3p(v1->g*v1->oow,v2->g*v2->oow,v3->g*v3->oow,s1,s2)); out->b = (uint8_t) (w * interp3p(v1->b*v1->oow,v2->b*v2->oow,v3->b*v3->oow,s1,s2)); out->a = (uint8_t) (w * interp3p(v1->a*v1->oow,v2->a*v2->oow,v3->a*v3->oow,s1,s2)); out->f = interp3p(v1->f*v1->oow,v2->f*v2->oow,v3->f*v3->oow,s1,s2) * w; } static INLINE void CalculateLODValues(VERTEX *v, int32_t i, int32_t j, float *lodFactor, float s_scale, float t_scale) { float deltaS = (v[j].u[0]/v[j].q - v[i].u[0]/v[i].q) * s_scale; float deltaT = (v[j].v[0]/v[j].q - v[i].v[0]/v[i].q) * t_scale; float deltaTexels = sqrtf( deltaS * deltaS + deltaT * deltaT ); float deltaX = (v[j].x - v[i].x)/rdp.scale_x; float deltaY = (v[j].y - v[i].y)/rdp.scale_y; float deltaPixels = sqrtf( deltaX * deltaX + deltaY * deltaY ); *lodFactor += deltaTexels / deltaPixels; } static void CalculateLOD(VERTEX *v, int n, uint32_t lodmode) { float intptr, lod_fraction, detailmax; int i, j, ilod, lod_tile; float s_scale = rdp.tiles[rdp.cur_tile].width / 255.0f; float t_scale = rdp.tiles[rdp.cur_tile].height / 255.0f; float lodFactor = 0; if (lodmode == G_TL_LOD) { n = 1; j = 1; } for (i = 0; i < n; i++) { if (lodmode == G_TL_TILE) j = (i < n-1) ? (i + 1) : 0; CalculateLODValues(v, i, j, &lodFactor, s_scale, t_scale); } if (lodmode == G_TL_TILE) lodFactor = lodFactor / n; // Divide by n (n edges) to find average ilod = (int)lodFactor; lod_tile = min((int)(log10f((float)ilod)/log10f(2.0f)), rdp.cur_tile + rdp.mipmap_level); lod_fraction = 1.0f; detailmax = 1.0f - lod_fraction; if (lod_tile < rdp.cur_tile + rdp.mipmap_level) lod_fraction = max((float)modff(lodFactor / pow(2.,lod_tile),&intptr), g_gdp.primitive_lod_min / 255.0f); if (cmb.dc0_detailmax < 0.5f) detailmax = lod_fraction; grTexDetailControl (GR_TMU0, cmb.dc0_lodbias, cmb.dc0_detailscale, detailmax); grTexDetailControl (GR_TMU1, cmb.dc1_lodbias, cmb.dc1_detailscale, detailmax); } float ScaleZ(float z) { if (settings.n64_z_scale) { int iz = (int)(z*8.0f+0.5f); if (iz < 0) iz = 0; else if (iz >= ZLUT_SIZE) iz = ZLUT_SIZE - 1; return (float)zLUT[iz]; } if (z < 0.0f) return 0.0f; z *= 1.9f; if (z > 65535.0f) return 65535.0f; return z; } static void DepthBuffer(VERTEX * vtx, int n) { unsigned i = 0; if ( gfx_plugin_accuracy < 3) return; if (fb_depth_render_enabled && dzdx && (rdp.flags & ZBUF_UPDATE)) { struct vertexi v[12]; int index = 0; int inc = 1; if (rdp.u_cull_mode == 1) //cull front { index = n - 1; inc = -1; } for (i = 0; i < n; i++) { v[i].x = (int)((vtx[index].x - rdp.offset_x) / rdp.scale_x * 65536.0); v[i].y = (int)((vtx[index].y - rdp.offset_y) / rdp.scale_y * 65536.0); v[i].z = (int)(vtx[index].z * 65536.0); index += inc; } Rasterize(v, n, dzdx); } for (i = 0; i < n; i++) vtx[i].z = ScaleZ(vtx[i].z); } #define clip_tri_uv(first, second, index, percent) \ rdp.vtxbuf[index].u[0] = first->u[0] + (second->u[0] - first->u[0]) * percent; \ rdp.vtxbuf[index].v[0] = first->v[0] + (second->v[0] - first->v[0]) * percent; \ rdp.vtxbuf[index].u[1] = first->u[1] + (second->u[1] - first->u[1]) * percent; \ rdp.vtxbuf[index].v[1] = first->v[1] + (second->v[1] - first->v[1]) * percent #define clip_tri_interp_colors(first, second, index, percent, val, interpolate_colors) \ if (interpolate_colors) \ glide64_interpolate_colors(first, second, &rdp.vtxbuf[index++], percent, 1.0f, 1.0f, 1.0f); \ else \ rdp.vtxbuf[index++].number = first->number | second->number | val static void clip_tri(int interpolate_colors) { int i,j,index,n=rdp.n_global; float percent; // Check which clipping is needed if (rdp.clip & CLIP_XMAX) // right of the screen { // Swap vertex buffers VERTEX *tmp = rdp.vtxbuf2; rdp.vtxbuf2 = rdp.vtxbuf; rdp.vtxbuf = tmp; rdp.vtx_buffer ^= 1; index = 0; // Check the vertices for clipping for (i=0; ix <= rdp.clip_max_x) { if (second->x <= rdp.clip_max_x) // Both are in, save the last one { save_inpoint = true; } else // First is in, second is out, save intersection { current = first; current2 = second; } } else { if (second->x <= rdp.clip_max_x) // First is out, second is in, save intersection & in point { current = second; current2 = first; save_inpoint = true; } } if (current && current2) { percent = (rdp.clip_max_x - current->x) / (current2->x - current->x); rdp.vtxbuf[index].x = rdp.clip_max_x; rdp.vtxbuf[index].y = current->y + (current2->y - current->y) * percent; rdp.vtxbuf[index].z = current->z + (current2->z - current->z) * percent; rdp.vtxbuf[index].q = current->q + (current2->q - current->q) * percent; clip_tri_uv(current, current2, index, percent); clip_tri_interp_colors(current, current2, index, percent, 8, interpolate_colors); } if (save_inpoint) { // Save the in point rdp.vtxbuf[index++] = rdp.vtxbuf2[j]; } } n = index; } if (rdp.clip & CLIP_XMIN) // left of the screen { // Swap vertex buffers VERTEX *tmp = rdp.vtxbuf2; rdp.vtxbuf2 = rdp.vtxbuf; rdp.vtxbuf = tmp; rdp.vtx_buffer ^= 1; index = 0; // Check the vertices for clipping for (i=0; ix >= rdp.clip_min_x) { if (second->x >= rdp.clip_min_x) // Both are in, save the last one { save_inpoint = true; } else // First is in, second is out, save intersection { current = first; current2 = second; } } else { if (second->x >= rdp.clip_min_x) // First is out, second is in, save intersection & in point { current = second; current2 = first; save_inpoint = true; } } if (current && current2) { percent = (rdp.clip_min_x - current->x) / (current2->x - current->x); rdp.vtxbuf[index].x = rdp.clip_min_x; rdp.vtxbuf[index].y = current->y + (current2->y - current->y) * percent; rdp.vtxbuf[index].z = current->z + (current2->z - current->z) * percent; rdp.vtxbuf[index].q = current->q + (current2->q - current->q) * percent; clip_tri_uv(current, current2, index, percent); clip_tri_interp_colors(current, current2, index, percent, 8, interpolate_colors); } if (save_inpoint) { // Save the in point rdp.vtxbuf[index++] = rdp.vtxbuf2[j]; } } n = index; } if (rdp.clip & CLIP_YMAX) // top of the screen { // Swap vertex buffers VERTEX *tmp = rdp.vtxbuf2; rdp.vtxbuf2 = rdp.vtxbuf; rdp.vtxbuf = tmp; rdp.vtx_buffer ^= 1; index = 0; // Check the vertices for clipping for (i=0; iy <= rdp.clip_max_y) { if (second->y <= rdp.clip_max_y) // Both are in, save the last one { save_inpoint = true; } else // First is in, second is out, save intersection { current = first; current2 = second; } } else { if (second->y <= rdp.clip_max_y) // First is out, second is in, save intersection & in point { current = second; current2 = first; save_inpoint = true; } } if (current && current2) { percent = (rdp.clip_max_y - current->y) / (current2->y - current->y); rdp.vtxbuf[index].x = current->x + (current2->x - current->x) * percent; rdp.vtxbuf[index].y = rdp.clip_max_y; rdp.vtxbuf[index].z = current->z + (current2->z - current->z) * percent; rdp.vtxbuf[index].q = current->q + (current2->q - current->q) * percent; clip_tri_uv(current, current2, index, percent); clip_tri_interp_colors(current, current2, index, percent, 16, interpolate_colors); } if (save_inpoint) { // Save the in point rdp.vtxbuf[index++] = rdp.vtxbuf2[j]; } } n = index; } if (rdp.clip & CLIP_YMIN) // bottom of the screen { // Swap vertex buffers VERTEX *tmp = rdp.vtxbuf2; rdp.vtxbuf2 = rdp.vtxbuf; rdp.vtxbuf = tmp; rdp.vtx_buffer ^= 1; index = 0; // Check the vertices for clipping for (i=0; iy >= rdp.clip_min_y) { if (second->y >= rdp.clip_min_y) // Both are in, save the last one { save_inpoint = true; } else // First is in, second is out, save intersection { current = first; current2 = second; } } else { if (second->y >= rdp.clip_min_y) // First is out, second is in, save intersection & in point { current = second; current2 = first; save_inpoint = true; } } if (current && current2) { percent = (rdp.clip_min_y - current->y) / (current2->y - current->y); rdp.vtxbuf[index].x = current->x + (current2->x - current->x) * percent; rdp.vtxbuf[index].y = rdp.clip_min_y; rdp.vtxbuf[index].z = current->z + (current2->z - current->z) * percent; rdp.vtxbuf[index].q = current->q + (current2->q - current->q) * percent; clip_tri_uv(current, current2, index, percent); clip_tri_interp_colors(current, current2, index, percent, 16, interpolate_colors); } if (save_inpoint) { // Save the in point rdp.vtxbuf[index++] = rdp.vtxbuf2[j]; } } n = index; } if (rdp.clip & CLIP_ZMAX) // far plane { // Swap vertex buffers VERTEX *tmp; float maxZ; tmp = (VERTEX*)rdp.vtxbuf2; rdp.vtxbuf2 = rdp.vtxbuf; rdp.vtxbuf = tmp; rdp.vtx_buffer ^= 1; index = 0; maxZ = rdp.view_trans[2] + rdp.view_scale[2]; // Check the vertices for clipping for (i=0; iz < maxZ) { if (second->z < maxZ) { /* Both are in, save the last one */ save_inpoint = true; } else { /* First is in, second is out, save intersection */ current = first; current2 = second; } } else { if (second->z < maxZ) { /* First is out, second is in, save intersection & in point */ current = second; current2 = first; if (second->z < maxZ) save_inpoint = true; } } if (current && current2) { percent = (maxZ - current->z) / (current2->z - current->z); rdp.vtxbuf[index].x = current->x + (current2->x - current->x) * percent; rdp.vtxbuf[index].y = current->y + (current2->y - current->y) * percent; rdp.vtxbuf[index].z = maxZ - 0.001f;; rdp.vtxbuf[index].q = current->q + (current2->q - current->q) * percent; clip_tri_uv(current, current2, index, percent); clip_tri_interp_colors(current, current2, index, percent, 0, interpolate_colors); } /* Save the in point */ if (save_inpoint) rdp.vtxbuf[index++] = rdp.vtxbuf2[j]; } n = index; } #if 0 if (rdp.clip & CLIP_ZMIN) // near Z { // Swap vertex buffers VERTEX *tmp = rdp.vtxbuf2; rdp.vtxbuf2 = rdp.vtxbuf; rdp.vtxbuf = tmp; rdp.vtx_buffer ^= 1; index = 0; // Check the vertices for clipping for (i=0; i= 0.0f) { if (rdp.vtxbuf2[j].z >= 0.0f) // Both are in, save the last one { rdp.vtxbuf[index++] = rdp.vtxbuf2[j]; } else // First is in, second is out, save intersection { percent = (-rdp.vtxbuf2[i].z) / (rdp.vtxbuf2[j].z - rdp.vtxbuf2[i].z); rdp.vtxbuf[index].x = rdp.vtxbuf2[i].x + (rdp.vtxbuf2[j].x - rdp.vtxbuf2[i].x) * percent; rdp.vtxbuf[index].y = rdp.vtxbuf2[i].y + (rdp.vtxbuf2[j].y - rdp.vtxbuf2[i].y) * percent; rdp.vtxbuf[index].z = 0.0f; rdp.vtxbuf[index].q = rdp.vtxbuf2[i].q + (rdp.vtxbuf2[j].q - rdp.vtxbuf2[i].q) * percent; rdp.vtxbuf[index].u[0] = rdp.vtxbuf2[i].u[0] + (rdp.vtxbuf2[j].u[0] - rdp.vtxbuf2[i].u[0]) * percent; rdp.vtxbuf[index].v[0] = rdp.vtxbuf2[i].v[0] + (rdp.vtxbuf2[j].v[0] - rdp.vtxbuf2[i].v[0]) * percent; rdp.vtxbuf[index].u[1] = rdp.vtxbuf2[i].u[1] + (rdp.vtxbuf2[j].u[1] - rdp.vtxbuf2[i].u[1]) * percent; rdp.vtxbuf[index].v[1] = rdp.vtxbuf2[i].v[1] + (rdp.vtxbuf2[j].v[1] - rdp.vtxbuf2[i].v[1]) * percent; if (interpolate_colors) glide64_interpolate_colors(&rdp.vtxbuf2[i], &rdp.vtxbuf2[j], &rdp.vtxbuf[index++], percent, 1.0f, 1.0f, 1.0f); else rdp.vtxbuf[index++].number = rdp.vtxbuf2[i].number | rdp.vtxbuf2[j].number; } } else { //if (rdp.vtxbuf2[j].z < 0.0f) // Both are out, save nothing if (rdp.vtxbuf2[j].z >= 0.0f) // First is out, second is in, save intersection & in point { percent = (-rdp.vtxbuf2[j].z) / (rdp.vtxbuf2[i].z - rdp.vtxbuf2[j].z); rdp.vtxbuf[index].x = rdp.vtxbuf2[j].x + (rdp.vtxbuf2[i].x - rdp.vtxbuf2[j].x) * percent; rdp.vtxbuf[index].y = rdp.vtxbuf2[j].y + (rdp.vtxbuf2[i].y - rdp.vtxbuf2[j].y) * percent; rdp.vtxbuf[index].z = 0.0f;; rdp.vtxbuf[index].q = rdp.vtxbuf2[j].q + (rdp.vtxbuf2[i].q - rdp.vtxbuf2[j].q) * percent; rdp.vtxbuf[index].u[0] = rdp.vtxbuf2[j].u[0] + (rdp.vtxbuf2[i].u[0] - rdp.vtxbuf2[j].u[0]) * percent; rdp.vtxbuf[index].v[0] = rdp.vtxbuf2[j].v[0] + (rdp.vtxbuf2[i].v[0] - rdp.vtxbuf2[j].v[0]) * percent; rdp.vtxbuf[index].u[1] = rdp.vtxbuf2[j].u[1] + (rdp.vtxbuf2[i].u[1] - rdp.vtxbuf2[j].u[1]) * percent; rdp.vtxbuf[index].v[1] = rdp.vtxbuf2[j].v[1] + (rdp.vtxbuf2[i].v[1] - rdp.vtxbuf2[j].v[1]) * percent; if (interpolate_colors) glide64_interpolate_colors(&rdp.vtxbuf2[j], &rdp.vtxbuf2[i], &rdp.vtxbuf[index++], percent, 1.0f, 1.0f, 1.0f); else rdp.vtxbuf[index++].number = rdp.vtxbuf2[i].number | rdp.vtxbuf2[j].number; // Save the in point rdp.vtxbuf[index++] = rdp.vtxbuf2[j]; } } } n = index; } #endif rdp.n_global = n; } static void render_tri (uint16_t linew, int old_interpolate) { int i, n; float fog; if (rdp.clip) clip_tri(old_interpolate); n = rdp.n_global; if ((rdp.clip & CLIP_ZMIN) && (rdp.othermode_l & G_OBJLT_TLUT)) { int to_render = false; for (i = 0; i < n; i++) { if (rdp.vtxbuf[i].z >= 0.0f) { to_render = true; break; } } if (!to_render) //all z < 0 return; } if (rdp.clip && !old_interpolate) { for (i = 0; i < n; i++) { float percent = 101.0f; VERTEX * v1 = 0, * v2 = 0; switch (rdp.vtxbuf[i].number&7) { case 1: case 2: case 4: continue; break; case 3: v1 = org_vtx[0]; v2 = org_vtx[1]; break; case 5: v1 = org_vtx[0]; v2 = org_vtx[2]; break; case 6: v1 = org_vtx[1]; v2 = org_vtx[2]; break; case 7: InterpolateColors3(org_vtx[0], org_vtx[1], org_vtx[2], &rdp.vtxbuf[i]); continue; break; } switch (rdp.vtxbuf[i].number&24) { case 8: percent = (rdp.vtxbuf[i].x-v1->sx)/(v2->sx-v1->sx); break; case 16: percent = (rdp.vtxbuf[i].y-v1->sy)/(v2->sy-v1->sy); break; default: { float d = (v2->sx-v1->sx); if (fabs(d) > 1.0) percent = (rdp.vtxbuf[i].x-v1->sx)/d; if (percent > 100.0f) percent = (rdp.vtxbuf[i].y-v1->sy)/(v2->sy-v1->sy); } } { float w = 1.0f / (v1->oow + (v2->oow - v1->oow) * percent); glide64_interpolate_colors(v1, v2, &rdp.vtxbuf[i], percent, v1->oow, v2->oow, w); } } } ConvertCoordsConvert (rdp.vtxbuf, n); switch (rdp.fog_mode) { case FOG_MODE_ENABLED: for (i = 0; i < n; i++) rdp.vtxbuf[i].f = 1.0f/max(4.0f, rdp.vtxbuf[i].f); break; case FOG_MODE_BLEND: fog = 1.0f/max(1, g_gdp.fog_color.a); for (i = 0; i < n; i++) rdp.vtxbuf[i].f = fog; break; case FOG_MODE_BLEND_INVERSE: fog = 1.0f/max(1, (~g_gdp.fog_color.total) & 0xFF); for (i = 0; i < n; i++) rdp.vtxbuf[i].f = fog; break; } if (settings.lodmode && rdp.cur_tile < rdp.mipmap_level) CalculateLOD(rdp.vtxbuf, n, settings.lodmode); cmb.cmb_ext_use = cmb.tex_cmb_ext_use = 0; if (linew > 0) { VERTEX v[4]; float width; VERTEX *V0 = &rdp.vtxbuf[0]; VERTEX *V1 = &rdp.vtxbuf[1]; if (fabs(V0->x - V1->x) < 0.01 && fabs(V0->y - V1->y) < 0.01) V1 = &rdp.vtxbuf[2]; V0->z = ScaleZ(V0->z); V1->z = ScaleZ(V1->z); v[0] = *V0; v[1] = *V0; v[2] = *V1; v[3] = *V1; width = linew * 0.25f; if (fabs(V0->y - V1->y) < 0.0001) { v[0].x = v[1].x = V0->x; v[2].x = v[3].x = V1->x; width *= rdp.scale_y; v[0].y = v[2].y = V0->y - width; v[1].y = v[3].y = V0->y + width; } else if (fabs(V0->x - V1->x) < 0.0001) { v[0].y = v[1].y = V0->y; v[2].y = v[3].y = V1->y; width *= rdp.scale_x; v[0].x = v[2].x = V0->x - width; v[1].x = v[3].x = V0->x + width; } else { float dx = V1->x - V0->x; float dy = V1->y - V0->y; float len = sqrtf(dx*dx + dy*dy); float wx = dy * width * rdp.scale_x / len; float wy = dx * width * rdp.scale_y / len; v[0].x = V0->x + wx; v[0].y = V0->y - wy; v[1].x = V0->x - wx; v[1].y = V0->y + wy; v[2].x = V1->x + wx; v[2].y = V1->y - wy; v[3].x = V1->x - wx; v[3].y = V1->y + wy; } grDrawVertexArrayContiguous(GR_TRIANGLE_STRIP, 4, &v[0]); } else { DepthBuffer(rdp.vtxbuf, n); if ((rdp.rm & 0xC10) == 0xC10) grDepthBiasLevel(-deltaZ); grDrawVertexArrayContiguous(GR_TRIANGLE_FAN, n, rdp.vtx_buffer ? rdp.vtx2 : rdp.vtx1); } } void do_triangle_stuff_2 (uint16_t linew, uint8_t no_clip, int old_interpolate) { int i; if (no_clip) rdp.clip = 0; for (i = 0; i < rdp.n_global; i++) { if (rdp.vtxbuf[i].x > rdp.clip_max_x) rdp.clip |= CLIP_XMAX; if (rdp.vtxbuf[i].x < rdp.clip_min_x) rdp.clip |= CLIP_XMIN; if (rdp.vtxbuf[i].y > rdp.clip_max_y) rdp.clip |= CLIP_YMAX; if (rdp.vtxbuf[i].y < rdp.clip_min_y) rdp.clip |= CLIP_YMIN; } render_tri (linew, old_interpolate); } void do_triangle_stuff (uint16_t linew, int old_interpolate) // what else?? do the triangle stuff :P (to keep from writing code twice) { int i; float maxZ = (g_gdp.other_modes.z_source_sel != 1) ? rdp.view_trans[2] + rdp.view_scale[2] : g_gdp.prim_color.z; uint8_t no_clip = 2; for (i=0; i< rdp.n_global; i++) { VERTEX *vtx = (VERTEX*)&rdp.vtxbuf[i]; if (vtx->not_zclipped) { //FRDP (" * NOT ZCLIPPPED: %d\n", vtx->number); vtx->x = vtx->sx; vtx->y = vtx->sy; vtx->z = vtx->sz; vtx->q = vtx->oow; vtx->u[0] = vtx->u_w[0]; vtx->v[0] = vtx->v_w[0]; vtx->u[1] = vtx->u_w[1]; vtx->v[1] = vtx->v_w[1]; } else { //FRDP (" * ZCLIPPED: %d\n", vtx->number); vtx->q = 1.0f / vtx->w; vtx->x = rdp.view_trans[0] + vtx->x * vtx->q * rdp.view_scale[0] + rdp.offset_x; vtx->y = rdp.view_trans[1] + vtx->y * vtx->q * rdp.view_scale[1] + rdp.offset_y; vtx->z = rdp.view_trans[2] + vtx->z * vtx->q * rdp.view_scale[2]; if (rdp.tex >= 1) { vtx->u[0] *= vtx->q; vtx->v[0] *= vtx->q; } if (rdp.tex >= 2) { vtx->u[1] *= vtx->q; vtx->v[1] *= vtx->q; } } if (g_gdp.other_modes.z_source_sel == 1) vtx->z = g_gdp.prim_color.z; // Don't remove clipping, or it will freeze if (vtx->x > rdp.clip_max_x) rdp.clip |= CLIP_XMAX; if (vtx->x < rdp.clip_min_x) rdp.clip |= CLIP_XMIN; if (vtx->y > rdp.clip_max_y) rdp.clip |= CLIP_YMAX; if (vtx->y < rdp.clip_min_y) rdp.clip |= CLIP_YMIN; if (vtx->z > maxZ) rdp.clip |= CLIP_ZMAX; if (vtx->z < 0.0f) rdp.clip |= CLIP_ZMIN; no_clip &= vtx->screen_translated; } if (!no_clip) { if (!settings.clip_zmin) rdp.clip &= ~CLIP_ZMIN; } do_triangle_stuff_2(linew, no_clip, old_interpolate); } void update_scissor(bool set_scissor) { if (!(g_gdp.flags & UPDATE_SCISSOR)) return; if (set_scissor) { rdp.scissor.ul_x = (uint32_t)rdp.clip_min_x; rdp.scissor.lr_x = (uint32_t)rdp.clip_max_x; rdp.scissor.ul_y = (uint32_t)rdp.clip_min_y; rdp.scissor.lr_y = (uint32_t)rdp.clip_max_y; } else { rdp.scissor.ul_x = (uint32_t)(g_gdp.__clip.xh * rdp.scale_x + rdp.offset_x); rdp.scissor.lr_x = (uint32_t)(g_gdp.__clip.xl * rdp.scale_x + rdp.offset_x); rdp.scissor.ul_y = (uint32_t)(g_gdp.__clip.yh * rdp.scale_y + rdp.offset_y); rdp.scissor.lr_y = (uint32_t)(g_gdp.__clip.yl * rdp.scale_y + rdp.offset_y); } grClipWindow (rdp.scissor.ul_x, rdp.scissor.ul_y, rdp.scissor.lr_x, rdp.scissor.lr_y); g_gdp.flags ^= UPDATE_SCISSOR; } static void glide64_z_compare(void) { int depthbias_level = 0; int depthbuf_func = GR_CMP_ALWAYS; int depthmask_val = FXFALSE; g_gdp.flags ^= UPDATE_ZBUF_ENABLED; if (((rdp.flags & ZBUF_ENABLED) || ((g_gdp.other_modes.z_source_sel == G_ZS_PRIM) && (((rdp.othermode_h & RDP_CYCLE_TYPE) >> 20) < G_CYC_COPY)))) { if (rdp.flags & ZBUF_COMPARE) { switch (g_gdp.other_modes.z_mode) { case ZMODE_OPA: depthbuf_func = settings.zmode_compare_less ? GR_CMP_LESS : GR_CMP_LEQUAL; break; case ZMODE_INTER: depthbias_level = -4; depthbuf_func = settings.zmode_compare_less ? GR_CMP_LESS : GR_CMP_LEQUAL; break; case ZMODE_XLU: if (settings.ucode == 7) depthbias_level = -4; depthbuf_func = GR_CMP_LESS; break; case ZMODE_DEC: // will be set dynamically per polygon //grDepthBiasLevel(-deltaZ); depthbuf_func = GR_CMP_LEQUAL; break; } } if (rdp.flags & ZBUF_UPDATE) depthmask_val = FXTRUE; } grDepthBiasLevel(depthbias_level); grDepthBufferFunction (depthbuf_func); grDepthMask(depthmask_val); } // // update - update states if they need it // void update(void) { bool set_scissor = false; // Check for rendermode changes // Z buffer if (rdp.render_mode_changed & 0x00000C30) { FRDP (" |- render_mode_changed zbuf - decal: %s, update: %s, compare: %s\n", str_yn[(rdp.othermode_l & G_CULL_BACK)?1:0], str_yn[(rdp.othermode_l & UPDATE_BIASLEVEL)?1:0], str_yn[(rdp.othermode_l & ALPHA_COMPARE)?1:0]); rdp.render_mode_changed &= ~0x00000C30; g_gdp.flags |= UPDATE_ZBUF_ENABLED; // Update? if ((rdp.othermode_l & RDP_Z_UPDATE_ENABLE)) rdp.flags |= ZBUF_UPDATE; else rdp.flags &= ~ZBUF_UPDATE; // Compare? if (rdp.othermode_l & ALPHA_COMPARE) rdp.flags |= ZBUF_COMPARE; else rdp.flags &= ~ZBUF_COMPARE; } // Alpha compare if (rdp.render_mode_changed & CULL_FRONT) { FRDP (" |- render_mode_changed alpha compare - on: %s\n", str_yn[(rdp.othermode_l & CULL_FRONT)?1:0]); rdp.render_mode_changed &= ~CULL_FRONT; g_gdp.flags |= UPDATE_ALPHA_COMPARE; if (rdp.othermode_l & CULL_FRONT) rdp.flags |= ALPHA_COMPARE; else rdp.flags &= ~ALPHA_COMPARE; } if (rdp.render_mode_changed & CULL_BACK) // alpha cvg sel { FRDP (" |- render_mode_changed alpha cvg sel - on: %s\n", str_yn[(rdp.othermode_l & CULL_BACK)?1:0]); rdp.render_mode_changed &= ~CULL_BACK; g_gdp.flags |= UPDATE_COMBINE; g_gdp.flags |= UPDATE_ALPHA_COMPARE; } // Force blend if (rdp.render_mode_changed & 0xFFFF0000) { FRDP (" |- render_mode_changed force_blend - %08lx\n", rdp.othermode_l&0xFFFF0000); rdp.render_mode_changed &= 0x0000FFFF; rdp.fbl_a0 = (uint8_t)((rdp.othermode_l>>30)&0x3); rdp.fbl_b0 = (uint8_t)((rdp.othermode_l>>26)&0x3); rdp.fbl_c0 = (uint8_t)((rdp.othermode_l>>22)&0x3); rdp.fbl_d0 = (uint8_t)((rdp.othermode_l>>18)&0x3); rdp.fbl_a1 = (uint8_t)((rdp.othermode_l>>28)&0x3); rdp.fbl_b1 = (uint8_t)((rdp.othermode_l>>24)&0x3); rdp.fbl_c1 = (uint8_t)((rdp.othermode_l>>20)&0x3); rdp.fbl_d1 = (uint8_t)((rdp.othermode_l>>16)&0x3); g_gdp.flags |= UPDATE_COMBINE; } // Combine MUST go before texture if ((g_gdp.flags & UPDATE_COMBINE) && rdp.allow_combine) { LRDP (" |-+ update_combine\n"); Combine (); } if (g_gdp.flags & UPDATE_TEXTURE) // note: UPDATE_TEXTURE and UPDATE_COMBINE are the same { rdp.tex_ctr ++; if (rdp.tex_ctr == 0xFFFFFFFF) rdp.tex_ctr = 0; TexCache (); if (rdp.noise == NOISE_MODE_NONE) g_gdp.flags ^= UPDATE_TEXTURE; } if (g_gdp.flags & UPDATE_ZBUF_ENABLED) glide64_z_compare(); // Alpha compare if (g_gdp.flags & UPDATE_ALPHA_COMPARE) { g_gdp.flags ^= UPDATE_ALPHA_COMPARE; if ((rdp.othermode_l & RDP_ALPHA_COMPARE) == 1 && !(rdp.othermode_l & RDP_ALPHA_CVG_SELECT) && (!(rdp.othermode_l & RDP_FORCE_BLEND) || (g_gdp.blend_color.a))) { uint8_t reference = (uint8_t)g_gdp.blend_color.a; grAlphaTestFunction (reference ? GR_CMP_GEQUAL : GR_CMP_GREATER, reference, 1); FRDP (" |- alpha compare: blend: %02lx\n", reference); } else { if (rdp.flags & ALPHA_COMPARE) { bool cond_set = (rdp.othermode_l & 0x5000) == 0x5000; grAlphaTestFunction (!cond_set ? GR_CMP_GEQUAL : GR_CMP_GREATER, 0x20, !cond_set ? 1 : 0); if (cond_set) grAlphaTestReferenceValue (((rdp.othermode_l & RDP_ALPHA_COMPARE) == 3) ? (uint8_t)g_gdp.blend_color.a : 0x00); } else { grAlphaTestFunction (GR_CMP_ALWAYS, 0x00, 0); LRDP (" |- alpha compare: none\n"); } } if ((rdp.othermode_l & RDP_ALPHA_COMPARE) == 3 && (((rdp.othermode_h & RDP_CYCLE_TYPE) >> 20) < G_CYC_COPY)) { if (settings.old_style_adither || g_gdp.other_modes.alpha_dither_sel != 3) { LRDP (" |- alpha compare: dither\n"); grStippleMode(settings.stipple_mode); } else grStippleMode(GR_STIPPLE_DISABLE); } else { //LRDP (" |- alpha compare: dither disabled\n"); grStippleMode(GR_STIPPLE_DISABLE); } } // Cull mode (leave this in for z-clipped triangles) if (g_gdp.flags & UPDATE_CULL_MODE) { uint32_t mode; g_gdp.flags ^= UPDATE_CULL_MODE; mode = (rdp.flags & CULLMASK) >> CULLSHIFT; FRDP (" |- cull_mode - mode: %s\n", str_cull[mode]); switch (mode) { case 0: // cull none case 3: // cull both grCullMode(GR_CULL_DISABLE); break; case 1: // cull front grCullMode(GR_CULL_NEGATIVE); break; case 2: // cull back grCullMode (GR_CULL_POSITIVE); break; } } //Added by Gonetz. if (settings.fog && (g_gdp.flags & UPDATE_FOG_ENABLED)) { uint16_t blender; g_gdp.flags ^= UPDATE_FOG_ENABLED; blender = (uint16_t)(rdp.othermode_l >> 16); if (rdp.flags & FOG_ENABLED) { rdp_blender_setting *bl = (rdp_blender_setting*)(&blender); if((rdp.fog_multiplier > 0) && (bl->c1_m1a==3 || bl->c1_m2a == 3 || bl->c2_m1a == 3 || bl->c2_m2a == 3)) { grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT, g_gdp.fog_color.total); rdp.fog_mode = FOG_MODE_ENABLED; LRDP("fog enabled \n"); } else { LRDP("fog disabled in blender\n"); rdp.fog_mode = FOG_MODE_DISABLED; grFogMode (GR_FOG_DISABLE, g_gdp.fog_color.total); } } else if (blender == 0xc410 || blender == 0xc411 || blender == 0xf500) { grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT, g_gdp.fog_color.total); rdp.fog_mode = FOG_MODE_BLEND; LRDP("fog blend \n"); } else if (blender == 0x04d1) { grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT, g_gdp.fog_color.total); rdp.fog_mode = FOG_MODE_BLEND_INVERSE; LRDP("fog blend \n"); } else { LRDP("fog disabled\n"); rdp.fog_mode = FOG_MODE_DISABLED; grFogMode (GR_FOG_DISABLE, g_gdp.fog_color.total); } } if (g_gdp.flags & UPDATE_VIEWPORT) { g_gdp.flags ^= UPDATE_VIEWPORT; { float scale_x = (float)fabs(rdp.view_scale[0]); float scale_y = (float)fabs(rdp.view_scale[1]); rdp.clip_min_x = max((rdp.view_trans[0] - scale_x + rdp.offset_x) / rdp.clip_ratio, 0.0f); rdp.clip_min_y = max((rdp.view_trans[1] - scale_y + rdp.offset_y) / rdp.clip_ratio, 0.0f); rdp.clip_max_x = min((rdp.view_trans[0] + scale_x + rdp.offset_x) * rdp.clip_ratio, settings.res_x); rdp.clip_max_y = min((rdp.view_trans[1] + scale_y + rdp.offset_y) * rdp.clip_ratio, settings.res_y); FRDP (" |- viewport - (%d, %d, %d, %d)\n", (uint32_t)rdp.clip_min_x, (uint32_t)rdp.clip_min_y, (uint32_t)rdp.clip_max_x, (uint32_t)rdp.clip_max_y); if (!rdp.scissor_set) { g_gdp.flags |= UPDATE_SCISSOR; set_scissor = true; } } } update_scissor(set_scissor); } libretro-common/libco/sjlj.c000664 001750 001750 00000004537 12655644434 017236 0ustar00sergiosergio000000 000000 /* libco.sjlj (2008-01-28) author: Nach license: public domain */ /* * Note this was designed for UNIX systems. Based on ideas expressed in a paper * by Ralf Engelschall. * For SJLJ on other systems, one would want to rewrite springboard() and * co_create() and hack the jmb_buf stack pointer. */ #define LIBCO_C #include #include #include #include #ifdef __cplusplus extern "C" { #endif typedef struct { sigjmp_buf context; void (*coentry)(void); void *stack; } cothread_struct; static thread_local cothread_struct co_primary; static thread_local cothread_struct *creating, *co_running = 0; static void springboard(int ignored) { if(sigsetjmp(creating->context, 0)) co_running->coentry(); } cothread_t co_active(void) { if (!co_running) co_running = &co_primary; return (cothread_t)co_running; } cothread_t co_create(unsigned int size, void (*coentry)(void)) { if(!co_running) co_running = &co_primary; cothread_struct *thread = (cothread_struct*)malloc(sizeof(cothread_struct)); if(thread) { stack_t stack; stack_t old_stack; struct sigaction handler = {{0}}; struct sigaction old_handler = {{0}}; thread->coentry = thread->stack = 0; stack.ss_flags = 0; stack.ss_size = size; thread->stack = stack.ss_sp = malloc(size); if(stack.ss_sp && !sigaltstack(&stack, &old_stack)) { handler.sa_handler = springboard; handler.sa_flags = SA_ONSTACK; sigemptyset(&handler.sa_mask); creating = thread; if(!sigaction(SIGUSR1, &handler, &old_handler)) { if(!raise(SIGUSR1)) thread->coentry = coentry; sigaltstack(&old_stack, 0); sigaction(SIGUSR1, &old_handler, 0); } } if(thread->coentry != coentry) { co_delete(thread); thread = 0; } } return (cothread_t)thread; } void co_delete(cothread_t cothread) { if (cothread) { if(((cothread_struct*)cothread)->stack) free(((cothread_struct*)cothread)->stack); free(cothread); } } void co_switch(cothread_t cothread) { if (!sigsetjmp(co_running->context, 0)) { co_running = (cothread_struct*)cothread; siglongjmp(co_running->context, 1); } } #ifdef __cplusplus } #endif mupen64plus-core/src/r4300/mi_controller.h000664 001750 001750 00000004635 12655644434 021437 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - mi_controller.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_R4300_MI_CONTROLLER_H #define M64P_R4300_MI_CONTROLLER_H #include #ifndef MI_REG #define MI_REG(a) ((a & 0xffff) >> 2) #endif struct r4300_core; enum mi_registers { MI_INIT_MODE_REG, MI_VERSION_REG, MI_INTR_REG, MI_INTR_MASK_REG, MI_REGS_COUNT }; enum mi_intr { MI_INTR_SP = 0x01, MI_INTR_SI = 0x02, MI_INTR_AI = 0x04, MI_INTR_VI = 0x08, MI_INTR_PI = 0x10, MI_INTR_DP = 0x20 }; struct mi_controller { uint32_t regs[MI_REGS_COUNT]; }; void init_mi(struct mi_controller* mi); int read_mi_regs(void* opaque, uint32_t address, uint32_t* value); int write_mi_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask); void raise_rcp_interrupt (struct r4300_core* r4300, uint32_t mi_intr); void signal_rcp_interrupt(struct r4300_core* r4300, uint32_t mi_intr); void clear_rcp_interrupt (struct r4300_core* r4300, uint32_t mi_intr); #endif glide2gl/src/Glitch64/glitchmain.c000664 001750 001750 00000024344 12655644434 020055 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include "glide.h" #include "glitchmain.h" #include "../Glide64/rdp.h" #include "../../libretro/SDL.h" extern retro_environment_t environ_cb; int width, height; int bgra8888_support; static int npot_support; // ZIGGY static GLuint default_texture; int glsl_support = 1; //Gonetz uint16_t *frameBuffer; static uint8_t *buf; #ifdef EMSCRIPTEN GLuint glitch_vbo; #endif static int isExtensionSupported(const char *extension) { const char *str = (const char*)glGetString(GL_EXTENSIONS); if (str && strstr(str, extension)) return 1; return 0; } void FindBestDepthBias(); uint32_t grSstWinOpen(void) { bool ret; struct retro_variable var = { "mupen64-screensize", 0 }; if (frameBuffer) grSstWinClose(0); ret = environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var); if (ret && var.value) { if (sscanf(var.value ? var.value : "640x480", "%dx%d", &width, &height) != 2) { width = 640; height = 480; } } else { width = 640; height =480; } // ZIGGY // allocate static texture names // the initial value should be big enough to support the maximal resolution glGenTextures(1, &default_texture); frameBuffer = (uint16_t*)malloc(width * height * sizeof(uint16_t)); buf = (uint8_t*)malloc(width * height * 4 * sizeof(uint8_t)); #ifdef EMSCRIPTEN glGenBuffers(1, &glitch_vbo); #endif glViewport(0, 0, width, height); #if 0 if (isExtensionSupported("GL_ARB_texture_env_combine") == 0 && isExtensionSupported("GL_EXT_texture_env_combine") == 0) DISPLAY_WARNING("Your video card doesn't support GL_ARB_texture_env_combine extension"); if (isExtensionSupported("GL_ARB_multitexture") == 0) DISPLAY_WARNING("Your video card doesn't support GL_ARB_multitexture extension"); if (isExtensionSupported("GL_ARB_texture_mirrored_repeat") == 0) DISPLAY_WARNING("Your video card doesn't support GL_ARB_texture_mirrored_repeat extension"); #endif packed_pixels_support = 0; // we can assume that non-GLES has GL_EXT_packed_pixels // support -it's included since OpenGL 1.2 if (isExtensionSupported("GL_EXT_packed_pixels") != 0) packed_pixels_support = 1; if (isExtensionSupported("GL_ARB_texture_non_power_of_two") == 0) { //DISPLAY_WARNING("GL_ARB_texture_non_power_of_two supported.\n"); npot_support = 0; } else { printf("GL_ARB_texture_non_power_of_two supported.\n"); npot_support = 1; } if (isExtensionSupported("GL_ARB_shading_language_100") && isExtensionSupported("GL_ARB_shader_objects") && isExtensionSupported("GL_ARB_fragment_shader") && isExtensionSupported("GL_ARB_vertex_shader")) {} if (isExtensionSupported("GL_EXT_texture_format_BGRA8888")) { printf("GL_EXT_texture_format_BGRA8888 supported.\n"); bgra8888_support = 1; } else { //DISPLAY_WARNING("GL_EXT_texture_format_BGRA8888 not supported.\n"); bgra8888_support = 0; } FindBestDepthBias(); init_geometry(); init_combiner(); init_textures(); return 1; } int32_t grSstWinClose(uint32_t context) { if (frameBuffer) free(frameBuffer); if (buf) free(buf); glDeleteTextures(1, &default_texture); #ifdef EMSCRIPTEN glDeleteBuffers(1, &glitch_vbo); #endif frameBuffer = NULL; buf = NULL; free_geometry(); free_combiners(); free_textures(); return FXTRUE; } // frame buffer int32_t grLfbLock( int32_t type, int32_t buffer, int32_t writeMode, int32_t origin, int32_t pixelPipeline, GrLfbInfo_t *info ) { info->origin = origin; info->strideInBytes = width * ((writeMode == GR_LFBWRITEMODE_888) ? 4 : 2); info->lfbPtr = frameBuffer; info->writeMode = writeMode; if (writeMode == GR_LFBWRITEMODE_565) { signed i, j; glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buf); for (j=0; j < height; j++) { for (i=0; i < width; i++) { frameBuffer[(height-j-1)*width+i] = ((buf[j*width*4+i*4+0] >> 3) << 11) | ((buf[j*width*4+i*4+1] >> 2) << 5) | (buf[j*width*4+i*4+2] >> 3); } } } return FXTRUE; } int32_t grLfbReadRegion( int32_t src_buffer, uint32_t src_x, uint32_t src_y, uint32_t src_width, uint32_t src_height, uint32_t dst_stride, void *dst_data ) { unsigned int i,j; glReadPixels(src_x, height-src_y-src_height, src_width, src_height, GL_RGBA, GL_UNSIGNED_BYTE, buf); for (j=0; j> 3) << 11) | ((buf[(src_height-j-1)*src_width*4+i*4+1] >> 2) << 5) | (buf[(src_height-j-1)*src_width*4+i*4+2] >> 3); } } return FXTRUE; } int32_t grLfbWriteRegion( int32_t dst_buffer, uint32_t dst_x, uint32_t dst_y, uint32_t src_format, uint32_t src_width, uint32_t src_height, int32_t pixelPipeline, int32_t src_stride, void *src_data ) { unsigned int i,j; uint16_t *frameBuffer = (uint16_t*)src_data; if(dst_buffer == GR_BUFFER_AUXBUFFER) { for (j=0; j>10)&0x1F)<<3; buf[j*src_width*4+i*4+1]=((col>>5)&0x1F)<<3; buf[j*src_width*4+i*4+2]=((col>>0)&0x1F)<<3; buf[j*src_width*4+i*4+3]=0xFF; } } glBindTexture(GL_TEXTURE_2D, default_texture); glTexSubImage2D(GL_TEXTURE_2D, 0, 4, src_width, src_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf); set_copy_shader(); glDisable(GL_DEPTH_TEST); glDisable(GL_BLEND); invert = 1; data[ 0] = (float)((int)dst_x); /* X 0 */ data[ 1] = (float)(invert*-((int)dst_y)); /* Y 0 */ data[ 2] = 0.0f; /* U 0 */ data[ 3] = 0.0f; /* V 0 */ data[ 4] = (float)((int)dst_x); /* X 1 */ data[ 5] = (float)(invert*-((int)dst_y + (int)src_height)); /* Y 1 */ data[ 6] = 0.0f; /* U 1 */ data[ 7] = (float)src_height; /* V 1 */ data[ 8] = (float)((int)dst_x + (int)src_width); data[ 9] = (float)(invert*-((int)dst_y + (int)src_height)); data[10] = (float)src_width; data[11] = (float)src_height; data[12] = (float)((int)dst_x); data[13] = (float)(invert*-((int)dst_y)); data[14] = 0.0f; data[15] = 0.0f; #ifdef EMSCRIPTEN glBindBuffer(GL_ARRAY_BUFFER, glitch_vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_DYNAMIC_DRAW); #endif glDisableVertexAttribArray(COLOUR_ATTR); glDisableVertexAttribArray(TEXCOORD_1_ATTR); glDisableVertexAttribArray(FOG_ATTR); #ifdef EMSCRIPTEN glVertexAttribPointer(POSITION_ATTR,2,GL_FLOAT,false,4 * sizeof(float), 0); //Position glVertexAttribPointer(TEXCOORD_0_ATTR,2,GL_FLOAT,false,4 * sizeof(float), 2); //Tex #else glVertexAttribPointer(POSITION_ATTR,2,GL_FLOAT,false,4 * sizeof(float), &data[0]); //Position glVertexAttribPointer(TEXCOORD_0_ATTR,2,GL_FLOAT,false,4 * sizeof(float), &data[2]); //Tex #endif glEnableVertexAttribArray(COLOUR_ATTR); glEnableVertexAttribArray(TEXCOORD_1_ATTR); glEnableVertexAttribArray(FOG_ATTR); textureSizes_location = glGetUniformLocation(program_object_default,"textureSizes"); glUniform4f(textureSizes_location,1,1,1,1); glDrawArrays(GL_TRIANGLE_STRIP,0,4); #ifdef EMSCRIPTEN glBindBuffer(GL_ARRAY_BUFFER, 0); #endif compile_shader(); glEnable(GL_DEPTH_TEST); glEnable(GL_BLEND); } return FXTRUE; } void grBufferSwap(uint32_t swap_interval) { bool swapmode = settings.swapmode_retro && BUFFERSWAP; if (!swapmode) retro_return(true); } void grClipWindow(uint32_t minx, uint32_t miny, uint32_t maxx, uint32_t maxy) { glScissor(minx, height - maxy, maxx - minx, maxy - miny); glEnable(GL_SCISSOR_TEST); } void grBufferClear(uint32_t color, uint32_t alpha, uint32_t depth) { glClearColor(((color >> 24) & 0xFF) / 255.0f, ((color >> 16) & 0xFF) / 255.0f, (color & 0xFF) / 255.0f, alpha / 255.0f); glClearDepth(depth / 65535.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } void grColorMask(bool rgb, bool a) { glColorMask(rgb, rgb, rgb, a); } mupen64plus-video-gliden64/src/F3DSWSE.cpp000664 001750 001750 00000004431 12655644434 021212 0ustar00sergiosergio000000 000000 #include "GLideN64.h" #include "Debug.h" #include "F3D.h" #include "F3DEX.h" #include "F3DSWSE.h" #include "F3DSWSE.h" #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gSP.h" #include "gDP.h" #include "GBI.h" void F3DSWSE_Vtx( u32 w0, u32 w1 ) { gSPVertex(w1, _SHIFTR(w0, 4, 12) / 33 + 1, 0); } void F3DSWSE_Tri1( u32 w0, u32 w1 ) { gSP1Triangle( _SHIFTR( w1, 16, 8 ) / 5, _SHIFTR( w1, 8, 8 ) / 5, _SHIFTR( w1, 0, 8 ) / 5); } void F3DSWSE_Quad( u32 w0, u32 w1 ) { gSP1Quadrangle( _SHIFTR( w1, 24, 8 ) / 5, _SHIFTR( w1, 16, 8 ) / 5, _SHIFTR( w1, 8, 8 ) / 5, _SHIFTR( w1, 0, 8 ) / 5 ); } void F3DSWSE_Init() { gSPSetupFunctions(); // Set GeometryMode flags GBI_InitFlags( F3D ); GBI.PCStackSize = 18; // GBI Command Command Value Command Function GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_MTX, F3D_MTX, F3D_Mtx ); GBI_SetGBI( G_RESERVED0, F3D_RESERVED0, F3D_Reserved0 ); GBI_SetGBI( G_MOVEMEM, F3D_MOVEMEM, F3D_MoveMem ); GBI_SetGBI( G_VTX, F3D_VTX, F3DSWSE_Vtx ); GBI_SetGBI( G_RESERVED1, F3D_RESERVED1, F3D_Reserved1 ); GBI_SetGBI( G_DL, F3D_DL, F3D_DList ); GBI_SetGBI( G_RESERVED2, F3D_RESERVED2, F3D_Reserved2 ); GBI_SetGBI( G_RESERVED3, F3D_RESERVED3, F3D_Reserved3 ); GBI_SetGBI( G_SPRITE2D_BASE, F3D_SPRITE2D_BASE, F3D_Sprite2D_Base ); GBI_SetGBI( G_TRI1, F3D_TRI1, F3DSWSE_Tri1 ); GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3D_CullDL ); GBI_SetGBI( G_POPMTX, F3D_POPMTX, F3D_PopMtx ); GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3D_MoveWord ); GBI_SetGBI( G_TEXTURE, F3D_TEXTURE, F3D_Texture ); GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L ); GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL ); GBI_SetGBI( G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, F3D_SetGeometryMode ); GBI_SetGBI( G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE, F3D_ClearGeometryMode ); GBI_SetGBI( G_QUAD, F3D_QUAD, F3DSWSE_Quad ); GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_RDPHALF_CONT, F3D_RDPHALF_CONT, F3D_RDPHalf_Cont ); GBI_SetGBI( G_TRI4, F3D_TRI4, F3D_Tri4 ); } gles2rice/src/RenderTexture.h000664 001750 001750 00000005567 12655644434 017353 0ustar00sergiosergio000000 000000 /* Copyright (C) 2002 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _TEXTURE_BUFFER_H_ #define _TEXTURE_BUFFER_H_ #include "typedefs.h" #include "TextureManager.h" class CRenderTexture; typedef struct { CRenderTexture *pRenderTexture; SetImgInfo CI_Info; uint32_t bufferWidth; uint32_t bufferHeight; uint32_t N64Width; uint32_t N64Height; float scaleX; float scaleY; int maxUsedHeight; uint32_t updateAtFrame; uint32_t updateAtUcodeCount; bool isUsed; uint32_t knownHeight; uint32_t crcInRDRAM; uint32_t crcCheckedAtFrame; TxtrCacheEntry txtEntry; } RenderTextureInfo; class CRenderTexture { public: friend class CGraphicsContext; friend class CDXGraphicsContext; friend class FrameBufferManager; friend class DXFrameBufferManager; friend class OGLFrameBufferManager; CRenderTexture(int width, int height, RenderTextureInfo* pInfo, TextureUsage usage) { m_beingRendered = false; m_width = m_height = 0; m_pTexture = NULL; m_pInfo = pInfo; m_usage = usage; } virtual ~CRenderTexture() {} virtual bool SetAsRenderTarget(bool enable)=0; virtual void LoadTexture(TxtrCacheEntry* pEntry)=0; virtual void StoreToRDRAM(int infoIdx) {}; void GetDimension(int &width, int &height) { width = m_width; height = m_height; } bool IsBeingRendered() { return m_beingRendered; } TextureUsage GetUsage() {return m_usage;} protected: int m_width; int m_height; bool m_beingRendered; TextureUsage m_usage; CTexture* m_pTexture; RenderTextureInfo* m_pInfo; }; class COGLRenderTexture : public CRenderTexture { // Haven't implemented yet public: COGLRenderTexture(int width, int height, RenderTextureInfo* pInfo, TextureUsage usage); ~COGLRenderTexture(); bool SetAsRenderTarget(bool enable); void LoadTexture(TxtrCacheEntry* pEntry); void StoreToRDRAM(int infoIdx); protected: bool InitPBuffer(void); void ShutdownPBuffer(void); int m_widthCreated; int m_heightCreated; COGLTexture *m_pOGLTexture; }; #endif mupen64plus-core/src/r4300/mi_controller.c000664 001750 001750 00000011360 12655644434 021423 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - mi_controller.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "mi_controller.h" #include "r4300.h" #include "r4300_core.h" #include "cp0_private.h" #include #define MI_RDRAM_REG_MODE 0x0200 static void update_mi_init_mode(struct r4300_core* r4300, uint32_t* mi_init_mode, uint32_t w) { /* set init_length */ *mi_init_mode &= ~0x7f; *mi_init_mode |= w & 0x7f; /* clear / set init_mode */ if (w & 0x80) *mi_init_mode &= ~0x80; if (w & 0x100) *mi_init_mode |= 0x80; /* clear / set ebus test_mode */ if (w & 0x200) *mi_init_mode &= ~0x100; if (w & 0x400) *mi_init_mode |= 0x100; /* clear DP interrupt */ if (w & 0x800) { clear_rcp_interrupt(r4300, MI_INTR_DP); } /* clear / set RDRAM reg_mode */ if (w & 0x1000) *mi_init_mode &= ~MI_RDRAM_REG_MODE; if (w & 0x2000) *mi_init_mode |= MI_RDRAM_REG_MODE; } static void update_mi_intr_mask(uint32_t* mi_intr_mask, uint32_t w) { if (w & 0x1) *mi_intr_mask &= ~MI_INTR_SP; // clear SP mask if (w & 0x2) *mi_intr_mask |= MI_INTR_SP; // set SP mask if (w & 0x4) *mi_intr_mask &= ~MI_INTR_SI; // clear SI mask if (w & 0x8) *mi_intr_mask |= MI_INTR_SI; // set SI mask if (w & 0x10) *mi_intr_mask &= ~MI_INTR_AI; // clear AI mask if (w & 0x20) *mi_intr_mask |= MI_INTR_AI; // set AI mask if (w & 0x40) *mi_intr_mask &= ~MI_INTR_VI; // clear VI mask if (w & 0x80) *mi_intr_mask |= MI_INTR_VI; // set VI mask if (w & 0x100) *mi_intr_mask &= ~MI_INTR_PI; // clear PI mask if (w & 0x200) *mi_intr_mask |= MI_INTR_PI; // set PI mask if (w & 0x400) *mi_intr_mask &= ~MI_INTR_DP; // clear DP mask if (w & 0x800) *mi_intr_mask |= MI_INTR_DP; // set DP mask } void init_mi(struct mi_controller* mi) { memset(mi->regs, 0, MI_REGS_COUNT*sizeof(uint32_t)); mi->regs[MI_VERSION_REG] = 0x02020102; } int read_mi_regs(void* opaque, uint32_t address, uint32_t* value) { struct r4300_core* r4300 = (struct r4300_core*)opaque; uint32_t reg = MI_REG(address); *value = r4300->mi.regs[reg]; return 0; } int write_mi_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask) { struct r4300_core* r4300 = (struct r4300_core*)opaque; uint32_t reg = MI_REG(address); const uint32_t *cp0_regs = r4300_cp0_regs(); switch(reg) { case MI_INIT_MODE_REG: update_mi_init_mode(r4300, &r4300->mi.regs[MI_INIT_MODE_REG], value & mask); break; case MI_INTR_MASK_REG: update_mi_intr_mask(&r4300->mi.regs[MI_INTR_MASK_REG], value & mask); check_interupt(); cp0_update_count(); if (next_interupt <= cp0_regs[CP0_COUNT_REG]) gen_interupt(); break; } return 0; } /* interrupt execution is immediate (if not masked) */ void raise_rcp_interrupt(struct r4300_core* r4300, uint32_t mi_intr) { r4300->mi.regs[MI_INTR_REG] |= mi_intr; if (r4300->mi.regs[MI_INTR_REG] & r4300->mi.regs[MI_INTR_MASK_REG]) raise_maskable_interrupt(0x400); } void signal_rcp_interrupt(struct r4300_core* r4300, uint32_t intr) { r4300->mi.regs[MI_INTR_REG] |= intr; check_interupt(); } void clear_rcp_interrupt(struct r4300_core* r4300, uint32_t mi_intr) { r4300->mi.regs[MI_INTR_REG] &= ~mi_intr; check_interupt(); } mupen64plus-core/src/r4300/hacktarux_dynarec/000700 001750 001750 00000000000 12656647145 022074 5ustar00sergiosergio000000 000000 mupen64plus-video-gliden64/src/L3DEX.cpp000664 001750 001750 00000004353 12655644434 020756 0ustar00sergiosergio000000 000000 #include "GLideN64.h" #include "Debug.h" #include "F3D.h" #include "F3DEX.h" #include "L3D.h" #include "L3DEX.h" #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gSP.h" #include "gDP.h" #include "GBI.h" void L3DEX_Line3D( u32 w0, u32 w1 ) { u32 wd = _SHIFTR( w1, 0, 8 ); if (wd == 0) gSPLine3D( _SHIFTR( w1, 17, 7 ), _SHIFTR( w1, 9, 7 ), 0 ); else gSPLineW3D( _SHIFTR( w1, 17, 7 ), _SHIFTR( w1, 9, 7 ), wd, 0 ); } void L3DEX_Init() { gSPSetupFunctions(); // Set GeometryMode flags GBI_InitFlags( F3DEX ); GBI.PCStackSize = 18; // GBI Command Command Value Command Function GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_MTX, F3D_MTX, F3D_Mtx ); GBI_SetGBI( G_RESERVED0, F3D_RESERVED0, F3D_Reserved0 ); GBI_SetGBI( G_MOVEMEM, F3D_MOVEMEM, F3D_MoveMem ); GBI_SetGBI( G_VTX, F3D_VTX, F3DEX_Vtx ); GBI_SetGBI( G_RESERVED1, F3D_RESERVED1, F3D_Reserved1 ); GBI_SetGBI( G_DL, F3D_DL, F3D_DList ); GBI_SetGBI( G_RESERVED2, F3D_RESERVED2, F3D_Reserved2 ); GBI_SetGBI( G_RESERVED3, F3D_RESERVED3, F3D_Reserved3 ); GBI_SetGBI( G_SPRITE2D_BASE, F3D_SPRITE2D_BASE, F3D_Sprite2D_Base ); // GBI_SetGBI( G_TRI1, F3D_TRI1, F3DEX_Tri1 ); GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3DEX_CullDL ); GBI_SetGBI( G_POPMTX, F3D_POPMTX, F3D_PopMtx ); GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3D_MoveWord ); GBI_SetGBI( G_TEXTURE, F3D_TEXTURE, F3D_Texture ); GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L ); GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL ); GBI_SetGBI( G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, F3D_SetGeometryMode ); GBI_SetGBI( G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE, F3D_ClearGeometryMode ); GBI_SetGBI( G_LINE3D, L3D_LINE3D, L3DEX_Line3D ); GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_MODIFYVTX, F3DEX_MODIFYVTX, F3DEX_ModifyVtx ); // GBI_SetGBI( G_TRI2, F3DEX_TRI2, F3DEX_Tri2 ); GBI_SetGBI( G_BRANCH_Z, F3DEX_BRANCH_Z, F3DEX_Branch_Z ); GBI_SetGBI( G_LOAD_UCODE, F3DEX_LOAD_UCODE, F3DEX_Load_uCode ); } mupen64plus-video-gliden64/src/GLideNHQ/TxFilterExport.cpp000664 001750 001750 00000005040 12655644434 024427 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef __MSC__ #pragma warning(disable: 4786) #endif #include "TxFilter.h" TxFilter *txFilter = NULL; #ifdef __cplusplus extern "C"{ #endif TAPI boolean TAPIENTRY txfilter_init(int maxwidth, int maxheight, int maxbpp, int options, int cachesize, const wchar_t * path, const wchar_t * texPackPath, const wchar_t * ident, dispInfoFuncExt callback) { if (txFilter) return 0; txFilter = new TxFilter(maxwidth, maxheight, maxbpp, options, cachesize, path, texPackPath, ident, callback); return (txFilter ? 1 : 0); } TAPI void TAPIENTRY txfilter_shutdown(void) { if (txFilter) delete txFilter; txFilter = NULL; } TAPI boolean TAPIENTRY txfilter_filter(uint8 *src, int srcwidth, int srcheight, uint16 srcformat, uint64 g64crc, GHQTexInfo *info) { if (txFilter) return txFilter->filter(src, srcwidth, srcheight, srcformat, g64crc, info); return 0; } TAPI boolean TAPIENTRY txfilter_hirestex(uint64 g64crc, uint64 r_crc64, uint16 *palette, GHQTexInfo *info) { if (txFilter) return txFilter->hirestex(g64crc, r_crc64, palette, info); return 0; } TAPI uint64 TAPIENTRY txfilter_checksum(uint8 *src, int width, int height, int size, int rowStride, uint8 *palette) { if (txFilter) return txFilter->checksum64(src, width, height, size, rowStride, palette); return 0; } TAPI boolean TAPIENTRY txfilter_dmptx(uint8 *src, int width, int height, int rowStridePixel, uint16 gfmt, uint16 n64fmt, uint64 r_crc64) { if (txFilter) return txFilter->dmptx(src, width, height, rowStridePixel, gfmt, n64fmt, r_crc64); return 0; } TAPI boolean TAPIENTRY txfilter_reloadhirestex() { if (txFilter) return txFilter->reloadhirestex(); return 0; } #ifdef __cplusplus } #endif mupen64plus-video-gliden64/src/ZSort.cpp000664 001750 001750 00000040411 12655644434 021213 0ustar00sergiosergio000000 000000 #include #include #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gSP.h" #include "gDP.h" #include "Log.h" #include "F3D.h" #include "OpenGL.h" #include "3DMath.h" #define GZM_USER0 0 #define GZM_USER1 2 #define GZM_MMTX 4 #define GZM_PMTX 6 #define GZM_MPMTX 8 #define GZM_OTHERMODE 10 #define GZM_VIEWPORT 12 #define GZF_LOAD 0 #define GZF_SAVE 1 #define ZH_NULL 0 #define ZH_SHTRI 1 #define ZH_TXTRI 2 #define ZH_SHQUAD 3 #define ZH_TXQUAD 4 typedef f32 M44[4][4]; struct ZSORTRDP { f32 view_scale[2]; f32 view_trans[2]; } zSortRdp = {{0, 0}, {0, 0}}; void ZSort_RDPCMD( u32, u32 _w1 ) { u32 addr = RSP_SegmentToPhysical(_w1) >> 2; if (addr) { __RSP.bLLE = true; while(true) { u32 w0 = ((u32*)gfx_info.RDRAM)[addr++]; __RSP.cmd = _SHIFTR( w0, 24, 8 ); if (__RSP.cmd == 0xDF) break; u32 w1 = ((u32*)gfx_info.RDRAM)[addr++]; if (__RSP.cmd == 0xE4 || __RSP.cmd == 0xE5) { addr++; __RDP.w2 = ((u32*)gfx_info.RDRAM)[addr++]; addr++; __RDP.w3 = ((u32*)gfx_info.RDRAM)[addr++]; } GBI.cmd[__RSP.cmd]( w0, w1 ); }; __RSP.bLLE = false; } } //RSP command VRCPL static int Calc_invw (int _w) { int count, neg; union { s32 W; u32 UW; s16 HW[2]; u16 UHW[2]; } Result; Result.W = _w; if (Result.UW == 0) { Result.UW = 0x7FFFFFFF; } else { if (Result.W < 0) { neg = TRUE; if (Result.UHW[1] == 0xFFFF && Result.HW[0] < 0) { Result.W = ~Result.W + 1; } else { Result.W = ~Result.W; } } else { neg = FALSE; } for (count = 31; count > 0; --count) { if ((Result.W & (1 << count))) { Result.W &= (0xFFC00000 >> (31 - count) ); count = 0; } } Result.W = 0x7FFFFFFF / Result.W; for (count = 31; count > 0; --count) { if ((Result.W & (1 << count))) { Result.W &= (0xFFFF8000 >> (31 - count) ); count = 0; } } if (neg == TRUE) { Result.W = ~Result.W; } } return Result.W; } static void ZSort_DrawObject (u8 * _addr, u32 _type) { u32 textured = 0, vnum = 0, vsize = 0; switch (_type) { case ZH_NULL: textured = vnum = vsize = 0; break; case ZH_SHTRI: textured = 0; vnum = 3; vsize = 8; break; case ZH_TXTRI: textured = 1; vnum = 3; vsize = 16; break; case ZH_SHQUAD: textured = 0; vnum = 4; vsize = 8; break; case ZH_TXQUAD: textured = 1; vnum = 4; vsize = 16; break; } OGLRender & render = video().getRender(); for (u32 i = 0; i < vnum; ++i) { SPVertex & vtx = render.getVertex(i); vtx.x = _FIXED2FLOAT(((s16*)_addr)[0 ^ 1], 2); vtx.y = _FIXED2FLOAT(((s16*)_addr)[1 ^ 1], 2); vtx.z = 0.0f; vtx.r = _addr[4^3] * 0.0039215689f; vtx.g = _addr[5^3] * 0.0039215689f; vtx.b = _addr[6^3] * 0.0039215689f; vtx.a = _addr[7^3] * 0.0039215689f; vtx.flag = 0; vtx.HWLight = 0; vtx.clip = 0; if (textured != 0) { vtx.s = _FIXED2FLOAT(((s16*)_addr)[4^1], 5 ); vtx.t = _FIXED2FLOAT(((s16*)_addr)[5^1], 5 ); vtx.w = Calc_invw(((int*)_addr)[3]) / 31.0f; } else vtx.w = 1.0f; _addr += vsize; } render.drawLLETriangle(vnum); } static u32 ZSort_LoadObject (u32 _zHeader, u32 * _pRdpCmds) { const u32 type = _zHeader & 7; u8 * addr = gfx_info.RDRAM + (_zHeader&0xFFFFFFF8); u32 w1; switch (type) { case ZH_SHTRI: case ZH_SHQUAD: { w1 = ((u32*)addr)[1]; if (w1 != _pRdpCmds[0]) { _pRdpCmds[0] = w1; ZSort_RDPCMD (0, w1); } ZSort_DrawObject(addr + 8, type); } break; case ZH_NULL: case ZH_TXTRI: case ZH_TXQUAD: { w1 = ((u32*)addr)[1]; if (w1 != _pRdpCmds[0]) { _pRdpCmds[0] = w1; ZSort_RDPCMD (0, w1); } w1 = ((u32*)addr)[2]; if (w1 != _pRdpCmds[1]) { ZSort_RDPCMD (0, w1); _pRdpCmds[1] = w1; } w1 = ((u32*)addr)[3]; if (w1 != _pRdpCmds[2]) { ZSort_RDPCMD (0, w1); _pRdpCmds[2] = w1; } if (type != 0) { ZSort_DrawObject(addr + 16, type); } } break; } return RSP_SegmentToPhysical(((u32*)addr)[0]); } void ZSort_Obj( u32 _w0, u32 _w1 ) { u32 rdpcmds[3] = {0, 0, 0}; u32 cmd1 = _w1; u32 zHeader = RSP_SegmentToPhysical(_w0); while (zHeader) zHeader = ZSort_LoadObject(zHeader, rdpcmds); zHeader = RSP_SegmentToPhysical(cmd1); while (zHeader) zHeader = ZSort_LoadObject(zHeader, rdpcmds); } void ZSort_Interpolate( u32, u32 ) { LOG(LOG_VERBOSE, "ZSort_Interpolate Ignored\n"); } void ZSort_XFMLight( u32 _w0, u32 _w1 ) { int mid = _SHIFTR(_w0, 0, 8); gSPNumLights(1 + _SHIFTR(_w1, 12, 8)); u32 addr = -1024 + _SHIFTR(_w1, 0, 12); assert(mid == GZM_MMTX); /* M44 *m; switch (mid) { case 4: m = (M44*)rdp.model; break; case 6: m = (M44*)rdp.proj; break; case 8: m = (M44*)gSP.matrix.combined; break; } */ gSP.lights[gSP.numLights].r = (f32)(((u8*)DMEM)[(addr+0)^3]) * 0.0039215689f; gSP.lights[gSP.numLights].g = (f32)(((u8*)DMEM)[(addr+1)^3]) * 0.0039215689f; gSP.lights[gSP.numLights].b = (f32)(((u8*)DMEM)[(addr+2)^3]) * 0.0039215689f; addr += 8; u32 i; for (i = 0; i < gSP.numLights; ++i) { gSP.lights[i].r = (f32)(((u8*)DMEM)[(addr+0)^3]) * 0.0039215689f; gSP.lights[i].g = (f32)(((u8*)DMEM)[(addr+1)^3]) * 0.0039215689f; gSP.lights[i].b = (f32)(((u8*)DMEM)[(addr+2)^3]) * 0.0039215689f; gSP.lights[i].x = (f32)(((s8*)DMEM)[(addr+8)^3]); gSP.lights[i].y = (f32)(((s8*)DMEM)[(addr+9)^3]); gSP.lights[i].z = (f32)(((s8*)DMEM)[(addr+10)^3]); addr += 24; } for (i = 0; i < 2; i++) { gSP.lookat[i].x = (f32)(((s8*)DMEM)[(addr+8)^3]); gSP.lookat[i].y = (f32)(((s8*)DMEM)[(addr+9)^3]); gSP.lookat[i].z = (f32)(((s8*)DMEM)[(addr+10)^3]); gSP.lookatEnable = (i == 0) || (i == 1 && gSP.lookat[i].x != 0 && gSP.lookat[i].y != 0); addr += 24; } } void ZSort_LightingL( u32, u32 ) { LOG(LOG_VERBOSE, "ZSort_LightingL Ignored\n"); } void ZSort_Lighting( u32 _w0, u32 _w1 ) { u32 csrs = -1024 + _SHIFTR(_w0, 12, 12); u32 nsrs = -1024 + _SHIFTR(_w0, 0, 12); u32 num = 1 + _SHIFTR(_w1, 24, 8); u32 cdest = -1024 + _SHIFTR(_w1, 12, 12); u32 tdest = -1024 + _SHIFTR(_w1, 0, 12); int use_material = (csrs != 0x0ff0); tdest >>= 1; OGLRender & render = video().getRender(); for (u32 i = 0; i < num; i++) { SPVertex & vtx = render.getVertex(i); vtx.nx = ((s8*)DMEM)[(nsrs++)^3]; vtx.ny = ((s8*)DMEM)[(nsrs++)^3]; vtx.nz = ((s8*)DMEM)[(nsrs++)^3]; TransformVectorNormalize( &vtx.nx, gSP.matrix.modelView[gSP.matrix.modelViewi] ); gSPLightVertex(vtx); f32 fLightDir[3] = {vtx.nx, vtx.ny, vtx.nz}; TransformVectorNormalize(fLightDir, gSP.matrix.projection); f32 x, y; if (gSP.lookatEnable) { x = DotProduct(&gSP.lookat[0].x, fLightDir); y = DotProduct(&gSP.lookat[1].x, fLightDir); } else { x = fLightDir[0]; y = fLightDir[1]; } vtx.s = (x + 1.0f) * 512.0f; vtx.t = (y + 1.0f) * 512.0f; vtx.a = 1.0f; if (use_material) { vtx.r *= DMEM[(csrs++)^3] * 0.0039215689f; vtx.g *= DMEM[(csrs++)^3] * 0.0039215689f; vtx.b *= DMEM[(csrs++)^3] * 0.0039215689f; vtx.a = DMEM[(csrs++)^3] * 0.0039215689f; } DMEM[(cdest++)^3] = (u8)(vtx.r * 255.0f); DMEM[(cdest++)^3] = (u8)(vtx.g * 255.0f); DMEM[(cdest++)^3] = (u8)(vtx.b * 255.0f); DMEM[(cdest++)^3] = (u8)(vtx.a * 255.0f); ((s16*)DMEM)[(tdest++)^1] = (s16)(vtx.s * 32.0f); ((s16*)DMEM)[(tdest++)^1] = (s16)(vtx.t * 32.0f); } } void ZSort_MTXRNSP( u32, u32 ) { LOG(LOG_VERBOSE, "ZSort_MTXRNSP Ignored\n"); } void ZSort_MTXCAT(u32 _w0, u32 _w1) { M44 *s = NULL; M44 *t = NULL; u32 S = _SHIFTR(_w0, 0, 4); u32 T = _SHIFTR(_w1, 16, 4); u32 D = _SHIFTR(_w1, 0, 4); switch (S) { case GZM_MMTX: s = (M44*)gSP.matrix.modelView[gSP.matrix.modelViewi]; break; case GZM_PMTX: s = (M44*)gSP.matrix.projection; break; case GZM_MPMTX: s = (M44*)gSP.matrix.combined; break; } switch (T) { case GZM_MMTX: t = (M44*)gSP.matrix.modelView[gSP.matrix.modelViewi]; break; case GZM_PMTX: t = (M44*)gSP.matrix.projection; break; case GZM_MPMTX: t = (M44*)gSP.matrix.combined; break; } assert(s != NULL && t != NULL); f32 m[4][4]; MultMatrix(*s, *t, m); switch (D) { case GZM_MMTX: memcpy (gSP.matrix.modelView[gSP.matrix.modelViewi], m, 64);; break; case GZM_PMTX: memcpy (gSP.matrix.projection, m, 64);; break; case GZM_MPMTX: memcpy (gSP.matrix.combined, m, 64);; break; } } struct zSortVDest{ s16 sy; s16 sx; s32 invw; s16 yi; s16 xi; s16 wi; u8 fog; u8 cc; }; void ZSort_MultMPMTX( u32 _w0, u32 _w1 ) { int num = 1 + _SHIFTR(_w1, 24, 8); int src = -1024 + _SHIFTR(_w1, 12, 12); int dst = -1024 + _SHIFTR(_w1, 0, 12); s16 * saddr = (s16*)(DMEM+src); zSortVDest * daddr = (zSortVDest*)(DMEM+dst); int idx = 0; zSortVDest v; memset(&v, 0, sizeof(zSortVDest)); for (int i = 0; i < num; ++i) { s16 sx = saddr[(idx++)^1]; s16 sy = saddr[(idx++)^1]; s16 sz = saddr[(idx++)^1]; f32 x = sx*gSP.matrix.combined[0][0] + sy*gSP.matrix.combined[1][0] + sz*gSP.matrix.combined[2][0] + gSP.matrix.combined[3][0]; f32 y = sx*gSP.matrix.combined[0][1] + sy*gSP.matrix.combined[1][1] + sz*gSP.matrix.combined[2][1] + gSP.matrix.combined[3][1]; f32 z = sx*gSP.matrix.combined[0][2] + sy*gSP.matrix.combined[1][2] + sz*gSP.matrix.combined[2][2] + gSP.matrix.combined[3][2]; f32 w = sx*gSP.matrix.combined[0][3] + sy*gSP.matrix.combined[1][3] + sz*gSP.matrix.combined[2][3] + gSP.matrix.combined[3][3]; v.sx = (s16)(zSortRdp.view_trans[0] + x / w * zSortRdp.view_scale[0]); v.sy = (s16)(zSortRdp.view_trans[1] + y / w * zSortRdp.view_scale[1]); v.xi = (s16)x; v.yi = (s16)y; v.wi = (s16)w; v.invw = Calc_invw((int)(w * 31.0)); if (w < 0.0f) v.fog = 0; else { int fog = (int)(z / w * gSP.fog.multiplier + gSP.fog.offset); if (fog > 255) fog = 255; v.fog = (fog >= 0) ? (u8)fog : 0; } v.cc = 0; if (x < -w) v.cc |= 0x10; if (x > w) v.cc |= 0x01; if (y < -w) v.cc |= 0x20; if (y > w) v.cc |= 0x02; if (w < 0.1f) v.cc |= 0x04; daddr[i] = v; } } void ZSort_LinkSubDL( u32, u32 ) { LOG(LOG_VERBOSE, "ZSort_LinkSubDL Ignored\n"); } void ZSort_SetSubDL( u32, u32 ) { LOG(LOG_VERBOSE, "ZSort_SetSubDL Ignored\n"); } void ZSort_WaitSignal( u32, u32 ) { LOG(LOG_VERBOSE, "ZSort_WaitSignal Ignored\n"); } void ZSort_SendSignal( u32, u32 ) { LOG(LOG_VERBOSE, "ZSort_SendSignal Ignored\n"); } static void ZSort_SetTexture() { gSP.texture.scales = 1.0f; gSP.texture.scalet = 1.0f; gSP.texture.level = 0; gSP.texture.on = 1; gSP.texture.tile = 0; gSPSetGeometryMode(0x0200); } void ZSort_MoveMem( u32 _w0, u32 _w1 ) { int idx = _w0 & 0x0E; int ofs = _SHIFTR(_w0, 6, 9)<<3; int len = 1 + (_SHIFTR(_w0, 15, 9)<<3); int flag = _w0 & 0x01; u32 addr = RSP_SegmentToPhysical(_w1); switch (idx) { case GZF_LOAD: //save/load if (flag == 0) { int dmem_addr = (idx<<3) + ofs; memcpy(DMEM + dmem_addr, gfx_info.RDRAM + addr, len); } else { int dmem_addr = (idx<<3) + ofs; memcpy(gfx_info.RDRAM + addr, DMEM + dmem_addr, len); } break; case GZM_MMTX: // model matrix RSP_LoadMatrix(gSP.matrix.modelView[gSP.matrix.modelViewi], addr); gSP.changed |= CHANGED_MATRIX; break; case GZM_PMTX: // projection matrix RSP_LoadMatrix(gSP.matrix.projection, addr); gSP.changed |= CHANGED_MATRIX; break; case GZM_MPMTX: // combined matrix RSP_LoadMatrix(gSP.matrix.combined, addr); gSP.changed &= ~CHANGED_MATRIX; break; case GZM_OTHERMODE: LOG(LOG_VERBOSE, "MoveMem Othermode Ignored\n"); break; case GZM_VIEWPORT: // VIEWPORT { u32 a = addr >> 1; const f32 scale_x = _FIXED2FLOAT( *(s16*)&gfx_info.RDRAM[(a+0)^1], 2 ); const f32 scale_y = _FIXED2FLOAT( *(s16*)&gfx_info.RDRAM[(a+1)^1], 2 ); const f32 scale_z = _FIXED2FLOAT( *(s16*)&gfx_info.RDRAM[(a+2)^1], 10 ); gSP.fog.multiplier = ((s16*)gfx_info.RDRAM)[(a+3)^1]; const f32 trans_x = _FIXED2FLOAT( *(s16*)&gfx_info.RDRAM[(a+4)^1], 2 ); const f32 trans_y = _FIXED2FLOAT( *(s16*)&gfx_info.RDRAM[(a+5)^1], 2 ); const f32 trans_z = _FIXED2FLOAT( *(s16*)&gfx_info.RDRAM[(a+6)^1], 10 ); gSP.fog.offset = ((s16*)gfx_info.RDRAM)[(a+7)^1]; gSP.viewport.vscale[0] = scale_x; gSP.viewport.vscale[1] = scale_y; gSP.viewport.vscale[2] = scale_z; gSP.viewport.vtrans[0] = trans_x; gSP.viewport.vtrans[1] = trans_y; gSP.viewport.vtrans[2] = trans_z; gSP.viewport.x = gSP.viewport.vtrans[0] - gSP.viewport.vscale[0]; gSP.viewport.y = gSP.viewport.vtrans[1] - gSP.viewport.vscale[1]; gSP.viewport.width = gSP.viewport.vscale[0] * 2; gSP.viewport.height = gSP.viewport.vscale[1] * 2; gSP.viewport.nearz = gSP.viewport.vtrans[2] - gSP.viewport.vscale[2]; gSP.viewport.farz = (gSP.viewport.vtrans[2] + gSP.viewport.vscale[2]) ; zSortRdp.view_scale[0] = scale_x*4.0f; zSortRdp.view_scale[1] = scale_y*4.0f; zSortRdp.view_trans[0] = trans_x*4.0f; zSortRdp.view_trans[1] = trans_y*4.0f; gSP.changed |= CHANGED_VIEWPORT; ZSort_SetTexture(); } break; default: LOG(LOG_ERROR, "ZSort_MoveMem UNKNOWN %d\n", idx); } } void SZort_SetScissor(u32 _w0, u32 _w1) { RDP_SetScissor(_w0, _w1); if ((gDP.scissor.lrx - gDP.scissor.ulx) > (zSortRdp.view_scale[0] - zSortRdp.view_trans[0])) { f32 w = (gDP.scissor.lrx - gDP.scissor.ulx) / 2.0f; f32 h = (gDP.scissor.lry - gDP.scissor.uly) / 2.0f; gSP.viewport.vscale[0] = w; gSP.viewport.vscale[1] = h; gSP.viewport.vtrans[0] = w; gSP.viewport.vtrans[1] = h; gSP.viewport.x = gSP.viewport.vtrans[0] - gSP.viewport.vscale[0]; gSP.viewport.y = gSP.viewport.vtrans[1] - gSP.viewport.vscale[1]; gSP.viewport.width = gSP.viewport.vscale[0] * 2; gSP.viewport.height = gSP.viewport.vscale[1] * 2; zSortRdp.view_scale[0] = w * 4.0f; zSortRdp.view_scale[1] = h * 4.0f; zSortRdp.view_trans[0] = w * 4.0f; zSortRdp.view_trans[1] = h * 4.0f; gSP.changed |= CHANGED_VIEWPORT; ZSort_SetTexture(); } } #define G_ZS_ZOBJ 0x80 #define G_ZS_RDPCMD 0x81 #define G_ZS_SETOTHERMODE_H 0xE3 #define G_ZS_SETOTHERMODE_L 0xE2 #define G_ZS_ENDDL 0xDF #define G_ZS_DL 0xDE #define G_ZS_MOVEMEM 0xDC #define G_ZS_MOVEWORD 0xDB #define G_ZS_SENDSIGNAL 0xDA #define G_ZS_WAITSIGNAL 0xD9 #define G_ZS_SETSUBDL 0xD8 #define G_ZS_LINKSUBDL 0xD7 #define G_ZS_MULT_MPMTX 0xD6 #define G_ZS_MTXCAT 0xD5 #define G_ZS_MTXTRNSP 0xD4 #define G_ZS_LIGHTING_L 0xD3 #define G_ZS_LIGHTING 0xD2 #define G_ZS_XFMLIGHT 0xD1 #define G_ZS_INTERPOLATE 0xD0 u32 G_ZOBJ, G_ZRDPCMD, G_ZSENDSIGNAL, G_ZWAITSIGNAL, G_ZSETSUBDL, G_ZLINKSUBDL, G_ZMULT_MPMTX, G_ZMTXCAT, G_ZMTXTRNSP; u32 G_ZLIGHTING_L, G_ZLIGHTING, G_ZXFMLIGHT, G_ZINTERPOLATE, G_ZSETSCISSOR; void ZSort_Init() { gSPSetupFunctions(); // Set GeometryMode flags GBI_InitFlags( F3D ); GBI.PCStackSize = 10; // GBI Command Command Value Command Function GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_RESERVED0, F3D_RESERVED0, F3D_Reserved0 ); GBI_SetGBI( G_RESERVED1, F3D_RESERVED1, F3D_Reserved1 ); GBI_SetGBI( G_DL, G_ZS_DL, F3D_DList ); GBI_SetGBI( G_RESERVED2, F3D_RESERVED2, F3D_Reserved2 ); GBI_SetGBI( G_RESERVED3, F3D_RESERVED3, F3D_Reserved3 ); GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3D_CullDL ); GBI_SetGBI( G_MOVEWORD, G_ZS_MOVEWORD, F3D_MoveWord ); GBI_SetGBI( G_TEXTURE, F3D_TEXTURE, F3D_Texture ); GBI_SetGBI( G_ZSETSCISSOR, G_SETSCISSOR, SZort_SetScissor ); GBI_SetGBI( G_SETOTHERMODE_H, G_ZS_SETOTHERMODE_H, F3D_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, G_ZS_SETOTHERMODE_L, F3D_SetOtherMode_L ); GBI_SetGBI( G_ENDDL, G_ZS_ENDDL, F3D_EndDL ); GBI_SetGBI( G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, F3D_SetGeometryMode ); GBI_SetGBI( G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE, F3D_ClearGeometryMode ); GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_RDPHALF_CONT, F3D_RDPHALF_CONT, F3D_RDPHalf_Cont ); GBI_SetGBI( G_ZOBJ, G_ZS_ZOBJ, ZSort_Obj ); GBI_SetGBI( G_ZRDPCMD, G_ZS_RDPCMD, ZSort_RDPCMD ); GBI_SetGBI( G_MOVEMEM, G_ZS_MOVEMEM, ZSort_MoveMem ); GBI_SetGBI( G_ZSENDSIGNAL, G_ZS_SENDSIGNAL, ZSort_SendSignal ); GBI_SetGBI( G_ZWAITSIGNAL, G_ZS_WAITSIGNAL, ZSort_WaitSignal ); GBI_SetGBI( G_ZSETSUBDL, G_ZS_SETSUBDL, ZSort_SetSubDL ); GBI_SetGBI( G_ZLINKSUBDL, G_ZS_LINKSUBDL, ZSort_LinkSubDL ); GBI_SetGBI( G_ZMULT_MPMTX, G_ZS_MULT_MPMTX, ZSort_MultMPMTX ); GBI_SetGBI( G_ZMTXCAT, G_ZS_MTXCAT, ZSort_MTXCAT ); GBI_SetGBI( G_ZMTXTRNSP, G_ZS_MTXTRNSP, ZSort_MTXRNSP ); GBI_SetGBI( G_ZLIGHTING_L, G_ZS_LIGHTING_L, ZSort_LightingL ); GBI_SetGBI( G_ZLIGHTING, G_ZS_LIGHTING, ZSort_Lighting ); GBI_SetGBI( G_ZXFMLIGHT, G_ZS_XFMLIGHT, ZSort_XFMLight ); GBI_SetGBI( G_ZINTERPOLATE, G_ZS_INTERPOLATE, ZSort_Interpolate ); } glide2gl/src/Glide64/CRC.h000664 001750 001750 00000004176 12655644434 016165 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** // // CRC32 calculation functions // // Created by Gonetz, 2004 // //**************************************************************** #ifndef GLIDE64_CRC32_H #define GLIDE64_CRC32_H void CRC_Glide64_BuildTable(void); extern unsigned int CRC32(unsigned int crc, void *buffer, unsigned int count); #endif mupen64plus-rsp-hle/src/hle_plugin.c000664 001750 001750 00000013270 12655644434 020555 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-rsp-hle - plugin.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * Copyright (C) 2009 Richard Goedeken * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include "common.h" #include "hle.h" #define M64P_PLUGIN_PROTOTYPES 1 #include "m64p_types.h" #include "m64p_common.h" #include "m64p_plugin.h" #define RSP_HLE_VERSION 0x020000 #define RSP_PLUGIN_API_VERSION 0x020000 /* local variables */ static struct hle_t g_hle; static void (*l_CheckInterrupts)(void) = NULL; static void (*l_ProcessDlistList)(void) = NULL; static void (*l_ProcessAlistList)(void) = NULL; static void (*l_ProcessRdpList)(void) = NULL; static void (*l_ShowCFB)(void) = NULL; static void (*l_DebugCallback)(void *, int, const char *) = NULL; static void *l_DebugCallContext = NULL; static int l_PluginInit = 0; /* local function */ static void DebugMessage(int level, const char *message, va_list args) { char msgbuf[1024]; if (l_DebugCallback == NULL) return; vsprintf(msgbuf, message, args); (*l_DebugCallback)(l_DebugCallContext, level, msgbuf); } /* Global functions needed by HLE core */ void HleVerboseMessage(void* UNUSED(user_defined), const char *message, ...) { va_list args; va_start(args, message); DebugMessage(M64MSG_VERBOSE, message, args); va_end(args); } void HleWarnMessage(void* UNUSED(user_defined), const char *message, ...) { va_list args; va_start(args, message); DebugMessage(M64MSG_WARNING, message, args); va_end(args); } /* DLL-exported functions */ EXPORT m64p_error CALL hlePluginStartup(m64p_dynlib_handle UNUSED(CoreLibHandle), void *Context, void (*DebugCallback)(void *, int, const char *)) { if (l_PluginInit) return M64ERR_ALREADY_INIT; /* first thing is to set the callback function for debug info */ l_DebugCallback = DebugCallback; l_DebugCallContext = Context; /* this plugin doesn't use any Core library functions (ex for Configuration), so no need to keep the CoreLibHandle */ l_PluginInit = 1; return M64ERR_SUCCESS; } EXPORT m64p_error CALL hlePluginShutdown(void) { if (!l_PluginInit) return M64ERR_NOT_INIT; /* reset some local variable */ l_DebugCallback = NULL; l_DebugCallContext = NULL; l_PluginInit = 0; return M64ERR_SUCCESS; } EXPORT m64p_error CALL hlePluginGetVersion(m64p_plugin_type *PluginType, int *PluginVersion, int *APIVersion, const char **PluginNamePtr, int *Capabilities) { /* set version info */ if (PluginType != NULL) *PluginType = M64PLUGIN_RSP; if (PluginVersion != NULL) *PluginVersion = RSP_HLE_VERSION; if (APIVersion != NULL) *APIVersion = RSP_PLUGIN_API_VERSION; if (PluginNamePtr != NULL) *PluginNamePtr = "Hacktarux/Azimer High-Level Emulation RSP Plugin"; if (Capabilities != NULL) *Capabilities = 0; return M64ERR_SUCCESS; } EXPORT unsigned int CALL hleDoRspCycles(unsigned int Cycles) { hle_execute(&g_hle); return Cycles; } EXPORT void CALL hleInitiateRSP(RSP_INFO Rsp_Info, unsigned int* UNUSED(CycleCount)) { hle_init(&g_hle, Rsp_Info.RDRAM, Rsp_Info.DMEM, Rsp_Info.IMEM, Rsp_Info.MI_INTR_REG, Rsp_Info.SP_MEM_ADDR_REG, Rsp_Info.SP_DRAM_ADDR_REG, Rsp_Info.SP_RD_LEN_REG, Rsp_Info.SP_WR_LEN_REG, Rsp_Info.SP_STATUS_REG, Rsp_Info.SP_DMA_FULL_REG, Rsp_Info.SP_DMA_BUSY_REG, Rsp_Info.SP_PC_REG, Rsp_Info.SP_SEMAPHORE_REG, Rsp_Info.DPC_START_REG, Rsp_Info.DPC_END_REG, Rsp_Info.DPC_CURRENT_REG, Rsp_Info.DPC_STATUS_REG, Rsp_Info.DPC_CLOCK_REG, Rsp_Info.DPC_BUFBUSY_REG, Rsp_Info.DPC_PIPEBUSY_REG, Rsp_Info.DPC_TMEM_REG, NULL); l_CheckInterrupts = Rsp_Info.CheckInterrupts; l_ProcessDlistList = Rsp_Info.ProcessDlistList; l_ProcessAlistList = Rsp_Info.ProcessAlistList; l_ProcessRdpList = Rsp_Info.ProcessRdpList; l_ShowCFB = Rsp_Info.ShowCFB; } EXPORT void CALL hleRomClosed(void) { /* do nothing */ } mupen64plus-video-gliden64/src/S2DEX.cpp000664 001750 001750 00000005457 12655644434 020772 0ustar00sergiosergio000000 000000 #include "OpenGL.h" #include "S2DEX.h" #include "F3D.h" #include "F3DEX.h" #include "GBI.h" #include "gSP.h" #include "gDP.h" #include "RSP.h" #include "Types.h" #include "Log.h" void S2DEX_BG_1Cyc( u32 w0, u32 w1 ) { gSPBgRect1Cyc( w1 ); } void S2DEX_BG_Copy( u32 w0, u32 w1 ) { gSPBgRectCopy( w1 ); } void S2DEX_Obj_Rectangle( u32 w0, u32 w1 ) { gSPObjRectangle( w1 ); } void S2DEX_Obj_Sprite( u32 w0, u32 w1 ) { gSPObjSprite( w1 ); } void S2DEX_Obj_MoveMem( u32 w0, u32 w1 ) { switch (_SHIFTR( w0, 0, 16 )) { case S2DEX_MV_MATRIX: gSPObjMatrix( w1 ); break; case S2DEX_MV_SUBMUTRIX: gSPObjSubMatrix( w1 ); break; case S2DEX_MV_VIEWPORT: gSPViewport( w1 ); break; } } void S2DEX_Select_DL( u32 w0, u32 w1 ) { LOG(LOG_WARNING, "S2DEX_Select_DL unimplemented\n"); } void S2DEX_Obj_RenderMode( u32 w0, u32 w1 ) { gSPObjRendermode(w1); } void S2DEX_Obj_Rectangle_R( u32 w0, u32 w1 ) { gSPObjRectangleR(w1); } void S2DEX_Obj_LoadTxtr( u32 w0, u32 w1 ) { gSPObjLoadTxtr( w1 ); } void S2DEX_Obj_LdTx_Sprite( u32 w0, u32 w1 ) { gSPObjLoadTxSprite( w1 ); } void S2DEX_Obj_LdTx_Rect( u32 w0, u32 w1 ) { gSPObjLoadTxRect(w1); } void S2DEX_Obj_LdTx_Rect_R( u32 w0, u32 w1 ) { gSPObjLoadTxRectR( w1 ); } void S2DEX_Init() { gSPSetupFunctions(); // Set GeometryMode flags GBI_InitFlags( F3DEX ); GBI.PCStackSize = 18; // GBI Command Command Value Command Function GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_BG_1CYC, S2DEX_BG_1CYC, S2DEX_BG_1Cyc ); GBI_SetGBI( G_BG_COPY, S2DEX_BG_COPY, S2DEX_BG_Copy ); GBI_SetGBI( G_OBJ_RECTANGLE, S2DEX_OBJ_RECTANGLE, S2DEX_Obj_Rectangle ); GBI_SetGBI( G_OBJ_SPRITE, S2DEX_OBJ_SPRITE, S2DEX_Obj_Sprite ); GBI_SetGBI( G_OBJ_MOVEMEM, S2DEX_OBJ_MOVEMEM, S2DEX_Obj_MoveMem ); GBI_SetGBI( G_DL, F3D_DL, F3D_DList ); GBI_SetGBI( G_SELECT_DL, S2DEX_SELECT_DL, S2DEX_Select_DL ); GBI_SetGBI( G_OBJ_RENDERMODE, S2DEX_OBJ_RENDERMODE, S2DEX_Obj_RenderMode ); GBI_SetGBI( G_OBJ_RECTANGLE_R, S2DEX_OBJ_RECTANGLE_R, S2DEX_Obj_Rectangle_R ); GBI_SetGBI( G_OBJ_LOADTXTR, S2DEX_OBJ_LOADTXTR, S2DEX_Obj_LoadTxtr ); GBI_SetGBI( G_OBJ_LDTX_SPRITE, S2DEX_OBJ_LDTX_SPRITE, S2DEX_Obj_LdTx_Sprite ); GBI_SetGBI( G_OBJ_LDTX_RECT, S2DEX_OBJ_LDTX_RECT, S2DEX_Obj_LdTx_Rect ); GBI_SetGBI( G_OBJ_LDTX_RECT_R, S2DEX_OBJ_LDTX_RECT_R, S2DEX_Obj_LdTx_Rect_R ); GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3D_MoveWord ); GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L ); GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL ); GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_LOAD_UCODE, S2DEX_LOAD_UCODE, F3DEX_Load_uCode ); } mupen64plus-video-gliden64/src/GLideNHQ/TextureFilters.h000664 001750 001750 00000007302 12655644434 024125 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __TEXTUREFILTERS_H__ #define __TEXTUREFILTERS_H__ /* 16bpp filters are somewhat buggy and output image is not clean. * Since there's not much time, we'll just convert them to ARGB8888 * and use 32bpp filters until fixed. * (1:enable hack, 0:disable hack) */ #define _16BPP_HACK 1 #include "TxInternal.h" #include "TextureFilters_xbrz.h" /* enhancers */ void hq4x_8888(unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int SrcPPL, int BpL); void hq2x_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height); void hq2xS_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height); void lq2x_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height); void lq2xS_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height); void Super2xSaI_8888(uint32 *srcPtr, uint32 *destPtr, uint32 width, uint32 height, uint32 pitch); void Texture2x_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height); /* filters */ void SharpFilter_8888(uint32 *src, uint32 srcwidth, uint32 srcheight, uint32 *dest, uint32 filter); void SmoothFilter_8888(uint32 *src, uint32 srcwidth, uint32 srcheight, uint32 *dest, uint32 filter); /* helper */ void filter_8888(uint32 *src, uint32 srcwidth, uint32 srcheight, uint32 *dest, uint32 filter); #if !_16BPP_HACK void hq4x_init(void); void hq4x_4444(unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int SrcPPL, int BpL); void hq4x_1555(unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int SrcPPL, int BpL); void hq4x_565 (unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int SrcPPL, int BpL); void hq2x_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height); void hq2xS_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height); void lq2x_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height); void lq2xS_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height); void Super2xSaI_4444(uint16 *srcPtr, uint16 *destPtr, uint32 width, uint32 height, uint32 pitch); void Super2xSaI_1555(uint16 *srcPtr, uint16 *destPtr, uint32 width, uint32 height, uint32 pitch); void Super2xSaI_565 (uint16 *srcPtr, uint16 *destPtr, uint32 width, uint32 height, uint32 pitch); void Super2xSaI_8 (uint8 *srcPtr, uint8 *destPtr, uint32 width, uint32 height, uint32 pitch); void Texture2x_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height); void SharpFilter_4444(uint16 *src, uint32 srcwidth, uint32 srcheight, uint16 *dest, uint32 filter); void SmoothFilter_4444(uint16 *src, uint32 srcwidth, uint32 srcheight, uint16 *dest, uint32 filter); #endif #endif /* __TEXTUREFILTERS_H__ */ mupen64plus-core/src/r4300/hacktarux_dynarec/assemble.h000664 001750 001750 00000100102 12655644434 024043 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - assemble.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2007 Richard Goedeken (Richard42) * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef __ASSEMBLE_H__ #define __ASSEMBLE_H__ #include "r4300/recomph.h" #include "api/callbacks.h" #include "osal/preproc.h" #include #include #ifdef __x86_64__ extern int64_t reg[32]; typedef uint64_t native_type; #define RAX 0 #define RCX 1 #define RDX 2 #define RBX 3 #define RSP 4 #define RBP 5 #define RSI 6 #define RDI 7 #else typedef uint32_t native_type; extern int64_t reg[32]; #endif #define EAX 0 #define ECX 1 #define EDX 2 #define EBX 3 #define ESP 4 #define EBP 5 #define ESI 6 #define EDI 7 #define AX 0 #define CX 1 #define DX 2 #define BX 3 #define SP 4 #define BP 5 #define SI 6 #define DI 7 #define AL 0 #define CL 1 #define DL 2 #define BL 3 #define AH 4 #define CH 5 #define DH 6 #define BH 7 extern int branch_taken; extern const uint16_t trunc_mode, round_mode, ceil_mode, floor_mode; void jump_start_rel8(void); void jump_end_rel8(void); void jump_start_rel32(void); void jump_end_rel32(void); void add_jump(unsigned int pc_addr, unsigned int mi_addr, unsigned int absolute64); static INLINE void put8(unsigned char octet) { (*inst_pointer)[code_length] = octet; code_length++; if (code_length == max_code_length) { *inst_pointer = (unsigned char*)realloc_exec(*inst_pointer, max_code_length, max_code_length+8192); max_code_length += 8192; } } static INLINE void put32(unsigned int dword) { if ((code_length + 4) >= max_code_length) { *inst_pointer = (unsigned char*)realloc_exec(*inst_pointer, max_code_length, max_code_length+8192); max_code_length += 8192; } *((unsigned int *) (*inst_pointer + code_length)) = dword; code_length += 4; } static INLINE void put64(uint64_t qword) { if ((code_length + 8) >= max_code_length) { *inst_pointer = realloc_exec(*inst_pointer, max_code_length, max_code_length+8192); max_code_length += 8192; } *((uint64_t*) (*inst_pointer + code_length)) = qword; code_length += 8; } static INLINE int rel_r15_offset(void *dest, const char *op_name) { /* calculate the destination pointer's offset from the base of the r4300 registers */ int64_t rel_offset = (int64_t) ((uint8_t *) dest - (uint8_t *) reg); if (llabs(rel_offset) > 0x7fffffff) { DebugMessage(M64MSG_ERROR, "Error: destination %p more than 2GB away from r15 base %p in %s()", dest, reg, op_name); OSAL_BREAKPOINT_INTERRUPT; } return (int) rel_offset; } #ifdef __x86_64__ static INLINE void fld_preg64_dword(int reg64) { put8(0xD9); put8(reg64); } static INLINE void fdiv_preg64_dword(int reg64) { put8(0xD8); put8(0x30 + reg64); } static INLINE void fstp_preg64_dword(int reg64) { put8(0xD9); put8(0x18 + reg64); } static INLINE void fstp_preg64_qword(int reg64) { put8(0xDD); put8(0x18 + reg64); } static INLINE void fadd_preg64_dword(int reg64) { put8(0xD8); put8(reg64); } static INLINE void fsub_preg64_dword(int reg64) { put8(0xD8); put8(0x20 + reg64); } static INLINE void fmul_preg64_dword(int reg64) { put8(0xD8); put8(0x08 + reg64); } static INLINE void fistp_preg64_dword(int reg64) { put8(0xDB); put8(0x18 + reg64); } static INLINE void fistp_preg64_qword(int reg64) { put8(0xDF); put8(0x38 + reg64); } static INLINE void fld_preg64_qword(int reg64) { put8(0xDD); put8(reg64); } static INLINE void fild_preg64_qword(int reg64) { put8(0xDF); put8(0x28+reg64); } static INLINE void fild_preg64_dword(int reg64) { put8(0xDB); put8(reg64); } static INLINE void fadd_preg64_qword(int reg64) { put8(0xDC); put8(reg64); } static INLINE void fdiv_preg64_qword(int reg64) { put8(0xDC); put8(0x30 + reg64); } static INLINE void fsub_preg64_qword(int reg64) { put8(0xDC); put8(0x20 + reg64); } static INLINE void fmul_preg64_qword(int reg64) { put8(0xDC); put8(0x08 + reg64); } static INLINE void cmp_reg64_imm32(int reg64, unsigned int imm32) { put8(0x48); put8(0x81); put8(0xF8 + reg64); put32(imm32); } static INLINE void cmp_preg64preg64_imm8(int reg1, int reg2, unsigned char imm8) { put8(0x80); put8(0x3C); put8((reg1 << 3) | reg2); put8(imm8); } static INLINE void sete_m8rel(unsigned char *m8) { int offset = rel_r15_offset(m8, "sete_m8rel"); put8(0x41); put8(0x0F); put8(0x94); put8(0x87); put32(offset); } static INLINE void setne_m8rel(unsigned char *m8) { int offset = rel_r15_offset(m8, "setne_m8rel"); put8(0x41); put8(0x0F); put8(0x95); put8(0x87); put32(offset); } static INLINE void setl_m8rel(unsigned char *m8) { int offset = rel_r15_offset(m8, "setl_m8rel"); put8(0x41); put8(0x0F); put8(0x9C); put8(0x87); put32(offset); } static INLINE void setle_m8rel(unsigned char *m8) { int offset = rel_r15_offset(m8, "setle_m8rel"); put8(0x41); put8(0x0F); put8(0x9E); put8(0x87); put32(offset); } static INLINE void setg_m8rel(unsigned char *m8) { int offset = rel_r15_offset(m8, "setg_m8rel"); put8(0x41); put8(0x0F); put8(0x9F); put8(0x87); put32(offset); } static INLINE void cmp_reg64_reg64(int reg1, int reg2) { put8(0x48); put8(0x39); put8((reg2 << 3) | reg1 | 0xC0); } static INLINE void cmp_reg64_imm8(int reg64, unsigned char imm8) { put8(0x48); put8(0x83); put8(0xF8 + reg64); put8(imm8); } static INLINE void mov_rax_memoffs64(uint64_t *memoffs64) { put8(0x48); put8(0xA1); put64((uint64_t) memoffs64); } static INLINE void mov_memoffs64_rax(uint64_t *memoffs64) { put8(0x48); put8(0xA3); put64((uint64_t) memoffs64); } static INLINE void mov_m8rel_xreg8(unsigned char *m8, int xreg8) { int offset = rel_r15_offset(m8, "mov_m8rel_xreg8"); put8(0x41 | ((xreg8 & 8) >> 1)); put8(0x88); put8(0x87 | ((xreg8 & 7) << 3)); put32(offset); } static INLINE void mov_xreg16_m16rel(int xreg16, unsigned short *m16) { int offset = rel_r15_offset(m16, "mov_xreg16_m16rel"); put8(0x66); put8(0x41 | ((xreg16 & 8) >> 1)); put8(0x8B); put8(0x87 | ((xreg16 & 7) << 3)); put32(offset); } static INLINE void mov_m16rel_xreg16(unsigned short *m16, int xreg16) { int offset = rel_r15_offset(m16, "mov_m16rel_xreg16"); put8(0x66); put8(0x41 | ((xreg16 & 8) >> 1)); put8(0x89); put8(0x87 | ((xreg16 & 7) << 3)); put32(offset); } static INLINE void cmp_xreg32_m32rel(int xreg32, unsigned int *m32) { int offset = rel_r15_offset(m32, "cmp_xreg32_m32rel"); put8(0x41 | ((xreg32 & 8) >> 1)); put8(0x3B); put8(0x87 | ((xreg32 & 7) << 3)); put32(offset); } static INLINE void cmp_xreg64_m64rel(int xreg64, uint64_t *m64) { int offset = rel_r15_offset(m64, "cmp_xreg64_m64rel"); put8(0x49 | ((xreg64 & 8) >> 1)); put8(0x3B); put8(0x87 | ((xreg64 & 7) << 3)); put32(offset); } #else static INLINE void or_reg32_reg32(unsigned int reg1, unsigned int reg2) { put8(0x09); put8(0xC0 | (reg2 << 3) | reg1); } static INLINE void fldcw_m16(unsigned short *m16) { put8(0xD9); put8(0x2D); put32((unsigned int)(m16)); } static INLINE void mov_reg8_m8(int reg8, unsigned char *m8) { put8(0x8A); put8((reg8 << 3) | 5); put32((unsigned int)(m8)); } static INLINE void mov_reg32_m32(unsigned int reg32, unsigned int* m32) { put8(0x8B); put8((reg32 << 3) | 5); put32((unsigned int)(m32)); } static INLINE void add_reg32_m32(unsigned int reg32, unsigned int *m32) { put8(0x03); put8((reg32 << 3) | 5); put32((unsigned int)(m32)); } static INLINE void movsx_reg32_m16(int reg32, unsigned short *m16) { put8(0x0F); put8(0xBF); put8((reg32 << 3) | 5); put32((unsigned int)(m16)); } static INLINE void movsx_reg32_m8(int reg32, unsigned char *m8) { put8(0x0F); put8(0xBE); put8((reg32 << 3) | 5); put32((unsigned int)(m8)); } static INLINE void mul_m32(unsigned int *m32) { put8(0xF7); put8(0x25); put32((unsigned int)(m32)); } static INLINE void mov_m32_imm32(unsigned int *m32, unsigned int imm32) { put8(0xC7); put8(0x05); put32((unsigned int)(m32)); put32(imm32); } static INLINE void cmp_m32_imm32(unsigned int *m32, unsigned int imm32) { put8(0x81); put8(0x3D); put32((unsigned int)(m32)); put32(imm32); } static INLINE void inc_m32(unsigned int *m32) { put8(0xFF); put8(0x05); put32((unsigned int)(m32)); } static INLINE void and_m32_imm32(unsigned int *m32, unsigned int imm32) { put8(0x81); put8(0x25); put32((unsigned int)(m32)); put32(imm32); } static INLINE void sub_m32_imm32(unsigned int *m32, unsigned int imm32) { put8(0x81); put8(0x2D); put32((unsigned int)(m32)); put32(imm32); } static INLINE void or_m32_imm32(unsigned int *m32, unsigned int imm32) { put8(0x81); put8(0x0D); put32((unsigned int)(m32)); put32(imm32); } static INLINE void mov_m8_reg8(unsigned char *m8, int reg8) { put8(0x88); put8((reg8 << 3) | 5); put32((unsigned int)(m8)); } static INLINE void mov_reg16_m16(int reg16, unsigned short *m16) { put8(0x66); put8(0x8B); put8((reg16 << 3) | 5); put32((unsigned int)(m16)); } static INLINE void mov_m16_reg16(unsigned short *m16, int reg16) { put8(0x66); put8(0x89); put8((reg16 << 3) | 5); put32((unsigned int)(m16)); } static INLINE void cmp_reg32_m32(int reg32, unsigned int *m32) { put8(0x3B); put8((reg32 << 3) | 5); put32((unsigned int)(m32)); } static INLINE void add_m32_reg32(unsigned int *m32, int reg32) { put8(0x01); put8((reg32 << 3) | 5); put32((unsigned int)(m32)); } static INLINE void sub_reg32_m32(int reg32, unsigned int *m32) { put8(0x2B); put8((reg32 << 3) | 5); put32((unsigned int)(m32)); } static INLINE void mov_eax_memoffs32(unsigned int *memoffs32) { put8(0xA1); put32((unsigned int)(memoffs32)); } static INLINE void cmp_preg32pimm32_imm8(int reg32, unsigned int imm32, unsigned char imm8) { put8(0x80); put8(0xB8 + reg32); put32(imm32); put8(imm8); } static INLINE void test_reg32_imm32(int reg32, unsigned int imm32) { put8(0xF7); put8(0xC0 + reg32); put32(imm32); } static INLINE void test_m32_imm32(unsigned int *m32, unsigned int imm32) { put8(0xF7); put8(0x05); put32((unsigned int)m32); put32(imm32); } static INLINE void sbb_reg32_reg32(int reg1, int reg2) { put8(0x19); put8((reg2 << 3) | reg1 | 0xC0); } static INLINE void sub_reg32_imm32(int reg32, unsigned int imm32) { put8(0x81); put8(0xE8 + reg32); put32(imm32); } static INLINE void mov_m32_reg32(unsigned int *m32, unsigned int reg32) { put8(0x89); put8((reg32 << 3) | 5); put32((unsigned int)(m32)); } static INLINE void fdiv_preg32_dword(int reg32) { put8(0xD8); put8(0x30 + reg32); } static INLINE void fstp_preg32_dword(int reg32) { put8(0xD9); put8(0x18 + reg32); } static INLINE void fstp_preg32_qword(int reg32) { put8(0xDD); put8(0x18 + reg32); } static INLINE void fadd_preg32_dword(int reg32) { put8(0xD8); put8(reg32); } static INLINE void fsub_preg32_dword(int reg32) { put8(0xD8); put8(0x20 + reg32); } static INLINE void fmul_preg32_dword(int reg32) { put8(0xD8); put8(0x08 + reg32); } static INLINE void fistp_preg32_dword(int reg32) { put8(0xDB); put8(0x18 + reg32); } static INLINE void fistp_preg32_qword(int reg32) { put8(0xDF); put8(0x38 + reg32); } static INLINE void fld_preg32_qword(int reg32) { put8(0xDD); put8(reg32); } static INLINE void fild_preg32_qword(int reg32) { put8(0xDF); put8(0x28+reg32); } static INLINE void fild_preg32_dword(int reg32) { put8(0xDB); put8(reg32); } static INLINE void fadd_preg32_qword(int reg32) { put8(0xDC); put8(reg32); } static INLINE void fdiv_preg32_qword(int reg32) { put8(0xDC); put8(0x30 + reg32); } static INLINE void fsub_preg32_qword(int reg32) { put8(0xDC); put8(0x20 + reg32); } static INLINE void fmul_preg32_qword(int reg32) { put8(0xDC); put8(0x08 + reg32); } #endif static INLINE void mov_memoffs32_eax(unsigned int *memoffs32) { put8(0xA3); #ifdef __x86_64__ put64((uint64_t) memoffs32); #else put32((unsigned int)(memoffs32)); #endif } static INLINE void cmp_reg32_reg32(int reg1, int reg2) { put8(0x39); put8((reg2 << 3) | reg1 | 0xC0); } static INLINE void cmp_reg32_imm8(int reg32, unsigned char imm8) { put8(0x83); put8(0xF8 + reg32); put8(imm8); } static INLINE void cmp_reg32_imm32(int reg32, unsigned int imm32) { put8(0x81); put8(0xF8 + reg32); put32(imm32); } static INLINE void setge_m8rel(unsigned char *m8) { int offset = rel_r15_offset(m8, "setge_m8rel"); put8(0x41); put8(0x0F); put8(0x9D); put8(0x87); put32(offset); } static INLINE void setl_reg8(unsigned int reg8) { put8(0x40); /* we need an REX prefix to use the uniform byte registers */ put8(0x0F); put8(0x9C); put8(0xC0 | reg8); } static INLINE void setb_reg8(unsigned int reg8) { put8(0x40); /* we need an REX prefix to use the uniform byte registers */ put8(0x0F); put8(0x92); put8(0xC0 | reg8); } static INLINE void test_m32rel_imm32(unsigned int *m32, unsigned int imm32) { int offset = rel_r15_offset(m32, "test_m32rel_imm32"); put8(0x41); put8(0xF7); put8(0x87); put32(offset); put32(imm32); } static INLINE void add_m32rel_xreg32(unsigned int *m32, int xreg32) { int offset = rel_r15_offset(m32, "add_m32rel_xreg32"); put8(0x41 | ((xreg32 & 8) >> 1)); put8(0x01); put8(0x87 | ((xreg32 & 7) << 3)); put32(offset); } static INLINE void sub_xreg32_m32rel(int xreg32, unsigned int *m32) { int offset = rel_r15_offset(m32, "sub_xreg32_m32rel"); put8(0x41 | ((xreg32 & 8) >> 1)); put8(0x2B); put8(0x87 | ((xreg32 & 7) << 3)); put32(offset); } static INLINE void sub_reg32_reg32(int reg1, int reg2) { put8(0x29); put8((reg2 << 3) | reg1 | 0xC0); } static INLINE void sub_reg64_reg64(int reg1, int reg2) { put8(0x48); put8(0x29); put8((reg2 << 3) | reg1 | 0xC0); } static INLINE void sub_reg64_imm32(int reg64, unsigned int imm32) { put8(0x48); put8(0x81); put8(0xE8 + reg64); put32(imm32); } static INLINE void sub_eax_imm32(unsigned int imm32) { put8(0x2D); put32(imm32); } static INLINE void jne_rj(unsigned char saut) { put8(0x75); put8(saut); } static INLINE void je_rj(unsigned char saut) { put8(0x74); put8(saut); } static INLINE void jb_rj(unsigned char saut) { put8(0x72); put8(saut); } static INLINE void jbe_rj(unsigned char saut) { put8(0x76); put8(saut); } static INLINE void ja_rj(unsigned char saut) { put8(0x77); put8(saut); } static INLINE void jae_rj(unsigned char saut) { put8(0x73); put8(saut); } static INLINE void jp_rj(unsigned char saut) { put8(0x7A); put8(saut); } static INLINE void je_near_rj(unsigned int saut) { put8(0x0F); put8(0x84); put32(saut); } static INLINE void mov_reg32_imm32(int reg32, unsigned int imm32) { put8(0xB8+reg32); put32(imm32); } static INLINE void mov_reg64_imm64(int reg64, uint64_t imm64) { put8(0x48); put8(0xB8+reg64); put64(imm64); } static INLINE void jmp_imm_short(char saut) { put8(0xEB); put8(saut); } static INLINE void or_m32rel_imm32(unsigned int *m32, unsigned int imm32) { int offset = rel_r15_offset(m32, "or_m32rel_imm32"); put8(0x41); put8(0x81); put8(0x8F); put32(offset); put32(imm32); } static INLINE void or_reg64_reg64(unsigned int reg1, unsigned int reg2) { put8(0x48); put8(0x09); put8(0xC0 | (reg2 << 3) | reg1); } static INLINE void and_reg64_reg64(unsigned int reg1, unsigned int reg2) { put8(0x48); put8(0x21); put8(0xC0 | (reg2 << 3) | reg1); } static INLINE void and_m32rel_imm32(unsigned int *m32, unsigned int imm32) { int offset = rel_r15_offset(m32, "and_m32rel_imm32"); put8(0x41); put8(0x81); put8(0xA7); put32(offset); put32(imm32); } static INLINE void xor_reg32_reg32(unsigned int reg1, unsigned int reg2) { put8(0x31); put8(0xC0 | (reg2 << 3) | reg1); } static INLINE void and_reg32_reg32(unsigned int reg1, unsigned int reg2) { put8(0x21); put8(0xC0 | (reg2 << 3) | reg1); } static INLINE void xor_reg64_reg64(unsigned int reg1, unsigned int reg2) { put8(0x48); put8(0x31); put8(0xC0 | (reg2 << 3) | reg1); } static INLINE void add_reg64_imm32(unsigned int reg64, unsigned int imm32) { put8(0x48); put8(0x81); put8(0xC0+reg64); put32(imm32); } static INLINE void add_reg32_imm32(unsigned int reg32, unsigned int imm32) { put8(0x81); put8(0xC0+reg32); put32(imm32); } static INLINE void inc_m32rel(unsigned int *m32) { int offset = rel_r15_offset(m32, "inc_m32rel"); put8(0x41); put8(0xFF); put8(0x87); put32(offset); } static INLINE void cmp_m32rel_imm32(unsigned int *m32, unsigned int imm32) { int offset = rel_r15_offset(m32, "cmp_m32rel_imm32"); put8(0x41); put8(0x81); put8(0xBF); put32(offset); put32(imm32); } static INLINE void cmp_eax_imm32(unsigned int imm32) { put8(0x3D); put32(imm32); } static INLINE void mov_m32rel_imm32(unsigned int *m32, unsigned int imm32) { int offset = rel_r15_offset(m32, "mov_m32rel_imm32"); put8(0x41); put8(0xC7); put8(0x87); put32(offset); put32(imm32); } static INLINE void shr_reg32_imm8(unsigned int reg32, unsigned char imm8) { put8(0xC1); put8(0xE8+reg32); put8(imm8); } static INLINE void call_reg32(unsigned int reg32) { put8(0xFF); put8(0xD0+reg32); } static INLINE void jmp(unsigned int mi_addr) { #ifdef __x86_64__ put8(0xFF); put8(0x25); put32(0); put64(0); add_jump(code_length-8, mi_addr, 1); #else put8(0xE9); put32(0); add_jump(code_length-4, mi_addr, 0); #endif } static INLINE void cdq(void) { put8(0x99); } static INLINE void call_reg64(unsigned int reg64) { put8(0xFF); put8(0xD0+reg64); } static INLINE void shr_reg64_imm8(unsigned int reg64, unsigned char imm8) { put8(0x48); put8(0xC1); put8(0xE8+reg64); put8(imm8); } static INLINE void shr_reg32_cl(unsigned int reg32) { put8(0xD3); put8(0xE8+reg32); } static INLINE void shr_reg64_cl(unsigned int reg64) { put8(0x48); put8(0xD3); put8(0xE8+reg64); } static INLINE void sar_reg32_cl(unsigned int reg32) { put8(0xD3); put8(0xF8+reg32); } static INLINE void sar_reg64_cl(unsigned int reg64) { put8(0x48); put8(0xD3); put8(0xF8+reg64); } static INLINE void shl_reg32_cl(unsigned int reg32) { put8(0xD3); put8(0xE0+reg32); } static INLINE void shld_reg32_reg32_cl(unsigned int reg1, unsigned int reg2) { put8(0x0F); put8(0xA5); put8(0xC0 | (reg2 << 3) | reg1); } static INLINE void shld_reg32_reg32_imm8(unsigned int reg1, unsigned int reg2, unsigned char imm8) { put8(0x0F); put8(0xA4); put8(0xC0 | (reg2 << 3) | reg1); put8(imm8); } static INLINE void shl_reg64_cl(unsigned int reg64) { put8(0x48); put8(0xD3); put8(0xE0+reg64); } static INLINE void sar_reg32_imm8(unsigned int reg32, unsigned char imm8) { put8(0xC1); put8(0xF8+reg32); put8(imm8); } static INLINE void shrd_reg32_reg32_imm8(unsigned int reg1, unsigned int reg2, unsigned char imm8) { put8(0x0F); put8(0xAC); put8(0xC0 | (reg2 << 3) | reg1); put8(imm8); } static INLINE void sar_reg64_imm8(unsigned int reg64, unsigned char imm8) { put8(0x48); put8(0xC1); put8(0xF8+reg64); put8(imm8); } static INLINE void mul_m32rel(unsigned int *m32) { int offset = rel_r15_offset(m32, "mul_m32rel"); put8(0x41); put8(0xF7); put8(0xA7); put32(offset); } static INLINE void imul_reg32(unsigned int reg32) { put8(0xF7); put8(0xE8+reg32); } static INLINE void mul_reg64(unsigned int reg64) { put8(0x48); put8(0xF7); put8(0xE0+reg64); } static INLINE void mul_reg32(unsigned int reg32) { put8(0xF7); put8(0xE0+reg32); } static INLINE void idiv_reg32(unsigned int reg32) { put8(0xF7); put8(0xF8+reg32); } static INLINE void div_reg32(unsigned int reg32) { put8(0xF7); put8(0xF0+reg32); } static INLINE void add_reg32_reg32(unsigned int reg1, unsigned int reg2) { put8(0x01); put8(0xC0 | (reg2 << 3) | reg1); } static INLINE void add_reg64_reg64(unsigned int reg1, unsigned int reg2) { put8(0x48); put8(0x01); put8(0xC0 | (reg2 << 3) | reg1); } static INLINE void jmp_reg32(unsigned int reg32) { put8(0xFF); put8(0xE0 + reg32); } static INLINE void jmp_reg64(unsigned int reg64) { put8(0xFF); put8(0xE0 + reg64); } static INLINE void mov_reg32_preg64(unsigned int reg1, unsigned int reg2) { put8(0x8B); put8((reg1 << 3) | reg2); } static INLINE void mov_preg64_reg32(int reg1, int reg2) { put8(0x89); put8((reg2 << 3) | reg1); } static INLINE void mov_reg64_preg64(int reg1, int reg2) { put8(0x48); put8(0x8B); put8((reg1 << 3) | reg2); } static INLINE void mov_reg32_preg32preg32pimm32(int reg1, int reg2, int reg3, unsigned int imm32) { put8(0x8B); put8((reg1 << 3) | 0x84); put8(reg2 | (reg3 << 3)); put32(imm32); } static INLINE void mov_preg32pimm32_imm8(int reg32, unsigned int imm32, unsigned char imm8) { put8(0xC6); put8(0x80 + reg32); put32(imm32); put8(imm8); } static INLINE void mov_preg32_reg32(int reg1, int reg2) { put8(0x89); put8((reg2 << 3) | reg1); } static INLINE void mov_preg32pimm32_reg16(int reg32, unsigned int imm32, int reg16) { put8(0x66); put8(0x89); put8(0x80 | reg32 | (reg16 << 3)); put32(imm32); } static INLINE void mov_preg32pimm32_reg32(int reg1, unsigned int imm32, int reg2) { put8(0x89); put8(0x80 | reg1 | (reg2 << 3)); put32(imm32); } static INLINE void mov_preg32pimm32_reg8(int reg32, unsigned int imm32, int reg8) { put8(0x88); put8(0x80 | reg32 | (reg8 << 3)); put32(imm32); } static INLINE void mov_reg32_preg32pimm32(int reg1, int reg2, unsigned int imm32) { put8(0x8B); put8(0x80 | (reg1 << 3) | reg2); put32(imm32); } static INLINE void mov_reg32_preg32x4pimm32(int reg1, int reg2, unsigned int imm32) { put8(0x8B); put8((reg1 << 3) | 4); put8(0x80 | (reg2 << 3) | 5); put32(imm32); } static INLINE void mov_reg32_preg32(unsigned int reg1, unsigned int reg2) { put8(0x8B); put8((reg1 << 3) | reg2); } static INLINE void mov_reg32_preg64preg64pimm32(int reg1, int reg2, int reg3, unsigned int imm32) { put8(0x8B); put8((reg1 << 3) | 0x84); put8(reg2 | (reg3 << 3)); put32(imm32); } static INLINE void mov_preg64preg64pimm32_reg32(int reg1, int reg2, unsigned int imm32, int reg3) { put8(0x89); put8((reg3 << 3) | 0x84); put8(reg1 | (reg2 << 3)); put32(imm32); } static INLINE void mov_reg64_preg64preg64pimm32(int reg1, int reg2, int reg3, unsigned int imm32) { put8(0x48); put8(0x8B); put8((reg1 << 3) | 0x84); put8(reg2 | (reg3 << 3)); put32(imm32); } static INLINE void mov_reg32_preg64preg64(int reg1, int reg2, int reg3) { put8(0x8B); put8((reg1 << 3) | 0x04); put8((reg2 << 3) | reg3); } static INLINE void mov_reg64_preg64preg64(int reg1, int reg2, int reg3) { put8(0x48); put8(0x8B); put8((reg1 << 3) | 0x04); put8(reg2 | (reg3 << 3)); } static INLINE void mov_reg32_preg64pimm32(int reg1, int reg2, unsigned int imm32) { put8(0x8B); put8(0x80 | (reg1 << 3) | reg2); put32(imm32); } static INLINE void mov_reg64_preg64pimm32(int reg1, int reg2, unsigned int imm32) { put8(0x48); put8(0x8B); put8(0x80 | (reg1 << 3) | reg2); put32(imm32); } static INLINE void mov_reg64_preg64pimm8(int reg1, int reg2, unsigned int imm8) { put8(0x48); put8(0x8B); put8(0x40 | (reg1 << 3) | reg2); put8(imm8); } static INLINE void mov_reg64_preg64x8preg64(int reg1, int reg2, int reg3) { put8(0x48); put8(0x8B); put8((reg1 << 3) | 4); put8(0xC0 | (reg2 << 3) | reg3); } static INLINE void mov_preg64preg64_reg8(int reg1, int reg2, int reg8) { put8(0x88); put8(0x04 | (reg8 << 3)); put8((reg1 << 3) | reg2); } static INLINE void mov_preg64preg64_imm8(int reg1, int reg2, unsigned char imm8) { put8(0xC6); put8(0x04); put8((reg1 << 3) | reg2); put8(imm8); } static INLINE void mov_preg64preg64_reg16(int reg1, int reg2, int reg16) { put8(0x66); put8(0x89); put8(0x04 | (reg16 << 3)); put8((reg1 << 3) | reg2); } static INLINE void mov_preg64preg64_reg32(int reg1, int reg2, int reg32) { put8(0x89); put8(0x04 | (reg32 << 3)); put8((reg1 << 3) | reg2); } static INLINE void mov_preg64pimm32_reg32(int reg1, unsigned int imm32, int reg2) { put8(0x89); put8(0x80 | reg1 | (reg2 << 3)); put32(imm32); } static INLINE void mov_preg64pimm8_reg64(int reg1, unsigned int imm8, int reg2) { put8(0x48); put8(0x89); put8(0x40 | (reg2 << 3) | reg1); put8(imm8); } static INLINE void add_eax_imm32(unsigned int imm32) { put8(0x05); put32(imm32); } static INLINE void shl_reg32_imm8(unsigned int reg32, unsigned char imm8) { put8(0xC1); put8(0xE0 + reg32); put8(imm8); } static INLINE void shl_reg64_imm8(unsigned int reg64, unsigned char imm8) { put8(0x48); put8(0xC1); put8(0xE0 + reg64); put8(imm8); } static INLINE void movsx_reg32_8preg32pimm32(int reg1, int reg2, unsigned int imm32) { put8(0x0F); put8(0xBE); put8((reg1 << 3) | reg2 | 0x80); put32(imm32); } static INLINE void movsx_reg32_16preg32pimm32(int reg1, int reg2, unsigned int imm32) { put8(0x0F); put8(0xBF); put8((reg1 << 3) | reg2 | 0x80); put32(imm32); } static INLINE void not_reg32(unsigned int reg32) { put8(0xF7); put8(0xD0 + reg32); } static INLINE void mov_reg32_reg32(unsigned int reg1, unsigned int reg2) { if (reg1 == reg2) return; put8(0x89); put8(0xC0 | (reg2 << 3) | reg1); } static INLINE void mov_reg64_reg64(unsigned int reg1, unsigned int reg2) { if (reg1 == reg2) return; put8(0x48); put8(0x89); put8(0xC0 | (reg2 << 3) | reg1); } static INLINE void mov_xreg32_m32rel(unsigned int xreg32, unsigned int *m32) { int offset = rel_r15_offset(m32, "mov_xreg32_m32rel"); put8(0x41 | ((xreg32 & 8) >> 1)); put8(0x8B); put8(0x87 | ((xreg32 & 7) << 3)); put32(offset); } static INLINE void mov_m32rel_xreg32(unsigned int *m32, unsigned int xreg32) { int offset = rel_r15_offset(m32, "mov_m32rel_xreg32"); put8(0x41 | ((xreg32 & 8) >> 1)); put8(0x89); put8(0x87 | ((xreg32 & 7) << 3)); put32(offset); } static INLINE void mov_xreg64_m64rel(unsigned int xreg64, uint64_t* m64) { int offset = rel_r15_offset(m64, "mov_xreg64_m64rel"); put8(0x49 | ((xreg64 & 8) >> 1)); put8(0x8B); put8(0x87 | ((xreg64 & 7) << 3)); put32(offset); } static INLINE void mov_m64rel_xreg64(uint64_t *m64, unsigned int xreg64) { int offset = rel_r15_offset(m64, "mov_m64rel_xreg64"); put8(0x49 | ((xreg64 & 8) >> 1)); put8(0x89); put8(0x87 | ((xreg64 & 7) << 3)); put32(offset); } static INLINE void mov_xreg8_m8rel(int xreg8, unsigned char *m8) { int offset = rel_r15_offset(m8, "mov_xreg8_m8rel"); put8(0x41 | ((xreg8 & 8) >> 1)); put8(0x8A); put8(0x87 | ((xreg8 & 7) << 3)); put32(offset); } static INLINE void adc_reg32_reg32(unsigned int reg1, unsigned int reg2) { put8(0x11); put8(0xC0 | (reg2 << 3) | reg1); } static INLINE void adc_reg32_imm32(unsigned int reg32, unsigned int imm32) { put8(0x81); put8(0xD0 + reg32); put32(imm32); } static INLINE void and_eax_imm32(unsigned int imm32) { put8(0x25); put32(imm32); } static INLINE void or_reg64_imm32(int reg64, unsigned int imm32) { put8(0x48); put8(0x81); put8(0xC8 + reg64); put32(imm32); } static INLINE void and_reg32_imm32(int reg32, unsigned int imm32) { put8(0x81); put8(0xE0 + reg32); put32(imm32); } static INLINE void and_reg64_imm32(int reg64, unsigned int imm32) { put8(0x48); put8(0x81); put8(0xE0 + reg64); put32(imm32); } static INLINE void and_reg64_imm8(int reg64, unsigned char imm8) { put8(0x48); put8(0x83); put8(0xE0 + reg64); put8(imm8); } static INLINE void or_reg32_imm32(int reg32, unsigned int imm32) { put8(0x81); put8(0xC8 + reg32); put32(imm32); } static INLINE void xor_reg32_imm32(int reg32, unsigned int imm32) { put8(0x81); put8(0xF0 + reg32); put32(imm32); } static INLINE void xor_reg8_imm8(int reg8, unsigned char imm8) { #ifdef __x86_64__ put8(0x40); /* we need an REX prefix to use the uniform byte registers */ #endif put8(0x80); put8(0xF0 + reg8); put8(imm8); } static INLINE void xor_reg64_imm32(int reg64, unsigned int imm32) { put8(0x48); put8(0x81); put8(0xF0 + reg64); put32(imm32); } static INLINE void not_reg64(unsigned int reg64) { put8(0x48); put8(0xF7); put8(0xD0 + reg64); } static INLINE void neg_reg32(unsigned int reg32) { put8(0xF7); put8(0xD8 + reg32); } static INLINE void neg_reg64(unsigned int reg64) { put8(0x48); put8(0xF7); put8(0xD8 + reg64); } static INLINE void movsx_xreg32_m8rel(int xreg32, unsigned char *m8) { int offset = rel_r15_offset(m8, "movsx_xreg32_m8rel"); put8(0x41 | ((xreg32 & 8) >> 1)); put8(0x0F); put8(0xBE); put8(0x87 | ((xreg32 & 7) << 3)); put32(offset); } static INLINE void movsx_reg32_8preg64preg64(int reg1, int reg2, int reg3) { put8(0x0F); put8(0xBE); put8((reg1 << 3) | 0x04); put8((reg2 << 3) | reg3); } static INLINE void movsx_reg32_16preg64preg64(int reg1, int reg2, int reg3) { put8(0x0F); put8(0xBF); put8((reg1 << 3) | 0x04); put8((reg2 << 3) | reg3); } static INLINE void movsx_xreg32_m16rel(int xreg32, unsigned short *m16) { int offset = rel_r15_offset(m16, "movsx_xreg32_m16rel"); put8(0x41 | ((xreg32 & 8) >> 1)); put8(0x0F); put8(0xBF); put8(0x87 | ((xreg32 & 7) << 3)); put32(offset); } static INLINE void movsxd_reg64_reg32(int reg64, int reg32) { put8(0x48); put8(0x63); put8((reg64 << 3) | reg32 | 0xC0); } static INLINE void fldcw_m16rel(unsigned short *m16) { int offset = rel_r15_offset(m16, "fldcw_m16rel"); put8(0x41); put8(0xD9); put8(0xAF); put32(offset); } static INLINE void fchs(void) { put8(0xD9); put8(0xE0); } static INLINE void fsqrt(void) { put8(0xD9); put8(0xFA); } static INLINE void fabs_(void) { put8(0xD9); put8(0xE1); } static INLINE void fcomip_fpreg(int fpreg) { put8(0xDF); put8(0xF0 + fpreg); } static INLINE void fucomip_fpreg(int fpreg) { put8(0xDF); put8(0xE8 + fpreg); } static INLINE void ffree_fpreg(int fpreg) { put8(0xDD); put8(0xC0 + fpreg); } static INLINE void jle_rj(unsigned char saut) { put8(0x7E); put8(saut); } static INLINE void jge_rj(unsigned char saut) { put8(0x7D); put8(saut); } static INLINE void jg_rj(unsigned char saut) { put8(0x7F); put8(saut); } static INLINE void jl_rj(unsigned char saut) { put8(0x7C); put8(saut); } static INLINE void fld_preg32_dword(int reg32) { put8(0xD9); put8(reg32); } static INLINE void shrd_reg32_reg32_cl(unsigned int reg1, unsigned int reg2) { put8(0x0F); put8(0xAD); put8(0xC0 | (reg2 << 3) | reg1); } #endif /* __ASSEMBLE_H__ */ gles2rice/src/CombinerDefs.h000664 001750 001750 00000010267 12655644434 017104 0ustar00sergiosergio000000 000000 /* Copyright (C) 2002 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _COMBINER_DEFS_H_ #define _COMBINER_DEFS_H_ #include "typedefs.h" #define MUX_MASK 0x1F #define MUX_MASK_WITH_ALPHA 0x5F #define MUX_MASK_WITH_NEG 0x3F #define MUX_MASK_WITH_COMP 0x9F // Combiner constants enum { MUX_0 = 0, MUX_1 = 1, MUX_COMBINED = 2, MUX_TEXEL0 = 3, MUX_TEXEL1 = 4, MUX_PRIM = 5, MUX_SHADE = 6, MUX_ENV = 7, MUX_COMBALPHA = 8, MUX_T0_ALPHA = 9, MUX_T1_ALPHA = 10, MUX_PRIM_ALPHA = 11, MUX_SHADE_ALPHA = 12, MUX_ENV_ALPHA = 13, MUX_LODFRAC = 14, MUX_PRIMLODFRAC = 15, MUX_K5 = 16, MUX_UNK, //Use this if you want to factor to be set to 0 // Don't change value of these three flags, then need to be within 1 uint8_t MUX_NEG = 0x20, //Support by NVidia register combiner MUX_ALPHAREPLICATE = 0x40, MUX_COMPLEMENT = 0x80, MUX_FORCE_0 = 0xFE, MUX_ERR = 0xFF, }; enum CombinerFormatType { CM_FMT_TYPE_NOT_USED, CM_FMT_TYPE_D, // = A can mapped to SEL(arg1) CM_FMT_TYPE_A_MOD_C, // = A*C can mapped to MOD(arg1,arg2) CM_FMT_TYPE_A_ADD_D, // = A+D can mapped to ADD(arg1,arg2) CM_FMT_TYPE_A_SUB_B, // = A-B can mapped to SUB(arg1,arg2) CM_FMT_TYPE_A_MOD_C_ADD_D, // = A*C+D can mapped to MULTIPLYADD(arg1,arg2,arg0) CM_FMT_TYPE_A_LERP_B_C, // = (A-B)*C+B can mapped to LERP(arg1,arg2,arg0) // or mapped to BLENDALPHA(arg1,arg2) if C is // alpha channel or DIF, TEX, FAC, CUR CM_FMT_TYPE_A_SUB_B_ADD_D, // = A-B+C can not map very well in 1 stage CM_FMT_TYPE_A_SUB_B_MOD_C, // = (A-B)*C can not map very well in 1 stage CM_FMT_TYPE_A_ADD_B_MOD_C, // = (A+B)*C can not map very well in 1 stage CM_FMT_TYPE_A_B_C_D, // = (A-B)*C+D can not map very well in 1 stage CM_FMT_TYPE_A_B_C_A, // = (A-B)*C+D can not map very well in 1 stage // Don't use these two types in default functions CM_FMT_TYPE_AB_ADD_CD, // = A*B+C*D Use by nvidia video cards CM_FMT_TYPE_AB_SUB_CD, // = A*B-C*D Use by nvidia video cards CM_FMT_TYPE_AB_ADD_C, // = A*B+C Use by ATI video cards CM_FMT_TYPE_AB_SUB_C, // = A*B-C Use by ATI video cards CM_FMT_TYPE_NOT_CHECKED = 0xFF, }; typedef enum { ENABLE_BOTH, DISABLE_ALPHA, DISABLE_COLOR, DISABLE_BOTH, COLOR_ONE, ALPHA_ONE, } BlendingFunc; typedef enum { COLOR_CHANNEL, ALPHA_CHANNEL, } CombineChannel; typedef struct { uint8_t a; uint8_t b; uint8_t c; uint8_t d; } N64CombinerType; #define CONST_FLAG4(a,b,c,d) (a|(b<<8)|(c<<16)|(d<<24)) //(A-B)*C+D #define CONST_MOD(a,b) (a|(b<<16)) //A*B #define CONST_SEL(a) (a<<24) //=D #define CONST_ADD(a,b) (a|b<<24) //A+D #define CONST_SUB(a,b) (a|b<<8) //A-B #define CONST_MULADD(a,b,c) (a|b<<16|c<<24) //A*C+D #define G_CCMUX_TEXEL1 2 #define G_ACMUX_TEXEL1 2 #define NOTUSED MUX_0 enum { TEX_0=0, TEX_1=1}; typedef struct { uint32_t op; uint32_t Arg1; uint32_t Arg2; uint32_t Arg0; } StageOperate; #endif mupen64plus-video-gliden64/src/RDP.cpp000664 001750 001750 00000040272 12655644434 020564 0ustar00sergiosergio000000 000000 #include #include #include #include "N64.h" #include "RSP.h" #include "RDP.h" #include "GBI.h" #include "gDP.h" #include "gSP.h" #include "OpenGL.h" #include "Debug.h" void RDP_Unknown( u32 w0, u32 w1 ) { #ifdef DEBUG DebugMsg( DEBUG_UNKNOWN, "RDP_Unknown\r\n" ); DebugMsg( DEBUG_UNKNOWN, "\tUnknown RDP opcode %02X\r\n", _SHIFTR( w0, 24, 8 ) ); #endif } void RDP_NoOp( u32 w0, u32 w1 ) { gDPNoOp(); } void RDP_SetCImg( u32 w0, u32 w1 ) { gDPSetColorImage( _SHIFTR( w0, 21, 3 ), // fmt _SHIFTR( w0, 19, 2 ), // siz _SHIFTR( w0, 0, 12 ) + 1, // width w1 ); // img } void RDP_SetZImg( u32 w0, u32 w1 ) { gDPSetDepthImage( w1 ); // img } void RDP_SetTImg( u32 w0, u32 w1 ) { gDPSetTextureImage( _SHIFTR( w0, 21, 3), // fmt _SHIFTR( w0, 19, 2 ), // siz _SHIFTR( w0, 0, 12 ) + 1, // width w1 ); // img } void RDP_SetCombine( u32 w0, u32 w1 ) { gDPSetCombine( _SHIFTR( w0, 0, 24 ), // muxs0 w1 ); // muxs1 } void RDP_SetEnvColor( u32 w0, u32 w1 ) { gDPSetEnvColor( _SHIFTR( w1, 24, 8 ), // r _SHIFTR( w1, 16, 8 ), // g _SHIFTR( w1, 8, 8 ), // b _SHIFTR( w1, 0, 8 ) ); // a } void RDP_SetPrimColor( u32 w0, u32 w1 ) { gDPSetPrimColor( _SHIFTR( w0, 8, 5 ), // m _SHIFTR( w0, 0, 8 ), // l _SHIFTR( w1, 24, 8 ), // r _SHIFTR( w1, 16, 8 ), // g _SHIFTR( w1, 8, 8 ), // b _SHIFTR( w1, 0, 8 ) ); // a } void RDP_SetBlendColor( u32 w0, u32 w1 ) { gDPSetBlendColor( _SHIFTR( w1, 24, 8 ), // r _SHIFTR( w1, 16, 8 ), // g _SHIFTR( w1, 8, 8 ), // b _SHIFTR( w1, 0, 8 ) ); // a } void RDP_SetFogColor( u32 w0, u32 w1 ) { gDPSetFogColor( _SHIFTR( w1, 24, 8 ), // r _SHIFTR( w1, 16, 8 ), // g _SHIFTR( w1, 8, 8 ), // b _SHIFTR( w1, 0, 8 ) ); // a } void RDP_SetFillColor( u32 w0, u32 w1 ) { gDPSetFillColor( w1 ); } void RDP_FillRect( u32 w0, u32 w1 ) { const u32 ulx = _SHIFTR(w1, 14, 10); const u32 uly = _SHIFTR(w1, 2, 10); const u32 lrx = _SHIFTR(w0, 14, 10); const u32 lry = _SHIFTR(w0, 2, 10); if (lrx < ulx || lry < uly) return; gDPFillRectangle(ulx, uly, lrx, lry); } void RDP_SetTile( u32 w0, u32 w1 ) { gDPSetTile( _SHIFTR( w0, 21, 3 ), // fmt _SHIFTR( w0, 19, 2 ), // siz _SHIFTR( w0, 9, 9 ), // line _SHIFTR( w0, 0, 9 ), // tmem _SHIFTR( w1, 24, 3 ), // tile _SHIFTR( w1, 20, 4 ), // palette _SHIFTR( w1, 18, 2 ), // cmt _SHIFTR( w1, 8, 2 ), // cms _SHIFTR( w1, 14, 4 ), // maskt _SHIFTR( w1, 4, 4 ), // masks _SHIFTR( w1, 10, 4 ), // shiftt _SHIFTR( w1, 0, 4 ) ); // shifts } void RDP_LoadTile( u32 w0, u32 w1 ) { gDPLoadTile( _SHIFTR( w1, 24, 3 ), // tile _SHIFTR( w0, 12, 12 ), // uls _SHIFTR( w0, 0, 12 ), // ult _SHIFTR( w1, 12, 12 ), // lrs _SHIFTR( w1, 0, 12 ) ); // lrt } static u32 lbw0, lbw1; void RDP_LoadBlock( u32 w0, u32 w1 ) { lbw0 = w0; lbw1 = w1; gDPLoadBlock( _SHIFTR( w1, 24, 3 ), // tile _SHIFTR( w0, 12, 12 ), // uls _SHIFTR( w0, 0, 12 ), // ult _SHIFTR( w1, 12, 12 ), // lrs _SHIFTR( w1, 0, 12 ) ); // dxt } void RDP_RepeatLastLoadBlock() { RDP_LoadBlock(lbw0, lbw1); } void RDP_SetTileSize( u32 w0, u32 w1 ) { gDPSetTileSize( _SHIFTR( w1, 24, 3 ), // tile _SHIFTR( w0, 12, 12 ), // uls _SHIFTR( w0, 0, 12 ), // ult _SHIFTR( w1, 12, 12 ), // lrs _SHIFTR( w1, 0, 12 ) ); // lrt } void RDP_LoadTLUT( u32 w0, u32 w1 ) { gDPLoadTLUT( _SHIFTR( w1, 24, 3 ), // tile _SHIFTR( w0, 12, 12 ), // uls _SHIFTR( w0, 0, 12 ), // ult _SHIFTR( w1, 12, 12 ), // lrs _SHIFTR( w1, 0, 12 ) ); // lrt } void RDP_SetOtherMode( u32 w0, u32 w1 ) { gDPSetOtherMode( _SHIFTR( w0, 0, 24 ), // mode0 w1 ); // mode1 } void RDP_SetPrimDepth( u32 w0, u32 w1 ) { gDPSetPrimDepth( _SHIFTR( w1, 16, 16 ), // z _SHIFTR( w1, 0, 16 ) ); // dz } void RDP_SetScissor( u32 w0, u32 w1 ) { gDPSetScissor( _SHIFTR( w1, 24, 2 ), // mode _FIXED2FLOAT( _SHIFTR( w0, 12, 12 ), 2 ), // ulx _FIXED2FLOAT( _SHIFTR( w0, 0, 12 ), 2 ), // uly _FIXED2FLOAT( _SHIFTR( w1, 12, 12 ), 2 ), // lrx _FIXED2FLOAT( _SHIFTR( w1, 0, 12 ), 2 ) ); // lry } void RDP_SetConvert( u32 w0, u32 w1 ) { gDPSetConvert( _SHIFTR( w0, 13, 9 ), // k0 _SHIFTR( w0, 4, 9 ), // k1 _SHIFTL( w0, 5, 4 ) | _SHIFTR( w1, 27, 5 ), // k2 _SHIFTR( w1, 18, 9 ), // k3 _SHIFTR( w1, 9, 9 ), // k4 _SHIFTR( w1, 0, 9 ) ); // k5 } void RDP_SetKeyR( u32 w0, u32 w1 ) { gDPSetKeyR( _SHIFTR( w1, 8, 8 ), // cR _SHIFTR( w1, 0, 8 ), // sR _SHIFTR( w1, 16, 12 ) ); // wR } void RDP_SetKeyGB( u32 w0, u32 w1 ) { gDPSetKeyGB( _SHIFTR( w1, 24, 8 ), // cG _SHIFTR( w1, 16, 8 ), // sG _SHIFTR( w0, 12, 12 ), // wG _SHIFTR( w1, 8, 8 ), // cB _SHIFTR( w1, 0, 8 ), // SB _SHIFTR( w0, 0, 12 ) ); // wB } void RDP_FullSync( u32 w0, u32 w1 ) { gDPFullSync(); } void RDP_TileSync( u32 w0, u32 w1 ) { gDPTileSync(); } void RDP_PipeSync( u32 w0, u32 w1 ) { gDPPipeSync(); } void RDP_LoadSync( u32 w0, u32 w1 ) { gDPLoadSync(); } static void _getTexRectParams(u32 & w2, u32 & w3) { if (__RSP.bLLE) { w2 = RDP.w2; w3 = RDP.w3; return; } enum { gspTexRect, gdpTexRect, halfTexRect } texRectMode = gdpTexRect; const u32 cmd1 = (*(u32*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi] + 0]) >> 24; const u32 cmd2 = (*(u32*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi] + 8]) >> 24; if (cmd1 == G_RDPHALF_1) { if (cmd2 == G_RDPHALF_2) texRectMode = gspTexRect; } else if (cmd1 == 0xB3) { if (cmd2 == 0xB2) texRectMode = gspTexRect; else texRectMode = halfTexRect; } else if (cmd1 == 0xF1) texRectMode = halfTexRect; switch (texRectMode) { case gspTexRect: w2 = *(u32*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi] + 4]; __RSP.PC[__RSP.PCi] += 8; w3 = *(u32*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi] + 4]; __RSP.PC[__RSP.PCi] += 8; break; case gdpTexRect: w2 = *(u32*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi] + 0]; w3 = *(u32*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi] + 4]; __RSP.PC[__RSP.PCi] += 8; break; case halfTexRect: w2 = 0; w3 = *(u32*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi] + 4]; __RSP.PC[__RSP.PCi] += 8; break; default: assert(false && "Unknown texrect mode"); } } void RDP_TexRectFlip( u32 w0, u32 w1 ) { u32 w2, w3; _getTexRectParams(w2, w3); const u32 ulx = _SHIFTR(w1, 12, 12); const u32 uly = _SHIFTR(w1, 0, 12); const u32 lrx = _SHIFTR(w0, 12, 12); const u32 lry = _SHIFTR(w0, 0, 12); if ((lrx >> 2) < (ulx >> 2) || (lry >> 2) < (uly >> 2)) return; gDPTextureRectangleFlip( _FIXED2FLOAT(ulx, 2), _FIXED2FLOAT(uly, 2), _FIXED2FLOAT(lrx, 2), _FIXED2FLOAT(lry, 2), _SHIFTR(w1, 24, 3), // tile _FIXED2FLOAT((s16)_SHIFTR(w2, 16, 16), 5), // s _FIXED2FLOAT((s16)_SHIFTR(w2, 0, 16), 5), // t _FIXED2FLOAT((s16)_SHIFTR(w3, 16, 16), 10), // dsdx _FIXED2FLOAT((s16)_SHIFTR(w3, 0, 16), 10)); // dsdy } void RDP_TexRect( u32 w0, u32 w1 ) { u32 w2, w3; _getTexRectParams(w2, w3); const u32 ulx = _SHIFTR(w1, 12, 12); const u32 uly = _SHIFTR(w1, 0, 12); const u32 lrx = _SHIFTR(w0, 12, 12); const u32 lry = _SHIFTR(w0, 0, 12); if ((lrx >> 2) < (ulx >> 2) || (lry >> 2) < (uly >> 2)) return; gDPTextureRectangle( _FIXED2FLOAT(ulx, 2), _FIXED2FLOAT(uly, 2), _FIXED2FLOAT(lrx, 2), _FIXED2FLOAT(lry, 2), _SHIFTR(w1, 24, 3), // tile _FIXED2FLOAT((s16)_SHIFTR(w2, 16, 16), 5), // s _FIXED2FLOAT((s16)_SHIFTR(w2, 0, 16), 5), // t _FIXED2FLOAT((s16)_SHIFTR(w3, 16, 16), 10), // dsdx _FIXED2FLOAT((s16)_SHIFTR(w3, 0, 16), 10)); // dsdy } void RDP_TriFill( u32 _w0, u32 _w1 ) { gDPTriFill(_w0, _w1); } void RDP_TriShade( u32 _w0, u32 _w1 ) { gDPTriShade(_w0, _w1); } void RDP_TriTxtr( u32 _w0, u32 _w1 ) { gDPTriTxtr(_w0, _w1); } void RDP_TriShadeTxtr( u32 _w0, u32 _w1 ) { gDPTriShadeTxtr(_w0, _w1); } void RDP_TriFillZ( u32 _w0, u32 _w1 ) { gDPTriFillZ(_w0, _w1); } void RDP_TriShadeZ( u32 _w0, u32 _w1 ) { gDPTriShadeZ(_w0, _w1); } void RDP_TriTxtrZ( u32 _w0, u32 _w1 ) { gDPTriTxtrZ(_w0, _w1); } void RDP_TriShadeTxtrZ( u32 _w0, u32 _w1 ) { gDPTriShadeTxtrZ(_w0, _w1); } RDPInfo __RDP; void RDP_Init() { // Initialize RDP commands to RDP_UNKNOWN for (int i = 0xC8; i <= 0xCF; i++) GBI.cmd[i] = RDP_Unknown; // Initialize RDP commands to RDP_UNKNOWN for (int i = 0xE4; i <= 0xFF; i++) GBI.cmd[i] = RDP_Unknown; // Set known GBI commands GBI.cmd[G_NOOP] = RDP_NoOp; GBI.cmd[G_SETCIMG] = RDP_SetCImg; GBI.cmd[G_SETZIMG] = RDP_SetZImg; GBI.cmd[G_SETTIMG] = RDP_SetTImg; GBI.cmd[G_SETCOMBINE] = RDP_SetCombine; GBI.cmd[G_SETENVCOLOR] = RDP_SetEnvColor; GBI.cmd[G_SETPRIMCOLOR] = RDP_SetPrimColor; GBI.cmd[G_SETBLENDCOLOR] = RDP_SetBlendColor; GBI.cmd[G_SETFOGCOLOR] = RDP_SetFogColor; GBI.cmd[G_SETFILLCOLOR] = RDP_SetFillColor; GBI.cmd[G_FILLRECT] = RDP_FillRect; GBI.cmd[G_SETTILE] = RDP_SetTile; GBI.cmd[G_LOADTILE] = RDP_LoadTile; GBI.cmd[G_LOADBLOCK] = RDP_LoadBlock; GBI.cmd[G_SETTILESIZE] = RDP_SetTileSize; GBI.cmd[G_LOADTLUT] = RDP_LoadTLUT; GBI.cmd[G_RDPSETOTHERMODE] = RDP_SetOtherMode; GBI.cmd[G_SETPRIMDEPTH] = RDP_SetPrimDepth; GBI.cmd[G_SETSCISSOR] = RDP_SetScissor; GBI.cmd[G_SETCONVERT] = RDP_SetConvert; GBI.cmd[G_SETKEYR] = RDP_SetKeyR; GBI.cmd[G_SETKEYGB] = RDP_SetKeyGB; GBI.cmd[G_RDPFULLSYNC] = RDP_FullSync; GBI.cmd[G_RDPTILESYNC] = RDP_TileSync; GBI.cmd[G_RDPPIPESYNC] = RDP_PipeSync; GBI.cmd[G_RDPLOADSYNC] = RDP_LoadSync; GBI.cmd[G_TEXRECTFLIP] = RDP_TexRectFlip; GBI.cmd[G_TEXRECT] = RDP_TexRect; RDP.w2 = RDP.w3 = 0; __RDP.cmd_ptr = __RDP.cmd_cur = 0; } static GBIFunc LLEcmd[64] = { /* 0x00 */ RDP_NoOp, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_TriFill, RDP_TriFillZ, RDP_TriTxtr, RDP_TriTxtrZ, RDP_TriShade, RDP_TriShadeZ, RDP_TriShadeTxtr, RDP_TriShadeTxtrZ, /* 0x10 */ RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, /* 0x20 */ RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_Unknown, RDP_TexRect, RDP_TexRectFlip, RDP_LoadSync, RDP_PipeSync, RDP_TileSync, RDP_FullSync, RDP_SetKeyGB, RDP_SetKeyR, RDP_SetConvert, RDP_SetScissor, RDP_SetPrimDepth, RDP_SetOtherMode, /* 0x30 */ RDP_LoadTLUT, RDP_Unknown, RDP_SetTileSize, RDP_LoadBlock, RDP_LoadTile, RDP_SetTile, RDP_FillRect, RDP_SetFillColor, RDP_SetFogColor, RDP_SetBlendColor, RDP_SetPrimColor, RDP_SetEnvColor, RDP_SetCombine, RDP_SetTImg, RDP_SetZImg, RDP_SetCImg }; static const u32 CmdLength[64] = { 8, // 0x00, No Op 8, // 0x01, ??? 8, // 0x02, ??? 8, // 0x03, ??? 8, // 0x04, ??? 8, // 0x05, ??? 8, // 0x06, ??? 8, // 0x07, ??? 32, // 0x08, Non-Shaded Triangle 32+16, // 0x09, Non-Shaded, Z-Buffered Triangle 32+64, // 0x0a, Textured Triangle 32+64+16, // 0x0b, Textured, Z-Buffered Triangle 32+64, // 0x0c, Shaded Triangle 32+64+16, // 0x0d, Shaded, Z-Buffered Triangle 32+64+64, // 0x0e, Shaded+Textured Triangle 32+64+64+16,// 0x0f, Shaded+Textured, Z-Buffered Triangle 8, // 0x10, ??? 8, // 0x11, ??? 8, // 0x12, ??? 8, // 0x13, ??? 8, // 0x14, ??? 8, // 0x15, ??? 8, // 0x16, ??? 8, // 0x17, ??? 8, // 0x18, ??? 8, // 0x19, ??? 8, // 0x1a, ??? 8, // 0x1b, ??? 8, // 0x1c, ??? 8, // 0x1d, ??? 8, // 0x1e, ??? 8, // 0x1f, ??? 8, // 0x20, ??? 8, // 0x21, ??? 8, // 0x22, ??? 8, // 0x23, ??? 16, // 0x24, Texture_Rectangle 16, // 0x25, Texture_Rectangle_Flip 8, // 0x26, Sync_Load 8, // 0x27, Sync_Pipe 8, // 0x28, Sync_Tile 8, // 0x29, Sync_Full 8, // 0x2a, Set_Key_GB 8, // 0x2b, Set_Key_R 8, // 0x2c, Set_Convert 8, // 0x2d, Set_Scissor 8, // 0x2e, Set_Prim_Depth 8, // 0x2f, Set_Other_Modes 8, // 0x30, Load_TLUT 8, // 0x31, ??? 8, // 0x32, Set_Tile_Size 8, // 0x33, Load_Block 8, // 0x34, Load_Tile 8, // 0x35, Set_Tile 8, // 0x36, Fill_Rectangle 8, // 0x37, Set_Fill_Color 8, // 0x38, Set_Fog_Color 8, // 0x39, Set_Blend_Color 8, // 0x3a, Set_Prim_Color 8, // 0x3b, Set_Env_Color 8, // 0x3c, Set_Combine 8, // 0x3d, Set_Texture_Image 8, // 0x3e, Set_Mask_Image 8 // 0x3f, Set_Color_Image }; void RDP_Half_1( u32 _c ) { u32 w0 = 0, w1 = _c; u32 cmd = _SHIFTR( _c, 24, 8 ); if (cmd >= 0xc8 && cmd <=0xcf) {//triangle command DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPHalf_1 LLE Triangle\n"); __RDP.cmd_ptr = 0; __RDP.cmd_cur = 0; do { __RDP.cmd_data[__RDP.cmd_ptr++] = w1; __RSP_CheckDLCounter(); w0 = *(u32*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi]]; w1 = *(u32*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi] + 4]; __RSP.cmd = _SHIFTR( w0, 24, 8 ); DebugRSPState( RSP.PCi, __RSP.PC[__RSP.PCi], _SHIFTR( w0, 24, 8 ), w0, w1 ); DebugMsg( DEBUG_LOW | DEBUG_HANDLED, "0x%08lX: CMD=0x%02lX W0=0x%08lX W1=0x%08lX\n", __RSP.PC[__RSP.PCi], _SHIFTR( w0, 24, 8 ), w0, w1 ); __RSP.PC[__RSP.PCi] += 8; // __RSP.nextCmd = _SHIFTR( *(u32*)&gfx_info.RDRAM[__RSP.PC[__RSP.PCi]], 24, 8 ); } while (__RSP.cmd != 0xb3); __RDP.cmd_data[__RDP.cmd_ptr++] = w1; __RSP.cmd = (__RDP.cmd_data[__RDP.cmd_cur] >> 24) & 0x3f; w0 = __RDP.cmd_data[__RDP.cmd_cur+0]; w1 = __RDP.cmd_data[__RDP.cmd_cur+1]; LLEcmd[__RSP.cmd](w0, w1); } else { DebugMsg( DEBUG_HIGH | DEBUG_IGNORED, "gDPHalf_1()\n" ); } } inline u32 READ_RDP_DATA(u32 address) { if ((*(u32*)gfx_info.DPC_STATUS_REG) & 0x1) // XBUS_DMEM_DMA enabled return gfx_info.DMEM[(address & 0xfff)>>2]; return gfx_info.RDRAM[address>>2]; } void RDP_ProcessRDPList() { if (ConfigOpen || video().isResizeWindow()) { (*(u32*)gfx_info.DPC_STATUS_REG) &= ~0x0002; gfx_info.DPC_START_REG = gfx_info.DPC_CURRENT_REG = gfx_info.DPC_END_REG; gDPFullSync(); return; } const u32 length = gfx_info.DPC_END_REG - gfx_info.DPC_CURRENT_REG; (*(u32*)gfx_info.DPC_STATUS_REG) &= ~0x0002; if (gfx_info.DPC_END_REG <= gfx_info.DPC_CURRENT_REG) return; __RSP.bLLE = true; // load command data for (u32 i = 0; i < length; i += 4) { __RDP.cmd_data[__RDP.cmd_ptr] = READ_RDP_DATA(*gfx_info.DPC_CURRENT_REG + i); __RDP.cmd_ptr = (__RDP.cmd_ptr + 1) & maxCMDMask; } bool setZero = true; while (__RDP.cmd_cur != __RDP.cmd_ptr) { u32 cmd = (__RDP.cmd_data[__RDP.cmd_cur] >> 24) & 0x3f; if ((((__RDP.cmd_ptr - __RDP.cmd_cur)&maxCMDMask) * 4) < CmdLength[cmd]) { setZero = false; break; } if (__RDP.cmd_cur + CmdLength[cmd] / 4 > MAXCMD) ::memcpy(__RDP.cmd_data + MAXCMD, __RDP.cmd_data, CmdLength[cmd] - (MAXCMD - __RDP.cmd_cur) * 4); // execute the command u32 w0 = __RDP.cmd_data[__RDP.cmd_cur+0]; u32 w1 = __RDP.cmd_data[__RDP.cmd_cur+1]; RDP.w2 = __RDP.cmd_data[__RDP.cmd_cur+2]; RDP.w3 = __RDP.cmd_data[__RDP.cmd_cur + 3]; __RSP.cmd = cmd; LLEcmd[cmd](w0, w1); __RDP.cmd_cur = (__RDP.cmd_cur + CmdLength[cmd] / 4) & maxCMDMask; } if (setZero) { __RDP.cmd_ptr = 0; __RDP.cmd_cur = 0; } __RSP.bLLE = false; gDP.changed |= CHANGED_COLORBUFFER; gDP.changed &= ~CHANGED_CPU_FB_WRITE; gfx_info.DPC_START_REG = gfx_info.DPC_CURRENT_REG = gfx_info.DPC_END_REG; } mupen64plus-core/src/r4300/hacktarux_dynarec/assemble.c000664 001750 001750 00000021671 12655644434 024053 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - assemble.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include "assemble.h" #include "api/m64p_types.h" #include "api/callbacks.h" #include "osal/preproc.h" #include "r4300/recomph.h" #include "r4300/recomp.h" #include "r4300/r4300.h" /* (64-bit x86_64 only) * Placeholder for RIP-relative offsets is maximum 32-bit signed value. * So, if recompiled code is run without running passe2() first, it will * cause an exception. */ #define REL_PLACEHOLDER 0x7fffffff /* (64-bit x86_64 only) */ typedef struct _riprelative_table { unsigned int pc_addr; /* index in bytes from start of x86_64 code block to the displacement value to write */ unsigned int extra_bytes; /* number of remaining instruction bytes (immediate data) after 4-byte displacement */ unsigned char *global_dst; /* 64-bit pointer to the data object */ } riprelative_table; typedef struct _jump_table { unsigned int mi_addr; unsigned int pc_addr; #ifdef __x86_64__ unsigned int absolute64; #endif } jump_table; #ifdef __x86_64__ #define JUMP_TABLE_SIZE 512 #else #define JUMP_TABLE_SIZE 1000 #endif static jump_table *jumps_table = NULL; static int jumps_number, max_jumps_number; static riprelative_table *riprel_table = NULL; static int riprel_number = 0, max_riprel_number = 0; void init_assembler(void *block_jumps_table, int block_jumps_number, void *block_riprel_table, int block_riprel_number) { if (block_jumps_table) { jumps_table = (jump_table *) block_jumps_table; jumps_number = block_jumps_number; #ifdef __x86_64__ if (jumps_number <= JUMP_TABLE_SIZE) max_jumps_number = JUMP_TABLE_SIZE; else max_jumps_number = (jumps_number + (JUMP_TABLE_SIZE-1)) & 0xfffffe00; #else max_jumps_number = jumps_number; #endif } else { jumps_table = (jump_table *) malloc(JUMP_TABLE_SIZE * sizeof(jump_table)); jumps_number = 0; max_jumps_number = JUMP_TABLE_SIZE; } #ifdef __x86_64__ if (block_riprel_table) { riprel_table = block_riprel_table; riprel_number = block_riprel_number; if (riprel_number <= JUMP_TABLE_SIZE) max_riprel_number = JUMP_TABLE_SIZE; else max_riprel_number = (riprel_number + (JUMP_TABLE_SIZE-1)) & 0xfffffe00; } else { riprel_table = malloc(JUMP_TABLE_SIZE * sizeof(riprelative_table)); riprel_number = 0; max_riprel_number = JUMP_TABLE_SIZE; } #endif } void free_assembler(void **block_jumps_table, int *block_jumps_number, void **block_riprel_table, int *block_riprel_number) { *block_jumps_table = jumps_table; *block_jumps_number = jumps_number; *block_riprel_table = NULL; /* RIP-relative addressing is only for x86-64 */ #ifdef __x86_64__ *block_riprel_table = riprel_table; #endif *block_riprel_number = 0; } void add_jump(unsigned int pc_addr, unsigned int mi_addr, unsigned int absolute64) { if (jumps_number == max_jumps_number) { jump_table *new_ptr = NULL; max_jumps_number += JUMP_TABLE_SIZE; new_ptr = (jump_table *) realloc(jumps_table, max_jumps_number*sizeof(jump_table)); if (!new_ptr) return; jumps_table = new_ptr; } jumps_table[jumps_number].pc_addr = pc_addr; jumps_table[jumps_number].mi_addr = mi_addr; #ifdef __x86_64__ jumps_table[jumps_number].absolute64 = absolute64; #endif jumps_number++; } void passe2(precomp_instr *dest, int start, int end, precomp_block *block) { unsigned int real_code_length; int i; build_wrappers(dest, start, end, block); #ifdef __x86_64__ /* First, fix up all the jumps. This involves a table lookup to find the offset into the block of x86_64 code for * for start of a recompiled r4300i instruction corresponding to the given jump destination address in the N64 * address space. Next, the relative offset between this destination and the location of the jump instruction is * computed and stored in memory, so that the jump will branch to the right place in the recompiled code. */ for (i = 0; i < jumps_number; i++) { precomp_instr *jump_instr = dest + ((jumps_table[i].mi_addr - dest[0].addr) / 4); unsigned int jmp_offset_loc = jumps_table[i].pc_addr; unsigned char *addr_dest = NULL; /* calculate the destination address to jump to */ if (jump_instr->reg_cache_infos.need_map) addr_dest = jump_instr->reg_cache_infos.jump_wrapper; else addr_dest = block->code + jump_instr->local_addr; /* write either a 32-bit IP-relative offset or a 64-bit absolute address */ if (jumps_table[i].absolute64) *((uint64_t *) (block->code + jmp_offset_loc)) = (uint64_t)addr_dest; else { long jump_rel_offset = (long) (addr_dest - (block->code + jmp_offset_loc + 4)); *((int *) (block->code + jmp_offset_loc)) = (int) jump_rel_offset; if (jump_rel_offset >= 0x7fffffffLL || jump_rel_offset < -0x80000000LL) { DebugMessage(M64MSG_ERROR, "assembler pass2 error: offset too big for relative jump from %p to %p", (block->code + jmp_offset_loc + 4), addr_dest); #if !defined(_MSC_VER) asm(" int $3; "); #endif } } } /* Next, fix up all of the RIP-relative memory accesses. This is unique to the x86_64 architecture, because * the 32-bit absolute displacement addressing mode is not available (and there's no 64-bit absolute displacement * mode either). */ for (i = 0; i < riprel_number; i++) { unsigned char *rel_offset_ptr = block->code + riprel_table[i].pc_addr; long rip_rel_offset = (long) (riprel_table[i].global_dst - (rel_offset_ptr + 4 + riprel_table[i].extra_bytes)); if (rip_rel_offset >= 0x7fffffffLL || rip_rel_offset < -0x80000000LL) { DebugMessage(M64MSG_ERROR, "assembler pass2 error: offset too big between mem target: %p and code position: %p", riprel_table[i].global_dst, rel_offset_ptr); #if !defined(_MSC_VER) asm(" int $3; "); #endif } *((int *) rel_offset_ptr) = (int) rip_rel_offset; } #else real_code_length = code_length; for (i=0; i < jumps_number; i++) { code_length = jumps_table[i].pc_addr; if (dest[(jumps_table[i].mi_addr - dest[0].addr)/4].reg_cache_infos.need_map) { unsigned int addr_dest = (unsigned int)dest[(jumps_table[i].mi_addr - dest[0].addr)/4].reg_cache_infos.jump_wrapper; put32(addr_dest-((unsigned int)block->code+code_length)-4); } else { unsigned int addr_dest = dest[(jumps_table[i].mi_addr - dest[0].addr)/4].local_addr; put32(addr_dest-code_length-4); } } code_length = real_code_length; #endif } static unsigned int g_jump_start8 = 0; static unsigned int g_jump_start32 = 0; void jump_start_rel8(void) { g_jump_start8 = code_length; } void jump_start_rel32(void) { g_jump_start32 = code_length; } void jump_end_rel8(void) { unsigned int jump_end = code_length; int jump_vec = jump_end - g_jump_start8; if (jump_vec > 127 || jump_vec < -128) { DebugMessage(M64MSG_ERROR, "8-bit relative jump too long! From %x to %x", g_jump_start8, jump_end); #if !defined(_MSC_VER) asm(" int $3; "); #endif } code_length = g_jump_start8 - 1; put8(jump_vec); code_length = jump_end; } void jump_end_rel32(void) { unsigned int jump_end = code_length; int jump_vec = jump_end - g_jump_start32; code_length = g_jump_start32 - 4; put32(jump_vec); code_length = jump_end; } mupen64plus-video-gliden64/src/wst.h000664 001750 001750 00000001304 12655644434 020412 0ustar00sergiosergio000000 000000 #ifndef WST_H #define WST_H #ifdef ANDROID static void gln_wcscat(wchar_t* destination, const wchar_t* source) { const u32 bufSize = 512; char cbuf[bufSize]; wcstombs(cbuf, destination, bufSize); std::string dest(cbuf); wcstombs(cbuf, source, bufSize); dest.append(cbuf); mbstowcs(destination, dest.c_str(), PLUGIN_PATH_SIZE); } class dummyWString { public: dummyWString(const char * _str) { wchar_t buf[512]; mbstowcs(buf, _str, 512); _wstr.assign(buf); } const wchar_t * c_str() const { return _wstr.c_str(); } private: std::wstring _wstr; }; #define wst(A) dummyWString(A).c_str() #else // ANDROID #define gln_wcscat wcscat #define wst(A) L##A #endif // ANDROID #endif // WST_H mupen64plus-video-gliden64/src/GLideNHQ/000700 001750 001750 00000000000 12656647145 020750 5ustar00sergiosergio000000 000000 mupen64plus-rsp-hle/src/000700 001750 001750 00000000000 12656647145 016247 5ustar00sergiosergio000000 000000 mupen64plus-core/tools/regtests/regression-video.py000755 001750 001750 00000055032 12655644434 023713 0ustar00sergiosergio000000 000000 #!/usr/bin/env python #/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # * Mupen64plus - regression-video.py * # * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * # * Copyright (C) 2008-2012 Richard Goedeken * # * * # * This program is free software; you can redistribute it and/or modify * # * it under the terms of the GNU General Public License as published by * # * the Free Software Foundation; either version 2 of the License, or * # * (at your option) any later version. * # * * # * This program is distributed in the hope that it will be useful, * # * but WITHOUT ANY WARRANTY; without even the implied warranty of * # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * # * GNU General Public License for more details. * # * * # * You should have received a copy of the GNU General Public License * # * along with this program; if not, write to the * # * Free Software Foundation, Inc., * # * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ from optparse import OptionParser from threading import Thread from datetime import date import subprocess import commands import shutil import stat import sys import os # set global report string report = "Mupen64Plus Regression Test report\n----------------------------------\n" #****************************************************************************** # main functions # def main(rootdir, cfgfile, nobuild, noemail): global report # set up child directory paths srcdir = os.path.join(rootdir, "source") shotdir = os.path.join(rootdir, "current") refdir = os.path.join(rootdir, "reference") archivedir = os.path.join(rootdir, "archive") # run the test procedure tester = RegTester(rootdir, srcdir, shotdir) rval = 0 while True: # Step 1: load the test config file if not tester.LoadConfig(cfgfile): rval = 1 break # Step 2: check out from Mercurial if not nobuild: if not tester.CheckoutSource(srcdir): rval = 2 break # Step 3: run test builds if not nobuild: for modname in tester.modulesAndParams: module = tester.modulesAndParams[modname] if "testbuilds" not in module: continue modurl = module["url"] modfilename = modurl.split('/')[-1] testlist = [ name.strip() for name in module["testbuilds"].split(',') ] makeparams = [ params.strip() for params in module["testbuildparams"].split(',') ] if len(testlist) != len(makeparams): report += "Config file error for test builds in %s. Build name list and makefile parameter list have different lengths.\n" % modname testbuilds = min(len(testlist), len(makeparams)) for i in range(testbuilds): buildname = testlist[i] buildmake = makeparams[i] BuildSource(srcdir, modfilename, modname, buildname, buildmake, module["outputfiles"], True) # Step 4: build the binary for the video regression test if not nobuild: for modname in tester.modulesAndParams: module = tester.modulesAndParams[modname] modurl = module["url"] modfilename = modurl.split('/')[-1] videobuild = module["videobuild"] videomake = module["videobuildparams"] if not BuildSource(srcdir, modfilename, modname, videobuild, videomake, module["outputfiles"], False): rval = 3 break if rval != 0: break # Step 5: run the tests, check the results if not tester.RunTests(): rval = 4 break if not tester.CheckResults(refdir): rval = 5 break # test procedure is finished break # Step 6: send email report and archive the results if not noemail: if not tester.SendReport(): rval = 6 if not tester.ArchiveResults(archivedir): rval = 7 # all done with test process return rval #****************************************************************************** # Checkout & build functions # def BuildSource(srcdir, moddir, modname, buildname, buildmake, outputfiles, istest): global report makepath = os.path.join(srcdir, moddir, "projects", "unix") # print build report message and clear counters testbuildcommand = "make -C %s %s" % (makepath, buildmake) if istest: report += "Running %s test build \"%s\"\n" % (modname, buildname) else: report += "Building %s \"%s\" for video test\n" % (modname, buildname) warnings = 0 errors = 0 # run make and capture the output output = commands.getoutput(testbuildcommand) makelines = output.split("\n") # print warnings and errors for line in makelines: if "error:" in line: report += " " + line + "\n" errors += 1 if "warning:" in line: report += " " + line + "\n" warnings += 1 report += "%i errors. %i warnings.\n" % (errors, warnings) if errors > 0 and not istest: return False # check for output files for filename in outputfiles.split(','): if not os.path.exists(os.path.join(makepath, filename)): report += "Build failed: '%s' not found\n" % filename errors += 1 if errors > 0 and not istest: return False # clean up if this was a test if istest: os.system("make -C %s clean" % makepath) # if this wasn't a test, then copy our output files and data files if not istest: for filename in outputfiles.split(','): shutil.move(os.path.join(makepath, filename), srcdir) datapath = os.path.join(srcdir, moddir, "data") if os.path.isdir(datapath): copytree(datapath, os.path.join(srcdir, "data")) # build was successful! return True #****************************************************************************** # Test execution classes # class RegTester: def __init__(self, rootdir, bindir, screenshotdir): self.rootdir = rootdir self.bindir = bindir self.screenshotdir = screenshotdir self.generalParams = { } self.gamesAndParams = { } self.modulesAndParams = { } self.videoplugins = [ "mupen64plus-video-rice.so" ] self.thisdate = str(date.today()) def LoadConfig(self, filename): global report # read the config file report += "\nLoading regression test configuration.\n" try: cfgfile = open(os.path.join(self.rootdir, filename), "r") cfglines = cfgfile.read().split("\n") cfgfile.close() except Exception, e: report += "Error in RegTestConfigParser::LoadConfig(): %s" % e return False # parse the file GameFilename = None ModuleName = None for line in cfglines: # strip leading and trailing whitespace line = line.strip() # test for comment if len(line) == 0 or line[0] == '#': continue # test for new game filename if line[0] == '[' and line [-1] == ']': GameFilename = line[1:-1] if GameFilename in self.gamesAndParams: report += " Warning: Config file '%s' contains duplicate game entry '%s'\n" % (filename, GameFilename) else: self.gamesAndParams[GameFilename] = { } continue # test for new source module build if line[0] == '{' and line [-1] == '}': ModuleName = line[1:-1] if ModuleName in self.modulesAndParams: report += " Warning: Config file '%s' contains duplicate source module '%s'\n" % (filename, ModuleName) else: self.modulesAndParams[ModuleName] = { } continue # print warning and continue if it's not a (key = value) pair pivot = line.find('=') if pivot == -1: report += " Warning: Config file '%s' contains unrecognized line: '%s'\n" % (filename, line) continue # parse key, value key = line[:pivot].strip().lower() value = line[pivot+1:].strip() if ModuleName is None: paramDict = self.generalParams elif GameFilename is None: paramDict = self.modulesAndParams[ModuleName] else: paramDict = self.gamesAndParams[GameFilename] if key in paramDict: report += " Warning: duplicate key '%s'\n" % key continue paramDict[key] = value # check for required parameters if "rompath" not in self.generalParams: report += " Error: rompath is not given in config file\n" return False # config is loaded return True def CheckoutSource(self, srcdir): global report # remove any current source directory if not deltree(srcdir): return False os.mkdir(srcdir) os.mkdir(os.path.join(srcdir, "data")) # loop through all of the source modules for modname in self.modulesAndParams: module = self.modulesAndParams[modname] if "url" not in module: report += "Error: no Hg repository URL for module %s\n\n" % modname return False modurl = module["url"] modfilename = modurl.split("/")[-1] # call Hg to checkout Mupen64Plus source module output = commands.getoutput("hg clone --cwd %s %s" % (srcdir, modurl)) # parse the output lastline = output.split("\n")[-1] if "0 files unresolved" not in lastline: report += "Hg Error: %s\n\n" % lastline return False # get the revision info RevFound = False output = commands.getoutput("hg tip -R %s" % os.path.join(srcdir, modfilename)) for line in output.split('\n'): words = line.split() if len(words) == 2 and words[0] == 'changeset:': report += "Hg Checkout %s: changeset %s\n" % (modfilename, words[1]) RevFound = True if not RevFound: report += "Hg Error: couldn't find revision information\n\n" return False return True def RunTests(self): global report rompath = self.generalParams["rompath"] if not os.path.exists(rompath): report += " Error: ROM directory '%s' does not exist!\n" % rompath return False # Remove any current screenshot directory if not deltree(self.screenshotdir): return False # Data initialization and start message os.mkdir(self.screenshotdir) for plugin in self.videoplugins: videoname = plugin[:plugin.find('.')] os.mkdir(os.path.join(self.screenshotdir, videoname)) report += "\nRunning regression tests on %i games.\n" % len(self.gamesAndParams) # loop over each game filename given in regtest config file for GameFilename in self.gamesAndParams: GameParams = self.gamesAndParams[GameFilename] # if no screenshots parameter given for this game then skip it if "screenshots" not in GameParams: report += " Warning: no screenshots taken for game '%s'\n" % GameFilename continue # make a list of screenshots and check it shotlist = [ str(int(framenum.strip())) for framenum in GameParams["screenshots"].split(',') ] if len(shotlist) < 1 or (len(shotlist) == 1 and shotlist[0] == '0'): report += " Warning: invalid screenshot list for game '%s'\n" % GameFilename continue # run a test for each video plugin for plugin in self.videoplugins: videoname = plugin[:plugin.find('.')] # check if this plugin should be skipped if "skipvideo" in GameParams: skipit = False skiplist = [ name.strip() for name in GameParams["skipvideo"].split(',') ] for skiptag in skiplist: if skiptag.lower() in plugin.lower(): skipit = True if skipit: continue # construct the command line exepath = os.path.join(self.bindir, "mupen64plus") exeparms = [ "--corelib", os.path.join(self.bindir, "libmupen64plus.so.2") ] exeparms += [ "--testshots", ",".join(shotlist) ] exeparms += [ "--sshotdir", os.path.join(self.screenshotdir, videoname) ] exeparms += [ "--plugindir", self.bindir ] exeparms += [ "--datadir", os.path.join(self.bindir, "data") ] myconfig = os.path.join(self.rootdir, "config") exeparms += [ "--configdir", myconfig ] exeparms += [ "--gfx", plugin ] exeparms += [ "--emumode", "2" ] exeparms += [ os.path.join(rompath, GameFilename) ] # run it, but if it takes too long print an error and kill it testrun = RegTestRunner(exepath, exeparms) testrun.start() testrun.join(60.0) if testrun.isAlive(): report += " Error: Test run timed out after 60 seconds: '%s'\n" % " ".join(exeparms) os.kill(testrun.pid, 9) testrun.join(10.0) # all tests have been run return True def CheckResults(self, refdir): global report # print message warnings = 0 errors = 0 report += "\nChecking regression test results\n" # get lists of files in the reference folders refshots = { } if not os.path.exists(refdir): os.mkdir(refdir) for plugin in self.videoplugins: videoname = plugin[:plugin.find('.')] videodir = os.path.join(refdir, videoname) if not os.path.exists(videodir): os.mkdir(videodir) refshots[videoname] = [ ] else: refshots[videoname] = [ filename for filename in os.listdir(videodir) ] # get lists of files produced by current test runs newshots = { } for plugin in self.videoplugins: videoname = plugin[:plugin.find('.')] videodir = os.path.join(self.screenshotdir, videoname) if not os.path.exists(videodir): newshots[videoname] = [ ] else: newshots[videoname] = [ filename for filename in os.listdir(videodir) ] # make list of matching ref/test screenshots, and look for missing reference screenshots checklist = { } for plugin in self.videoplugins: videoname = plugin[:plugin.find('.')] checklist[videoname] = [ ] for filename in newshots[videoname]: if filename in refshots[videoname]: checklist[videoname] += [ filename ] else: report += " Warning: reference screenshot '%s/%s' missing. Copying from current test run\n" % (videoname, filename) shutil.copy(os.path.join(self.screenshotdir, videoname, filename), os.path.join(refdir, videoname)) warnings += 1 # look for missing test screenshots for plugin in self.videoplugins: videoname = plugin[:plugin.find('.')] for filename in refshots[videoname]: if filename not in newshots[videoname]: report += " Error: Test screenshot '%s/%s' missing.\n" % (videoname, filename) errors += 1 # do image comparisons for plugin in self.videoplugins: videoname = plugin[:plugin.find('.')] for filename in checklist[videoname]: refimage = os.path.join(refdir, videoname, filename) testimage = os.path.join(self.screenshotdir, videoname, filename) diffimage = os.path.join(self.screenshotdir, videoname, os.path.splitext(filename)[0] + "_DIFF.png") cmd = ("/usr/bin/compare", "-metric", "PSNR", refimage, testimage, diffimage) pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout similarity = pipe.read().strip() pipe.close() try: db = float(similarity) except: db = 0 if db > 60.0: os.unlink(diffimage) else: report += " Warning: test image '%s/%s' does not match reference. PSNR = %s\n" % (videoname, filename, similarity) warnings += 1 # give report and return report += "%i errors. %i warnings.\n" % (errors, warnings) return True def SendReport(self): global report # if there are no email addresses in the config file, then just we're done if "sendemail" not in self.generalParams: return True if len(self.generalParams["sendemail"]) < 5: return True # construct the email message header emailheader = "To: %s\n" % self.generalParams["sendemail"] emailheader += "From: Mupen64Plus-Tester@fascination.homelinux.net\n" emailheader += "Subject: %s Regression Test Results for Mupen64Plus\n" % self.thisdate emailheader += "Reply-to: do-not-reply@fascination.homelinux.net\n" emailheader += "Content-Type: text/plain; charset=UTF-8\n" emailheader += "Content-Transfer-Encoding: 8bit\n\n" # open a pipe to sendmail and dump our report try: pipe = subprocess.Popen(("/usr/sbin/sendmail", "-t"), stdin=subprocess.PIPE).stdin pipe.write(emailheader) pipe.write(report) pipe.close() except Exception, e: report += "Exception encountered when calling sendmail: '%s'\n" % e report += "Email header:\n%s\n" % emailheader return False return True def ArchiveResults(self, archivedir): global report # create archive dir if it doesn't exist if not os.path.exists(archivedir): os.mkdir(archivedir) # move the images into a subdirectory of 'archive' given by date subdir = os.path.join(archivedir, self.thisdate) if os.path.exists(subdir): if not deltree(subdir): return False if os.path.exists(self.screenshotdir): shutil.move(self.screenshotdir, subdir) # copy the report into the archive directory f = open(os.path.join(archivedir, "report_%s.txt" % self.thisdate), "w") f.write(report) f.close() # archival is complete return True class RegTestRunner(Thread): def __init__(self, exepath, exeparms): self.exepath = exepath self.exeparms = exeparms self.pid = 0 self.returnval = None Thread.__init__(self) def run(self): # start the process testprocess = subprocess.Popen([self.exepath] + self.exeparms) # get the PID of the new test process self.pid = testprocess.pid # wait for the test to complete self.returnval = testprocess.wait() #****************************************************************************** # Generic helper functions # def deltree(dirname): global report if not os.path.exists(dirname): return True try: for path in (os.path.join(dirname, filename) for filename in os.listdir(dirname)): if os.path.isdir(path): if not deltree(path): return False else: os.unlink(path) os.rmdir(dirname) except Exception, e: report += "Error in deltree(): %s\n" % e return False return True def copytree(srcpath, dstpath): if not os.path.isdir(srcpath) or not os.path.isdir(dstpath): return False for filename in os.listdir(srcpath): filepath = os.path.join(srcpath, filename) if os.path.isdir(filepath): subdstpath = os.path.join(dstpath, filename) os.mkdir(subdstpath) copytree(filepath, subdstpath) else: shutil.copy(filepath, dstpath) return True #****************************************************************************** # main function call for standard script execution # if __name__ == "__main__": # parse the command-line arguments parser = OptionParser() parser.add_option("-n", "--nobuild", dest="nobuild", default=False, action="store_true", help="Assume source code is present; don't check out and build") parser.add_option("-e", "--noemail", dest="noemail", default=False, action="store_true", help="don't send email or archive results") parser.add_option("-t", "--testpath", dest="testpath", help="Set root of testing directory to PATH", metavar="PATH") parser.add_option("-c", "--cfgfile", dest="cfgfile", default="daily-tests.cfg", help="Use regression test config file FILE", metavar="FILE") (opts, args) = parser.parse_args() # check test path if opts.testpath is None: # change directory to the directory containing this script and set root test path to "." scriptdir = os.path.dirname(sys.argv[0]) os.chdir(scriptdir) rootdir = "." else: rootdir = opts.testpath # call the main function rval = main(rootdir, opts.cfgfile, opts.nobuild, opts.noemail) sys.exit(rval) mupen64plus-video-gliden64/src/CommonPluginAPI.cpp000664 001750 001750 00000001470 12655644434 023075 0ustar00sergiosergio000000 000000 #ifdef OS_WINDOWS # include #else # include "winlnxdefs.h" #endif // OS_WINDOWS #include "PluginAPI.h" extern "C" { EXPORT BOOL CALL InitiateGFX (GFX_INFO Gfx_Info) { return api().InitiateGFX(Gfx_Info); } EXPORT void CALL MoveScreen (int xpos, int ypos) { api().MoveScreen(xpos, ypos); } EXPORT void CALL ProcessDList(void) { api().ProcessDList(); } EXPORT void CALL ProcessRDPList(void) { api().ProcessRDPList(); } EXPORT void CALL RomClosed (void) { api().RomClosed(); } EXPORT void CALL ShowCFB (void) { api().ShowCFB(); } EXPORT void CALL UpdateScreen (void) { api().UpdateScreen(); } EXPORT void CALL ViStatusChanged (void) { api().ViStatusChanged(); } EXPORT void CALL ViWidthChanged (void) { api().ViWidthChanged(); } EXPORT void CALL ChangeWindow(void) { api().ChangeWindow(); } } gles2n64/src/gles2N64.h000664 001750 001750 00000000624 12655644434 015531 0ustar00sergiosergio000000 000000 #ifndef GLN64_H #define GLN64_H #ifdef __cplusplus extern "C" { #endif #include "m64p_config.h" #include "stdio.h" //#define DEBUG #define PLUGIN_NAME "gles2n64" #define PLUGIN_VERSION 0x000005 #define PLUGIN_API_VERSION 0x020200 #ifdef __LIBRETRO__ // Avoid symbol clash #define renderCallback gln64RenderCallback #endif extern void (*renderCallback)(); #ifdef __cplusplus } #endif #endif gles2n64/src/N64.h000664 001750 001750 00000000514 12655644434 014572 0ustar00sergiosergio000000 000000 #ifndef N64_H #define N64_H #ifdef __cplusplus extern "C" { #endif #include "Types.h" #include "m64p_plugin.h" #define MI_INTR_SP 0x1 // Bit 1: SP intr #define MI_INTR_DP 0x20 // Bit 5: DP intr extern u64 TMEM[512]; extern u32 RDRAMSize; extern GFX_INFO gfx_info; #ifdef __cplusplus } #endif #endif mupen64plus-core/src/r4300/new_dynarec/linkage_offsets.h000664 001750 001750 00000002744 12655644434 024227 0ustar00sergiosergio000000 000000 #define LO_dynarec_local 0 #define LO_next_interupt (LO_dynarec_local + 64) #define LO_cycle_count (LO_next_interupt + 4) #define LO_last_count (LO_cycle_count + 4) #define LO_pending_exception (LO_last_count + 4) #define LO_pcaddr (LO_pending_exception + 4) #define LO_stop (LO_pcaddr + 4) #define LO_invc_ptr (LO_stop + 4) #define LO_address (LO_invc_ptr + 4) #define LO_readmem_dword (LO_address + 4) #define LO_dword (LO_readmem_dword + 8) #define LO_word (LO_dword + 8) #define LO_hword (LO_word + 4) #define LO_cpu_byte (LO_hword + 2) #define LO_cpu_byte_two (LO_cpu_byte + 1) #define LO_FCR0 (LO_cpu_byte_two + 1) #define LO_FCR31 (LO_FCR0 + 4) #define LO_reg (LO_FCR31 + 4) #define LO_hi (LO_reg + 256) #define LO_lo (LO_hi + 8) #define LO_g_cp0_regs (LO_lo + 8) #define LO_reg_cop1_simple (LO_g_cp0_regs + 128) #define LO_reg_cop1_double (LO_reg_cop1_simple + 128) #define LO_rounding_modes (LO_reg_cop1_double + 128) #define LO_branch_target (LO_rounding_modes + 16) #define LO_PC (LO_branch_target + 4) #define LO_fake_pc (LO_PC + 4) #define LO_ram_offset (LO_fake_pc + 132) #define LO_mini_ht (LO_ram_offset + 4) #define LO_restore_candidate (LO_mini_ht + 256) #define LO_memory_map (LO_restore_candidate + 512) gles2n64/src/N64.c000664 001750 001750 00000000130 12655644434 014557 0ustar00sergiosergio000000 000000 #include "N64.h" #include "Types.h" u8 *DMEM; u64 TMEM[512]; u8 *RDRAM; u32 RDRAMSize; mupen64plus-rsp-cxd4/vu/multiply.h000664 001750 001750 00000041043 12655644434 020247 0ustar00sergiosergio000000 000000 /******************************************************************************\ * Authors: Iconoclast * * Release: 2013.11.26 * * License: CC0 Public Domain Dedication * * * * To the extent possible under law, the author(s) have dedicated all copyright * * and related and neighboring rights to this software to the public domain * * worldwide. This software is distributed without any warranty. * * * * You should have received a copy of the CC0 Public Domain Dedication along * * with this software. * * If not, see . * \******************************************************************************/ #ifndef SEMIFRAC /* * acc = VS * VT; * acc = acc + 0x8000; // rounding value * acc = acc << 1; // partial value shifting * * Wrong: ACC(HI) = -((INT32)(acc) < 0) * Right: ACC(HI) = -(SEMIFRAC < 0) */ #define SEMIFRAC (VS[i]*VT[i]*2/2 + 0x8000/2) #endif #ifdef ARCH_MIN_SSE2 static INLINE void SIGNED_CLAMP_AM(short* VD) { /* typical sign-clamp of accumulator-mid (bits 31:16) */ __m128i pvs = _mm_load_si128((__m128i *)VACC_H); __m128i pvd = _mm_load_si128((__m128i *)VACC_M); __m128i dst = _mm_unpacklo_epi16(pvd, pvs); __m128i src = _mm_unpackhi_epi16(pvd, pvs); dst = _mm_packs_epi32(dst, src); _mm_store_si128((__m128i *)VD, dst); } #else static INLINE void SIGNED_CLAMP_AM(short* VD) { /* typical sign-clamp of accumulator-mid (bits 31:16) */ short hi[N], lo[N]; register int i; for (i = 0; i < N; i++) lo[i] = (VACC_H[i] < ~0); for (i = 0; i < N; i++) lo[i] |= (VACC_H[i] < 0) & !(VACC_M[i] < 0); for (i = 0; i < N; i++) hi[i] = (VACC_H[i] > 0); for (i = 0; i < N; i++) hi[i] |= (VACC_H[i] == 0) & (VACC_M[i] < 0); vector_copy(VD, VACC_M); for (i = 0; i < N; i++) VD[i] &= -(lo[i] ^ 1); for (i = 0; i < N; i++) VD[i] |= -(hi[i] ^ 0); for (i = 0; i < N; i++) VD[i] ^= 0x8000 * (hi[i] | lo[i]); } #endif static INLINE void UNSIGNED_CLAMP(short* VD) { /* sign-zero hybrid clamp of accumulator-mid (bits 31:16) */ short cond[N]; short temp[N]; register int i; SIGNED_CLAMP_AM(temp); /* no direct map in SSE, but closely based on this */ for (i = 0; i < N; i++) cond[i] = -(temp[i] > VACC_M[i]); /* VD |= -(ACC47..16 > +32767) */ for (i = 0; i < N; i++) VD[i] = temp[i] & ~(temp[i] >> 15); /* Only this clamp is unsigned. */ for (i = 0; i < N; i++) VD[i] = VD[i] | cond[i]; } static INLINE void SIGNED_CLAMP_AL(short* VD) { /* sign-clamp accumulator-low (bits 15:0) */ ALIGNED int16_t temp[N]; int16_t cond[N]; register int i; SIGNED_CLAMP_AM(temp); /* no direct map in SSE, but closely based on this */ for (i = 0; i < N; i++) cond[i] = (temp[i] != VACC_M[i]); /* result_clamped != result_raw ? */ for (i = 0; i < N; i++) temp[i] ^= 0x8000; /* clamps 0x0000:0xFFFF instead of -0x8000:+0x7FFF */ for (i = 0; i < N; i++) VD[i] = (cond[i] ? temp[i] : VACC_L[i]); } static INLINE void do_macf(short* VD, short* VS, short* VT) { int32_t product[N]; uint32_t addend[N]; register int i; for (i = 0; i < N; i++) product[i] = VS[i] * VT[i]; for (i = 0; i < N; i++) addend[i] = (product[i] << 1) & 0x00000000FFFF; for (i = 0; i < N; i++) addend[i] = (unsigned short)(VACC_L[i]) + addend[i]; for (i = 0; i < N; i++) VACC_L[i] = (short)(addend[i]); for (i = 0; i < N; i++) addend[i] = (addend[i] >> 16) + (unsigned short)(product[i] >> 15); for (i = 0; i < N; i++) addend[i] = (unsigned short)(VACC_M[i]) + addend[i]; for (i = 0; i < N; i++) VACC_M[i] = (short)(addend[i]); for (i = 0; i < N; i++) VACC_H[i] -= (product[i] < 0); for (i = 0; i < N; i++) VACC_H[i] += addend[i] >> 16; } static INLINE void do_mulf(short* VD, short* VS, short* VT) { register int i; for (i = 0; i < N; i++) VACC_L[i] = (SEMIFRAC << 1) >> 0; for (i = 0; i < N; i++) VACC_M[i] = (SEMIFRAC << 1) >> 16; for (i = 0; i < N; i++) VACC_H[i] = -((VACC_M[i] < 0) & (VS[i] != VT[i])); /* -32768 * -32768 */ #ifndef ARCH_MIN_SSE2 vector_copy(VD, VACC_M); for (i = 0; i < N; i++) VD[i] -= (VACC_M[i] < 0) & (VS[i] == VT[i]); /* ACC b 31 set, min*min */ #else SIGNED_CLAMP_AM(VD); #endif } static INLINE void do_mulu(short* VD, short* VS, short* VT) { register int i; for (i = 0; i < N; i++) VACC_L[i] = (SEMIFRAC << 1) >> 0; for (i = 0; i < N; i++) VACC_M[i] = (SEMIFRAC << 1) >> 16; for (i = 0; i < N; i++) VACC_H[i] = -((VACC_M[i] < 0) & (VS[i] != VT[i])); /* -32768 * -32768 */ #if (0) UNSIGNED_CLAMP(VD); #else vector_copy(VD, VACC_M); for (i = 0; i < N; i++) VD[i] |= (VACC_M[i] >> 15); /* VD |= -(result == 0x000080008000) */ for (i = 0; i < N; i++) VD[i] &= ~(VACC_H[i] >> 0); /* VD &= -(result >= 0x000000000000) */ #endif } static INLINE void do_madm(short* VD, short* VS, short* VT) { #ifdef ARCH_MIN_SSE2 __m128i acc_hi, acc_md, acc_lo; __m128i prod_hi, prod_lo; __m128i overflow; __m128i vs, vt; vs = _mm_loadu_si128((__m128i *)VS); vt = _mm_loadu_si128((__m128i *)VT); prod_lo = _mm_mullo_epi16(vs, vt); prod_hi = _mm_mulhi_epu16(vs, vt); vs = _mm_srai_epi16(vs, 15); vt = _mm_and_si128(vt, vs); prod_hi = _mm_sub_epi16(prod_hi, vt); /* * Writeback phase to the accumulator. * VMADM stores accumulator += the product achieved by VMUDM. */ acc_lo = _mm_loadu_si128((__m128i *)VACC_L); acc_md = _mm_loadu_si128((__m128i *)VACC_M); acc_hi = _mm_loadu_si128((__m128i *)VACC_H); acc_lo = _mm_add_epi16(acc_lo, prod_lo); _mm_storeu_si128((__m128i *)VACC_L, acc_lo); overflow = _mm_cmplt_epu16(acc_lo, prod_lo); /* overflow: (x + y < y) */ prod_hi = _mm_sub_epi16(prod_hi, overflow); acc_md = _mm_add_epi16(acc_md, prod_hi); _mm_storeu_si128((__m128i *)VACC_M, acc_md); overflow = _mm_cmplt_epu16(acc_md, prod_hi); prod_hi = _mm_srai_epi16(prod_hi, 15); acc_hi = _mm_add_epi16(acc_hi, prod_hi); acc_hi = _mm_sub_epi16(acc_hi, overflow); _mm_storeu_si128((__m128i *)VACC_H, acc_hi); vt = _mm_unpackhi_epi16(acc_md, acc_hi); vs = _mm_unpacklo_epi16(acc_md, acc_hi); vs = _mm_packs_epi32(vs, vt); _mm_storeu_si128((__m128i *)VD, vs); #else uint32_t addend[N]; register int i; for (i = 0; i < N; i++) addend[i] = (unsigned short)(VACC_L[i]) + (unsigned short)(VS[i]*VT[i]); for (i = 0; i < N; i++) VACC_L[i] += (short)(VS[i] * VT[i]); for (i = 0; i < N; i++) addend[i] = (addend[i] >> 16) + (VS[i]*(unsigned short)(VT[i]) >> 16); for (i = 0; i < N; i++) addend[i] = (unsigned short)(VACC_M[i]) + addend[i]; for (i = 0; i < N; i++) VACC_M[i] = (short)addend[i]; for (i = 0; i < N; i++) VACC_H[i] += addend[i] >> 16; SIGNED_CLAMP_AM(VD); #endif } static INLINE void do_madh(short* VD, short* VS, short* VT) { #ifdef ARCH_MIN_SSE2 __m128i acc_mid; __m128i prod_high; __m128i vs, vt; vs = _mm_loadu_si128((__m128i *)VS); vt = _mm_loadu_si128((__m128i *)VT); prod_high = _mm_mulhi_epi16(vs, vt); vs = _mm_mullo_epi16(vs, vt); /* * We're required to load the source product from the accumulator to add to. * While we're at it, conveniently sneak in a acc[31..16] += (vs*vt)[15..0]. */ acc_mid = _mm_loadu_si128((__m128i *)VACC_M); vs = _mm_add_epi16(vs, acc_mid); _mm_storeu_si128((__m128i *)VACC_M, vs); vt = _mm_loadu_si128((__m128i *)VACC_H); /* * While accumulating base_lo + product_lo is easy, getting the correct data * for base_hi + product_hi is tricky and needs unsigned overflow detection. * * The one-liner solution to detecting unsigned overflow (thus adding a carry * value of 1 to the higher word) is _mm_cmplt_epu16, but none of the Intel * MMX-based instruction sets define unsigned comparison ops FOR us, so... */ vt = _mm_add_epi16(vt, prod_high); vs = _mm_cmplt_epu16(vs, acc_mid); /* acc.mid + prod.low < acc.mid */ vt = _mm_sub_epi16(vt, vs); /* += 1 if overflow, by doing -= ~0 */ _mm_storeu_si128((__m128i *)VACC_H, vt); vs = _mm_loadu_si128((__m128i *)VACC_M); prod_high = _mm_unpackhi_epi16(vs, vt); vs = _mm_unpacklo_epi16(vs, vt); vs = _mm_packs_epi32(vs, prod_high); _mm_storeu_si128((__m128i *)VD, vs); #else int32_t product[N]; uint32_t addend[N]; register int i; for (i = 0; i < N; i++) product[i] = (signed short)(VS[i]) * (signed short)(VT[i]); for (i = 0; i < N; i++) addend[i] = (unsigned short)(VACC_M[i]) + (unsigned short)(product[i]); for (i = 0; i < N; i++) VACC_M[i] += (short)(VS[i] * VT[i]); for (i = 0; i < N; i++) VACC_H[i] += (addend[i] >> 16) + (product[i] >> 16); SIGNED_CLAMP_AM(VD); #endif } static INLINE void do_mudm(short* VD, short* VS, short* VT) { register int i; for (i = 0; i < N; i++) VACC_L[i] = (VS[i]*(unsigned short)(VT[i]) & 0x00000000FFFF) >> 0; for (i = 0; i < N; i++) VACC_M[i] = (VS[i]*(unsigned short)(VT[i]) & 0x0000FFFF0000) >> 16; for (i = 0; i < N; i++) VACC_H[i] = -(VACC_M[i] < 0); vector_copy(VD, VACC_M); /* no possibilities to clamp */ } static INLINE void do_mudn(short* VD, short* VS, short* VT) { register int i; for (i = 0; i < N; i++) VACC_L[i] = ((unsigned short)(VS[i])*VT[i] & 0x00000000FFFF) >> 0; for (i = 0; i < N; i++) VACC_M[i] = ((unsigned short)(VS[i])*VT[i] & 0x0000FFFF0000) >> 16; for (i = 0; i < N; i++) VACC_H[i] = -(VACC_M[i] < 0); vector_copy(VD, VACC_L); /* no possibilities to clamp */ } static INLINE void do_mudh(short* VD, short* VS, short* VT) { register int i; for (i = 0; i < N; i++) VACC_L[i] = 0x0000; for (i = 0; i < N; i++) VACC_M[i] = (short)(VS[i]*VT[i] >> 0); for (i = 0; i < N; i++) VACC_H[i] = (short)(VS[i]*VT[i] >> 16); SIGNED_CLAMP_AM(VD); } static INLINE void do_madn(short* VD, short* VS, short* VT) { #ifdef ARCH_MIN_SSE2 __m128i acc_hi, acc_md, acc_lo; __m128i prod_hi, prod_lo; __m128i overflow; __m128i vs, vt; vs = _mm_loadu_si128((__m128i *)VS); vt = _mm_loadu_si128((__m128i *)VT); prod_lo = _mm_mullo_epi16(vs, vt); prod_hi = _mm_mulhi_epu16(vs, vt); vt = _mm_srai_epi16(vt, 15); vs = _mm_and_si128(vs, vt); prod_hi = _mm_sub_epi16(prod_hi, vs); /* * Writeback phase to the accumulator. * VMADN stores accumulator += the product achieved by VMUDN. */ acc_lo = _mm_loadu_si128((__m128i *)VACC_L); acc_md = _mm_loadu_si128((__m128i *)VACC_M); acc_hi = _mm_loadu_si128((__m128i *)VACC_H); acc_lo = _mm_add_epi16(acc_lo, prod_lo); _mm_storeu_si128((__m128i *)VACC_L, acc_lo); overflow = _mm_cmplt_epu16(acc_lo, prod_lo); /* overflow: (x + y < y) */ prod_hi = _mm_sub_epi16(prod_hi, overflow); acc_md = _mm_add_epi16(acc_md, prod_hi); _mm_storeu_si128((__m128i *)VACC_M, acc_md); overflow = _mm_cmplt_epu16(acc_md, prod_hi); prod_hi = _mm_srai_epi16(prod_hi, 15); acc_hi = _mm_add_epi16(acc_hi, prod_hi); acc_hi = _mm_sub_epi16(acc_hi, overflow); _mm_storeu_si128((__m128i *)VACC_H, acc_hi); /* * Do a signed clamp...sort of (VM?DM, VM?DH: middle; VM?DL, VM?DN: low). * if (acc_47..16 < -32768) result = -32768 ^ 0x8000; # 0000 * else if (acc_47..16 > +32767) result = +32767 ^ 0x8000; # FFFF * else { result = acc_15..0 & 0xFFFF; } * So it is based on the standard signed clamping logic for VM?DM, VM?DH, * except that extra steps must be concatenated to that definition. */ vt = _mm_unpackhi_epi16(acc_md, acc_hi); vs = _mm_unpacklo_epi16(acc_md, acc_hi); vs = _mm_packs_epi32(vs, vt); acc_md = _mm_cmpeq_epi16(acc_md, vs); /* (unclamped == clamped) ... */ acc_lo = _mm_and_si128(acc_lo, acc_md); /* ... ? low : mid */ vt = _mm_cmpeq_epi16(vt, vt); acc_md = _mm_xor_si128(acc_md, vt); /* (unclamped != clamped) ... */ vs = _mm_and_si128(vs, acc_md); /* ... ? VS_clamped : 0x0000 */ vs = _mm_or_si128(vs, acc_lo); /* : acc_lo */ acc_md = _mm_slli_epi16(acc_md, 15); /* ... ? ^ 0x8000 : ^ 0x0000 */ vs = _mm_xor_si128(vs, acc_md); /* Stupid unsigned-clamp-ish adjustment. */ _mm_storeu_si128((__m128i *)VD, vs); #else uint32_t addend[N]; register int i; for (i = 0; i < N; i++) addend[i] = (unsigned short)(VACC_L[i]) + (unsigned short)(VS[i]*VT[i]); for (i = 0; i < N; i++) VACC_L[i] += (short)(VS[i] * VT[i]); for (i = 0; i < N; i++) addend[i] = (addend[i] >> 16) + ((unsigned short)(VS[i])*VT[i] >> 16); for (i = 0; i < N; i++) addend[i] = (unsigned short)(VACC_M[i]) + addend[i]; for (i = 0; i < N; i++) VACC_M[i] = (short)addend[i]; for (i = 0; i < N; i++) VACC_H[i] += addend[i] >> 16; SIGNED_CLAMP_AL(VD); #endif } static INLINE void do_madl(short* VD, short* VS, short* VT) { int32_t product[N]; uint32_t addend[N]; register int i; for (i = 0; i < N; i++) product[i] = (unsigned short)(VS[i]) * (unsigned short)(VT[i]); for (i = 0; i < N; i++) addend[i] = (product[i] & 0x0000FFFF0000) >> 16; for (i = 0; i < N; i++) addend[i] = (unsigned short)(VACC_L[i]) + addend[i]; for (i = 0; i < N; i++) VACC_L[i] = (short)(addend[i]); for (i = 0; i < N; i++) addend[i] = (unsigned short)(addend[i] >> 16); for (i = 0; i < N; i++) addend[i] = (unsigned short)(VACC_M[i]) + addend[i]; for (i = 0; i < N; i++) VACC_M[i] = (short)(addend[i]); for (i = 0; i < N; i++) VACC_H[i] += addend[i] >> 16; SIGNED_CLAMP_AL(VD); } static INLINE void do_mudl(short* VD, short* VS, short* VT) { #ifdef ARCH_MIN_SSE2 __m128i vs = _mm_loadu_si128((__m128i *)VS); __m128i vt = _mm_loadu_si128((__m128i *)VT); /* * 2015.07.27 --cxd4 * This next instruction is virtually identical to the whole VMUDL operation. * temp[i]31..0 = vs[i]15..0 * vt[i]15..0 * result[i]15..0 = temp[i]31..16 */ vs = _mm_mulhi_epu16(vs, vt); _mm_storeu_si128((__m128i *)VD, vs); _mm_storeu_si128((__m128i *)VACC_L, vs); vt = _mm_xor_si128(vt, vt); /* (u16 * u16) >> 16 is too small for MD/HI. */ _mm_storeu_si128((__m128i *)VACC_M, vt); _mm_storeu_si128((__m128i *)VACC_H, vt); #else register int i; for (i = 0; i < N; i++) VACC_L[i] = (unsigned short)(VS[i])*(unsigned short)(VT[i]) >> 16; for (i = 0; i < N; i++) VACC_M[i] = 0x0000; for (i = 0; i < N; i++) VACC_H[i] = 0x0000; vector_copy(VD, VACC_L); /* no possibilities to clamp */ #endif } static void VMUDL(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_mudl(VR[vd], VR[vs], ST); } static void VMADL(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_madl(VR[vd], VR[vs], ST); } static void VMADN(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_madn(VR[vd], VR[vs], ST); } static void VMUDH(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_mudh(VR[vd], VR[vs], ST); } static void VMUDN(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_mudn(VR[vd], VR[vs], ST); } static void VMUDM(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_mudm(VR[vd], VR[vs], ST); } static void VMADH(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_madh(VR[vd], VR[vs], ST); } static void VMADM(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_madm(VR[vd], VR[vs], ST); } static INLINE void VMULU(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_mulu(VR[vd], VR[vs], ST); } static void VMULF(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_mulf(VR[vd], VR[vs], ST); } static void VMACF(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_macf(VR[vd], VR[vs], ST); SIGNED_CLAMP_AM(VR[vd]); } static void VMACU(int vd, int vs, int vt, int e) { short ST[N]; SHUFFLE_VECTOR(ST, VR[vt], e); do_macf(VR[vd], VR[vs], ST); UNSIGNED_CLAMP(VR[vd]); } gles2n64/src/gles2N64.c000664 001750 001750 00000015610 12655644434 015525 0ustar00sergiosergio000000 000000 #ifndef _WIN32 #include #endif #include #include "m64p_types.h" #include "m64p_plugin.h" #include "gles2N64.h" #include "Debug.h" #include "OpenGL.h" #include "N64.h" #include "RSP.h" #include "RDP.h" #include "VI.h" #include "Config.h" #include "Textures.h" #include "ShaderCombiner.h" #include "3DMath.h" #include "../../libretro/SDL.h" #ifdef __LIBRETRO__ // Prefix API #define VIDEO_TAG(X) gln64##X #define ReadScreen2 VIDEO_TAG(ReadScreen2) #define PluginStartup VIDEO_TAG(PluginStartup) #define PluginShutdown VIDEO_TAG(PluginShutdown) #define PluginGetVersion VIDEO_TAG(PluginGetVersion) #define CaptureScreen VIDEO_TAG(CaptureScreen) #define ChangeWindow VIDEO_TAG(ChangeWindow) #define CloseDLL VIDEO_TAG(CloseDLL) #define DllTest VIDEO_TAG(DllTest) #define DrawScreen VIDEO_TAG(DrawScreen) #define GetDllInfo VIDEO_TAG(GetDllInfo) #define InitiateGFX VIDEO_TAG(InitiateGFX) #define MoveScreen VIDEO_TAG(MoveScreen) #define RomClosed VIDEO_TAG(RomClosed) #define RomOpen VIDEO_TAG(RomOpen) #define ShowCFB VIDEO_TAG(ShowCFB) #define SetRenderingCallback VIDEO_TAG(SetRenderingCallback) #define UpdateScreen VIDEO_TAG(UpdateScreen) #define ViStatusChanged VIDEO_TAG(ViStatusChanged) #define ViWidthChanged VIDEO_TAG(ViWidthChanged) #define ReadScreen VIDEO_TAG(ReadScreen) #define FBGetFrameBufferInfo VIDEO_TAG(FBGetFrameBufferInfo) #define FBRead VIDEO_TAG(FBRead) #define FBWrite VIDEO_TAG(FBWrite) #define ProcessDList VIDEO_TAG(ProcessDList) #define ProcessRDPList VIDEO_TAG(ProcessRDPList) #define ResizeVideoOutput VIDEO_TAG(ResizeVideoOutput) #endif u32 last_good_ucode = (u32) -1; void (*renderCallback)() = NULL; EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context, void (*DebugCallback)(void *, int, const char *)) { #ifdef __NEON_OPT unsigned cpu = 0; if (perf_get_cpu_features_cb) cpu = perf_get_cpu_features_cb(); if (cpu & RETRO_SIMD_NEON) MathInitNeon(); #endif return M64ERR_SUCCESS; } EXPORT m64p_error CALL PluginShutdown(void) { OGL_Stop(); // paulscode, OGL_Stop missing from Yongzh's code return M64ERR_SUCCESS; // __LIBRETRO__: Fix warning } EXPORT m64p_error CALL PluginGetVersion(m64p_plugin_type *PluginType, int *PluginVersion, int *APIVersion, const char **PluginNamePtr, int *Capabilities) { /* set version info */ if (PluginType != NULL) *PluginType = M64PLUGIN_GFX; if (PluginVersion != NULL) *PluginVersion = PLUGIN_VERSION; if (APIVersion != NULL) *APIVersion = PLUGIN_API_VERSION; if (PluginNamePtr != NULL) *PluginNamePtr = PLUGIN_NAME; if (Capabilities != NULL) { *Capabilities = 0; } return M64ERR_SUCCESS; } EXPORT void CALL ChangeWindow (void) { } EXPORT void CALL MoveScreen (int xpos, int ypos) { } EXPORT int CALL InitiateGFX (GFX_INFO Gfx_Info) { Config_gln64_LoadConfig(); Config_gln64_LoadRomConfig(Gfx_Info.HEADER); OGL_Start(); return 1; } EXPORT void CALL ProcessDList(void) { OGL.frame_dl++; RSP_ProcessDList(); OGL.mustRenderDlist = true; } EXPORT void CALL ResizeVideoOutput(int Width, int Height) { } EXPORT void CALL RomClosed (void) { } EXPORT int CALL RomOpen (void) { RSP_Init(); OGL.frame_dl = 0; OGL.frame_prevdl = -1; OGL.mustRenderDlist = false; return 1; } EXPORT void CALL RomResumed(void) { } EXPORT void CALL ShowCFB (void) { } EXPORT void CALL UpdateScreen (void) { //has there been any display lists since last update if (OGL.frame_prevdl == OGL.frame_dl) return; OGL.frame_prevdl = OGL.frame_dl; if (OGL.mustRenderDlist) { OGL.screenUpdate=true; VI_UpdateScreen(); OGL.mustRenderDlist = false; } } EXPORT void CALL ViStatusChanged (void) { } EXPORT void CALL ViWidthChanged (void) { } /****************************************************************** Function: FrameBufferRead Purpose: This function is called to notify the dll that the frame buffer memory is beening read at the given address. DLL should copy content from its render buffer to the frame buffer in N64 RDRAM DLL is responsible to maintain its own frame buffer memory addr list DLL should copy 4KB block content back to RDRAM frame buffer. Emulator should not call this function again if other memory is read within the same 4KB range Since depth buffer is also being watched, the reported addr may belong to depth buffer input: addr rdram address val val size 1 = uint8, 2 = uint16, 4 = uint32 output: none *******************************************************************/ EXPORT void CALL FBRead(u32 addr) { } /****************************************************************** Function: FrameBufferWrite Purpose: This function is called to notify the dll that the frame buffer has been modified by CPU at the given address. Since depth buffer is also being watched, the reported addr may belong to depth buffer input: addr rdram address val val size 1 = uint8, 2 = uint16, 4 = uint32 output: none *******************************************************************/ EXPORT void CALL FBWrite(u32 addr, u32 size) { } /************************************************************************ Function: FBGetFrameBufferInfo Purpose: This function is called by the emulator core to retrieve frame buffer information from the video plugin in order to be able to notify the video plugin about CPU frame buffer read/write operations size: = 1 byte = 2 word (16 bit) <-- this is N64 default depth buffer format = 4 dword (32 bit) when frame buffer information is not available yet, set all values in the FrameBufferInfo structure to 0 input: FrameBufferInfo pinfo[6] pinfo is pointed to a FrameBufferInfo structure which to be filled in by this function output: Values are return in the FrameBufferInfo structure Plugin can return up to 6 frame buffer info ************************************************************************/ EXPORT void CALL FBGetFrameBufferInfo(void *p) { } // paulscode, API changed this to "ReadScreen2" in Mupen64Plus 1.99.4 EXPORT void CALL ReadScreen2(void *dest, int *width, int *height, int front) { /* TODO: 'int front' was added in 1.99.4. What to do with this here? */ OGL_ReadScreen(dest, width, height); } EXPORT void CALL SetRenderingCallback(void (*callback)()) { renderCallback = callback; } EXPORT void CALL StartGL(void) { OGL_Start(); } EXPORT void CALL StopGL(void) { OGL_Stop(); } #ifdef __LIBRETRO__ void gles2n64_reset(void) { // HACK: Check for leaks! OGL_Stop(); OGL_Start(); RSP_Init(); } #endif glide2gl/src/Glitch64/geometry.c000664 001750 001750 00000023403 12655644434 017564 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "glide.h" #include "glitchmain.h" #include "../Glide64/rdp.h" /* TODO: get rid of glitch_vbo */ /* TODO: try glDrawElements */ /* TODO: #ifdefs for EMSCRIPTEN (ToadKing?) */ /* TODO: investigate triangle degeneration to allow caching GL_TRIANGLE_STRIP */ /* This structure is a truncated version of VERTEX, we use it to lower memory * usage and speed up the caching process. */ typedef struct { float x, y, z, q; uint8_t b; uint8_t g; uint8_t r; uint8_t a; float coord[4]; float f; //fog } VBufVertex; #define VERTEX_OFF(x) (vbuf_vbo ? (void*)offsetof(VBufVertex, x) : (void*)&vbuf_data->x) #define VERTEX_SIZE sizeof(VBufVertex) #define VERTEX_BUFFER_SIZE (1500) static VBufVertex vbuf_data[VERTEX_BUFFER_SIZE]; static GLenum vbuf_primitive = GL_TRIANGLES; static unsigned vbuf_length = 0; static bool vbuf_use_vbo = false; static bool vbuf_enabled = false; static GLuint vbuf_vbo = 0; static size_t vbuf_vbo_size = 0; static bool vbuf_drawing = false; extern retro_environment_t environ_cb; #ifdef EMSCRIPTEN static struct draw_buffer *gli_vbo; static unsigned gli_vbo_size; #endif void vbo_init(void) { #ifdef EMSCRIPTEN struct retro_variable var = { "mupen64-vcache-vbo", "on" }; #else struct retro_variable var = { "mupen64-vcache-vbo", 0 }; #endif vbuf_use_vbo = false; vbuf_length = 0; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) vbuf_use_vbo = (strcmp(var.value, "on") == 0); if (vbuf_use_vbo) { glGenBuffers(1, &vbuf_vbo); if (!vbuf_vbo) { log_cb(RETRO_LOG_ERROR, "Failed to create the VBO."); vbuf_use_vbo = false; } else log_cb(RETRO_LOG_INFO, "Vertex cache VBO enabled.\n"); } } void vbo_free(void) { if (vbuf_vbo) glDeleteBuffers(1, &vbuf_vbo); vbuf_vbo = 0; vbuf_vbo_size = 0; vbuf_length = 0; vbuf_enabled = false; vbuf_drawing = false; } void vbo_bind() { if (vbuf_vbo) glBindBuffer(GL_ARRAY_BUFFER, vbuf_vbo); } void vbo_unbind() { if (vbuf_vbo) glBindBuffer(GL_ARRAY_BUFFER, 0); } void vbo_buffer_data(void *data, size_t size) { if (vbuf_vbo) { if (size > vbuf_vbo_size) { glBufferData(GL_ARRAY_BUFFER, size, data, GL_DYNAMIC_DRAW); if (size > VERTEX_BUFFER_SIZE) log_cb(RETRO_LOG_INFO, "Extending vertex cache VBO.\n"); vbuf_vbo_size = size; } else glBufferSubData(GL_ARRAY_BUFFER, 0, size, data); } } void vbo_draw(void) { if (!vbuf_length || vbuf_drawing) return; /* avoid infinite loop in sgl*BindBuffer */ vbuf_drawing = true; if (vbuf_vbo) { glBindBuffer(GL_ARRAY_BUFFER, vbuf_vbo); glBufferSubData(GL_ARRAY_BUFFER, 0, VERTEX_SIZE * vbuf_length, vbuf_data); glDrawArrays(vbuf_primitive, 0, vbuf_length); glBindBuffer(GL_ARRAY_BUFFER, 0); } else glDrawArrays(vbuf_primitive, 0, vbuf_length); vbuf_length = 0; vbuf_drawing = false; } static void vbo_append(GLenum mode, GLsizei count, void *pointers) { if (vbuf_length + count > VERTEX_BUFFER_SIZE) vbo_draw(); /* keep caching triangles as much as possible. */ if (count == 3 && vbuf_primitive == GL_TRIANGLES) mode = GL_TRIANGLES; while (count--) { memcpy(&vbuf_data[vbuf_length++], pointers, VERTEX_SIZE); pointers = (char*)pointers + sizeof(VERTEX); } vbuf_primitive = mode; /* we can't handle anything but triangles so flush it */ if (mode != GL_TRIANGLES) vbo_draw(); } void vbo_enable(void) { bool was_drawing = vbuf_drawing; if (vbuf_enabled) return; vbuf_drawing = true; if (vbuf_vbo) { glBindBuffer(GL_ARRAY_BUFFER, vbuf_vbo); if (vbuf_vbo_size < VERTEX_BUFFER_SIZE * sizeof(VBufVertex)) vbo_buffer_data(NULL, VERTEX_BUFFER_SIZE * sizeof(VBufVertex)); } glEnableVertexAttribArray(POSITION_ATTR); glEnableVertexAttribArray(COLOUR_ATTR); glEnableVertexAttribArray(TEXCOORD_0_ATTR); glEnableVertexAttribArray(TEXCOORD_1_ATTR); glEnableVertexAttribArray(FOG_ATTR); glVertexAttribPointer(POSITION_ATTR, 4, GL_FLOAT, false, VERTEX_SIZE, VERTEX_OFF(x)); glVertexAttribPointer(COLOUR_ATTR, 4, GL_UNSIGNED_BYTE, true, VERTEX_SIZE, VERTEX_OFF(b)); glVertexAttribPointer(TEXCOORD_0_ATTR, 2, GL_FLOAT, false, VERTEX_SIZE, VERTEX_OFF(coord[2])); glVertexAttribPointer(TEXCOORD_1_ATTR, 2, GL_FLOAT, false, VERTEX_SIZE, VERTEX_OFF(coord[0])); glVertexAttribPointer(FOG_ATTR, 1, GL_FLOAT, false, VERTEX_SIZE, VERTEX_OFF(f)); if (vbuf_vbo) glBindBuffer(GL_ARRAY_BUFFER, 0); vbuf_enabled = true; vbuf_drawing = was_drawing; } void vbo_disable() { vbo_draw(); vbuf_enabled = false; } void grCullMode( int32_t mode ) { switch(mode) { case GR_CULL_DISABLE: glDisable(GL_CULL_FACE); break; case GR_CULL_NEGATIVE: glCullFace(GL_FRONT); glEnable(GL_CULL_FACE); break; case GR_CULL_POSITIVE: glCullFace(GL_BACK); glEnable(GL_CULL_FACE); break; } } // Depth buffer void grDepthBufferFunction(GLenum func) { glDepthFunc(func); } void grDepthMask(bool mask) { glDepthMask(mask); } bool biasFound = false; extern float polygonOffsetFactor; extern float polygonOffsetUnits; void FindBestDepthBias(void) { const char *renderer = NULL; #if defined(__LIBRETRO__) // TODO: How to calculate this? if (biasFound) return; renderer = (const char*)glGetString(GL_RENDERER); if (log_cb) log_cb(RETRO_LOG_INFO, "GL_RENDERER: %s\n", renderer); biasFound = true; #else #if 0 float f, bestz = 0.25f; int x; if (biasFactor) return; biasFactor = 64.0f; // default value glPushAttrib(GL_ALL_ATTRIB_BITS); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_ALWAYS); glEnable(GL_POLYGON_OFFSET_FILL); glDrawBuffer(GL_BACK); glReadBuffer(GL_BACK); glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST); glColor4ub(255,255,255,255); glDepthMask(GL_TRUE); for (x=0, f=1.0f; f<=65536.0f; x+=4, f*=2.0f) { float z; glPolygonOffset(0, f); glBegin(GL_TRIANGLE_STRIP); glVertex3f(float(x+4 - widtho)/(width/2), float(0 - heighto)/(height/2), 0.5); glVertex3f(float(x - widtho)/(width/2), float(0 - heighto)/(height/2), 0.5); glVertex3f(float(x+4 - widtho)/(width/2), float(4 - heighto)/(height/2), 0.5); glVertex3f(float(x - widtho)/(width/2), float(4 - heighto)/(height/2), 0.5); glEnd(); glReadPixels(x+2, 2, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z); z -= 0.75f + 8e-6f; if (z<0.0f) z = -z; if (z > 0.01f) continue; if (z < bestz) { bestz = z; biasFactor = f; } //printf("f %g z %g\n", f, z); } //printf(" --> bias factor %g\n", biasFactor); glPopAttrib(); #endif #endif } void grDepthBiasLevel( int32_t level ) { if (level) { glPolygonOffset(polygonOffsetFactor, (float)level * settings.depth_bias * 0.01f); glEnable(GL_POLYGON_OFFSET_FILL); } else { glPolygonOffset(0,0); glDisable(GL_POLYGON_OFFSET_FILL); } } #ifdef EMSCRIPTEN #define buffer_struct struct draw_buffer #define gl_offset(x) offsetof(buffer_struct, x) #else #define buffer_struct VERTEX #define gl_offset(x) &v->x #endif void grDrawVertexArrayContiguous(uint32_t mode, uint32_t count, void *pointers) { if(need_to_compile) compile_shader(); vbo_enable(); vbo_append(mode, count, pointers); /* #ifdef EMSCRIPTEN unsigned i; #endif VERTEX *v = (VERTEX*)pointers; if(need_to_compile) compile_shader(); #ifdef EMSCRIPTEN if (count > gli_vbo_size) { gli_vbo_size = count; gli_vbo = realloc(gli_vbo, sizeof(struct draw_buffer) * gli_vbo_size); } for (i = 0; i < count; i++) { memcpy(&gli_vbo[i], &v[i], sizeof(struct draw_buffer)); } glBindBuffer(GL_ARRAY_BUFFER, glitch_vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(buffer_struct) * count, gli_vbo, GL_DYNAMIC_DRAW); #endif glEnableVertexAttribArray(POSITION_ATTR); glVertexAttribPointer(POSITION_ATTR, 4, GL_FLOAT, false, sizeof(buffer_struct), gl_offset(x)); //Position glEnableVertexAttribArray(COLOUR_ATTR); glVertexAttribPointer(COLOUR_ATTR, 4, GL_UNSIGNED_BYTE, true, sizeof(buffer_struct), gl_offset(b)); //Colour glEnableVertexAttribArray(TEXCOORD_0_ATTR); glVertexAttribPointer(TEXCOORD_0_ATTR, 2, GL_FLOAT, false, sizeof(buffer_struct), gl_offset(coord[2])); //Tex0 glEnableVertexAttribArray(TEXCOORD_1_ATTR); glVertexAttribPointer(TEXCOORD_1_ATTR, 2, GL_FLOAT, false, sizeof(buffer_struct), gl_offset(coord[0])); //Tex1 glEnableVertexAttribArray(FOG_ATTR); glVertexAttribPointer(FOG_ATTR, 1, GL_FLOAT, false, sizeof(buffer_struct), gl_offset(f)); //Fog glDrawArrays(mode, 0, count); #ifdef EMSCRIPTEN glBindBuffer(GL_ARRAY_BUFFER, 0); #endif */ } void init_geometry() { vbo_init(); } void free_geometry() { vbo_free(); } gles2rice/src/Timing.h000664 001750 001750 00000011143 12655644434 015765 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _RSP_RDP_TIMING_H_ #define _RSP_RDP_TIMING_H_ enum { Timing_SP_Minimal = 10, Timing_SP_Minimal2 = 20, Timing_SP_Minimal4 = 40, Timing_SP_Minimal8 = 80, Timing_SP_Each_Triangle = 80, Timing_SP_Each_2_Triangle2 = 160, Timing_RSP_GBI1_SpNoop = Timing_SP_Minimal, Timing_RSP_GBI0_Mtx = Timing_SP_Minimal8, Timing_RSP_GBI1_Reserved = Timing_SP_Minimal2, Timing_RSP_GBI1_MoveMem = Timing_SP_Minimal2, // Fix me Timing_RSP_GBI1_Vtx = Timing_SP_Minimal4, // for each vertex Timing_RSP_GBI0_Vtx = Timing_SP_Minimal4, // for each vertex Timing_RSP_GBI0_DL = Timing_SP_Minimal*2, Timing_RSP_GBI1_Sprite2DBase = Timing_SP_Minimal8, Timing_RSP_GBI1_LoadUCode = 800, Timing_RSP_GBI1_BranchZ = Timing_SP_Minimal2, Timing_RSP_GBI1_Tri2 = Timing_SP_Each_2_Triangle2, Timing_RSP_GBI1_ModifyVtx = Timing_SP_Minimal4, Timing_RSP_GBI1_RDPHalf_2 = Timing_SP_Minimal, Timing_RSP_GBI1_RDPHalf_1 = Timing_SP_Minimal, Timing_RSP_GBI1_RDPHalf_Cont = Timing_SP_Minimal, Timing_RSP_GBI1_Line3D = Timing_SP_Each_Triangle, Timing_RSP_GBI1_ClearGeometryMode = Timing_SP_Minimal, Timing_RSP_GBI1_SetGeometryMode = Timing_SP_Minimal, Timing_RSP_GBI2_GeometryMode = Timing_SP_Minimal, Timing_RSP_GBI1_EndDL = Timing_SP_Minimal, Timing_RSP_GBI1_SetOtherModeL = Timing_SP_Minimal, Timing_RSP_GBI1_SetOtherModeH = Timing_SP_Minimal, Timing_RSP_GBI1_Texture = Timing_SP_Minimal2, Timing_RSP_GBI1_MoveWord = Timing_SP_Minimal2, Timing_RSP_GBI2_SubModule = Timing_SP_Minimal2, Timing_RSP_GBI1_PopMtx = Timing_SP_Minimal8, Timing_RSP_GBI1_CullDL = Timing_SP_Minimal2, Timing_RSP_GBI1_Tri1 = Timing_SP_Each_Triangle, Timing_RSP_GBI1_Noop = Timing_SP_Minimal, Timing_RSP_S2DEX_SPObjLoadTxtr_Ucode1 = Timing_SP_Minimal8, Timing_DP_Minimal = 10, Timing_DP_Minimal2 = 20, Timing_DP_Minimal4 = 40, Timing_DP_Minimal8 = 80, Timing_DP_Minimal16 = 160, Timing_DP_Each_Point = 1, Timing_RDP_TriFill = Timing_DP_Minimal8, Timing_RDP_TriFillZ = Timing_DP_Minimal8, Timing_RDP_TriTxtr = Timing_DP_Minimal8, Timing_RDP_TriTxtrZ = Timing_DP_Minimal8, Timing_RDP_TriShade = Timing_DP_Minimal8, Timing_RDP_TriShadeZ = Timing_DP_Minimal8, Timing_RDP_TriShadeTxtr = Timing_DP_Minimal8, Timing_RDP_TriShadeTxtrZ = Timing_DP_Minimal8, Timing_DLParser_TexRect = Timing_DP_Minimal8, Timing_DLParser_TexRectFlip = Timing_DP_Minimal8, Timing_DLParser_RDPLoadSync = Timing_DP_Minimal, Timing_DLParser_RDPPipeSync = Timing_DP_Minimal, Timing_DLParser_RDPTileSync = Timing_DP_Minimal, Timing_DLParser_RDPFullSync = Timing_DP_Minimal8, Timing_DLParser_SetKeyGB = Timing_DP_Minimal, Timing_DLParser_SetKeyR = Timing_DP_Minimal, Timing_DLParser_SetConvert = Timing_DP_Minimal2, Timing_DLParser_SetScissor = Timing_DP_Minimal2, Timing_DLParser_SetPrimDepth = Timing_DP_Minimal2, Timing_DLParser_RDPSetOtherMode = Timing_DP_Minimal, Timing_DLParser_LoadTLut = Timing_DP_Minimal16, Timing_RSP_RDP_Nothing = Timing_DP_Minimal, Timing_DLParser_SetTileSize = Timing_DP_Minimal4, Timing_DLParser_LoadBlock = Timing_DP_Minimal16, Timing_DLParser_LoadTile = Timing_DP_Minimal16, Timing_DLParser_SetTile = Timing_DP_Minimal8, Timing_DLParser_FillRect = Timing_DP_Minimal16, Timing_DLParser_SetFillColor = Timing_DP_Minimal, Timing_DLParser_SetFogColor = Timing_DP_Minimal, Timing_DLParser_SetBlendColor = Timing_DP_Minimal, Timing_DLParser_SetPrimColor = Timing_DP_Minimal, Timing_DLParser_SetEnvColor = Timing_DP_Minimal, Timing_DLParser_SetCombine = Timing_DP_Minimal, Timing_DLParser_SetTImg = Timing_DP_Minimal, Timing_DLParser_SetZImg = Timing_DP_Minimal, Timing_DLParser_SetCImg = Timing_DP_Minimal, }; #define DP_Timing(t) {status.DPCycleCount+=Timing_##t;} #define SP_Timing(t) {status.SPCycleCount+=Timing_##t;} #endif mupen64plus-core/doc/emuwiki-api-doc/Mupen64Plus_v2.0_Core_API_v1.0.txt000664 001750 001750 00000013216 12655644434 026420 0ustar00sergiosergio000000 000000 [http://mupen64plus.retrouprising.com Project page] Please note: as of January 2011, this API is a work in progress.
The core Mupen64Plus v2.0 modules are complete, but work on GUI front-end applications is ongoing. To view the design proposal which preceded this API definition, go to [[Mupen64Plus v2.0 Design Proposal 3|Design Proposal 3]]. == New Architecture == Earlier versions of Mupen64Plus (and other plugin-based N64 emulators) used a single monolithic application (containing the emulator core) and four plugins. The plugins were dynamically-loaded libraries, and the application used one plugin of each type: Video, Audio, Input, and RSP. Each plugin and the application contained its own GUI code for user interface, and each plugin and the application were individually responsible for finding their own data files and finding, loading, parsing, and storing their own configuration data files. This was an acceptable architecture for emulators which were only designed to run on a single platform (such as Windows), but causes a lot of developer and user headaches when applied to a cross-platform emulator such as Mupen64Plus. For this reason, we are re-designing the layout of the emulator to solve some of the problems caused by the old architecture. Under the new architecture, the old monolithic emulator application is split into two parts: a core emulator library and a main application, called the front-end. The front-end is primarily responsible for the user interface. All GUI code will be removed from the core and plugin libraries. The primary function of the core library is to emulate the R4300 CPU and memory system, attaching the plugins to form a full N64 system emulator. The core library also contains some utility functions which may be used by the front-end and plugins, such as a configuration parameter handler. == High-level Usage == The expected sequence of operations which will be taken by the front-end application are as follows: # Load core library (libmupen64plus.so) and set function pointers # Call CoreGetVersion, check core version and capabilities # Call CoreStartup to initialize the core library # Load front-end configuration from core config API or through own mechanism # Find plugins, open dynamic libraries, call PluginStartup for each # Enter message loop for user interaction # If user selects ROM and presses Play: #* Load and de-compress the ROM #* Use CoreDoCommand to open the ROM #* Call CoreAttachPlugin to attach selected plugins to core #* Use CoreDoCommand to start emulation #* When emulation is finished, call CoreDetachPlugin on all plugins, then close the ROM == Core API == === [[Mupen64Plus v2.0 Core Basic|Basic Core Functions]] === These two functions (PluginGetVersion and CoreErrorMessage) are utility functions and may be called at any time (even before core startup). These functions are used by both the front-end and the plugins. === [[Mupen64Plus v2.0 Core Front-End|Front-End Functions]] === There are several types of functions here, which are exported from the Core library to be used by the front-end. There are 'housekeeping' functions, for startup and shutdown, and attaching and detaching plugins. There is also a Command API which is used for many simple functions such as loading, executing, or stopping a ROM. Finally the Cheat API is here, for adding and removing cheat functions. === [[Mupen64Plus v2.0 Core Video Extension|Video Extension API]] === These functions are exported from the Core library for use by the video plugin. These functions are used for high-level video setup tasks such as enumerating available screen resolutions, setting the video mode, window caption, OpenGL attributes, and fullscreen mode. The video extension API allows for the abstraction of these functions away from the hard-coded SDL function calls currently in the video plugins, so that a front-end may override these functions and provide its own video API. === [[Mupen64Plus v2.0 Core Debugger|Debugger Functions]] === These are the debugger functions, which are also called only from the front-end. Most of these functions will return with an error if the core library was not compiled with the debugger enabled. A front-end may examine the Capabilities value returned by the CoreGetVersion function to determine if the core library was built with the debugger enabled. === [[Mupen64Plus v2.0 Core Config|Configuration API]] === These configuration functions are exported from the core library and are used by the core and the plugins to store all of their persistent configuration parameters. The front-end application may also use these functions to store its configuration options, or it may use a different mechanism. This section also contains two Operating System Abstraction functions. These functions are used by the core, plugins, and the front-end to find full filepaths to shared data files and user-specific data files. == Plugin API == === [[Mupen64Plus v2.0 Plugin API|Plugin API]] === This section lists all of the functions which are exported by the plugins. The front-end application should only use the PluginStartup, PluginShutdown, and PluginGetVersion functions. All other functions will only be called from the core. == Configuration Parameters == === [[Mupen64Plus Core Parameters|Core Parameters]] === This section lists the names and descriptions of all of the configuration parameters used by the Core library. === [[Mupen64Plus Plugin Parameters|Plugin Parameters]] === This section lists the names and descriptions of all of the configuration parameters used by the Plugin libraries. mupen64plus-video-gliden64/src/N64.h000664 001750 001750 00000000362 12655644434 020147 0ustar00sergiosergio000000 000000 #ifndef N64_H #define N64_H #include "Types.h" #define MI_INTR_DP 0x20 // Bit 5: DP intr extern u8 *HEADER; extern u8 *DMEM; extern u8 *IMEM; extern u8 *RDRAM; extern u64 TMEM[512]; extern u32 RDRAMSize; extern bool ConfigOpen; #endif gles2rice/src/RDP_Texture.h000664 001750 001750 00000171563 12655644434 016720 0ustar00sergiosergio000000 000000 /* Copyright (C) 2002 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // Texture related ucode #ifndef RDP_TEXTURE_H #define RDP_TEXTURE_H #include #include #include "Render.h" #ifndef min #define min(a,b) ((a) < (b) ? (a) : (b)) #endif #ifndef max #define max(a,b) ((a) > (b) ? (a) : (b)) #endif uint32_t g_TmemFlag[16]; void SetTmemFlag(uint32_t tmemAddr, uint32_t size); bool IsTmemFlagValid(uint32_t tmemAddr); uint32_t GetValidTmemInfoIndex(uint32_t tmemAddr); void LoadHiresTexture( TxtrCacheEntry &entry ); extern TMEMLoadMapInfo g_tmemInfo0; // Info for Tmem=0 extern TMEMLoadMapInfo g_tmemInfo1; // Info for Tmem=0x100 TmemType g_Tmem; /************************************************************************/ /* */ /************************************************************************/ uint32_t sizeShift[4] = {2,1,0,0}; uint32_t sizeIncr[4] = {3,1,0,0}; uint32_t sizeBytes[4] = {0,1,2,4}; inline uint32_t Txl2Words(uint32_t width, uint32_t size) { if( size == TXT_SIZE_4b ) return max(1, width/16); else return max(1, width*sizeBytes[size]/8); } inline uint32_t CalculateImgSize(uint32_t width, uint32_t height, uint32_t size) { //(((width)*(height) + siz##_INCR) >> siz##_SHIFT) -1 return (((width)*(height) + sizeIncr[size]) >> sizeShift[size]) -1; } inline uint32_t CalculateDXT(uint32_t txl2words) { //#define CALC_DXT(width, b_txl) ((2048 + TXL2WORDS(width, b_txl) - 1) / TXL2WORDS(width, b_txl)) if( txl2words == 0 ) return 1; else return (2048+txl2words-1)/txl2words; } inline uint32_t ReverseDXT(uint32_t val, uint32_t lrs, uint32_t width, uint32_t size) { //#define TXL2WORDS(txls, b_txl) MAX(1, ((txls)*(b_txl)/8)) if( val == 0x800 ) return 1; unsigned int low = 2047/val; unsigned int high = 2047/(val-1); if( CalculateDXT(low) > val ) low++; if( low == high ) return low; for( unsigned int i=low; i<=high; i++ ) { if( Txl2Words(width, size) == i ) return i; } return (low+high)/2; //dxt = 2047 / (dxt-1); } #if defined(_WIN32) || defined(_WIN64) /* * 2015.07.27 cxd4 * Windows uses Microsoft's own "LLP64" ABI, so `long` is not a 64-bit type. */ #include typedef size_t ptr_as_int; #elif defined(UINTPTR_MAX) /* Use extension or core C99 support to define it. */ typedef uintptr_t ptr_as_int; #else typedef unsigned long ptr_as_int; #endif #ifdef _WIN64 #define NO_ASM #endif // The following inline assemble routines are borrowed from glN64, I am too tired to // rewrite these routine by myself. // Rice, 02/24/2004 static inline void UnswapCopy( void *src, void *dest, uint32_t numBytes ) { // copy leading bytes int leadingBytes = ((ptr_as_int)src) & 3; if (leadingBytes != 0) { leadingBytes = 4-leadingBytes; if ((unsigned int)leadingBytes > numBytes) leadingBytes = numBytes; numBytes -= leadingBytes; #ifdef MSB_FIRST src = (void *)((ptr_as_int)src); #else src = (void *)((ptr_as_int)src ^ 3); #endif for (int i = 0; i < leadingBytes; i++) { *(uint8_t *)(dest) = *(uint8_t *)(src); dest = (void *)((ptr_as_int)dest+1); src = (void *)((ptr_as_int)src -1); } src = (void *)((ptr_as_int)src+5); } // copy dwords int numDWords = numBytes >> 2; while (numDWords--) { uint32_t dword = *(uint32_t *)src; dword = ((dword<<24)|((dword<<8)&0x00FF0000)|((dword>>8)&0x0000FF00)|(dword>>24)); *(uint32_t *)dest = dword; dest = (void *)((ptr_as_int)dest+4); src = (void *)((ptr_as_int)src +4); } // copy trailing bytes int trailingBytes = numBytes & 3; if (trailingBytes) { #ifdef MSB_FIRST src = (void *)((ptr_as_int)src); #else src = (void *)((ptr_as_int)src ^ 3); #endif for (int i = 0; i < trailingBytes; i++) { *(uint8_t *)(dest) = *(uint8_t *)(src); dest = (void *)((ptr_as_int)dest+1); src = (void *)((ptr_as_int)src -1); } } } static inline void DWordInterleave( void *mem, uint32_t numDWords ) { int tmp; while( numDWords-- ) { tmp = *(int *)((ptr_as_int)mem + 0); *(int *)((ptr_as_int)mem + 0) = *(int *)((ptr_as_int)mem + 4); *(int *)((ptr_as_int)mem + 4) = tmp; mem = (void *)((ptr_as_int)mem + 8); } } static inline void QWordInterleave( void *mem, uint32_t numDWords ) { numDWords >>= 1; // qwords while( numDWords-- ) { int tmp0, tmp1; tmp0 = *(int *)((ptr_as_int)mem + 0); tmp1 = *(int *)((ptr_as_int)mem + 4); *(int *)((ptr_as_int)mem + 0) = *(int *)((ptr_as_int)mem + 8); *(int *)((ptr_as_int)mem + 8) = tmp0; *(int *)((ptr_as_int)mem + 4) = *(int *)((ptr_as_int)mem + 12); *(int *)((ptr_as_int)mem + 12) = tmp1; mem = (void *)((ptr_as_int)mem + 16); } } inline uint32_t swapdword( uint32_t value ) { return ((value & 0xff000000) >> 24) | ((value & 0x00ff0000) >> 8) | ((value & 0x0000ff00) << 8) | ((value & 0x000000ff) << 24); } static inline uint16_t swapword( uint16_t value ) { return (value << 8) | (value >> 8); } void ComputeTileDimension(int mask, int clamp, int mirror, int width, uint32_t &widthToCreate, uint32_t &widthToLoad) { int maskwidth = mask > 0 ? (1< 0 ) { if( width > maskwidth ) { if( clamp == 0 ) { // clamp is not used, so just use the dwTileMaskWidth as the real width widthToCreate = widthToLoad = maskwidth; } else { widthToLoad = maskwidth; //gti.WidthToCreate = dwTileWidth; // keep the current WidthToCreate, we will do mirror/wrap // during texture loading, not during rendering } } else if( width < maskwidth ) { // dwTileWidth < dwTileMaskWidth if( clamp == 0 ) { if( maskwidth%width == 0 ) { if( (maskwidth/width)%2 == 0 || mirror == 0 ) { // Do nothing // gti.WidthToLoad = gti.WidthToCreate = gRDP.tiles[tileno].dwWidth = dwTileWidth } else { widthToCreate = maskwidth; } } else { widthToCreate = maskwidth; //widthToLoad = maskwidth; } } else { widthToCreate = maskwidth; //widthToLoad = maskwidth; } } else // dwTileWidth == dwTileMaskWidth { } // Some hacks, to limit the image size if( mask >= 8 ) { if( maskwidth / width >= 2 ) { widthToCreate = width; } } } } bool conkerSwapHack=false; bool CalculateTileSizes_method_2(int tileno, TMEMLoadMapInfo *info, TxtrInfo >i) { Tile &tile = gRDP.tiles[tileno]; Tile &loadtile = gRDP.tiles[RDP_TXT_LOADTILE]; uint32_t dwPitch; // Now Initialize the texture dimension int dwTileWidth; int dwTileHeight; if( info->bSetBy == CMD_LOADTILE ) { if( tile.sl >= tile.sh ) { dwTileWidth = info->dwWidth; // From SetTImage dwTileWidth = dwTileWidth << info->dwSize >> tile.dwSize; } else { dwTileWidth= tile.sh - tile.sl + 1; } if( tile.tl >= tile.th ) { dwTileHeight= info->th - info->tl + 1; } else { dwTileHeight= tile.th - tile.tl + 1; } } else { if( tile.dwMaskS == 0 || tile.bClampS ) { dwTileWidth = tile.hilite_sh - tile.hilite_sl +1; if( dwTileWidth < tile.sh - tile.sl +1 ) dwTileWidth = tile.sh - tile.sl +1; if( dwTileWidth <= 0 ) { DebuggerAppendMsg("Error"); } } else { if( tile.dwMaskS < 8 ) dwTileWidth = (1 << tile.dwMaskS ); else if( tile.dwLine ) { dwTileWidth = (tile.dwLine<<5)>>tile.dwSize; } else { if( tile.sl <= tile.sh ) { dwTileWidth = tile.sh - tile.sl +1; } else if( loadtile.sl <= loadtile.sh ) { dwTileWidth = loadtile.sh - loadtile.sl +1; } else { dwTileWidth = tile.sh - tile.sl +1; } } } if( tile.dwMaskT == 0 || tile.bClampT ) { dwTileHeight= tile.hilite_th - tile.hilite_tl +1; if( dwTileHeight < tile.th - tile.tl +1 ) dwTileHeight = tile.th - tile.tl +1; if( dwTileHeight <= 0 ) { DebuggerAppendMsg("Error"); } } else { if( tile.dwMaskT < 8 ) dwTileHeight = (1 << tile.dwMaskT ); else if( tile.tl <= tile.th ) { dwTileHeight = tile.th - tile.tl +1; } else if( loadtile.tl <= loadtile.th ) { dwTileHeight = loadtile.th - loadtile.tl +1; } else { dwTileHeight = tile.th - tile.tl +1; } } } int dwTileMaskWidth = tile.dwMaskS > 0 ? (1 << tile.dwMaskS ) : 0; int dwTileMaskHeight = tile.dwMaskT > 0 ? (1 << tile.dwMaskT ) : 0; if( dwTileWidth < 0 || dwTileHeight < 0) { if( dwTileMaskWidth > 0 ) dwTileWidth = dwTileMaskWidth; else if( dwTileWidth < 0 ) dwTileWidth = -dwTileWidth; if( dwTileMaskHeight > 0 ) dwTileHeight = dwTileMaskHeight; else if( dwTileHeight < 0 ) dwTileHeight = -dwTileHeight; } if( dwTileWidth-dwTileMaskWidth == 1 && dwTileMaskWidth && dwTileHeight-dwTileMaskHeight == 1 && dwTileMaskHeight ) { // Hack for Mario Kart dwTileWidth--; dwTileHeight--; } ComputeTileDimension(tile.dwMaskS, tile.bClampS, tile.bMirrorS, dwTileWidth, gti.WidthToCreate, gti.WidthToLoad); tile.dwWidth = gti.WidthToCreate; ComputeTileDimension(tile.dwMaskT, tile.bClampT, tile.bMirrorT, dwTileHeight, gti.HeightToCreate, gti.HeightToLoad); tile.dwHeight = gti.HeightToCreate; #ifdef DEBUGGER if( gti.WidthToCreate < gti.WidthToLoad ) TRACE2("Check me, width to create = %d, width to load = %d", gti.WidthToCreate, gti.WidthToLoad); if( gti.HeightToCreate < gti.HeightToLoad ) TRACE2("Check me, height to create = %d, height to load = %d", gti.HeightToCreate, gti.HeightToLoad); #endif gti.bSwapped = info->bSwapped; if( info->bSetBy == CMD_LOADTILE ) { // It was a tile - the pitch is set by LoadTile dwPitch = info->dwWidth<<(info->dwSize-1); if( dwPitch == 0 ) { dwPitch = 1024; // Hack for Bust-A-Move } } else //Set by LoadBlock { // It was a block load - the pitch is determined by the tile size if (info->dxt == 0 || info->dwTmem != tile.dwTMem ) { dwPitch = tile.dwLine << 3; gti.bSwapped = TRUE; if( info->dwTmem != tile.dwTMem && info->dxt != 0 && info->dwSize == TXT_SIZE_16b && tile.dwSize == TXT_SIZE_4b ) conkerSwapHack = true; } else { uint32_t DXT = info->dxt; if( info->dxt > 1 ) { DXT = ReverseDXT(info->dxt, info->sh, dwTileWidth, tile.dwSize); } dwPitch = DXT << 3; } if (tile.dwSize == TXT_SIZE_32b) dwPitch = tile.dwLine << 4; } gti.Pitch = tile.dwPitch = dwPitch; if( (gti.WidthToLoad < gti.WidthToCreate || tile.bSizeIsValid == false) && tile.dwMaskS > 0 && gti.WidthToLoad != (unsigned int)dwTileMaskWidth && info->bSetBy == CMD_LOADBLOCK ) //if( (gti.WidthToLoad < gti.WidthToCreate ) && tile.dwMaskS > 0 && gti.WidthToLoad != dwTileMaskWidth && // info->bSetBy == CMD_LOADBLOCK ) { // We have got the pitch now, recheck the width_to_load uint32_t pitchwidth = dwPitch<<1>>tile.dwSize; if( pitchwidth == (unsigned int)dwTileMaskWidth ) { gti.WidthToLoad = pitchwidth; } } if( (gti.HeightToLoad < gti.HeightToCreate || tile.bSizeIsValid == false) && tile.dwMaskT > 0 && gti.HeightToLoad != (unsigned int)dwTileMaskHeight && info->bSetBy == CMD_LOADBLOCK ) //if( (gti.HeightToLoad < gti.HeightToCreate ) && tile.dwMaskT > 0 && gti.HeightToLoad != dwTileMaskHeight && // info->bSetBy == CMD_LOADBLOCK ) { //uint32_t pitchwidth = dwPitch<<1>>tile.dwSize; uint32_t pitchHeight = (info->dwTotalWords<<1)/dwPitch; if( pitchHeight == (unsigned int)dwTileMaskHeight || gti.HeightToLoad == 1 ) { gti.HeightToLoad = pitchHeight; } } if( gti.WidthToCreate < gti.WidthToLoad ) gti.WidthToCreate = gti.WidthToLoad; if( gti.HeightToCreate < gti.HeightToLoad ) gti.HeightToCreate = gti.HeightToLoad; if( info->bSetBy == CMD_LOADTILE ) { gti.LeftToLoad = (info->sl<dwSize)>>tile.dwSize; gti.TopToLoad = info->tl; } else { gti.LeftToLoad = (info->sl<dwSize)>>tile.dwSize; gti.TopToLoad = (info->tl<dwSize)>>tile.dwSize; } uint32_t total64BitWordsToLoad = (gti.HeightToLoad*gti.WidthToLoad)>>(4-tile.dwSize); if( total64BitWordsToLoad + tile.dwTMem > 0x200 ) { //TRACE0("Warning: texture loading TMEM is over range"); if( gti.WidthToLoad > gti.HeightToLoad ) { uint32_t newheight = (dwPitch << 1 )>> tile.dwSize; tile.dwWidth = gti.WidthToLoad = gti.WidthToCreate = min(newheight, (gti.WidthToLoad&0xFFFFFFFE)); tile.dwHeight = gti.HeightToCreate = gti.HeightToLoad = ((0x200 - tile.dwTMem) << (4-tile.dwSize)) / gti.WidthToLoad; } else { tile.dwHeight = gti.HeightToCreate = gti.HeightToLoad = info->dwTotalWords / ((gti.WidthToLoad << tile.dwSize) >> 1); } } // Check the info if( (info->dwTotalWords>>2) < total64BitWordsToLoad+tile.dwTMem-info->dwTmem - 4 ) { // Hack here if( (options.enableHackForGames == HACK_FOR_ZELDA||options.enableHackForGames == HACK_FOR_ZELDA_MM) && (unsigned int)tileno != gRSP.curTile ) { return false; } if( total64BitWordsToLoad+tile.dwTMem-info->dwTmem <= 0x200 ) { LOG_TEXTURE(TRACE4("Fix me, info is not covering this TMEM address,Info start: 0x%x, total=0x%x, TMEM start: 0x%x, total=0x%x", info->dwTmem,info->dwTotalWords>>2, tile.dwTMem, total64BitWordsToLoad)); } } //Check memory boundary if( gti.Address + gti.HeightToLoad*gti.Pitch >= g_dwRamSize ) { WARNING(TRACE0("Warning: texture loading TMEM is over range 3")); gti.HeightToCreate = gti.HeightToLoad = tile.dwHeight = (g_dwRamSize-gti.Address)/gti.Pitch; } return true; } bool CalculateTileSizes_method_1(int tileno, TMEMLoadMapInfo *info, TxtrInfo >i) { Tile &tile = gRDP.tiles[tileno]; //Tile &loadtile = gRDP.tiles[RDP_TXT_LOADTILE]; // Now Initialize the texture dimension int loadwidth, loadheight; int maskwidth = tile.dwMaskS ? (1 << tile.dwMaskS ) : 0; int maskheight = tile.dwMaskT ? (1 << tile.dwMaskT ) : 0; int clampwidth = abs(tile.hilite_sh - tile.hilite_sl) +1; int clampheight = abs(tile.hilite_th - tile.hilite_tl) +1; int linewidth = tile.dwLine << (5 - tile.dwSize); gti.bSwapped = info->bSwapped; if( info->bSetBy == CMD_LOADTILE ) { loadwidth = (abs(info->sh - info->sl) + 1) << info->dwSize >> tile.dwSize; loadheight = (abs(info->th - info->tl) + 1) << info->dwSize >> tile.dwSize; tile.dwPitch = info->dwWidth << info->dwSize >> 1; if( tile.dwPitch == 0 ) tile.dwPitch = 1024; // Hack for Bust-A-Move gti.LeftToLoad = (info->sl<dwSize)>>tile.dwSize; gti.TopToLoad = info->tl; } else { loadwidth = abs(tile.sh - tile.sl) +1; if( tile.dwMaskS ) { loadwidth = maskwidth; } loadheight = abs(tile.th - tile.tl) +1; if( tile.dwMaskT ) { loadheight = maskheight; } // It was a block load - the pitch is determined by the tile size if (tile.dwSize == TXT_SIZE_32b) tile.dwPitch = tile.dwLine << 4; else if (info->dxt == 0 ) { tile.dwPitch = tile.dwLine << 3; gti.bSwapped = TRUE; if( info->dwTmem != tile.dwTMem && info->dxt != 0 && info->dwSize == TXT_SIZE_16b && tile.dwSize == TXT_SIZE_4b ) conkerSwapHack = true; } else { uint32_t DXT = info->dxt; if( info->dxt > 1 ) { DXT = ReverseDXT(info->dxt, info->sh, loadwidth, tile.dwSize); } tile.dwPitch = DXT << 3; } gti.LeftToLoad = (info->sl<dwSize)>>tile.dwSize; gti.TopToLoad = (info->tl<dwSize)>>tile.dwSize; } if( options.enableHackForGames == HACK_FOR_MARIO_KART ) { if( loadwidth-maskwidth == 1 && tile.dwMaskS ) { loadwidth--; if( loadheight%2 ) loadheight--; } if( loadheight-maskheight == 1 && tile.dwMaskT ) { loadheight--; if(loadwidth%2) loadwidth--; } if( loadwidth - ((g_TI.dwWidth<>tile.dwSize) == 1 ) { loadwidth--; if( loadheight%2 ) loadheight--; } } // Limit the texture size if( g_curRomInfo.bUseSmallerTexture ) { if( tile.dwMaskS && tile.bClampS ) { if( !tile.bMirrorS ) { if( clampwidth/maskwidth >= 2 ) { clampwidth = maskwidth; tile.bForceWrapS = true; } else if( clampwidth && maskwidth/clampwidth >= 2 ) { maskwidth = clampwidth; tile.bForceClampS = true; } } else { if( clampwidth/maskwidth == 2 ) { clampwidth = maskwidth*2; tile.bForceWrapS = false; } else if( clampwidth/maskwidth > 2 ) { clampwidth = maskwidth*2; tile.bForceWrapS = true; } } } if( tile.dwMaskT && tile.bClampT ) { if( !tile.bMirrorT ) { if( clampheight/maskheight >= 2 ) { clampheight = maskheight; tile.bForceWrapT = true; } else if( clampheight && maskheight/clampheight >= 2 ) { maskwidth = clampwidth; tile.bForceClampT = true; } } else { if( clampheight/maskheight == 2 ) { clampheight = maskheight*2; tile.bForceWrapT = false; } else if( clampheight/maskheight >= 2 ) { clampheight = maskheight*2; tile.bForceWrapT = true; } } } } else { //if( clampwidth > linewidth ) clampwidth = linewidth; if( clampwidth > 512 && clampheight > 512 ) { if( clampwidth > maskwidth && maskwidth && clampheight > 256 ) clampwidth = maskwidth; if( clampheight > maskheight && maskheight && clampheight > 256 ) clampheight = maskheight; } if( tile.dwMaskS > 8 && tile.dwMaskT > 8 ) { maskwidth = loadwidth; maskheight = loadheight; } else { if( tile.dwMaskS > 10 ) maskwidth = loadwidth; if( tile.dwMaskT > 10 ) maskheight = loadheight; } } gti.Pitch = tile.dwPitch; if( tile.dwMaskS == 0 || tile.bClampS ) { gti.WidthToLoad = linewidth ? min( linewidth, maskwidth ? min(clampwidth,maskwidth) : clampwidth ) : clampwidth; if( tile.dwMaskS && clampwidth < maskwidth ) tile.dwWidth = gti.WidthToCreate = clampwidth; else tile.dwWidth = gti.WidthToCreate = max(clampwidth,maskwidth); } else { gti.WidthToLoad = loadwidth > 2 ? min(loadwidth,maskwidth) : maskwidth; if( linewidth ) gti.WidthToLoad = min( linewidth, (int)gti.WidthToLoad ); tile.dwWidth = gti.WidthToCreate = maskwidth; } if( tile.dwMaskT == 0 || tile.bClampT ) { gti.HeightToLoad = maskheight ? min(clampheight,maskheight) : clampheight; if( tile.dwMaskT && clampheight < maskheight ) tile.dwHeight = gti.HeightToCreate = clampheight; else tile.dwHeight = gti.HeightToCreate = max(clampheight,maskheight); } else { gti.HeightToLoad = loadheight > 2 ? min(loadheight,maskheight) : maskheight; tile.dwHeight = gti.HeightToCreate = maskheight; } if( options.enableHackForGames == HACK_FOR_MARIO_KART ) { if( gti.WidthToLoad - ((g_TI.dwWidth<>tile.dwSize) == 1 ) { gti.WidthToLoad--; if( gti.HeightToLoad%2 ) gti.HeightToLoad--; } } // Double check uint32_t total64BitWordsToLoad = (gti.HeightToLoad*gti.WidthToLoad)>>(4-tile.dwSize); if( total64BitWordsToLoad + tile.dwTMem > 0x200 ) { //TRACE0("Warning: texture loading tmem is over range"); if( gti.WidthToLoad > gti.HeightToLoad ) { uint32_t newheight = (tile.dwPitch << 1 )>> tile.dwSize; tile.dwWidth = gti.WidthToLoad = gti.WidthToCreate = min(newheight, (gti.WidthToLoad&0xFFFFFFFE)); tile.dwHeight = gti.HeightToCreate = gti.HeightToLoad = ((0x200 - tile.dwTMem) << (4-tile.dwSize)) / gti.WidthToLoad; } else { tile.dwHeight = gti.HeightToCreate = gti.HeightToLoad = info->dwTotalWords / ((gti.WidthToLoad << tile.dwSize) >> 1); } } // Check the info if( (info->dwTotalWords>>2) < total64BitWordsToLoad+tile.dwTMem-info->dwTmem - 4 ) { // Hack here if( (options.enableHackForGames == HACK_FOR_ZELDA||options.enableHackForGames == HACK_FOR_ZELDA_MM) && (unsigned int)tileno != gRSP.curTile ) { return false; } if( total64BitWordsToLoad+tile.dwTMem-info->dwTmem <= 0x200 ) { LOG_TEXTURE(TRACE4("Fix me, info is not covering this Tmem address,Info start: 0x%x, total=0x%x, Tmem start: 0x%x, total=0x%x", info->dwTmem,info->dwTotalWords>>2, tile.dwTMem, total64BitWordsToLoad)); } } //Check memory boundary if( gti.Address + gti.HeightToLoad*gti.Pitch >= g_dwRamSize ) { WARNING(TRACE0("Warning: texture loading tmem is over range 3")); gti.HeightToCreate = gti.HeightToLoad = tile.dwHeight = (g_dwRamSize-gti.Address)/gti.Pitch; } return true; } TxtrCacheEntry* LoadTexture(uint32_t tileno) { //TxtrCacheEntry *pEntry = NULL; TxtrInfo gti; uint32_t *rdram_uint32_t = (uint32_t*)gfx_info.RDRAM; Tile &tile = gRDP.tiles[tileno]; // Retrieve the tile loading info uint32_t infoTmemAddr = tile.dwTMem; TMEMLoadMapInfo *info = &g_tmemLoadAddrMap[infoTmemAddr]; if( !IsTmemFlagValid(infoTmemAddr) ) { infoTmemAddr = GetValidTmemInfoIndex(infoTmemAddr); info = &g_tmemLoadAddrMap[infoTmemAddr]; } if( info->dwFormat != tile.dwFormat ) { // Check the tile format, hack for Zelda's road if( tileno != gRSP.curTile && tile.dwTMem == gRDP.tiles[gRSP.curTile].dwTMem && tile.dwFormat != gRDP.tiles[gRSP.curTile].dwFormat ) { //TRACE1("Tile %d format is not matching the loaded texture format", tileno); return NULL; } } gti = tile; // Copy tile info to textureInfo entry gti.TLutFmt = gRDP.otherMode.text_tlut <dwLoadAddress+(tile.dwTMem-infoTmemAddr)*8) & (g_dwRamSize-1) ; gti.pPhysicalAddress = ((uint8_t*)rdram_uint32_t) + gti.Address; gti.tileNo = tileno; if( g_curRomInfo.bTxtSizeMethod2 ) { if( !CalculateTileSizes_method_2(tileno, info, gti) ) return NULL; } else { if( !CalculateTileSizes_method_1(tileno, info, gti) ) return NULL; } LOG_TEXTURE( { TRACE0("Loading texture:\n"); DebuggerAppendMsg("Left: %d, Top: %d, Width: %d, Height: %d, Size to Load (%d, %d)", gti.LeftToLoad, gti.TopToLoad, gti.WidthToCreate, gti.HeightToCreate, gti.WidthToLoad, gti.HeightToLoad); DebuggerAppendMsg("Pitch: %d, Addr: 0x%08x", gti.Pitch, gti.Address); }); // Option for faster loading tiles if( g_curRomInfo.bFastLoadTile && info->bSetBy == CMD_LOADTILE && ((gti.Pitch<<1)>>gti.Size) <= 0x400 //&& ((gti.Pitch<<1)>>gti.Size) > 128 && status.primitiveType == PRIM_TEXTRECT ) { uint32_t idx = tileno-gRSP.curTile; status.LargerTileRealLeft[idx] = gti.LeftToLoad; gti.LeftToLoad=0; gti.WidthToLoad = gti.WidthToCreate = ((gti.Pitch<<1)>>gti.Size); status.UseLargerTile[idx]=true; } // Loading the textures by using texture cache manager return gTextureManager.GetTexture(>i, true, true, true); // Load the texture by using texture cache } void PrepareTextures() { if( gRDP.textureIsChanged || !currentRomOptions.bFastTexCRC || CRender::g_pRender->m_pColorCombiner->m_pDecodedMux->m_ColorTextureFlag[0] || CRender::g_pRender->m_pColorCombiner->m_pDecodedMux->m_ColorTextureFlag[1] ) { status.UseLargerTile[0]=false; status.UseLargerTile[1]=false; int tilenos[2]; if( CRender::g_pRender->IsTexel0Enable() || gRDP.otherMode.cycle_type == CYCLE_TYPE_COPY ) tilenos[0] = gRSP.curTile; else tilenos[0] = -1; if( gRSP.curTile<7 && CRender::g_pRender->IsTexel1Enable() ) tilenos[1] = gRSP.curTile+1; else tilenos[1] = -1; for( int i=0; i<2; i++ ) { if( tilenos[i] < 0 ) continue; if( CRender::g_pRender->m_pColorCombiner->m_pDecodedMux->m_ColorTextureFlag[i] ) { TxtrCacheEntry *pEntry = gTextureManager.GetConstantColorTexture(CRender::g_pRender->m_pColorCombiner->m_pDecodedMux->m_ColorTextureFlag[i]); CRender::g_pRender->SetCurrentTexture( tilenos[i], pEntry->pTexture, 4, 4, pEntry); } else { TxtrCacheEntry *pEntry = LoadTexture(tilenos[i]); if (pEntry && pEntry->pTexture ) { CRender::g_pRender->SetCurrentTexture( tilenos[i], pEntry->pTexture, pEntry->ti.WidthToLoad, pEntry->ti.HeightToLoad, pEntry); } else { pEntry = gTextureManager.GetBlackTexture(); CRender::g_pRender->SetCurrentTexture( tilenos[i], pEntry->pTexture, 4, 4, pEntry); _VIDEO_DisplayTemporaryMessage("Fail to load texture, use black to replace"); } } } gRDP.textureIsChanged = false; } } extern uint32_t g_TxtLoadBy;; void DLParser_LoadTLut(Gfx *gfx) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; gRDP.textureIsChanged = true; uint32_t tileno = gfx->loadtile.tile; uint32_t uls = gfx->loadtile.sl/4; uint32_t ult = gfx->loadtile.tl/4; uint32_t lrs = gfx->loadtile.sh/4; uint32_t lrt = gfx->loadtile.th/4; #ifdef DEBUGGER uint32_t dwTLutFmt = (gRDP.otherModeH >> RSP_SETOTHERMODE_SHIFT_TEXTLUT)&0x3; #endif // Starting location in the palettes uint32_t dwTMEMOffset = gRDP.tiles[tileno].dwTMem - 256; // Number to copy uint32_t dwCount = ((uint16_t)((gfx->words.w1) >> 14) & 0x03FF) + 1; uint32_t dwRDRAMOffset = 0; Tile &tile = gRDP.tiles[tileno]; tile.bForceWrapS = tile.bForceWrapT = tile.bForceClampS = tile.bForceClampT = false; tile.hilite_sl = tile.sl = uls; tile.hilite_tl = tile.tl = ult; tile.sh = lrs; tile.th = lrt; tile.bSizeIsValid = true; tile.lastTileCmd = CMD_LOADTLUT; #ifdef DEBUGGER /* if((((gfx->words.w0)>>12)&0x3) != 0 || (((gfx->words.w0))&0x3) != 0 || (((gfx->words.w1)>>12)&0x3) != 0 || (((gfx->words.w1))&0x3) != 0) TRACE0("Load tlut, sl,tl,sh,th are not integers"); */ #endif dwCount = (lrs - uls)+1; dwRDRAMOffset = (uls + ult*g_TI.dwWidth )*2; uint32_t dwPalAddress = g_TI.dwAddr + dwRDRAMOffset; //Copy PAL to the PAL memory uint16_t *srcPal = (uint16_t*)(rdram_u8 + (dwPalAddress& (g_dwRamSize-1)) ); for (uint32_t i=0; iloadtile.tile; uint32_t uls = gfx->loadtile.sl; uint32_t ult = gfx->loadtile.tl; uint32_t lrs = gfx->loadtile.sh; uint32_t dxt = gfx->loadtile.th; // 1.11 fixed point Tile &tile = gRDP.tiles[tileno]; tile.bForceWrapS = tile.bForceWrapT = tile.bForceClampS = tile.bForceClampT = false; uint32_t size = lrs+1; if( tile.dwSize == TXT_SIZE_32b ) size<<=1; SetTmemFlag(tile.dwTMem, size>>2); TMEMLoadMapInfo &info = g_tmemLoadAddrMap[tile.dwTMem]; info.bSwapped = (dxt == 0? TRUE : FALSE); info.sl = tile.hilite_sl = tile.sl = uls; info.sh = tile.hilite_sh = tile.sh = lrs; info.tl = tile.tl = ult; info.th = tile.th = dxt; tile.bSizeIsValid = false; for( int i=0; i<8; i++ ) { if( gRDP.tiles[i].dwTMem == tile.dwTMem ) tile.lastTileCmd = CMD_LOADBLOCK; } info.dwLoadAddress = g_TI.dwAddr; info.bSetBy = CMD_LOADBLOCK; info.dxt = dxt; info.dwLine = tile.dwLine; info.dwFormat = g_TI.dwFormat; info.dwSize = g_TI.dwSize; info.dwWidth = g_TI.dwWidth; info.dwTotalWords = size; info.dwTmem = tile.dwTMem; if( gRDP.tiles[tileno].dwTMem == 0 ) { if( size >= 1024 ) { memcpy(&g_tmemInfo0, &info, sizeof(TMEMLoadMapInfo) ); g_tmemInfo0.dwTotalWords = size>>2; } if( size == 2048 ) { memcpy(&g_tmemInfo1, &info, sizeof(TMEMLoadMapInfo) ); g_tmemInfo1.dwTotalWords = size>>2; } } else if( tile.dwTMem == 0x100 ) { if( size == 1024 ) { memcpy(&g_tmemInfo1, &info, sizeof(TMEMLoadMapInfo) ); g_tmemInfo1.dwTotalWords = size>>2; } } g_TxtLoadBy = CMD_LOADBLOCK; if( options.bUseFullTMEM ) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; uint32_t bytes = (lrs + 1) << tile.dwSize >> 1; uint32_t address = g_TI.dwAddr + ult * g_TI.bpl + (uls << g_TI.dwSize >> 1); if ((bytes == 0) || ((address + bytes) > g_dwRamSize) || (((tile.dwTMem << 3) + bytes) > 4096)) { return; } uint64_t* src = (uint64_t*)(rdram_u8 + address); uint64_t* dest = &g_Tmem.g_Tmem64bit[tile.dwTMem]; if( dxt > 0) { void (*Interleave)( void *mem, uint32_t numDWords ); uint32_t line = (2047 + dxt) / dxt; uint32_t bpl = line << 3; uint32_t height = bytes / bpl; if (tile.dwSize == TXT_SIZE_32b) Interleave = QWordInterleave; else Interleave = DWordInterleave; for (uint32_t y = 0; y < height; y++) { UnswapCopy( src, dest, bpl ); if (y & 1) Interleave( dest, line ); src += line; dest += line; } } else { UnswapCopy( src, dest, bytes ); } } LOG_UCODE(" Tile:%d (%d,%d - %d) DXT:0x%04x\n", tileno, uls, ult, lrs, dxt); LOG_TEXTURE( { DebuggerAppendMsg("LoadBlock:%d (%d,%d,%d) DXT:0x%04x(%X)\n", tileno, uls, ult, (((gfx->words.w1)>>12)&0x0FFF), dxt, ((gfx->words.w1)&0x0FFF)); }); DEBUGGER_PAUSE_COUNT_N(NEXT_TEXTURE_CMD); } void swap(uint32_t &a, uint32_t &b) { uint32_t temp = a; a = b; b = temp; } void DLParser_LoadTile(Gfx *gfx) { gRDP.textureIsChanged = true; uint32_t tileno = gfx->loadtile.tile; uint32_t uls = gfx->loadtile.sl/4; uint32_t ult = gfx->loadtile.tl/4; uint32_t lrs = gfx->loadtile.sh/4; uint32_t lrt = gfx->loadtile.th/4; Tile &tile = gRDP.tiles[tileno]; tile.bForceWrapS = tile.bForceWrapT = tile.bForceClampS = tile.bForceClampT = false; if (lrt < ult) swap(lrt, ult); if (lrs < uls) swap(lrs, uls); tile.hilite_sl = tile.sl = uls; tile.hilite_tl = tile.tl = ult; tile.hilite_sh = tile.sh = lrs; tile.hilite_th = tile.th = lrt; tile.bSizeIsValid = true; // compute block height, and bpl of source and destination uint32_t bpl = (lrs - uls + 1) << tile.dwSize >> 1; uint32_t height = lrt - ult + 1; uint32_t line = tile.dwLine; if (tile.dwSize == TXT_SIZE_32b) line <<= 1; if (((tile.dwTMem << 3) + line * height) > 4096) // check destination ending point (TMEM is 4k bytes) return; if( options.bUseFullTMEM ) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; void (*Interleave)( void *mem, uint32_t numDWords ); if( g_TI.bpl == 0 ) { if( options.enableHackForGames == HACK_FOR_BUST_A_MOVE ) { g_TI.bpl = 1024; // Hack for Bust-A-Move } else { TRACE0("Warning: g_TI.bpl = 0" ); } } uint32_t address = g_TI.dwAddr + tile.tl * g_TI.bpl + (tile.sl << g_TI.dwSize >> 1); uint64_t* src = (uint64_t*)&rdram_u8[address]; uint8_t* dest = (uint8_t*)&g_Tmem.g_Tmem64bit[tile.dwTMem]; if ((address + height * bpl) > g_dwRamSize) // check source ending point { return; } // Line given for 32-bit is half what it seems it should since they split the // high and low words. I'm cheating by putting them together. if (tile.dwSize == TXT_SIZE_32b) { Interleave = QWordInterleave; } else { Interleave = DWordInterleave; } if( tile.dwLine == 0 ) { //tile.dwLine = 1; return; } for (uint32_t y = 0; y < height; y++) { UnswapCopy( src, dest, bpl ); if (y & 1) Interleave( dest, line ); src += g_TI.bpl; dest += line; } } for( int i=0; i<8; i++ ) { if( gRDP.tiles[i].dwTMem == tile.dwTMem ) gRDP.tiles[i].lastTileCmd = CMD_LOADTILE; } uint32_t size = line * height; SetTmemFlag(tile.dwTMem,size ); LOG_TEXTURE( { DebuggerAppendMsg("LoadTile:%d (%d,%d) -> (%d,%d) [%d x %d]\n", tileno, uls, ult, lrs, lrt, (lrs - uls)+1, (lrt - ult)+1); }); DEBUGGER_PAUSE_COUNT_N(NEXT_TEXTURE_CMD); LOG_UCODE(" Tile:%d (%d,%d) -> (%d,%d) [%d x %d]", tileno, uls, ult, lrs, lrt, (lrs - uls)+1, (lrt - ult)+1); TMEMLoadMapInfo &info = g_tmemLoadAddrMap[tile.dwTMem]; info.dwLoadAddress = g_TI.dwAddr; info.dwFormat = g_TI.dwFormat; info.dwSize = g_TI.dwSize; info.dwWidth = g_TI.dwWidth; info.sl = uls; info.sh = lrs; info.tl = ult; info.th = lrt; info.dxt = 0; info.dwLine = tile.dwLine; info.dwTmem = tile.dwTMem; info.dwTotalWords = size<<2; info.bSetBy = CMD_LOADTILE; info.bSwapped =FALSE; g_TxtLoadBy = CMD_LOADTILE; if( tile.dwTMem == 0 ) { if( size >= 256 ) { memcpy(&g_tmemInfo0, &info, sizeof(TMEMLoadMapInfo) ); g_tmemInfo0.dwTotalWords = size; } if( size == 512 ) { memcpy(&g_tmemInfo1, &info, sizeof(TMEMLoadMapInfo) ); g_tmemInfo1.dwTotalWords = size; } } else if( tile.dwTMem == 0x100 ) { if( size == 256 ) { memcpy(&g_tmemInfo1, &info, sizeof(TMEMLoadMapInfo) ); g_tmemInfo1.dwTotalWords = size; } } } const char *pszOnOff[2] = {"Off", "On"}; uint32_t lastSetTile; void DLParser_SetTile(Gfx *gfx) { gRDP.textureIsChanged = true; uint32_t tileno = gfx->settile.tile; Tile &tile = gRDP.tiles[tileno]; tile.bForceWrapS = tile.bForceWrapT = tile.bForceClampS = tile.bForceClampT = false; lastSetTile = tileno; tile.dwFormat = gfx->settile.fmt; tile.dwSize = gfx->settile.siz; tile.dwLine = gfx->settile.line; tile.dwTMem = gfx->settile.tmem; tile.dwPalette = gfx->settile.palette; tile.bClampT = gfx->settile.ct; tile.bMirrorT = gfx->settile.mt; tile.dwMaskT = gfx->settile.maskt; tile.dwShiftT = gfx->settile.shiftt; tile.bClampS = gfx->settile.cs; tile.bMirrorS = gfx->settile.ms; tile.dwMaskS = gfx->settile.masks; tile.dwShiftS = gfx->settile.shifts; tile.fShiftScaleS = 1.0f; if( tile.dwShiftS ) { if( tile.dwShiftS > 10 ) { tile.fShiftScaleS = (float)(1 << (16 - tile.dwShiftS)); } else { tile.fShiftScaleS = (float)1.0f/(1 << tile.dwShiftS); } } tile.fShiftScaleT = 1.0f; if( tile.dwShiftT ) { if( tile.dwShiftT > 10 ) { tile.fShiftScaleT = (float)(1 << (16 - tile.dwShiftT)); } else { tile.fShiftScaleT = (float)1.0f/(1 << tile.dwShiftT); } } // Hack for DK64 /* if( tile.dwMaskS > 0 && tile.dwMaskT > 0 && tile.dwMaskS < 8 && tile.dwMaskT < 8 ) { tile.sh = tile.sl + (1<loadtile.tile; int sl = gfx->loadtile.sl; int tl = gfx->loadtile.tl; int sh = gfx->loadtile.sh; int th = gfx->loadtile.th; Tile &tile = gRDP.tiles[tileno]; tile.bForceWrapS = tile.bForceWrapT = tile.bForceClampS = tile.bForceClampT = false; if( options.bUseFullTMEM ) { tile.bSizeIsValid = true; tile.hilite_sl = tile.sl = sl / 4; tile.hilite_tl = tile.tl = tl / 4; tile.hilite_sh = tile.sh = sh / 4; tile.hilite_th = tile.th = th / 4; tile.fhilite_sl = tile.fsl = sl / 4.0f; tile.fhilite_tl = tile.ftl = tl / 4.0f; tile.fhilite_sh = tile.fsh = sh / 4.0f; tile.fhilite_th = tile.fth = th / 4.0f; tile.lastTileCmd = CMD_SETTILE_SIZE; } else { if( tile.lastTileCmd != CMD_SETTILE_SIZE ) { tile.bSizeIsValid = true; if( sl/4 > sh/4 || tl/4 > th/4 || (sh == 0 && tile.dwShiftS==0 && th == 0 && tile.dwShiftT ==0 ) ) { #ifdef DEBUGGER if( sl != 0 || tl != 0 || sh != 0 || th != 0 ) { if( tile.dwMaskS==0 || tile.dwMaskT==0 ) TRACE0("Check me, setTileSize is not correct"); } #endif tile.bSizeIsValid = false; } tile.hilite_sl = tile.sl = sl / 4; tile.hilite_tl = tile.tl = tl / 4; tile.hilite_sh = tile.sh = sh / 4; tile.hilite_th = tile.th = th / 4; tile.fhilite_sl = tile.fsl = sl / 4.0f; tile.fhilite_tl = tile.ftl = tl / 4.0f; tile.fhilite_sh = tile.fsh = sh / 4.0f; tile.fhilite_th = tile.fth = th / 4.0f; tile.lastTileCmd = CMD_SETTILE_SIZE; } else { tile.fhilite_sh = tile.fsh; tile.fhilite_th = tile.fth; tile.fhilite_sl = tile.fsl = (sl>0x7ff ? (sl-0xfff) : sl)/4.0f; tile.fhilite_tl = tile.ftl = (tl>0x7ff ? (tl-0xfff) : tl)/4.0f; tile.hilite_sl = sl>0x7ff ? (sl-0xfff) : sl; tile.hilite_tl = tl>0x7ff ? (tl-0xfff) : tl; tile.hilite_sl /= 4; tile.hilite_tl /= 4; tile.hilite_sh = sh/4; tile.hilite_th = th/4; tile.lastTileCmd = CMD_SETTILE_SIZE; } } LOG_TEXTURE( { DebuggerAppendMsg("SetTileSize:%d (%d/4,%d/4) -> (%d/4,%d/4) [%d x %d]\n", tileno, sl, tl, sh, th, ((sh/4) - (sl/4)) + 1, ((th/4) - (tl/4)) + 1); }); DEBUGGER_PAUSE_COUNT_N(NEXT_TEXTURE_CMD); LOG_UCODE(" Tile:%d (%d,%d) -> (%d,%d) [%d x %d]", tileno, sl/4, tl/4, sh/4, th/4, ((sh/4) - (sl/4)) + 1, ((th/4) - (tl/4)) + 1); } extern const char *pszImgFormat[8];// = {"RGBA", "YUV", "CI", "IA", "I", "?1", "?2", "?3"}; extern const char *pszImgSize[4];// = {"4", "8", "16", "32"}; void DLParser_SetTImg(Gfx *gfx) { gRDP.textureIsChanged = true; g_TI.dwFormat = gfx->setimg.fmt; g_TI.dwSize = gfx->setimg.siz; g_TI.dwWidth = gfx->setimg.width + 1; g_TI.dwAddr = RSPSegmentAddr((gfx->setimg.addr)); g_TI.bpl = g_TI.dwWidth << g_TI.dwSize >> 1; #ifdef DEBUGGER if( g_TI.dwAddr == 0x00ffffff) { TRACE0("Check me here in setTimg"); } LOG_TEXTURE(TRACE4("SetTImage: 0x%08x Fmt: %s/%s Width in Pixel: %d\n", g_TI.dwAddr, pszImgFormat[g_TI.dwFormat], pszImgSize[g_TI.dwSize], g_TI.dwWidth)); DEBUGGER_PAUSE_COUNT_N(NEXT_TEXTURE_CMD); LOG_UCODE("Image: 0x%08x Fmt: %s/%s Width in Pixel: %d", g_TI.dwAddr, pszImgFormat[g_TI.dwFormat], pszImgSize[g_TI.dwSize], g_TI.dwWidth); #endif } void DLParser_TexRect(Gfx *gfx) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; //Gtexrect *gtextrect = (Gtexrect *)gfx; if( !status.bCIBufferIsRendered ) g_pFrameBufferManager->ActiveTextureBuffer(); status.primitiveType = PRIM_TEXTRECT; // This command used 128bits, and not 64 bits. This means that we have to look one // Command ahead in the buffer, and update the PC. uint32_t dwPC = gDlistStack[gDlistStackPointer].pc; // This points to the next instruction uint32_t dwCmd2 = *(uint32_t *)(rdram_u8 + dwPC+4); uint32_t dwCmd3 = *(uint32_t *)(rdram_u8 + dwPC+4+8); uint32_t dwHalf1 = *(uint32_t *)(rdram_u8 + dwPC); uint32_t dwHalf2 = *(uint32_t *)(rdram_u8 + dwPC+8); if( options.enableHackForGames == HACK_FOR_ALL_STAR_BASEBALL || options.enableHackForGames == HACK_FOR_MLB ) { if( ((dwHalf1>>24) == 0xb4 || (dwHalf1>>24) == 0xb3 || (dwHalf1>>24) == 0xb2 || (dwHalf1>>24) == 0xe1) && ((dwHalf2>>24) == 0xb4 || (dwHalf2>>24) == 0xb3 || (dwHalf2>>24) == 0xb2 || (dwHalf2>>24) == 0xf1) ) { // Increment PC so that it points to the right place gDlistStack[gDlistStackPointer].pc += 16; } else { // Hack for some games, All_Star_Baseball_2000 gDlistStack[gDlistStackPointer].pc += 8; dwCmd3 = dwCmd2; //dwCmd2 = dwHalf1; //dwCmd2 = 0; // fix me here dwCmd2 = (((dwHalf1>>12)&0x03FF)<<17) | (((dwHalf1)&0x03FF)<<1); } } else { gDlistStack[gDlistStackPointer].pc += 16; } // Hack for Mario Tennis if( !status.bHandleN64RenderTexture && g_CI.dwAddr == g_ZI.dwAddr ) { return; } LOG_UCODE("0x%08x: %08x %08x", dwPC, *(uint32_t *)(rdram_u8 + dwPC+0), *(uint32_t *)(rdram_u8 + dwPC+4)); LOG_UCODE("0x%08x: %08x %08x", dwPC+8, *(uint32_t *)(rdram_u8 + dwPC+8), *(uint32_t *)(rdram_u8 + dwPC+8+4)); uint32_t dwXH = (((gfx->words.w0)>>12)&0x0FFF)/4; uint32_t dwYH = (((gfx->words.w0) )&0x0FFF)/4; uint32_t tileno = ((gfx->words.w1)>>24)&0x07; uint32_t dwXL = (((gfx->words.w1)>>12)&0x0FFF)/4; uint32_t dwYL = (((gfx->words.w1) )&0x0FFF)/4; uint16_t uS = (uint16_t)( dwCmd2>>16)&0xFFFF; uint16_t uT = (uint16_t)( dwCmd2 )&0xFFFF; uint16_t uDSDX = (uint16_t)(( dwCmd3>>16)&0xFFFF); uint16_t uDTDY = (uint16_t)(( dwCmd3 )&0xFFFF); if( (int)dwXL >= gRDP.scissor.right || (int)dwYL >= gRDP.scissor.bottom || (int)dwXH < gRDP.scissor.left || (int)dwYH < gRDP.scissor.top ) { // Clipping return; } short s16S = *(short*)(&uS); short s16T = *(short*)(&uT); short s16DSDX = *(short*)(&uDSDX); short s16DTDY = *(short*)(&uDTDY); uint32_t curTile = gRSP.curTile; ForceMainTextureIndex(tileno); float fS0 = s16S / 32.0f; float fT0 = s16T / 32.0f; float fDSDX = s16DSDX / 1024.0f; float fDTDY = s16DTDY / 1024.0f; uint32_t cycletype = gRDP.otherMode.cycle_type; if (cycletype == CYCLE_TYPE_COPY) { fDSDX /= 4.0f; // In copy mode 4 pixels are copied at once. dwXH++; dwYH++; } else if (cycletype == CYCLE_TYPE_FILL) { dwXH++; dwYH++; } if( fDSDX == 0 ) fDSDX = 1; if( fDTDY == 0 ) fDTDY = 1; float fS1 = fS0 + (fDSDX * (dwXH - dwXL)); float fT1 = fT0 + (fDTDY * (dwYH - dwYL)); LOG_UCODE(" Tile:%d Screen(%d,%d) -> (%d,%d)", tileno, dwXL, dwYL, dwXH, dwYH); LOG_UCODE(" Tex:(%#5f,%#5f) -> (%#5f,%#5f) (DSDX:%#5f DTDY:%#5f)", fS0, fT0, fS1, fT1, fDSDX, fDTDY); LOG_UCODE(""); float t0u0 = (fS0-gRDP.tiles[tileno].hilite_sl) * gRDP.tiles[tileno].fShiftScaleS; float t0v0 = (fT0-gRDP.tiles[tileno].hilite_tl) * gRDP.tiles[tileno].fShiftScaleT; float t0u1 = t0u0 + (fDSDX * (dwXH - dwXL))*gRDP.tiles[tileno].fShiftScaleS; float t0v1 = t0v0 + (fDTDY * (dwYH - dwYL))*gRDP.tiles[tileno].fShiftScaleT; if( dwXL==0 && dwYL==0 && dwXH==windowSetting.fViWidth-1 && dwYH==windowSetting.fViHeight-1 && t0u0 == 0 && t0v0==0 && t0u1==0 && t0v1==0 ) { //Using TextRect to clear the screen } else { if( status.bHandleN64RenderTexture && //status.bDirectWriteIntoRDRAM && g_pRenderTextureInfo->CI_Info.dwFormat == gRDP.tiles[tileno].dwFormat && g_pRenderTextureInfo->CI_Info.dwSize == gRDP.tiles[tileno].dwSize && gRDP.tiles[tileno].dwFormat == TXT_FMT_CI && gRDP.tiles[tileno].dwSize == TXT_SIZE_8b ) { if( options.enableHackForGames == HACK_FOR_YOSHI ) { // Hack for Yoshi background image PrepareTextures(); TexRectToFrameBuffer_8b(dwXL, dwYL, dwXH, dwYH, t0u0, t0v0, t0u1, t0v1, tileno); DEBUGGER_PAUSE_AT_COND_AND_DUMP_COUNT_N((eventToPause == NEXT_FLUSH_TRI || eventToPause == NEXT_TEXTRECT), { DebuggerAppendMsg("TexRect: tile=%d, X0=%d, Y0=%d, X1=%d, Y1=%d,\nfS0=%f, fT0=%f, ScaleS=%f, ScaleT=%f\n", gRSP.curTile, dwXL, dwYL, dwXH, dwYH, fS0, fT0, fDSDX, fDTDY); DebuggerAppendMsg("Pause after TexRect for Yoshi\n"); }); } else { if( frameBufferOptions.bUpdateCIInfo ) { PrepareTextures(); TexRectToFrameBuffer_8b(dwXL, dwYL, dwXH, dwYH, t0u0, t0v0, t0u1, t0v1, tileno); } if( !status.bDirectWriteIntoRDRAM ) { CRender::g_pRender->TexRect(dwXL, dwYL, dwXH, dwYH, fS0, fT0, fDSDX, fDTDY, false, 0xFFFFFFFF); status.dwNumTrisRendered += 2; } } } else { CRender::g_pRender->TexRect(dwXL, dwYL, dwXH, dwYH, fS0, fT0, fDSDX, fDTDY, false, 0xFFFFFFFF); status.bFrameBufferDrawnByTriangles = true; status.dwNumTrisRendered += 2; } } if( status.bHandleN64RenderTexture ) g_pRenderTextureInfo->maxUsedHeight = max(g_pRenderTextureInfo->maxUsedHeight,(int)dwYH); ForceMainTextureIndex(curTile); } void DLParser_TexRectFlip(Gfx *gfx) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; status.bCIBufferIsRendered = true; status.primitiveType = PRIM_TEXTRECTFLIP; // This command used 128bits, and not 64 bits. This means that we have to look one // Command ahead in the buffer, and update the PC. uint32_t dwPC = gDlistStack[gDlistStackPointer].pc; // This points to the next instruction uint32_t dwCmd2 = *(uint32_t *)(rdram_u8 + dwPC+4); uint32_t dwCmd3 = *(uint32_t *)(rdram_u8 + dwPC+4+8); // Increment PC so that it points to the right place gDlistStack[gDlistStackPointer].pc += 16; uint32_t dwXH = (((gfx->words.w0)>>12)&0x0FFF)/4; uint32_t dwYH = (((gfx->words.w0) )&0x0FFF)/4; uint32_t tileno = ((gfx->words.w1)>>24)&0x07; uint32_t dwXL = (((gfx->words.w1)>>12)&0x0FFF)/4; uint32_t dwYL = (((gfx->words.w1) )&0x0FFF)/4; uint32_t dwS = ( dwCmd2>>16)&0xFFFF; uint32_t dwT = ( dwCmd2 )&0xFFFF; int nDSDX = (int)(short)(( dwCmd3>>16)&0xFFFF); int nDTDY = (int)(short)(( dwCmd3 )&0xFFFF); uint32_t curTile = gRSP.curTile; ForceMainTextureIndex(tileno); float fS0 = (float)dwS / 32.0f; float fT0 = (float)dwT / 32.0f; float fDSDX = (float)nDSDX / 1024.0f; float fDTDY = (float)nDTDY / 1024.0f; uint32_t cycletype = gRDP.otherMode.cycle_type; if (cycletype == CYCLE_TYPE_COPY) { fDSDX /= 4.0f; // In copy mode 4 pixels are copied at once. dwXH++; dwYH++; } else if (cycletype == CYCLE_TYPE_FILL) { dwXH++; dwYH++; } float fS1 = fS0 + (fDSDX * (dwYH - dwYL)); float fT1 = fT0 + (fDTDY * (dwXH - dwXL)); LOG_UCODE(" Tile:%d (%d,%d) -> (%d,%d)", tileno, dwXL, dwYL, dwXH, dwYH); LOG_UCODE(" Tex:(%#5f,%#5f) -> (%#5f,%#5f) (DSDX:%#5f DTDY:%#5f)", fS0, fT0, fS1, fT1, fDSDX, fDTDY); LOG_UCODE(""); float t0u0 = (fS0) * gRDP.tiles[tileno].fShiftScaleS-gRDP.tiles[tileno].sl; float t0v0 = (fT0) * gRDP.tiles[tileno].fShiftScaleT-gRDP.tiles[tileno].tl; float t0u1 = t0u0 + (fDSDX * (dwYH - dwYL))*gRDP.tiles[tileno].fShiftScaleS; float t0v1 = t0v0 + (fDTDY * (dwXH - dwXL))*gRDP.tiles[tileno].fShiftScaleT; CRender::g_pRender->TexRectFlip(dwXL, dwYL, dwXH, dwYH, t0u0, t0v0, t0u1, t0v1); status.dwNumTrisRendered += 2; if( status.bHandleN64RenderTexture ) g_pRenderTextureInfo->maxUsedHeight = max(g_pRenderTextureInfo->maxUsedHeight,int(dwYL+(dwXH-dwXL))); ForceMainTextureIndex(curTile); } /************************************************************************/ /* */ /************************************************************************/ /* * TMEM emulation * There are 0x200's 64bits entry in TMEM * Usually, textures are loaded into TMEM at 0x0, and TLUT is loaded at 0x100 * of course, the whole TMEM can be used by textures if TLUT is not used, and TLUT * can be at other address of TMEM. * * We don't want to emulate TMEM by creating a block of memory for TMEM and load * everything into the block of memory, this will be slow. */ typedef struct TmemInfoEntry{ uint32_t start; uint32_t length; uint32_t rdramAddr; TmemInfoEntry* next; } TmemInfoEntry; const int tmenMaxEntry=20; TmemInfoEntry tmenEntryBuffer[20]={{0}}; TmemInfoEntry *g_pTMEMInfo=NULL; TmemInfoEntry *g_pTMEMFreeList=tmenEntryBuffer; void TMEM_Init() { g_pTMEMInfo=NULL; g_pTMEMFreeList=tmenEntryBuffer; int i; for( i=0; (i < (tmenMaxEntry-1)); i++ ) { tmenEntryBuffer[i].start=0; tmenEntryBuffer[i].length=0; tmenEntryBuffer[i].rdramAddr=0; tmenEntryBuffer[i].next = &(tmenEntryBuffer[i+1]); } tmenEntryBuffer[i-1].next = NULL; } void TMEM_SetBlock(uint32_t tmemstart, uint32_t length, uint32_t rdramaddr) { TmemInfoEntry *p=g_pTMEMInfo; if( p == NULL ) { // Move an entry from freelist and link it to the header p = g_pTMEMFreeList; g_pTMEMFreeList = g_pTMEMFreeList->next; p->start = tmemstart; p->length = length; p->rdramAddr = rdramaddr; p->next = NULL; } else { while ( tmemstart > (p->start+p->length) ) { if( p->next != NULL ) { p = p->next; continue; } else { break; } } if ( p->start == tmemstart ) { // need to replace the block of 'p' // or append a new block depend the block lengths if( length == p->length ) { p->rdramAddr = rdramaddr; return; } else if( length < p->length ) { TmemInfoEntry *newentry = g_pTMEMFreeList; g_pTMEMFreeList = g_pTMEMFreeList->next; newentry->length = p->length - length; newentry->next = p->next; newentry->rdramAddr = p->rdramAddr + p->length; newentry->start = p->start + p->length; p->length = length; p->next = newentry; p->rdramAddr = rdramaddr; } } else if( p->start > tmemstart ) { // p->start > tmemstart, need to insert the new block before 'p' TmemInfoEntry *newentry = g_pTMEMFreeList; g_pTMEMFreeList = g_pTMEMFreeList->next; if( length+tmemstart < p->start+p->length ) { newentry->length = p->length - length; newentry->next = p->next; newentry->rdramAddr = p->rdramAddr + p->length; newentry->start = p->start + p->length; p->length = length; p->next = newentry; p->rdramAddr = rdramaddr; p->start = tmemstart; } else if( length+tmemstart == p->start+p->length ) { // TODO: Implement } } else { // TODO: Implement } } } uint32_t TMEM_GetRdramAddr(uint32_t tmemstart, uint32_t length) { return 0; } /* * New implementation of texture loading */ bool IsTmemFlagValid(uint32_t tmemAddr) { uint32_t index = tmemAddr>>5; uint32_t bitIndex = (tmemAddr&0x1F); return ((g_TmemFlag[index] & (1<>5; uint32_t bitIndex = (tmemAddr&0x1F); if ((g_TmemFlag[index] & (1<>5; uint32_t bitIndex = (tmemAddr&0x1F); #ifdef DEBUGGER if( size > 0x200 ) { DebuggerAppendMsg("Check me: tmemaddr=%X, size=%x", tmemAddr, size); size = 0x200-tmemAddr; } #endif if( bitIndex == 0 ) { uint32_t i; for( i=0; i< (size>>5); i++ ) { g_TmemFlag[index+i] = 0; } if( (size&0x1F) != 0 ) { //ErrorMsg("Check me: tmemaddr=%X, size=%x", tmemAddr, size); g_TmemFlag[index+i] &= ~((1<<(size&0x1F))-1); } g_TmemFlag[index] |= 1; } else { if( bitIndex + size <= 0x1F ) { uint32_t val = g_TmemFlag[index]; uint32_t mask = (1<<(bitIndex))-1; mask |= ~((1<<(bitIndex + size))-1); val &= mask; val |= (1<>5); i++ ) { g_TmemFlag[index+i] = 0; } if( (size&0x1F) != 0 ) { //ErrorMsg("Check me: tmemaddr=%X, size=%x", tmemAddr, size); g_TmemFlag[index+i] &= ~((1<<(size&0x1F))-1); } } } } #undef min #undef max #endif gles2rice/src/RSP_GBI2.h000664 001750 001750 00000070437 12655644434 015760 0ustar00sergiosergio000000 000000 /* Copyright (C) 2002 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "Render.h" #include "Timing.h" void RSP_GBI2_Vtx(Gfx *gfx) { uint32_t addr = RSPSegmentAddr((gfx->gbi2vtx.addr)); int vend = gfx->gbi2vtx.vend/2; int n = gfx->gbi2vtx.n; int v0 = vend - n; LOG_UCODE(" Vtx: Address 0x%08x, vEnd: %d, v0: %d, Num: %d", addr, vend, v0, n); if( vend > 64 ) { DebuggerAppendMsg("Warning, attempting to load into invalid vertex positions, v0=%d, n=%d", v0, n); return; } if ((addr + (n*16)) > g_dwRamSize) { DebuggerAppendMsg("ProcessVertexData: Address out of range (0x%08x)", addr); } else { ProcessVertexData(addr, v0, n); status.dwNumVertices += n; DisplayVertexInfo(addr, v0, n); } } void RSP_GBI2_EndDL(Gfx *gfx) { SP_Timing(RSP_GBI1_EndDL); RDP_GFX_PopDL(); } void RSP_GBI2_CullDL(Gfx *gfx) { SP_Timing(RSP_GBI1_CullDL); #ifdef DEBUGGER if( !debuggerEnableCullFace ) { return; //Disable Culling } #endif if( g_curRomInfo.bDisableCulling ) { return; //Disable Culling } uint32_t dwVFirst = (((gfx->words.w0)) & 0xfff) / gRSP.vertexMult; uint32_t dwVLast = (((gfx->words.w1)) & 0xfff) / gRSP.vertexMult; LOG_UCODE(" Culling using verts %d to %d", dwVFirst, dwVLast); // Mask into range dwVFirst &= 0x1f; dwVLast &= 0x1f; if( dwVLast < dwVFirst ) return; if( !gRSP.bRejectVtx ) return; for (uint32_t i = dwVFirst; i <= dwVLast; i++) { //if (g_dwVtxFlags[i] == 0) if (g_clipFlag[i] == 0) { LOG_UCODE(" Vertex %d is visible, returning", i); return; } } status.dwNumDListsCulled++; LOG_UCODE(" No vertices were visible, culling"); RDP_GFX_PopDL(); } void RSP_GBI2_MoveWord(Gfx *gfx) { SP_Timing(RSP_GBI1_MoveWord); switch (gfx->gbi2moveword.type) { case RSP_MOVE_WORD_MATRIX: RSP_RDP_InsertMatrix(gfx); break; case RSP_MOVE_WORD_NUMLIGHT: { uint32_t dwNumLights = gfx->gbi2moveword.value/24; gRSP.ambientLightIndex = dwNumLights; SetNumLights(dwNumLights); } break; case RSP_MOVE_WORD_CLIP: { switch (gfx->gbi2moveword.offset) { case RSP_MV_WORD_OFFSET_CLIP_RNX: case RSP_MV_WORD_OFFSET_CLIP_RNY: case RSP_MV_WORD_OFFSET_CLIP_RPX: case RSP_MV_WORD_OFFSET_CLIP_RPY: CRender::g_pRender->SetClipRatio(gfx->gbi2moveword.offset, gfx->gbi2moveword.value); default: LOG_UCODE(" RSP_MOVE_WORD_CLIP ? : 0x%08x", gfx->words.w1); break; } } break; case RSP_MOVE_WORD_SEGMENT: { uint32_t dwSeg = gfx->gbi2moveword.offset / 4; uint32_t dwAddr = gfx->gbi2moveword.value & 0x00FFFFFF; // Hack - convert to physical LOG_UCODE(" RSP_MOVE_WORD_SEGMENT Segment[%d] = 0x%08x", dwSeg, dwAddr); if( dwAddr > g_dwRamSize ) { gRSP.segments[dwSeg] = dwAddr; #ifdef DEBUGGER if( pauseAtNext ) DebuggerAppendMsg("warning: Segment %d addr is %8X", dwSeg, dwAddr); #endif } else { gRSP.segments[dwSeg] = dwAddr; } } break; case RSP_MOVE_WORD_FOG: { uint16_t wMult = (uint16_t)((gfx->gbi2moveword.value >> 16) & 0xFFFF); uint16_t wOff = (uint16_t)((gfx->gbi2moveword.value ) & 0xFFFF); float fMult = (float)(short)wMult; float fOff = (float)(short)wOff; float rng = 128000.0f / fMult; float fMin = 500.0f - (fOff*rng/256.0f); float fMax = rng + fMin; FOG_DUMP(TRACE4("Set Fog: Min=%f, Max=%f, Mul=%f, Off=%f", fMin, fMax, fMult, fOff)); //if( fMult <= 0 || fMin > fMax || fMax < 0 || fMin > 1000 ) if( fMult <= 0 || fMax < 0 ) { // Hack fMin = 996; fMax = 1000; fMult = 0; fOff = 1; } SetFogMinMax(fMin, fMax, fMult, fOff); FOG_DUMP(TRACE3("Set Fog: Min=%f, Max=%f, Data=0x%08X", fMin, fMax, gfx->gbi2moveword.value)); } break; case RSP_MOVE_WORD_LIGHTCOL: { uint32_t dwLight = gfx->gbi2moveword.offset / 0x18; uint32_t dwField = (gfx->gbi2moveword.offset & 0x7); switch (dwField) { case 0: if (dwLight == gRSP.ambientLightIndex) { SetAmbientLight( (gfx->gbi2moveword.value>>8) ); } else { SetLightCol(dwLight, gfx->gbi2moveword.value); } break; case 4: break; default: DebuggerAppendMsg("RSP_MOVE_WORD_LIGHTCOL with unknown offset 0x%08x", dwField); break; } } break; case RSP_MOVE_WORD_PERSPNORM: LOG_UCODE(" RSP_MOVE_WORD_PERSPNORM 0x%04x", (short)gfx->words.w1); break; case RSP_MOVE_WORD_POINTS: LOG_UCODE(" 2nd cmd of Force Matrix"); break; default: { LOG_UCODE(" Ignored!!"); } break; } } void RSP_GBI2_Tri1(Gfx *gfx) { if( gfx->words.w0 == 0x05000017 && gfx->gbi2tri1.flag == 0x80 ) { // The ObjLoadTxtr / Tlut cmd for Evangelion.v64 RSP_S2DEX_SPObjLoadTxtr(gfx); DebuggerAppendMsg("Fix me, SPObjLoadTxtr as RSP_GBI2_Tri2"); } else { status.primitiveType = PRIM_TRI1; bool bTrisAdded = false; bool bTexturesAreEnabled = CRender::g_pRender->IsTextureEnabled(); // While the next command pair is Tri1, add vertices uint32_t dwPC = gDlistStack[gDlistStackPointer].pc; do { uint32_t dwV2 = gfx->gbi2tri1.v2/gRSP.vertexMult; uint32_t dwV1 = gfx->gbi2tri1.v1/gRSP.vertexMult; uint32_t dwV0 = gfx->gbi2tri1.v0/gRSP.vertexMult; if (IsTriangleVisible(dwV0, dwV1, dwV2)) { DEBUG_DUMP_VERTEXES("ZeldaTri1", dwV0, dwV1, dwV2); LOG_UCODE(" ZeldaTri1: 0x%08x 0x%08x %d,%d,%d", gfx->words.w0, gfx->words.w1, dwV0, dwV1, dwV2); if (!bTrisAdded) { if( bTexturesAreEnabled ) { PrepareTextures(); InitVertexTextureConstants(); } CRender::g_pRender->SetCombinerAndBlender(); bTrisAdded = true; } PrepareTriangle(dwV0, dwV1, dwV2); } gfx++; dwPC += 8; #ifdef DEBUGGER } while (!(pauseAtNext && eventToPause==NEXT_TRIANGLE) && gfx->words.cmd == (uint8_t)RSP_ZELDATRI1); #else } while( gfx->words.cmd == (uint8_t)RSP_ZELDATRI1); #endif gDlistStack[gDlistStackPointer].pc = dwPC-8; if (bTrisAdded) { CRender::g_pRender->DrawTriangles(); } DEBUG_TRIANGLE(TRACE0("Pause at GBI2 TRI1")); } } void RSP_GBI2_Tri2(Gfx *gfx) { if( gfx->words.w0 == 0x0600002f && gfx->gbi2tri2.flag == 0x80 ) { // The ObjTxSprite cmd for Evangelion.v64 RSP_S2DEX_SPObjLoadTxSprite(gfx); DebuggerAppendMsg("Fix me, SPObjLoadTxSprite as RSP_GBI2_Tri2"); } else { status.primitiveType = PRIM_TRI2; bool bTrisAdded = false; // While the next command pair is Tri2, add vertices uint32_t dwPC = gDlistStack[gDlistStackPointer].pc; bool bTexturesAreEnabled = CRender::g_pRender->IsTextureEnabled(); do { uint32_t dwV2 = gfx->gbi2tri2.v2; uint32_t dwV1 = gfx->gbi2tri2.v1; uint32_t dwV0 = gfx->gbi2tri2.v0; uint32_t dwV5 = gfx->gbi2tri2.v5; uint32_t dwV4 = gfx->gbi2tri2.v4; uint32_t dwV3 = gfx->gbi2tri2.v3; LOG_UCODE(" ZeldaTri2: 0x%08x 0x%08x", gfx->words.w0, gfx->words.w1); LOG_UCODE(" V0: %d, V1: %d, V2: %d", dwV0, dwV1, dwV2); LOG_UCODE(" V3: %d, V4: %d, V5: %d", dwV3, dwV4, dwV5); // Do first tri if (IsTriangleVisible(dwV0, dwV1, dwV2)) { DEBUG_DUMP_VERTEXES("ZeldaTri2 1/2", dwV0, dwV1, dwV2); if (!bTrisAdded) { if( bTexturesAreEnabled ) { PrepareTextures(); InitVertexTextureConstants(); } CRender::g_pRender->SetCombinerAndBlender(); bTrisAdded = true; } PrepareTriangle(dwV0, dwV1, dwV2); } // Do second tri if (IsTriangleVisible(dwV3, dwV4, dwV5)) { DEBUG_DUMP_VERTEXES("ZeldaTri2 2/2", dwV3, dwV4, dwV5); if (!bTrisAdded) { if( bTexturesAreEnabled ) { PrepareTextures(); InitVertexTextureConstants(); } CRender::g_pRender->SetCombinerAndBlender(); bTrisAdded = true; } PrepareTriangle(dwV3, dwV4, dwV5); } gfx++; dwPC += 8; #ifdef DEBUGGER } while (!(pauseAtNext && eventToPause==NEXT_TRIANGLE) && gfx->words.cmd == (uint8_t)RSP_ZELDATRI2); #else } while ( gfx->words.cmd == (uint8_t)RSP_ZELDATRI2 );//&& status.dwNumTrisRendered < 50); #endif gDlistStack[gDlistStackPointer].pc = dwPC-8; if (bTrisAdded) { CRender::g_pRender->DrawTriangles(); } DEBUG_TRIANGLE(TRACE0("Pause at GBI2 TRI2")); } } void RSP_GBI2_Line3D(Gfx *gfx) { if( gfx->words.w0 == 0x0700002f && (gfx->words.w1>>24) == 0x80 ) { // The ObjTxSprite cmd for Evangelion.v64 RSP_S2DEX_SPObjLoadTxRect(gfx); } else { status.primitiveType = PRIM_TRI3; uint32_t dwPC = gDlistStack[gDlistStackPointer].pc; bool bTrisAdded = false; do { uint32_t dwV0 = gfx->gbi2line3d.v0/gRSP.vertexMult; uint32_t dwV1 = gfx->gbi2line3d.v1/gRSP.vertexMult; uint32_t dwV2 = gfx->gbi2line3d.v2/gRSP.vertexMult; uint32_t dwV3 = gfx->gbi2line3d.v3/gRSP.vertexMult; uint32_t dwV4 = gfx->gbi2line3d.v4/gRSP.vertexMult; uint32_t dwV5 = gfx->gbi2line3d.v5/gRSP.vertexMult; LOG_UCODE(" ZeldaTri3: 0x%08x 0x%08x", gfx->words.w0, gfx->words.w1); LOG_UCODE(" V0: %d, V1: %d, V2: %d", dwV0, dwV1, dwV2); LOG_UCODE(" V3: %d, V4: %d, V5: %d", dwV3, dwV4, dwV5); // Do first tri if (IsTriangleVisible(dwV0, dwV1, dwV2)) { DEBUG_DUMP_VERTEXES("ZeldaTri3 1/2", dwV0, dwV1, dwV2); if (!bTrisAdded && CRender::g_pRender->IsTextureEnabled()) { PrepareTextures(); InitVertexTextureConstants(); } if( !bTrisAdded ) { CRender::g_pRender->SetCombinerAndBlender(); } bTrisAdded = true; PrepareTriangle(dwV0, dwV1, dwV2); } // Do second tri if (IsTriangleVisible(dwV3, dwV4, dwV5)) { DEBUG_DUMP_VERTEXES("ZeldaTri3 2/2", dwV3, dwV4, dwV5); if (!bTrisAdded && CRender::g_pRender->IsTextureEnabled()) { PrepareTextures(); InitVertexTextureConstants(); } if( !bTrisAdded ) { CRender::g_pRender->SetCombinerAndBlender(); } bTrisAdded = true; PrepareTriangle(dwV3, dwV4, dwV5); } gfx++; dwPC += 8; #ifdef DEBUGGER } while (!(pauseAtNext && eventToPause==NEXT_TRIANGLE) && gfx->words.cmd == (uint8_t)RSP_LINE3D); #else } while ( gfx->words.cmd == (uint8_t)RSP_LINE3D); #endif gDlistStack[gDlistStackPointer].pc = dwPC-8; if (bTrisAdded) { CRender::g_pRender->DrawTriangles(); } DEBUG_TRIANGLE(TRACE0("Pause at GBI2 Line3D")); } } void RSP_GBI2_Texture(Gfx *gfx) { SP_Timing(RSP_GBI1_Texture); float fTextureScaleS = (float)(gfx->texture.scaleS) / (65536.0f * 32.0f); float fTextureScaleT = (float)(gfx->texture.scaleT) / (65536.0f * 32.0f); if( (((gfx->words.w1)>>16)&0xFFFF) == 0xFFFF ) { fTextureScaleS = 1/32.0f; } else if( (((gfx->words.w1)>>16)&0xFFFF) == 0x8000 ) { fTextureScaleS = 1/64.0f; } if( (((gfx->words.w1) )&0xFFFF) == 0xFFFF ) { fTextureScaleT = 1/32.0f; } else if( (((gfx->words.w1) )&0xFFFF) == 0x8000 ) { fTextureScaleT = 1/64.0f; } CRender::g_pRender->SetTextureEnableAndScale(gfx->texture.tile, gfx->texture.enable_gbi2, fTextureScaleS, fTextureScaleT); /* if( g_curRomInfo.bTextureScaleHack ) { // Hack, need to verify, refer to N64 programming manual // that if scale = 0.5 (1/64), vtx s,t are also doubled if( ((word1>>16)&0xFFFF) == 0x8000 ) { fTextureScaleS = 1/128.0f; if( ((word1)&0xFFFF) == 0xFFFF ) { fTextureScaleT = 1/64.0f; } } if( ((word1 )&0xFFFF) == 0x8000 ) { fTextureScaleT = 1/128.0f; if( ((word1>>16)&0xFFFF) == 0xFFFF ) { fTextureScaleS = 1/64.0f; } } } */ CRender::g_pRender->SetTextureEnableAndScale(gfx->texture.tile, gfx->texture.enable_gbi2, fTextureScaleS, fTextureScaleT); LOG_TEXTURE( { DebuggerAppendMsg("SetTexture: Level: %d Tile: %d %s\n", gfx->texture.level, gfx->texture.tile, gfx->texture.enable_gbi2 ? "enabled":"disabled"); DebuggerAppendMsg(" ScaleS: %f, ScaleT: %f\n", fTextureScaleS*32.0f, fTextureScaleT*32.0f); }); DEBUGGER_PAUSE_COUNT_N(NEXT_SET_TEXTURE); LOG_UCODE(" Level: %d Tile: %d %s", gfx->texture.level, gfx->texture.tile, gfx->texture.enable_gbi2 ? "enabled":"disabled"); LOG_UCODE(" ScaleS: %f, ScaleT: %f", fTextureScaleS*32.0f, fTextureScaleT*32.0f); } void RSP_GBI2_PopMtx(Gfx *gfx) { SP_Timing(RSP_GBI1_PopMtx); uint8_t nCommand = (uint8_t)(gfx->words.w0 & 0xFF); LOG_UCODE(" PopMtx: 0x%02x (%s)", nCommand, (nCommand & RSP_ZELDA_MTX_PROJECTION) ? "Projection" : "ModelView"); /* if (nCommand & RSP_ZELDA_MTX_PROJECTION) { CRender::g_pRender->PopProjection(); } else*/ { CRender::g_pRender->PopWorldView(); } #ifdef DEBUGGER if( pauseAtNext && eventToPause == NEXT_MATRIX_CMD ) { pauseAtNext = false; debuggerPause = true; TRACE0("Pause after Pop GBI2_PopMtx:"); } else { if( pauseAtNext && logMatrix ) { TRACE0("Pause after Pop GBI2_PopMtx:"); } } #endif } #define RSP_ZELDA_ZBUFFER 0x00000001 // Guess #define RSP_ZELDA_CULL_BACK 0x00000200 #define RSP_ZELDA_CULL_FRONT 0x00000400 #define RSP_ZELDA_FOG 0x00010000 #define RSP_ZELDA_LIGHTING 0x00020000 #define RSP_ZELDA_TEXTURE_GEN 0x00040000 #define RSP_ZELDA_TEXTURE_GEN_LINEAR 0x00080000 #define RSP_ZELDA_SHADING_SMOOTH 0x00200000 void RSP_GBI2_GeometryMode(Gfx *gfx) { SP_Timing(RSP_GBI2_GeometryMode); uint32_t dwAnd = ((gfx->words.w0)) & 0x00FFFFFF; uint32_t dwOr = ((gfx->words.w1)) & 0x00FFFFFF; #ifdef DEBUGGER LOG_UCODE(" 0x%08x 0x%08x =(x & 0x%08x) | 0x%08x", gfx->words.w0, gfx->words.w1, dwAnd, dwOr); if ((~dwAnd) & RSP_ZELDA_ZBUFFER) LOG_UCODE(" Disabling ZBuffer"); //if ((~dwAnd) & RSP_ZELDA_TEXTURE_ENABLE) LOG_UCODE(" Disabling Texture"); //if ((~dwAnd) & RSP_ZELDA_SHADE) LOG_UCODE(" Disabling Shade"); if ((~dwAnd) & RSP_ZELDA_SHADING_SMOOTH) LOG_UCODE(" Disabling Flat Shading"); if ((~dwAnd) & RSP_ZELDA_CULL_FRONT) LOG_UCODE(" Disabling Front Culling"); if ((~dwAnd) & RSP_ZELDA_CULL_BACK) LOG_UCODE(" Disabling Back Culling"); if ((~dwAnd) & RSP_ZELDA_FOG) LOG_UCODE(" Disabling Fog"); if ((~dwAnd) & RSP_ZELDA_LIGHTING) LOG_UCODE(" Disabling Lighting"); if ((~dwAnd) & RSP_ZELDA_TEXTURE_GEN) LOG_UCODE(" Disabling Texture Gen"); if ((~dwAnd) & RSP_ZELDA_TEXTURE_GEN_LINEAR) LOG_UCODE(" Disabling Texture Gen Linear"); // if ((~dwAnd) & RSP_ZELDA_LOD) LOG_UCODE(" Disabling LOD (no impl)"); if (dwOr & RSP_ZELDA_ZBUFFER) LOG_UCODE(" Enabling ZBuffer"); //if (dwOr & RSP_ZELDA_TEXTURE_ENABLE) LOG_UCODE(" Enabling Texture"); //if (dwOr & RSP_ZELDA_SHADE) LOG_UCODE(" Enabling Shade"); if (dwOr & RSP_ZELDA_SHADING_SMOOTH) LOG_UCODE(" Enabling Flat Shading"); if (dwOr & RSP_ZELDA_CULL_FRONT) LOG_UCODE(" Enabling Front Culling"); if (dwOr & RSP_ZELDA_CULL_BACK) LOG_UCODE(" Enabling Back Culling"); if (dwOr & RSP_ZELDA_FOG) LOG_UCODE(" Enabling Fog"); if (dwOr & RSP_ZELDA_LIGHTING) LOG_UCODE(" Enabling Lighting"); if (dwOr & RSP_ZELDA_TEXTURE_GEN) LOG_UCODE(" Enabling Texture Gen"); if (dwOr & RSP_ZELDA_TEXTURE_GEN_LINEAR) LOG_UCODE(" Enabling Texture Gen Linear"); ///if (dwOr & RSP_ZELDA_LOD) LOG_UCODE(" Enabling LOD (no impl)"); #endif // DEBUGGER gRDP.geometryMode &= dwAnd; gRDP.geometryMode |= dwOr; bool bCullFront = (gRDP.geometryMode & RSP_ZELDA_CULL_FRONT) ? true : false; bool bCullBack = (gRDP.geometryMode & RSP_ZELDA_CULL_BACK) ? true : false; //bool bShade = (gRDP.geometryMode & G_SHADE) ? true : false; //bool bFlatShade = (gRDP.geometryMode & RSP_ZELDA_SHADING_SMOOTH) ? true : false; bool bFlatShade = (gRDP.geometryMode & RSP_ZELDA_TEXTURE_GEN_LINEAR) ? true : false; if( options.enableHackForGames == HACK_FOR_TIGER_HONEY_HUNT ) bFlatShade = false; bool bFog = (gRDP.geometryMode & RSP_ZELDA_FOG) ? true : false; bool bTextureGen = (gRDP.geometryMode & RSP_ZELDA_TEXTURE_GEN) ? true : false; bool bLighting = (gRDP.geometryMode & RSP_ZELDA_LIGHTING) ? true : false; bool bZBuffer = (gRDP.geometryMode & RSP_ZELDA_ZBUFFER) ? true : false; CRender::g_pRender->SetCullMode(bCullFront, bCullBack); //if (bFlatShade||!bShade) CRender::g_pRender->SetShadeMode( SHADE_FLAT ); if (bFlatShade) CRender::g_pRender->SetShadeMode( SHADE_FLAT ); else CRender::g_pRender->SetShadeMode( SHADE_SMOOTH ); SetTextureGen(bTextureGen); SetLighting( bLighting ); CRender::g_pRender->ZBufferEnable( bZBuffer ); CRender::g_pRender->SetFogEnable( bFog ); } int dlistMtxCount=0; extern uint32_t dwConkerVtxZAddr; void RSP_GBI2_Mtx(Gfx *gfx) { SP_Timing(RSP_GBI0_Mtx); dwConkerVtxZAddr = 0; // For Conker BFD uint32_t addr = RSPSegmentAddr((gfx->gbi2matrix.addr)); if( gfx->gbi2matrix.param == 0 && gfx->gbi2matrix.len == 0 ) { DLParser_Bomberman2TextRect(gfx); return; } LOG_UCODE(" Mtx: %s %s %s Length %d Address 0x%08x", gfx->gbi2matrix.projection ? "Projection" : "ModelView", gfx->gbi2matrix.load ? "Load" : "Mul", gfx->gbi2matrix.nopush==0 ? "Push" : "No Push", gfx->gbi2matrix.len, addr); if (addr + 64 > g_dwRamSize) { DebuggerAppendMsg("ZeldaMtx: Address invalid (0x%08x)", addr); return; } LoadMatrix(addr); if (gfx->gbi2matrix.projection) { // So far only Extreme-G seems to Push/Pop projection matrices CRender::g_pRender->SetProjection(matToLoad, gfx->gbi2matrix.nopush==0, gfx->gbi2matrix.load); } else { CRender::g_pRender->SetWorldView(matToLoad, gfx->gbi2matrix.nopush==0, gfx->gbi2matrix.load); if( options.enableHackForGames == HACK_FOR_SOUTH_PARK_RALLY ) { dlistMtxCount++; if( dlistMtxCount == 2 ) { CRender::g_pRender->ClearZBuffer(1.0f); } } } #ifdef DEBUGGER const char *loadstr = gfx->gbi2matrix.load?"Load":"Mul"; const char *pushstr = gfx->gbi2matrix.nopush==0?"Push":"Nopush"; int projlevel = CRender::g_pRender->GetProjectMatrixLevel(); int worldlevel = CRender::g_pRender->GetWorldViewMatrixLevel(); if( pauseAtNext && eventToPause == NEXT_MATRIX_CMD ) { pauseAtNext = false; debuggerPause = true; if (gfx->gbi2matrix.projection) { DebuggerAppendMsg("Pause after %s and %s Matrix: Projection, level=%d\n", loadstr, pushstr, projlevel ); } else { DebuggerAppendMsg("Pause after %s and %s Matrix: WorldView level=%d\n", loadstr, pushstr, worldlevel); } } else { if( pauseAtNext && logMatrix ) { if (gfx->gbi2matrix.projection) { DebuggerAppendMsg("Matrix: %s and %s Projection level=%d\n", loadstr, pushstr, projlevel); } else { DebuggerAppendMsg("Matrix: %s and %s WorldView\n level=%d", loadstr, pushstr, worldlevel); } } } #endif } void RSP_GBI2_MoveMem(Gfx *gfx) { SP_Timing(RSP_GBI1_MoveMem); uint32_t addr = RSPSegmentAddr((gfx->words.w1)); uint32_t type = ((gfx->words.w0) ) & 0xFE; //uint32_t dwLen = ((gfx->words.w0) >> 16) & 0xFF; //uint32_t dwOffset = ((gfx->words.w0) >> 8) & 0xFFFF; switch (type) { case RSP_GBI2_MV_MEM__VIEWPORT: { RSP_MoveMemViewport(addr); } break; case RSP_GBI2_MV_MEM__LIGHT: { int8_t *rdram_s8 = (int8_t*)gfx_info.RDRAM; uint32_t dwOffset2 = ((gfx->words.w0) >> 5) & 0x3FFF; switch (dwOffset2) { case 0x00: { int8_t * pcBase = rdram_s8 + addr; LOG_UCODE(" RSP_GBI1_MV_MEM_LOOKATX %f %f %f", (float)pcBase[8 ^ 0x3], (float)pcBase[9 ^ 0x3], (float)pcBase[10 ^ 0x3]); } break; case 0x18: { int8_t * pcBase = rdram_s8 + addr; LOG_UCODE(" RSP_GBI1_MV_MEM_LOOKATY %f %f %f", (float)pcBase[8 ^ 0x3], (float)pcBase[9 ^ 0x3], (float)pcBase[10 ^ 0x3]); } break; default: //0x30/48/60 { uint32_t dwLight = (dwOffset2 - 0x30)/0x18; LOG_UCODE(" Light %d:", dwLight); RSP_MoveMemLight(dwLight, addr); } break; } break; } case RSP_GBI2_MV_MEM__MATRIX: LOG_UCODE("Force Matrix: addr=%08X", addr); RSP_GFX_Force_Matrix(addr); break; case RSP_GBI2_MV_MEM_O_L0: case RSP_GBI2_MV_MEM_O_L1: case RSP_GBI2_MV_MEM_O_L2: case RSP_GBI2_MV_MEM_O_L3: case RSP_GBI2_MV_MEM_O_L4: case RSP_GBI2_MV_MEM_O_L5: case RSP_GBI2_MV_MEM_O_L6: case RSP_GBI2_MV_MEM_O_L7: LOG_UCODE("Zelda Move Light"); RDP_NOIMPL_WARN("Zelda Move Light"); break; case RSP_GBI2_MV_MEM__POINT: LOG_UCODE("Zelda Move Point"); void RDP_NOIMPL_WARN(const char* op); RDP_NOIMPL_WARN("Zelda Move Point"); break; case RSP_GBI2_MV_MEM_O_LOOKATX: if( (gfx->words.w0) == 0xDC170000 && ((gfx->words.w1)&0xFF000000) == 0x80000000 ) { // Ucode for Evangelion.v64, the ObjMatrix cmd RSP_S2DEX_OBJ_MOVEMEM(gfx); } break; case RSP_GBI2_MV_MEM_O_LOOKATY: RSP_RDP_NOIMPL("Not implemented ZeldaMoveMem LOOKATY, Cmd0=0x%08X, Cmd1=0x%08X", gfx->words.w0, gfx->words.w1); break; case 0x02: if( (gfx->words.w0) == 0xDC070002 && ((gfx->words.w1)&0xFF000000) == 0x80000000 ) { RSP_S2DEX_OBJ_MOVEMEM(gfx); break; } default: LOG_UCODE("ZeldaMoveMem Type: Unknown"); RSP_RDP_NOIMPL("Unknown ZeldaMoveMem Type, type=0x%X, Addr=%08X", type, addr); break; } } void RSP_GBI2_DL(Gfx *gfx) { SP_Timing(RSP_GBI0_DL); uint32_t dwPush = ((gfx->words.w0) >> 16) & 0xFF; uint32_t dwAddr = RSPSegmentAddr((gfx->words.w1)); if( dwAddr > g_dwRamSize ) { RSP_RDP_NOIMPL("Error: DL addr = %08X out of range, PC=%08X", dwAddr, gDlistStack[gDlistStackPointer].pc ); dwAddr &= (g_dwRamSize-1); DebuggerPauseCountN( NEXT_DLIST ); } LOG_UCODE(" DL: Push:0x%02x Addr: 0x%08x", dwPush, dwAddr); switch (dwPush) { case RSP_DLIST_PUSH: LOG_UCODE(" Pushing ZeldaDisplayList 0x%08x", dwAddr); gDlistStackPointer++; gDlistStack[gDlistStackPointer].pc = dwAddr; gDlistStack[gDlistStackPointer].countdown = MAX_DL_COUNT; break; case RSP_DLIST_NOPUSH: LOG_UCODE(" Jumping to ZeldaDisplayList 0x%08x", dwAddr); if( gDlistStack[gDlistStackPointer].pc == dwAddr+8 ) //Is this a loop { //Hack for Gauntlet Legends gDlistStack[gDlistStackPointer].pc = dwAddr+8; } else gDlistStack[gDlistStackPointer].pc = dwAddr; gDlistStack[gDlistStackPointer].countdown = MAX_DL_COUNT; break; } LOG_UCODE(""); LOG_UCODE("\\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/"); LOG_UCODE("#############################################"); } void RSP_GBI2_SetOtherModeL(Gfx *gfx) { SP_Timing(RSP_GBI1_SetOtherModeL); uint32_t dwShift = ((gfx->words.w0)>>8)&0xFF; uint32_t dwLength= ((gfx->words.w0) )&0xFF; uint32_t dwData = (gfx->words.w1); // Mask is constructed slightly differently uint32_t dwMask = (uint32_t)((int32_t)(0x80000000)>>dwLength)>>dwShift; dwData &= dwMask; uint32_t modeL = gRDP.otherModeL; modeL = (modeL&(~dwMask)) | dwData; Gfx tempgfx; tempgfx.words.w0 = gRDP.otherModeH; tempgfx.words.w1 = modeL; DLParser_RDPSetOtherMode(&tempgfx ); } void RSP_GBI2_SetOtherModeH(Gfx *gfx) { SP_Timing(RSP_GBI1_SetOtherModeH); uint32_t dwLength= (((gfx->words.w0))&0xFF)+1; uint32_t dwShift = 32 - (((gfx->words.w0)>>8)&0xFF) - dwLength; uint32_t dwData = (gfx->words.w1); uint32_t dwMask2 = ((1<words.w0), (gfx->words.w1)); } gles2rice/src/osal_opengl.h000664 001750 001750 00000005655 12655644434 017053 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - osal_opengl.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2013 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #if !defined(OSAL_OPENGL_H) #define OSAL_OPENGL_H #include #if defined(_MSC_VER) && !defined(_XBOX) #include #elif defined(_XBOX) #include #endif #include #if !defined(__LIBRETRO__) || defined(HAVE_OPENGLES2) // Desktop GL fix #define GLSL_VERSION "100" #else #define GLSL_VERSION "120" #endif // Extension names #define OSAL_GL_ARB_TEXTURE_ENV_ADD "GL_texture_env_add" // Vertex shader params #define VS_POSITION 0 #define VS_COLOR 1 #define VS_TEXCOORD0 2 #define VS_TEXCOORD1 3 #define VS_FOG 4 // Constant substitutions #ifdef HAVE_OPENGLES2 #define GL_CLAMP GL_CLAMP_TO_EDGE #define GL_MAX_TEXTURE_UNITS GL_MAX_TEXTURE_IMAGE_UNITS #define GL_ADD 0x0104 #define GL_MODULATE 0x2100 #define GL_INTERPOLATE 0x8575 #define GL_CONSTANT 0x8576 #define GL_PREVIOUS 0x8578 #endif // Function substitutions #define pglActiveTexture glActiveTexture // No-op substitutions (unavailable in GLES2) #define glLoadIdentity() #define glMatrixMode(x) #define glOrtho(a,b,c,d,e,f) #define glReadBuffer(x) #define glTexEnvi(x,y,z) #define glTexEnvfv(x,y,z) #endif // OSAL_OPENGL_H mupen64plus-video-gliden64/src/GLideNHQ/TextureFilters_xbrz.cpp000664 001750 001750 00000120762 12655644434 025533 0ustar00sergiosergio000000 000000 // **************************************************************************** // * This file is part of the HqMAME project. It is distributed under * // * GNU General Public License: http://www.gnu.org/licenses/gpl-3.0 * // * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved * // * * // * Additionally and as a special exception, the author gives permission * // * to link the code of this program with the MAME library (or with modified * // * versions of MAME that use the same license as MAME), and distribute * // * linked combinations including the two. You must obey the GNU General * // * Public License in all respects for all of the code used other than MAME. * // * If you modify this file, you may extend this exception to your version * // * of the file, but you are not obligated to do so. If you do not wish to * // * do so, delete this exception statement from your version. * // **************************************************************************** #include "TextureFilters_xbrz.h" #include #include #include namespace { template inline unsigned char getByte(uint32_t val) { return static_cast((val >> (8 * N)) & 0xff); } inline unsigned char getAlpha(uint32_t pix) { return getByte<3>(pix); } inline unsigned char getBlue (uint32_t pix) { return getByte<2>(pix); } inline unsigned char getGreen(uint32_t pix) { return getByte<1>(pix); } inline unsigned char getRed (uint32_t pix) { return getByte<0>(pix); } inline uint32_t makePixel(unsigned char b, unsigned char g, unsigned char r) { return (b << 16) | (g << 8) | r; } inline uint32_t makePixel(unsigned char a, unsigned char b, unsigned char g, unsigned char r) { return (a << 24) | (b << 16) | (g << 8) | r; } template inline uint32_t gradientBGR(uint32_t pixFront, uint32_t pixBack) //blend front color with opacity M / N over opaque background: http://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending { static_assert(0 < M && M < N && N <= 1000, ""); auto calcColor = [](unsigned char colFront, unsigned char colBack) -> unsigned char { return (colFront * M + colBack * (N - M)) / N; }; return makePixel(calcColor(getBlue(pixFront), getBlue(pixBack)), calcColor(getGreen(pixFront), getGreen(pixBack)), calcColor(getRed(pixFront), getRed(pixBack))); } template inline uint32_t gradientABGR(uint32_t pixFront, uint32_t pixBack) //find intermediate color between two colors with alpha channels (=> NO alpha blending!!!) { static_assert(0 < M && M < N && N <= 1000, ""); const unsigned int weightFront = getAlpha(pixFront) * M; const unsigned int weightBack = getAlpha(pixBack) * (N - M); const unsigned int weightSum = weightFront + weightBack; if (weightSum == 0) return 0; auto calcColor = [=](unsigned char colFront, unsigned char colBack) { return static_cast((colFront * weightFront + colBack * weightBack) / weightSum); }; return makePixel(static_cast(weightSum / N), calcColor(getBlue(pixFront), getBlue(pixBack)), calcColor(getGreen(pixFront), getGreen(pixBack)), calcColor(getRed(pixFront), getRed(pixBack))); } //inline //double fastSqrt(double n) //{ // __asm //speeds up xBRZ by about 9% compared to std::sqrt which internally uses the same assembler instructions but adds some "fluff" // { // fld n // fsqrt // } //} // uint32_t* byteAdvance(uint32_t* ptr, int bytes) { return reinterpret_cast< uint32_t*>(reinterpret_cast< char*>(ptr)+bytes); } const uint32_t* byteAdvance(const uint32_t* ptr, int bytes) { return reinterpret_cast(reinterpret_cast(ptr)+bytes); } //fill block with the given color inline void fillBlock(uint32_t* trg, int pitch, uint32_t col, int blockWidth, int blockHeight) { //for (int y = 0; y < blockHeight; ++y, trg = byteAdvance(trg, pitch)) // std::fill(trg, trg + blockWidth, col); for (int y = 0; y < blockHeight; ++y, trg = byteAdvance(trg, pitch)) for (int x = 0; x < blockWidth; ++x) trg[x] = col; } inline void fillBlock(uint32_t* trg, int pitch, uint32_t col, int n) { fillBlock(trg, pitch, col, n, n); } #ifdef _MSC_VER #define FORCE_INLINE __forceinline #elif defined __GNUC__ #define FORCE_INLINE __attribute__((always_inline)) inline #else #define FORCE_INLINE inline #endif enum RotationDegree //clock-wise { ROT_0, ROT_90, ROT_180, ROT_270 }; //calculate input matrix coordinates after rotation at compile time template struct MatrixRotation; template struct MatrixRotation { static const size_t I_old = I; static const size_t J_old = J; }; template //(i, j) = (row, col) indices, N = size of (square) matrix struct MatrixRotation { static const size_t I_old = N - 1 - MatrixRotation(rotDeg - 1), I, J, N>::J_old; //old coordinates before rotation! static const size_t J_old = MatrixRotation(rotDeg - 1), I, J, N>::I_old; // }; template class OutputMatrix { public: OutputMatrix(uint32_t* out, int outWidth) : //access matrix area, top-left at position "out" for image with given width out_(out), outWidth_(outWidth) {} template uint32_t& ref() const { static const size_t I_old = MatrixRotation::I_old; static const size_t J_old = MatrixRotation::J_old; return *(out_ + J_old + I_old * outWidth_); } private: uint32_t* out_; const int outWidth_; }; template inline T square(T value) { return value * value; } inline double distRGB(uint32_t pix1, uint32_t pix2) { const double r_diff = static_cast(getRed(pix1)) - getRed(pix2); const double g_diff = static_cast(getGreen(pix1)) - getGreen(pix2); const double b_diff = static_cast(getBlue(pix1)) - getBlue(pix2); //euklidean RGB distance return std::sqrt(square(r_diff) + square(g_diff) + square(b_diff)); } inline double distYCbCr(uint32_t pix1, uint32_t pix2, double lumaWeight) { //http://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.601_conversion //YCbCr conversion is a matrix multiplication => take advantage of linearity by subtracting first! const int r_diff = static_cast(getRed(pix1)) - getRed(pix2); //we may delay division by 255 to after matrix multiplication const int g_diff = static_cast(getGreen(pix1)) - getGreen(pix2); // const int b_diff = static_cast(getBlue(pix1)) - getBlue(pix2); //substraction for int is noticeable faster than for double! //const double k_b = 0.0722; //ITU-R BT.709 conversion //const double k_r = 0.2126; // const double k_b = 0.0593; //ITU-R BT.2020 conversion const double k_r = 0.2627; // const double k_g = 1 - k_b - k_r; const double scale_b = 0.5 / (1 - k_b); const double scale_r = 0.5 / (1 - k_r); const double y = k_r * r_diff + k_g * g_diff + k_b * b_diff; //[!], analog YCbCr! const double c_b = scale_b * (b_diff - y); const double c_r = scale_r * (r_diff - y); //we skip division by 255 to have similar range like other distance functions return std::sqrt(square(lumaWeight * y) + square(c_b) + square(c_r)); } struct DistYCbCrBuffer //30% perf boost compared to distYCbCr()! { public: static double dist(uint32_t pix1, uint32_t pix2) { //#if defined _MSC_VER && _MSC_VER < 1900 //#error function scope static initialization is not yet thread-safe! //#endif static const DistYCbCrBuffer inst; return inst.distImpl(pix1, pix2); } private: DistYCbCrBuffer() : buffer(256 * 256 * 256) { for (uint32_t i = 0; i < 256 * 256 * 256; ++i) //startup time: 114 ms on Intel Core i5 (four cores) { const int r_diff = getByte<2>(i) * 2 - 255; const int g_diff = getByte<1>(i) * 2 - 255; const int b_diff = getByte<0>(i) * 2 - 255; const double k_b = 0.0593; //ITU-R BT.2020 conversion const double k_r = 0.2627; // const double k_g = 1 - k_b - k_r; const double scale_b = 0.5 / (1 - k_b); const double scale_r = 0.5 / (1 - k_r); const double y = k_r * r_diff + k_g * g_diff + k_b * b_diff; //[!], analog YCbCr! const double c_b = scale_b * (b_diff - y); const double c_r = scale_r * (r_diff - y); buffer[i] = static_cast(std::sqrt(square(y) + square(c_b) + square(c_r))); } } double distImpl(uint32_t pix1, uint32_t pix2) const { //if (pix1 == pix2) -> 8% perf degradation! // return 0; //if (pix1 > pix2) // std::swap(pix1, pix2); -> 30% perf degradation!!! const int r_diff = static_cast(getRed(pix1)) - getRed(pix2); const int g_diff = static_cast(getGreen(pix1)) - getGreen(pix2); const int b_diff = static_cast(getBlue(pix1)) - getBlue(pix2); return buffer[(((b_diff + 255) / 2) << 16) | //slightly reduce precision (division by 2) to squeeze value into single byte (((g_diff + 255) / 2) << 8) | ((r_diff + 255) / 2)]; } std::vector buffer; //consumes 64 MB memory; using double is only 2% faster, but takes 128 MB }; enum BlendType { BLEND_NONE = 0, BLEND_NORMAL, //a normal indication to blend BLEND_DOMINANT, //a strong indication to blend //attention: BlendType must fit into the value range of 2 bit!!! }; struct BlendResult { BlendType /**/blend_f, blend_g, /**/blend_j, blend_k; }; struct Kernel_4x4 //kernel for preprocessing step { uint32_t /**/a, b, c, d, /**/e, f, g, h, /**/i, j, k, l, /**/m, n, o, p; }; /* input kernel area naming convention: ----------------- | A | B | C | D | ----|---|---|---| | E | F | G | H | //evaluate the four corners between F, G, J, K ----|---|---|---| //input pixel is at position F | I | J | K | L | ----|---|---|---| | M | N | O | P | ----------------- */ template FORCE_INLINE //detect blend direction BlendResult preProcessCorners(const Kernel_4x4& ker, const xbrz::ScalerCfg& cfg) //result: F, G, J, K corners of "GradientType" { BlendResult result = {}; if ((ker.f == ker.g && ker.j == ker.k) || (ker.f == ker.j && ker.g == ker.k)) return result; auto dist = [&](uint32_t pix1, uint32_t pix2) { return ColorDistance::dist(pix1, pix2, cfg.luminanceWeight); }; const int weight = 4; double jg = dist(ker.i, ker.f) + dist(ker.f, ker.c) + dist(ker.n, ker.k) + dist(ker.k, ker.h) + weight * dist(ker.j, ker.g); double fk = dist(ker.e, ker.j) + dist(ker.j, ker.o) + dist(ker.b, ker.g) + dist(ker.g, ker.l) + weight * dist(ker.f, ker.k); if (jg < fk) //test sample: 70% of values max(jg, fk) / min(jg, fk) are between 1.1 and 3.7 with median being 1.8 { const bool dominantGradient = cfg.dominantDirectionThreshold * jg < fk; if (ker.f != ker.g && ker.f != ker.j) result.blend_f = dominantGradient ? BLEND_DOMINANT : BLEND_NORMAL; if (ker.k != ker.j && ker.k != ker.g) result.blend_k = dominantGradient ? BLEND_DOMINANT : BLEND_NORMAL; } else if (fk < jg) { const bool dominantGradient = cfg.dominantDirectionThreshold * fk < jg; if (ker.j != ker.f && ker.j != ker.k) result.blend_j = dominantGradient ? BLEND_DOMINANT : BLEND_NORMAL; if (ker.g != ker.f && ker.g != ker.k) result.blend_g = dominantGradient ? BLEND_DOMINANT : BLEND_NORMAL; } return result; } struct Kernel_3x3 { uint32_t /**/a, b, c, /**/d, e, f, /**/g, h, i; }; #define DEF_GETTER(x) template uint32_t inline get_##x(const Kernel_3x3& ker) { return ker.x; } //we cannot and NEED NOT write "ker.##x" since ## concatenates preprocessor tokens but "." is not a token DEF_GETTER(a) DEF_GETTER(b) DEF_GETTER(c) DEF_GETTER(d) DEF_GETTER(e) DEF_GETTER(f) DEF_GETTER(g) DEF_GETTER(h) DEF_GETTER(i) #undef DEF_GETTER #define DEF_GETTER(x, y) template <> inline uint32_t get_##x(const Kernel_3x3& ker) { return ker.y; } DEF_GETTER(a, g) DEF_GETTER(b, d) DEF_GETTER(c, a) DEF_GETTER(d, h) DEF_GETTER(e, e) DEF_GETTER(f, b) DEF_GETTER(g, i) DEF_GETTER(h, f) DEF_GETTER(i, c) #undef DEF_GETTER #define DEF_GETTER(x, y) template <> inline uint32_t get_##x(const Kernel_3x3& ker) { return ker.y; } DEF_GETTER(a, i) DEF_GETTER(b, h) DEF_GETTER(c, g) DEF_GETTER(d, f) DEF_GETTER(e, e) DEF_GETTER(f, d) DEF_GETTER(g, c) DEF_GETTER(h, b) DEF_GETTER(i, a) #undef DEF_GETTER #define DEF_GETTER(x, y) template <> inline uint32_t get_##x(const Kernel_3x3& ker) { return ker.y; } DEF_GETTER(a, c) DEF_GETTER(b, f) DEF_GETTER(c, i) DEF_GETTER(d, b) DEF_GETTER(e, e) DEF_GETTER(f, h) DEF_GETTER(g, a) DEF_GETTER(h, d) DEF_GETTER(i, g) #undef DEF_GETTER //compress four blend types into a single byte inline BlendType getTopL(unsigned char b) { return static_cast(0x3 & b); } inline BlendType getTopR(unsigned char b) { return static_cast(0x3 & (b >> 2)); } inline BlendType getBottomR(unsigned char b) { return static_cast(0x3 & (b >> 4)); } inline BlendType getBottomL(unsigned char b) { return static_cast(0x3 & (b >> 6)); } inline void setTopL(unsigned char& b, BlendType bt) { b |= bt; } //buffer is assumed to be initialized before preprocessing! inline void setTopR(unsigned char& b, BlendType bt) { b |= (bt << 2); } inline void setBottomR(unsigned char& b, BlendType bt) { b |= (bt << 4); } inline void setBottomL(unsigned char& b, BlendType bt) { b |= (bt << 6); } inline bool blendingNeeded(unsigned char b) { return b != 0; } template inline unsigned char rotateBlendInfo(unsigned char b) { return b; } template <> inline unsigned char rotateBlendInfo(unsigned char b) { return ((b << 2) | (b >> 6)) & 0xff; } template <> inline unsigned char rotateBlendInfo(unsigned char b) { return ((b << 4) | (b >> 4)) & 0xff; } template <> inline unsigned char rotateBlendInfo(unsigned char b) { return ((b << 6) | (b >> 2)) & 0xff; } #ifndef NDEBUG int debugPixelX = -1; int debugPixelY = 12; __declspec(thread) bool breakIntoDebugger = false; #endif /* input kernel area naming convention: ------------- | A | B | C | ----|---|---| | D | E | F | //input pixel is at position E ----|---|---| | G | H | I | ------------- */ template FORCE_INLINE //perf: quite worth it! void blendPixel(const Kernel_3x3& ker, uint32_t* target, int trgWidth, unsigned char blendInfo, //result of preprocessing all four corners of pixel "e" const xbrz::ScalerCfg& cfg) { #define a get_a(ker) #define b get_b(ker) #define c get_c(ker) #define d get_d(ker) #define e get_e(ker) #define f get_f(ker) #define g get_g(ker) #define h get_h(ker) #define i get_i(ker) #ifndef NDEBUG if (breakIntoDebugger) __debugbreak(); //__asm int 3; #endif const unsigned char blend = rotateBlendInfo(blendInfo); if (getBottomR(blend) >= BLEND_NORMAL) { auto eq = [&](uint32_t pix1, uint32_t pix2) { return ColorDistance::dist(pix1, pix2, cfg.luminanceWeight) < cfg.equalColorTolerance; }; auto dist = [&](uint32_t pix1, uint32_t pix2) { return ColorDistance::dist(pix1, pix2, cfg.luminanceWeight); }; const bool doLineBlend = [&]() -> bool { if (getBottomR(blend) >= BLEND_DOMINANT) return true; //make sure there is no second blending in an adjacent rotation for this pixel: handles insular pixels, mario eyes if (getTopR(blend) != BLEND_NONE && !eq(e, g)) //but support double-blending for 90° corners return false; if (getBottomL(blend) != BLEND_NONE && !eq(e, c)) return false; //no full blending for L-shapes; blend corner only (handles "mario mushroom eyes") if (!eq(e, i) && eq(g, h) && eq(h, i) && eq(i, f) && eq(f, c)) return false; return true; }(); const uint32_t px = dist(e, f) <= dist(e, h) ? f : h; //choose most similar color OutputMatrix out(target, trgWidth); if (doLineBlend) { const double fg = dist(f, g); //test sample: 70% of values max(fg, hc) / min(fg, hc) are between 1.1 and 3.7 with median being 1.9 const double hc = dist(h, c); // const bool haveShallowLine = cfg.steepDirectionThreshold * fg <= hc && e != g && d != g; const bool haveSteepLine = cfg.steepDirectionThreshold * hc <= fg && e != c && b != c; if (haveShallowLine) { if (haveSteepLine) Scaler::blendLineSteepAndShallow(px, out); else Scaler::blendLineShallow(px, out); } else { if (haveSteepLine) Scaler::blendLineSteep(px, out); else Scaler::blendLineDiagonal(px, out); } } else Scaler::blendCorner(px, out); } #undef a #undef b #undef c #undef d #undef e #undef f #undef g #undef h #undef i } template //scaler policy: see "Scaler2x" reference implementation void scaleImage(const uint32_t* src, uint32_t* trg, int srcWidth, int srcHeight, const xbrz::ScalerCfg& cfg, int yFirst, int yLast) { yFirst = std::max(yFirst, 0); yLast = std::min(yLast, srcHeight); if (yFirst >= yLast || srcWidth <= 0) return; const int trgWidth = srcWidth * Scaler::scale; //"use" space at the end of the image as temporary buffer for "on the fly preprocessing": we even could use larger area of //"sizeof(uint32_t) * srcWidth * (yLast - yFirst)" bytes without risk of accidental overwriting before accessing const int bufferSize = srcWidth; unsigned char* preProcBuffer = reinterpret_cast(trg + yLast * Scaler::scale * trgWidth) - bufferSize; std::fill(preProcBuffer, preProcBuffer + bufferSize, 0); static_assert(BLEND_NONE == 0, ""); //initialize preprocessing buffer for first row of current stripe: detect upper left and right corner blending //this cannot be optimized for adjacent processing stripes; we must not allow for a memory race condition! if (yFirst > 0) { const int y = yFirst - 1; const uint32_t* s_m1 = src + srcWidth * std::max(y - 1, 0); const uint32_t* s_0 = src + srcWidth * y; //center line const uint32_t* s_p1 = src + srcWidth * std::min(y + 1, srcHeight - 1); const uint32_t* s_p2 = src + srcWidth * std::min(y + 2, srcHeight - 1); for (int x = 0; x < srcWidth; ++x) { const int x_m1 = std::max(x - 1, 0); const int x_p1 = std::min(x + 1, srcWidth - 1); const int x_p2 = std::min(x + 2, srcWidth - 1); Kernel_4x4 ker = {}; //perf: initialization is negligible ker.a = s_m1[x_m1]; //read sequentially from memory as far as possible ker.b = s_m1[x]; ker.c = s_m1[x_p1]; ker.d = s_m1[x_p2]; ker.e = s_0[x_m1]; ker.f = s_0[x]; ker.g = s_0[x_p1]; ker.h = s_0[x_p2]; ker.i = s_p1[x_m1]; ker.j = s_p1[x]; ker.k = s_p1[x_p1]; ker.l = s_p1[x_p2]; ker.m = s_p2[x_m1]; ker.n = s_p2[x]; ker.o = s_p2[x_p1]; ker.p = s_p2[x_p2]; const BlendResult res = preProcessCorners(ker, cfg); /* preprocessing blend result: --------- | F | G | //evalute corner between F, G, J, K ----|---| //input pixel is at position F | J | K | --------- */ setTopR(preProcBuffer[x], res.blend_j); if (x + 1 < bufferSize) setTopL(preProcBuffer[x + 1], res.blend_k); } } //------------------------------------------------------------------------------------ for (int y = yFirst; y < yLast; ++y) { uint32_t* out = trg + Scaler::scale * y * trgWidth; //consider MT "striped" access const uint32_t* s_m1 = src + srcWidth * std::max(y - 1, 0); const uint32_t* s_0 = src + srcWidth * y; //center line const uint32_t* s_p1 = src + srcWidth * std::min(y + 1, srcHeight - 1); const uint32_t* s_p2 = src + srcWidth * std::min(y + 2, srcHeight - 1); unsigned char blend_xy1 = 0; //corner blending for current (x, y + 1) position for (int x = 0; x < srcWidth; ++x, out += Scaler::scale) { #ifndef NDEBUG breakIntoDebugger = debugPixelX == x && debugPixelY == y; #endif //all those bounds checks have only insignificant impact on performance! const int x_m1 = std::max(x - 1, 0); //perf: prefer array indexing to additional pointers! const int x_p1 = std::min(x + 1, srcWidth - 1); const int x_p2 = std::min(x + 2, srcWidth - 1); Kernel_4x4 ker4 = {}; //perf: initialization is negligible ker4.a = s_m1[x_m1]; //read sequentially from memory as far as possible ker4.b = s_m1[x]; ker4.c = s_m1[x_p1]; ker4.d = s_m1[x_p2]; ker4.e = s_0[x_m1]; ker4.f = s_0[x]; ker4.g = s_0[x_p1]; ker4.h = s_0[x_p2]; ker4.i = s_p1[x_m1]; ker4.j = s_p1[x]; ker4.k = s_p1[x_p1]; ker4.l = s_p1[x_p2]; ker4.m = s_p2[x_m1]; ker4.n = s_p2[x]; ker4.o = s_p2[x_p1]; ker4.p = s_p2[x_p2]; //evaluate the four corners on bottom-right of current pixel unsigned char blend_xy = 0; //for current (x, y) position { const BlendResult res = preProcessCorners(ker4, cfg); /* preprocessing blend result: --------- | F | G | //evalute corner between F, G, J, K ----|---| //current input pixel is at position F | J | K | --------- */ blend_xy = preProcBuffer[x]; setBottomR(blend_xy, res.blend_f); //all four corners of (x, y) have been determined at this point due to processing sequence! setTopR(blend_xy1, res.blend_j); //set 2nd known corner for (x, y + 1) preProcBuffer[x] = blend_xy1; //store on current buffer position for use on next row blend_xy1 = 0; setTopL(blend_xy1, res.blend_k); //set 1st known corner for (x + 1, y + 1) and buffer for use on next column if (x + 1 < bufferSize) //set 3rd known corner for (x + 1, y) setBottomL(preProcBuffer[x + 1], res.blend_g); } //fill block of size scale * scale with the given color fillBlock(out, trgWidth * sizeof(uint32_t), ker4.f, Scaler::scale); //place *after* preprocessing step, to not overwrite the results while processing the the last pixel! //blend four corners of current pixel if (blendingNeeded(blend_xy)) //good 5% perf-improvement { Kernel_3x3 ker3 = {}; //perf: initialization is negligible ker3.a = ker4.a; ker3.b = ker4.b; ker3.c = ker4.c; ker3.d = ker4.e; ker3.e = ker4.f; ker3.f = ker4.g; ker3.g = ker4.i; ker3.h = ker4.j; ker3.i = ker4.k; blendPixel(ker3, out, trgWidth, blend_xy, cfg); blendPixel(ker3, out, trgWidth, blend_xy, cfg); blendPixel(ker3, out, trgWidth, blend_xy, cfg); blendPixel(ker3, out, trgWidth, blend_xy, cfg); } } } } //------------------------------------------------------------------------------------ template struct Scaler2x : public ColorGradient { static const int scale = 2; template //bring template function into scope for GCC static void alphaGrad(uint32_t& pixBack, uint32_t pixFront) { ColorGradient::template alphaGrad(pixBack, pixFront); } template static void blendLineShallow(uint32_t col, OutputMatrix& out) { alphaGrad<1, 4>(out.template ref(), col); alphaGrad<3, 4>(out.template ref(), col); } template static void blendLineSteep(uint32_t col, OutputMatrix& out) { alphaGrad<1, 4>(out.template ref<0, scale - 1>(), col); alphaGrad<3, 4>(out.template ref<1, scale - 1>(), col); } template static void blendLineSteepAndShallow(uint32_t col, OutputMatrix& out) { alphaGrad<1, 4>(out.template ref<1, 0>(), col); alphaGrad<1, 4>(out.template ref<0, 1>(), col); alphaGrad<5, 6>(out.template ref<1, 1>(), col); //[!] fixes 7/8 used in xBR } template static void blendLineDiagonal(uint32_t col, OutputMatrix& out) { alphaGrad<1, 2>(out.template ref<1, 1>(), col); } template static void blendCorner(uint32_t col, OutputMatrix& out) { //model a round corner alphaGrad<21, 100>(out.template ref<1, 1>(), col); //exact: 1 - pi/4 = 0.2146018366 } }; template struct Scaler3x : public ColorGradient { static const int scale = 3; template //bring template function into scope for GCC static void alphaGrad(uint32_t& pixBack, uint32_t pixFront) { ColorGradient::template alphaGrad(pixBack, pixFront); } template static void blendLineShallow(uint32_t col, OutputMatrix& out) { alphaGrad<1, 4>(out.template ref(), col); alphaGrad<1, 4>(out.template ref(), col); alphaGrad<3, 4>(out.template ref(), col); out.template ref() = col; } template static void blendLineSteep(uint32_t col, OutputMatrix& out) { alphaGrad<1, 4>(out.template ref<0, scale - 1>(), col); alphaGrad<1, 4>(out.template ref<2, scale - 2>(), col); alphaGrad<3, 4>(out.template ref<1, scale - 1>(), col); out.template ref<2, scale - 1>() = col; } template static void blendLineSteepAndShallow(uint32_t col, OutputMatrix& out) { alphaGrad<1, 4>(out.template ref<2, 0>(), col); alphaGrad<1, 4>(out.template ref<0, 2>(), col); alphaGrad<3, 4>(out.template ref<2, 1>(), col); alphaGrad<3, 4>(out.template ref<1, 2>(), col); out.template ref<2, 2>() = col; } template static void blendLineDiagonal(uint32_t col, OutputMatrix& out) { alphaGrad<1, 8>(out.template ref<1, 2>(), col); //conflict with other rotations for this odd scale alphaGrad<1, 8>(out.template ref<2, 1>(), col); alphaGrad<7, 8>(out.template ref<2, 2>(), col); // } template static void blendCorner(uint32_t col, OutputMatrix& out) { //model a round corner alphaGrad<45, 100>(out.template ref<2, 2>(), col); //exact: 0.4545939598 //alphaGrad<7, 256>(out.template ref<2, 1>(), col); //0.02826017254 -> negligible + avoid conflicts with other rotations for this odd scale //alphaGrad<7, 256>(out.template ref<1, 2>(), col); //0.02826017254 } }; template struct Scaler4x : public ColorGradient { static const int scale = 4; template //bring template function into scope for GCC static void alphaGrad(uint32_t& pixBack, uint32_t pixFront) { ColorGradient::template alphaGrad(pixBack, pixFront); } template static void blendLineShallow(uint32_t col, OutputMatrix& out) { alphaGrad<1, 4>(out.template ref(), col); alphaGrad<1, 4>(out.template ref(), col); alphaGrad<3, 4>(out.template ref(), col); alphaGrad<3, 4>(out.template ref(), col); out.template ref() = col; out.template ref() = col; } template static void blendLineSteep(uint32_t col, OutputMatrix& out) { alphaGrad<1, 4>(out.template ref<0, scale - 1>(), col); alphaGrad<1, 4>(out.template ref<2, scale - 2>(), col); alphaGrad<3, 4>(out.template ref<1, scale - 1>(), col); alphaGrad<3, 4>(out.template ref<3, scale - 2>(), col); out.template ref<2, scale - 1>() = col; out.template ref<3, scale - 1>() = col; } template static void blendLineSteepAndShallow(uint32_t col, OutputMatrix& out) { alphaGrad<3, 4>(out.template ref<3, 1>(), col); alphaGrad<3, 4>(out.template ref<1, 3>(), col); alphaGrad<1, 4>(out.template ref<3, 0>(), col); alphaGrad<1, 4>(out.template ref<0, 3>(), col); alphaGrad<1, 3>(out.template ref<2, 2>(), col); //[!] fixes 1/4 used in xBR out.template ref<3, 3>() = col; out.template ref<3, 2>() = col; out.template ref<2, 3>() = col; } template static void blendLineDiagonal(uint32_t col, OutputMatrix& out) { alphaGrad<1, 2>(out.template ref(), col); alphaGrad<1, 2>(out.template ref(), col); out.template ref() = col; } template static void blendCorner(uint32_t col, OutputMatrix& out) { //model a round corner alphaGrad<68, 100>(out.template ref<3, 3>(), col); //exact: 0.6848532563 alphaGrad< 9, 100>(out.template ref<3, 2>(), col); //0.08677704501 alphaGrad< 9, 100>(out.template ref<2, 3>(), col); //0.08677704501 } }; template struct Scaler5x : public ColorGradient { static const int scale = 5; template //bring template function into scope for GCC static void alphaGrad(uint32_t& pixBack, uint32_t pixFront) { ColorGradient::template alphaGrad(pixBack, pixFront); } template static void blendLineShallow(uint32_t col, OutputMatrix& out) { alphaGrad<1, 4>(out.template ref(), col); alphaGrad<1, 4>(out.template ref(), col); alphaGrad<1, 4>(out.template ref(), col); alphaGrad<3, 4>(out.template ref(), col); alphaGrad<3, 4>(out.template ref(), col); out.template ref() = col; out.template ref() = col; out.template ref() = col; out.template ref() = col; } template static void blendLineSteep(uint32_t col, OutputMatrix& out) { alphaGrad<1, 4>(out.template ref<0, scale - 1>(), col); alphaGrad<1, 4>(out.template ref<2, scale - 2>(), col); alphaGrad<1, 4>(out.template ref<4, scale - 3>(), col); alphaGrad<3, 4>(out.template ref<1, scale - 1>(), col); alphaGrad<3, 4>(out.template ref<3, scale - 2>(), col); out.template ref<2, scale - 1>() = col; out.template ref<3, scale - 1>() = col; out.template ref<4, scale - 1>() = col; out.template ref<4, scale - 2>() = col; } template static void blendLineSteepAndShallow(uint32_t col, OutputMatrix& out) { alphaGrad<1, 4>(out.template ref<0, scale - 1>(), col); alphaGrad<1, 4>(out.template ref<2, scale - 2>(), col); alphaGrad<3, 4>(out.template ref<1, scale - 1>(), col); alphaGrad<1, 4>(out.template ref(), col); alphaGrad<1, 4>(out.template ref(), col); alphaGrad<3, 4>(out.template ref(), col); alphaGrad<2, 3>(out.template ref<3, 3>(), col); out.template ref<2, scale - 1>() = col; out.template ref<3, scale - 1>() = col; out.template ref<4, scale - 1>() = col; out.template ref() = col; out.template ref() = col; } template static void blendLineDiagonal(uint32_t col, OutputMatrix& out) { alphaGrad<1, 8>(out.template ref(), col); //conflict with other rotations for this odd scale alphaGrad<1, 8>(out.template ref(), col); alphaGrad<1, 8>(out.template ref(), col); // alphaGrad<7, 8>(out.template ref<4, 3>(), col); alphaGrad<7, 8>(out.template ref<3, 4>(), col); out.template ref<4, 4>() = col; } template static void blendCorner(uint32_t col, OutputMatrix& out) { //model a round corner alphaGrad<86, 100>(out.template ref<4, 4>(), col); //exact: 0.8631434088 alphaGrad<23, 100>(out.template ref<4, 3>(), col); //0.2306749731 alphaGrad<23, 100>(out.template ref<3, 4>(), col); //0.2306749731 //alphaGrad<1, 64>(out.template ref<4, 2>(), col); //0.01676812367 -> negligible + avoid conflicts with other rotations for this odd scale //alphaGrad<1, 64>(out.template ref<2, 4>(), col); //0.01676812367 } }; template struct Scaler6x : public ColorGradient { static const int scale = 6; template //bring template function into scope for GCC static void alphaGrad(uint32_t& pixBack, uint32_t pixFront) { ColorGradient::template alphaGrad(pixBack, pixFront); } template static void blendLineShallow(uint32_t col, OutputMatrix& out) { alphaGrad<1, 4>(out.template ref(), col); alphaGrad<1, 4>(out.template ref(), col); alphaGrad<1, 4>(out.template ref(), col); alphaGrad<3, 4>(out.template ref(), col); alphaGrad<3, 4>(out.template ref(), col); alphaGrad<3, 4>(out.template ref(), col); out.template ref() = col; out.template ref() = col; out.template ref() = col; out.template ref() = col; out.template ref() = col; out.template ref() = col; } template static void blendLineSteep(uint32_t col, OutputMatrix& out) { alphaGrad<1, 4>(out.template ref<0, scale - 1>(), col); alphaGrad<1, 4>(out.template ref<2, scale - 2>(), col); alphaGrad<1, 4>(out.template ref<4, scale - 3>(), col); alphaGrad<3, 4>(out.template ref<1, scale - 1>(), col); alphaGrad<3, 4>(out.template ref<3, scale - 2>(), col); alphaGrad<3, 4>(out.template ref<5, scale - 3>(), col); out.template ref<2, scale - 1>() = col; out.template ref<3, scale - 1>() = col; out.template ref<4, scale - 1>() = col; out.template ref<5, scale - 1>() = col; out.template ref<4, scale - 2>() = col; out.template ref<5, scale - 2>() = col; } template static void blendLineSteepAndShallow(uint32_t col, OutputMatrix& out) { alphaGrad<1, 4>(out.template ref<0, scale - 1>(), col); alphaGrad<1, 4>(out.template ref<2, scale - 2>(), col); alphaGrad<3, 4>(out.template ref<1, scale - 1>(), col); alphaGrad<3, 4>(out.template ref<3, scale - 2>(), col); alphaGrad<1, 4>(out.template ref(), col); alphaGrad<1, 4>(out.template ref(), col); alphaGrad<3, 4>(out.template ref(), col); alphaGrad<3, 4>(out.template ref(), col); out.template ref<2, scale - 1>() = col; out.template ref<3, scale - 1>() = col; out.template ref<4, scale - 1>() = col; out.template ref<5, scale - 1>() = col; out.template ref<4, scale - 2>() = col; out.template ref<5, scale - 2>() = col; out.template ref() = col; out.template ref() = col; } template static void blendLineDiagonal(uint32_t col, OutputMatrix& out) { alphaGrad<1, 2>(out.template ref(), col); alphaGrad<1, 2>(out.template ref(), col); alphaGrad<1, 2>(out.template ref(), col); out.template ref() = col; out.template ref() = col; out.template ref() = col; } template static void blendCorner(uint32_t col, OutputMatrix& out) { //model a round corner alphaGrad<97, 100>(out.template ref<5, 5>(), col); //exact: 0.9711013910 alphaGrad<42, 100>(out.template ref<4, 5>(), col); //0.4236372243 alphaGrad<42, 100>(out.template ref<5, 4>(), col); //0.4236372243 alphaGrad< 6, 100>(out.template ref<5, 3>(), col); //0.05652034508 alphaGrad< 6, 100>(out.template ref<3, 5>(), col); //0.05652034508 } }; //------------------------------------------------------------------------------------ struct ColorDistanceBGR { static double dist(uint32_t pix1, uint32_t pix2, double luminanceWeight) { return DistYCbCrBuffer::dist(pix1, pix2); //if (pix1 == pix2) //about 4% perf boost // return 0; //return distYCbCr(pix1, pix2, luminanceWeight); } }; struct ColorDistanceABGR { static double dist(uint32_t pix1, uint32_t pix2, double luminanceWeight) { const double a1 = getAlpha(pix1) / 255.0; const double a2 = getAlpha(pix2) / 255.0; /* Requirements for a color distance handling alpha channel: with a1, a2 in [0, 1] 1. if a1 = a2, distance should be: a1 * distYCbCr() 2. if a1 = 0, distance should be: a2 * distYCbCr(black, white) = a2 * 255 3. if a1 = 1, ??? maybe: 255 * (1 - a2) + a2 * distYCbCr() */ //return std::min(a1, a2) * DistYCbCrBuffer::dist(pix1, pix2) + 255 * abs(a1 - a2); //=> following code is 15% faster: const double d = DistYCbCrBuffer::dist(pix1, pix2); if (a1 < a2) return a1 * d + 255 * (a2 - a1); else return a2 * d + 255 * (a1 - a2); //alternative? return std::sqrt(a1 * a2 * square(DistYCbCrBuffer::dist(pix1, pix2)) + square(255 * (a1 - a2))); } }; struct ColorGradientBGR { template static void alphaGrad(uint32_t& pixBack, uint32_t pixFront) { pixBack = gradientBGR(pixFront, pixBack); } }; struct ColorGradientABGR { template static void alphaGrad(uint32_t& pixBack, uint32_t pixFront) { pixBack = gradientABGR(pixFront, pixBack); } }; } void xbrz::init() { static bool inited = false; if (!inited) { DistYCbCrBuffer::dist(0, 0); inited = true; } } void xbrz::scale(size_t factor, const uint32_t* src, uint32_t* trg, int srcWidth, int srcHeight, ColorFormat colFmt, const xbrz::ScalerCfg& cfg, int yFirst, int yLast) { switch (colFmt) { case ColorFormat::ABGR: switch (factor) { case 2: return scaleImage, ColorDistanceABGR>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast); case 3: return scaleImage, ColorDistanceABGR>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast); case 4: return scaleImage, ColorDistanceABGR>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast); case 5: return scaleImage, ColorDistanceABGR>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast); case 6: return scaleImage, ColorDistanceABGR>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast); } break; case ColorFormat::BGR: switch (factor) { case 2: return scaleImage, ColorDistanceBGR>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast); case 3: return scaleImage, ColorDistanceBGR>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast); case 4: return scaleImage, ColorDistanceBGR>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast); case 5: return scaleImage, ColorDistanceBGR>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast); case 6: return scaleImage, ColorDistanceBGR>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast); } break; } assert(false); } bool xbrz::equalColorTest(uint32_t col1, uint32_t col2, ColorFormat colFmt, double luminanceWeight, double equalColorTolerance) { switch (colFmt) { case ColorFormat::ABGR: return ColorDistanceABGR::dist(col1, col2, luminanceWeight) < equalColorTolerance; case ColorFormat::BGR: return ColorDistanceBGR::dist(col1, col2, luminanceWeight) < equalColorTolerance; } assert(false); return false; } void xbrz::nearestNeighborScale(const uint32_t* src, int srcWidth, int srcHeight, int srcPitch, uint32_t* trg, int trgWidth, int trgHeight, int trgPitch, SliceType st, int yFirst, int yLast) { if (srcPitch < srcWidth * static_cast(sizeof(uint32_t)) || trgPitch < trgWidth * static_cast(sizeof(uint32_t))) { assert(false); return; } switch (st) { case NN_SCALE_SLICE_SOURCE: //nearest-neighbor (going over source image - fast for upscaling, since source is read only once yFirst = std::max(yFirst, 0); yLast = std::min(yLast, srcHeight); if (yFirst >= yLast || trgWidth <= 0 || trgHeight <= 0) return; for (int y = yFirst; y < yLast; ++y) { //mathematically: ySrc = floor(srcHeight * yTrg / trgHeight) // => search for integers in: [ySrc, ySrc + 1) * trgHeight / srcHeight //keep within for loop to support MT input slices! const int yTrg_first = (y * trgHeight + srcHeight - 1) / srcHeight; //=ceil(y * trgHeight / srcHeight) const int yTrg_last = ((y + 1) * trgHeight + srcHeight - 1) / srcHeight; //=ceil(((y + 1) * trgHeight) / srcHeight) const int blockHeight = yTrg_last - yTrg_first; if (blockHeight > 0) { const uint32_t* srcLine = byteAdvance(src, y * srcPitch); uint32_t* trgLine = byteAdvance(trg, yTrg_first * trgPitch); int xTrg_first = 0; for (int x = 0; x < srcWidth; ++x) { int xTrg_last = ((x + 1) * trgWidth + srcWidth - 1) / srcWidth; const int blockWidth = xTrg_last - xTrg_first; if (blockWidth > 0) { xTrg_first = xTrg_last; fillBlock(trgLine, trgPitch, srcLine[x], blockWidth, blockHeight); trgLine += blockWidth; } } } } break; case NN_SCALE_SLICE_TARGET: //nearest-neighbor (going over target image - slow for upscaling, since source is read multiple times missing out on cache! Fast for similar image sizes!) yFirst = std::max(yFirst, 0); yLast = std::min(yLast, trgHeight); if (yFirst >= yLast || srcHeight <= 0 || srcWidth <= 0) return; for (int y = yFirst; y < yLast; ++y) { uint32_t* trgLine = byteAdvance(trg, y * trgPitch); const int ySrc = srcHeight * y / trgHeight; const uint32_t* srcLine = byteAdvance(src, ySrc * srcPitch); for (int x = 0; x < trgWidth; ++x) { const int xSrc = srcWidth * x / trgWidth; trgLine[x] = srcLine[xSrc]; } } break; } } mupen64plus-core/RELEASE000664 001750 001750 00000077325 12655644434 016070 0ustar00sergiosergio000000 000000 Mupen64Plus-Core Emulator Library RELEASE ----------------------------------------- Mupen64Plus v1.99.5 - March 10, 2012 ------------------------------------ - New feature: support for N64 internal real-time clock - use X-Scale's PIF-CIC algorithm instead of the hard-coded challenge-response pairs - New config parameter for path to save SRAM/EEPROM/MPK files, so they can be separated from emulator snapshots - updated core for new Mupen64plus 2.0 API versioning scheme - split core configuration data into 2 sections: Core and CoreEvents. Added version numbers and upgrade handling to both - Accurately emulate the RSP DMA operation (from Bobby Smiles) - bugfix: #290 - OnScreenDisplay text is sometimes captured in screenshots - bugfix: when the front-end specifies an override for the configuration directory, always use this path, so that we don't load the config from there and then save it back to the default user path - bugfix: #468 - On-screen-display problem under OSX - bugfix: Use option SaveStatePath from config file - bugfix: don't call SDL_Quit() until the core library is being unloaded. fixes some front-end use cases - bugfix: #410 - segfault in dma_pi_write()-->strlen() if /home/username/.local/share/mupen64plus/ owned by root - bugfix: for Interpreter cores, use proper math functions for ceil/floor/round/trunc instead of x87 rounding modes - many makefile fixes and improvements Mupen64Plus v1.99.4 - February 22, 2010 --------------------------------------- - Added some type checking to ConfigGetParameter() function, and a new error type - Bugfix: avoid segfault in the video extension code if SDL initialization fails (because video plugin fails) - Added new CoreGetRomSettings() function for front-ends - Allow to run dynarec in hardware DEP protected windows - Allow core .cfg parser to accept strings without quotes around them - API change: use new ReadScreen2() video plugin function - New re-entrant R4300 disassembler, from tty68k/zzt32, a man who loves MIPS processors - makefile fixes and improvements, code cleanups Mupen64Plus v1.99.3 - February 13, 2010 --------------------------------------- - New feature: configuration function ConfigGetParameterType() - New feature: up to 1000 screenshots per ROM are allowed - New feature: support for Gameshark 3.3 patch codes - Bugfix: Use Dynarec by default when core supports it. If dynarec is selected but unavailable, fall back to cached interpreter - Bugfix: screenshot directory handling code used unix-specific path separators; now is platform-independent - Bugfix: #313 - 64-bit inline assembly code in r4300/x86_64/rjump.c needs to have underscores before the symbols names in OSX - Bugfix: old bug in the core - hang if a ROM *without* a 16kb EEPROM type is loaded after a ROM *with* a 16kb EEPROM type - Bugfix: rumble feature caused memory corruption - Bugfix: Problem with zilmar API: the plugin RomOpen() functions had no way of returning errors to the core, causing crashes - Replaced api documentation .tar.gz file with the mediawiki text - Build script improvements: - new feature: m64p_update.sh script can take an input argument to update to a tag or revision - new feature: added bash script for building source packages of individual modules - Makefile improvements: - dont run ldconfig on make install unless user is root - added OS type GNU/kFreeBSD Mupen64Plus v1.99.2 - January 6, 2010 --------------------------------------- - doc: added tarball of emuwiki api documentation from 2010-01-06 for backup purposes - clean-up: removed almost all of the ifdef WIN32 statements - bugfix: stop spamming console with "Core: couldn't open memory pack file '...' for reading" messages - bugfix: stop spamming console with "Core: couldn't open eeprom file '...' for reading" messages - new feature: MSVC8 project file for mupen64plus-core, refactored code for VC8 compatibility - Makefile improvements: - throw error if OS/CPU not supported - use DESTDIR in install/uninstall paths - Allow user-specified CC/CXX/LD paths - makefile needs to install Core header files so that plugins can be built later Mupen64Plus v1.99.1 - December 14, 2009 --------------------------------------- New 2.0 architecture advantages: - Simplified emulator Core, making it much more portable - Removed all GUI code from plugins, making them simpler and more portable - User interface development is not tied to Core emulator releases - All messages from core/plugins can be filtered and shown in GUI instead of only on console - Video Extension allows Front-end to override some video functions, ie to support embedded render window - Startup in Fullscreen mode, instead of always starting in windowed mode and switching to FS after few seconds - video resolution can be given via command-line parameter - all configuration options for core and plugins are in a single config file, can be configured with a single GUI - dummy plugins are automatically used if plugin loading fails for any reason - core and plugins all use the same conventions for where to put data/config files Mupen64Plus core: - New feature: cheat code support - New feature: Keyboard shortcuts for Core commands are now user-configurable - New feature: can load/save PJ64 state files - Major code cleanup, refactored build system to separate source and object files - Removed many dependencies to simplify porting to other platforms - Moved all of the SDL event-related stuff into a new source file eventloop.c - Use XDG directory convention for file locations on Unix - bugfix: frame advance feature should advance every frame, instead of every vertical interrupt (every field) - bugfix: allow diagonal hat movements for core joystick commands - bugfix: modified SDL event loop joystick code so that gameshark button press is captured, and joystick commands that are level-triggered instead of edge-triggered (such as fast foward) can be accommodated - bugfix: fixed the outstanding SDL event issues by re-writing the code which handles the joystick-event-driven core commands. Now the axis-based commands use hysteresis and there is a single global event function for determining if the gameshark button is pressed - bugfix: OSD crash after pause-stop-start-pause of emulator - bugfix: Set video width and status, aiDacrate during savestate load - bugfix: in pure interpreter, Dont allow to override r0 register - bugfix #52: PJ64 load state patch from olejl77 - bugfix #268: use aligned malloc and mprotect to set executable status for dynarec emitted code - bugfix #51: Floating Point Register data was not correctly converted when switching between 32-bit (MIPS-I) mode and 64-bit (MIPS III). New code more closely emulates behavior of r4300 hardware. Fixes collision problems in Banjo-Tooie - bugfix #272: rounding mode for x86 FPU not being set correctly in interpreter and pure interpreter cores - bugfix: many games need different ScreenUpdateSetting to work properly with Rice Video Mupen64Plus v1.5 - January 4, 2009 ---------------------------------- Major New Features: - support for Macintosh OSX platform with Intel CPUs - Qt4 GUI by slougi, Tillin9, and others - Rom Cache System (r636, others), by Tillin9, Okaygo, and Hasone. Minor New Features: - r1235: Debugger: memory breakpoint speedup - r1170-1178,1181: QT GUI: translations for English, Norwegian, German, and Dutch - r1155: Use configurable key commands for special emulator functions - r1134: got our own custom test ROM, courtesy of Marshallh - r1046: debugger: new r4300 disassembler from ZZT32 - r829: jttl_audio: added GTK GUI configuration dialog - r793: soft reset (hit F9) - r782: jttl_audio: both SDL-based and OSS-based volume control methods are now supported - r765: added savestate conversion tool to be able to load pre-v1.5 savestate files - r711: 7-zip support - r692: Multi-file Zip support - r667: GTK GUI: user-configurable columns in ROM browser - r659: LZMA archive support - r638: BZip2 archive support - r629,634: LIRC - added support for speedup, slowdown, pause, and frame advance Updates: - r1007,1032: GTK GUI improvements - r970, 1019: use SDL threading support instead of pthreads - r935,938,940: Gtk GUI updates for core and Jttl - r642,655-657,663,664,747,759,761-763,768-770,774,775,780,781,783,786,787,825,828,931: mupen64plus.ini updates: Good Names, stars, EEPROM types, players, rumble support Bugfixes: - r1247: rsp_hle: memory overwrite bug with Zelda:OOT - r1234: out of bound array bug in memory access function handlers - r1222,1223,1228,1229: Debugger fixes - r1183: Blight Input: sometimes the axis direction would flip - r1133: Added stop rumble to load savestate, fixes issue 165 - r1077: GTK GUI bugfixes - r1063: rice video: crash in MMX/SSE checking functions - r800: logical error in strcpy loop in util.c - r798: small bugfixes in blight_input: 1. only save config file after running config dialog, not every time DLL is closed. 2. If rumble is not available on a controller, don't allow user to switch between rumble and mempack. 3. If rumble is selected in config file but not available on a controller, select mempack instead. - r789: 3 glN64 bugfixes (segfaults on a 64-bit system in Perfect Dark): prevent clamp values from being negative, handle TMEM wrap-arounds from wacky height/line values in texture cache load and texture CRC functions - r788: rice video: add checks for uint32 height/width parameters which can be negative, causing segfault on 64-bit systems - r784: 64-bit problem causing GUI crashes - gotta save/restore all the callee-saved registers around the dynarec - r758: fixed some savestate problems - r748: Fixed 64-bit dynarec crash in genj_idle() and genjal_idle() - r715: Bugfixes thanks to Valgrind. Two using strcpy with source and destination overlay, i.e. strcpy(p,p+1) - r700: set ScreenUpdateSetting=1 in rice video ini file for Conkers BFD - r694: require bash shell scripting for install.sh - r686: fixed OSD crash bug after running a game, disabling OSD, then running another game - r684: OGLFT measuring functions were taking a huge chunk of CPU time. Refactored code to measure only once and store the line size and the message sizes instead of re-measuring all the time. This eliminated nearly all of the OSD overhead on my PC - r681: Refactored OGLFT to do color setting outside of glyph compiling, so the OSD fading doesnt force bitmaps to be continually recreated with calls to renderGlyph. Seems to have cut the excessive cpu usage of the OSD about by half - r680: removed many unused classes from OGLFT font library code - r676: bugfix in my BYTESWAP macros - r674: Removed glide64/Tmem_nasm.asm source file and the project dependency on nasm/yasm assemblers - r673: removed inline assembly sections in rdp_loadblock and rdp_loadtile, including their dependency on functions in Tmem_nasm.asm. Replaced with new C code. This fixes a segfault on some 64-bit source builds - r669: string function causing crash on 64-bit linux - r667: issue #88 - added basic view menu in GTK GUI - r628,633: Small patch to get glide64.so to compile with O3 optimizations - r622: Fixed segfault in Glide64 as per issue 133 - r619: fix LIRC build to integrate w/ new screenshot mechanism - r608: another couple of memory leak fixes from Tub, in main/config.c - r605: fix from Tub for free() bug in main/util.c/list_delete() - r587: issue #111: close screenshot file after saving Mupen64Plus v1.4 - June 14, 2008 ----------------------------------- - New feature: Graphical debugger for R4300 core - New feature: On Screen Display - New feature: KDE4 GUI (experimental) - New feature: cheat system with Gameshark codes - New feature: search/filter box in GTK GUI - New feature: Single frame advance - New feature: adjust emulator playback speed up or down in 5% increments - New feature: Rumble Pak support with force feedback - New feature: Map emulator functions (fullscreen, stop emulation, etc) to joystick buttons or axis movements. - New feature: Volume up/down - Blight Input: Individually configure each direction of X and Y axis, which allows inverting the axis - JTTL_Audio: libsamplerate support for high quality audio resampling - GTK GUI: Removed second status bar which was not used - GTK GUI: Implemented accelerator keys - GTK GUI: Replaced custom directory browser with GTK file chooser - GTK GUI: numerous small changes and fixes - Added Mupen64Plus 'man' (manual) page - Removed mupen64_audio plugin, as it was unnecessary and mostly broken - Added NoMemoryExpansion parameter to emulate 4MB console; fixes some games - Overhaul of rom handling functions; numerous small fixes - Bugfix: Removed NoAudioDelay core option to resolve issue #48 - Bugfix: check for stopped state in dynarec jump function, to fix unresponsive emulator when game gets stuck in loop - Bugfix: GTK GUI: #6 - if a ROM is selected in the ROM browser and 'play' is pressed, emulation will start - Bugfix: GTK GUI: #62 - ROM browser column sorting works - Bugfix: Rice Video: Support hi-res textures with different scale factors for X and Y - Bugfix: Blight Input: don't use 100% CPU in configuration dialog Mupen64Plus v1.3 - March 29th, 2008 ----------------------------------- - New feature: Glide64 video plugin for 32-bit and 64-bit, renamed project Mupen64Plus - New feature: Combine mupen64 and mupen64_nogui into a single binary - New feature: ability to change icon size - New feature: support different directories for install (plugins, icons, etc) and config (save games, config files) - New feature: support for creating/using ~/.mupen64plus dir for storing user data - New feature: support for installation via "make install" or "./install.sh" - New feature: support for plugins given via command line option in GUI mode - New feature: config dialog checkbox to toggle "noask" setting - New feature: pause/continue functionality with LIRC - Removed messagebox utility and replaced it with cleaner alert_message/confirm_message calls - GTK GUI: Set parent window for all popups so WM will center popup windows over the main gui window - Added README file with information about usage of Mupen64Plus and plugins - Removed mupen64_soft_gfx, as it didn't work - Removed Win32 code from RSP HLE plugin, - Change fullscreen hotkey to Alt+Enter - Only plugin filenames (not paths) are stored in the mupen64plus.conf file - Modified pre.mk and glide64 makefile to auto-select yasm or nasm - Bugfix: Rice Video: Make configuration during gameplay possible again - Bugfix: many compiler warnings and errors in Glide64 - Bugfix: segfault in Goldeneye and Perfect Dark for 64-bit dynarec - Bugfix: 64-bit dynarec bug in genld() - Bugfix: buffer overflow allocating temp strings for basename/dirname - Bugfix: GTK GUI: Exiting via File -> Exit wasn't writing out config file to disk - Bugfix: GTK GUI: "About" menu does not pop up while emulation is running - Bugfix: Glide64: Refactored a bunch of inline asm code with potential bugs - Bugfix: Added plugin error checking before emulator is started - Bugfix: Logo not loading in "about" window - Bugfix: Segfault in plugin_scan_directory() - Bugfix: ROM pause/continue while playing - Bugfix: Too many dialog windows when loading a bad dump or hacked rom - Bugfix: Closing emulation window now stops emulator - Bugfix: Rice Video: config dialog bug, now it displays proper resolution - Bugfix: GTK GUI: "Toolbar Style" now works - Bugfix: Glide64: changed inline asm label syntax, for compatibility with gcc 4.3.0 - Bugfix: Many other minor bug fixes, GTK warnings fixes, translation corrections, etc Mupen64-amd64 v1.2 - February 10th, 2008 ---------------------------------------- - New feature: Dynamic Recompiler for 64-bit - New feature: New ROM Browser for Mupen64 GUI build - New feature: LIRC remote control integration for NOGUI build - Added R4300 instruction counting capability to 64-bit Dynarec - Added R4300 profile data output for 32-bit and 64-bit dynamic recompilers - TLB Optimization / bugfix - Revised makefiles to support PPC builds - Bugfix: memory leaks in mupenIniApi.c - Bugfix: corrupted filenames being saved to disk for mupen64.ini - Bugfix: crash in jttl_audio - Bugfix: crash when running game from gui after first time - Bugfix: spurious noise blip when running game from gui after first time RiceVideoLinux v1.2 - February 10th, 2008 ----------------------------------------- - Revised makefiles to support PPC builds - Added more logging to hi-res texture loading - Bugfix: Texture dumping now works Mupen64-amd64 v1.1 - December 9th, 2007 ---------------------------------------- - New icons for GTK GUI - Removed GTK 1.2 GUI build; GTK 2.0 is required now - Added file pointer checking for frwite() calls and error logging - Added scrolling to the the rom list widget - Added main/version.h file to store Mupen64-amd64 package version - Print joystick numbers along with names in blight input to tell multiple devices apart - Merged okaygo's TLB hack for Goldeneye from Mupen64++ - Rework GTK GUI config dialog; fixed bugs in ROM directory list - Bugfix: segfault from playing same game twice in a row from GUI - Bugfix: segfault from fwrite() failure in dma_pi_read in memory/dma.c - Bugfix: exit properly instead of segfault after dyna_stop is called - Bugfix: blight input: SDL_PumpEvents must be called from thread which initialized SDL video mode - Bugfix: blight_input: joystick handling caused glitch in config dialog - Bugfix: makefile: 32-bit CFLAGS must be used when doing 32-bit build on 64-bit machine - Bugfix: Added makefile to root folder for building releases RiceVideoLinux v1.1 - December 9th, 2007 ----------------------------------------- - Removed configure script and config.h; added SDL and GTK library checking and handling in main makefile - Added capability to load 24-bit PNG files into 32-bit texture buffer - Added more error logging to hi-res texture code - Added combiner type logging to DeviceBuilder class - Bugfix: added quotes around BUILD_NUMBER to prevent segfault on About box - Bugfix: SSE vertex lighting inline ASM code was incorrect - Bugfix: makefile: 32-bit CFLAGS must be used when doing 32-bit build on 64-bit machine - Bugfix: segfault with hi-res textures (incorrect scale factor used when creating memory buffer) - Bugfix: modified DrawSprite function in RenderExt.cpp to eliminate gaps between textures in Puyo Puyo 4 - Bugfix: opengl error in ApplyTextureFilter due to wrong enum type - Bugfix: Simplified fragment program and removed ATTRIB parameters to fix problems on Intel X3100 hardware Mupen64-amd64 v1.0 - November 12th, 2007 ---------------------------------------- - Forked from Mupen64 v0.5 - Ported to 64-bit architecture by NMN/SirRichard42 - Fixed texture cache problem in glN64 - Print more information during plugin loading process - Added blight input config file for logitech dual-action style controllers - Added SDL_GL_SWAP_CONTROL attribute in glN64 to prevent tearing - Changed glVoids to voids due to strange compilation bug that occurs on certain systems - Totally refactored makefiles; now plugins are built as sub-modules - Better logging for R4300 core selection, disallow Dynamic Recompilation for 64-bit builds at compile time - Set execstack attribute for all mupen64 binaries, to prevent segfault when Dynamic Recompilation is used - Lots of code cleanup - Removed 'multi-user' mode of operation - Removed 'configure' script and config.h file - Refactored plugin loading code in _nogui build, much more user-friendly now - Added comments and SDL shutdown code to main.c - Bugfix: fixed memory leaks in plugin.c - Bugfix: strcpy in main/gui_gtk/config.c should not copy overlapping strings - Bugfix: blight audio: only close down audio and timer sub-systems when exiting RiceVideoLinux v1.0 - November 12th, 2007 ----------------------------------------- - Forked from RiceVideo 6.1.1 beta 10 - Ported to Linux by Hacktarux - Ported to 64-bit architecture by SirRichard42 - Added rudimentary debug support for Linux - Merged all Non-Win32 changes from Mudlord's RiceVideo SVN 6.1.3.2 (mostly hi-res texture load/save) - Added more logging information - Tweaked Z-Buffer and Z-Bias (Decal Z-mode) handling to be like that of D3D renderer - Added screenshot capability for Linux build - Cleaned up Makefile, added 32-bit and debug build modes, help info - Removed all Win32 code, massive cleanup - Fixed uninitialized data members in several places - Bugfix: crash in Banjo Kazooie - dont delete cached texture if its currently loaded in the g_textures array - Bugfix: crash in Carmaggedon caused by illegal values in texture loading function - Bugfix: screen flashes in Mario Kart and Kirby64, tweaked .ini ScreenUpdateSetting what's new in 0.5: - Core + detection of invalid code cache for ambiguous region now use adler32 (faster than previous algorithm) + fixed a bug in ini file compression + added support for framebuffer effects functions : these functions are there to help the plugins that support framebuffer extension to zilmar's spec. These functions are based on rice's idea. I've worked closely with Gonetz to implement these and the only plugin that support this feature is Glide64 0.8 (when option is enabled). Many hard to emulate framebuffer effects are supported by this feature. Mariokart's monitor in first race running fullspeed and puzzle effect in banjo's intro are two examples that i can think about but there are many more. + detection of VI interupt rate works on weird country codes + better detection of self modifying code in dma + warnings fixed on new gcc versions + rsp's dmem and imem are now contiguous in PC's memory (some windows plugins were requiring this) + slightly improved audio timing + better detection of self modifying code when accessing memory through TLB + fixed a bug in RSP memory write + reading from ai_current_delay register should work even when Count register is looping + in interpreter code : fixed a bug in jump opcodes (detection of exceptions in delay slot in some rare conditions) + the event scheduler has better support for Count register loops + better AI interrupt handling (for musyx games for example) + jump opcodes changed in pure interpreter core so that they are timed exactly like on the other cores (easier to debug this way) + fixed a bug when accessing memory through invalid TLB in LDL, LDR, LWL, LWR, SWL, SDL, SDR, SWR opcodes + added LL, SC opcodes + two consecutive jump opcodes doesn't crash in the dynarec (result is undefined according to the r4300 manual but some games are doing it). + basic implementation of fpu opcodes in dynarec + division by 0 in FPU opcodes is returning NaN + all jump opcodes implemented in the dynarec + faster inside function loop with dynarec (register cache) + various bug fixes in dynarec opcodes + memory access improvements in dynarec - Linux version + GUI and all plugins have been switched to GKT2 (all old plugins should be recompiled for GTK2) + detection of GTK 1.2 or GTK 2 in the configure script : if both are detected, the user can choose which one to use + configure script rewritten so that it's compatible with standard unix shells instead of bash + much improved multi-user install support : if multi-user is choosen in configure script, mupen64 should be compiled ("make") and installed ("make install"). Then, when a user launch mupen64, it will create automatically a .mupen64 folder in his home and put all required files there. + language saved and restored correctly when quitting mupen64 + the console version (mupen64_nogui) has command line support and can read settings from the gui version config file thanks to jogibear's patch + autoincrement save slot option when quick saving (thanks to jdratlif's patch) + speed limiter in the core + support for plugin configuration changes when a rom is running - Windows version + autoincrement save slot option when quick saving (thanks to jdratlif's patch) + stabilty improvements on the GUI (when closing a rom for example) + added support for readScreen function to support avi recording feature on plugins that don't use opengl or directx (ie: glide64...) - Sound plugin + thread synchronisation improvements what's new in 0.4: - A totally new core based on a dynamic recompiler with register caching, it doesn't compile the fpu yet but it's already much faster compared to older versions of mupen64 :) - Self mod code detection has been improved and emulation is faster now - A lot of little fixes that should improve compaibitlity quite a bit - A new video recording feature (record in own mupen64 movie format that can be converted later into a standard avi file) - The windows GUI has been redesigned by linker - A lot of other things i forgot... sorry :P what's new in 0.3: - All versions + General speed up, 10-20 in most games Save states long loading time fixed, now it should load in less than a second + sound sync is far more accurate now (thanks to Azimer) it makes some additionnal games booting + 64dd detection to fix F-zero + a little idle loops bug has been fixed - Windows port + Configuration and initialisation of plugins now can be done prior running a rom. It fixes numerous configuration issues with plugins as well + Recent roms menu with option to clear and freeze + Command line arguments support with option to run in GUIless mode, compatible with 1964 options, read more about it in pdf + Choosing and saving of plugins used per game, access it from Rom Properties + Reset rom menu added + Speed Modifier to allow game to run at any speed between 1-200% of original Use + and - to increase, decrease it, while in the game. And . to return to 100%. + Start game in fullscreen option + Pause emulation when idle fixes + Global plugin settings (should be unchecked if you want to use plugins per game option from rom properties) + Switch on/off ToolBar (ALT+T) and Status Bar (ALT+S), useful when plugin sets wrong resolution in windowed mode, and for those who hate toolbars :) + Selection of columns to show in rom browser + English language template updated + Support for debugview by linker Put dll in the main folder, if you want to see log output + Tonnes of little fixes... - RSP hle plugin + mario kart sound fixed what's new in 0.2: - Core + better sound plugin integration + optimizations in interrupt handling + a totally new interpreter core (half of a compiler => far much faster) it caches the opcodes when they're decoded + self modifying code detection code for the new interpreter and the compiler when it'll be implemented + RSP plugin integration + pif2 implemented for banjo tooie - RSP hle plugin + the first version of this plugin based on uhle sound code + 3 main audio ucode implemented (based on uhle) + mp3 ucode implemented (direct asm to c translation) + jpeg ucode (direct asm to c translation) + boot code for btooie and dk + on windows: ability to use the hle part of a sound plugin while using another to output the sound (example: using hle from Azimer's plugin and ouputing with Jabo's plugin) This option doesn't work with azimer's audio plugin 0.3 version Please see more info about RSP and this feature in readme.pdf in chapter "3.3.2 Configuration" - Sound Plugin for linux + a new lle sound plugin that's using the OSS api - Windows port + Major cleanup of gui code and bug fixes + Gui improvements in rombrowser + Gui changes in configuration sheets and about dialog + Updates in language support and template Dialog with proper credits to translators ,send us your translations now :) + Support for screenshots from menu (depends on video plugin) (F3 key) + Added some shortcuts for gui functions to accelerators + Option to choose directories of plugins,screenshots and save states in sheets + Auto limit VI/s according to game region (60 or 50) + Ini updated with latest N64 releases + ... what's new in 0.1: - Core + sram bug zelda oot fixed + flashram is working + a new interupt system that'll enabled more accurate timing in the future but can cause some compatibility issues right now + bug in DMULT/DMULTU opcode fixed + some optimizations in jump instructions + sound plugins support implemented but not well supported use sound at your own risk :D + a clean tlb implementation + tlb exception handled correctly + compressed save states with slots + the whole memory map has been almost completes + newly emulated games include goldeneye, conker's bad fur day and perfect dark :) - Windows port + Zipped Cache to Rom Browser + Multy slot save states + Md5 based Ini + Rom properties dialog + Sound support + Config plugins dialog Allows you to chose and configure plugins + Multy directories in rom browser with recursion as an option + Audit roms dialog + Many bugs fixed and minor features added + ... - Linux port + A new gui made by Blight very similar to the windows one Everything in the gui is new so one line many new things ;) what's new in 0.0.90: - this is a huge update many games are playable now :) but only pure interpreter work on this release it will be fixed in the future but currently i am only working on compatibility - i have totally rewritten the pure interpreter core - nearly all missing opcodes have been added - interrupt code has been totally rewritten and should never crash now - tlb code rewritten, it's faster even if it's not perfect yet - some fpu opcodes have been debugged - fpu precision emulation improvements (only for x86 processors) - many bugs to allow port to big endian processors - fixed endianness when cpu write directly to pif ram - rewritten dma code for pure interpreter (with this core it always work now ) - update dp status register when a display list has been processed it fixed a lot of roms - implemented 8Mb RDRAM - implemented memory pack, eeprom, sram (thanks to Jabo and Zilmar for the pj64 source code on this part) - flashram is partially implemented (it's enough to get zelda2 starting) - a new debugger for linux was made by DavFR (it's for linux and it uses gtk library) - zip file support - a new gui for windows port has been made by ShadowPri, it features a rom browser with *classic* UHLE look,multy directories support , a toolbar (thx Schibo for help on it :), multy languages support, saving of configuration, .... - and much more ;) what's new in 0.0.4: - a new pure interpreter core (better compatibility but really slow, will help to debug in the future) - input plugins (a basic keyboard plugin is included and the obsidian joystick plugin ) - coprocessor unusable exception implemented - gui for windows - again many little bugs i can't remember fixed - automatic comparison between two cores via a pipe (for debugging) - .... what's new in 0.0.3: - unaligned dma exception fix - a little gui in gtk - new opcodes implemented - memory map fixes - better initial registers (this was find in the pj64 source code thanks Zilmar and Jabo) - implemented Zilmar spec Gfx plugins - included : a linux port of the tr64 plugin v0.5c what's new in 0.0.2: - MARIO64 works!!! - sound temporarly disabled (Just to not hurt your ears because hle audio doesn't work :) - various speed improvements - various stupid bugs removed what's new in 0.0.1: - everything it's the first public release :) mupen64plus-video-gliden64/src/mupenplus/Config_mupenplus.cpp000664 001750 001750 00000037373 12655644434 025514 0ustar00sergiosergio000000 000000 #include "GLideN64_mupenplus.h" #include #include #include #include #include "../Config.h" #include "../GLideN64.h" #include "../OpenGL.h" #include "../GBI.h" #include "../RSP.h" #include "../Log.h" Config config; static const u32 uMegabyte = 1024U*1024U; static m64p_handle g_configVideoGeneral = NULL; static m64p_handle g_configVideoGliden64 = NULL; static bool Config_SetDefault() { if (ConfigOpenSection("Video-General", &g_configVideoGeneral) != M64ERR_SUCCESS) { LOG(LOG_ERROR, "Unable to open Video-General configuration section"); return false; } if (ConfigOpenSection("Video-GLideN64", &g_configVideoGliden64) != M64ERR_SUCCESS) { LOG(LOG_ERROR, "Unable to open GLideN64 configuration section"); return false; } config.resetToDefaults(); // Set default values for "Video-General" section, if they are not set yet. Taken from RiceVideo m64p_error res = ConfigSetDefaultBool(g_configVideoGeneral, "Fullscreen", config.video.fullscreen, "Use fullscreen mode if True, or windowed mode if False "); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultInt(g_configVideoGeneral, "ScreenWidth", config.video.windowedWidth, "Width of output window or fullscreen width"); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultInt(g_configVideoGeneral, "ScreenHeight", config.video.windowedHeight, "Height of output window or fullscreen height"); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultBool(g_configVideoGeneral, "VerticalSync", config.video.verticalSync, "If true, activate the SDL_GL_SWAP_CONTROL attribute"); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultInt(g_configVideoGliden64, "configVersion", CONFIG_VERSION_CURRENT, "Settings version. Don't touch it."); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultInt(g_configVideoGliden64, "MultiSampling", config.video.multisampling, "Enable/Disable MultiSampling (0=off, 2,4,8,16=quality)"); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultInt(g_configVideoGliden64, "AspectRatio", config.frameBufferEmulation.aspect, "Screen aspect ratio (0=stretch, 1=force 4:3, 2=force 16:9, 3=adjust)"); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultInt(g_configVideoGliden64, "BufferSwapMode", config.frameBufferEmulation.bufferSwapMode, "Swap frame buffers (0=On VI update call, 1=On VI origin change, 2=On buffer update)"); assert(res == M64ERR_SUCCESS); //#Texture Settings res = ConfigSetDefaultBool(g_configVideoGliden64, "bilinearMode", config.texture.bilinearMode, "Bilinear filtering mode (0=N64 3point, 1=standard)"); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultBool(g_configVideoGliden64, "MaxAnisotropy", config.texture.maxAnisotropy, "Max level of Anisotropic Filtering, 0 for off"); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultInt(g_configVideoGliden64, "CacheSize", config.texture.maxBytes / uMegabyte, "Size of texture cache in megabytes. Good value is VRAM*3/4"); assert(res == M64ERR_SUCCESS); //#Emulation Settings res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableFog", config.generalEmulation.enableFog, "Enable fog emulation."); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableNoise", config.generalEmulation.enableNoise, "Enable color noise emulation."); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableLOD", config.generalEmulation.enableLOD, "Enable LOD emulation."); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableHWLighting", config.generalEmulation.enableHWLighting, "Enable hardware per-pixel lighting."); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableShadersStorage", config.generalEmulation.enableShadersStorage, "Use persistent storage for compiled shaders."); assert(res == M64ERR_SUCCESS); #ifdef ANDROID res = ConfigSetDefaultBool(g_configVideoGliden64, "ForcePolygonOffset", config.generalEmulation.forcePolygonOffset, "If true, use polygon offset values specified below"); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultFloat(g_configVideoGliden64, "PolygonOffsetFactor", config.generalEmulation.polygonOffsetFactor, "Specifies a scale factor that is used to create a variable depth offset for each polygon"); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultFloat(g_configVideoGliden64, "PolygonOffsetUnits", config.generalEmulation.polygonOffsetUnits, "Is multiplied by an implementation-specific value to create a constant depth offset"); assert(res == M64ERR_SUCCESS); #endif //#Frame Buffer Settings:" res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableFBEmulation", config.frameBufferEmulation.enable, "Enable frame and|or depth buffer emulation."); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableCopyAuxiliaryToRDRAM", config.frameBufferEmulation.copyAuxToRDRAM, "Copy auxiliary buffers to RDRAM"); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultInt(g_configVideoGliden64, "EnableCopyColorToRDRAM", config.frameBufferEmulation.copyToRDRAM, "Enable color buffer copy to RDRAM (0=do not copy, 1=copy in sync mode, 2=copy in async mode)"); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableCopyDepthToRDRAM", config.frameBufferEmulation.copyDepthToRDRAM, "Enable depth buffer copy to RDRAM."); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableCopyColorFromRDRAM", config.frameBufferEmulation.copyFromRDRAM, "Enable color buffer copy from RDRAM."); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableN64DepthCompare", config.frameBufferEmulation.N64DepthCompare, "Enable N64 depth compare instead of OpenGL standard one. Experimental."); assert(res == M64ERR_SUCCESS); //#Texture filter settings res = ConfigSetDefaultInt(g_configVideoGliden64, "txFilterMode", config.textureFilter.txFilterMode, "Texture filter (0=none, 1=Smooth filtering 1, 2=Smooth filtering 2, 3=Smooth filtering 3, 4=Smooth filtering 4, 5=Sharp filtering 1, 6=Sharp filtering 2)"); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultInt(g_configVideoGliden64, "txEnhancementMode", config.textureFilter.txEnhancementMode, "Texture Enhancement (0=none, 1=store as is, 2=X2, 3=X2SAI, 4=HQ2X, 5=HQ2XS, 6=LQ2X, 7=LQ2XS, 8=HQ4X, 9=2xBRZ, 10=3xBRZ, 11=4xBRZ, 12=5xBRZ), 13=6xBRZ"); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultBool(g_configVideoGliden64, "txFilterIgnoreBG", config.textureFilter.txFilterIgnoreBG, "Don't filter background textures."); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultInt(g_configVideoGliden64, "txCacheSize", config.textureFilter.txCacheSize/uMegabyte, "Size of filtered textures cache in megabytes."); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultBool(g_configVideoGliden64, "txHiresEnable", config.textureFilter.txHiresEnable, "Use high-resolution texture packs if available."); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultBool(g_configVideoGliden64, "txHiresFullAlphaChannel", config.textureFilter.txHiresFullAlphaChannel, "Allow to use alpha channel of high-res texture fully."); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultBool(g_configVideoGliden64, "txHresAltCRC", config.textureFilter.txHresAltCRC, "Use alternative method of paletted textures CRC calculation."); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultBool(g_configVideoGliden64, "txDump", config.textureFilter.txDump, "Enable dump of loaded N64 textures."); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultBool(g_configVideoGliden64, "txCacheCompression", config.textureFilter.txCacheCompression, "Zip textures cache."); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultBool(g_configVideoGliden64, "txForce16bpp", config.textureFilter.txForce16bpp, "Force use 16bit texture formats for HD textures."); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultBool(g_configVideoGliden64, "txSaveCache", config.textureFilter.txSaveCache, "Save texture cache to hard disk."); assert(res == M64ERR_SUCCESS); // Convert to multibyte char txPath[PLUGIN_PATH_SIZE * 2]; wcstombs(txPath, config.textureFilter.txPath, PLUGIN_PATH_SIZE * 2); res = ConfigSetDefaultString(g_configVideoGliden64, "txPath", txPath, "Path to folder with hi-res texture packs."); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultString(g_configVideoGliden64, "fontName", config.font.name.c_str(), "File name of True Type Font for text messages."); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultInt(g_configVideoGliden64, "fontSize", config.font.size, "Font size."); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultString(g_configVideoGliden64, "fontColor", "B5E61D", "Font color in RGB format."); assert(res == M64ERR_SUCCESS); //#Bloom filter settings res = ConfigSetDefaultInt(g_configVideoGliden64, "EnableBloom", config.bloomFilter.enable, "Enable bloom filter"); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultInt(g_configVideoGliden64, "bloomThresholdLevel", config.bloomFilter.thresholdLevel, "Brightness threshold level for bloom. Values [2, 6]"); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultInt(g_configVideoGliden64, "bloomBlendMode", config.bloomFilter.blendMode, "Bloom blend mode (0=Strong, 1=Mild, 2=Light)"); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultInt(g_configVideoGliden64, "blurAmount", config.bloomFilter.blurAmount, "Blur radius. Values [2, 10]"); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultInt(g_configVideoGliden64, "blurStrength", config.bloomFilter.blurStrength, "Blur strength. Values [10, 100]"); assert(res == M64ERR_SUCCESS); //#Gamma correction settings res = ConfigSetDefaultBool(g_configVideoGliden64, "ForceGammaCorrection", config.gammaCorrection.force, "Force gamma correction."); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultFloat(g_configVideoGliden64, "GammaCorrectionLevel", config.gammaCorrection.level, "Gamma correction level."); assert(res == M64ERR_SUCCESS); return ConfigSaveSection("Video-GLideN64") == M64ERR_SUCCESS; } void Config_LoadConfig() { const u32 hacks = config.generalEmulation.hacks; if (!Config_SetDefault()) { config.generalEmulation.hacks = hacks; return; } config.version = ConfigGetParamInt(g_configVideoGliden64, "configVersion"); if (config.version != CONFIG_VERSION_CURRENT) { m64p_error res = ConfigDeleteSection("Video-GLideN64"); assert(res == M64ERR_SUCCESS); ConfigSaveFile(); if (!Config_SetDefault()) { config.generalEmulation.hacks = hacks; return; } } config.video.fullscreen = ConfigGetParamBool(g_configVideoGeneral, "Fullscreen"); config.video.windowedWidth = ConfigGetParamInt(g_configVideoGeneral, "ScreenWidth"); config.video.windowedHeight = ConfigGetParamInt(g_configVideoGeneral, "ScreenHeight"); config.video.verticalSync = ConfigGetParamBool(g_configVideoGeneral, "VerticalSync"); #ifdef GL_MULTISAMPLING_SUPPORT config.video.multisampling = ConfigGetParamInt(g_configVideoGliden64, "MultiSampling"); #else config.video.multisampling = 0; #endif config.frameBufferEmulation.aspect = ConfigGetParamInt(g_configVideoGliden64, "AspectRatio"); config.frameBufferEmulation.bufferSwapMode = ConfigGetParamInt(g_configVideoGliden64, "BufferSwapMode"); //#Texture Settings config.texture.bilinearMode = ConfigGetParamBool(g_configVideoGliden64, "bilinearMode"); config.texture.maxAnisotropy = ConfigGetParamInt(g_configVideoGliden64, "MaxAnisotropy"); config.texture.maxBytes = ConfigGetParamInt(g_configVideoGliden64, "CacheSize") * uMegabyte; //#Emulation Settings config.generalEmulation.enableFog = ConfigGetParamBool(g_configVideoGliden64, "EnableFog"); config.generalEmulation.enableNoise = ConfigGetParamBool(g_configVideoGliden64, "EnableNoise"); config.generalEmulation.enableLOD = ConfigGetParamBool(g_configVideoGliden64, "EnableLOD"); config.generalEmulation.enableHWLighting = ConfigGetParamBool(g_configVideoGliden64, "EnableHWLighting"); config.generalEmulation.enableShadersStorage = ConfigGetParamBool(g_configVideoGliden64, "EnableShadersStorage"); #ifdef ANDROID config.generalEmulation.forcePolygonOffset = ConfigGetParamBool(g_configVideoGliden64, "ForcePolygonOffset"); config.generalEmulation.polygonOffsetFactor = ConfigGetParamFloat(g_configVideoGliden64, "PolygonOffsetFactor"); config.generalEmulation.polygonOffsetUnits = ConfigGetParamFloat(g_configVideoGliden64, "PolygonOffsetUnits"); #endif //#Frame Buffer Settings:" config.frameBufferEmulation.enable = ConfigGetParamBool(g_configVideoGliden64, "EnableFBEmulation"); config.frameBufferEmulation.copyAuxToRDRAM = ConfigGetParamBool(g_configVideoGliden64, "EnableCopyAuxiliaryToRDRAM"); config.frameBufferEmulation.copyToRDRAM = ConfigGetParamInt(g_configVideoGliden64, "EnableCopyColorToRDRAM"); config.frameBufferEmulation.copyDepthToRDRAM = ConfigGetParamBool(g_configVideoGliden64, "EnableCopyDepthToRDRAM"); config.frameBufferEmulation.copyFromRDRAM = ConfigGetParamBool(g_configVideoGliden64, "EnableCopyColorFromRDRAM"); config.frameBufferEmulation.N64DepthCompare = ConfigGetParamBool(g_configVideoGliden64, "EnableN64DepthCompare"); //#Texture filter settings config.textureFilter.txFilterMode = ConfigGetParamInt(g_configVideoGliden64, "txFilterMode"); config.textureFilter.txEnhancementMode = ConfigGetParamInt(g_configVideoGliden64, "txEnhancementMode"); config.textureFilter.txFilterIgnoreBG = ConfigGetParamBool(g_configVideoGliden64, "txFilterIgnoreBG"); config.textureFilter.txCacheSize = ConfigGetParamInt(g_configVideoGliden64, "txCacheSize") * uMegabyte; config.textureFilter.txHiresEnable = ConfigGetParamBool(g_configVideoGliden64, "txHiresEnable"); config.textureFilter.txHiresFullAlphaChannel = ConfigGetParamBool(g_configVideoGliden64, "txHiresFullAlphaChannel"); config.textureFilter.txHresAltCRC = ConfigGetParamBool(g_configVideoGliden64, "txHresAltCRC"); config.textureFilter.txDump = ConfigGetParamBool(g_configVideoGliden64, "txDump"); config.textureFilter.txForce16bpp = ConfigGetParamBool(g_configVideoGliden64, "txForce16bpp"); config.textureFilter.txCacheCompression = ConfigGetParamBool(g_configVideoGliden64, "txCacheCompression"); config.textureFilter.txSaveCache = ConfigGetParamBool(g_configVideoGliden64, "txSaveCache"); ::mbstowcs(config.textureFilter.txPath, ConfigGetParamString(g_configVideoGliden64, "txPath"), PLUGIN_PATH_SIZE); //#Font settings config.font.name = ConfigGetParamString(g_configVideoGliden64, "fontName"); if (config.font.name.empty()) config.font.name = "arial.ttf"; char buf[16]; sprintf(buf, "0x%s", ConfigGetParamString(g_configVideoGliden64, "fontColor")); long int uColor = strtol(buf, NULL, 16); if (uColor != 0) { config.font.color[0] = _SHIFTR(uColor, 16, 8); config.font.color[1] = _SHIFTR(uColor, 8, 8); config.font.color[2] = _SHIFTR(uColor, 0, 8); config.font.color[3] = 0xFF; config.font.colorf[0] = _FIXED2FLOAT(config.font.color[0], 8); config.font.colorf[1] = _FIXED2FLOAT(config.font.color[1], 8); config.font.colorf[2] = _FIXED2FLOAT(config.font.color[2], 8); config.font.colorf[3] = 1.0f; } config.font.size = ConfigGetParamInt(g_configVideoGliden64, "fontSize"); if (config.font.size == 0) config.font.size = 30; //#Bloom filter settings config.bloomFilter.enable = ConfigGetParamInt(g_configVideoGliden64, "EnableBloom"); config.bloomFilter.thresholdLevel = ConfigGetParamInt(g_configVideoGliden64, "bloomThresholdLevel"); config.bloomFilter.blendMode = ConfigGetParamInt(g_configVideoGliden64, "bloomBlendMode"); config.bloomFilter.blurAmount = ConfigGetParamInt(g_configVideoGliden64, "blurAmount"); config.bloomFilter.blurStrength = ConfigGetParamInt(g_configVideoGliden64, "blurStrength"); //#Gamma correction settings config.gammaCorrection.force = ConfigGetParamBool(g_configVideoGliden64, "ForceGammaCorrection"); config.gammaCorrection.level = ConfigGetParamFloat(g_configVideoGliden64, "GammaCorrectionLevel"); config.generalEmulation.hacks = hacks; } mupen64plus-core/src/r4300/macros.h000664 001750 001750 00000005156 12655644434 020052 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - macros.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_R4300_MACROS_H #define M64P_R4300_MACROS_H #define SE8(a) ((int64_t) ((int8_t) (a))) #define SE16(a) ((int64_t) ((int16_t) (a))) #define SE32(a) ((int64_t) ((int32_t) (a))) #define rrt *PC->f.r.rt #define rrd *PC->f.r.rd #define rfs PC->f.r.nrd #define rrs *PC->f.r.rs #define rsa PC->f.r.sa #define irt *PC->f.i.rt #define ioffset PC->f.i.immediate #define iimmediate PC->f.i.immediate #define irs *PC->f.i.rs #define ibase *PC->f.i.rs #define jinst_index PC->f.j.inst_index #define lfbase PC->f.lf.base #define lfft PC->f.lf.ft #define lfoffset PC->f.lf.offset #define cfft PC->f.cf.ft #define cffs PC->f.cf.fs #define cffd PC->f.cf.fd // 32 bits macros #ifdef MSB_FIRST #define rrt32 *((int32_t*)PC->f.r.rt+1) #define rrd32 *((int32_t*)PC->f.r.rd+1) #define rrs32 *((int32_t*)PC->f.r.rs+1) #define irs32 *((int32_t*)PC->f.i.rs+1) #define irt32 *((int32_t*)PC->f.i.rt+1) #else #define rrt32 *((int32_t*)PC->f.r.rt) #define rrd32 *((int32_t*)PC->f.r.rd) #define rrs32 *((int32_t*)PC->f.r.rs) #define irs32 *((int32_t*)PC->f.i.rs) #define irt32 *((int32_t*)PC->f.i.rt) #endif #endif /* M64P_R4300_MACROS_H */ gles2n64/src/L3DEX2.h000664 001750 001750 00000000351 12655644434 015123 0ustar00sergiosergio000000 000000 #ifndef L3DEX2_H #define L3DEX2_H #ifdef __cplusplus extern "C" { #endif #include "Types.h" #define L3DEX2_LINE3D 0x08 void L3DEX2_Line3D( u32 w0, u32 w1 ); void L3DEX2_Init(); #ifdef __cplusplus } #endif #endif libretro-common/glsym/000700 001750 001750 00000000000 12656647145 016151 5ustar00sergiosergio000000 000000 tools/gen_romdb.py000755 001750 001750 00000006362 12655644434 015375 0ustar00sergiosergio000000 000000 #!/usr/bin/env python2 # -*- coding: utf-8 -*- # usage: gen_romdb.py mupen64plus.ini import io import os import re import sys from pprint import pprint # for debugging from ConfigParser import ConfigParser from collections import OrderedDict OUTPUT_FILE='rom_luts.c' if len(sys.argv) < 2: print("usage: %s mupen64plus.ini" % sys.argv[0]) sys.exit(0) gConf = ConfigParser() gGames = dict() def get_save_type(t): return t.upper().replace(' ', '_') sys.stderr.write("Parsing " + sys.argv[1] + "...\n") gConf.readfp(open(sys.argv[1])) gNameRe = re.compile(r'([^(]+)', re.IGNORECASE) gEeprom16k = list() gFlashRAM = list() gEeprom4k = list() gCountPerOp = list() for section in gConf.sections(): conf = dict(gConf.items(section)) conf['crc'] = conf['crc'].replace(' ', '') conf['simplename'] = gNameRe.search(conf['goodname']).group(0).strip() name = conf['simplename'].lower() if not name in gGames: gGames[name] = [] skip = False for game in gGames[name]: if game['crc'] == conf['crc']: skip = True break if not skip: gGames[name].append(conf) # order by rom name gGames = OrderedDict(sorted(gGames.items(), key=lambda t: t[0])) # detect eeprom16k for _, games in gGames.items(): for game in games: if game.get('savetype', '').lower() == 'eeprom 16kb': gEeprom16k.append(game) if game.get('savetype', '').lower() == 'eeprom 4kb': gEeprom4k.append(game) if game.get('savetype', '').lower() == 'flash ram': gFlashRAM.append(game) if 'countperop' in game: gCountPerOp.append(game) print("Wrote " + OUTPUT_FILE) romdb = open(OUTPUT_FILE, 'w') romdb.write("/* This file was generated by gen_romdb.py */\n") romdb.write("/* Games that use 16Kbit EEPROM */\n") romdb.write("static const uint64_t lut_ee16k[] = {\n") i = 0 for game in gEeprom16k: comma = ',' if i == len(gEeprom16k) - 1: comma = ' ' romdb.write(' 0x' + game['crc'] + 'ULL' + comma + ' /* ' + game['goodname'] + " */\n") i = i + 1 romdb.write("};\n") romdb.write("/* Games that use 4Kbit EEPROM */\n") romdb.write("static const uint64_t lut_ee4k[] = {\n") i = 0 for game in gEeprom4k: comma = ',' if i == len(gEeprom4k) - 1: comma = ' ' romdb.write(' 0x' + game['crc'] + 'ULL' + comma + ' /* ' + game['goodname'] + " */\n") i = i + 1 romdb.write("};\n") romdb.write("/* Games that use Flash RAM */\n") romdb.write("static const uint64_t lut_flashram[] = {\n") i = 0 for game in gFlashRAM: comma = ',' if i == len(gFlashRAM) - 1: comma = ' ' romdb.write(' 0x' + game['crc'] + 'ULL' + comma + ' /* ' + game['goodname'] + " */\n") i = i + 1 romdb.write("};\n") i = 0 romdb.write("/* Cycles per emulated instruction (aka CountPerOp) */\n") romdb.write("static const uint64_t lut_cpop[][2] = {\n") for game in gCountPerOp: comma = ',' if i == len(gEeprom16k) - 1: comma = ' ' if i == len(gEeprom4k) - 1: comma = ' ' if i == len(gFlashRAM) - 1: comma = ' ' romdb.write(' { 0x' + game['crc'] + 'ULL, ' + game['countperop'] + ' }' + comma + ' /* ' + game['goodname'] + " */\n") romdb.write("};\n") romdb.close() tools/m64pmigrate.c000664 001750 001750 00000004043 12655644434 015363 0ustar00sergiosergio000000 000000 /* m64migrate * Migrate .srm files from the old layout to the new one. * * The new layout was introduced in 2015/02/11. */ #include #include #include #include #include struct old_layout { unsigned char eeprom[0x200]; unsigned char mempack[4][0x8000]; unsigned char sram[0x8000]; unsigned char flashram[0x20000]; unsigned char eeprom2[0x600]; }; int main(int argc, char *argv[]) { int i; char backup_path[4096]; struct old_layout save; FILE *fp, *fp2; if (argc < 2) { printf("usage: %s [file2.srm] ... [file.srm]", argv[0]); exit(EXIT_FAILURE); } for (i = 1; i < argc; ++i) { snprintf(backup_path, sizeof(backup_path), "%s.bak", argv[i]); printf("Processing '%s'...\n", argv[i]); if (access(argv[i], R_OK|W_OK) != 0) { fprintf(stderr, "Unable to read or write '%s': %s\n", argv[i], strerror(errno)); continue; } if (access(backup_path, F_OK) == 0) { printf("Backup file '%s' found, do you want to overwrite (y/n)? ", backup_path); if (fgetc(stdin) != 'y') { puts(" skipping."); continue; } puts(" overwriting."); } memset(&save, 0, sizeof(save)); if (!(fp = fopen(argv[i], "r+b"))) { fprintf(stderr, "Failed to open '%s', skipping: %s\n", argv[i], strerror(errno)); continue; } fread(&save, 1, sizeof(save), fp); if (!(fp2 = fopen(backup_path, "wb"))) { fprintf(stderr, "Failed to open '%s', skipping: %s\n", backup_path, strerror(errno)); fclose(fp); continue; } if (fwrite(&save, 1, sizeof(save), fp2) < sizeof(save)) { fprintf(stderr, "Failed to backup '%s', skipping: %s\n", argv[i], strerror(errno)); unlink(backup_path); fclose(fp); fclose(fp2); continue; } fclose(fp2); rewind(fp); fwrite(save.eeprom, 1, sizeof(save.eeprom), fp); fwrite(save.eeprom2, 1, sizeof(save.eeprom2), fp); fwrite(save.mempack, 1, sizeof(save.mempack), fp); fwrite(save.sram, 1, sizeof(save.sram), fp); fwrite(save.flashram, 1, sizeof(save.flashram), fp); fclose(fp); continue; } return 0; } mupen64plus-rsp-hle/src/alist.h000664 001750 001750 00000013544 12655644434 017554 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-rsp-hle - alist.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef ALIST_INTERNAL_H #define ALIST_INTERNAL_H #include #include #include struct hle_t; typedef void (*acmd_callback_t)(struct hle_t* hle, uint32_t w1, uint32_t w2); void alist_process(struct hle_t* hle, const acmd_callback_t abi[], unsigned int abi_size); uint32_t alist_get_address(struct hle_t* hle, uint32_t so, const uint32_t *segments, size_t n); void alist_set_address(struct hle_t* hle, uint32_t so, uint32_t *segments, size_t n); void alist_clear(struct hle_t* hle, uint16_t dmem, uint16_t count); void alist_load(struct hle_t* hle, uint16_t dmem, uint32_t address, uint16_t count); void alist_save(struct hle_t* hle, uint16_t dmem, uint32_t address, uint16_t count); void alist_move(struct hle_t* hle, uint16_t dmemo, uint16_t dmemi, uint16_t count); void alist_copy_every_other_sample(struct hle_t* hle, uint16_t dmemo, uint16_t dmemi, uint16_t count); void alist_repeat64(struct hle_t* hle, uint16_t dmemo, uint16_t dmemi, uint8_t count); void alist_copy_blocks(struct hle_t* hle, uint16_t dmemo, uint16_t dmemi, uint16_t block_size, uint8_t count); void alist_interleave(struct hle_t* hle, uint16_t dmemo, uint16_t left, uint16_t right, uint16_t count); void alist_envmix_exp( struct hle_t* hle, bool init, bool aux, uint16_t dmem_dl, uint16_t dmem_dr, uint16_t dmem_wl, uint16_t dmem_wr, uint16_t dmemi, uint16_t count, int16_t dry, int16_t wet, const int16_t *vol, const int16_t *target, const int32_t *rate, uint32_t address); void alist_envmix_ge( struct hle_t* hle, bool init, bool aux, uint16_t dmem_dl, uint16_t dmem_dr, uint16_t dmem_wl, uint16_t dmem_wr, uint16_t dmemi, uint16_t count, int16_t dry, int16_t wet, const int16_t *vol, const int16_t *target, const int32_t *rate, uint32_t address); void alist_envmix_lin( struct hle_t* hle, bool init, uint16_t dmem_dl, uint16_t dmem_dr, uint16_t dmem_wl, uint16_t dmem_wr, uint16_t dmemi, uint16_t count, int16_t dry, int16_t wet, const int16_t *vol, const int16_t *target, const int32_t *rate, uint32_t address); void alist_envmix_nead( struct hle_t* hle, bool swap_wet_LR, uint16_t dmem_dl, uint16_t dmem_dr, uint16_t dmem_wl, uint16_t dmem_wr, uint16_t dmemi, unsigned count, uint16_t *env_values, uint16_t *env_steps, const int16_t *xors); void alist_mix(struct hle_t* hle, uint16_t dmemo, uint16_t dmemi, uint16_t count, int16_t gain); void alist_multQ44(struct hle_t* hle, uint16_t dmem, uint16_t count, int8_t gain); void alist_add(struct hle_t* hle, uint16_t dmemo, uint16_t dmemi, uint16_t count); void alist_adpcm( struct hle_t* hle, bool init, bool loop, bool two_bit_per_sample, uint16_t dmemo, uint16_t dmemi, uint16_t count, const int16_t* codebook, uint32_t loop_address, uint32_t last_frame_address); void alist_resample( struct hle_t* hle, bool init, bool flag2, uint16_t dmemo, uint16_t dmemi, uint16_t count, uint32_t pitch, uint32_t address); void alist_resample_zoh( struct hle_t* hle, uint16_t dmemo, uint16_t dmemi, uint16_t count, uint32_t pitch, uint32_t pitch_accu); void alist_filter( struct hle_t* hle, uint16_t dmem, uint16_t count, uint32_t address, const uint32_t* lut_address); void alist_polef( struct hle_t* hle, bool init, uint16_t dmemo, uint16_t dmemi, uint16_t count, uint16_t gain, int16_t* table, uint32_t address); void alist_iirf( struct hle_t* hle, bool init, uint16_t dmemo, uint16_t dmemi, uint16_t count, int16_t* table, uint32_t address); /* * Audio flags */ #define A_INIT 0x01 #define A_CONTINUE 0x00 #define A_LOOP 0x02 #define A_OUT 0x02 #define A_LEFT 0x02 #define A_RIGHT 0x00 #define A_VOL 0x04 #define A_RATE 0x00 #define A_AUX 0x08 #define A_NOAUX 0x00 #define A_MAIN 0x00 #define A_MIX 0x10 #endif gles2n64/src/L3DEX2.c000664 001750 001750 00000005634 12655644434 015127 0ustar00sergiosergio000000 000000 #include "gles2N64.h" #include "Debug.h" #include "F3D.h" #include "F3DEX.h" #include "F3DEX2.h" #include "L3DEX2.h" #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gSP.h" #include "gDP.h" #include "GBI.h" void L3DEX2_Line3D( u32 w0, u32 w1 ) { u32 wd = _SHIFTR( w0, 0, 8 ); if (wd == 0) gSPLine3D( _SHIFTR( w0, 17, 7 ), _SHIFTR( w0, 9, 7 ), 0 ); else gSPLineW3D( _SHIFTR( w0, 17, 7 ), _SHIFTR( w0, 9, 7 ), wd, 0 ); } void L3DEX2_Init(void) { gSPSetupFunctions(); // Set GeometryMode flags GBI_InitFlags( F3DEX2 ); GBI.PCStackSize = 18; // GBI Command Command Value Command Function // GBI_SetGBI( G_BG_COPY, 0x0A, S2DEX_BG_Copy ); GBI_SetGBI( G_RDPHALF_2, F3DEX2_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_SETOTHERMODE_H, F3DEX2_SETOTHERMODE_H, F3DEX2_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3DEX2_SETOTHERMODE_L, F3DEX2_SetOtherMode_L ); GBI_SetGBI( G_RDPHALF_1, F3DEX2_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_SPNOOP, F3DEX2_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_ENDDL, F3DEX2_ENDDL, F3D_EndDL ); GBI_SetGBI( G_DL, F3DEX2_DL, F3D_DList ); GBI_SetGBI( G_LOAD_UCODE, F3DEX2_LOAD_UCODE, F3DEX_Load_uCode ); GBI_SetGBI( G_MOVEMEM, F3DEX2_MOVEMEM, F3DEX2_MoveMem ); GBI_SetGBI( G_MOVEWORD, F3DEX2_MOVEWORD, F3DEX2_MoveWord ); GBI_SetGBI( G_MTX, F3DEX2_MTX, F3DEX2_Mtx ); GBI_SetGBI( G_GEOMETRYMODE, F3DEX2_GEOMETRYMODE, F3DEX2_GeometryMode ); GBI_SetGBI( G_POPMTX, F3DEX2_POPMTX, F3DEX2_PopMtx ); GBI_SetGBI( G_TEXTURE, F3DEX2_TEXTURE, F3DEX2_Texture ); GBI_SetGBI( G_DMA_IO, F3DEX2_DMA_IO, F3DEX2_DMAIO ); GBI_SetGBI( G_SPECIAL_1, F3DEX2_SPECIAL_1, F3DEX2_Special_1 ); GBI_SetGBI( G_SPECIAL_2, F3DEX2_SPECIAL_2, F3DEX2_Special_2 ); GBI_SetGBI( G_SPECIAL_3, F3DEX2_SPECIAL_3, F3DEX2_Special_3 ); GBI_SetGBI( G_VTX, F3DEX2_VTX, F3DEX2_Vtx ); GBI_SetGBI( G_MODIFYVTX, F3DEX2_MODIFYVTX, F3DEX_ModifyVtx ); GBI_SetGBI( G_CULLDL, F3DEX2_CULLDL, F3DEX_CullDL ); GBI_SetGBI( G_BRANCH_Z, F3DEX2_BRANCH_Z, F3DEX_Branch_Z ); // GBI_SetGBI( G_TRI1, F3DEX2_TRI1, F3DEX2_Tri1 ); // GBI_SetGBI( G_TRI2, F3DEX2_TRI2, F3DEX_Tri2 ); // GBI_SetGBI( G_QUAD, F3DEX2_QUAD, F3DEX2_Quad ); GBI_SetGBI( G_LINE3D, L3DEX2_LINE3D, L3DEX2_Line3D ); } glide2gl/src/Glide64/ucode09rdp.h000664 001750 001750 00000005273 12655644434 017533 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** // // December 2008 Created by Gonetz (Gonetz@ngs.ru) // //**************************************************************** #include "GBI.h" void uc9_rpdcmd(uint32_t w0, uint32_t w1) { uint32_t a = RSP_SegmentToPhysical(w1) >> 2; FRDP ("uc9:rdpcmd addr: %08lx\n", a); if (a) { uint32_t cmd; rdp.LLE = 1; cmd = 0; do { rdp.cmd0 = ((uint32_t*)gfx_info.RDRAM)[a++]; cmd = rdp.cmd0>>24; if (cmd == F3DEX2_ENDDL) break; rdp.cmd1 = ((uint32_t*)gfx_info.RDRAM)[a++]; if (cmd == G_TEXRECT || cmd == G_TEXRECTFLIP) { a++; rdp.cmd2 = ((uint32_t*)gfx_info.RDRAM)[a++]; a++; rdp.cmd3 = ((uint32_t*)gfx_info.RDRAM)[a++]; } gfx_instruction[ucode_zSort][cmd](w0, w1); }while(1); rdp.LLE = 0; } } gles2n64/src/F3DEX2CBFD.h000664 001750 001750 00000000261 12655644434 015534 0ustar00sergiosergio000000 000000 #ifndef F3DEX2CBFD_H #define F3DEX2CBFD_H #define F3DEX2CBFD_TRI4 16 #ifdef __cplusplus extern "C" { #endif void F3DEX2CBFD_Init(void); #ifdef __cplusplus } #endif #endif mupen64plus-core/src/ai/000700 001750 001750 00000000000 12656647145 016216 5ustar00sergiosergio000000 000000 mupen64plus-core/tools/r4300prof.c000664 001750 001750 00000042316 12655644434 020020 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - r4300prof.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2008 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include /* Global data */ unsigned int instr_samples[132]; char instr_name[][10] = { "reserved", "NI", "J", "JAL", "BEQ", "BNE", "BLEZ", "BGTZ", "ADDI", "ADDIU", "SLTI", "SLTIU", "ANDI", "ORI", "XORI", "LUI", "BEQL", "BNEL", "BLEZL", "BGTZL", "DADDI", "DADDIU", "LDL", "LDR", "LB", "LH", "LW", "LWL", "LBU", "LHU", "LWU", "LWR", "SB", "SH", "SW", "SWL", "SWR", "SDL", "SDR", "LWC1", "LDC1", "LD", "LL", "SWC1", "SDC1", "SD", "SC", "BLTZ", "BGEZ", "BLTZL", "BGEZL", "BLTZAL", "BGEZAL", "BLTZALL", "BGEZALL", "SLL", "SRL", "SRA", "SLLV", "SRLV", "SRAV", "JR", "JALR", "SYSCALL", "MFHI", "MTHI", "MFLO", "MTLO", "DSLLV", "DSRLV", "DSRAV", "MULT", "MULTU", "DIV", "DIVU", "DMULT", "DMULTU", "DDIV", "DDIVU", "ADD", "ADDU", "SUB", "SUBU", "AND", "OR", "XOR", "NOR", "SLT", "SLTU", "DADD", "DADDU", "DSUB", "DSUBU", "DSLL", "DSRL", "DSRA", "TEQ", "DSLL32", "DSRL32", "DSRA32", "BC1F", "BC1T", "BC1FL", "BC1TL", "TLBWI", "TLBP", "TLBR", "TLBWR", "ERET", "MFC0", "MTC0", "MFC1", "DMFC1", "CFC1", "MTC1", "DMTC1", "CTC1", "f.CVT", "f.CMP", "f.ADD", "f.SUB", "f.MUL", "f.DIV", "f.SQRT", "f.ABS", "f.MOV", "f.NEG", "f.ROUND", "f.TRUNC", "f.CEIL", "f.FLOOR" }; unsigned int instr_type[131] = { 9, 10, 6, 6, 7, 7, 7, 7, 3, 3, 4, 4, 3, 4, 4, 0, 7, 7, 7, 7, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 7, 7, 7, 7, 7, 7, 7, 7, 3, 3, 3, 3, 3, 3, 6, 6, 10, 2, 2, 2, 2, 4, 4, 4, 3, 3, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 7, 7, 7, 7, 10, 10, 10, 10, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5 }; char instr_typename[][20] = { "Load", "Store", "Data move/convert", "32-bit math", "64-bit math", "Float Math", "Jump", "Branch", "Exceptions", "Reserved", "Other" }; /* Global functions */ int GetInstrType(int opcode); int AddrCompare(const void *, const void *); int ParseProfLine(const char *pchIn, long *plAddress, int *piSamples, float *pfPercentage); /* defined types */ typedef struct __attribute__ ((__packed__)) { int mipsop; long x86addr; } r4300op; typedef struct { long x86addr; int samples; } profilehit; /* static functions */ static int isSpace(char ch) { return (ch == ' ' || ch == '\t' ? 1 : 0); } static int isNum(char ch) { return (ch >= '0' && ch <= '9' ? 1 : 0); } static int isFloat(char ch) { return ((ch >= '0' && ch <= '9') || ch == '.' || ch == '+' || ch == '-' || ch == 'e' ? 1 : 0); } static int isHex(char ch) { return ((ch >= '0' && ch <= '9') || ((ch & 0xdf) >= 'A' && (ch & 0xdf) <= 'F') ? 1 : 0); } /* main */ int main(int argc, void *argv[]) { long lOpStart, lOpEnd; int flength, oplistlength, totaltime, proflistlength; int samp_unknown, samp_blockend, samp_notcompiled, samp_wrappers, samp_flush; int i, j; FILE *pfIn; r4300op *pOpAddrTable; profilehit *pProfTable; char *pch, *pchSampleData; /* check arguments */ if (argc < 3) { printf("Usage: r4300prof r4300addr.dat x86profile.txt\n\n"); printf("r4300addr.dat - binary table of r4300 opcodes and corresponding x86 starting addresses\n"); printf("x86profile.txt - text file containing a list of profile sample counts by x86 address on the heap\n\n"); return 1; } /* open r4300 opcode/x86 address table generated from emulator run */ printf("Loading %s...\n", argv[1]); pfIn = fopen(argv[1], "rb"); if (pfIn == NULL) { printf("Couldn't open input file: %s\n", argv[1]); return 2; } /* get file length and calculate number of r4300op table entries */ fseek(pfIn, 0L, SEEK_END); flength = (int) ftell(pfIn); fseek(pfIn, 0L, SEEK_SET); oplistlength = flength / sizeof(r4300op); /* read the file */ pOpAddrTable = (r4300op *) malloc(flength); if (pOpAddrTable == NULL) { printf("Failed to allocate %i bytes for OpAddrTable!\n", flength); fclose(pfIn); return 3; } fread(pOpAddrTable, 1, flength, pfIn); fclose(pfIn); printf("%i r4300 instruction locations read.\n", oplistlength); /* sort the opcode/address table according to x86addr */ qsort(pOpAddrTable, oplistlength, sizeof(r4300op), AddrCompare); /* remove any 0-length r4300 instructions */ i = 0; j = 0; while (i < oplistlength) { pOpAddrTable[j].mipsop = pOpAddrTable[i].mipsop; pOpAddrTable[j].x86addr = pOpAddrTable[i].x86addr; i++; if (pOpAddrTable[j].x86addr != pOpAddrTable[i].x86addr) j++; } oplistlength = j; printf("%i non-empty MIPS instructions.\n", oplistlength); /* convert each r4300 opcode to an instruction type index */ for (i = 0; i < oplistlength; i++) if (pOpAddrTable[i].mipsop > 0 || pOpAddrTable[i].mipsop < -16) pOpAddrTable[i].mipsop = GetInstrType(pOpAddrTable[i].mipsop); /* open the profiling sample data file */ printf("Loading %s...\n", argv[2]); pfIn = fopen(argv[2], "rb"); if (pfIn == NULL) { printf("Couldn't open input file: %s\n", argv[2]); free(pOpAddrTable); return 4; } /* load it */ fseek(pfIn, 0L, SEEK_END); flength = (int) ftell(pfIn); fseek(pfIn, 0L, SEEK_SET); pchSampleData = (char *) malloc(flength + 16); if (pchSampleData == NULL) { printf("Failed to allocate %i bytes for pchSampleData!\n", flength + 16); fclose(pfIn); free(pOpAddrTable); return 5; } fread(pchSampleData, 1, flength, pfIn); pchSampleData[flength] = 0; fclose(pfIn); /* count the number of newlines in the ascii-formatted sample data file */ proflistlength = 1; pch = pchSampleData; while (pch = strchr(pch, '\n')) { proflistlength++; pch++; } printf("%i lines in sample data file.\n", proflistlength); /* extract text data into binary table */ pProfTable = (profilehit *) malloc(proflistlength * sizeof(profilehit)); if (pProfTable == NULL) { printf("Failed to allocate %i bytes for pProfTable!\n", proflistlength * sizeof(profilehit)); free(pOpAddrTable); free(pchSampleData); return 6; } pch = pchSampleData; j = 0; long long llOffset = 0; while (j < proflistlength) { long lAddress; int iSamples; float fPercentage; char *pchNext = strchr(pch, '\n'); if (pchNext != NULL) *pchNext++ = 0; // null-terminate this line if (strstr(pch, "range:0x") != NULL) // search for offset change { pch = strstr(pch, "range:0x") + 8; // extract hex value and update our offset char *pch2 = pch; while (isHex(*pch2)) pch2++; *pch2 = 0; llOffset = strtoll(pch, NULL, 16); } else // parse line for sample point { int rval = ParseProfLine(pch, &lAddress, &iSamples, &fPercentage); if (rval != 0) { pProfTable[j].x86addr = (unsigned long) (lAddress + llOffset); pProfTable[j].samples = iSamples; j++; } } pch = pchNext; if (pch == NULL) break; } free(pchSampleData); proflistlength = j; printf("Found %i profile hits.\n", proflistlength); /* clear r4300 instruction sample data table */ for (i = 0; i < 132; i++) instr_samples[i] = 0; /* calculate r4300 instruction profiling data by merging the tables */ samp_unknown = 0; samp_blockend = 0; samp_notcompiled = 0; samp_wrappers = 0; samp_flush = 0; i = 0; // i == OpAddrTable index lOpStart = pOpAddrTable[0].x86addr; lOpEnd = pOpAddrTable[1].x86addr; for (j = 0; j < proflistlength; j++) // j == pProfTable index { long lOpx86addr = pProfTable[j].x86addr; if (lOpx86addr >= lOpStart && lOpx86addr <= lOpEnd) /* these profile samples lie within current r4300 instruction */ { int instr = pOpAddrTable[i].mipsop; if (instr == -1) printf("%lx sample point lies between %i/%lx and %i/%lx\n", lOpx86addr, instr, lOpStart, pOpAddrTable[i+1].mipsop, lOpEnd); if (instr == -1) samp_unknown += pProfTable[j].samples; else if (instr == -2) samp_notcompiled += pProfTable[j].samples; else if (instr == -3) samp_blockend += pProfTable[j].samples; else if (instr == -4) samp_wrappers += pProfTable[j].samples; else if (instr == -5) samp_flush += pProfTable[j].samples; else instr_samples[instr] += pProfTable[j].samples; continue; } if (lOpx86addr < pOpAddrTable[0].x86addr || lOpx86addr >= pOpAddrTable[oplistlength-1].x86addr) { /* outside the range of all recompiled instructions */ samp_unknown += pProfTable[j].samples; continue; } if (lOpx86addr < lOpStart) /* discontinuity in profile list, go back to start */ { i = 0; lOpStart = pOpAddrTable[0].x86addr; lOpEnd = pOpAddrTable[1].x86addr; j--; continue; } /* this profile point is ahead of current r4300 instruction */ do /* race ahead in r4300 opcode list until we hit this profile sample point */ { i++; } while (i+1 < oplistlength && lOpx86addr > pOpAddrTable[i+1].x86addr); lOpStart = pOpAddrTable[i].x86addr; lOpEnd = pOpAddrTable[i+1].x86addr; if (lOpx86addr < lOpStart || lOpx86addr > lOpEnd) { printf("Error: lOpx86addr = %lx but lOpStart, lOpEnd = %lx, %lx\n", lOpx86addr, lOpStart, lOpEnd); free(pOpAddrTable); free(pProfTable); return 7; } /* we have found the correct r4300 instruction corresponding to this profile point */ j--; } /* print the results */ unsigned int iTypeCount[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; printf("\nInstruction time (samples):\n"); totaltime = 0; for (i = 0; i < 131; i++) { printf("%8s: %08i ", instr_name[i], instr_samples[i]); if (i % 5 == 4) printf("\n"); iTypeCount[instr_type[i]] += instr_samples[i]; totaltime += instr_samples[i]; } int special = samp_flush + samp_wrappers + samp_notcompiled + samp_blockend; printf("\n\nSpecial code samples:\n"); printf(" Regcache flushing: %i\n", samp_flush); printf(" Jump wrappers: %i\n", samp_wrappers); printf(" NOTCOMPILED: %i\n", samp_notcompiled); printf(" block postfix & link samples: %i\n", samp_blockend); printf("\nUnaccounted samples: %i\n", samp_unknown); printf("Total accounted instruction samples: %i\n", totaltime + special); for (i = 0; i < 11; i++) { printf("%20s: %04.1f%% (%i)\n", instr_typename[i], (float) iTypeCount[i] * 100.0 / totaltime, iTypeCount[i]); } free(pOpAddrTable); free(pProfTable); return 0; } int AddrCompare(const void *p1, const void *p2) { const r4300op *pOp1 = (const r4300op *) p1; const r4300op *pOp2 = (const r4300op *) p2; if (pOp1->x86addr < pOp2->x86addr) return -1; else if (pOp1->x86addr == pOp2->x86addr) return (int) (pOp1 - pOp2); /* this forces qsort to be stable */ else return 1; } int ParseProfLine(const char *pchIn, long *plAddress, int *piSamples, float *pfPercentage) { char chVal[128], *pchOut; /* skip any initial whitespace */ while (isSpace(*pchIn)) pchIn++; if (!isHex(*pchIn)) return 0; /* parse hexadecimal address value */ pchOut = chVal; while (isHex(*pchIn)) *pchOut++ = *pchIn++; *pchOut = 0; if (!isSpace(*pchIn)) return 0; *plAddress = strtol(chVal, NULL, 16); /* skip more whitespace */ while (isSpace(*pchIn)) pchIn++; if (!isNum(*pchIn)) return 0; /* parse decimal sample count value */ pchOut = chVal; while (isNum(*pchIn)) *pchOut++ = *pchIn++; *pchOut = 0; if (!isSpace(*pchIn)) return 0; *piSamples = atoi(chVal); /* skip more whitespace */ while (isSpace(*pchIn)) pchIn++; if (!isFloat(*pchIn)) return 0; /* parse floating-point percentage value */ pchOut = chVal; while (isFloat(*pchIn)) *pchOut++ = *pchIn++; *pchOut = 0; if (!isSpace(*pchIn) && *pchIn != '\r' && *pchIn != '\n' && *pchIn != 0) return 0; *pfPercentage = atof(chVal); /* if this isn't the end of the line, it's not a valid sample point */ while (isSpace(*pchIn)) pchIn++; if (*pchIn != '\r' && *pchIn != '\n' && *pchIn != 0) return 0; return 1; } static int InstrTypeStd[64] = { -1, -1, 02, 03, 04, 05, 06, 07, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, 00, 00, 16, 17, 18, 19, 20, 21, 22, 23, 00, 00, 00, 00, 24, 25, 27, 26, 28, 29, 31, 30, 32, 33, 35, 34, 37, 38, 36, 01, 42, 39, 00, 00, 01, 40, 00, 41, 46, 43, 00, 00, 01, 44, 00, 45 }; static int InstrTypeSpecial[64] = { 55, 00, 56, 57, 58, 00, 59, 60, 61, 62, 00, 00, 63, 01, 00, 00, 64, 65, 66, 67, 68, 00, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 00, 00, 87, 88, 89, 90, 91, 92, 01, 01, 01, 01, 96, 00, 01, 00, 93, 00, 94, 95, 97, 00, 98, 99 }; static int InstrTypeRegImm[32] = { 47, 48, 49, 50, 00, 00, 00, 00, 01, 01, 01, 01, 01, 00, 01, 00, 51, 52, 53, 54, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 }; static int InstrTypeCop1[32] = { 111, 112, 113, 00, 114, 115, 116, 00, -1, 00, 00, 00, 00, 00, 00, 00, -1, -1, 00, 00, -1, -1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 }; static int InstrTypeCop1Math[64] = { 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 127, 128, 129, 130, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 117, 117, 00, 00, 117, 117, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118 }; int GetInstrType(int opcode) { int iType = (opcode >> 26) & 63; if (iType == 0) { /* SPECIAL instruction */ iType = opcode & 63; return InstrTypeSpecial[iType]; } else if (iType == 1) { /* REGIMM instruction */ iType = (opcode >> 16) & 31; return InstrTypeRegImm[iType]; } else if (iType == 16) { /* COP0 instruction */ int iType1 = opcode & 0x01FFFFFF; int iType2 = (opcode >> 21) & 31; if (iType1 == 1) return 106; // TLBR else if (iType1 == 2) return 104; // TLBWI else if (iType1 == 6) return 107; // TLBWR else if (iType1 == 8) return 105; // TLBP else if (iType1 == 24) return 108; // ERET else if ((opcode & 0x7FF) == 0 && iType2 == 0) return 109; // MFC0 else if ((opcode & 0x7FF) == 0 && iType2 == 4) return 110; // MTC0 else return 0; // reserved } else if (iType == 17) { /* COP1 instruction */ int iType1 = (opcode >> 21) & 31; if (iType1 == 8) { /* conditional branch */ int iType2 = (opcode >> 16) & 31; if (iType2 == 0) return 100; // BC1F else if (iType2 == 1) return 101; // BC1T else if (iType2 == 2) return 102; // BC1FL else if (iType2 == 3) return 103; // BC1TL else return 0; // reserved } else if (iType1 == 16 || iType1 == 17 || iType1 == 20 || iType1 == 21) { /* Single, Double, Word, Long instructions */ int iType2 = opcode & 63; return InstrTypeCop1Math[iType2]; } else { /* other Cop1 (move) */ return InstrTypeCop1[iType1]; } } /* standard MIPS instruction */ return InstrTypeStd[iType]; } mupen64plus-core/doc/emuwiki-api-doc/Mupen64Plus_v2.0_Core_Config.txt000664 001750 001750 00000047400 12655644434 026452 0ustar00sergiosergio000000 000000 [[Mupen64Plus v2.0 Core API v1.0|Mupen64Plus v2.0 API]] = Mupen64Plus v2.0 Configuration API = Most libmupen64plus functions return an m64p_error return code, which is an enumerated type defined in [[Mupen64Plus v2.0 headers#m64p_types.h|m64p_types.h]]. Front-end code should check the return value of each call to a libmupen64plus function. == Selector Functions == These functions are used by the front-end to discover the sections in the configuration file, open a section, discover parameters within a section, and find out if a section has been changed. {| border="1" |Prototype |'''m64p_error ConfigListSections(void *context, void (*SectionListCallback)(void * context, const char * SectionName))''' |- |Input Parameters |'''context''' Void pointer to be passed to the SectionListCallback function
'''SectionListCallback''' Pointer to function in front-end for receiving the name of every section in the Mupen64Plus Core configuration data. This function will be called once for each section in the core configuration data structure, and then the ConfigListSections() function will return. |- |Requirements |The Mupen64Plus library must already be initialized before calling this function. The '''SectionListCallback''' pointer cannot be NULL. |- |Usage |This function is called to enumerate the list of Sections in the Mupen64Plus Core configuration file. It is expected that there will be a section named "Core" for core-specific configuration data, "Graphics" for common graphics options, and one section for each plugin library. |}
{| border="1" |Prototype |'''m64p_error ConfigOpenSection(const char *SectionName, m64p_handle *ConfigSectionHandle)''' |- |Input Parameters |'''SectionName''' Name of the Mupen64Plus configuration section to open. This name is case-insensitive. If no section exists with the given name, a new one will be created with no parameters. This name may consist of any ASCII characters between 32 and 127 except brackets "[]".
'''ConfigSectionHandle''' This is a handle (defined in [[Mupen64Plus v2.0 headers#m64p_types.h|m64p_types.h]]) which is required to be used for subsequent calls to core configuration functions to list, retrieve, or set configuration parameters. |- |Requirements |The Mupen64Plus library must already be initialized before calling this function. The '''SectionName''' and '''ConfigSectionHandle''' pointers cannot be NULL. |- |Usage |This function is used to give a configuration section handle to the front-end which may be used to read or write configuration parameter values in a given section of the configuration file. |}
{| border="1" |Prototype |'''m64p_error ConfigListParameters(m64p_handle ConfigSectionHandle, void *context, void (*ParameterListCallback)(void * context, const char *ParamName, m64p_type ParamType))''' |- |Input Parameters |'''ConfigSectionHandle''' An m64p_handle given by the '''ConfigOpenSection''' function.
'''context''' Void pointer to be passed to the ParameterListCallback function
'''ParameterListCallback''' Pointer to function in front-end for receiving the name of every parameter in the given section of the Mupen64Plus Core configuration data. This function will be called once for each parameter in the section, and then the ConfigListParameters() function will return. |- |Requirements |The Mupen64Plus library must already be initialized before calling this function. The '''ConfigSectionHandle''' and '''ParameterListCallback''' pointers cannot be NULL. |- |Usage |This function is called to enumerate the list of Parameters in a given Section of the Mupen64Plus Core configuration file. |}
{| border="1" |Prototype |'''int ConfigHasUnsavedChanges(const char *SectionName)''' |- |Input Parameters |'''SectionName''' Name of the Mupen64Plus configuration section to check for unsaved changes. This name is case-insensitive. If this pointer is NULL or points to an empty string, then all sections are checked. |- |Requirements |The Mupen64Plus library must already be initialized before calling this function.
This function was added in the Config API version 2.2.0. |- |Usage |This function is called to determine if a given Section (or all sections) of the Mupen64Plus Core configuration file has been modified since it was last saved. A return value of 0 means there are no unsaved changes, while a 1 will be returned if there are unsaved changes. |} == Modifier Functions == These functions are used for deleting parts of the configuration list or saving the configuration data to disk. {| border="1" |Prototype |'''m64p_error ConfigDeleteSection(const char *SectionName)''' |- |Input Parameters |'''SectionName''' Name of the Mupen64Plus configuration section to delete. This name is case-insensitive. This name may consist of any ASCII characters between 32 and 127 except brackets "[]".
|- |Requirements |The Mupen64Plus library must already be initialized before calling this function. |- |Usage |This function deletes a section from the Mupen64Plus configuration data. |}
{| border="1" |Prototype |'''m64p_error ConfigSaveFile(void)''' |- |Input Parameters |N/A |- |Requirements |The Mupen64Plus library must already be initialized before calling this function. |- |Usage |This function saves the Mupen64Plus configuration file to disk. |}
{| border="1" |Prototype |'''m64p_error ConfigSaveSection(const char *SectionName)''' |- |Input Parameters |'''SectionName''' Name of the Mupen64Plus configuration section to save. This name is case-insensitive. |- |Requirements |The Mupen64Plus library must already be initialized before calling this function. The named section must exist in the current configuration.
This function was added in the Config API version 2.1.0. |- |Usage |This function saves one section of the current Mupen64Plus configuration to disk, while leaving the other sections unmodified. |}
{| border="1" |Prototype |'''m64p_error ConfigRevertChanges(const char *SectionName)''' |- |Input Parameters |'''SectionName''' Name of the Mupen64Plus configuration section to modify. This name is case-insensitive. This pointer cannot be NULL. |- |Requirements |The Mupen64Plus library must already be initialized before calling this function. The named section must exist in the current configuration.
This function was added in the Config API version 2.2.0. |- |Usage |This function reverts changes previously made to one section of the current Mupen64Plus configuration file, so that it will match with the configuration at the last time that it was loaded from or saved to disk. |} == Generic Get/Set Functions == These functions should be used for reading or writing configuration values in most cases. {| border="1" |Prototype |'''m64p_error ConfigSetParameter(m64p_handle ConfigSectionHandle, const char *ParamName, m64p_type ParamType, const void *ParamValue)''' |- |Input Parameters |'''ConfigSectionHandle''' An m64p_handle given by the '''ConfigOpenSection''' function.
'''ParamName''' NULL-terminated string containing the name of the parameter whose value is being set. This name is case-insensitive. This name may consist of any ASCII characters between 32 and 127 except the equals and hash signs, and may not end in a space.
'''ParamType''' An m64p_type value giving the type of the data object that '''ParamValue''' points to. If this is different from the native data representation used by the core, it will be converted into the type used by the core.
'''ParamValue''' Pointer to data object containing the value of the parameter to be set.
|- |Requirements |The Mupen64Plus library must already be initialized before calling this function. The '''ConfigSectionHandle''', '''ParamName''' and '''ParamValue''' pointers cannot be NULL. |- |Usage |This function sets the value of one of the emulator's configuration parameters in the section which is represented by '''ConfigSectionHandle'''. |}
{| border="1" |Prototype |'''m64p_error ConfigGetParameter(m64p_handle ConfigSectionHandle, const char *ParamName, m64p_type ParamType, void *ParamValue, int MaxSize)''' |- |Input Parameters |'''ConfigSectionHandle''' An m64p_handle given by the '''ConfigOpenSection''' function.
'''ParamName''' NULL-terminated string containing the name of the parameter whose value is being retrieved. This name is case-insensitive. This name may consist of any ASCII characters between 32 and 127 except the equals and hash signs, and may not end in a space.
'''ParamType''' An m64p_type value giving the type of the data object that '''ParamValue''' points to. If this is different from the native data representation used by the core, it will be converted into the type given by '''ParamType'''.
'''ParamValue''' Pointer to data object to receive the value of the parameter being retrieved.
'''MaxSize''' Size (in bytes) of the data object that '''ParamValue''' points to. |- |Requirements |The Mupen64Plus library must already be initialized before calling this function. The '''ConfigSectionHandle''', '''ParamName''' and '''ParamValue''' pointers cannot be NULL. |- |Usage |This function retrieves the value of one of the emulator's parameters in the section which is represented by '''ConfigSectionHandle'''. |}
{| border="1" |Prototype |'''m64p_error ConfigGetParameterType(m64p_handle ConfigSectionHandle, const char *ParamName, m64p_type *ParamType)''' |- |Input Parameters |'''ConfigSectionHandle''' An m64p_handle given by the '''ConfigOpenSection''' function.
'''ParamName''' Pointer to a NULL-terminated string containing the name of the parameter whose type is being retrieved. This name is case-insensitive. This name may consist of any ASCII characters between 32 and 127 except the equals and hash signs, and may not end in a space.
'''ParamType''' Pointer to an m64p_type value to receive the type of the parameter indicated by '''ParamName'''. |- |Requirements |The Mupen64Plus library must already be initialized before calling this function. The '''ConfigSectionHandle''', '''ParamName''', and '''ParamType''' pointers cannot be NULL. |- |Usage |This function retrieves the type of one of the emulator's parameters in the section which is represented by '''ConfigSectionHandle'''. If there is no parameter with the given '''ParamName''', the error M64ERR_INPUT_NOT_FOUND will be returned. |}
{| border="1" |Prototype |'''const char * ConfigGetParameterHelp(m64p_handle ConfigSectionHandle, const char *ParamName)''' |- |Return Value |Pointer to a NULL-terminated string containing usage information for the '''ParamName''' parameter. May be NULL. |- |Input Parameters |'''ConfigSectionHandle''' An m64p_handle given by the '''ConfigOpenSection''' function.
'''ParamName''' NULL-terminated string containing the name of the parameter for which usage information is being retrieved. This name is case-insensitive. This name may consist of any ASCII characters between 32 and 127 except the equals and hash signs, and may not end in a space. |- |Requirements |The Mupen64Plus library must already be initialized before calling this function. The '''ConfigSectionHandle''', and '''ParamName''' pointers cannot be NULL. |- |Usage |This function retrieves the help information about one of the emulator's parameters in the section which is represented by '''ConfigSectionHandle'''. |} == Special Get/Set Functions == These parameterized Get/SetDefault functions are provided for simplifying the task of handling default values within a single module. Each code module using the Core's configuration API should set the default values for all configuration parameters used by that module during its Startup() function. This allows the software to set up the default values automatically rather than storing them in a separate "default config file" which has proven problematic in the past. This also solves the problem which occurs when an upgraded module contains a new config parameter not present in the previous release. The special Get functions return the configuration value directly rather than writing them through a pointer and returning an error code. For this reason, these parameterized Get functions should only be used within a module which 'owns' the configuration section and set up its default values in the Startup() function. Because these functions cannot signal an error to the caller, a front-end should not use these functions to retrieve configuration values for the core or the plugins, unless the names of the parameters have been enumerated with ConfigListParameters and are therefore guaranteed to exist.
{| border="1" |Prototype |'''m64p_error ConfigSetDefaultInt(m64p_handle ConfigSectionHandle, const char *ParamName, int ParamValue, const char *ParamHelp)'''
'''m64p_error ConfigSetDefaultFloat(m64p_handle ConfigSectionHandle, const char *ParamName, float ParamValue, const char *ParamHelp)'''
'''m64p_error ConfigSetDefaultBool(m64p_handle ConfigSectionHandle, const char *ParamName, int ParamValue, const char *ParamHelp)'''
'''m64p_error ConfigSetDefaultString(m64p_handle ConfigSectionHandle, const char *ParamName, const char * ParamValue, const char *ParamHelp)''' |- |Input Parameters |'''ConfigSectionHandle''' An m64p_handle given by the '''ConfigOpenSection''' function.
'''ParamName''' NULL-terminated string containing the name of the parameter whose value is being set. This name is case-insensitive. This name may consist of any ASCII characters between 32 and 127 except the equals and hash signs, and may not end in a space.
'''ParamValue''' Integer or null-terminated string pointer containing the value of the parameter to be set.
'''ParamHelp''' NULL-terminated string containing some human-readable information about the usage of this parameter. Can be NULL. |- |Requirements |The Mupen64Plus library must already be initialized before calling this function. The '''ConfigSectionHandle''' and '''ParamName''' pointers cannot be NULL. |- |Usage |This function is used to set the value of a configuration parameter if it is not already present in the configuration file. This may happen if a new user runs the emulator, or an upgraded module uses a new parameter, or the user deletes his or her configuration file. If a parameter named '''ParamName''' is already present in the given section of the configuration file, then no action will be taken and this function will return successfully. Otherwise, a new parameter will be created its value will be assigned to '''ParamValue'''. |}
{| border="1" |Prototype | {| |- |'''int''' || '''ConfigGetParamInt(m64p_handle ConfigSectionHandle, const char *ParamName)''' |- |'''float''' || '''ConfigGetParamFloat(m64p_handle ConfigSectionHandle, const char *ParamName)''' |- |'''int''' || '''ConfigGetParamBool(m64p_handle ConfigSectionHandle, const char *ParamName)''' |- |'''const char *''' || '''ConfigGetParamString(m64p_handle ConfigSectionHandle, const char *ParamName)''' |} |- |Input Parameters |'''ConfigSectionHandle''' An m64p_handle given by the '''ConfigOpenSection''' function.
'''ParamName''' NULL-terminated string containing the name of the parameter whose value is being retrieved. This name is case-insensitive. This name may consist of any ASCII characters between 32 and 127 except the equals and hash signs, and may not end in a space. |- |Requirements |The Mupen64Plus library must already be initialized before calling this function. The '''ConfigSectionHandle''' and '''ParamName''' pointers cannot be NULL. |- |Usage |This function retrieves the value of one of the emulator's parameters in the section which is represented by '''ConfigSectionHandle''', and returns the value directly to the calling function. If an errors occurs (such as if '''ConfigSectionHandle''' is invalid, or there is no configuration parameter named '''ParamName'''), then an error will be sent to the front-end via the DebugCallback() function, and either a 0 (zero) or an empty string will be returned. |} == OS-Abstraction Functions == {| border="1" |Prototype |'''const char * ConfigGetSharedDataFilepath(const char *filename)''' |- |Return Value |Pointer to a NULL-terminated string containing a full directory path and filename to a given shared data file, or NULL if this file was not found. |- |Requirements |The Mupen64Plus library must already be initialized before calling this function. |- |Usage |It is common for shared data files on Unix systems to be installed in different places on different systems. Therefore, this core function is provided to allow a plugin to retrieve a full pathname to a given shared data file. This type of file is intended to be shared among multiple users on a system, so it is likely to be read-only. Examples of these types of files include: the .ini files for Rice Video and Glide64, the font and Mupen64Plus.ini files for the core, and the cheat code files for the front-end. This function will first search in a directory given via the DataPath parameter to the '''CoreStartup''' function, then in a directory given by the SharedDataPath core configuration parameter, then in a directory which may be supplied at compile time through a Makefile or configure script option, and finally in some common system locations (such as /usr/share/mupen64plus and /usr/local/share/mupen64plus on Unix systems). |}
{| border="1" |Prototype |'''const char * ConfigGetUserConfigPath(void)''' |- |Return Value |Pointer to a NULL-terminated string containing the directory path to user-specific configuration files. |- |Requirements |The Mupen64Plus library must already be initialized before calling this function. |- |Usage |This function may be used by the plugins or front-end to get a path to the directory for storing user-specific configuration files. This will be the directory where the configuration file "mupen64plus.cfg" is located. |}
{| border="1" |Prototype |'''const char * ConfigGetUserDataPath(void)''' |- |Return Value |Pointer to a NULL-terminated string containing the directory path to user-specific data files. |- |Requirements |The Mupen64Plus library must already be initialized before calling this function. |- |Usage |This function may be used by the plugins or front-end to get a path to the directory for storing user-specific data files. This may be used to store files such as screenshots, saved game states, or hi-res textures. |}
{| border="1" |Prototype |'''const char * ConfigGetUserCachePath(void)''' |- |Return Value |Pointer to a NULL-terminated string containing the directory path to user-specific caching data files. |- |Requirements |The Mupen64Plus library must already be initialized before calling this function. |- |Usage |This function may be used by the plugins or front-end to get a path to the directory for storing user-specific caching data files. Files in this directory may be deleted by the user to save space, so critical information should not be stored here. This directory may be used to store files such as the ROM browser cache. |} mupen64plus-rsp-hle/src/alist.c000664 001750 001750 00000073572 12655644434 017556 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-rsp-hle - alist.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * Copyright (C) 2009 Richard Goedeken * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include "alist.h" #include "arithmetics.h" #include "audio.h" #include "hle_external.h" #include "hle_internal.h" #include "memory.h" struct ramp_t { int64_t value; int64_t step; int64_t target; }; /* local functions */ static void swap(int16_t **a, int16_t **b) { int16_t* tmp = *b; *b = *a; *a = tmp; } #define sample(hle, pos) ((int16_t*)(hle)->alist_buffer + ((pos) ^ S)) #define alist_u8(hle, dmem) (u8((hle)->alist_buffer, (dmem))) #define alist_s16(hle, dmem) ((int16_t*)u16((hle)->alist_buffer, (dmem))) #define sample_mix(dst, src, gain) (clamp_s16(*(dst) + (((src) * (gain)) >> 15))) static void alist_envmix_mix(size_t n, int16_t** dst, const int16_t* gains, int16_t src) { size_t i; for(i = 0; i < n; ++i) *dst[i] = sample_mix(dst[i], src, gains[i]); } static int16_t ramp_step(struct ramp_t* ramp) { bool target_reached; ramp->value += ramp->step; target_reached = (ramp->step <= 0) ? (ramp->value <= ramp->target) : (ramp->value >= ramp->target); if (target_reached) { ramp->value = ramp->target; ramp->step = 0; } return (int16_t)(ramp->value >> 16); } /* global functions */ void alist_process(struct hle_t* hle, const acmd_callback_t abi[], unsigned int abi_size) { uint32_t addr = *dmem_u32(hle, TASK_DATA_PTR); const uint32_t *alist = dram_u32(hle, addr); const uint32_t *const alist_end = alist + (*dmem_u32(hle, TASK_DATA_SIZE) >> 2); while (alist != alist_end) { uint32_t w1 = *(alist++); uint32_t w2 = *(alist++); uint32_t acmd = (w1 >> 24) & 0x7f; if (acmd < abi_size) (*abi[acmd])(hle, w1, w2); } } uint32_t alist_get_address(struct hle_t* hle, uint32_t so, const uint32_t *segments, size_t n) { uint8_t segment = (so >> 24); uint32_t offset = (so & 0xffffff); if (segment >= n) { HleWarnMessage(hle->user_defined, "Invalid segment %u", segment); return offset; } return segments[segment] + offset; } void alist_set_address(struct hle_t* hle, uint32_t so, uint32_t *segments, size_t n) { uint8_t segment = (so >> 24); uint32_t offset = (so & 0xffffff); if (segment >= n) { HleWarnMessage(hle->user_defined, "Invalid segment %u", segment); return; } segments[segment] = offset; } void alist_clear(struct hle_t* hle, uint16_t dmem, uint16_t count) { memset(hle->alist_buffer + dmem, 0, count); } void alist_load(struct hle_t* hle, uint16_t dmem, uint32_t address, uint16_t count) { /* enforce DMA alignment constraints */ dmem &= ~3; address &= ~7; count = align(count, 8); memcpy(hle->alist_buffer + dmem, hle->dram + address, count); } void alist_save(struct hle_t* hle, uint16_t dmem, uint32_t address, uint16_t count) { /* enforce DMA alignment constraints */ dmem &= ~3; address &= ~7; count = align(count, 8); memcpy(hle->dram + address, hle->alist_buffer + dmem, count); } void alist_move(struct hle_t* hle, uint16_t dmemo, uint16_t dmemi, uint16_t count) { while (count) { *alist_u8(hle, dmemo++) = *alist_u8(hle, dmemi++); --count; } } void alist_copy_every_other_sample(struct hle_t* hle, uint16_t dmemo, uint16_t dmemi, uint16_t count) { while (count) { *alist_s16(hle, dmemo) = *alist_s16(hle, dmemi); dmemo += 2; dmemi += 4; --count; } } void alist_repeat64(struct hle_t* hle, uint16_t dmemo, uint16_t dmemi, uint8_t count) { uint16_t buffer[64]; memcpy(buffer, hle->alist_buffer + dmemi, 128); while(count) { memcpy(hle->alist_buffer + dmemo, buffer, 128); dmemo += 128; --count; } } void alist_copy_blocks(struct hle_t* hle, uint16_t dmemo, uint16_t dmemi, uint16_t block_size, uint8_t count) { int block_left = count; do { int bytes_left = block_size; do { memcpy(hle->alist_buffer + dmemo, hle->alist_buffer + dmemi, 0x20); bytes_left -= 0x20; dmemi += 0x20; dmemo += 0x20; } while(bytes_left > 0); --block_left; } while(block_left > 0); } void alist_interleave(struct hle_t* hle, uint16_t dmemo, uint16_t left, uint16_t right, uint16_t count) { uint16_t *dst = (uint16_t*)(hle->alist_buffer + dmemo); const uint16_t *srcL = (uint16_t*)(hle->alist_buffer + left); const uint16_t *srcR = (uint16_t*)(hle->alist_buffer + right); count >>= 2; while(count) { uint16_t l1 = *(srcL++); uint16_t l2 = *(srcL++); uint16_t r1 = *(srcR++); uint16_t r2 = *(srcR++); #ifdef MSB_FIRST *(dst++) = l1; *(dst++) = r1; *(dst++) = l2; *(dst++) = r2; #else *(dst++) = r2; *(dst++) = l2; *(dst++) = r1; *(dst++) = l1; #endif --count; } } void alist_envmix_exp( struct hle_t* hle, bool init, bool aux, uint16_t dmem_dl, uint16_t dmem_dr, uint16_t dmem_wl, uint16_t dmem_wr, uint16_t dmemi, uint16_t count, int16_t dry, int16_t wet, const int16_t *vol, const int16_t *target, const int32_t *rate, uint32_t address) { struct ramp_t ramps[2]; int32_t exp_seq[2]; int32_t exp_rates[2]; int x, y; size_t n = (aux) ? 4 : 2; const int16_t* const in = (int16_t*)(hle->alist_buffer + dmemi); int16_t* const dl = (int16_t*)(hle->alist_buffer + dmem_dl); int16_t* const dr = (int16_t*)(hle->alist_buffer + dmem_dr); int16_t* const wl = (int16_t*)(hle->alist_buffer + dmem_wl); int16_t* const wr = (int16_t*)(hle->alist_buffer + dmem_wr); uint32_t ptr = 0; short *save_buffer = (short*)((uint8_t*)hle->dram + address); if (init) { ramps[0].value = (vol[0] << 16); ramps[1].value = (vol[1] << 16); ramps[0].target = (target[0] << 16); ramps[1].target = (target[1] << 16); exp_rates[0] = rate[0]; exp_rates[1] = rate[1]; exp_seq[0] = (vol[0] * rate[0]); exp_seq[1] = (vol[1] * rate[1]); } else { wet = *(int16_t *)(save_buffer + 0); /* 0-1 */ dry = *(int16_t *)(save_buffer + 2); /* 2-3 */ ramps[0].target = *(int32_t *)(save_buffer + 4); /* 4-5 */ ramps[1].target = *(int32_t *)(save_buffer + 6); /* 6-7 */ exp_rates[0] = *(int32_t *)(save_buffer + 8); /* 8-9 (save_buffer is a 16bit pointer) */ exp_rates[1] = *(int32_t *)(save_buffer + 10); /* 10-11 */ exp_seq[0] = *(int32_t *)(save_buffer + 12); /* 12-13 */ exp_seq[1] = *(int32_t *)(save_buffer + 14); /* 14-15 */ ramps[0].value = *(int32_t *)(save_buffer + 16); /* 12-13 */ ramps[1].value = *(int32_t *)(save_buffer + 18); /* 14-15 */ } /* init which ensure ramp.step != 0 iff ramp.value == ramp.target */ ramps[0].step = ramps[0].target - ramps[0].value; ramps[1].step = ramps[1].target - ramps[1].value; for (y = 0; y < count; y += 16) { if (ramps[0].step) { exp_seq[0] = ((int64_t)exp_seq[0]*(int64_t)exp_rates[0]) >> 16; ramps[0].step = (exp_seq[0] - ramps[0].value) >> 3; } if (ramps[1].step) { exp_seq[1] = ((int64_t)exp_seq[1]*(int64_t)exp_rates[1]) >> 16; ramps[1].step = (exp_seq[1] - ramps[1].value) >> 3; } for (x = 0; x < 8; ++x) { int16_t gains[4]; int16_t* buffers[4]; int16_t l_vol = ramp_step(&ramps[0]); int16_t r_vol = ramp_step(&ramps[1]); buffers[0] = dl + (ptr^S); buffers[1] = dr + (ptr^S); buffers[2] = wl + (ptr^S); buffers[3] = wr + (ptr^S); gains[0] = clamp_s16((l_vol * dry + 0x4000) >> 15); gains[1] = clamp_s16((r_vol * dry + 0x4000) >> 15); gains[2] = clamp_s16((l_vol * wet + 0x4000) >> 15); gains[3] = clamp_s16((r_vol * wet + 0x4000) >> 15); alist_envmix_mix(n, buffers, gains, in[ptr^S]); ++ptr; } } *(int16_t *)(save_buffer + 0) = wet; /* 0-1 */ *(int16_t *)(save_buffer + 2) = dry; /* 2-3 */ *(int32_t *)(save_buffer + 4) = (int32_t)ramps[0].target; /* 4-5 */ *(int32_t *)(save_buffer + 6) = (int32_t)ramps[1].target; /* 6-7 */ *(int32_t *)(save_buffer + 8) = exp_rates[0]; /* 8-9 (save_buffer is a 16bit pointer) */ *(int32_t *)(save_buffer + 10) = exp_rates[1]; /* 10-11 */ *(int32_t *)(save_buffer + 12) = exp_seq[0]; /* 12-13 */ *(int32_t *)(save_buffer + 14) = exp_seq[1]; /* 14-15 */ *(int32_t *)(save_buffer + 16) = (int32_t)ramps[0].value; /* 12-13 */ *(int32_t *)(save_buffer + 18) = (int32_t)ramps[1].value; /* 14-15 */ } void alist_envmix_ge( struct hle_t* hle, bool init, bool aux, uint16_t dmem_dl, uint16_t dmem_dr, uint16_t dmem_wl, uint16_t dmem_wr, uint16_t dmemi, uint16_t count, int16_t dry, int16_t wet, const int16_t *vol, const int16_t *target, const int32_t *rate, uint32_t address) { unsigned k; struct ramp_t ramps[2]; size_t n = (aux) ? 4 : 2; const int16_t* const in = (int16_t*)(hle->alist_buffer + dmemi); int16_t* const dl = (int16_t*)(hle->alist_buffer + dmem_dl); int16_t* const dr = (int16_t*)(hle->alist_buffer + dmem_dr); int16_t* const wl = (int16_t*)(hle->alist_buffer + dmem_wl); int16_t* const wr = (int16_t*)(hle->alist_buffer + dmem_wr); short *save_buffer = (short*)((uint8_t*)hle->dram + address); if (init) { ramps[0].value = (vol[0] << 16); ramps[1].value = (vol[1] << 16); ramps[0].target = (target[0] << 16); ramps[1].target = (target[1] << 16); ramps[0].step = rate[0] / 8; ramps[1].step = rate[1] / 8; } else { wet = *(int16_t *)(save_buffer + 0); /* 0-1 */ dry = *(int16_t *)(save_buffer + 2); /* 2-3 */ ramps[0].target = *(int32_t *)(save_buffer + 4); /* 4-5 */ ramps[1].target = *(int32_t *)(save_buffer + 6); /* 6-7 */ ramps[0].step = *(int32_t *)(save_buffer + 8); /* 8-9 (save_buffer is a 16bit pointer) */ ramps[1].step = *(int32_t *)(save_buffer + 10); /* 10-11 */ /* *(int32_t *)(save_buffer + 12);*/ /* 12-13 */ /* *(int32_t *)(save_buffer + 14);*/ /* 14-15 */ ramps[0].value = *(int32_t *)(save_buffer + 16); /* 12-13 */ ramps[1].value = *(int32_t *)(save_buffer + 18); /* 14-15 */ } count >>= 1; for (k = 0; k < count; ++k) { int16_t gains[4]; int16_t* buffers[4]; int16_t l_vol = ramp_step(&ramps[0]); int16_t r_vol = ramp_step(&ramps[1]); buffers[0] = dl + (k^S); buffers[1] = dr + (k^S); buffers[2] = wl + (k^S); buffers[3] = wr + (k^S); gains[0] = clamp_s16((l_vol * dry + 0x4000) >> 15); gains[1] = clamp_s16((r_vol * dry + 0x4000) >> 15); gains[2] = clamp_s16((l_vol * wet + 0x4000) >> 15); gains[3] = clamp_s16((r_vol * wet + 0x4000) >> 15); alist_envmix_mix(n, buffers, gains, in[k^S]); } *(int16_t *)(save_buffer + 0) = wet; /* 0-1 */ *(int16_t *)(save_buffer + 2) = dry; /* 2-3 */ *(int32_t *)(save_buffer + 4) = (int32_t)ramps[0].target; /* 4-5 */ *(int32_t *)(save_buffer + 6) = (int32_t)ramps[1].target; /* 6-7 */ *(int32_t *)(save_buffer + 8) = (int32_t)ramps[0].step; /* 8-9 (save_buffer is a 16bit pointer) */ *(int32_t *)(save_buffer + 10) = (int32_t)ramps[1].step; /* 10-11 */ /* *(int32_t *)(save_buffer + 12); */ /* 12-13 */ /* *(int32_t *)(save_buffer + 14); */ /* 14-15 */ *(int32_t *)(save_buffer + 16) = (int32_t)ramps[0].value; /* 12-13 */ *(int32_t *)(save_buffer + 18) = (int32_t)ramps[1].value; /* 14-15 */ } void alist_envmix_lin( struct hle_t* hle, bool init, uint16_t dmem_dl, uint16_t dmem_dr, uint16_t dmem_wl, uint16_t dmem_wr, uint16_t dmemi, uint16_t count, int16_t dry, int16_t wet, const int16_t *vol, const int16_t *target, const int32_t *rate, uint32_t address) { size_t k; struct ramp_t ramps[2]; short *save_buffer = (short*)((uint8_t*)hle->dram + address); const int16_t * const in = (int16_t*)(hle->alist_buffer + dmemi); int16_t* const dl = (int16_t*)(hle->alist_buffer + dmem_dl); int16_t* const dr = (int16_t*)(hle->alist_buffer + dmem_dr); int16_t* const wl = (int16_t*)(hle->alist_buffer + dmem_wl); int16_t* const wr = (int16_t*)(hle->alist_buffer + dmem_wr); if (init) { ramps[0].step = rate[0] / 8; ramps[0].value = (vol[0] << 16); ramps[0].target = (target[0] << 16); ramps[1].step = rate[1] / 8; ramps[1].value = (vol[1] << 16); ramps[1].target = (target[1] << 16); } else { wet = *(int16_t *)(save_buffer + 0); /* 0-1 */ dry = *(int16_t *)(save_buffer + 2); /* 2-3 */ ramps[0].target = *(int16_t *)(save_buffer + 4) << 16; /* 4-5 */ ramps[1].target = *(int16_t *)(save_buffer + 6) << 16; /* 6-7 */ ramps[0].step = *(int32_t *)(save_buffer + 8); /* 8-9 (save_buffer is a 16bit pointer) */ ramps[1].step = *(int32_t *)(save_buffer + 10); /* 10-11 */ ramps[0].value = *(int32_t *)(save_buffer + 16); /* 16-17 */ ramps[1].value = *(int32_t *)(save_buffer + 18); /* 16-17 */ } count >>= 1; for(k = 0; k < count; ++k) { int16_t gains[4]; int16_t* buffers[4]; int16_t l_vol = ramp_step(&ramps[0]); int16_t r_vol = ramp_step(&ramps[1]); buffers[0] = dl + (k^S); buffers[1] = dr + (k^S); buffers[2] = wl + (k^S); buffers[3] = wr + (k^S); gains[0] = clamp_s16((l_vol * dry + 0x4000) >> 15); gains[1] = clamp_s16((r_vol * dry + 0x4000) >> 15); gains[2] = clamp_s16((l_vol * wet + 0x4000) >> 15); gains[3] = clamp_s16((r_vol * wet + 0x4000) >> 15); alist_envmix_mix(4, buffers, gains, in[k^S]); } *(int16_t *)(save_buffer + 0) = wet; /* 0-1 */ *(int16_t *)(save_buffer + 2) = dry; /* 2-3 */ *(int16_t *)(save_buffer + 4) = (ramps[0].target>>16)&0xFFFF; /* 4-5 */ *(int16_t *)(save_buffer + 6) = (ramps[1].target>>16)&0xFFFF; /* 6-7 */ *(int32_t *)(save_buffer + 8) = (int32_t)ramps[0].step; /* 8-9 (save_buffer is a 16bit pointer) */ *(int32_t *)(save_buffer + 10) = (int32_t)ramps[1].step; /* 10-11 */ *(int32_t *)(save_buffer + 16) = (int32_t)ramps[0].value; /* 16-17 */ *(int32_t *)(save_buffer + 18) = (int32_t)ramps[1].value; /* 18-19 */ } void alist_envmix_nead( struct hle_t* hle, bool swap_wet_LR, uint16_t dmem_dl, uint16_t dmem_dr, uint16_t dmem_wl, uint16_t dmem_wr, uint16_t dmemi, unsigned count, uint16_t *env_values, uint16_t *env_steps, const int16_t *xors) { int16_t *in = (int16_t*)(hle->alist_buffer + dmemi); int16_t *dl = (int16_t*)(hle->alist_buffer + dmem_dl); int16_t *dr = (int16_t*)(hle->alist_buffer + dmem_dr); int16_t *wl = (int16_t*)(hle->alist_buffer + dmem_wl); int16_t *wr = (int16_t*)(hle->alist_buffer + dmem_wr); /* make sure count is a multiple of 8 */ count = align(count, 8); if (swap_wet_LR) swap(&wl, &wr); while (count) { size_t i; for(i = 0; i < 8; ++i) { int16_t l = (((int32_t)in[i^S] * (uint32_t)env_values[0]) >> 16) ^ xors[0]; int16_t r = (((int32_t)in[i^S] * (uint32_t)env_values[1]) >> 16) ^ xors[1]; int16_t l2 = (((int32_t)l * (uint32_t)env_values[2]) >> 16) ^ xors[2]; int16_t r2 = (((int32_t)r * (uint32_t)env_values[2]) >> 16) ^ xors[3]; dl[i^S] = clamp_s16(dl[i^S] + l); dr[i^S] = clamp_s16(dr[i^S] + r); wl[i^S] = clamp_s16(wl[i^S] + l2); wr[i^S] = clamp_s16(wr[i^S] + r2); } env_values[0] += env_steps[0]; env_values[1] += env_steps[1]; env_values[2] += env_steps[2]; dl += 8; dr += 8; wl += 8; wr += 8; in += 8; count -= 8; } } void alist_mix(struct hle_t* hle, uint16_t dmemo, uint16_t dmemi, uint16_t count, int16_t gain) { int16_t *dst = (int16_t*)(hle->alist_buffer + dmemo); const int16_t *src = (int16_t*)(hle->alist_buffer + dmemi); count >>= 1; while(count) { *dst = sample_mix(dst, *src, gain); ++dst; ++src; --count; } } void alist_multQ44(struct hle_t* hle, uint16_t dmem, uint16_t count, int8_t gain) { int16_t *dst = (int16_t*)(hle->alist_buffer + dmem); count >>= 1; while(count) { *dst = clamp_s16(*dst * gain >> 4); ++dst; --count; } } void alist_add(struct hle_t* hle, uint16_t dmemo, uint16_t dmemi, uint16_t count) { int16_t *dst = (int16_t*)(hle->alist_buffer + dmemo); const int16_t *src = (int16_t*)(hle->alist_buffer + dmemi); count >>= 1; while(count) { *dst = clamp_s16(*dst + *src); ++dst; ++src; --count; } } static void alist_resample_reset(struct hle_t* hle, uint16_t pos, uint32_t* pitch_accu) { unsigned k; for(k = 0; k < 4; ++k) *sample(hle, pos + k) = 0; *pitch_accu = 0; } static void alist_resample_load(struct hle_t* hle, uint32_t address, uint16_t pos, uint32_t* pitch_accu) { *sample(hle, pos + 0) = *dram_u16(hle, address + 0); *sample(hle, pos + 1) = *dram_u16(hle, address + 2); *sample(hle, pos + 2) = *dram_u16(hle, address + 4); *sample(hle, pos + 3) = *dram_u16(hle, address + 6); *pitch_accu = *dram_u16(hle, address + 8); } static void alist_resample_save(struct hle_t* hle, uint32_t address, uint16_t pos, uint32_t pitch_accu) { *dram_u16(hle, address + 0) = *sample(hle, pos + 0); *dram_u16(hle, address + 2) = *sample(hle, pos + 1); *dram_u16(hle, address + 4) = *sample(hle, pos + 2); *dram_u16(hle, address + 6) = *sample(hle, pos + 3); *dram_u16(hle, address + 8) = pitch_accu; } void alist_resample( struct hle_t* hle, bool init, bool flag2, uint16_t dmemo, uint16_t dmemi, uint16_t count, uint32_t pitch, /* Q16.16 */ uint32_t address) { uint32_t pitch_accu; uint16_t ipos = (dmemi >> 1) - 4; uint16_t opos = dmemo >> 1; count >>= 1; #ifndef NDEBUG if (flag2) HleWarnMessage(hle->user_defined, "alist_resample: flag2 is not implemented"); #endif if (init) alist_resample_reset(hle, ipos, &pitch_accu); else alist_resample_load(hle, address, ipos, &pitch_accu); while (count) { const int16_t* lut = RESAMPLE_LUT + ((pitch_accu & 0xfc00) >> 8); *sample(hle, opos++) = clamp_s16( ((*sample(hle, ipos ) * lut[0]) >> 15) + ((*sample(hle, ipos + 1) * lut[1]) >> 15) + ((*sample(hle, ipos + 2) * lut[2]) >> 15) + ((*sample(hle, ipos + 3) * lut[3]) >> 15)); pitch_accu += pitch; ipos += (pitch_accu >> 16); pitch_accu &= 0xffff; --count; } alist_resample_save(hle, address, ipos, pitch_accu); } void alist_resample_zoh( struct hle_t* hle, uint16_t dmemo, uint16_t dmemi, uint16_t count, uint32_t pitch, uint32_t pitch_accu) { uint16_t ipos = dmemi >> 1; uint16_t opos = dmemo >> 1; count >>= 1; while(count) { *sample(hle, opos++) = *sample(hle, ipos); pitch_accu += pitch; ipos += (pitch_accu >> 16); pitch_accu &= 0xffff; --count; } } typedef unsigned int (*adpcm_predict_frame_t)(struct hle_t* hle, int16_t* dst, uint16_t dmemi, unsigned char scale); static unsigned int adpcm_predict_frame_4bits(struct hle_t* hle, int16_t* dst, uint16_t dmemi, unsigned char scale) { unsigned int i; unsigned int rshift = (scale < 12) ? 12 - scale : 0; for(i = 0; i < 8; ++i) { uint8_t byte = *alist_u8(hle, dmemi++); *(dst++) = adpcm_predict_sample(byte, 0xf0, 8, rshift); *(dst++) = adpcm_predict_sample(byte, 0x0f, 12, rshift); } return 8; } static unsigned int adpcm_predict_frame_2bits(struct hle_t* hle, int16_t* dst, uint16_t dmemi, unsigned char scale) { unsigned int i; unsigned int rshift = (scale < 14) ? 14 - scale : 0; for(i = 0; i < 4; ++i) { uint8_t byte = *alist_u8(hle, dmemi++); *(dst++) = adpcm_predict_sample(byte, 0xc0, 8, rshift); *(dst++) = adpcm_predict_sample(byte, 0x30, 10, rshift); *(dst++) = adpcm_predict_sample(byte, 0x0c, 12, rshift); *(dst++) = adpcm_predict_sample(byte, 0x03, 14, rshift); } return 4; } void alist_adpcm( struct hle_t* hle, bool init, bool loop, bool two_bit_per_sample, uint16_t dmemo, uint16_t dmemi, uint16_t count, const int16_t* codebook, uint32_t loop_address, uint32_t last_frame_address) { int16_t last_frame[16]; size_t i; adpcm_predict_frame_t predict_frame = (two_bit_per_sample) ? adpcm_predict_frame_2bits : adpcm_predict_frame_4bits; assert((count & 0x1f) == 0); if (init) memset(last_frame, 0, 16*sizeof(last_frame[0])); else dram_load_u16(hle, (uint16_t*)last_frame, (loop) ? loop_address : last_frame_address, 16); for(i = 0; i < 16; ++i, dmemo += 2) *alist_s16(hle, dmemo) = last_frame[i]; while (count) { int16_t frame[16]; uint8_t code = *alist_u8(hle, dmemi++); unsigned char scale = (code & 0xf0) >> 4; const int16_t* const cb_entry = codebook + ((code & 0xf) << 4); dmemi += predict_frame(hle, frame, dmemi, scale); adpcm_compute_residuals(last_frame , frame , cb_entry, last_frame + 14, 8); adpcm_compute_residuals(last_frame + 8, frame + 8, cb_entry, last_frame + 6 , 8); for(i = 0; i < 16; ++i, dmemo += 2) *alist_s16(hle, dmemo) = last_frame[i]; count -= 32; } dram_store_u16(hle, (uint16_t*)last_frame, last_frame_address, 16); } void alist_filter( struct hle_t* hle, uint16_t dmem, uint16_t count, uint32_t address, const uint32_t* lut_address) { int x; int16_t outbuff[0x3c0]; int16_t *outp = outbuff; int16_t* const lutt6 = (int16_t*)(hle->dram + lut_address[0]); int16_t* const lutt5 = (int16_t*)(hle->dram + lut_address[1]); int16_t* in1 = (int16_t*)(hle->dram + address); int16_t* in2 = (int16_t*)(hle->alist_buffer + dmem); for (x = 0; x < 8; ++x) { int32_t v = (lutt5[x] + lutt6[x]) >> 1; lutt5[x] = lutt6[x] = v; } for (x = 0; x < count; x += 16) { int32_t v[8]; v[1] = in1[0] * lutt6[6]; v[1] += in1[3] * lutt6[7]; v[1] += in1[2] * lutt6[4]; v[1] += in1[5] * lutt6[5]; v[1] += in1[4] * lutt6[2]; v[1] += in1[7] * lutt6[3]; v[1] += in1[6] * lutt6[0]; v[1] += in2[1] * lutt6[1]; /* 1 */ v[0] = in1[3] * lutt6[6]; v[0] += in1[2] * lutt6[7]; v[0] += in1[5] * lutt6[4]; v[0] += in1[4] * lutt6[5]; v[0] += in1[7] * lutt6[2]; v[0] += in1[6] * lutt6[3]; v[0] += in2[1] * lutt6[0]; v[0] += in2[0] * lutt6[1]; v[3] = in1[2] * lutt6[6]; v[3] += in1[5] * lutt6[7]; v[3] += in1[4] * lutt6[4]; v[3] += in1[7] * lutt6[5]; v[3] += in1[6] * lutt6[2]; v[3] += in2[1] * lutt6[3]; v[3] += in2[0] * lutt6[0]; v[3] += in2[3] * lutt6[1]; v[2] = in1[5] * lutt6[6]; v[2] += in1[4] * lutt6[7]; v[2] += in1[7] * lutt6[4]; v[2] += in1[6] * lutt6[5]; v[2] += in2[1] * lutt6[2]; v[2] += in2[0] * lutt6[3]; v[2] += in2[3] * lutt6[0]; v[2] += in2[2] * lutt6[1]; v[5] = in1[4] * lutt6[6]; v[5] += in1[7] * lutt6[7]; v[5] += in1[6] * lutt6[4]; v[5] += in2[1] * lutt6[5]; v[5] += in2[0] * lutt6[2]; v[5] += in2[3] * lutt6[3]; v[5] += in2[2] * lutt6[0]; v[5] += in2[5] * lutt6[1]; v[4] = in1[7] * lutt6[6]; v[4] += in1[6] * lutt6[7]; v[4] += in2[1] * lutt6[4]; v[4] += in2[0] * lutt6[5]; v[4] += in2[3] * lutt6[2]; v[4] += in2[2] * lutt6[3]; v[4] += in2[5] * lutt6[0]; v[4] += in2[4] * lutt6[1]; v[7] = in1[6] * lutt6[6]; v[7] += in2[1] * lutt6[7]; v[7] += in2[0] * lutt6[4]; v[7] += in2[3] * lutt6[5]; v[7] += in2[2] * lutt6[2]; v[7] += in2[5] * lutt6[3]; v[7] += in2[4] * lutt6[0]; v[7] += in2[7] * lutt6[1]; v[6] = in2[1] * lutt6[6]; v[6] += in2[0] * lutt6[7]; v[6] += in2[3] * lutt6[4]; v[6] += in2[2] * lutt6[5]; v[6] += in2[5] * lutt6[2]; v[6] += in2[4] * lutt6[3]; v[6] += in2[7] * lutt6[0]; v[6] += in2[6] * lutt6[1]; outp[1] = ((v[1] + 0x4000) >> 15); outp[0] = ((v[0] + 0x4000) >> 15); outp[3] = ((v[3] + 0x4000) >> 15); outp[2] = ((v[2] + 0x4000) >> 15); outp[5] = ((v[5] + 0x4000) >> 15); outp[4] = ((v[4] + 0x4000) >> 15); outp[7] = ((v[7] + 0x4000) >> 15); outp[6] = ((v[6] + 0x4000) >> 15); in1 = in2; in2 += 8; outp += 8; } memcpy(hle->dram + address, in2 - 8, 16); memcpy(hle->alist_buffer + dmem, outbuff, count); } void alist_polef( struct hle_t* hle, bool init, uint16_t dmemo, uint16_t dmemi, uint16_t count, uint16_t gain, int16_t* table, uint32_t address) { unsigned i; int16_t h2_before[8]; int16_t l1 = 0; int16_t l2 = 0; int16_t *dst = (int16_t*)(hle->alist_buffer + dmemo); const int16_t* const h1 = table; int16_t* const h2 = table + 8; count = align(count, 16); if (!init) { l1 = *dram_u16(hle, address + 4); l2 = *dram_u16(hle, address + 6); } for(i = 0; i < 8; ++i) { h2_before[i] = h2[i]; h2[i] = (((int32_t)h2[i] * gain) >> 14); } do { int16_t frame[8]; for(i = 0; i < 8; ++i, dmemi += 2) frame[i] = *alist_s16(hle, dmemi); for(i = 0; i < 8; ++i) { int32_t accu = frame[i] * gain; accu += h1[i]*l1 + h2_before[i]*l2 + rdot(i, h2, frame + i); dst[i^S] = clamp_s16(accu >> 14); } l1 = dst[6^S]; l2 = dst[7^S]; dst += 8; count -= 16; }while(count); dram_store_u16(hle, (uint16_t*)(dst - 4), address, 4); } void alist_iirf( struct hle_t* hle, bool init, uint16_t dmemo, uint16_t dmemi, uint16_t count, int16_t* table, uint32_t address) { int32_t i, prev; int16_t frame[8]; int16_t ibuf[4]; uint16_t index = 7; int16_t *dst = (int16_t*)(hle->alist_buffer + dmemo); count = align(count, 16); if(init) { for(i = 0; i < 8; ++i) frame[i] = 0; ibuf[1] = 0; ibuf[2] = 0; } else { frame[6] = *dram_u16(hle, address + 4); frame[7] = *dram_u16(hle, address + 6); ibuf[1] = (int16_t)*dram_u16(hle, address + 8); ibuf[2] = (int16_t)*dram_u16(hle, address + 10); } prev = vmulf(table[9], frame[6]) * 2; do { for(i = 0; i < 8; ++i) { int32_t accu; ibuf[index&3] = *alist_s16(hle, dmemi); accu = prev + vmulf(table[0], ibuf[index&3]) + vmulf(table[1], ibuf[(index-1)&3]) + vmulf(table[0], ibuf[(index-2)&3]); accu += vmulf(table[8], frame[index]) * 2; prev = vmulf(table[9], frame[index]) * 2; dst[i^S] = frame[i] = accu; index = (index+1)&7; dmemi += 2; } dst += 8; count -= 0x10; } while (count > 0); dram_store_u16(hle, (uint16_t*)&frame[6], address + 4, 4); dram_store_u16(hle, (uint16_t*)&ibuf[(index-2)&3], address+8, 2); dram_store_u16(hle, (uint16_t*)&ibuf[(index-1)&3], address+10, 2); } gles2n64/src/F3DEX2CBFD.c000664 001750 001750 00000010353 12655644434 015532 0ustar00sergiosergio000000 000000 #include "gles2N64.h" #include "Debug.h" #include "F3D.h" #include "F3DEX.h" #include "F3DEX2.h" #include "F3DEX2CBFD.h" #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gSP.h" #include "gDP.h" #include "GBI.h" #include "OpenGL.h" void F3DEX2CBFD_Vtx( u32 w0, u32 w1 ) { u32 n = _SHIFTR( w0, 12, 8 ); gSPCBFDVertex( w1, n, _SHIFTR( w0, 1, 7 ) - n ); } void F3DEX2CBFD_MoveWord( u32 w0, u32 w1 ) { switch (_SHIFTR( w0, 16, 8 )) { case G_MW_NUMLIGHT: gSPNumLights(w1 / 48); break; case G_MW_CLIP: gSPClipRatio( w1 ); break; case G_MW_SEGMENT: gSPSegment( _SHIFTR( w0, 0, 16 ) >> 2, w1 & 0x00FFFFFF ); break; case G_MW_FOG: gSPFogFactor( (s16)_SHIFTR( w1, 16, 16 ), (s16)_SHIFTR( w1, 0, 16 ) ); break; case G_MW_PERSPNORM: gSPPerspNormalize( w1 ); break; case G_MV_COORDMOD: gSPCoordMod( w0, w1 ); break; } } void F3DEX2CBFD_MoveMem( u32 w0, u32 w1 ) { switch (_SHIFTR( w0, 0, 8 )) { case F3DCBFD_MV_VIEWPORT: gSPViewport(w1); break; case F3DCBFD_MV_LIGHT: { const u32 offset = _SHIFTR(w0, 5, 14); u32 n = offset / 48; if (n < 2) gSPLookAt(w1, n); else gSPLightCBFD(w1, n - 2); } break; case G_MV_NORMALES: gSPSetVertexNormaleBase(w1); break; } } void F3DEX2CBFD_Tri4( u32 w0, u32 w1 ) { gSP4Triangles( _SHIFTR( w0, 23, 5 ), _SHIFTR( w0, 18, 5 ), (_SHIFTR( w0, 15, 3 )<<2)|_SHIFTR( w1, 30, 2 ), _SHIFTR( w0, 10, 5 ), _SHIFTR( w0, 5, 5 ), _SHIFTR( w0, 0, 5 ), _SHIFTR( w1, 25, 5 ), _SHIFTR( w1, 20, 5 ), _SHIFTR( w1, 15, 5 ), _SHIFTR( w1, 10, 5 ), _SHIFTR( w1, 5, 5 ), _SHIFTR( w1, 0, 5 ) ); } void F3DEX2CBFD_Init(void) { int i; gSPSetupFunctions(); // Set GeometryMode flags GBI_InitFlags(F3DEX2); GBI.PCStackSize = 18; // GBI Command Command Value Command Function GBI_SetGBI( G_RDPHALF_2, F3DEX2_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_SETOTHERMODE_H, F3DEX2_SETOTHERMODE_H, F3DEX2_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3DEX2_SETOTHERMODE_L, F3DEX2_SetOtherMode_L ); GBI_SetGBI( G_RDPHALF_1, F3DEX2_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_SPNOOP, F3DEX2_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_ENDDL, F3DEX2_ENDDL, F3D_EndDL ); GBI_SetGBI( G_DL, F3DEX2_DL, F3D_DList ); GBI_SetGBI( G_LOAD_UCODE, F3DEX2_LOAD_UCODE, F3DEX_Load_uCode ); GBI_SetGBI( G_MOVEMEM, F3DEX2_MOVEMEM, F3DEX2CBFD_MoveMem); GBI_SetGBI( G_MOVEWORD, F3DEX2_MOVEWORD, F3DEX2CBFD_MoveWord); GBI_SetGBI( G_MTX, F3DEX2_MTX, F3DEX2_Mtx ); GBI_SetGBI( G_GEOMETRYMODE, F3DEX2_GEOMETRYMODE, F3DEX2_GeometryMode ); GBI_SetGBI( G_POPMTX, F3DEX2_POPMTX, F3DEX2_PopMtx ); GBI_SetGBI( G_TEXTURE, F3DEX2_TEXTURE, F3DEX2_Texture ); GBI_SetGBI( G_DMA_IO, F3DEX2_DMA_IO, F3DEX2_DMAIO ); GBI_SetGBI( G_SPECIAL_1, F3DEX2_SPECIAL_1, F3DEX2_Special_1 ); GBI_SetGBI( G_SPECIAL_2, F3DEX2_SPECIAL_2, F3DEX2_Special_2 ); GBI_SetGBI( G_SPECIAL_3, F3DEX2_SPECIAL_3, F3DEX2_Special_3 ); GBI_SetGBI(G_VTX, F3DEX2_VTX, F3DEX2CBFD_Vtx); GBI_SetGBI(G_MODIFYVTX, F3DEX2_MODIFYVTX, F3DEX_ModifyVtx); GBI_SetGBI(G_CULLDL, F3DEX2_CULLDL, F3DEX_CullDL); GBI_SetGBI(G_BRANCH_Z, F3DEX2_BRANCH_Z, F3DEX_Branch_Z); GBI_SetGBI(G_TRI1, F3DEX2_TRI1, F3DEX2_Tri1); GBI_SetGBI(G_TRI2, F3DEX2_TRI2, F3DEX_Tri2); GBI_SetGBI(G_QUAD, F3DEX2_QUAD, F3DEX2_Quad); GBI_SetGBI( G_LINE3D, F3DEX2_LINE3D, F3DEX2_Line3D ); for(i = 0; i < 16; i++) GBI_SetGBI(G_TRI4, i, F3DEX2CBFD_Tri4); } gles2n64/src/F3DEX.h000664 001750 001750 00000003303 12655644434 015033 0ustar00sergiosergio000000 000000 #ifndef F3DEX_H #define F3DEX_H #ifdef __cplusplus extern "C" { #endif #define F3DEX_MTX_STACKSIZE 18 #define F3DEX_MTX_MODELVIEW 0x00 #define F3DEX_MTX_PROJECTION 0x01 #define F3DEX_MTX_MUL 0x00 #define F3DEX_MTX_LOAD 0x02 #define F3DEX_MTX_NOPUSH 0x00 #define F3DEX_MTX_PUSH 0x04 #define F3DEX_TEXTURE_ENABLE 0x00000002 #define F3DEX_SHADING_SMOOTH 0x00000200 #define F3DEX_CULL_FRONT 0x00001000 #define F3DEX_CULL_BACK 0x00002000 #define F3DEX_CULL_BOTH 0x00003000 #define F3DEX_CLIPPING 0x00800000 #define F3DEX_MV_VIEWPORT 0x80 #define F3DEX_MWO_aLIGHT_1 0x00 #define F3DEX_MWO_bLIGHT_1 0x04 #define F3DEX_MWO_aLIGHT_2 0x20 #define F3DEX_MWO_bLIGHT_2 0x24 #define F3DEX_MWO_aLIGHT_3 0x40 #define F3DEX_MWO_bLIGHT_3 0x44 #define F3DEX_MWO_aLIGHT_4 0x60 #define F3DEX_MWO_bLIGHT_4 0x64 #define F3DEX_MWO_aLIGHT_5 0x80 #define F3DEX_MWO_bLIGHT_5 0x84 #define F3DEX_MWO_aLIGHT_6 0xa0 #define F3DEX_MWO_bLIGHT_6 0xa4 #define F3DEX_MWO_aLIGHT_7 0xc0 #define F3DEX_MWO_bLIGHT_7 0xc4 #define F3DEX_MWO_aLIGHT_8 0xe0 #define F3DEX_MWO_bLIGHT_8 0xe4 // F3DEX commands #define F3DEX_MODIFYVTX 0xB2 #define F3DEX_TRI2 0xB1 #define F3DEX_BRANCH_Z 0xB0 #define F3DEX_LOAD_UCODE 0xAF // 0xCF void F3DEX_Vtx( u32 w0, u32 w1 ); void F3DEX_Tri1( u32 w0, u32 w1 ); void F3DEX_CullDL( u32 w0, u32 w1 ); void F3DEX_ModifyVtx( u32 w0, u32 w1 ); void F3DEX_Tri2( u32 w0, u32 w1 ); void F3DEX_Branch_Z( u32 w0, u32 w1 ); void F3DEX_Load_uCode( u32 w0, u32 w1 ); void F3DEX_Init(); #ifdef __cplusplus } #endif #endif mupen64plus-core/doc/font-license000664 001750 001750 00000004627 12655644434 020136 0ustar00sergiosergio000000 000000 Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera Sans Bitstream Vera Sans - Roman Release 1.10 Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.http://www.bitstream.com gles2n64/src/F3DEX.c000664 001750 001750 00000006771 12655644434 015042 0ustar00sergiosergio000000 000000 #include "gles2N64.h" #include "Debug.h" #include "F3D.h" #include "F3DEX.h" #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gSP.h" #include "gDP.h" #include "GBI.h" void F3DEX_Vtx( u32 w0, u32 w1 ) { gSPVertex( w1, _SHIFTR( w0, 10, 6 ), _SHIFTR( w0, 17, 7 ) ); } void F3DEX_Tri1( u32 w0, u32 w1 ) { gSP1Triangle( _SHIFTR( w1, 17, 7 ), _SHIFTR( w1, 9, 7 ), _SHIFTR( w1, 1, 7 )); } void F3DEX_CullDL( u32 w0, u32 w1 ) { gSPCullDisplayList( _SHIFTR( w0, 1, 15 ), _SHIFTR( w1, 1, 15 ) ); } void F3DEX_ModifyVtx( u32 w0, u32 w1 ) { gSPModifyVertex( _SHIFTR( w0, 1, 15 ), _SHIFTR( w0, 16, 8 ), w1 ); } void F3DEX_Tri2( u32 w0, u32 w1 ) { gSP2Triangles( _SHIFTR( w0, 17, 7 ), _SHIFTR( w0, 9, 7 ), _SHIFTR( w0, 1, 7 ), 0, _SHIFTR( w1, 17, 7 ), _SHIFTR( w1, 9, 7 ), _SHIFTR( w1, 1, 7 ), 0); } void F3DEX_Quad( u32 w0, u32 w1 ) { gSP1Quadrangle( _SHIFTR( w1, 25, 7 ), _SHIFTR( w1, 17, 7 ), _SHIFTR( w1, 9, 7 ), _SHIFTR( w1, 1, 7 ) ); } void F3DEX_Branch_Z( u32 w0, u32 w1 ) { gSPBranchLessZ( gDP.half_1, _SHIFTR( w0, 1, 11 ), (s32)w1 / 65535.0f / 1023.0f ); } void F3DEX_Load_uCode( u32 w0, u32 w1 ) { gSPLoadUcodeEx( w1, gDP.half_1, _SHIFTR( w0, 0, 16 ) + 1 ); } void F3DEX_Init(void) { gSPSetupFunctions(); // Set GeometryMode flags GBI_InitFlags( F3DEX ); GBI.PCStackSize = 18; // GBI Command Command Value Command Function GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_MTX, F3D_MTX, F3D_Mtx ); GBI_SetGBI( G_RESERVED0, F3D_RESERVED0, F3D_Reserved0 ); GBI_SetGBI( G_MOVEMEM, F3D_MOVEMEM, F3D_MoveMem ); GBI_SetGBI( G_VTX, F3D_VTX, F3DEX_Vtx ); GBI_SetGBI( G_RESERVED1, F3D_RESERVED1, F3D_Reserved1 ); GBI_SetGBI( G_DL, F3D_DL, F3D_DList ); GBI_SetGBI( G_RESERVED2, F3D_RESERVED2, F3D_Reserved2 ); GBI_SetGBI( G_RESERVED3, F3D_RESERVED3, F3D_Reserved3 ); GBI_SetGBI( G_SPRITE2D_BASE, F3D_SPRITE2D_BASE, F3D_Sprite2D_Base ); GBI_SetGBI( G_TRI1, F3D_TRI1, F3DEX_Tri1 ); GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3DEX_CullDL ); GBI_SetGBI( G_POPMTX, F3D_POPMTX, F3D_PopMtx ); GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3D_MoveWord ); GBI_SetGBI( G_TEXTURE, F3D_TEXTURE, F3D_Texture ); GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L ); GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL ); GBI_SetGBI( G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, F3D_SetGeometryMode ); GBI_SetGBI( G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE, F3D_ClearGeometryMode ); GBI_SetGBI( G_QUAD, F3D_QUAD, F3DEX_Quad ); GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_MODIFYVTX, F3DEX_MODIFYVTX, F3DEX_ModifyVtx ); GBI_SetGBI( G_TRI2, F3DEX_TRI2, F3DEX_Tri2 ); GBI_SetGBI( G_BRANCH_Z, F3DEX_BRANCH_Z, F3DEX_Branch_Z ); GBI_SetGBI( G_LOAD_UCODE, F3DEX_LOAD_UCODE, F3DEX_Load_uCode ); } mupen64plus-video-gliden64/src/GLideNHQ/TextureFilters_xbrz.h000664 001750 001750 00000011651 12655644434 025174 0ustar00sergiosergio000000 000000 // **************************************************************************** // * This file is part of the HqMAME project. It is distributed under * // * GNU General Public License: http://www.gnu.org/licenses/gpl-3.0 * // * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved * // * * // * Additionally and as a special exception, the author gives permission * // * to link the code of this program with the MAME library (or with modified * // * versions of MAME that use the same license as MAME), and distribute * // * linked combinations including the two. You must obey the GNU General * // * Public License in all respects for all of the code used other than MAME. * // * If you modify this file, you may extend this exception to your version * // * of the file, but you are not obligated to do so. If you do not wish to * // * do so, delete this exception statement from your version. * // **************************************************************************** // **************************************************************************** // Minor modifications for GLideN64 project by Sergey Lipskiy (gonetz AT ngs DOT ru) // Changes: color formats changed from RGB/ARGB to BGR/ABGR // added init() function. // ScalerCfg moved to this file // **************************************************************************** #ifndef XBRZ_HEADER_3847894708239054 #define XBRZ_HEADER_3847894708239054 #include //size_t #include //uint32_t #include namespace xbrz { /* ------------------------------------------------------------------------- | xBRZ: "Scale by rules" - high quality image upscaling filter by Zenju | ------------------------------------------------------------------------- using a modified approach of xBR: http://board.byuu.org/viewtopic.php?f=10&t=2248 - new rule set preserving small image features - highly optimized for performance - support alpha channel - support multithreading - support 64-bit architectures - support processing image slices - support scaling up to 6xBRZ */ struct ScalerCfg { double luminanceWeight = 1; double equalColorTolerance = 30; double dominantDirectionThreshold = 3.6; double steepDirectionThreshold = 2.2; double newTestAttribute = 0; //unused; test new parameters }; enum class ColorFormat //from high bits -> low bits, 8 bit per channel { ABGR, //including alpha channel BGR, //8 bit for each red, green, blue, upper 8 bits unused }; /* Initialization of static members to avoid #error function scope static initialization is not yet thread-safe! with my compiler. */ void init(); /* -> map source (srcWidth * srcHeight) to target (scale * width x scale * height) image, optionally processing a half-open slice of rows [yFirst, yLast) only -> support for source/target pitch in bytes! -> if your emulator changes only a few image slices during each cycle (e.g. DOSBox) then there's no need to run xBRZ on the complete image: Just make sure you enlarge the source image slice by 2 rows on top and 2 on bottom (this is the additional range the xBRZ algorithm is using during analysis) Caveat: If there are multiple changed slices, make sure they do not overlap after adding these additional rows in order to avoid a memory race condition in the target image data if you are using multiple threads for processing each enlarged slice! THREAD-SAFETY: - parts of the same image may be scaled by multiple threads as long as the [yFirst, yLast) ranges do not overlap! - there is a minor inefficiency for the first row of a slice, so avoid processing single rows only */ void scale(size_t factor, //valid range: 2 - 6 const uint32_t* src, uint32_t* trg, int srcWidth, int srcHeight, ColorFormat colFmt, const ScalerCfg& cfg = ScalerCfg(), int yFirst = 0, int yLast = INT_MAX); //slice of source image void nearestNeighborScale(const uint32_t* src, int srcWidth, int srcHeight, uint32_t* trg, int trgWidth, int trgHeight); enum SliceType { NN_SCALE_SLICE_SOURCE, NN_SCALE_SLICE_TARGET, }; void nearestNeighborScale(const uint32_t* src, int srcWidth, int srcHeight, int srcPitch, //pitch in bytes! uint32_t* trg, int trgWidth, int trgHeight, int trgPitch, SliceType st, int yFirst, int yLast); //parameter tuning bool equalColorTest(uint32_t col1, uint32_t col2, ColorFormat colFmt, double luminanceWeight, double equalColorTolerance); //########################### implementation ########################### inline void nearestNeighborScale(const uint32_t* src, int srcWidth, int srcHeight, uint32_t* trg, int trgWidth, int trgHeight) { nearestNeighborScale(src, srcWidth, srcHeight, srcWidth * sizeof(uint32_t), trg, trgWidth, trgHeight, trgWidth * sizeof(uint32_t), NN_SCALE_SLICE_TARGET, 0, trgHeight); } } #endif libretro/msvc/GL/glext.h000664 001750 001750 00002613651 12655644434 016325 0ustar00sergiosergio000000 000000 #ifndef __glext_h_ #define __glext_h_ #ifdef __cplusplus extern "C" { #endif /* ** Copyright (c) 2007-2012 The Khronos Group Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a ** copy of this software and/or associated documentation files (the ** "Materials"), to deal in the Materials without restriction, including ** without limitation the rights to use, copy, modify, merge, publish, ** distribute, sublicense, and/or sell copies of the Materials, and to ** permit persons to whom the Materials are furnished to do so, subject to ** the following conditions: ** ** The above copyright notice and this permission notice shall be included ** in all copies or substantial portions of the Materials. ** ** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. */ /* Header file version number, required by OpenGL ABI for Linux */ /* glext.h last updated $Date: 2012-09-19 19:02:24 -0700 (Wed, 19 Sep 2012) $ */ /* Current version at http://www.opengl.org/registry/ */ #define GL_GLEXT_VERSION 85 /* Function declaration macros - to move into glplatform.h */ #if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) #define WIN32_LEAN_AND_MEAN 1 #include #endif #ifndef APIENTRY #define APIENTRY #endif #ifndef APIENTRYP #define APIENTRYP APIENTRY * #endif #ifndef GLAPI #define GLAPI extern #endif /*************************************************************/ #ifndef GL_VERSION_1_2 #define GL_UNSIGNED_BYTE_3_3_2 0x8032 #define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 #define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 #define GL_UNSIGNED_INT_8_8_8_8 0x8035 #define GL_UNSIGNED_INT_10_10_10_2 0x8036 #define GL_TEXTURE_BINDING_3D 0x806A #define GL_PACK_SKIP_IMAGES 0x806B #define GL_PACK_IMAGE_HEIGHT 0x806C #define GL_UNPACK_SKIP_IMAGES 0x806D #define GL_UNPACK_IMAGE_HEIGHT 0x806E #define GL_TEXTURE_3D 0x806F #define GL_PROXY_TEXTURE_3D 0x8070 #define GL_TEXTURE_DEPTH 0x8071 #define GL_TEXTURE_WRAP_R 0x8072 #define GL_MAX_3D_TEXTURE_SIZE 0x8073 #define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 #define GL_UNSIGNED_SHORT_5_6_5 0x8363 #define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 #define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 #define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 #define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 #define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 #define GL_BGR 0x80E0 #define GL_BGRA 0x80E1 #define GL_MAX_ELEMENTS_VERTICES 0x80E8 #define GL_MAX_ELEMENTS_INDICES 0x80E9 #define GL_CLAMP_TO_EDGE 0x812F #define GL_TEXTURE_MIN_LOD 0x813A #define GL_TEXTURE_MAX_LOD 0x813B #define GL_TEXTURE_BASE_LEVEL 0x813C #define GL_TEXTURE_MAX_LEVEL 0x813D #define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 #define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 #define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 #define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 #define GL_ALIASED_LINE_WIDTH_RANGE 0x846E #define GL_RESCALE_NORMAL 0x803A #define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 #define GL_SINGLE_COLOR 0x81F9 #define GL_SEPARATE_SPECULAR_COLOR 0x81FA #define GL_ALIASED_POINT_SIZE_RANGE 0x846D #endif #ifndef GL_ARB_imaging #define GL_CONSTANT_COLOR 0x8001 #define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 #define GL_CONSTANT_ALPHA 0x8003 #define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 #define GL_BLEND_COLOR 0x8005 #define GL_FUNC_ADD 0x8006 #define GL_MIN 0x8007 #define GL_MAX 0x8008 #define GL_BLEND_EQUATION 0x8009 #define GL_FUNC_SUBTRACT 0x800A #define GL_FUNC_REVERSE_SUBTRACT 0x800B #define GL_CONVOLUTION_1D 0x8010 #define GL_CONVOLUTION_2D 0x8011 #define GL_SEPARABLE_2D 0x8012 #define GL_CONVOLUTION_BORDER_MODE 0x8013 #define GL_CONVOLUTION_FILTER_SCALE 0x8014 #define GL_CONVOLUTION_FILTER_BIAS 0x8015 #define GL_REDUCE 0x8016 #define GL_CONVOLUTION_FORMAT 0x8017 #define GL_CONVOLUTION_WIDTH 0x8018 #define GL_CONVOLUTION_HEIGHT 0x8019 #define GL_MAX_CONVOLUTION_WIDTH 0x801A #define GL_MAX_CONVOLUTION_HEIGHT 0x801B #define GL_POST_CONVOLUTION_RED_SCALE 0x801C #define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D #define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E #define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F #define GL_POST_CONVOLUTION_RED_BIAS 0x8020 #define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 #define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 #define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 #define GL_HISTOGRAM 0x8024 #define GL_PROXY_HISTOGRAM 0x8025 #define GL_HISTOGRAM_WIDTH 0x8026 #define GL_HISTOGRAM_FORMAT 0x8027 #define GL_HISTOGRAM_RED_SIZE 0x8028 #define GL_HISTOGRAM_GREEN_SIZE 0x8029 #define GL_HISTOGRAM_BLUE_SIZE 0x802A #define GL_HISTOGRAM_ALPHA_SIZE 0x802B #define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C #define GL_HISTOGRAM_SINK 0x802D #define GL_MINMAX 0x802E #define GL_MINMAX_FORMAT 0x802F #define GL_MINMAX_SINK 0x8030 #define GL_TABLE_TOO_LARGE 0x8031 #define GL_COLOR_MATRIX 0x80B1 #define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 #define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 #define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 #define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 #define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 #define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 #define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 #define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 #define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA #define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB #define GL_COLOR_TABLE 0x80D0 #define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 #define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 #define GL_PROXY_COLOR_TABLE 0x80D3 #define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 #define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 #define GL_COLOR_TABLE_SCALE 0x80D6 #define GL_COLOR_TABLE_BIAS 0x80D7 #define GL_COLOR_TABLE_FORMAT 0x80D8 #define GL_COLOR_TABLE_WIDTH 0x80D9 #define GL_COLOR_TABLE_RED_SIZE 0x80DA #define GL_COLOR_TABLE_GREEN_SIZE 0x80DB #define GL_COLOR_TABLE_BLUE_SIZE 0x80DC #define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD #define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE #define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF #define GL_CONSTANT_BORDER 0x8151 #define GL_REPLICATE_BORDER 0x8153 #define GL_CONVOLUTION_BORDER_COLOR 0x8154 #endif #ifndef GL_VERSION_1_3 #define GL_TEXTURE0 0x84C0 #define GL_TEXTURE1 0x84C1 #define GL_TEXTURE2 0x84C2 #define GL_TEXTURE3 0x84C3 #define GL_TEXTURE4 0x84C4 #define GL_TEXTURE5 0x84C5 #define GL_TEXTURE6 0x84C6 #define GL_TEXTURE7 0x84C7 #define GL_TEXTURE8 0x84C8 #define GL_TEXTURE9 0x84C9 #define GL_TEXTURE10 0x84CA #define GL_TEXTURE11 0x84CB #define GL_TEXTURE12 0x84CC #define GL_TEXTURE13 0x84CD #define GL_TEXTURE14 0x84CE #define GL_TEXTURE15 0x84CF #define GL_TEXTURE16 0x84D0 #define GL_TEXTURE17 0x84D1 #define GL_TEXTURE18 0x84D2 #define GL_TEXTURE19 0x84D3 #define GL_TEXTURE20 0x84D4 #define GL_TEXTURE21 0x84D5 #define GL_TEXTURE22 0x84D6 #define GL_TEXTURE23 0x84D7 #define GL_TEXTURE24 0x84D8 #define GL_TEXTURE25 0x84D9 #define GL_TEXTURE26 0x84DA #define GL_TEXTURE27 0x84DB #define GL_TEXTURE28 0x84DC #define GL_TEXTURE29 0x84DD #define GL_TEXTURE30 0x84DE #define GL_TEXTURE31 0x84DF #define GL_ACTIVE_TEXTURE 0x84E0 #define GL_MULTISAMPLE 0x809D #define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E #define GL_SAMPLE_ALPHA_TO_ONE 0x809F #define GL_SAMPLE_COVERAGE 0x80A0 #define GL_SAMPLE_BUFFERS 0x80A8 #define GL_SAMPLES 0x80A9 #define GL_SAMPLE_COVERAGE_VALUE 0x80AA #define GL_SAMPLE_COVERAGE_INVERT 0x80AB #define GL_TEXTURE_CUBE_MAP 0x8513 #define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 #define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A #define GL_PROXY_TEXTURE_CUBE_MAP 0x851B #define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C #define GL_COMPRESSED_RGB 0x84ED #define GL_COMPRESSED_RGBA 0x84EE #define GL_TEXTURE_COMPRESSION_HINT 0x84EF #define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 #define GL_TEXTURE_COMPRESSED 0x86A1 #define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 #define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 #define GL_CLAMP_TO_BORDER 0x812D #define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 #define GL_MAX_TEXTURE_UNITS 0x84E2 #define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 #define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 #define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 #define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 #define GL_MULTISAMPLE_BIT 0x20000000 #define GL_NORMAL_MAP 0x8511 #define GL_REFLECTION_MAP 0x8512 #define GL_COMPRESSED_ALPHA 0x84E9 #define GL_COMPRESSED_LUMINANCE 0x84EA #define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB #define GL_COMPRESSED_INTENSITY 0x84EC #define GL_COMBINE 0x8570 #define GL_COMBINE_RGB 0x8571 #define GL_COMBINE_ALPHA 0x8572 #define GL_SOURCE0_RGB 0x8580 #define GL_SOURCE1_RGB 0x8581 #define GL_SOURCE2_RGB 0x8582 #define GL_SOURCE0_ALPHA 0x8588 #define GL_SOURCE1_ALPHA 0x8589 #define GL_SOURCE2_ALPHA 0x858A #define GL_OPERAND0_RGB 0x8590 #define GL_OPERAND1_RGB 0x8591 #define GL_OPERAND2_RGB 0x8592 #define GL_OPERAND0_ALPHA 0x8598 #define GL_OPERAND1_ALPHA 0x8599 #define GL_OPERAND2_ALPHA 0x859A #define GL_RGB_SCALE 0x8573 #define GL_ADD_SIGNED 0x8574 #define GL_INTERPOLATE 0x8575 #define GL_SUBTRACT 0x84E7 #define GL_CONSTANT 0x8576 #define GL_PRIMARY_COLOR 0x8577 #define GL_PREVIOUS 0x8578 #define GL_DOT3_RGB 0x86AE #define GL_DOT3_RGBA 0x86AF #endif #ifndef GL_VERSION_1_4 #define GL_BLEND_DST_RGB 0x80C8 #define GL_BLEND_SRC_RGB 0x80C9 #define GL_BLEND_DST_ALPHA 0x80CA #define GL_BLEND_SRC_ALPHA 0x80CB #define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 #define GL_DEPTH_COMPONENT16 0x81A5 #define GL_DEPTH_COMPONENT24 0x81A6 #define GL_DEPTH_COMPONENT32 0x81A7 #define GL_MIRRORED_REPEAT 0x8370 #define GL_MAX_TEXTURE_LOD_BIAS 0x84FD #define GL_TEXTURE_LOD_BIAS 0x8501 #define GL_INCR_WRAP 0x8507 #define GL_DECR_WRAP 0x8508 #define GL_TEXTURE_DEPTH_SIZE 0x884A #define GL_TEXTURE_COMPARE_MODE 0x884C #define GL_TEXTURE_COMPARE_FUNC 0x884D #define GL_POINT_SIZE_MIN 0x8126 #define GL_POINT_SIZE_MAX 0x8127 #define GL_POINT_DISTANCE_ATTENUATION 0x8129 #define GL_GENERATE_MIPMAP 0x8191 #define GL_GENERATE_MIPMAP_HINT 0x8192 #define GL_FOG_COORDINATE_SOURCE 0x8450 #define GL_FOG_COORDINATE 0x8451 #define GL_FRAGMENT_DEPTH 0x8452 #define GL_CURRENT_FOG_COORDINATE 0x8453 #define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 #define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 #define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 #define GL_FOG_COORDINATE_ARRAY 0x8457 #define GL_COLOR_SUM 0x8458 #define GL_CURRENT_SECONDARY_COLOR 0x8459 #define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A #define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B #define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C #define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D #define GL_SECONDARY_COLOR_ARRAY 0x845E #define GL_TEXTURE_FILTER_CONTROL 0x8500 #define GL_DEPTH_TEXTURE_MODE 0x884B #define GL_COMPARE_R_TO_TEXTURE 0x884E #endif #ifndef GL_VERSION_1_5 #define GL_BUFFER_SIZE 0x8764 #define GL_BUFFER_USAGE 0x8765 #define GL_QUERY_COUNTER_BITS 0x8864 #define GL_CURRENT_QUERY 0x8865 #define GL_QUERY_RESULT 0x8866 #define GL_QUERY_RESULT_AVAILABLE 0x8867 #define GL_ARRAY_BUFFER 0x8892 #define GL_ELEMENT_ARRAY_BUFFER 0x8893 #define GL_ARRAY_BUFFER_BINDING 0x8894 #define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 #define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F #define GL_READ_ONLY 0x88B8 #define GL_WRITE_ONLY 0x88B9 #define GL_READ_WRITE 0x88BA #define GL_BUFFER_ACCESS 0x88BB #define GL_BUFFER_MAPPED 0x88BC #define GL_BUFFER_MAP_POINTER 0x88BD #define GL_STREAM_DRAW 0x88E0 #define GL_STREAM_READ 0x88E1 #define GL_STREAM_COPY 0x88E2 #define GL_STATIC_DRAW 0x88E4 #define GL_STATIC_READ 0x88E5 #define GL_STATIC_COPY 0x88E6 #define GL_DYNAMIC_DRAW 0x88E8 #define GL_DYNAMIC_READ 0x88E9 #define GL_DYNAMIC_COPY 0x88EA #define GL_SAMPLES_PASSED 0x8914 #define GL_SRC1_ALPHA 0x8589 #define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 #define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 #define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 #define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 #define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A #define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B #define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C #define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D #define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E #define GL_FOG_COORD_SRC 0x8450 #define GL_FOG_COORD 0x8451 #define GL_CURRENT_FOG_COORD 0x8453 #define GL_FOG_COORD_ARRAY_TYPE 0x8454 #define GL_FOG_COORD_ARRAY_STRIDE 0x8455 #define GL_FOG_COORD_ARRAY_POINTER 0x8456 #define GL_FOG_COORD_ARRAY 0x8457 #define GL_FOG_COORD_ARRAY_BUFFER_BINDING 0x889D #define GL_SRC0_RGB 0x8580 #define GL_SRC1_RGB 0x8581 #define GL_SRC2_RGB 0x8582 #define GL_SRC0_ALPHA 0x8588 #define GL_SRC2_ALPHA 0x858A #endif #ifndef GL_VERSION_2_0 #define GL_BLEND_EQUATION_RGB 0x8009 #define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 #define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 #define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 #define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 #define GL_CURRENT_VERTEX_ATTRIB 0x8626 #define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 #define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 #define GL_STENCIL_BACK_FUNC 0x8800 #define GL_STENCIL_BACK_FAIL 0x8801 #define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 #define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 #define GL_MAX_DRAW_BUFFERS 0x8824 #define GL_DRAW_BUFFER0 0x8825 #define GL_DRAW_BUFFER1 0x8826 #define GL_DRAW_BUFFER2 0x8827 #define GL_DRAW_BUFFER3 0x8828 #define GL_DRAW_BUFFER4 0x8829 #define GL_DRAW_BUFFER5 0x882A #define GL_DRAW_BUFFER6 0x882B #define GL_DRAW_BUFFER7 0x882C #define GL_DRAW_BUFFER8 0x882D #define GL_DRAW_BUFFER9 0x882E #define GL_DRAW_BUFFER10 0x882F #define GL_DRAW_BUFFER11 0x8830 #define GL_DRAW_BUFFER12 0x8831 #define GL_DRAW_BUFFER13 0x8832 #define GL_DRAW_BUFFER14 0x8833 #define GL_DRAW_BUFFER15 0x8834 #define GL_BLEND_EQUATION_ALPHA 0x883D #define GL_MAX_VERTEX_ATTRIBS 0x8869 #define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A #define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 #define GL_FRAGMENT_SHADER 0x8B30 #define GL_VERTEX_SHADER 0x8B31 #define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 #define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A #define GL_MAX_VARYING_FLOATS 0x8B4B #define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C #define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D #define GL_SHADER_TYPE 0x8B4F #define GL_FLOAT_VEC2 0x8B50 #define GL_FLOAT_VEC3 0x8B51 #define GL_FLOAT_VEC4 0x8B52 #define GL_INT_VEC2 0x8B53 #define GL_INT_VEC3 0x8B54 #define GL_INT_VEC4 0x8B55 #define GL_BOOL 0x8B56 #define GL_BOOL_VEC2 0x8B57 #define GL_BOOL_VEC3 0x8B58 #define GL_BOOL_VEC4 0x8B59 #define GL_FLOAT_MAT2 0x8B5A #define GL_FLOAT_MAT3 0x8B5B #define GL_FLOAT_MAT4 0x8B5C #define GL_SAMPLER_1D 0x8B5D #define GL_SAMPLER_2D 0x8B5E #define GL_SAMPLER_3D 0x8B5F #define GL_SAMPLER_CUBE 0x8B60 #define GL_SAMPLER_1D_SHADOW 0x8B61 #define GL_SAMPLER_2D_SHADOW 0x8B62 #define GL_DELETE_STATUS 0x8B80 #define GL_COMPILE_STATUS 0x8B81 #define GL_LINK_STATUS 0x8B82 #define GL_VALIDATE_STATUS 0x8B83 #define GL_INFO_LOG_LENGTH 0x8B84 #define GL_ATTACHED_SHADERS 0x8B85 #define GL_ACTIVE_UNIFORMS 0x8B86 #define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 #define GL_SHADER_SOURCE_LENGTH 0x8B88 #define GL_ACTIVE_ATTRIBUTES 0x8B89 #define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A #define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B #define GL_SHADING_LANGUAGE_VERSION 0x8B8C #define GL_CURRENT_PROGRAM 0x8B8D #define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 #define GL_LOWER_LEFT 0x8CA1 #define GL_UPPER_LEFT 0x8CA2 #define GL_STENCIL_BACK_REF 0x8CA3 #define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 #define GL_STENCIL_BACK_WRITEMASK 0x8CA5 #define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 #define GL_POINT_SPRITE 0x8861 #define GL_COORD_REPLACE 0x8862 #define GL_MAX_TEXTURE_COORDS 0x8871 #endif #ifndef GL_VERSION_2_1 #define GL_PIXEL_PACK_BUFFER 0x88EB #define GL_PIXEL_UNPACK_BUFFER 0x88EC #define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED #define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF #define GL_FLOAT_MAT2x3 0x8B65 #define GL_FLOAT_MAT2x4 0x8B66 #define GL_FLOAT_MAT3x2 0x8B67 #define GL_FLOAT_MAT3x4 0x8B68 #define GL_FLOAT_MAT4x2 0x8B69 #define GL_FLOAT_MAT4x3 0x8B6A #define GL_SRGB 0x8C40 #define GL_SRGB8 0x8C41 #define GL_SRGB_ALPHA 0x8C42 #define GL_SRGB8_ALPHA8 0x8C43 #define GL_COMPRESSED_SRGB 0x8C48 #define GL_COMPRESSED_SRGB_ALPHA 0x8C49 #define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F #define GL_SLUMINANCE_ALPHA 0x8C44 #define GL_SLUMINANCE8_ALPHA8 0x8C45 #define GL_SLUMINANCE 0x8C46 #define GL_SLUMINANCE8 0x8C47 #define GL_COMPRESSED_SLUMINANCE 0x8C4A #define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B #endif #ifndef GL_VERSION_3_0 #define GL_COMPARE_REF_TO_TEXTURE 0x884E #define GL_CLIP_DISTANCE0 0x3000 #define GL_CLIP_DISTANCE1 0x3001 #define GL_CLIP_DISTANCE2 0x3002 #define GL_CLIP_DISTANCE3 0x3003 #define GL_CLIP_DISTANCE4 0x3004 #define GL_CLIP_DISTANCE5 0x3005 #define GL_CLIP_DISTANCE6 0x3006 #define GL_CLIP_DISTANCE7 0x3007 #define GL_MAX_CLIP_DISTANCES 0x0D32 #define GL_MAJOR_VERSION 0x821B #define GL_MINOR_VERSION 0x821C #define GL_NUM_EXTENSIONS 0x821D #define GL_CONTEXT_FLAGS 0x821E #define GL_COMPRESSED_RED 0x8225 #define GL_COMPRESSED_RG 0x8226 #define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001 #define GL_RGBA32F 0x8814 #define GL_RGB32F 0x8815 #define GL_RGBA16F 0x881A #define GL_RGB16F 0x881B #define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD #define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF #define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 #define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 #define GL_CLAMP_READ_COLOR 0x891C #define GL_FIXED_ONLY 0x891D #define GL_MAX_VARYING_COMPONENTS 0x8B4B #define GL_TEXTURE_1D_ARRAY 0x8C18 #define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 #define GL_TEXTURE_2D_ARRAY 0x8C1A #define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B #define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C #define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D #define GL_R11F_G11F_B10F 0x8C3A #define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B #define GL_RGB9_E5 0x8C3D #define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E #define GL_TEXTURE_SHARED_SIZE 0x8C3F #define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 #define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F #define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 #define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 #define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 #define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 #define GL_PRIMITIVES_GENERATED 0x8C87 #define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 #define GL_RASTERIZER_DISCARD 0x8C89 #define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A #define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B #define GL_INTERLEAVED_ATTRIBS 0x8C8C #define GL_SEPARATE_ATTRIBS 0x8C8D #define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E #define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F #define GL_RGBA32UI 0x8D70 #define GL_RGB32UI 0x8D71 #define GL_RGBA16UI 0x8D76 #define GL_RGB16UI 0x8D77 #define GL_RGBA8UI 0x8D7C #define GL_RGB8UI 0x8D7D #define GL_RGBA32I 0x8D82 #define GL_RGB32I 0x8D83 #define GL_RGBA16I 0x8D88 #define GL_RGB16I 0x8D89 #define GL_RGBA8I 0x8D8E #define GL_RGB8I 0x8D8F #define GL_RED_INTEGER 0x8D94 #define GL_GREEN_INTEGER 0x8D95 #define GL_BLUE_INTEGER 0x8D96 #define GL_RGB_INTEGER 0x8D98 #define GL_RGBA_INTEGER 0x8D99 #define GL_BGR_INTEGER 0x8D9A #define GL_BGRA_INTEGER 0x8D9B #define GL_SAMPLER_1D_ARRAY 0x8DC0 #define GL_SAMPLER_2D_ARRAY 0x8DC1 #define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 #define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 #define GL_SAMPLER_CUBE_SHADOW 0x8DC5 #define GL_UNSIGNED_INT_VEC2 0x8DC6 #define GL_UNSIGNED_INT_VEC3 0x8DC7 #define GL_UNSIGNED_INT_VEC4 0x8DC8 #define GL_INT_SAMPLER_1D 0x8DC9 #define GL_INT_SAMPLER_2D 0x8DCA #define GL_INT_SAMPLER_3D 0x8DCB #define GL_INT_SAMPLER_CUBE 0x8DCC #define GL_INT_SAMPLER_1D_ARRAY 0x8DCE #define GL_INT_SAMPLER_2D_ARRAY 0x8DCF #define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 #define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 #define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 #define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 #define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 #define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 #define GL_QUERY_WAIT 0x8E13 #define GL_QUERY_NO_WAIT 0x8E14 #define GL_QUERY_BY_REGION_WAIT 0x8E15 #define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 #define GL_BUFFER_ACCESS_FLAGS 0x911F #define GL_BUFFER_MAP_LENGTH 0x9120 #define GL_BUFFER_MAP_OFFSET 0x9121 /* Reuse tokens from ARB_depth_buffer_float */ /* reuse GL_DEPTH_COMPONENT32F */ /* reuse GL_DEPTH32F_STENCIL8 */ /* reuse GL_FLOAT_32_UNSIGNED_INT_24_8_REV */ /* Reuse tokens from ARB_framebuffer_object */ /* reuse GL_INVALID_FRAMEBUFFER_OPERATION */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE */ /* reuse GL_FRAMEBUFFER_DEFAULT */ /* reuse GL_FRAMEBUFFER_UNDEFINED */ /* reuse GL_DEPTH_STENCIL_ATTACHMENT */ /* reuse GL_INDEX */ /* reuse GL_MAX_RENDERBUFFER_SIZE */ /* reuse GL_DEPTH_STENCIL */ /* reuse GL_UNSIGNED_INT_24_8 */ /* reuse GL_DEPTH24_STENCIL8 */ /* reuse GL_TEXTURE_STENCIL_SIZE */ /* reuse GL_TEXTURE_RED_TYPE */ /* reuse GL_TEXTURE_GREEN_TYPE */ /* reuse GL_TEXTURE_BLUE_TYPE */ /* reuse GL_TEXTURE_ALPHA_TYPE */ /* reuse GL_TEXTURE_DEPTH_TYPE */ /* reuse GL_UNSIGNED_NORMALIZED */ /* reuse GL_FRAMEBUFFER_BINDING */ /* reuse GL_DRAW_FRAMEBUFFER_BINDING */ /* reuse GL_RENDERBUFFER_BINDING */ /* reuse GL_READ_FRAMEBUFFER */ /* reuse GL_DRAW_FRAMEBUFFER */ /* reuse GL_READ_FRAMEBUFFER_BINDING */ /* reuse GL_RENDERBUFFER_SAMPLES */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */ /* reuse GL_FRAMEBUFFER_COMPLETE */ /* reuse GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT */ /* reuse GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT */ /* reuse GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER */ /* reuse GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER */ /* reuse GL_FRAMEBUFFER_UNSUPPORTED */ /* reuse GL_MAX_COLOR_ATTACHMENTS */ /* reuse GL_COLOR_ATTACHMENT0 */ /* reuse GL_COLOR_ATTACHMENT1 */ /* reuse GL_COLOR_ATTACHMENT2 */ /* reuse GL_COLOR_ATTACHMENT3 */ /* reuse GL_COLOR_ATTACHMENT4 */ /* reuse GL_COLOR_ATTACHMENT5 */ /* reuse GL_COLOR_ATTACHMENT6 */ /* reuse GL_COLOR_ATTACHMENT7 */ /* reuse GL_COLOR_ATTACHMENT8 */ /* reuse GL_COLOR_ATTACHMENT9 */ /* reuse GL_COLOR_ATTACHMENT10 */ /* reuse GL_COLOR_ATTACHMENT11 */ /* reuse GL_COLOR_ATTACHMENT12 */ /* reuse GL_COLOR_ATTACHMENT13 */ /* reuse GL_COLOR_ATTACHMENT14 */ /* reuse GL_COLOR_ATTACHMENT15 */ /* reuse GL_DEPTH_ATTACHMENT */ /* reuse GL_STENCIL_ATTACHMENT */ /* reuse GL_FRAMEBUFFER */ /* reuse GL_RENDERBUFFER */ /* reuse GL_RENDERBUFFER_WIDTH */ /* reuse GL_RENDERBUFFER_HEIGHT */ /* reuse GL_RENDERBUFFER_INTERNAL_FORMAT */ /* reuse GL_STENCIL_INDEX1 */ /* reuse GL_STENCIL_INDEX4 */ /* reuse GL_STENCIL_INDEX8 */ /* reuse GL_STENCIL_INDEX16 */ /* reuse GL_RENDERBUFFER_RED_SIZE */ /* reuse GL_RENDERBUFFER_GREEN_SIZE */ /* reuse GL_RENDERBUFFER_BLUE_SIZE */ /* reuse GL_RENDERBUFFER_ALPHA_SIZE */ /* reuse GL_RENDERBUFFER_DEPTH_SIZE */ /* reuse GL_RENDERBUFFER_STENCIL_SIZE */ /* reuse GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE */ /* reuse GL_MAX_SAMPLES */ /* Reuse tokens from ARB_framebuffer_sRGB */ /* reuse GL_FRAMEBUFFER_SRGB */ /* Reuse tokens from ARB_half_float_vertex */ /* reuse GL_HALF_FLOAT */ /* Reuse tokens from ARB_map_buffer_range */ /* reuse GL_MAP_READ_BIT */ /* reuse GL_MAP_WRITE_BIT */ /* reuse GL_MAP_INVALIDATE_RANGE_BIT */ /* reuse GL_MAP_INVALIDATE_BUFFER_BIT */ /* reuse GL_MAP_FLUSH_EXPLICIT_BIT */ /* reuse GL_MAP_UNSYNCHRONIZED_BIT */ /* Reuse tokens from ARB_texture_compression_rgtc */ /* reuse GL_COMPRESSED_RED_RGTC1 */ /* reuse GL_COMPRESSED_SIGNED_RED_RGTC1 */ /* reuse GL_COMPRESSED_RG_RGTC2 */ /* reuse GL_COMPRESSED_SIGNED_RG_RGTC2 */ /* Reuse tokens from ARB_texture_rg */ /* reuse GL_RG */ /* reuse GL_RG_INTEGER */ /* reuse GL_R8 */ /* reuse GL_R16 */ /* reuse GL_RG8 */ /* reuse GL_RG16 */ /* reuse GL_R16F */ /* reuse GL_R32F */ /* reuse GL_RG16F */ /* reuse GL_RG32F */ /* reuse GL_R8I */ /* reuse GL_R8UI */ /* reuse GL_R16I */ /* reuse GL_R16UI */ /* reuse GL_R32I */ /* reuse GL_R32UI */ /* reuse GL_RG8I */ /* reuse GL_RG8UI */ /* reuse GL_RG16I */ /* reuse GL_RG16UI */ /* reuse GL_RG32I */ /* reuse GL_RG32UI */ /* Reuse tokens from ARB_vertex_array_object */ /* reuse GL_VERTEX_ARRAY_BINDING */ #define GL_CLAMP_VERTEX_COLOR 0x891A #define GL_CLAMP_FRAGMENT_COLOR 0x891B #define GL_ALPHA_INTEGER 0x8D97 /* Reuse tokens from ARB_framebuffer_object */ /* reuse GL_TEXTURE_LUMINANCE_TYPE */ /* reuse GL_TEXTURE_INTENSITY_TYPE */ #endif #ifndef GL_VERSION_3_1 #define GL_SAMPLER_2D_RECT 0x8B63 #define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 #define GL_SAMPLER_BUFFER 0x8DC2 #define GL_INT_SAMPLER_2D_RECT 0x8DCD #define GL_INT_SAMPLER_BUFFER 0x8DD0 #define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 #define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 #define GL_TEXTURE_BUFFER 0x8C2A #define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B #define GL_TEXTURE_BINDING_BUFFER 0x8C2C #define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D #define GL_TEXTURE_RECTANGLE 0x84F5 #define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 #define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 #define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 #define GL_RED_SNORM 0x8F90 #define GL_RG_SNORM 0x8F91 #define GL_RGB_SNORM 0x8F92 #define GL_RGBA_SNORM 0x8F93 #define GL_R8_SNORM 0x8F94 #define GL_RG8_SNORM 0x8F95 #define GL_RGB8_SNORM 0x8F96 #define GL_RGBA8_SNORM 0x8F97 #define GL_R16_SNORM 0x8F98 #define GL_RG16_SNORM 0x8F99 #define GL_RGB16_SNORM 0x8F9A #define GL_RGBA16_SNORM 0x8F9B #define GL_SIGNED_NORMALIZED 0x8F9C #define GL_PRIMITIVE_RESTART 0x8F9D #define GL_PRIMITIVE_RESTART_INDEX 0x8F9E /* Reuse tokens from ARB_copy_buffer */ /* reuse GL_COPY_READ_BUFFER */ /* reuse GL_COPY_WRITE_BUFFER */ /* Reuse tokens from ARB_draw_instanced (none) */ /* Reuse tokens from ARB_uniform_buffer_object */ /* reuse GL_UNIFORM_BUFFER */ /* reuse GL_UNIFORM_BUFFER_BINDING */ /* reuse GL_UNIFORM_BUFFER_START */ /* reuse GL_UNIFORM_BUFFER_SIZE */ /* reuse GL_MAX_VERTEX_UNIFORM_BLOCKS */ /* reuse GL_MAX_FRAGMENT_UNIFORM_BLOCKS */ /* reuse GL_MAX_COMBINED_UNIFORM_BLOCKS */ /* reuse GL_MAX_UNIFORM_BUFFER_BINDINGS */ /* reuse GL_MAX_UNIFORM_BLOCK_SIZE */ /* reuse GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS */ /* reuse GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS */ /* reuse GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT */ /* reuse GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH */ /* reuse GL_ACTIVE_UNIFORM_BLOCKS */ /* reuse GL_UNIFORM_TYPE */ /* reuse GL_UNIFORM_SIZE */ /* reuse GL_UNIFORM_NAME_LENGTH */ /* reuse GL_UNIFORM_BLOCK_INDEX */ /* reuse GL_UNIFORM_OFFSET */ /* reuse GL_UNIFORM_ARRAY_STRIDE */ /* reuse GL_UNIFORM_MATRIX_STRIDE */ /* reuse GL_UNIFORM_IS_ROW_MAJOR */ /* reuse GL_UNIFORM_BLOCK_BINDING */ /* reuse GL_UNIFORM_BLOCK_DATA_SIZE */ /* reuse GL_UNIFORM_BLOCK_NAME_LENGTH */ /* reuse GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS */ /* reuse GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES */ /* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER */ /* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER */ /* reuse GL_INVALID_INDEX */ #endif #ifndef GL_VERSION_3_2 #define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 #define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 #define GL_LINES_ADJACENCY 0x000A #define GL_LINE_STRIP_ADJACENCY 0x000B #define GL_TRIANGLES_ADJACENCY 0x000C #define GL_TRIANGLE_STRIP_ADJACENCY 0x000D #define GL_PROGRAM_POINT_SIZE 0x8642 #define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 #define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 #define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 #define GL_GEOMETRY_SHADER 0x8DD9 #define GL_GEOMETRY_VERTICES_OUT 0x8916 #define GL_GEOMETRY_INPUT_TYPE 0x8917 #define GL_GEOMETRY_OUTPUT_TYPE 0x8918 #define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF #define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 #define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 #define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 #define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 #define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 #define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 #define GL_CONTEXT_PROFILE_MASK 0x9126 /* reuse GL_MAX_VARYING_COMPONENTS */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */ /* Reuse tokens from ARB_depth_clamp */ /* reuse GL_DEPTH_CLAMP */ /* Reuse tokens from ARB_draw_elements_base_vertex (none) */ /* Reuse tokens from ARB_fragment_coord_conventions (none) */ /* Reuse tokens from ARB_provoking_vertex */ /* reuse GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION */ /* reuse GL_FIRST_VERTEX_CONVENTION */ /* reuse GL_LAST_VERTEX_CONVENTION */ /* reuse GL_PROVOKING_VERTEX */ /* Reuse tokens from ARB_seamless_cube_map */ /* reuse GL_TEXTURE_CUBE_MAP_SEAMLESS */ /* Reuse tokens from ARB_sync */ /* reuse GL_MAX_SERVER_WAIT_TIMEOUT */ /* reuse GL_OBJECT_TYPE */ /* reuse GL_SYNC_CONDITION */ /* reuse GL_SYNC_STATUS */ /* reuse GL_SYNC_FLAGS */ /* reuse GL_SYNC_FENCE */ /* reuse GL_SYNC_GPU_COMMANDS_COMPLETE */ /* reuse GL_UNSIGNALED */ /* reuse GL_SIGNALED */ /* reuse GL_ALREADY_SIGNALED */ /* reuse GL_TIMEOUT_EXPIRED */ /* reuse GL_CONDITION_SATISFIED */ /* reuse GL_WAIT_FAILED */ /* reuse GL_TIMEOUT_IGNORED */ /* reuse GL_SYNC_FLUSH_COMMANDS_BIT */ /* reuse GL_TIMEOUT_IGNORED */ /* Reuse tokens from ARB_texture_multisample */ /* reuse GL_SAMPLE_POSITION */ /* reuse GL_SAMPLE_MASK */ /* reuse GL_SAMPLE_MASK_VALUE */ /* reuse GL_MAX_SAMPLE_MASK_WORDS */ /* reuse GL_TEXTURE_2D_MULTISAMPLE */ /* reuse GL_PROXY_TEXTURE_2D_MULTISAMPLE */ /* reuse GL_TEXTURE_2D_MULTISAMPLE_ARRAY */ /* reuse GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY */ /* reuse GL_TEXTURE_BINDING_2D_MULTISAMPLE */ /* reuse GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY */ /* reuse GL_TEXTURE_SAMPLES */ /* reuse GL_TEXTURE_FIXED_SAMPLE_LOCATIONS */ /* reuse GL_SAMPLER_2D_MULTISAMPLE */ /* reuse GL_INT_SAMPLER_2D_MULTISAMPLE */ /* reuse GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE */ /* reuse GL_SAMPLER_2D_MULTISAMPLE_ARRAY */ /* reuse GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY */ /* reuse GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY */ /* reuse GL_MAX_COLOR_TEXTURE_SAMPLES */ /* reuse GL_MAX_DEPTH_TEXTURE_SAMPLES */ /* reuse GL_MAX_INTEGER_SAMPLES */ /* Don't need to reuse tokens from ARB_vertex_array_bgra since they're already in 1.2 core */ #endif #ifndef GL_VERSION_3_3 #define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE /* Reuse tokens from ARB_blend_func_extended */ /* reuse GL_SRC1_COLOR */ /* reuse GL_ONE_MINUS_SRC1_COLOR */ /* reuse GL_ONE_MINUS_SRC1_ALPHA */ /* reuse GL_MAX_DUAL_SOURCE_DRAW_BUFFERS */ /* Reuse tokens from ARB_explicit_attrib_location (none) */ /* Reuse tokens from ARB_occlusion_query2 */ /* reuse GL_ANY_SAMPLES_PASSED */ /* Reuse tokens from ARB_sampler_objects */ /* reuse GL_SAMPLER_BINDING */ /* Reuse tokens from ARB_shader_bit_encoding (none) */ /* Reuse tokens from ARB_texture_rgb10_a2ui */ /* reuse GL_RGB10_A2UI */ /* Reuse tokens from ARB_texture_swizzle */ /* reuse GL_TEXTURE_SWIZZLE_R */ /* reuse GL_TEXTURE_SWIZZLE_G */ /* reuse GL_TEXTURE_SWIZZLE_B */ /* reuse GL_TEXTURE_SWIZZLE_A */ /* reuse GL_TEXTURE_SWIZZLE_RGBA */ /* Reuse tokens from ARB_timer_query */ /* reuse GL_TIME_ELAPSED */ /* reuse GL_TIMESTAMP */ /* Reuse tokens from ARB_vertex_type_2_10_10_10_rev */ /* reuse GL_INT_2_10_10_10_REV */ #endif #ifndef GL_VERSION_4_0 #define GL_SAMPLE_SHADING 0x8C36 #define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 #define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E #define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F #define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 #define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A #define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B #define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C #define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D #define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E #define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F /* Reuse tokens from ARB_texture_query_lod (none) */ /* Reuse tokens from ARB_draw_buffers_blend (none) */ /* Reuse tokens from ARB_draw_indirect */ /* reuse GL_DRAW_INDIRECT_BUFFER */ /* reuse GL_DRAW_INDIRECT_BUFFER_BINDING */ /* Reuse tokens from ARB_gpu_shader5 */ /* reuse GL_GEOMETRY_SHADER_INVOCATIONS */ /* reuse GL_MAX_GEOMETRY_SHADER_INVOCATIONS */ /* reuse GL_MIN_FRAGMENT_INTERPOLATION_OFFSET */ /* reuse GL_MAX_FRAGMENT_INTERPOLATION_OFFSET */ /* reuse GL_FRAGMENT_INTERPOLATION_OFFSET_BITS */ /* reuse GL_MAX_VERTEX_STREAMS */ /* Reuse tokens from ARB_gpu_shader_fp64 */ /* reuse GL_DOUBLE_VEC2 */ /* reuse GL_DOUBLE_VEC3 */ /* reuse GL_DOUBLE_VEC4 */ /* reuse GL_DOUBLE_MAT2 */ /* reuse GL_DOUBLE_MAT3 */ /* reuse GL_DOUBLE_MAT4 */ /* reuse GL_DOUBLE_MAT2x3 */ /* reuse GL_DOUBLE_MAT2x4 */ /* reuse GL_DOUBLE_MAT3x2 */ /* reuse GL_DOUBLE_MAT3x4 */ /* reuse GL_DOUBLE_MAT4x2 */ /* reuse GL_DOUBLE_MAT4x3 */ /* Reuse tokens from ARB_shader_subroutine */ /* reuse GL_ACTIVE_SUBROUTINES */ /* reuse GL_ACTIVE_SUBROUTINE_UNIFORMS */ /* reuse GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS */ /* reuse GL_ACTIVE_SUBROUTINE_MAX_LENGTH */ /* reuse GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH */ /* reuse GL_MAX_SUBROUTINES */ /* reuse GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS */ /* reuse GL_NUM_COMPATIBLE_SUBROUTINES */ /* reuse GL_COMPATIBLE_SUBROUTINES */ /* Reuse tokens from ARB_tessellation_shader */ /* reuse GL_PATCHES */ /* reuse GL_PATCH_VERTICES */ /* reuse GL_PATCH_DEFAULT_INNER_LEVEL */ /* reuse GL_PATCH_DEFAULT_OUTER_LEVEL */ /* reuse GL_TESS_CONTROL_OUTPUT_VERTICES */ /* reuse GL_TESS_GEN_MODE */ /* reuse GL_TESS_GEN_SPACING */ /* reuse GL_TESS_GEN_VERTEX_ORDER */ /* reuse GL_TESS_GEN_POINT_MODE */ /* reuse GL_ISOLINES */ /* reuse GL_FRACTIONAL_ODD */ /* reuse GL_FRACTIONAL_EVEN */ /* reuse GL_MAX_PATCH_VERTICES */ /* reuse GL_MAX_TESS_GEN_LEVEL */ /* reuse GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS */ /* reuse GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS */ /* reuse GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS */ /* reuse GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS */ /* reuse GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS */ /* reuse GL_MAX_TESS_PATCH_COMPONENTS */ /* reuse GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS */ /* reuse GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS */ /* reuse GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS */ /* reuse GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS */ /* reuse GL_MAX_TESS_CONTROL_INPUT_COMPONENTS */ /* reuse GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS */ /* reuse GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS */ /* reuse GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS */ /* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER */ /* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER */ /* reuse GL_TESS_EVALUATION_SHADER */ /* reuse GL_TESS_CONTROL_SHADER */ /* Reuse tokens from ARB_texture_buffer_object_rgb32 (none) */ /* Reuse tokens from ARB_transform_feedback2 */ /* reuse GL_TRANSFORM_FEEDBACK */ /* reuse GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED */ /* reuse GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE */ /* reuse GL_TRANSFORM_FEEDBACK_BINDING */ /* Reuse tokens from ARB_transform_feedback3 */ /* reuse GL_MAX_TRANSFORM_FEEDBACK_BUFFERS */ /* reuse GL_MAX_VERTEX_STREAMS */ #endif #ifndef GL_VERSION_4_1 /* Reuse tokens from ARB_ES2_compatibility */ /* reuse GL_FIXED */ /* reuse GL_IMPLEMENTATION_COLOR_READ_TYPE */ /* reuse GL_IMPLEMENTATION_COLOR_READ_FORMAT */ /* reuse GL_LOW_FLOAT */ /* reuse GL_MEDIUM_FLOAT */ /* reuse GL_HIGH_FLOAT */ /* reuse GL_LOW_INT */ /* reuse GL_MEDIUM_INT */ /* reuse GL_HIGH_INT */ /* reuse GL_SHADER_COMPILER */ /* reuse GL_SHADER_BINARY_FORMATS */ /* reuse GL_NUM_SHADER_BINARY_FORMATS */ /* reuse GL_MAX_VERTEX_UNIFORM_VECTORS */ /* reuse GL_MAX_VARYING_VECTORS */ /* reuse GL_MAX_FRAGMENT_UNIFORM_VECTORS */ /* reuse GL_RGB565 */ /* Reuse tokens from ARB_get_program_binary */ /* reuse GL_PROGRAM_BINARY_RETRIEVABLE_HINT */ /* reuse GL_PROGRAM_BINARY_LENGTH */ /* reuse GL_NUM_PROGRAM_BINARY_FORMATS */ /* reuse GL_PROGRAM_BINARY_FORMATS */ /* Reuse tokens from ARB_separate_shader_objects */ /* reuse GL_VERTEX_SHADER_BIT */ /* reuse GL_FRAGMENT_SHADER_BIT */ /* reuse GL_GEOMETRY_SHADER_BIT */ /* reuse GL_TESS_CONTROL_SHADER_BIT */ /* reuse GL_TESS_EVALUATION_SHADER_BIT */ /* reuse GL_ALL_SHADER_BITS */ /* reuse GL_PROGRAM_SEPARABLE */ /* reuse GL_ACTIVE_PROGRAM */ /* reuse GL_PROGRAM_PIPELINE_BINDING */ /* Reuse tokens from ARB_shader_precision (none) */ /* Reuse tokens from ARB_vertex_attrib_64bit - all are in GL 3.0 and 4.0 already */ /* Reuse tokens from ARB_viewport_array - some are in GL 1.1 and ARB_provoking_vertex already */ /* reuse GL_MAX_VIEWPORTS */ /* reuse GL_VIEWPORT_SUBPIXEL_BITS */ /* reuse GL_VIEWPORT_BOUNDS_RANGE */ /* reuse GL_LAYER_PROVOKING_VERTEX */ /* reuse GL_VIEWPORT_INDEX_PROVOKING_VERTEX */ /* reuse GL_UNDEFINED_VERTEX */ #endif #ifndef GL_VERSION_4_2 /* Reuse tokens from ARB_base_instance (none) */ /* Reuse tokens from ARB_shading_language_420pack (none) */ /* Reuse tokens from ARB_transform_feedback_instanced (none) */ /* Reuse tokens from ARB_compressed_texture_pixel_storage */ /* reuse GL_UNPACK_COMPRESSED_BLOCK_WIDTH */ /* reuse GL_UNPACK_COMPRESSED_BLOCK_HEIGHT */ /* reuse GL_UNPACK_COMPRESSED_BLOCK_DEPTH */ /* reuse GL_UNPACK_COMPRESSED_BLOCK_SIZE */ /* reuse GL_PACK_COMPRESSED_BLOCK_WIDTH */ /* reuse GL_PACK_COMPRESSED_BLOCK_HEIGHT */ /* reuse GL_PACK_COMPRESSED_BLOCK_DEPTH */ /* reuse GL_PACK_COMPRESSED_BLOCK_SIZE */ /* Reuse tokens from ARB_conservative_depth (none) */ /* Reuse tokens from ARB_internalformat_query */ /* reuse GL_NUM_SAMPLE_COUNTS */ /* Reuse tokens from ARB_map_buffer_alignment */ /* reuse GL_MIN_MAP_BUFFER_ALIGNMENT */ /* Reuse tokens from ARB_shader_atomic_counters */ /* reuse GL_ATOMIC_COUNTER_BUFFER */ /* reuse GL_ATOMIC_COUNTER_BUFFER_BINDING */ /* reuse GL_ATOMIC_COUNTER_BUFFER_START */ /* reuse GL_ATOMIC_COUNTER_BUFFER_SIZE */ /* reuse GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE */ /* reuse GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS */ /* reuse GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES */ /* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER */ /* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER */ /* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER */ /* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER */ /* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER */ /* reuse GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS */ /* reuse GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS */ /* reuse GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS */ /* reuse GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS */ /* reuse GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS */ /* reuse GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS */ /* reuse GL_MAX_VERTEX_ATOMIC_COUNTERS */ /* reuse GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS */ /* reuse GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS */ /* reuse GL_MAX_GEOMETRY_ATOMIC_COUNTERS */ /* reuse GL_MAX_FRAGMENT_ATOMIC_COUNTERS */ /* reuse GL_MAX_COMBINED_ATOMIC_COUNTERS */ /* reuse GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE */ /* reuse GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS */ /* reuse GL_ACTIVE_ATOMIC_COUNTER_BUFFERS */ /* reuse GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX */ /* reuse GL_UNSIGNED_INT_ATOMIC_COUNTER */ /* Reuse tokens from ARB_shader_image_load_store */ /* reuse GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT */ /* reuse GL_ELEMENT_ARRAY_BARRIER_BIT */ /* reuse GL_UNIFORM_BARRIER_BIT */ /* reuse GL_TEXTURE_FETCH_BARRIER_BIT */ /* reuse GL_SHADER_IMAGE_ACCESS_BARRIER_BIT */ /* reuse GL_COMMAND_BARRIER_BIT */ /* reuse GL_PIXEL_BUFFER_BARRIER_BIT */ /* reuse GL_TEXTURE_UPDATE_BARRIER_BIT */ /* reuse GL_BUFFER_UPDATE_BARRIER_BIT */ /* reuse GL_FRAMEBUFFER_BARRIER_BIT */ /* reuse GL_TRANSFORM_FEEDBACK_BARRIER_BIT */ /* reuse GL_ATOMIC_COUNTER_BARRIER_BIT */ /* reuse GL_ALL_BARRIER_BITS */ /* reuse GL_MAX_IMAGE_UNITS */ /* reuse GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS */ /* reuse GL_IMAGE_BINDING_NAME */ /* reuse GL_IMAGE_BINDING_LEVEL */ /* reuse GL_IMAGE_BINDING_LAYERED */ /* reuse GL_IMAGE_BINDING_LAYER */ /* reuse GL_IMAGE_BINDING_ACCESS */ /* reuse GL_IMAGE_1D */ /* reuse GL_IMAGE_2D */ /* reuse GL_IMAGE_3D */ /* reuse GL_IMAGE_2D_RECT */ /* reuse GL_IMAGE_CUBE */ /* reuse GL_IMAGE_BUFFER */ /* reuse GL_IMAGE_1D_ARRAY */ /* reuse GL_IMAGE_2D_ARRAY */ /* reuse GL_IMAGE_CUBE_MAP_ARRAY */ /* reuse GL_IMAGE_2D_MULTISAMPLE */ /* reuse GL_IMAGE_2D_MULTISAMPLE_ARRAY */ /* reuse GL_INT_IMAGE_1D */ /* reuse GL_INT_IMAGE_2D */ /* reuse GL_INT_IMAGE_3D */ /* reuse GL_INT_IMAGE_2D_RECT */ /* reuse GL_INT_IMAGE_CUBE */ /* reuse GL_INT_IMAGE_BUFFER */ /* reuse GL_INT_IMAGE_1D_ARRAY */ /* reuse GL_INT_IMAGE_2D_ARRAY */ /* reuse GL_INT_IMAGE_CUBE_MAP_ARRAY */ /* reuse GL_INT_IMAGE_2D_MULTISAMPLE */ /* reuse GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY */ /* reuse GL_UNSIGNED_INT_IMAGE_1D */ /* reuse GL_UNSIGNED_INT_IMAGE_2D */ /* reuse GL_UNSIGNED_INT_IMAGE_3D */ /* reuse GL_UNSIGNED_INT_IMAGE_2D_RECT */ /* reuse GL_UNSIGNED_INT_IMAGE_CUBE */ /* reuse GL_UNSIGNED_INT_IMAGE_BUFFER */ /* reuse GL_UNSIGNED_INT_IMAGE_1D_ARRAY */ /* reuse GL_UNSIGNED_INT_IMAGE_2D_ARRAY */ /* reuse GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY */ /* reuse GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE */ /* reuse GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY */ /* reuse GL_MAX_IMAGE_SAMPLES */ /* reuse GL_IMAGE_BINDING_FORMAT */ /* reuse GL_IMAGE_FORMAT_COMPATIBILITY_TYPE */ /* reuse GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE */ /* reuse GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS */ /* reuse GL_MAX_VERTEX_IMAGE_UNIFORMS */ /* reuse GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS */ /* reuse GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS */ /* reuse GL_MAX_GEOMETRY_IMAGE_UNIFORMS */ /* reuse GL_MAX_FRAGMENT_IMAGE_UNIFORMS */ /* reuse GL_MAX_COMBINED_IMAGE_UNIFORMS */ /* Reuse tokens from ARB_shading_language_packing (none) */ /* Reuse tokens from ARB_texture_storage */ /* reuse GL_TEXTURE_IMMUTABLE_FORMAT */ #endif #ifndef GL_VERSION_4_3 #define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9 #define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E /* Reuse tokens from ARB_arrays_of_arrays (none, GLSL only) */ /* Reuse tokens from ARB_fragment_layer_viewport (none, GLSL only) */ /* Reuse tokens from ARB_shader_image_size (none, GLSL only) */ /* Reuse tokens from ARB_ES3_compatibility */ /* reuse GL_COMPRESSED_RGB8_ETC2 */ /* reuse GL_COMPRESSED_SRGB8_ETC2 */ /* reuse GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 */ /* reuse GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 */ /* reuse GL_COMPRESSED_RGBA8_ETC2_EAC */ /* reuse GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC */ /* reuse GL_COMPRESSED_R11_EAC */ /* reuse GL_COMPRESSED_SIGNED_R11_EAC */ /* reuse GL_COMPRESSED_RG11_EAC */ /* reuse GL_COMPRESSED_SIGNED_RG11_EAC */ /* reuse GL_PRIMITIVE_RESTART_FIXED_INDEX */ /* reuse GL_ANY_SAMPLES_PASSED_CONSERVATIVE */ /* reuse GL_MAX_ELEMENT_INDEX */ /* Reuse tokens from ARB_clear_buffer_object (none) */ /* Reuse tokens from ARB_compute_shader */ /* reuse GL_COMPUTE_SHADER */ /* reuse GL_MAX_COMPUTE_UNIFORM_BLOCKS */ /* reuse GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS */ /* reuse GL_MAX_COMPUTE_IMAGE_UNIFORMS */ /* reuse GL_MAX_COMPUTE_SHARED_MEMORY_SIZE */ /* reuse GL_MAX_COMPUTE_UNIFORM_COMPONENTS */ /* reuse GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS */ /* reuse GL_MAX_COMPUTE_ATOMIC_COUNTERS */ /* reuse GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS */ /* reuse GL_MAX_COMPUTE_LOCAL_INVOCATIONS */ /* reuse GL_MAX_COMPUTE_WORK_GROUP_COUNT */ /* reuse GL_MAX_COMPUTE_WORK_GROUP_SIZE */ /* reuse GL_COMPUTE_LOCAL_WORK_SIZE */ /* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER */ /* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER */ /* reuse GL_DISPATCH_INDIRECT_BUFFER */ /* reuse GL_DISPATCH_INDIRECT_BUFFER_BINDING */ /* Reuse tokens from ARB_copy_image (none) */ /* Reuse tokens from KHR_debug */ /* reuse GL_DEBUG_OUTPUT_SYNCHRONOUS */ /* reuse GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH */ /* reuse GL_DEBUG_CALLBACK_FUNCTION */ /* reuse GL_DEBUG_CALLBACK_USER_PARAM */ /* reuse GL_DEBUG_SOURCE_API */ /* reuse GL_DEBUG_SOURCE_WINDOW_SYSTEM */ /* reuse GL_DEBUG_SOURCE_SHADER_COMPILER */ /* reuse GL_DEBUG_SOURCE_THIRD_PARTY */ /* reuse GL_DEBUG_SOURCE_APPLICATION */ /* reuse GL_DEBUG_SOURCE_OTHER */ /* reuse GL_DEBUG_TYPE_ERROR */ /* reuse GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR */ /* reuse GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR */ /* reuse GL_DEBUG_TYPE_PORTABILITY */ /* reuse GL_DEBUG_TYPE_PERFORMANCE */ /* reuse GL_DEBUG_TYPE_OTHER */ /* reuse GL_MAX_DEBUG_MESSAGE_LENGTH */ /* reuse GL_MAX_DEBUG_LOGGED_MESSAGES */ /* reuse GL_DEBUG_LOGGED_MESSAGES */ /* reuse GL_DEBUG_SEVERITY_HIGH */ /* reuse GL_DEBUG_SEVERITY_MEDIUM */ /* reuse GL_DEBUG_SEVERITY_LOW */ /* reuse GL_DEBUG_TYPE_MARKER */ /* reuse GL_DEBUG_TYPE_PUSH_GROUP */ /* reuse GL_DEBUG_TYPE_POP_GROUP */ /* reuse GL_DEBUG_SEVERITY_NOTIFICATION */ /* reuse GL_MAX_DEBUG_GROUP_STACK_DEPTH */ /* reuse GL_DEBUG_GROUP_STACK_DEPTH */ /* reuse GL_BUFFER */ /* reuse GL_SHADER */ /* reuse GL_PROGRAM */ /* reuse GL_QUERY */ /* reuse GL_PROGRAM_PIPELINE */ /* reuse GL_SAMPLER */ /* reuse GL_DISPLAY_LIST */ /* reuse GL_MAX_LABEL_LENGTH */ /* reuse GL_DEBUG_OUTPUT */ /* reuse GL_CONTEXT_FLAG_DEBUG_BIT */ /* reuse GL_STACK_UNDERFLOW */ /* reuse GL_STACK_OVERFLOW */ /* Reuse tokens from ARB_explicit_uniform_location */ /* reuse GL_MAX_UNIFORM_LOCATIONS */ /* Reuse tokens from ARB_framebuffer_no_attachments */ /* reuse GL_FRAMEBUFFER_DEFAULT_WIDTH */ /* reuse GL_FRAMEBUFFER_DEFAULT_HEIGHT */ /* reuse GL_FRAMEBUFFER_DEFAULT_LAYERS */ /* reuse GL_FRAMEBUFFER_DEFAULT_SAMPLES */ /* reuse GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS */ /* reuse GL_MAX_FRAMEBUFFER_WIDTH */ /* reuse GL_MAX_FRAMEBUFFER_HEIGHT */ /* reuse GL_MAX_FRAMEBUFFER_LAYERS */ /* reuse GL_MAX_FRAMEBUFFER_SAMPLES */ /* Reuse tokens from ARB_internalformat_query2 */ /* reuse GL_INTERNALFORMAT_SUPPORTED */ /* reuse GL_INTERNALFORMAT_PREFERRED */ /* reuse GL_INTERNALFORMAT_RED_SIZE */ /* reuse GL_INTERNALFORMAT_GREEN_SIZE */ /* reuse GL_INTERNALFORMAT_BLUE_SIZE */ /* reuse GL_INTERNALFORMAT_ALPHA_SIZE */ /* reuse GL_INTERNALFORMAT_DEPTH_SIZE */ /* reuse GL_INTERNALFORMAT_STENCIL_SIZE */ /* reuse GL_INTERNALFORMAT_SHARED_SIZE */ /* reuse GL_INTERNALFORMAT_RED_TYPE */ /* reuse GL_INTERNALFORMAT_GREEN_TYPE */ /* reuse GL_INTERNALFORMAT_BLUE_TYPE */ /* reuse GL_INTERNALFORMAT_ALPHA_TYPE */ /* reuse GL_INTERNALFORMAT_DEPTH_TYPE */ /* reuse GL_INTERNALFORMAT_STENCIL_TYPE */ /* reuse GL_MAX_WIDTH */ /* reuse GL_MAX_HEIGHT */ /* reuse GL_MAX_DEPTH */ /* reuse GL_MAX_LAYERS */ /* reuse GL_MAX_COMBINED_DIMENSIONS */ /* reuse GL_COLOR_COMPONENTS */ /* reuse GL_DEPTH_COMPONENTS */ /* reuse GL_STENCIL_COMPONENTS */ /* reuse GL_COLOR_RENDERABLE */ /* reuse GL_DEPTH_RENDERABLE */ /* reuse GL_STENCIL_RENDERABLE */ /* reuse GL_FRAMEBUFFER_RENDERABLE */ /* reuse GL_FRAMEBUFFER_RENDERABLE_LAYERED */ /* reuse GL_FRAMEBUFFER_BLEND */ /* reuse GL_READ_PIXELS */ /* reuse GL_READ_PIXELS_FORMAT */ /* reuse GL_READ_PIXELS_TYPE */ /* reuse GL_TEXTURE_IMAGE_FORMAT */ /* reuse GL_TEXTURE_IMAGE_TYPE */ /* reuse GL_GET_TEXTURE_IMAGE_FORMAT */ /* reuse GL_GET_TEXTURE_IMAGE_TYPE */ /* reuse GL_MIPMAP */ /* reuse GL_MANUAL_GENERATE_MIPMAP */ /* reuse GL_AUTO_GENERATE_MIPMAP */ /* reuse GL_COLOR_ENCODING */ /* reuse GL_SRGB_READ */ /* reuse GL_SRGB_WRITE */ /* reuse GL_FILTER */ /* reuse GL_VERTEX_TEXTURE */ /* reuse GL_TESS_CONTROL_TEXTURE */ /* reuse GL_TESS_EVALUATION_TEXTURE */ /* reuse GL_GEOMETRY_TEXTURE */ /* reuse GL_FRAGMENT_TEXTURE */ /* reuse GL_COMPUTE_TEXTURE */ /* reuse GL_TEXTURE_SHADOW */ /* reuse GL_TEXTURE_GATHER */ /* reuse GL_TEXTURE_GATHER_SHADOW */ /* reuse GL_SHADER_IMAGE_LOAD */ /* reuse GL_SHADER_IMAGE_STORE */ /* reuse GL_SHADER_IMAGE_ATOMIC */ /* reuse GL_IMAGE_TEXEL_SIZE */ /* reuse GL_IMAGE_COMPATIBILITY_CLASS */ /* reuse GL_IMAGE_PIXEL_FORMAT */ /* reuse GL_IMAGE_PIXEL_TYPE */ /* reuse GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST */ /* reuse GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST */ /* reuse GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE */ /* reuse GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE */ /* reuse GL_TEXTURE_COMPRESSED_BLOCK_WIDTH */ /* reuse GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT */ /* reuse GL_TEXTURE_COMPRESSED_BLOCK_SIZE */ /* reuse GL_CLEAR_BUFFER */ /* reuse GL_TEXTURE_VIEW */ /* reuse GL_VIEW_COMPATIBILITY_CLASS */ /* reuse GL_FULL_SUPPORT */ /* reuse GL_CAVEAT_SUPPORT */ /* reuse GL_IMAGE_CLASS_4_X_32 */ /* reuse GL_IMAGE_CLASS_2_X_32 */ /* reuse GL_IMAGE_CLASS_1_X_32 */ /* reuse GL_IMAGE_CLASS_4_X_16 */ /* reuse GL_IMAGE_CLASS_2_X_16 */ /* reuse GL_IMAGE_CLASS_1_X_16 */ /* reuse GL_IMAGE_CLASS_4_X_8 */ /* reuse GL_IMAGE_CLASS_2_X_8 */ /* reuse GL_IMAGE_CLASS_1_X_8 */ /* reuse GL_IMAGE_CLASS_11_11_10 */ /* reuse GL_IMAGE_CLASS_10_10_10_2 */ /* reuse GL_VIEW_CLASS_128_BITS */ /* reuse GL_VIEW_CLASS_96_BITS */ /* reuse GL_VIEW_CLASS_64_BITS */ /* reuse GL_VIEW_CLASS_48_BITS */ /* reuse GL_VIEW_CLASS_32_BITS */ /* reuse GL_VIEW_CLASS_24_BITS */ /* reuse GL_VIEW_CLASS_16_BITS */ /* reuse GL_VIEW_CLASS_8_BITS */ /* reuse GL_VIEW_CLASS_S3TC_DXT1_RGB */ /* reuse GL_VIEW_CLASS_S3TC_DXT1_RGBA */ /* reuse GL_VIEW_CLASS_S3TC_DXT3_RGBA */ /* reuse GL_VIEW_CLASS_S3TC_DXT5_RGBA */ /* reuse GL_VIEW_CLASS_RGTC1_RED */ /* reuse GL_VIEW_CLASS_RGTC2_RG */ /* reuse GL_VIEW_CLASS_BPTC_UNORM */ /* reuse GL_VIEW_CLASS_BPTC_FLOAT */ /* Reuse tokens from ARB_invalidate_subdata (none) */ /* Reuse tokens from ARB_multi_draw_indirect (none) */ /* Reuse tokens from ARB_program_interface_query */ /* reuse GL_UNIFORM */ /* reuse GL_UNIFORM_BLOCK */ /* reuse GL_PROGRAM_INPUT */ /* reuse GL_PROGRAM_OUTPUT */ /* reuse GL_BUFFER_VARIABLE */ /* reuse GL_SHADER_STORAGE_BLOCK */ /* reuse GL_VERTEX_SUBROUTINE */ /* reuse GL_TESS_CONTROL_SUBROUTINE */ /* reuse GL_TESS_EVALUATION_SUBROUTINE */ /* reuse GL_GEOMETRY_SUBROUTINE */ /* reuse GL_FRAGMENT_SUBROUTINE */ /* reuse GL_COMPUTE_SUBROUTINE */ /* reuse GL_VERTEX_SUBROUTINE_UNIFORM */ /* reuse GL_TESS_CONTROL_SUBROUTINE_UNIFORM */ /* reuse GL_TESS_EVALUATION_SUBROUTINE_UNIFORM */ /* reuse GL_GEOMETRY_SUBROUTINE_UNIFORM */ /* reuse GL_FRAGMENT_SUBROUTINE_UNIFORM */ /* reuse GL_COMPUTE_SUBROUTINE_UNIFORM */ /* reuse GL_TRANSFORM_FEEDBACK_VARYING */ /* reuse GL_ACTIVE_RESOURCES */ /* reuse GL_MAX_NAME_LENGTH */ /* reuse GL_MAX_NUM_ACTIVE_VARIABLES */ /* reuse GL_MAX_NUM_COMPATIBLE_SUBROUTINES */ /* reuse GL_NAME_LENGTH */ /* reuse GL_TYPE */ /* reuse GL_ARRAY_SIZE */ /* reuse GL_OFFSET */ /* reuse GL_BLOCK_INDEX */ /* reuse GL_ARRAY_STRIDE */ /* reuse GL_MATRIX_STRIDE */ /* reuse GL_IS_ROW_MAJOR */ /* reuse GL_ATOMIC_COUNTER_BUFFER_INDEX */ /* reuse GL_BUFFER_BINDING */ /* reuse GL_BUFFER_DATA_SIZE */ /* reuse GL_NUM_ACTIVE_VARIABLES */ /* reuse GL_ACTIVE_VARIABLES */ /* reuse GL_REFERENCED_BY_VERTEX_SHADER */ /* reuse GL_REFERENCED_BY_TESS_CONTROL_SHADER */ /* reuse GL_REFERENCED_BY_TESS_EVALUATION_SHADER */ /* reuse GL_REFERENCED_BY_GEOMETRY_SHADER */ /* reuse GL_REFERENCED_BY_FRAGMENT_SHADER */ /* reuse GL_REFERENCED_BY_COMPUTE_SHADER */ /* reuse GL_TOP_LEVEL_ARRAY_SIZE */ /* reuse GL_TOP_LEVEL_ARRAY_STRIDE */ /* reuse GL_LOCATION */ /* reuse GL_LOCATION_INDEX */ /* reuse GL_IS_PER_PATCH */ /* Reuse tokens from ARB_robust_buffer_access_behavior (none) */ /* Reuse tokens from ARB_shader_storage_buffer_object */ /* reuse GL_SHADER_STORAGE_BUFFER */ /* reuse GL_SHADER_STORAGE_BUFFER_BINDING */ /* reuse GL_SHADER_STORAGE_BUFFER_START */ /* reuse GL_SHADER_STORAGE_BUFFER_SIZE */ /* reuse GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS */ /* reuse GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS */ /* reuse GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS */ /* reuse GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS */ /* reuse GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS */ /* reuse GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS */ /* reuse GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS */ /* reuse GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS */ /* reuse GL_MAX_SHADER_STORAGE_BLOCK_SIZE */ /* reuse GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT */ /* reuse GL_SHADER_STORAGE_BARRIER_BIT */ /* reuse GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES */ /* Reuse tokens from ARB_stencil_texturing */ /* reuse GL_DEPTH_STENCIL_TEXTURE_MODE */ /* Reuse tokens from ARB_texture_buffer_range */ /* reuse GL_TEXTURE_BUFFER_OFFSET */ /* reuse GL_TEXTURE_BUFFER_SIZE */ /* reuse GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT */ /* Reuse tokens from ARB_texture_query_levels (none) */ /* Reuse tokens from ARB_texture_storage_multisample (none) */ /* Reuse tokens from ARB_texture_view */ /* reuse GL_TEXTURE_VIEW_MIN_LEVEL */ /* reuse GL_TEXTURE_VIEW_NUM_LEVELS */ /* reuse GL_TEXTURE_VIEW_MIN_LAYER */ /* reuse GL_TEXTURE_VIEW_NUM_LAYERS */ /* reuse GL_TEXTURE_IMMUTABLE_LEVELS */ /* Reuse tokens from ARB_vertex_attrib_binding */ /* reuse GL_VERTEX_ATTRIB_BINDING */ /* reuse GL_VERTEX_ATTRIB_RELATIVE_OFFSET */ /* reuse GL_VERTEX_BINDING_DIVISOR */ /* reuse GL_VERTEX_BINDING_OFFSET */ /* reuse GL_VERTEX_BINDING_STRIDE */ /* reuse GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET */ /* reuse GL_MAX_VERTEX_ATTRIB_BINDINGS */ #endif #ifndef GL_ARB_multitexture #define GL_TEXTURE0_ARB 0x84C0 #define GL_TEXTURE1_ARB 0x84C1 #define GL_TEXTURE2_ARB 0x84C2 #define GL_TEXTURE3_ARB 0x84C3 #define GL_TEXTURE4_ARB 0x84C4 #define GL_TEXTURE5_ARB 0x84C5 #define GL_TEXTURE6_ARB 0x84C6 #define GL_TEXTURE7_ARB 0x84C7 #define GL_TEXTURE8_ARB 0x84C8 #define GL_TEXTURE9_ARB 0x84C9 #define GL_TEXTURE10_ARB 0x84CA #define GL_TEXTURE11_ARB 0x84CB #define GL_TEXTURE12_ARB 0x84CC #define GL_TEXTURE13_ARB 0x84CD #define GL_TEXTURE14_ARB 0x84CE #define GL_TEXTURE15_ARB 0x84CF #define GL_TEXTURE16_ARB 0x84D0 #define GL_TEXTURE17_ARB 0x84D1 #define GL_TEXTURE18_ARB 0x84D2 #define GL_TEXTURE19_ARB 0x84D3 #define GL_TEXTURE20_ARB 0x84D4 #define GL_TEXTURE21_ARB 0x84D5 #define GL_TEXTURE22_ARB 0x84D6 #define GL_TEXTURE23_ARB 0x84D7 #define GL_TEXTURE24_ARB 0x84D8 #define GL_TEXTURE25_ARB 0x84D9 #define GL_TEXTURE26_ARB 0x84DA #define GL_TEXTURE27_ARB 0x84DB #define GL_TEXTURE28_ARB 0x84DC #define GL_TEXTURE29_ARB 0x84DD #define GL_TEXTURE30_ARB 0x84DE #define GL_TEXTURE31_ARB 0x84DF #define GL_ACTIVE_TEXTURE_ARB 0x84E0 #define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 #define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 #endif #ifndef GL_ARB_transpose_matrix #define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 #define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 #define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 #define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 #endif #ifndef GL_ARB_multisample #define GL_MULTISAMPLE_ARB 0x809D #define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E #define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F #define GL_SAMPLE_COVERAGE_ARB 0x80A0 #define GL_SAMPLE_BUFFERS_ARB 0x80A8 #define GL_SAMPLES_ARB 0x80A9 #define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA #define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB #define GL_MULTISAMPLE_BIT_ARB 0x20000000 #endif #ifndef GL_ARB_texture_env_add #endif #ifndef GL_ARB_texture_cube_map #define GL_NORMAL_MAP_ARB 0x8511 #define GL_REFLECTION_MAP_ARB 0x8512 #define GL_TEXTURE_CUBE_MAP_ARB 0x8513 #define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 #define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A #define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B #define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C #endif #ifndef GL_ARB_texture_compression #define GL_COMPRESSED_ALPHA_ARB 0x84E9 #define GL_COMPRESSED_LUMINANCE_ARB 0x84EA #define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB #define GL_COMPRESSED_INTENSITY_ARB 0x84EC #define GL_COMPRESSED_RGB_ARB 0x84ED #define GL_COMPRESSED_RGBA_ARB 0x84EE #define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF #define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 #define GL_TEXTURE_COMPRESSED_ARB 0x86A1 #define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 #define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 #endif #ifndef GL_ARB_texture_border_clamp #define GL_CLAMP_TO_BORDER_ARB 0x812D #endif #ifndef GL_ARB_point_parameters #define GL_POINT_SIZE_MIN_ARB 0x8126 #define GL_POINT_SIZE_MAX_ARB 0x8127 #define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 #define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 #endif #ifndef GL_ARB_vertex_blend #define GL_MAX_VERTEX_UNITS_ARB 0x86A4 #define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 #define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 #define GL_VERTEX_BLEND_ARB 0x86A7 #define GL_CURRENT_WEIGHT_ARB 0x86A8 #define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 #define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA #define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB #define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC #define GL_WEIGHT_ARRAY_ARB 0x86AD #define GL_MODELVIEW0_ARB 0x1700 #define GL_MODELVIEW1_ARB 0x850A #define GL_MODELVIEW2_ARB 0x8722 #define GL_MODELVIEW3_ARB 0x8723 #define GL_MODELVIEW4_ARB 0x8724 #define GL_MODELVIEW5_ARB 0x8725 #define GL_MODELVIEW6_ARB 0x8726 #define GL_MODELVIEW7_ARB 0x8727 #define GL_MODELVIEW8_ARB 0x8728 #define GL_MODELVIEW9_ARB 0x8729 #define GL_MODELVIEW10_ARB 0x872A #define GL_MODELVIEW11_ARB 0x872B #define GL_MODELVIEW12_ARB 0x872C #define GL_MODELVIEW13_ARB 0x872D #define GL_MODELVIEW14_ARB 0x872E #define GL_MODELVIEW15_ARB 0x872F #define GL_MODELVIEW16_ARB 0x8730 #define GL_MODELVIEW17_ARB 0x8731 #define GL_MODELVIEW18_ARB 0x8732 #define GL_MODELVIEW19_ARB 0x8733 #define GL_MODELVIEW20_ARB 0x8734 #define GL_MODELVIEW21_ARB 0x8735 #define GL_MODELVIEW22_ARB 0x8736 #define GL_MODELVIEW23_ARB 0x8737 #define GL_MODELVIEW24_ARB 0x8738 #define GL_MODELVIEW25_ARB 0x8739 #define GL_MODELVIEW26_ARB 0x873A #define GL_MODELVIEW27_ARB 0x873B #define GL_MODELVIEW28_ARB 0x873C #define GL_MODELVIEW29_ARB 0x873D #define GL_MODELVIEW30_ARB 0x873E #define GL_MODELVIEW31_ARB 0x873F #endif #ifndef GL_ARB_matrix_palette #define GL_MATRIX_PALETTE_ARB 0x8840 #define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 #define GL_MAX_PALETTE_MATRICES_ARB 0x8842 #define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 #define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 #define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 #define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 #define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 #define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 #define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 #endif #ifndef GL_ARB_texture_env_combine #define GL_COMBINE_ARB 0x8570 #define GL_COMBINE_RGB_ARB 0x8571 #define GL_COMBINE_ALPHA_ARB 0x8572 #define GL_SOURCE0_RGB_ARB 0x8580 #define GL_SOURCE1_RGB_ARB 0x8581 #define GL_SOURCE2_RGB_ARB 0x8582 #define GL_SOURCE0_ALPHA_ARB 0x8588 #define GL_SOURCE1_ALPHA_ARB 0x8589 #define GL_SOURCE2_ALPHA_ARB 0x858A #define GL_OPERAND0_RGB_ARB 0x8590 #define GL_OPERAND1_RGB_ARB 0x8591 #define GL_OPERAND2_RGB_ARB 0x8592 #define GL_OPERAND0_ALPHA_ARB 0x8598 #define GL_OPERAND1_ALPHA_ARB 0x8599 #define GL_OPERAND2_ALPHA_ARB 0x859A #define GL_RGB_SCALE_ARB 0x8573 #define GL_ADD_SIGNED_ARB 0x8574 #define GL_INTERPOLATE_ARB 0x8575 #define GL_SUBTRACT_ARB 0x84E7 #define GL_CONSTANT_ARB 0x8576 #define GL_PRIMARY_COLOR_ARB 0x8577 #define GL_PREVIOUS_ARB 0x8578 #endif #ifndef GL_ARB_texture_env_crossbar #endif #ifndef GL_ARB_texture_env_dot3 #define GL_DOT3_RGB_ARB 0x86AE #define GL_DOT3_RGBA_ARB 0x86AF #endif #ifndef GL_ARB_texture_mirrored_repeat #define GL_MIRRORED_REPEAT_ARB 0x8370 #endif #ifndef GL_ARB_depth_texture #define GL_DEPTH_COMPONENT16_ARB 0x81A5 #define GL_DEPTH_COMPONENT24_ARB 0x81A6 #define GL_DEPTH_COMPONENT32_ARB 0x81A7 #define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A #define GL_DEPTH_TEXTURE_MODE_ARB 0x884B #endif #ifndef GL_ARB_shadow #define GL_TEXTURE_COMPARE_MODE_ARB 0x884C #define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D #define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E #endif #ifndef GL_ARB_shadow_ambient #define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF #endif #ifndef GL_ARB_window_pos #endif #ifndef GL_ARB_vertex_program #define GL_COLOR_SUM_ARB 0x8458 #define GL_VERTEX_PROGRAM_ARB 0x8620 #define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 #define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 #define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 #define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 #define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 #define GL_PROGRAM_LENGTH_ARB 0x8627 #define GL_PROGRAM_STRING_ARB 0x8628 #define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E #define GL_MAX_PROGRAM_MATRICES_ARB 0x862F #define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 #define GL_CURRENT_MATRIX_ARB 0x8641 #define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 #define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 #define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 #define GL_PROGRAM_ERROR_POSITION_ARB 0x864B #define GL_PROGRAM_BINDING_ARB 0x8677 #define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 #define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A #define GL_PROGRAM_ERROR_STRING_ARB 0x8874 #define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 #define GL_PROGRAM_FORMAT_ARB 0x8876 #define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 #define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 #define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 #define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 #define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 #define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 #define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 #define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 #define GL_PROGRAM_PARAMETERS_ARB 0x88A8 #define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 #define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA #define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB #define GL_PROGRAM_ATTRIBS_ARB 0x88AC #define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD #define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE #define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF #define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 #define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 #define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 #define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 #define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 #define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 #define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 #define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 #define GL_MATRIX0_ARB 0x88C0 #define GL_MATRIX1_ARB 0x88C1 #define GL_MATRIX2_ARB 0x88C2 #define GL_MATRIX3_ARB 0x88C3 #define GL_MATRIX4_ARB 0x88C4 #define GL_MATRIX5_ARB 0x88C5 #define GL_MATRIX6_ARB 0x88C6 #define GL_MATRIX7_ARB 0x88C7 #define GL_MATRIX8_ARB 0x88C8 #define GL_MATRIX9_ARB 0x88C9 #define GL_MATRIX10_ARB 0x88CA #define GL_MATRIX11_ARB 0x88CB #define GL_MATRIX12_ARB 0x88CC #define GL_MATRIX13_ARB 0x88CD #define GL_MATRIX14_ARB 0x88CE #define GL_MATRIX15_ARB 0x88CF #define GL_MATRIX16_ARB 0x88D0 #define GL_MATRIX17_ARB 0x88D1 #define GL_MATRIX18_ARB 0x88D2 #define GL_MATRIX19_ARB 0x88D3 #define GL_MATRIX20_ARB 0x88D4 #define GL_MATRIX21_ARB 0x88D5 #define GL_MATRIX22_ARB 0x88D6 #define GL_MATRIX23_ARB 0x88D7 #define GL_MATRIX24_ARB 0x88D8 #define GL_MATRIX25_ARB 0x88D9 #define GL_MATRIX26_ARB 0x88DA #define GL_MATRIX27_ARB 0x88DB #define GL_MATRIX28_ARB 0x88DC #define GL_MATRIX29_ARB 0x88DD #define GL_MATRIX30_ARB 0x88DE #define GL_MATRIX31_ARB 0x88DF #endif #ifndef GL_ARB_fragment_program #define GL_FRAGMENT_PROGRAM_ARB 0x8804 #define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 #define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 #define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 #define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 #define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 #define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A #define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B #define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C #define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D #define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E #define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F #define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 #define GL_MAX_TEXTURE_COORDS_ARB 0x8871 #define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 #endif #ifndef GL_ARB_vertex_buffer_object #define GL_BUFFER_SIZE_ARB 0x8764 #define GL_BUFFER_USAGE_ARB 0x8765 #define GL_ARRAY_BUFFER_ARB 0x8892 #define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 #define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 #define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 #define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 #define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 #define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 #define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 #define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A #define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B #define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C #define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D #define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E #define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F #define GL_READ_ONLY_ARB 0x88B8 #define GL_WRITE_ONLY_ARB 0x88B9 #define GL_READ_WRITE_ARB 0x88BA #define GL_BUFFER_ACCESS_ARB 0x88BB #define GL_BUFFER_MAPPED_ARB 0x88BC #define GL_BUFFER_MAP_POINTER_ARB 0x88BD #define GL_STREAM_DRAW_ARB 0x88E0 #define GL_STREAM_READ_ARB 0x88E1 #define GL_STREAM_COPY_ARB 0x88E2 #define GL_STATIC_DRAW_ARB 0x88E4 #define GL_STATIC_READ_ARB 0x88E5 #define GL_STATIC_COPY_ARB 0x88E6 #define GL_DYNAMIC_DRAW_ARB 0x88E8 #define GL_DYNAMIC_READ_ARB 0x88E9 #define GL_DYNAMIC_COPY_ARB 0x88EA #endif #ifndef GL_ARB_occlusion_query #define GL_QUERY_COUNTER_BITS_ARB 0x8864 #define GL_CURRENT_QUERY_ARB 0x8865 #define GL_QUERY_RESULT_ARB 0x8866 #define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 #define GL_SAMPLES_PASSED_ARB 0x8914 #endif #ifndef GL_ARB_shader_objects #define GL_PROGRAM_OBJECT_ARB 0x8B40 #define GL_SHADER_OBJECT_ARB 0x8B48 #define GL_OBJECT_TYPE_ARB 0x8B4E #define GL_OBJECT_SUBTYPE_ARB 0x8B4F #define GL_FLOAT_VEC2_ARB 0x8B50 #define GL_FLOAT_VEC3_ARB 0x8B51 #define GL_FLOAT_VEC4_ARB 0x8B52 #define GL_INT_VEC2_ARB 0x8B53 #define GL_INT_VEC3_ARB 0x8B54 #define GL_INT_VEC4_ARB 0x8B55 #define GL_BOOL_ARB 0x8B56 #define GL_BOOL_VEC2_ARB 0x8B57 #define GL_BOOL_VEC3_ARB 0x8B58 #define GL_BOOL_VEC4_ARB 0x8B59 #define GL_FLOAT_MAT2_ARB 0x8B5A #define GL_FLOAT_MAT3_ARB 0x8B5B #define GL_FLOAT_MAT4_ARB 0x8B5C #define GL_SAMPLER_1D_ARB 0x8B5D #define GL_SAMPLER_2D_ARB 0x8B5E #define GL_SAMPLER_3D_ARB 0x8B5F #define GL_SAMPLER_CUBE_ARB 0x8B60 #define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 #define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 #define GL_SAMPLER_2D_RECT_ARB 0x8B63 #define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 #define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 #define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 #define GL_OBJECT_LINK_STATUS_ARB 0x8B82 #define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 #define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 #define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 #define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 #define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 #define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 #endif #ifndef GL_ARB_vertex_shader #define GL_VERTEX_SHADER_ARB 0x8B31 #define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A #define GL_MAX_VARYING_FLOATS_ARB 0x8B4B #define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C #define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D #define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 #define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A #endif #ifndef GL_ARB_fragment_shader #define GL_FRAGMENT_SHADER_ARB 0x8B30 #define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 #define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B #endif #ifndef GL_ARB_shading_language_100 #define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C #endif #ifndef GL_ARB_texture_non_power_of_two #endif #ifndef GL_ARB_point_sprite #define GL_POINT_SPRITE_ARB 0x8861 #define GL_COORD_REPLACE_ARB 0x8862 #endif #ifndef GL_ARB_fragment_program_shadow #endif #ifndef GL_ARB_draw_buffers #define GL_MAX_DRAW_BUFFERS_ARB 0x8824 #define GL_DRAW_BUFFER0_ARB 0x8825 #define GL_DRAW_BUFFER1_ARB 0x8826 #define GL_DRAW_BUFFER2_ARB 0x8827 #define GL_DRAW_BUFFER3_ARB 0x8828 #define GL_DRAW_BUFFER4_ARB 0x8829 #define GL_DRAW_BUFFER5_ARB 0x882A #define GL_DRAW_BUFFER6_ARB 0x882B #define GL_DRAW_BUFFER7_ARB 0x882C #define GL_DRAW_BUFFER8_ARB 0x882D #define GL_DRAW_BUFFER9_ARB 0x882E #define GL_DRAW_BUFFER10_ARB 0x882F #define GL_DRAW_BUFFER11_ARB 0x8830 #define GL_DRAW_BUFFER12_ARB 0x8831 #define GL_DRAW_BUFFER13_ARB 0x8832 #define GL_DRAW_BUFFER14_ARB 0x8833 #define GL_DRAW_BUFFER15_ARB 0x8834 #endif #ifndef GL_ARB_texture_rectangle #define GL_TEXTURE_RECTANGLE_ARB 0x84F5 #define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 #define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 #define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 #endif #ifndef GL_ARB_color_buffer_float #define GL_RGBA_FLOAT_MODE_ARB 0x8820 #define GL_CLAMP_VERTEX_COLOR_ARB 0x891A #define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B #define GL_CLAMP_READ_COLOR_ARB 0x891C #define GL_FIXED_ONLY_ARB 0x891D #endif #ifndef GL_ARB_half_float_pixel #define GL_HALF_FLOAT_ARB 0x140B #endif #ifndef GL_ARB_texture_float #define GL_TEXTURE_RED_TYPE_ARB 0x8C10 #define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 #define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 #define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 #define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 #define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 #define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 #define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 #define GL_RGBA32F_ARB 0x8814 #define GL_RGB32F_ARB 0x8815 #define GL_ALPHA32F_ARB 0x8816 #define GL_INTENSITY32F_ARB 0x8817 #define GL_LUMINANCE32F_ARB 0x8818 #define GL_LUMINANCE_ALPHA32F_ARB 0x8819 #define GL_RGBA16F_ARB 0x881A #define GL_RGB16F_ARB 0x881B #define GL_ALPHA16F_ARB 0x881C #define GL_INTENSITY16F_ARB 0x881D #define GL_LUMINANCE16F_ARB 0x881E #define GL_LUMINANCE_ALPHA16F_ARB 0x881F #endif #ifndef GL_ARB_pixel_buffer_object #define GL_PIXEL_PACK_BUFFER_ARB 0x88EB #define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC #define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED #define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF #endif #ifndef GL_ARB_depth_buffer_float #define GL_DEPTH_COMPONENT32F 0x8CAC #define GL_DEPTH32F_STENCIL8 0x8CAD #define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD #endif #ifndef GL_ARB_draw_instanced #endif #ifndef GL_ARB_framebuffer_object #define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 #define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 #define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 #define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 #define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 #define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 #define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 #define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 #define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 #define GL_FRAMEBUFFER_DEFAULT 0x8218 #define GL_FRAMEBUFFER_UNDEFINED 0x8219 #define GL_DEPTH_STENCIL_ATTACHMENT 0x821A #define GL_MAX_RENDERBUFFER_SIZE 0x84E8 #define GL_DEPTH_STENCIL 0x84F9 #define GL_UNSIGNED_INT_24_8 0x84FA #define GL_DEPTH24_STENCIL8 0x88F0 #define GL_TEXTURE_STENCIL_SIZE 0x88F1 #define GL_TEXTURE_RED_TYPE 0x8C10 #define GL_TEXTURE_GREEN_TYPE 0x8C11 #define GL_TEXTURE_BLUE_TYPE 0x8C12 #define GL_TEXTURE_ALPHA_TYPE 0x8C13 #define GL_TEXTURE_DEPTH_TYPE 0x8C16 #define GL_UNSIGNED_NORMALIZED 0x8C17 #define GL_FRAMEBUFFER_BINDING 0x8CA6 #define GL_DRAW_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING #define GL_RENDERBUFFER_BINDING 0x8CA7 #define GL_READ_FRAMEBUFFER 0x8CA8 #define GL_DRAW_FRAMEBUFFER 0x8CA9 #define GL_READ_FRAMEBUFFER_BINDING 0x8CAA #define GL_RENDERBUFFER_SAMPLES 0x8CAB #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 #define GL_FRAMEBUFFER_COMPLETE 0x8CD5 #define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 #define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 #define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB #define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC #define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD #define GL_MAX_COLOR_ATTACHMENTS 0x8CDF #define GL_COLOR_ATTACHMENT0 0x8CE0 #define GL_COLOR_ATTACHMENT1 0x8CE1 #define GL_COLOR_ATTACHMENT2 0x8CE2 #define GL_COLOR_ATTACHMENT3 0x8CE3 #define GL_COLOR_ATTACHMENT4 0x8CE4 #define GL_COLOR_ATTACHMENT5 0x8CE5 #define GL_COLOR_ATTACHMENT6 0x8CE6 #define GL_COLOR_ATTACHMENT7 0x8CE7 #define GL_COLOR_ATTACHMENT8 0x8CE8 #define GL_COLOR_ATTACHMENT9 0x8CE9 #define GL_COLOR_ATTACHMENT10 0x8CEA #define GL_COLOR_ATTACHMENT11 0x8CEB #define GL_COLOR_ATTACHMENT12 0x8CEC #define GL_COLOR_ATTACHMENT13 0x8CED #define GL_COLOR_ATTACHMENT14 0x8CEE #define GL_COLOR_ATTACHMENT15 0x8CEF #define GL_DEPTH_ATTACHMENT 0x8D00 #define GL_STENCIL_ATTACHMENT 0x8D20 #define GL_FRAMEBUFFER 0x8D40 #define GL_RENDERBUFFER 0x8D41 #define GL_RENDERBUFFER_WIDTH 0x8D42 #define GL_RENDERBUFFER_HEIGHT 0x8D43 #define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 #define GL_STENCIL_INDEX1 0x8D46 #define GL_STENCIL_INDEX4 0x8D47 #define GL_STENCIL_INDEX8 0x8D48 #define GL_STENCIL_INDEX16 0x8D49 #define GL_RENDERBUFFER_RED_SIZE 0x8D50 #define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 #define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 #define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 #define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 #define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 #define GL_MAX_SAMPLES 0x8D57 #define GL_INDEX 0x8222 #define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 #define GL_TEXTURE_INTENSITY_TYPE 0x8C15 #endif #ifndef GL_ARB_framebuffer_sRGB #define GL_FRAMEBUFFER_SRGB 0x8DB9 #endif #ifndef GL_ARB_geometry_shader4 #define GL_LINES_ADJACENCY_ARB 0x000A #define GL_LINE_STRIP_ADJACENCY_ARB 0x000B #define GL_TRIANGLES_ADJACENCY_ARB 0x000C #define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0x000D #define GL_PROGRAM_POINT_SIZE_ARB 0x8642 #define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29 #define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7 #define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8 #define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9 #define GL_GEOMETRY_SHADER_ARB 0x8DD9 #define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA #define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB #define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC #define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD #define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE #define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF #define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0 #define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1 /* reuse GL_MAX_VARYING_COMPONENTS */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */ #endif #ifndef GL_ARB_half_float_vertex #define GL_HALF_FLOAT 0x140B #endif #ifndef GL_ARB_instanced_arrays #define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE #endif #ifndef GL_ARB_map_buffer_range #define GL_MAP_READ_BIT 0x0001 #define GL_MAP_WRITE_BIT 0x0002 #define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 #define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 #define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 #define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 #endif #ifndef GL_ARB_texture_buffer_object #define GL_TEXTURE_BUFFER_ARB 0x8C2A #define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B #define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C #define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D #define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E #endif #ifndef GL_ARB_texture_compression_rgtc #define GL_COMPRESSED_RED_RGTC1 0x8DBB #define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC #define GL_COMPRESSED_RG_RGTC2 0x8DBD #define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE #endif #ifndef GL_ARB_texture_rg #define GL_RG 0x8227 #define GL_RG_INTEGER 0x8228 #define GL_R8 0x8229 #define GL_R16 0x822A #define GL_RG8 0x822B #define GL_RG16 0x822C #define GL_R16F 0x822D #define GL_R32F 0x822E #define GL_RG16F 0x822F #define GL_RG32F 0x8230 #define GL_R8I 0x8231 #define GL_R8UI 0x8232 #define GL_R16I 0x8233 #define GL_R16UI 0x8234 #define GL_R32I 0x8235 #define GL_R32UI 0x8236 #define GL_RG8I 0x8237 #define GL_RG8UI 0x8238 #define GL_RG16I 0x8239 #define GL_RG16UI 0x823A #define GL_RG32I 0x823B #define GL_RG32UI 0x823C #endif #ifndef GL_ARB_vertex_array_object #define GL_VERTEX_ARRAY_BINDING 0x85B5 #endif #ifndef GL_ARB_uniform_buffer_object #define GL_UNIFORM_BUFFER 0x8A11 #define GL_UNIFORM_BUFFER_BINDING 0x8A28 #define GL_UNIFORM_BUFFER_START 0x8A29 #define GL_UNIFORM_BUFFER_SIZE 0x8A2A #define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B #define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C #define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D #define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E #define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F #define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 #define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 #define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 #define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 #define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 #define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 #define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 #define GL_UNIFORM_TYPE 0x8A37 #define GL_UNIFORM_SIZE 0x8A38 #define GL_UNIFORM_NAME_LENGTH 0x8A39 #define GL_UNIFORM_BLOCK_INDEX 0x8A3A #define GL_UNIFORM_OFFSET 0x8A3B #define GL_UNIFORM_ARRAY_STRIDE 0x8A3C #define GL_UNIFORM_MATRIX_STRIDE 0x8A3D #define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E #define GL_UNIFORM_BLOCK_BINDING 0x8A3F #define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 #define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 #define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 #define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 #define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 #define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 #define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 #define GL_INVALID_INDEX 0xFFFFFFFFu #endif #ifndef GL_ARB_compatibility /* ARB_compatibility just defines tokens from core 3.0 */ #endif #ifndef GL_ARB_copy_buffer #define GL_COPY_READ_BUFFER_BINDING 0x8F36 #define GL_COPY_READ_BUFFER GL_COPY_READ_BUFFER_BINDING #define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 #define GL_COPY_WRITE_BUFFER GL_COPY_WRITE_BUFFER_BINDING #endif #ifndef GL_ARB_shader_texture_lod #endif #ifndef GL_ARB_depth_clamp #define GL_DEPTH_CLAMP 0x864F #endif #ifndef GL_ARB_draw_elements_base_vertex #endif #ifndef GL_ARB_fragment_coord_conventions #endif #ifndef GL_ARB_provoking_vertex #define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C #define GL_FIRST_VERTEX_CONVENTION 0x8E4D #define GL_LAST_VERTEX_CONVENTION 0x8E4E #define GL_PROVOKING_VERTEX 0x8E4F #endif #ifndef GL_ARB_seamless_cube_map #define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F #endif #ifndef GL_ARB_sync #define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 #define GL_OBJECT_TYPE 0x9112 #define GL_SYNC_CONDITION 0x9113 #define GL_SYNC_STATUS 0x9114 #define GL_SYNC_FLAGS 0x9115 #define GL_SYNC_FENCE 0x9116 #define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 #define GL_UNSIGNALED 0x9118 #define GL_SIGNALED 0x9119 #define GL_ALREADY_SIGNALED 0x911A #define GL_TIMEOUT_EXPIRED 0x911B #define GL_CONDITION_SATISFIED 0x911C #define GL_WAIT_FAILED 0x911D #define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 #define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull #endif #ifndef GL_ARB_texture_multisample #define GL_SAMPLE_POSITION 0x8E50 #define GL_SAMPLE_MASK 0x8E51 #define GL_SAMPLE_MASK_VALUE 0x8E52 #define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 #define GL_TEXTURE_2D_MULTISAMPLE 0x9100 #define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 #define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 #define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 #define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 #define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 #define GL_TEXTURE_SAMPLES 0x9106 #define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 #define GL_SAMPLER_2D_MULTISAMPLE 0x9108 #define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 #define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A #define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B #define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C #define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D #define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E #define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F #define GL_MAX_INTEGER_SAMPLES 0x9110 #endif #ifndef GL_ARB_vertex_array_bgra /* reuse GL_BGRA */ #endif #ifndef GL_ARB_draw_buffers_blend #endif #ifndef GL_ARB_sample_shading #define GL_SAMPLE_SHADING_ARB 0x8C36 #define GL_MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37 #endif #ifndef GL_ARB_texture_cube_map_array #define GL_TEXTURE_CUBE_MAP_ARRAY_ARB 0x9009 #define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A #define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B #define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C #define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D #define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E #define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F #endif #ifndef GL_ARB_texture_gather #define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E #define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F #define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB 0x8F9F #endif #ifndef GL_ARB_texture_query_lod #endif #ifndef GL_ARB_shading_language_include #define GL_SHADER_INCLUDE_ARB 0x8DAE #define GL_NAMED_STRING_LENGTH_ARB 0x8DE9 #define GL_NAMED_STRING_TYPE_ARB 0x8DEA #endif #ifndef GL_ARB_texture_compression_bptc #define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C #define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D #define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E #define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F #endif #ifndef GL_ARB_blend_func_extended #define GL_SRC1_COLOR 0x88F9 /* reuse GL_SRC1_ALPHA */ #define GL_ONE_MINUS_SRC1_COLOR 0x88FA #define GL_ONE_MINUS_SRC1_ALPHA 0x88FB #define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC #endif #ifndef GL_ARB_explicit_attrib_location #endif #ifndef GL_ARB_occlusion_query2 #define GL_ANY_SAMPLES_PASSED 0x8C2F #endif #ifndef GL_ARB_sampler_objects #define GL_SAMPLER_BINDING 0x8919 #endif #ifndef GL_ARB_shader_bit_encoding #endif #ifndef GL_ARB_texture_rgb10_a2ui #define GL_RGB10_A2UI 0x906F #endif #ifndef GL_ARB_texture_swizzle #define GL_TEXTURE_SWIZZLE_R 0x8E42 #define GL_TEXTURE_SWIZZLE_G 0x8E43 #define GL_TEXTURE_SWIZZLE_B 0x8E44 #define GL_TEXTURE_SWIZZLE_A 0x8E45 #define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 #endif #ifndef GL_ARB_timer_query #define GL_TIME_ELAPSED 0x88BF #define GL_TIMESTAMP 0x8E28 #endif #ifndef GL_ARB_vertex_type_2_10_10_10_rev /* reuse GL_UNSIGNED_INT_2_10_10_10_REV */ #define GL_INT_2_10_10_10_REV 0x8D9F #endif #ifndef GL_ARB_draw_indirect #define GL_DRAW_INDIRECT_BUFFER 0x8F3F #define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 #endif #ifndef GL_ARB_gpu_shader5 #define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F #define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A #define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B #define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C #define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D /* reuse GL_MAX_VERTEX_STREAMS */ #endif #ifndef GL_ARB_gpu_shader_fp64 /* reuse GL_DOUBLE */ #define GL_DOUBLE_VEC2 0x8FFC #define GL_DOUBLE_VEC3 0x8FFD #define GL_DOUBLE_VEC4 0x8FFE #define GL_DOUBLE_MAT2 0x8F46 #define GL_DOUBLE_MAT3 0x8F47 #define GL_DOUBLE_MAT4 0x8F48 #define GL_DOUBLE_MAT2x3 0x8F49 #define GL_DOUBLE_MAT2x4 0x8F4A #define GL_DOUBLE_MAT3x2 0x8F4B #define GL_DOUBLE_MAT3x4 0x8F4C #define GL_DOUBLE_MAT4x2 0x8F4D #define GL_DOUBLE_MAT4x3 0x8F4E #endif #ifndef GL_ARB_shader_subroutine #define GL_ACTIVE_SUBROUTINES 0x8DE5 #define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6 #define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47 #define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48 #define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49 #define GL_MAX_SUBROUTINES 0x8DE7 #define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8 #define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A #define GL_COMPATIBLE_SUBROUTINES 0x8E4B /* reuse GL_UNIFORM_SIZE */ /* reuse GL_UNIFORM_NAME_LENGTH */ #endif #ifndef GL_ARB_tessellation_shader #define GL_PATCHES 0x000E #define GL_PATCH_VERTICES 0x8E72 #define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73 #define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74 #define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75 #define GL_TESS_GEN_MODE 0x8E76 #define GL_TESS_GEN_SPACING 0x8E77 #define GL_TESS_GEN_VERTEX_ORDER 0x8E78 #define GL_TESS_GEN_POINT_MODE 0x8E79 /* reuse GL_TRIANGLES */ /* reuse GL_QUADS */ #define GL_ISOLINES 0x8E7A /* reuse GL_EQUAL */ #define GL_FRACTIONAL_ODD 0x8E7B #define GL_FRACTIONAL_EVEN 0x8E7C /* reuse GL_CCW */ /* reuse GL_CW */ #define GL_MAX_PATCH_VERTICES 0x8E7D #define GL_MAX_TESS_GEN_LEVEL 0x8E7E #define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F #define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80 #define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81 #define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82 #define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83 #define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84 #define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85 #define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86 #define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 #define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A #define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C #define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D #define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E #define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F #define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 #define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 #define GL_TESS_EVALUATION_SHADER 0x8E87 #define GL_TESS_CONTROL_SHADER 0x8E88 #endif #ifndef GL_ARB_texture_buffer_object_rgb32 /* reuse GL_RGB32F */ /* reuse GL_RGB32UI */ /* reuse GL_RGB32I */ #endif #ifndef GL_ARB_transform_feedback2 #define GL_TRANSFORM_FEEDBACK 0x8E22 #define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 #define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED GL_TRANSFORM_FEEDBACK_PAUSED #define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 #define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE GL_TRANSFORM_FEEDBACK_ACTIVE #define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 #endif #ifndef GL_ARB_transform_feedback3 #define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 #define GL_MAX_VERTEX_STREAMS 0x8E71 #endif #ifndef GL_ARB_ES2_compatibility #define GL_FIXED 0x140C #define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A #define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B #define GL_LOW_FLOAT 0x8DF0 #define GL_MEDIUM_FLOAT 0x8DF1 #define GL_HIGH_FLOAT 0x8DF2 #define GL_LOW_INT 0x8DF3 #define GL_MEDIUM_INT 0x8DF4 #define GL_HIGH_INT 0x8DF5 #define GL_SHADER_COMPILER 0x8DFA #define GL_SHADER_BINARY_FORMATS 0x8DF8 #define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 #define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB #define GL_MAX_VARYING_VECTORS 0x8DFC #define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD #define GL_RGB565 0x8D62 #endif #ifndef GL_ARB_get_program_binary #define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 #define GL_PROGRAM_BINARY_LENGTH 0x8741 #define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE #define GL_PROGRAM_BINARY_FORMATS 0x87FF #endif #ifndef GL_ARB_separate_shader_objects #define GL_VERTEX_SHADER_BIT 0x00000001 #define GL_FRAGMENT_SHADER_BIT 0x00000002 #define GL_GEOMETRY_SHADER_BIT 0x00000004 #define GL_TESS_CONTROL_SHADER_BIT 0x00000008 #define GL_TESS_EVALUATION_SHADER_BIT 0x00000010 #define GL_ALL_SHADER_BITS 0xFFFFFFFF #define GL_PROGRAM_SEPARABLE 0x8258 #define GL_ACTIVE_PROGRAM 0x8259 #define GL_PROGRAM_PIPELINE_BINDING 0x825A #endif #ifndef GL_ARB_shader_precision #endif #ifndef GL_ARB_vertex_attrib_64bit /* reuse GL_RGB32I */ /* reuse GL_DOUBLE_VEC2 */ /* reuse GL_DOUBLE_VEC3 */ /* reuse GL_DOUBLE_VEC4 */ /* reuse GL_DOUBLE_MAT2 */ /* reuse GL_DOUBLE_MAT3 */ /* reuse GL_DOUBLE_MAT4 */ /* reuse GL_DOUBLE_MAT2x3 */ /* reuse GL_DOUBLE_MAT2x4 */ /* reuse GL_DOUBLE_MAT3x2 */ /* reuse GL_DOUBLE_MAT3x4 */ /* reuse GL_DOUBLE_MAT4x2 */ /* reuse GL_DOUBLE_MAT4x3 */ #endif #ifndef GL_ARB_viewport_array /* reuse GL_SCISSOR_BOX */ /* reuse GL_VIEWPORT */ /* reuse GL_DEPTH_RANGE */ /* reuse GL_SCISSOR_TEST */ #define GL_MAX_VIEWPORTS 0x825B #define GL_VIEWPORT_SUBPIXEL_BITS 0x825C #define GL_VIEWPORT_BOUNDS_RANGE 0x825D #define GL_LAYER_PROVOKING_VERTEX 0x825E #define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F #define GL_UNDEFINED_VERTEX 0x8260 /* reuse GL_FIRST_VERTEX_CONVENTION */ /* reuse GL_LAST_VERTEX_CONVENTION */ /* reuse GL_PROVOKING_VERTEX */ #endif #ifndef GL_ARB_cl_event #define GL_SYNC_CL_EVENT_ARB 0x8240 #define GL_SYNC_CL_EVENT_COMPLETE_ARB 0x8241 #endif #ifndef GL_ARB_debug_output #define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242 #define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243 #define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244 #define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245 #define GL_DEBUG_SOURCE_API_ARB 0x8246 #define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247 #define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248 #define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249 #define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A #define GL_DEBUG_SOURCE_OTHER_ARB 0x824B #define GL_DEBUG_TYPE_ERROR_ARB 0x824C #define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D #define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E #define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F #define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250 #define GL_DEBUG_TYPE_OTHER_ARB 0x8251 #define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143 #define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144 #define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145 #define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146 #define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147 #define GL_DEBUG_SEVERITY_LOW_ARB 0x9148 #endif #ifndef GL_ARB_robustness /* reuse GL_NO_ERROR */ #define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004 #define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 #define GL_GUILTY_CONTEXT_RESET_ARB 0x8253 #define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254 #define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255 #define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 #define GL_NO_RESET_NOTIFICATION_ARB 0x8261 #endif #ifndef GL_ARB_shader_stencil_export #endif #ifndef GL_ARB_base_instance #endif #ifndef GL_ARB_shading_language_420pack #endif #ifndef GL_ARB_transform_feedback_instanced #endif #ifndef GL_ARB_compressed_texture_pixel_storage #define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127 #define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128 #define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129 #define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A #define GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B #define GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C #define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D #define GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E #endif #ifndef GL_ARB_conservative_depth #endif #ifndef GL_ARB_internalformat_query #define GL_NUM_SAMPLE_COUNTS 0x9380 #endif #ifndef GL_ARB_map_buffer_alignment #define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC #endif #ifndef GL_ARB_shader_atomic_counters #define GL_ATOMIC_COUNTER_BUFFER 0x92C0 #define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1 #define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2 #define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3 #define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4 #define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5 #define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6 #define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7 #define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8 #define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9 #define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA #define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB #define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC #define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD #define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE #define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF #define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0 #define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1 #define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2 #define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3 #define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4 #define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5 #define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6 #define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7 #define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8 #define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC #define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9 #define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA #define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB #endif #ifndef GL_ARB_shader_image_load_store #define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 #define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 #define GL_UNIFORM_BARRIER_BIT 0x00000004 #define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 #define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 #define GL_COMMAND_BARRIER_BIT 0x00000040 #define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 #define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 #define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 #define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 #define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 #define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 #define GL_ALL_BARRIER_BITS 0xFFFFFFFF #define GL_MAX_IMAGE_UNITS 0x8F38 #define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39 #define GL_IMAGE_BINDING_NAME 0x8F3A #define GL_IMAGE_BINDING_LEVEL 0x8F3B #define GL_IMAGE_BINDING_LAYERED 0x8F3C #define GL_IMAGE_BINDING_LAYER 0x8F3D #define GL_IMAGE_BINDING_ACCESS 0x8F3E #define GL_IMAGE_1D 0x904C #define GL_IMAGE_2D 0x904D #define GL_IMAGE_3D 0x904E #define GL_IMAGE_2D_RECT 0x904F #define GL_IMAGE_CUBE 0x9050 #define GL_IMAGE_BUFFER 0x9051 #define GL_IMAGE_1D_ARRAY 0x9052 #define GL_IMAGE_2D_ARRAY 0x9053 #define GL_IMAGE_CUBE_MAP_ARRAY 0x9054 #define GL_IMAGE_2D_MULTISAMPLE 0x9055 #define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056 #define GL_INT_IMAGE_1D 0x9057 #define GL_INT_IMAGE_2D 0x9058 #define GL_INT_IMAGE_3D 0x9059 #define GL_INT_IMAGE_2D_RECT 0x905A #define GL_INT_IMAGE_CUBE 0x905B #define GL_INT_IMAGE_BUFFER 0x905C #define GL_INT_IMAGE_1D_ARRAY 0x905D #define GL_INT_IMAGE_2D_ARRAY 0x905E #define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F #define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060 #define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061 #define GL_UNSIGNED_INT_IMAGE_1D 0x9062 #define GL_UNSIGNED_INT_IMAGE_2D 0x9063 #define GL_UNSIGNED_INT_IMAGE_3D 0x9064 #define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065 #define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 #define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067 #define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068 #define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 #define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A #define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B #define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C #define GL_MAX_IMAGE_SAMPLES 0x906D #define GL_IMAGE_BINDING_FORMAT 0x906E #define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7 #define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8 #define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9 #define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA #define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB #define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC #define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD #define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE #define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF #endif #ifndef GL_ARB_shading_language_packing #endif #ifndef GL_ARB_texture_storage #define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F #endif #ifndef GL_KHR_texture_compression_astc_ldr #define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 #define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 #define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 #define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 #define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 #define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 #define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 #define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 #define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 #define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 #define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA #define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB #define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC #define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD #endif #ifndef GL_KHR_debug #define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 #define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 #define GL_DEBUG_CALLBACK_FUNCTION 0x8244 #define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 #define GL_DEBUG_SOURCE_API 0x8246 #define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 #define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 #define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 #define GL_DEBUG_SOURCE_APPLICATION 0x824A #define GL_DEBUG_SOURCE_OTHER 0x824B #define GL_DEBUG_TYPE_ERROR 0x824C #define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D #define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E #define GL_DEBUG_TYPE_PORTABILITY 0x824F #define GL_DEBUG_TYPE_PERFORMANCE 0x8250 #define GL_DEBUG_TYPE_OTHER 0x8251 #define GL_DEBUG_TYPE_MARKER 0x8268 #define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 #define GL_DEBUG_TYPE_POP_GROUP 0x826A #define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B #define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C #define GL_DEBUG_GROUP_STACK_DEPTH 0x826D #define GL_BUFFER 0x82E0 #define GL_SHADER 0x82E1 #define GL_PROGRAM 0x82E2 #define GL_QUERY 0x82E3 #define GL_PROGRAM_PIPELINE 0x82E4 #define GL_SAMPLER 0x82E6 #define GL_DISPLAY_LIST 0x82E7 /* DISPLAY_LIST used in compatibility profile only */ #define GL_MAX_LABEL_LENGTH 0x82E8 #define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 #define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 #define GL_DEBUG_LOGGED_MESSAGES 0x9145 #define GL_DEBUG_SEVERITY_HIGH 0x9146 #define GL_DEBUG_SEVERITY_MEDIUM 0x9147 #define GL_DEBUG_SEVERITY_LOW 0x9148 #define GL_DEBUG_OUTPUT 0x92E0 #define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 /* reuse GL_STACK_UNDERFLOW */ /* reuse GL_STACK_OVERFLOW */ #endif #ifndef GL_ARB_arrays_of_arrays #endif #ifndef GL_ARB_clear_buffer_object #endif #ifndef GL_ARB_compute_shader #define GL_COMPUTE_SHADER 0x91B9 #define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB #define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC #define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD #define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262 #define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263 #define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264 #define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265 #define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266 #define GL_MAX_COMPUTE_LOCAL_INVOCATIONS 0x90EB #define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE #define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF #define GL_COMPUTE_LOCAL_WORK_SIZE 0x8267 #define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC #define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED #define GL_DISPATCH_INDIRECT_BUFFER 0x90EE #define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF #define GL_COMPUTE_SHADER_BIT 0x00000020 #endif #ifndef GL_ARB_copy_image #endif #ifndef GL_ARB_texture_view #define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB #define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC #define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD #define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE #define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF #endif #ifndef GL_ARB_vertex_attrib_binding #define GL_VERTEX_ATTRIB_BINDING 0x82D4 #define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 #define GL_VERTEX_BINDING_DIVISOR 0x82D6 #define GL_VERTEX_BINDING_OFFSET 0x82D7 #define GL_VERTEX_BINDING_STRIDE 0x82D8 #define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 #define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA #endif #ifndef GL_ARB_robustness_isolation #endif #ifndef GL_ARB_ES3_compatibility #define GL_COMPRESSED_RGB8_ETC2 0x9274 #define GL_COMPRESSED_SRGB8_ETC2 0x9275 #define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 #define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 #define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 #define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 #define GL_COMPRESSED_R11_EAC 0x9270 #define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 #define GL_COMPRESSED_RG11_EAC 0x9272 #define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 #define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 #define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A #define GL_MAX_ELEMENT_INDEX 0x8D6B #endif #ifndef GL_ARB_explicit_uniform_location #define GL_MAX_UNIFORM_LOCATIONS 0x826E #endif #ifndef GL_ARB_fragment_layer_viewport #endif #ifndef GL_ARB_framebuffer_no_attachments #define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310 #define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311 #define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312 #define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313 #define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314 #define GL_MAX_FRAMEBUFFER_WIDTH 0x9315 #define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 #define GL_MAX_FRAMEBUFFER_LAYERS 0x9317 #define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 #endif #ifndef GL_ARB_internalformat_query2 /* reuse GL_IMAGE_FORMAT_COMPATIBILITY_TYPE */ /* reuse GL_NUM_SAMPLE_COUNTS */ /* reuse GL_RENDERBUFFER */ /* reuse GL_SAMPLES */ /* reuse GL_TEXTURE_1D */ /* reuse GL_TEXTURE_1D_ARRAY */ /* reuse GL_TEXTURE_2D */ /* reuse GL_TEXTURE_2D_ARRAY */ /* reuse GL_TEXTURE_3D */ /* reuse GL_TEXTURE_CUBE_MAP */ /* reuse GL_TEXTURE_CUBE_MAP_ARRAY */ /* reuse GL_TEXTURE_RECTANGLE */ /* reuse GL_TEXTURE_BUFFER */ /* reuse GL_TEXTURE_2D_MULTISAMPLE */ /* reuse GL_TEXTURE_2D_MULTISAMPLE_ARRAY */ /* reuse GL_TEXTURE_COMPRESSED */ #define GL_INTERNALFORMAT_SUPPORTED 0x826F #define GL_INTERNALFORMAT_PREFERRED 0x8270 #define GL_INTERNALFORMAT_RED_SIZE 0x8271 #define GL_INTERNALFORMAT_GREEN_SIZE 0x8272 #define GL_INTERNALFORMAT_BLUE_SIZE 0x8273 #define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274 #define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275 #define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276 #define GL_INTERNALFORMAT_SHARED_SIZE 0x8277 #define GL_INTERNALFORMAT_RED_TYPE 0x8278 #define GL_INTERNALFORMAT_GREEN_TYPE 0x8279 #define GL_INTERNALFORMAT_BLUE_TYPE 0x827A #define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B #define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C #define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D #define GL_MAX_WIDTH 0x827E #define GL_MAX_HEIGHT 0x827F #define GL_MAX_DEPTH 0x8280 #define GL_MAX_LAYERS 0x8281 #define GL_MAX_COMBINED_DIMENSIONS 0x8282 #define GL_COLOR_COMPONENTS 0x8283 #define GL_DEPTH_COMPONENTS 0x8284 #define GL_STENCIL_COMPONENTS 0x8285 #define GL_COLOR_RENDERABLE 0x8286 #define GL_DEPTH_RENDERABLE 0x8287 #define GL_STENCIL_RENDERABLE 0x8288 #define GL_FRAMEBUFFER_RENDERABLE 0x8289 #define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A #define GL_FRAMEBUFFER_BLEND 0x828B #define GL_READ_PIXELS 0x828C #define GL_READ_PIXELS_FORMAT 0x828D #define GL_READ_PIXELS_TYPE 0x828E #define GL_TEXTURE_IMAGE_FORMAT 0x828F #define GL_TEXTURE_IMAGE_TYPE 0x8290 #define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291 #define GL_GET_TEXTURE_IMAGE_TYPE 0x8292 #define GL_MIPMAP 0x8293 #define GL_MANUAL_GENERATE_MIPMAP 0x8294 #define GL_AUTO_GENERATE_MIPMAP 0x8295 #define GL_COLOR_ENCODING 0x8296 #define GL_SRGB_READ 0x8297 #define GL_SRGB_WRITE 0x8298 #define GL_SRGB_DECODE_ARB 0x8299 #define GL_FILTER 0x829A #define GL_VERTEX_TEXTURE 0x829B #define GL_TESS_CONTROL_TEXTURE 0x829C #define GL_TESS_EVALUATION_TEXTURE 0x829D #define GL_GEOMETRY_TEXTURE 0x829E #define GL_FRAGMENT_TEXTURE 0x829F #define GL_COMPUTE_TEXTURE 0x82A0 #define GL_TEXTURE_SHADOW 0x82A1 #define GL_TEXTURE_GATHER 0x82A2 #define GL_TEXTURE_GATHER_SHADOW 0x82A3 #define GL_SHADER_IMAGE_LOAD 0x82A4 #define GL_SHADER_IMAGE_STORE 0x82A5 #define GL_SHADER_IMAGE_ATOMIC 0x82A6 #define GL_IMAGE_TEXEL_SIZE 0x82A7 #define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8 #define GL_IMAGE_PIXEL_FORMAT 0x82A9 #define GL_IMAGE_PIXEL_TYPE 0x82AA #define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC #define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD #define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE #define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF #define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1 #define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2 #define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3 #define GL_CLEAR_BUFFER 0x82B4 #define GL_TEXTURE_VIEW 0x82B5 #define GL_VIEW_COMPATIBILITY_CLASS 0x82B6 #define GL_FULL_SUPPORT 0x82B7 #define GL_CAVEAT_SUPPORT 0x82B8 #define GL_IMAGE_CLASS_4_X_32 0x82B9 #define GL_IMAGE_CLASS_2_X_32 0x82BA #define GL_IMAGE_CLASS_1_X_32 0x82BB #define GL_IMAGE_CLASS_4_X_16 0x82BC #define GL_IMAGE_CLASS_2_X_16 0x82BD #define GL_IMAGE_CLASS_1_X_16 0x82BE #define GL_IMAGE_CLASS_4_X_8 0x82BF #define GL_IMAGE_CLASS_2_X_8 0x82C0 #define GL_IMAGE_CLASS_1_X_8 0x82C1 #define GL_IMAGE_CLASS_11_11_10 0x82C2 #define GL_IMAGE_CLASS_10_10_10_2 0x82C3 #define GL_VIEW_CLASS_128_BITS 0x82C4 #define GL_VIEW_CLASS_96_BITS 0x82C5 #define GL_VIEW_CLASS_64_BITS 0x82C6 #define GL_VIEW_CLASS_48_BITS 0x82C7 #define GL_VIEW_CLASS_32_BITS 0x82C8 #define GL_VIEW_CLASS_24_BITS 0x82C9 #define GL_VIEW_CLASS_16_BITS 0x82CA #define GL_VIEW_CLASS_8_BITS 0x82CB #define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC #define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD #define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE #define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF #define GL_VIEW_CLASS_RGTC1_RED 0x82D0 #define GL_VIEW_CLASS_RGTC2_RG 0x82D1 #define GL_VIEW_CLASS_BPTC_UNORM 0x82D2 #define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3 #endif #ifndef GL_ARB_invalidate_subdata #endif #ifndef GL_ARB_multi_draw_indirect #endif #ifndef GL_ARB_program_interface_query #define GL_UNIFORM 0x92E1 #define GL_UNIFORM_BLOCK 0x92E2 #define GL_PROGRAM_INPUT 0x92E3 #define GL_PROGRAM_OUTPUT 0x92E4 #define GL_BUFFER_VARIABLE 0x92E5 #define GL_SHADER_STORAGE_BLOCK 0x92E6 /* reuse GL_ATOMIC_COUNTER_BUFFER */ #define GL_VERTEX_SUBROUTINE 0x92E8 #define GL_TESS_CONTROL_SUBROUTINE 0x92E9 #define GL_TESS_EVALUATION_SUBROUTINE 0x92EA #define GL_GEOMETRY_SUBROUTINE 0x92EB #define GL_FRAGMENT_SUBROUTINE 0x92EC #define GL_COMPUTE_SUBROUTINE 0x92ED #define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE #define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF #define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0 #define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1 #define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2 #define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3 #define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4 #define GL_ACTIVE_RESOURCES 0x92F5 #define GL_MAX_NAME_LENGTH 0x92F6 #define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7 #define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8 #define GL_NAME_LENGTH 0x92F9 #define GL_TYPE 0x92FA #define GL_ARRAY_SIZE 0x92FB #define GL_OFFSET 0x92FC #define GL_BLOCK_INDEX 0x92FD #define GL_ARRAY_STRIDE 0x92FE #define GL_MATRIX_STRIDE 0x92FF #define GL_IS_ROW_MAJOR 0x9300 #define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 #define GL_BUFFER_BINDING 0x9302 #define GL_BUFFER_DATA_SIZE 0x9303 #define GL_NUM_ACTIVE_VARIABLES 0x9304 #define GL_ACTIVE_VARIABLES 0x9305 #define GL_REFERENCED_BY_VERTEX_SHADER 0x9306 #define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307 #define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308 #define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309 #define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A #define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B #define GL_TOP_LEVEL_ARRAY_SIZE 0x930C #define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D #define GL_LOCATION 0x930E #define GL_LOCATION_INDEX 0x930F #define GL_IS_PER_PATCH 0x92E7 /* reuse GL_NUM_COMPATIBLE_SUBROUTINES */ /* reuse GL_COMPATIBLE_SUBROUTINES */ #endif #ifndef GL_ARB_robust_buffer_access_behavior #endif #ifndef GL_ARB_shader_image_size #endif #ifndef GL_ARB_shader_storage_buffer_object #define GL_SHADER_STORAGE_BUFFER 0x90D2 #define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3 #define GL_SHADER_STORAGE_BUFFER_START 0x90D4 #define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5 #define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6 #define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7 #define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8 #define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9 #define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA #define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB #define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC #define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD #define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE #define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF #define GL_SHADER_STORAGE_BARRIER_BIT 0x2000 #define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS /* reuse GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS */ #endif #ifndef GL_ARB_stencil_texturing #define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA #endif #ifndef GL_ARB_texture_buffer_range #define GL_TEXTURE_BUFFER_OFFSET 0x919D #define GL_TEXTURE_BUFFER_SIZE 0x919E #define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F #endif #ifndef GL_ARB_texture_query_levels #endif #ifndef GL_ARB_texture_storage_multisample #endif #ifndef GL_EXT_abgr #define GL_ABGR_EXT 0x8000 #endif #ifndef GL_EXT_blend_color #define GL_CONSTANT_COLOR_EXT 0x8001 #define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 #define GL_CONSTANT_ALPHA_EXT 0x8003 #define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 #define GL_BLEND_COLOR_EXT 0x8005 #endif #ifndef GL_EXT_polygon_offset #define GL_POLYGON_OFFSET_EXT 0x8037 #define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 #define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 #endif #ifndef GL_EXT_texture #define GL_ALPHA4_EXT 0x803B #define GL_ALPHA8_EXT 0x803C #define GL_ALPHA12_EXT 0x803D #define GL_ALPHA16_EXT 0x803E #define GL_LUMINANCE4_EXT 0x803F #define GL_LUMINANCE8_EXT 0x8040 #define GL_LUMINANCE12_EXT 0x8041 #define GL_LUMINANCE16_EXT 0x8042 #define GL_LUMINANCE4_ALPHA4_EXT 0x8043 #define GL_LUMINANCE6_ALPHA2_EXT 0x8044 #define GL_LUMINANCE8_ALPHA8_EXT 0x8045 #define GL_LUMINANCE12_ALPHA4_EXT 0x8046 #define GL_LUMINANCE12_ALPHA12_EXT 0x8047 #define GL_LUMINANCE16_ALPHA16_EXT 0x8048 #define GL_INTENSITY_EXT 0x8049 #define GL_INTENSITY4_EXT 0x804A #define GL_INTENSITY8_EXT 0x804B #define GL_INTENSITY12_EXT 0x804C #define GL_INTENSITY16_EXT 0x804D #define GL_RGB2_EXT 0x804E #define GL_RGB4_EXT 0x804F #define GL_RGB5_EXT 0x8050 #define GL_RGB8_EXT 0x8051 #define GL_RGB10_EXT 0x8052 #define GL_RGB12_EXT 0x8053 #define GL_RGB16_EXT 0x8054 #define GL_RGBA2_EXT 0x8055 #define GL_RGBA4_EXT 0x8056 #define GL_RGB5_A1_EXT 0x8057 #define GL_RGBA8_EXT 0x8058 #define GL_RGB10_A2_EXT 0x8059 #define GL_RGBA12_EXT 0x805A #define GL_RGBA16_EXT 0x805B #define GL_TEXTURE_RED_SIZE_EXT 0x805C #define GL_TEXTURE_GREEN_SIZE_EXT 0x805D #define GL_TEXTURE_BLUE_SIZE_EXT 0x805E #define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F #define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 #define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 #define GL_REPLACE_EXT 0x8062 #define GL_PROXY_TEXTURE_1D_EXT 0x8063 #define GL_PROXY_TEXTURE_2D_EXT 0x8064 #define GL_TEXTURE_TOO_LARGE_EXT 0x8065 #endif #ifndef GL_EXT_texture3D #define GL_PACK_SKIP_IMAGES_EXT 0x806B #define GL_PACK_IMAGE_HEIGHT_EXT 0x806C #define GL_UNPACK_SKIP_IMAGES_EXT 0x806D #define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E #define GL_TEXTURE_3D_EXT 0x806F #define GL_PROXY_TEXTURE_3D_EXT 0x8070 #define GL_TEXTURE_DEPTH_EXT 0x8071 #define GL_TEXTURE_WRAP_R_EXT 0x8072 #define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 #endif #ifndef GL_SGIS_texture_filter4 #define GL_FILTER4_SGIS 0x8146 #define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147 #endif #ifndef GL_EXT_subtexture #endif #ifndef GL_EXT_copy_texture #endif #ifndef GL_EXT_histogram #define GL_HISTOGRAM_EXT 0x8024 #define GL_PROXY_HISTOGRAM_EXT 0x8025 #define GL_HISTOGRAM_WIDTH_EXT 0x8026 #define GL_HISTOGRAM_FORMAT_EXT 0x8027 #define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 #define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 #define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A #define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B #define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C #define GL_HISTOGRAM_SINK_EXT 0x802D #define GL_MINMAX_EXT 0x802E #define GL_MINMAX_FORMAT_EXT 0x802F #define GL_MINMAX_SINK_EXT 0x8030 #define GL_TABLE_TOO_LARGE_EXT 0x8031 #endif #ifndef GL_EXT_convolution #define GL_CONVOLUTION_1D_EXT 0x8010 #define GL_CONVOLUTION_2D_EXT 0x8011 #define GL_SEPARABLE_2D_EXT 0x8012 #define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 #define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 #define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 #define GL_REDUCE_EXT 0x8016 #define GL_CONVOLUTION_FORMAT_EXT 0x8017 #define GL_CONVOLUTION_WIDTH_EXT 0x8018 #define GL_CONVOLUTION_HEIGHT_EXT 0x8019 #define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A #define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B #define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C #define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D #define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E #define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F #define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 #define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 #define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 #define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 #endif #ifndef GL_SGI_color_matrix #define GL_COLOR_MATRIX_SGI 0x80B1 #define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 #define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 #define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 #define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 #define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 #define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 #define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 #define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 #define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA #define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB #endif #ifndef GL_SGI_color_table #define GL_COLOR_TABLE_SGI 0x80D0 #define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 #define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 #define GL_PROXY_COLOR_TABLE_SGI 0x80D3 #define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 #define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 #define GL_COLOR_TABLE_SCALE_SGI 0x80D6 #define GL_COLOR_TABLE_BIAS_SGI 0x80D7 #define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 #define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 #define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA #define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB #define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC #define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD #define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE #define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF #endif #ifndef GL_SGIS_pixel_texture #define GL_PIXEL_TEXTURE_SGIS 0x8353 #define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354 #define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355 #define GL_PIXEL_GROUP_COLOR_SGIS 0x8356 #endif #ifndef GL_SGIX_pixel_texture #define GL_PIXEL_TEX_GEN_SGIX 0x8139 #define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B #endif #ifndef GL_SGIS_texture4D #define GL_PACK_SKIP_VOLUMES_SGIS 0x8130 #define GL_PACK_IMAGE_DEPTH_SGIS 0x8131 #define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 #define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 #define GL_TEXTURE_4D_SGIS 0x8134 #define GL_PROXY_TEXTURE_4D_SGIS 0x8135 #define GL_TEXTURE_4DSIZE_SGIS 0x8136 #define GL_TEXTURE_WRAP_Q_SGIS 0x8137 #define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138 #define GL_TEXTURE_4D_BINDING_SGIS 0x814F #endif #ifndef GL_SGI_texture_color_table #define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC #define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD #endif #ifndef GL_EXT_cmyka #define GL_CMYK_EXT 0x800C #define GL_CMYKA_EXT 0x800D #define GL_PACK_CMYK_HINT_EXT 0x800E #define GL_UNPACK_CMYK_HINT_EXT 0x800F #endif #ifndef GL_EXT_texture_object #define GL_TEXTURE_PRIORITY_EXT 0x8066 #define GL_TEXTURE_RESIDENT_EXT 0x8067 #define GL_TEXTURE_1D_BINDING_EXT 0x8068 #define GL_TEXTURE_2D_BINDING_EXT 0x8069 #define GL_TEXTURE_3D_BINDING_EXT 0x806A #endif #ifndef GL_SGIS_detail_texture #define GL_DETAIL_TEXTURE_2D_SGIS 0x8095 #define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096 #define GL_LINEAR_DETAIL_SGIS 0x8097 #define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098 #define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099 #define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A #define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B #define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C #endif #ifndef GL_SGIS_sharpen_texture #define GL_LINEAR_SHARPEN_SGIS 0x80AD #define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE #define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF #define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0 #endif #ifndef GL_EXT_packed_pixels #define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 #define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 #define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 #define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 #define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 #endif #ifndef GL_SGIS_texture_lod #define GL_TEXTURE_MIN_LOD_SGIS 0x813A #define GL_TEXTURE_MAX_LOD_SGIS 0x813B #define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C #define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D #endif #ifndef GL_SGIS_multisample #define GL_MULTISAMPLE_SGIS 0x809D #define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E #define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F #define GL_SAMPLE_MASK_SGIS 0x80A0 #define GL_1PASS_SGIS 0x80A1 #define GL_2PASS_0_SGIS 0x80A2 #define GL_2PASS_1_SGIS 0x80A3 #define GL_4PASS_0_SGIS 0x80A4 #define GL_4PASS_1_SGIS 0x80A5 #define GL_4PASS_2_SGIS 0x80A6 #define GL_4PASS_3_SGIS 0x80A7 #define GL_SAMPLE_BUFFERS_SGIS 0x80A8 #define GL_SAMPLES_SGIS 0x80A9 #define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA #define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB #define GL_SAMPLE_PATTERN_SGIS 0x80AC #endif #ifndef GL_EXT_rescale_normal #define GL_RESCALE_NORMAL_EXT 0x803A #endif #ifndef GL_EXT_vertex_array #define GL_VERTEX_ARRAY_EXT 0x8074 #define GL_NORMAL_ARRAY_EXT 0x8075 #define GL_COLOR_ARRAY_EXT 0x8076 #define GL_INDEX_ARRAY_EXT 0x8077 #define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 #define GL_EDGE_FLAG_ARRAY_EXT 0x8079 #define GL_VERTEX_ARRAY_SIZE_EXT 0x807A #define GL_VERTEX_ARRAY_TYPE_EXT 0x807B #define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C #define GL_VERTEX_ARRAY_COUNT_EXT 0x807D #define GL_NORMAL_ARRAY_TYPE_EXT 0x807E #define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F #define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 #define GL_COLOR_ARRAY_SIZE_EXT 0x8081 #define GL_COLOR_ARRAY_TYPE_EXT 0x8082 #define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 #define GL_COLOR_ARRAY_COUNT_EXT 0x8084 #define GL_INDEX_ARRAY_TYPE_EXT 0x8085 #define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 #define GL_INDEX_ARRAY_COUNT_EXT 0x8087 #define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 #define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 #define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A #define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B #define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C #define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D #define GL_VERTEX_ARRAY_POINTER_EXT 0x808E #define GL_NORMAL_ARRAY_POINTER_EXT 0x808F #define GL_COLOR_ARRAY_POINTER_EXT 0x8090 #define GL_INDEX_ARRAY_POINTER_EXT 0x8091 #define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 #define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 #endif #ifndef GL_EXT_misc_attribute #endif #ifndef GL_SGIS_generate_mipmap #define GL_GENERATE_MIPMAP_SGIS 0x8191 #define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 #endif #ifndef GL_SGIX_clipmap #define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 #define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171 #define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172 #define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173 #define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174 #define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175 #define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176 #define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177 #define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 #define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D #define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E #define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F #endif #ifndef GL_SGIX_shadow #define GL_TEXTURE_COMPARE_SGIX 0x819A #define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B #define GL_TEXTURE_LEQUAL_R_SGIX 0x819C #define GL_TEXTURE_GEQUAL_R_SGIX 0x819D #endif #ifndef GL_SGIS_texture_edge_clamp #define GL_CLAMP_TO_EDGE_SGIS 0x812F #endif #ifndef GL_SGIS_texture_border_clamp #define GL_CLAMP_TO_BORDER_SGIS 0x812D #endif #ifndef GL_EXT_blend_minmax #define GL_FUNC_ADD_EXT 0x8006 #define GL_MIN_EXT 0x8007 #define GL_MAX_EXT 0x8008 #define GL_BLEND_EQUATION_EXT 0x8009 #endif #ifndef GL_EXT_blend_subtract #define GL_FUNC_SUBTRACT_EXT 0x800A #define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B #endif #ifndef GL_EXT_blend_logic_op #endif #ifndef GL_SGIX_interlace #define GL_INTERLACE_SGIX 0x8094 #endif #ifndef GL_SGIX_pixel_tiles #define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E #define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F #define GL_PIXEL_TILE_WIDTH_SGIX 0x8140 #define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141 #define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142 #define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143 #define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144 #define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145 #endif #ifndef GL_SGIS_texture_select #define GL_DUAL_ALPHA4_SGIS 0x8110 #define GL_DUAL_ALPHA8_SGIS 0x8111 #define GL_DUAL_ALPHA12_SGIS 0x8112 #define GL_DUAL_ALPHA16_SGIS 0x8113 #define GL_DUAL_LUMINANCE4_SGIS 0x8114 #define GL_DUAL_LUMINANCE8_SGIS 0x8115 #define GL_DUAL_LUMINANCE12_SGIS 0x8116 #define GL_DUAL_LUMINANCE16_SGIS 0x8117 #define GL_DUAL_INTENSITY4_SGIS 0x8118 #define GL_DUAL_INTENSITY8_SGIS 0x8119 #define GL_DUAL_INTENSITY12_SGIS 0x811A #define GL_DUAL_INTENSITY16_SGIS 0x811B #define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C #define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D #define GL_QUAD_ALPHA4_SGIS 0x811E #define GL_QUAD_ALPHA8_SGIS 0x811F #define GL_QUAD_LUMINANCE4_SGIS 0x8120 #define GL_QUAD_LUMINANCE8_SGIS 0x8121 #define GL_QUAD_INTENSITY4_SGIS 0x8122 #define GL_QUAD_INTENSITY8_SGIS 0x8123 #define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124 #define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125 #endif #ifndef GL_SGIX_sprite #define GL_SPRITE_SGIX 0x8148 #define GL_SPRITE_MODE_SGIX 0x8149 #define GL_SPRITE_AXIS_SGIX 0x814A #define GL_SPRITE_TRANSLATION_SGIX 0x814B #define GL_SPRITE_AXIAL_SGIX 0x814C #define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D #define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E #endif #ifndef GL_SGIX_texture_multi_buffer #define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E #endif #ifndef GL_EXT_point_parameters #define GL_POINT_SIZE_MIN_EXT 0x8126 #define GL_POINT_SIZE_MAX_EXT 0x8127 #define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 #define GL_DISTANCE_ATTENUATION_EXT 0x8129 #endif #ifndef GL_SGIS_point_parameters #define GL_POINT_SIZE_MIN_SGIS 0x8126 #define GL_POINT_SIZE_MAX_SGIS 0x8127 #define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128 #define GL_DISTANCE_ATTENUATION_SGIS 0x8129 #endif #ifndef GL_SGIX_instruments #define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 #define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 #endif #ifndef GL_SGIX_texture_scale_bias #define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 #define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A #define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B #define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C #endif #ifndef GL_SGIX_framezoom #define GL_FRAMEZOOM_SGIX 0x818B #define GL_FRAMEZOOM_FACTOR_SGIX 0x818C #define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D #endif #ifndef GL_SGIX_tag_sample_buffer #endif #ifndef GL_FfdMaskSGIX #define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001 #define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002 #endif #ifndef GL_SGIX_polynomial_ffd #define GL_GEOMETRY_DEFORMATION_SGIX 0x8194 #define GL_TEXTURE_DEFORMATION_SGIX 0x8195 #define GL_DEFORMATIONS_MASK_SGIX 0x8196 #define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197 #endif #ifndef GL_SGIX_reference_plane #define GL_REFERENCE_PLANE_SGIX 0x817D #define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E #endif #ifndef GL_SGIX_flush_raster #endif #ifndef GL_SGIX_depth_texture #define GL_DEPTH_COMPONENT16_SGIX 0x81A5 #define GL_DEPTH_COMPONENT24_SGIX 0x81A6 #define GL_DEPTH_COMPONENT32_SGIX 0x81A7 #endif #ifndef GL_SGIS_fog_function #define GL_FOG_FUNC_SGIS 0x812A #define GL_FOG_FUNC_POINTS_SGIS 0x812B #define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C #endif #ifndef GL_SGIX_fog_offset #define GL_FOG_OFFSET_SGIX 0x8198 #define GL_FOG_OFFSET_VALUE_SGIX 0x8199 #endif #ifndef GL_HP_image_transform #define GL_IMAGE_SCALE_X_HP 0x8155 #define GL_IMAGE_SCALE_Y_HP 0x8156 #define GL_IMAGE_TRANSLATE_X_HP 0x8157 #define GL_IMAGE_TRANSLATE_Y_HP 0x8158 #define GL_IMAGE_ROTATE_ANGLE_HP 0x8159 #define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A #define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B #define GL_IMAGE_MAG_FILTER_HP 0x815C #define GL_IMAGE_MIN_FILTER_HP 0x815D #define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E #define GL_CUBIC_HP 0x815F #define GL_AVERAGE_HP 0x8160 #define GL_IMAGE_TRANSFORM_2D_HP 0x8161 #define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162 #define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163 #endif #ifndef GL_HP_convolution_border_modes #define GL_IGNORE_BORDER_HP 0x8150 #define GL_CONSTANT_BORDER_HP 0x8151 #define GL_REPLICATE_BORDER_HP 0x8153 #define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154 #endif #ifndef GL_INGR_palette_buffer #endif #ifndef GL_SGIX_texture_add_env #define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE #endif #ifndef GL_EXT_color_subtable #endif #ifndef GL_PGI_vertex_hints #define GL_VERTEX_DATA_HINT_PGI 0x1A22A #define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B #define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C #define GL_MAX_VERTEX_HINT_PGI 0x1A22D #define GL_COLOR3_BIT_PGI 0x00010000 #define GL_COLOR4_BIT_PGI 0x00020000 #define GL_EDGEFLAG_BIT_PGI 0x00040000 #define GL_INDEX_BIT_PGI 0x00080000 #define GL_MAT_AMBIENT_BIT_PGI 0x00100000 #define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 #define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 #define GL_MAT_EMISSION_BIT_PGI 0x00800000 #define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 #define GL_MAT_SHININESS_BIT_PGI 0x02000000 #define GL_MAT_SPECULAR_BIT_PGI 0x04000000 #define GL_NORMAL_BIT_PGI 0x08000000 #define GL_TEXCOORD1_BIT_PGI 0x10000000 #define GL_TEXCOORD2_BIT_PGI 0x20000000 #define GL_TEXCOORD3_BIT_PGI 0x40000000 #define GL_TEXCOORD4_BIT_PGI 0x80000000 #define GL_VERTEX23_BIT_PGI 0x00000004 #define GL_VERTEX4_BIT_PGI 0x00000008 #endif #ifndef GL_PGI_misc_hints #define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 #define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD #define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE #define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202 #define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203 #define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204 #define GL_ALWAYS_FAST_HINT_PGI 0x1A20C #define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D #define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E #define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F #define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210 #define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211 #define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216 #define GL_STRICT_LIGHTING_HINT_PGI 0x1A217 #define GL_STRICT_SCISSOR_HINT_PGI 0x1A218 #define GL_FULL_STIPPLE_HINT_PGI 0x1A219 #define GL_CLIP_NEAR_HINT_PGI 0x1A220 #define GL_CLIP_FAR_HINT_PGI 0x1A221 #define GL_WIDE_LINE_HINT_PGI 0x1A222 #define GL_BACK_NORMALS_HINT_PGI 0x1A223 #endif #ifndef GL_EXT_paletted_texture #define GL_COLOR_INDEX1_EXT 0x80E2 #define GL_COLOR_INDEX2_EXT 0x80E3 #define GL_COLOR_INDEX4_EXT 0x80E4 #define GL_COLOR_INDEX8_EXT 0x80E5 #define GL_COLOR_INDEX12_EXT 0x80E6 #define GL_COLOR_INDEX16_EXT 0x80E7 #define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED #endif #ifndef GL_EXT_clip_volume_hint #define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 #endif #ifndef GL_SGIX_list_priority #define GL_LIST_PRIORITY_SGIX 0x8182 #endif #ifndef GL_SGIX_ir_instrument1 #define GL_IR_INSTRUMENT1_SGIX 0x817F #endif #ifndef GL_SGIX_calligraphic_fragment #define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183 #endif #ifndef GL_SGIX_texture_lod_bias #define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E #define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F #define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190 #endif #ifndef GL_SGIX_shadow_ambient #define GL_SHADOW_AMBIENT_SGIX 0x80BF #endif #ifndef GL_EXT_index_texture #endif #ifndef GL_EXT_index_material #define GL_INDEX_MATERIAL_EXT 0x81B8 #define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9 #define GL_INDEX_MATERIAL_FACE_EXT 0x81BA #endif #ifndef GL_EXT_index_func #define GL_INDEX_TEST_EXT 0x81B5 #define GL_INDEX_TEST_FUNC_EXT 0x81B6 #define GL_INDEX_TEST_REF_EXT 0x81B7 #endif #ifndef GL_EXT_index_array_formats #define GL_IUI_V2F_EXT 0x81AD #define GL_IUI_V3F_EXT 0x81AE #define GL_IUI_N3F_V2F_EXT 0x81AF #define GL_IUI_N3F_V3F_EXT 0x81B0 #define GL_T2F_IUI_V2F_EXT 0x81B1 #define GL_T2F_IUI_V3F_EXT 0x81B2 #define GL_T2F_IUI_N3F_V2F_EXT 0x81B3 #define GL_T2F_IUI_N3F_V3F_EXT 0x81B4 #endif #ifndef GL_EXT_compiled_vertex_array #define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 #define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 #endif #ifndef GL_EXT_cull_vertex #define GL_CULL_VERTEX_EXT 0x81AA #define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB #define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC #endif #ifndef GL_SGIX_ycrcb #define GL_YCRCB_422_SGIX 0x81BB #define GL_YCRCB_444_SGIX 0x81BC #endif #ifndef GL_SGIX_fragment_lighting #define GL_FRAGMENT_LIGHTING_SGIX 0x8400 #define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401 #define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402 #define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403 #define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404 #define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405 #define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406 #define GL_LIGHT_ENV_MODE_SGIX 0x8407 #define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 #define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 #define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A #define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B #define GL_FRAGMENT_LIGHT0_SGIX 0x840C #define GL_FRAGMENT_LIGHT1_SGIX 0x840D #define GL_FRAGMENT_LIGHT2_SGIX 0x840E #define GL_FRAGMENT_LIGHT3_SGIX 0x840F #define GL_FRAGMENT_LIGHT4_SGIX 0x8410 #define GL_FRAGMENT_LIGHT5_SGIX 0x8411 #define GL_FRAGMENT_LIGHT6_SGIX 0x8412 #define GL_FRAGMENT_LIGHT7_SGIX 0x8413 #endif #ifndef GL_IBM_rasterpos_clip #define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262 #endif #ifndef GL_HP_texture_lighting #define GL_TEXTURE_LIGHTING_MODE_HP 0x8167 #define GL_TEXTURE_POST_SPECULAR_HP 0x8168 #define GL_TEXTURE_PRE_SPECULAR_HP 0x8169 #endif #ifndef GL_EXT_draw_range_elements #define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 #define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 #endif #ifndef GL_WIN_phong_shading #define GL_PHONG_WIN 0x80EA #define GL_PHONG_HINT_WIN 0x80EB #endif #ifndef GL_WIN_specular_fog #define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC #endif #ifndef GL_EXT_light_texture #define GL_FRAGMENT_MATERIAL_EXT 0x8349 #define GL_FRAGMENT_NORMAL_EXT 0x834A #define GL_FRAGMENT_COLOR_EXT 0x834C #define GL_ATTENUATION_EXT 0x834D #define GL_SHADOW_ATTENUATION_EXT 0x834E #define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F #define GL_TEXTURE_LIGHT_EXT 0x8350 #define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 #define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 /* reuse GL_FRAGMENT_DEPTH_EXT */ #endif #ifndef GL_SGIX_blend_alpha_minmax #define GL_ALPHA_MIN_SGIX 0x8320 #define GL_ALPHA_MAX_SGIX 0x8321 #endif #ifndef GL_SGIX_impact_pixel_texture #define GL_PIXEL_TEX_GEN_Q_CEILING_SGIX 0x8184 #define GL_PIXEL_TEX_GEN_Q_ROUND_SGIX 0x8185 #define GL_PIXEL_TEX_GEN_Q_FLOOR_SGIX 0x8186 #define GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX 0x8187 #define GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX 0x8188 #define GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX 0x8189 #define GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX 0x818A #endif #ifndef GL_EXT_bgra #define GL_BGR_EXT 0x80E0 #define GL_BGRA_EXT 0x80E1 #endif #ifndef GL_SGIX_async #define GL_ASYNC_MARKER_SGIX 0x8329 #endif #ifndef GL_SGIX_async_pixel #define GL_ASYNC_TEX_IMAGE_SGIX 0x835C #define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D #define GL_ASYNC_READ_PIXELS_SGIX 0x835E #define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F #define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 #define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 #endif #ifndef GL_SGIX_async_histogram #define GL_ASYNC_HISTOGRAM_SGIX 0x832C #define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D #endif #ifndef GL_INTEL_texture_scissor #endif #ifndef GL_INTEL_parallel_arrays #define GL_PARALLEL_ARRAYS_INTEL 0x83F4 #define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 #define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 #define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 #define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 #endif #ifndef GL_HP_occlusion_test #define GL_OCCLUSION_TEST_HP 0x8165 #define GL_OCCLUSION_TEST_RESULT_HP 0x8166 #endif #ifndef GL_EXT_pixel_transform #define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 #define GL_PIXEL_MAG_FILTER_EXT 0x8331 #define GL_PIXEL_MIN_FILTER_EXT 0x8332 #define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 #define GL_CUBIC_EXT 0x8334 #define GL_AVERAGE_EXT 0x8335 #define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 #define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 #define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 #endif #ifndef GL_EXT_pixel_transform_color_table #endif #ifndef GL_EXT_shared_texture_palette #define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB #endif #ifndef GL_EXT_separate_specular_color #define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 #define GL_SINGLE_COLOR_EXT 0x81F9 #define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA #endif #ifndef GL_EXT_secondary_color #define GL_COLOR_SUM_EXT 0x8458 #define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 #define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A #define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B #define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C #define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D #define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E #endif #ifndef GL_EXT_texture_perturb_normal #define GL_PERTURB_EXT 0x85AE #define GL_TEXTURE_NORMAL_EXT 0x85AF #endif #ifndef GL_EXT_multi_draw_arrays #endif #ifndef GL_EXT_fog_coord #define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 #define GL_FOG_COORDINATE_EXT 0x8451 #define GL_FRAGMENT_DEPTH_EXT 0x8452 #define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 #define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 #define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 #define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 #define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 #endif #ifndef GL_REND_screen_coordinates #define GL_SCREEN_COORDINATES_REND 0x8490 #define GL_INVERTED_SCREEN_W_REND 0x8491 #endif #ifndef GL_EXT_coordinate_frame #define GL_TANGENT_ARRAY_EXT 0x8439 #define GL_BINORMAL_ARRAY_EXT 0x843A #define GL_CURRENT_TANGENT_EXT 0x843B #define GL_CURRENT_BINORMAL_EXT 0x843C #define GL_TANGENT_ARRAY_TYPE_EXT 0x843E #define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F #define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 #define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 #define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 #define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 #define GL_MAP1_TANGENT_EXT 0x8444 #define GL_MAP2_TANGENT_EXT 0x8445 #define GL_MAP1_BINORMAL_EXT 0x8446 #define GL_MAP2_BINORMAL_EXT 0x8447 #endif #ifndef GL_EXT_texture_env_combine #define GL_COMBINE_EXT 0x8570 #define GL_COMBINE_RGB_EXT 0x8571 #define GL_COMBINE_ALPHA_EXT 0x8572 #define GL_RGB_SCALE_EXT 0x8573 #define GL_ADD_SIGNED_EXT 0x8574 #define GL_INTERPOLATE_EXT 0x8575 #define GL_CONSTANT_EXT 0x8576 #define GL_PRIMARY_COLOR_EXT 0x8577 #define GL_PREVIOUS_EXT 0x8578 #define GL_SOURCE0_RGB_EXT 0x8580 #define GL_SOURCE1_RGB_EXT 0x8581 #define GL_SOURCE2_RGB_EXT 0x8582 #define GL_SOURCE0_ALPHA_EXT 0x8588 #define GL_SOURCE1_ALPHA_EXT 0x8589 #define GL_SOURCE2_ALPHA_EXT 0x858A #define GL_OPERAND0_RGB_EXT 0x8590 #define GL_OPERAND1_RGB_EXT 0x8591 #define GL_OPERAND2_RGB_EXT 0x8592 #define GL_OPERAND0_ALPHA_EXT 0x8598 #define GL_OPERAND1_ALPHA_EXT 0x8599 #define GL_OPERAND2_ALPHA_EXT 0x859A #endif #ifndef GL_APPLE_specular_vector #define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 #endif #ifndef GL_APPLE_transform_hint #define GL_TRANSFORM_HINT_APPLE 0x85B1 #endif #ifndef GL_SGIX_fog_scale #define GL_FOG_SCALE_SGIX 0x81FC #define GL_FOG_SCALE_VALUE_SGIX 0x81FD #endif #ifndef GL_SUNX_constant_data #define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 #define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 #endif #ifndef GL_SUN_global_alpha #define GL_GLOBAL_ALPHA_SUN 0x81D9 #define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA #endif #ifndef GL_SUN_triangle_list #define GL_RESTART_SUN 0x0001 #define GL_REPLACE_MIDDLE_SUN 0x0002 #define GL_REPLACE_OLDEST_SUN 0x0003 #define GL_TRIANGLE_LIST_SUN 0x81D7 #define GL_REPLACEMENT_CODE_SUN 0x81D8 #define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 #define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 #define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 #define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 #define GL_R1UI_V3F_SUN 0x85C4 #define GL_R1UI_C4UB_V3F_SUN 0x85C5 #define GL_R1UI_C3F_V3F_SUN 0x85C6 #define GL_R1UI_N3F_V3F_SUN 0x85C7 #define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 #define GL_R1UI_T2F_V3F_SUN 0x85C9 #define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA #define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB #endif #ifndef GL_SUN_vertex #endif #ifndef GL_EXT_blend_func_separate #define GL_BLEND_DST_RGB_EXT 0x80C8 #define GL_BLEND_SRC_RGB_EXT 0x80C9 #define GL_BLEND_DST_ALPHA_EXT 0x80CA #define GL_BLEND_SRC_ALPHA_EXT 0x80CB #endif #ifndef GL_INGR_color_clamp #define GL_RED_MIN_CLAMP_INGR 0x8560 #define GL_GREEN_MIN_CLAMP_INGR 0x8561 #define GL_BLUE_MIN_CLAMP_INGR 0x8562 #define GL_ALPHA_MIN_CLAMP_INGR 0x8563 #define GL_RED_MAX_CLAMP_INGR 0x8564 #define GL_GREEN_MAX_CLAMP_INGR 0x8565 #define GL_BLUE_MAX_CLAMP_INGR 0x8566 #define GL_ALPHA_MAX_CLAMP_INGR 0x8567 #endif #ifndef GL_INGR_interlace_read #define GL_INTERLACE_READ_INGR 0x8568 #endif #ifndef GL_EXT_stencil_wrap #define GL_INCR_WRAP_EXT 0x8507 #define GL_DECR_WRAP_EXT 0x8508 #endif #ifndef GL_EXT_422_pixels #define GL_422_EXT 0x80CC #define GL_422_REV_EXT 0x80CD #define GL_422_AVERAGE_EXT 0x80CE #define GL_422_REV_AVERAGE_EXT 0x80CF #endif #ifndef GL_NV_texgen_reflection #define GL_NORMAL_MAP_NV 0x8511 #define GL_REFLECTION_MAP_NV 0x8512 #endif #ifndef GL_EXT_texture_cube_map #define GL_NORMAL_MAP_EXT 0x8511 #define GL_REFLECTION_MAP_EXT 0x8512 #define GL_TEXTURE_CUBE_MAP_EXT 0x8513 #define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 #define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A #define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B #define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C #endif #ifndef GL_SUN_convolution_border_modes #define GL_WRAP_BORDER_SUN 0x81D4 #endif #ifndef GL_EXT_texture_env_add #endif #ifndef GL_EXT_texture_lod_bias #define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD #define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 #define GL_TEXTURE_LOD_BIAS_EXT 0x8501 #endif #ifndef GL_EXT_texture_filter_anisotropic #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF #endif #ifndef GL_EXT_vertex_weighting #define GL_MODELVIEW0_STACK_DEPTH_EXT GL_MODELVIEW_STACK_DEPTH #define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 #define GL_MODELVIEW0_MATRIX_EXT GL_MODELVIEW_MATRIX #define GL_MODELVIEW1_MATRIX_EXT 0x8506 #define GL_VERTEX_WEIGHTING_EXT 0x8509 #define GL_MODELVIEW0_EXT GL_MODELVIEW #define GL_MODELVIEW1_EXT 0x850A #define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B #define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C #define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D #define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E #define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F #define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 #endif #ifndef GL_NV_light_max_exponent #define GL_MAX_SHININESS_NV 0x8504 #define GL_MAX_SPOT_EXPONENT_NV 0x8505 #endif #ifndef GL_NV_vertex_array_range #define GL_VERTEX_ARRAY_RANGE_NV 0x851D #define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E #define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F #define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 #define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 #endif #ifndef GL_NV_register_combiners #define GL_REGISTER_COMBINERS_NV 0x8522 #define GL_VARIABLE_A_NV 0x8523 #define GL_VARIABLE_B_NV 0x8524 #define GL_VARIABLE_C_NV 0x8525 #define GL_VARIABLE_D_NV 0x8526 #define GL_VARIABLE_E_NV 0x8527 #define GL_VARIABLE_F_NV 0x8528 #define GL_VARIABLE_G_NV 0x8529 #define GL_CONSTANT_COLOR0_NV 0x852A #define GL_CONSTANT_COLOR1_NV 0x852B #define GL_PRIMARY_COLOR_NV 0x852C #define GL_SECONDARY_COLOR_NV 0x852D #define GL_SPARE0_NV 0x852E #define GL_SPARE1_NV 0x852F #define GL_DISCARD_NV 0x8530 #define GL_E_TIMES_F_NV 0x8531 #define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 #define GL_UNSIGNED_IDENTITY_NV 0x8536 #define GL_UNSIGNED_INVERT_NV 0x8537 #define GL_EXPAND_NORMAL_NV 0x8538 #define GL_EXPAND_NEGATE_NV 0x8539 #define GL_HALF_BIAS_NORMAL_NV 0x853A #define GL_HALF_BIAS_NEGATE_NV 0x853B #define GL_SIGNED_IDENTITY_NV 0x853C #define GL_SIGNED_NEGATE_NV 0x853D #define GL_SCALE_BY_TWO_NV 0x853E #define GL_SCALE_BY_FOUR_NV 0x853F #define GL_SCALE_BY_ONE_HALF_NV 0x8540 #define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 #define GL_COMBINER_INPUT_NV 0x8542 #define GL_COMBINER_MAPPING_NV 0x8543 #define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 #define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 #define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 #define GL_COMBINER_MUX_SUM_NV 0x8547 #define GL_COMBINER_SCALE_NV 0x8548 #define GL_COMBINER_BIAS_NV 0x8549 #define GL_COMBINER_AB_OUTPUT_NV 0x854A #define GL_COMBINER_CD_OUTPUT_NV 0x854B #define GL_COMBINER_SUM_OUTPUT_NV 0x854C #define GL_MAX_GENERAL_COMBINERS_NV 0x854D #define GL_NUM_GENERAL_COMBINERS_NV 0x854E #define GL_COLOR_SUM_CLAMP_NV 0x854F #define GL_COMBINER0_NV 0x8550 #define GL_COMBINER1_NV 0x8551 #define GL_COMBINER2_NV 0x8552 #define GL_COMBINER3_NV 0x8553 #define GL_COMBINER4_NV 0x8554 #define GL_COMBINER5_NV 0x8555 #define GL_COMBINER6_NV 0x8556 #define GL_COMBINER7_NV 0x8557 /* reuse GL_TEXTURE0_ARB */ /* reuse GL_TEXTURE1_ARB */ /* reuse GL_ZERO */ /* reuse GL_NONE */ /* reuse GL_FOG */ #endif #ifndef GL_NV_fog_distance #define GL_FOG_DISTANCE_MODE_NV 0x855A #define GL_EYE_RADIAL_NV 0x855B #define GL_EYE_PLANE_ABSOLUTE_NV 0x855C /* reuse GL_EYE_PLANE */ #endif #ifndef GL_NV_texgen_emboss #define GL_EMBOSS_LIGHT_NV 0x855D #define GL_EMBOSS_CONSTANT_NV 0x855E #define GL_EMBOSS_MAP_NV 0x855F #endif #ifndef GL_NV_blend_square #endif #ifndef GL_NV_texture_env_combine4 #define GL_COMBINE4_NV 0x8503 #define GL_SOURCE3_RGB_NV 0x8583 #define GL_SOURCE3_ALPHA_NV 0x858B #define GL_OPERAND3_RGB_NV 0x8593 #define GL_OPERAND3_ALPHA_NV 0x859B #endif #ifndef GL_MESA_resize_buffers #endif #ifndef GL_MESA_window_pos #endif #ifndef GL_EXT_texture_compression_s3tc #define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 #define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 #define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 #define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 #endif #ifndef GL_IBM_cull_vertex #define GL_CULL_VERTEX_IBM 103050 #endif #ifndef GL_IBM_multimode_draw_arrays #endif #ifndef GL_IBM_vertex_array_lists #define GL_VERTEX_ARRAY_LIST_IBM 103070 #define GL_NORMAL_ARRAY_LIST_IBM 103071 #define GL_COLOR_ARRAY_LIST_IBM 103072 #define GL_INDEX_ARRAY_LIST_IBM 103073 #define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 #define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 #define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 #define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 #define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 #define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 #define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 #define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 #define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 #define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 #define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 #define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 #endif #ifndef GL_SGIX_subsample #define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 #define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 #define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 #define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 #define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 #endif #ifndef GL_SGIX_ycrcb_subsample #endif #ifndef GL_SGIX_ycrcba #define GL_YCRCB_SGIX 0x8318 #define GL_YCRCBA_SGIX 0x8319 #endif #ifndef GL_SGI_depth_pass_instrument #define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310 #define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311 #define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312 #endif #ifndef GL_3DFX_texture_compression_FXT1 #define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 #define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 #endif #ifndef GL_3DFX_multisample #define GL_MULTISAMPLE_3DFX 0x86B2 #define GL_SAMPLE_BUFFERS_3DFX 0x86B3 #define GL_SAMPLES_3DFX 0x86B4 #define GL_MULTISAMPLE_BIT_3DFX 0x20000000 #endif #ifndef GL_3DFX_tbuffer #endif #ifndef GL_EXT_multisample #define GL_MULTISAMPLE_EXT 0x809D #define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E #define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F #define GL_SAMPLE_MASK_EXT 0x80A0 #define GL_1PASS_EXT 0x80A1 #define GL_2PASS_0_EXT 0x80A2 #define GL_2PASS_1_EXT 0x80A3 #define GL_4PASS_0_EXT 0x80A4 #define GL_4PASS_1_EXT 0x80A5 #define GL_4PASS_2_EXT 0x80A6 #define GL_4PASS_3_EXT 0x80A7 #define GL_SAMPLE_BUFFERS_EXT 0x80A8 #define GL_SAMPLES_EXT 0x80A9 #define GL_SAMPLE_MASK_VALUE_EXT 0x80AA #define GL_SAMPLE_MASK_INVERT_EXT 0x80AB #define GL_SAMPLE_PATTERN_EXT 0x80AC #define GL_MULTISAMPLE_BIT_EXT 0x20000000 #endif #ifndef GL_SGIX_vertex_preclip #define GL_VERTEX_PRECLIP_SGIX 0x83EE #define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF #endif #ifndef GL_SGIX_convolution_accuracy #define GL_CONVOLUTION_HINT_SGIX 0x8316 #endif #ifndef GL_SGIX_resample #define GL_PACK_RESAMPLE_SGIX 0x842C #define GL_UNPACK_RESAMPLE_SGIX 0x842D #define GL_RESAMPLE_REPLICATE_SGIX 0x842E #define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F #define GL_RESAMPLE_DECIMATE_SGIX 0x8430 #endif #ifndef GL_SGIS_point_line_texgen #define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 #define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 #define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 #define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 #define GL_EYE_POINT_SGIS 0x81F4 #define GL_OBJECT_POINT_SGIS 0x81F5 #define GL_EYE_LINE_SGIS 0x81F6 #define GL_OBJECT_LINE_SGIS 0x81F7 #endif #ifndef GL_SGIS_texture_color_mask #define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF #endif #ifndef GL_EXT_texture_env_dot3 #define GL_DOT3_RGB_EXT 0x8740 #define GL_DOT3_RGBA_EXT 0x8741 #endif #ifndef GL_ATI_texture_mirror_once #define GL_MIRROR_CLAMP_ATI 0x8742 #define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 #endif #ifndef GL_NV_fence #define GL_ALL_COMPLETED_NV 0x84F2 #define GL_FENCE_STATUS_NV 0x84F3 #define GL_FENCE_CONDITION_NV 0x84F4 #endif #ifndef GL_IBM_texture_mirrored_repeat #define GL_MIRRORED_REPEAT_IBM 0x8370 #endif #ifndef GL_NV_evaluators #define GL_EVAL_2D_NV 0x86C0 #define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 #define GL_MAP_TESSELLATION_NV 0x86C2 #define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 #define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 #define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 #define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 #define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 #define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 #define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 #define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA #define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB #define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC #define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD #define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE #define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF #define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 #define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 #define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 #define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 #define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 #define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 #define GL_MAX_MAP_TESSELLATION_NV 0x86D6 #define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 #endif #ifndef GL_NV_packed_depth_stencil #define GL_DEPTH_STENCIL_NV 0x84F9 #define GL_UNSIGNED_INT_24_8_NV 0x84FA #endif #ifndef GL_NV_register_combiners2 #define GL_PER_STAGE_CONSTANTS_NV 0x8535 #endif #ifndef GL_NV_texture_compression_vtc #endif #ifndef GL_NV_texture_rectangle #define GL_TEXTURE_RECTANGLE_NV 0x84F5 #define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 #define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 #define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 #endif #ifndef GL_NV_texture_shader #define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C #define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D #define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E #define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 #define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA #define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB #define GL_DSDT_MAG_INTENSITY_NV 0x86DC #define GL_SHADER_CONSISTENT_NV 0x86DD #define GL_TEXTURE_SHADER_NV 0x86DE #define GL_SHADER_OPERATION_NV 0x86DF #define GL_CULL_MODES_NV 0x86E0 #define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 #define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 #define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 #define GL_OFFSET_TEXTURE_2D_MATRIX_NV GL_OFFSET_TEXTURE_MATRIX_NV #define GL_OFFSET_TEXTURE_2D_SCALE_NV GL_OFFSET_TEXTURE_SCALE_NV #define GL_OFFSET_TEXTURE_2D_BIAS_NV GL_OFFSET_TEXTURE_BIAS_NV #define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 #define GL_CONST_EYE_NV 0x86E5 #define GL_PASS_THROUGH_NV 0x86E6 #define GL_CULL_FRAGMENT_NV 0x86E7 #define GL_OFFSET_TEXTURE_2D_NV 0x86E8 #define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 #define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA #define GL_DOT_PRODUCT_NV 0x86EC #define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED #define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE #define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 #define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 #define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 #define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 #define GL_HILO_NV 0x86F4 #define GL_DSDT_NV 0x86F5 #define GL_DSDT_MAG_NV 0x86F6 #define GL_DSDT_MAG_VIB_NV 0x86F7 #define GL_HILO16_NV 0x86F8 #define GL_SIGNED_HILO_NV 0x86F9 #define GL_SIGNED_HILO16_NV 0x86FA #define GL_SIGNED_RGBA_NV 0x86FB #define GL_SIGNED_RGBA8_NV 0x86FC #define GL_SIGNED_RGB_NV 0x86FE #define GL_SIGNED_RGB8_NV 0x86FF #define GL_SIGNED_LUMINANCE_NV 0x8701 #define GL_SIGNED_LUMINANCE8_NV 0x8702 #define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 #define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 #define GL_SIGNED_ALPHA_NV 0x8705 #define GL_SIGNED_ALPHA8_NV 0x8706 #define GL_SIGNED_INTENSITY_NV 0x8707 #define GL_SIGNED_INTENSITY8_NV 0x8708 #define GL_DSDT8_NV 0x8709 #define GL_DSDT8_MAG8_NV 0x870A #define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B #define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C #define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D #define GL_HI_SCALE_NV 0x870E #define GL_LO_SCALE_NV 0x870F #define GL_DS_SCALE_NV 0x8710 #define GL_DT_SCALE_NV 0x8711 #define GL_MAGNITUDE_SCALE_NV 0x8712 #define GL_VIBRANCE_SCALE_NV 0x8713 #define GL_HI_BIAS_NV 0x8714 #define GL_LO_BIAS_NV 0x8715 #define GL_DS_BIAS_NV 0x8716 #define GL_DT_BIAS_NV 0x8717 #define GL_MAGNITUDE_BIAS_NV 0x8718 #define GL_VIBRANCE_BIAS_NV 0x8719 #define GL_TEXTURE_BORDER_VALUES_NV 0x871A #define GL_TEXTURE_HI_SIZE_NV 0x871B #define GL_TEXTURE_LO_SIZE_NV 0x871C #define GL_TEXTURE_DS_SIZE_NV 0x871D #define GL_TEXTURE_DT_SIZE_NV 0x871E #define GL_TEXTURE_MAG_SIZE_NV 0x871F #endif #ifndef GL_NV_texture_shader2 #define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF #endif #ifndef GL_NV_vertex_array_range2 #define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 #endif #ifndef GL_NV_vertex_program #define GL_VERTEX_PROGRAM_NV 0x8620 #define GL_VERTEX_STATE_PROGRAM_NV 0x8621 #define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 #define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 #define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 #define GL_CURRENT_ATTRIB_NV 0x8626 #define GL_PROGRAM_LENGTH_NV 0x8627 #define GL_PROGRAM_STRING_NV 0x8628 #define GL_MODELVIEW_PROJECTION_NV 0x8629 #define GL_IDENTITY_NV 0x862A #define GL_INVERSE_NV 0x862B #define GL_TRANSPOSE_NV 0x862C #define GL_INVERSE_TRANSPOSE_NV 0x862D #define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E #define GL_MAX_TRACK_MATRICES_NV 0x862F #define GL_MATRIX0_NV 0x8630 #define GL_MATRIX1_NV 0x8631 #define GL_MATRIX2_NV 0x8632 #define GL_MATRIX3_NV 0x8633 #define GL_MATRIX4_NV 0x8634 #define GL_MATRIX5_NV 0x8635 #define GL_MATRIX6_NV 0x8636 #define GL_MATRIX7_NV 0x8637 #define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 #define GL_CURRENT_MATRIX_NV 0x8641 #define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 #define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 #define GL_PROGRAM_PARAMETER_NV 0x8644 #define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 #define GL_PROGRAM_TARGET_NV 0x8646 #define GL_PROGRAM_RESIDENT_NV 0x8647 #define GL_TRACK_MATRIX_NV 0x8648 #define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 #define GL_VERTEX_PROGRAM_BINDING_NV 0x864A #define GL_PROGRAM_ERROR_POSITION_NV 0x864B #define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 #define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 #define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 #define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 #define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 #define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 #define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 #define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 #define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 #define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 #define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A #define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B #define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C #define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D #define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E #define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F #define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 #define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 #define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 #define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 #define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 #define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 #define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 #define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 #define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 #define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 #define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A #define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B #define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C #define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D #define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E #define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F #define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 #define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 #define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 #define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 #define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 #define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 #define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 #define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 #define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 #define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 #define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A #define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B #define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C #define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D #define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E #define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F #endif #ifndef GL_SGIX_texture_coordinate_clamp #define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 #define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A #define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B #endif #ifndef GL_SGIX_scalebias_hint #define GL_SCALEBIAS_HINT_SGIX 0x8322 #endif #ifndef GL_OML_interlace #define GL_INTERLACE_OML 0x8980 #define GL_INTERLACE_READ_OML 0x8981 #endif #ifndef GL_OML_subsample #define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 #define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 #endif #ifndef GL_OML_resample #define GL_PACK_RESAMPLE_OML 0x8984 #define GL_UNPACK_RESAMPLE_OML 0x8985 #define GL_RESAMPLE_REPLICATE_OML 0x8986 #define GL_RESAMPLE_ZERO_FILL_OML 0x8987 #define GL_RESAMPLE_AVERAGE_OML 0x8988 #define GL_RESAMPLE_DECIMATE_OML 0x8989 #endif #ifndef GL_NV_copy_depth_to_color #define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E #define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F #endif #ifndef GL_ATI_envmap_bumpmap #define GL_BUMP_ROT_MATRIX_ATI 0x8775 #define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 #define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 #define GL_BUMP_TEX_UNITS_ATI 0x8778 #define GL_DUDV_ATI 0x8779 #define GL_DU8DV8_ATI 0x877A #define GL_BUMP_ENVMAP_ATI 0x877B #define GL_BUMP_TARGET_ATI 0x877C #endif #ifndef GL_ATI_fragment_shader #define GL_FRAGMENT_SHADER_ATI 0x8920 #define GL_REG_0_ATI 0x8921 #define GL_REG_1_ATI 0x8922 #define GL_REG_2_ATI 0x8923 #define GL_REG_3_ATI 0x8924 #define GL_REG_4_ATI 0x8925 #define GL_REG_5_ATI 0x8926 #define GL_REG_6_ATI 0x8927 #define GL_REG_7_ATI 0x8928 #define GL_REG_8_ATI 0x8929 #define GL_REG_9_ATI 0x892A #define GL_REG_10_ATI 0x892B #define GL_REG_11_ATI 0x892C #define GL_REG_12_ATI 0x892D #define GL_REG_13_ATI 0x892E #define GL_REG_14_ATI 0x892F #define GL_REG_15_ATI 0x8930 #define GL_REG_16_ATI 0x8931 #define GL_REG_17_ATI 0x8932 #define GL_REG_18_ATI 0x8933 #define GL_REG_19_ATI 0x8934 #define GL_REG_20_ATI 0x8935 #define GL_REG_21_ATI 0x8936 #define GL_REG_22_ATI 0x8937 #define GL_REG_23_ATI 0x8938 #define GL_REG_24_ATI 0x8939 #define GL_REG_25_ATI 0x893A #define GL_REG_26_ATI 0x893B #define GL_REG_27_ATI 0x893C #define GL_REG_28_ATI 0x893D #define GL_REG_29_ATI 0x893E #define GL_REG_30_ATI 0x893F #define GL_REG_31_ATI 0x8940 #define GL_CON_0_ATI 0x8941 #define GL_CON_1_ATI 0x8942 #define GL_CON_2_ATI 0x8943 #define GL_CON_3_ATI 0x8944 #define GL_CON_4_ATI 0x8945 #define GL_CON_5_ATI 0x8946 #define GL_CON_6_ATI 0x8947 #define GL_CON_7_ATI 0x8948 #define GL_CON_8_ATI 0x8949 #define GL_CON_9_ATI 0x894A #define GL_CON_10_ATI 0x894B #define GL_CON_11_ATI 0x894C #define GL_CON_12_ATI 0x894D #define GL_CON_13_ATI 0x894E #define GL_CON_14_ATI 0x894F #define GL_CON_15_ATI 0x8950 #define GL_CON_16_ATI 0x8951 #define GL_CON_17_ATI 0x8952 #define GL_CON_18_ATI 0x8953 #define GL_CON_19_ATI 0x8954 #define GL_CON_20_ATI 0x8955 #define GL_CON_21_ATI 0x8956 #define GL_CON_22_ATI 0x8957 #define GL_CON_23_ATI 0x8958 #define GL_CON_24_ATI 0x8959 #define GL_CON_25_ATI 0x895A #define GL_CON_26_ATI 0x895B #define GL_CON_27_ATI 0x895C #define GL_CON_28_ATI 0x895D #define GL_CON_29_ATI 0x895E #define GL_CON_30_ATI 0x895F #define GL_CON_31_ATI 0x8960 #define GL_MOV_ATI 0x8961 #define GL_ADD_ATI 0x8963 #define GL_MUL_ATI 0x8964 #define GL_SUB_ATI 0x8965 #define GL_DOT3_ATI 0x8966 #define GL_DOT4_ATI 0x8967 #define GL_MAD_ATI 0x8968 #define GL_LERP_ATI 0x8969 #define GL_CND_ATI 0x896A #define GL_CND0_ATI 0x896B #define GL_DOT2_ADD_ATI 0x896C #define GL_SECONDARY_INTERPOLATOR_ATI 0x896D #define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E #define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F #define GL_NUM_PASSES_ATI 0x8970 #define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 #define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 #define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 #define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 #define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 #define GL_SWIZZLE_STR_ATI 0x8976 #define GL_SWIZZLE_STQ_ATI 0x8977 #define GL_SWIZZLE_STR_DR_ATI 0x8978 #define GL_SWIZZLE_STQ_DQ_ATI 0x8979 #define GL_SWIZZLE_STRQ_ATI 0x897A #define GL_SWIZZLE_STRQ_DQ_ATI 0x897B #define GL_RED_BIT_ATI 0x00000001 #define GL_GREEN_BIT_ATI 0x00000002 #define GL_BLUE_BIT_ATI 0x00000004 #define GL_2X_BIT_ATI 0x00000001 #define GL_4X_BIT_ATI 0x00000002 #define GL_8X_BIT_ATI 0x00000004 #define GL_HALF_BIT_ATI 0x00000008 #define GL_QUARTER_BIT_ATI 0x00000010 #define GL_EIGHTH_BIT_ATI 0x00000020 #define GL_SATURATE_BIT_ATI 0x00000040 #define GL_COMP_BIT_ATI 0x00000002 #define GL_NEGATE_BIT_ATI 0x00000004 #define GL_BIAS_BIT_ATI 0x00000008 #endif #ifndef GL_ATI_pn_triangles #define GL_PN_TRIANGLES_ATI 0x87F0 #define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 #define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 #define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 #define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 #define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 #define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 #define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 #define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 #endif #ifndef GL_ATI_vertex_array_object #define GL_STATIC_ATI 0x8760 #define GL_DYNAMIC_ATI 0x8761 #define GL_PRESERVE_ATI 0x8762 #define GL_DISCARD_ATI 0x8763 #define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 #define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 #define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 #define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 #endif #ifndef GL_EXT_vertex_shader #define GL_VERTEX_SHADER_EXT 0x8780 #define GL_VERTEX_SHADER_BINDING_EXT 0x8781 #define GL_OP_INDEX_EXT 0x8782 #define GL_OP_NEGATE_EXT 0x8783 #define GL_OP_DOT3_EXT 0x8784 #define GL_OP_DOT4_EXT 0x8785 #define GL_OP_MUL_EXT 0x8786 #define GL_OP_ADD_EXT 0x8787 #define GL_OP_MADD_EXT 0x8788 #define GL_OP_FRAC_EXT 0x8789 #define GL_OP_MAX_EXT 0x878A #define GL_OP_MIN_EXT 0x878B #define GL_OP_SET_GE_EXT 0x878C #define GL_OP_SET_LT_EXT 0x878D #define GL_OP_CLAMP_EXT 0x878E #define GL_OP_FLOOR_EXT 0x878F #define GL_OP_ROUND_EXT 0x8790 #define GL_OP_EXP_BASE_2_EXT 0x8791 #define GL_OP_LOG_BASE_2_EXT 0x8792 #define GL_OP_POWER_EXT 0x8793 #define GL_OP_RECIP_EXT 0x8794 #define GL_OP_RECIP_SQRT_EXT 0x8795 #define GL_OP_SUB_EXT 0x8796 #define GL_OP_CROSS_PRODUCT_EXT 0x8797 #define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 #define GL_OP_MOV_EXT 0x8799 #define GL_OUTPUT_VERTEX_EXT 0x879A #define GL_OUTPUT_COLOR0_EXT 0x879B #define GL_OUTPUT_COLOR1_EXT 0x879C #define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D #define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E #define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F #define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 #define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 #define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 #define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 #define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 #define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 #define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 #define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 #define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 #define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 #define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA #define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB #define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC #define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD #define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE #define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF #define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 #define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 #define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 #define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 #define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 #define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 #define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 #define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 #define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 #define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 #define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA #define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB #define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC #define GL_OUTPUT_FOG_EXT 0x87BD #define GL_SCALAR_EXT 0x87BE #define GL_VECTOR_EXT 0x87BF #define GL_MATRIX_EXT 0x87C0 #define GL_VARIANT_EXT 0x87C1 #define GL_INVARIANT_EXT 0x87C2 #define GL_LOCAL_CONSTANT_EXT 0x87C3 #define GL_LOCAL_EXT 0x87C4 #define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 #define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 #define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 #define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 #define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 #define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA #define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB #define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC #define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD #define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE #define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF #define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 #define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 #define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 #define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 #define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 #define GL_X_EXT 0x87D5 #define GL_Y_EXT 0x87D6 #define GL_Z_EXT 0x87D7 #define GL_W_EXT 0x87D8 #define GL_NEGATIVE_X_EXT 0x87D9 #define GL_NEGATIVE_Y_EXT 0x87DA #define GL_NEGATIVE_Z_EXT 0x87DB #define GL_NEGATIVE_W_EXT 0x87DC #define GL_ZERO_EXT 0x87DD #define GL_ONE_EXT 0x87DE #define GL_NEGATIVE_ONE_EXT 0x87DF #define GL_NORMALIZED_RANGE_EXT 0x87E0 #define GL_FULL_RANGE_EXT 0x87E1 #define GL_CURRENT_VERTEX_EXT 0x87E2 #define GL_MVP_MATRIX_EXT 0x87E3 #define GL_VARIANT_VALUE_EXT 0x87E4 #define GL_VARIANT_DATATYPE_EXT 0x87E5 #define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 #define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 #define GL_VARIANT_ARRAY_EXT 0x87E8 #define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 #define GL_INVARIANT_VALUE_EXT 0x87EA #define GL_INVARIANT_DATATYPE_EXT 0x87EB #define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC #define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED #endif #ifndef GL_ATI_vertex_streams #define GL_MAX_VERTEX_STREAMS_ATI 0x876B #define GL_VERTEX_STREAM0_ATI 0x876C #define GL_VERTEX_STREAM1_ATI 0x876D #define GL_VERTEX_STREAM2_ATI 0x876E #define GL_VERTEX_STREAM3_ATI 0x876F #define GL_VERTEX_STREAM4_ATI 0x8770 #define GL_VERTEX_STREAM5_ATI 0x8771 #define GL_VERTEX_STREAM6_ATI 0x8772 #define GL_VERTEX_STREAM7_ATI 0x8773 #define GL_VERTEX_SOURCE_ATI 0x8774 #endif #ifndef GL_ATI_element_array #define GL_ELEMENT_ARRAY_ATI 0x8768 #define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 #define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A #endif #ifndef GL_SUN_mesh_array #define GL_QUAD_MESH_SUN 0x8614 #define GL_TRIANGLE_MESH_SUN 0x8615 #endif #ifndef GL_SUN_slice_accum #define GL_SLICE_ACCUM_SUN 0x85CC #endif #ifndef GL_NV_multisample_filter_hint #define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 #endif #ifndef GL_NV_depth_clamp #define GL_DEPTH_CLAMP_NV 0x864F #endif #ifndef GL_NV_occlusion_query #define GL_PIXEL_COUNTER_BITS_NV 0x8864 #define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 #define GL_PIXEL_COUNT_NV 0x8866 #define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 #endif #ifndef GL_NV_point_sprite #define GL_POINT_SPRITE_NV 0x8861 #define GL_COORD_REPLACE_NV 0x8862 #define GL_POINT_SPRITE_R_MODE_NV 0x8863 #endif #ifndef GL_NV_texture_shader3 #define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 #define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 #define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 #define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 #define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 #define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 #define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 #define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 #define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 #define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 #define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A #define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B #define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C #define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D #define GL_HILO8_NV 0x885E #define GL_SIGNED_HILO8_NV 0x885F #define GL_FORCE_BLUE_TO_ONE_NV 0x8860 #endif #ifndef GL_NV_vertex_program1_1 #endif #ifndef GL_EXT_shadow_funcs #endif #ifndef GL_EXT_stencil_two_side #define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 #define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 #endif #ifndef GL_ATI_text_fragment_shader #define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 #endif #ifndef GL_APPLE_client_storage #define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 #endif #ifndef GL_APPLE_element_array #define GL_ELEMENT_ARRAY_APPLE 0x8A0C #define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8A0D #define GL_ELEMENT_ARRAY_POINTER_APPLE 0x8A0E #endif #ifndef GL_APPLE_fence #define GL_DRAW_PIXELS_APPLE 0x8A0A #define GL_FENCE_APPLE 0x8A0B #endif #ifndef GL_APPLE_vertex_array_object #define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 #endif #ifndef GL_APPLE_vertex_array_range #define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D #define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E #define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F #define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 #define GL_STORAGE_CLIENT_APPLE 0x85B4 #define GL_STORAGE_CACHED_APPLE 0x85BE #define GL_STORAGE_SHARED_APPLE 0x85BF #endif #ifndef GL_APPLE_ycbcr_422 #define GL_YCBCR_422_APPLE 0x85B9 #define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA #define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB #endif #ifndef GL_S3_s3tc #define GL_RGB_S3TC 0x83A0 #define GL_RGB4_S3TC 0x83A1 #define GL_RGBA_S3TC 0x83A2 #define GL_RGBA4_S3TC 0x83A3 #define GL_RGBA_DXT5_S3TC 0x83A4 #define GL_RGBA4_DXT5_S3TC 0x83A5 #endif #ifndef GL_ATI_draw_buffers #define GL_MAX_DRAW_BUFFERS_ATI 0x8824 #define GL_DRAW_BUFFER0_ATI 0x8825 #define GL_DRAW_BUFFER1_ATI 0x8826 #define GL_DRAW_BUFFER2_ATI 0x8827 #define GL_DRAW_BUFFER3_ATI 0x8828 #define GL_DRAW_BUFFER4_ATI 0x8829 #define GL_DRAW_BUFFER5_ATI 0x882A #define GL_DRAW_BUFFER6_ATI 0x882B #define GL_DRAW_BUFFER7_ATI 0x882C #define GL_DRAW_BUFFER8_ATI 0x882D #define GL_DRAW_BUFFER9_ATI 0x882E #define GL_DRAW_BUFFER10_ATI 0x882F #define GL_DRAW_BUFFER11_ATI 0x8830 #define GL_DRAW_BUFFER12_ATI 0x8831 #define GL_DRAW_BUFFER13_ATI 0x8832 #define GL_DRAW_BUFFER14_ATI 0x8833 #define GL_DRAW_BUFFER15_ATI 0x8834 #endif #ifndef GL_ATI_pixel_format_float #define GL_RGBA_FLOAT_MODE_ATI 0x8820 #define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 #endif #ifndef GL_ATI_texture_env_combine3 #define GL_MODULATE_ADD_ATI 0x8744 #define GL_MODULATE_SIGNED_ADD_ATI 0x8745 #define GL_MODULATE_SUBTRACT_ATI 0x8746 #endif #ifndef GL_ATI_texture_float #define GL_RGBA_FLOAT32_ATI 0x8814 #define GL_RGB_FLOAT32_ATI 0x8815 #define GL_ALPHA_FLOAT32_ATI 0x8816 #define GL_INTENSITY_FLOAT32_ATI 0x8817 #define GL_LUMINANCE_FLOAT32_ATI 0x8818 #define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 #define GL_RGBA_FLOAT16_ATI 0x881A #define GL_RGB_FLOAT16_ATI 0x881B #define GL_ALPHA_FLOAT16_ATI 0x881C #define GL_INTENSITY_FLOAT16_ATI 0x881D #define GL_LUMINANCE_FLOAT16_ATI 0x881E #define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F #endif #ifndef GL_NV_float_buffer #define GL_FLOAT_R_NV 0x8880 #define GL_FLOAT_RG_NV 0x8881 #define GL_FLOAT_RGB_NV 0x8882 #define GL_FLOAT_RGBA_NV 0x8883 #define GL_FLOAT_R16_NV 0x8884 #define GL_FLOAT_R32_NV 0x8885 #define GL_FLOAT_RG16_NV 0x8886 #define GL_FLOAT_RG32_NV 0x8887 #define GL_FLOAT_RGB16_NV 0x8888 #define GL_FLOAT_RGB32_NV 0x8889 #define GL_FLOAT_RGBA16_NV 0x888A #define GL_FLOAT_RGBA32_NV 0x888B #define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C #define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D #define GL_FLOAT_RGBA_MODE_NV 0x888E #endif #ifndef GL_NV_fragment_program #define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 #define GL_FRAGMENT_PROGRAM_NV 0x8870 #define GL_MAX_TEXTURE_COORDS_NV 0x8871 #define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 #define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 #define GL_PROGRAM_ERROR_STRING_NV 0x8874 #endif #ifndef GL_NV_half_float #define GL_HALF_FLOAT_NV 0x140B #endif #ifndef GL_NV_pixel_data_range #define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 #define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 #define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A #define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B #define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C #define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D #endif #ifndef GL_NV_primitive_restart #define GL_PRIMITIVE_RESTART_NV 0x8558 #define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 #endif #ifndef GL_NV_texture_expand_normal #define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F #endif #ifndef GL_NV_vertex_program2 #endif #ifndef GL_ATI_map_object_buffer #endif #ifndef GL_ATI_separate_stencil #define GL_STENCIL_BACK_FUNC_ATI 0x8800 #define GL_STENCIL_BACK_FAIL_ATI 0x8801 #define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 #define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 #endif #ifndef GL_ATI_vertex_attrib_array_object #endif #ifndef GL_OES_read_format #define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A #define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B #endif #ifndef GL_EXT_depth_bounds_test #define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 #define GL_DEPTH_BOUNDS_EXT 0x8891 #endif #ifndef GL_EXT_texture_mirror_clamp #define GL_MIRROR_CLAMP_EXT 0x8742 #define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 #define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 #endif #ifndef GL_EXT_blend_equation_separate #define GL_BLEND_EQUATION_RGB_EXT 0x8009 #define GL_BLEND_EQUATION_ALPHA_EXT 0x883D #endif #ifndef GL_MESA_pack_invert #define GL_PACK_INVERT_MESA 0x8758 #endif #ifndef GL_MESA_ycbcr_texture #define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA #define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB #define GL_YCBCR_MESA 0x8757 #endif #ifndef GL_EXT_pixel_buffer_object #define GL_PIXEL_PACK_BUFFER_EXT 0x88EB #define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC #define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED #define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF #endif #ifndef GL_NV_fragment_program_option #endif #ifndef GL_NV_fragment_program2 #define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 #define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 #define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 #define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 #define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 #endif #ifndef GL_NV_vertex_program2_option /* reuse GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */ /* reuse GL_MAX_PROGRAM_CALL_DEPTH_NV */ #endif #ifndef GL_NV_vertex_program3 /* reuse GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB */ #endif #ifndef GL_EXT_framebuffer_object #define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 #define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 #define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 #define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 #define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 #define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 #define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 #define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 #define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA #define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB #define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC #define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD #define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF #define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 #define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 #define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 #define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 #define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 #define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 #define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 #define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 #define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 #define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 #define GL_COLOR_ATTACHMENT10_EXT 0x8CEA #define GL_COLOR_ATTACHMENT11_EXT 0x8CEB #define GL_COLOR_ATTACHMENT12_EXT 0x8CEC #define GL_COLOR_ATTACHMENT13_EXT 0x8CED #define GL_COLOR_ATTACHMENT14_EXT 0x8CEE #define GL_COLOR_ATTACHMENT15_EXT 0x8CEF #define GL_DEPTH_ATTACHMENT_EXT 0x8D00 #define GL_STENCIL_ATTACHMENT_EXT 0x8D20 #define GL_FRAMEBUFFER_EXT 0x8D40 #define GL_RENDERBUFFER_EXT 0x8D41 #define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 #define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 #define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 #define GL_STENCIL_INDEX1_EXT 0x8D46 #define GL_STENCIL_INDEX4_EXT 0x8D47 #define GL_STENCIL_INDEX8_EXT 0x8D48 #define GL_STENCIL_INDEX16_EXT 0x8D49 #define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 #define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 #define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 #define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 #define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 #define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 #endif #ifndef GL_GREMEDY_string_marker #endif #ifndef GL_EXT_packed_depth_stencil #define GL_DEPTH_STENCIL_EXT 0x84F9 #define GL_UNSIGNED_INT_24_8_EXT 0x84FA #define GL_DEPTH24_STENCIL8_EXT 0x88F0 #define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 #endif #ifndef GL_EXT_stencil_clear_tag #define GL_STENCIL_TAG_BITS_EXT 0x88F2 #define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 #endif #ifndef GL_EXT_texture_sRGB #define GL_SRGB_EXT 0x8C40 #define GL_SRGB8_EXT 0x8C41 #define GL_SRGB_ALPHA_EXT 0x8C42 #define GL_SRGB8_ALPHA8_EXT 0x8C43 #define GL_SLUMINANCE_ALPHA_EXT 0x8C44 #define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 #define GL_SLUMINANCE_EXT 0x8C46 #define GL_SLUMINANCE8_EXT 0x8C47 #define GL_COMPRESSED_SRGB_EXT 0x8C48 #define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 #define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A #define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B #define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F #endif #ifndef GL_EXT_framebuffer_blit #define GL_READ_FRAMEBUFFER_EXT 0x8CA8 #define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 #define GL_DRAW_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING_EXT #define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA #endif #ifndef GL_EXT_framebuffer_multisample #define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 #define GL_MAX_SAMPLES_EXT 0x8D57 #endif #ifndef GL_MESAX_texture_stack #define GL_TEXTURE_1D_STACK_MESAX 0x8759 #define GL_TEXTURE_2D_STACK_MESAX 0x875A #define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B #define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C #define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D #define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E #endif #ifndef GL_EXT_timer_query #define GL_TIME_ELAPSED_EXT 0x88BF #endif #ifndef GL_EXT_gpu_program_parameters #endif #ifndef GL_APPLE_flush_buffer_range #define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 #define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 #endif #ifndef GL_NV_gpu_program4 #define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 #define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905 #define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 #define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 #define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 #define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 #define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 #define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 #endif #ifndef GL_NV_geometry_program4 #define GL_LINES_ADJACENCY_EXT 0x000A #define GL_LINE_STRIP_ADJACENCY_EXT 0x000B #define GL_TRIANGLES_ADJACENCY_EXT 0x000C #define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0x000D #define GL_GEOMETRY_PROGRAM_NV 0x8C26 #define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 #define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 #define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA #define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB #define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC #define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 #define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 #define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 #define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 #define GL_PROGRAM_POINT_SIZE_EXT 0x8642 #endif #ifndef GL_EXT_geometry_shader4 #define GL_GEOMETRY_SHADER_EXT 0x8DD9 /* reuse GL_GEOMETRY_VERTICES_OUT_EXT */ /* reuse GL_GEOMETRY_INPUT_TYPE_EXT */ /* reuse GL_GEOMETRY_OUTPUT_TYPE_EXT */ /* reuse GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT */ #define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD #define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE #define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B #define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF #define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 #define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 /* reuse GL_LINES_ADJACENCY_EXT */ /* reuse GL_LINE_STRIP_ADJACENCY_EXT */ /* reuse GL_TRIANGLES_ADJACENCY_EXT */ /* reuse GL_TRIANGLE_STRIP_ADJACENCY_EXT */ /* reuse GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT */ /* reuse GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */ /* reuse GL_PROGRAM_POINT_SIZE_EXT */ #endif #ifndef GL_NV_vertex_program4 #define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD #endif #ifndef GL_EXT_gpu_shader4 #define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 #define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 #define GL_SAMPLER_BUFFER_EXT 0x8DC2 #define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 #define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 #define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 #define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 #define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 #define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 #define GL_INT_SAMPLER_1D_EXT 0x8DC9 #define GL_INT_SAMPLER_2D_EXT 0x8DCA #define GL_INT_SAMPLER_3D_EXT 0x8DCB #define GL_INT_SAMPLER_CUBE_EXT 0x8DCC #define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD #define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE #define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF #define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 #define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 #define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 #define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 #define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 #define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 #define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 #define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 #define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 #endif #ifndef GL_EXT_draw_instanced #endif #ifndef GL_EXT_packed_float #define GL_R11F_G11F_B10F_EXT 0x8C3A #define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B #define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C #endif #ifndef GL_EXT_texture_array #define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 #define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 #define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A #define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B #define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C #define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D #define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF #define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E /* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */ #endif #ifndef GL_EXT_texture_buffer_object #define GL_TEXTURE_BUFFER_EXT 0x8C2A #define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B #define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C #define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D #define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E #endif #ifndef GL_EXT_texture_compression_latc #define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 #define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 #define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 #define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 #endif #ifndef GL_EXT_texture_compression_rgtc #define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB #define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC #define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD #define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE #endif #ifndef GL_EXT_texture_shared_exponent #define GL_RGB9_E5_EXT 0x8C3D #define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E #define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F #endif #ifndef GL_NV_depth_buffer_float #define GL_DEPTH_COMPONENT32F_NV 0x8DAB #define GL_DEPTH32F_STENCIL8_NV 0x8DAC #define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD #define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF #endif #ifndef GL_NV_fragment_program4 #endif #ifndef GL_NV_framebuffer_multisample_coverage #define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB #define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 #define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11 #define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12 #endif #ifndef GL_EXT_framebuffer_sRGB #define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 #define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA #endif #ifndef GL_NV_geometry_shader4 #endif #ifndef GL_NV_parameter_buffer_object #define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0 #define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1 #define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2 #define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3 #define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 #endif #ifndef GL_EXT_draw_buffers2 #endif #ifndef GL_NV_transform_feedback #define GL_BACK_PRIMARY_COLOR_NV 0x8C77 #define GL_BACK_SECONDARY_COLOR_NV 0x8C78 #define GL_TEXTURE_COORD_NV 0x8C79 #define GL_CLIP_DISTANCE_NV 0x8C7A #define GL_VERTEX_ID_NV 0x8C7B #define GL_PRIMITIVE_ID_NV 0x8C7C #define GL_GENERIC_ATTRIB_NV 0x8C7D #define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E #define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F #define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 #define GL_ACTIVE_VARYINGS_NV 0x8C81 #define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 #define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 #define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 #define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 #define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 #define GL_PRIMITIVES_GENERATED_NV 0x8C87 #define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 #define GL_RASTERIZER_DISCARD_NV 0x8C89 #define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV 0x8C8A #define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B #define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C #define GL_SEPARATE_ATTRIBS_NV 0x8C8D #define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E #define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F #define GL_LAYER_NV 0x8DAA #define GL_NEXT_BUFFER_NV -2 #define GL_SKIP_COMPONENTS4_NV -3 #define GL_SKIP_COMPONENTS3_NV -4 #define GL_SKIP_COMPONENTS2_NV -5 #define GL_SKIP_COMPONENTS1_NV -6 #endif #ifndef GL_EXT_bindable_uniform #define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 #define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 #define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 #define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED #define GL_UNIFORM_BUFFER_EXT 0x8DEE #define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF #endif #ifndef GL_EXT_texture_integer #define GL_RGBA32UI_EXT 0x8D70 #define GL_RGB32UI_EXT 0x8D71 #define GL_ALPHA32UI_EXT 0x8D72 #define GL_INTENSITY32UI_EXT 0x8D73 #define GL_LUMINANCE32UI_EXT 0x8D74 #define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 #define GL_RGBA16UI_EXT 0x8D76 #define GL_RGB16UI_EXT 0x8D77 #define GL_ALPHA16UI_EXT 0x8D78 #define GL_INTENSITY16UI_EXT 0x8D79 #define GL_LUMINANCE16UI_EXT 0x8D7A #define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B #define GL_RGBA8UI_EXT 0x8D7C #define GL_RGB8UI_EXT 0x8D7D #define GL_ALPHA8UI_EXT 0x8D7E #define GL_INTENSITY8UI_EXT 0x8D7F #define GL_LUMINANCE8UI_EXT 0x8D80 #define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 #define GL_RGBA32I_EXT 0x8D82 #define GL_RGB32I_EXT 0x8D83 #define GL_ALPHA32I_EXT 0x8D84 #define GL_INTENSITY32I_EXT 0x8D85 #define GL_LUMINANCE32I_EXT 0x8D86 #define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 #define GL_RGBA16I_EXT 0x8D88 #define GL_RGB16I_EXT 0x8D89 #define GL_ALPHA16I_EXT 0x8D8A #define GL_INTENSITY16I_EXT 0x8D8B #define GL_LUMINANCE16I_EXT 0x8D8C #define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D #define GL_RGBA8I_EXT 0x8D8E #define GL_RGB8I_EXT 0x8D8F #define GL_ALPHA8I_EXT 0x8D90 #define GL_INTENSITY8I_EXT 0x8D91 #define GL_LUMINANCE8I_EXT 0x8D92 #define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 #define GL_RED_INTEGER_EXT 0x8D94 #define GL_GREEN_INTEGER_EXT 0x8D95 #define GL_BLUE_INTEGER_EXT 0x8D96 #define GL_ALPHA_INTEGER_EXT 0x8D97 #define GL_RGB_INTEGER_EXT 0x8D98 #define GL_RGBA_INTEGER_EXT 0x8D99 #define GL_BGR_INTEGER_EXT 0x8D9A #define GL_BGRA_INTEGER_EXT 0x8D9B #define GL_LUMINANCE_INTEGER_EXT 0x8D9C #define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D #define GL_RGBA_INTEGER_MODE_EXT 0x8D9E #endif #ifndef GL_GREMEDY_frame_terminator #endif #ifndef GL_NV_conditional_render #define GL_QUERY_WAIT_NV 0x8E13 #define GL_QUERY_NO_WAIT_NV 0x8E14 #define GL_QUERY_BY_REGION_WAIT_NV 0x8E15 #define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16 #endif #ifndef GL_NV_present_video #define GL_FRAME_NV 0x8E26 #define GL_FIELDS_NV 0x8E27 #define GL_CURRENT_TIME_NV 0x8E28 #define GL_NUM_FILL_STREAMS_NV 0x8E29 #define GL_PRESENT_TIME_NV 0x8E2A #define GL_PRESENT_DURATION_NV 0x8E2B #endif #ifndef GL_EXT_transform_feedback #define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E #define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84 #define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85 #define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F #define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C #define GL_SEPARATE_ATTRIBS_EXT 0x8C8D #define GL_PRIMITIVES_GENERATED_EXT 0x8C87 #define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88 #define GL_RASTERIZER_DISCARD_EXT 0x8C89 #define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A #define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B #define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80 #define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83 #define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F #define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76 #endif #ifndef GL_EXT_direct_state_access #define GL_PROGRAM_MATRIX_EXT 0x8E2D #define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E #define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F #endif #ifndef GL_EXT_vertex_array_bgra /* reuse GL_BGRA */ #endif #ifndef GL_EXT_texture_swizzle #define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42 #define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43 #define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44 #define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45 #define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46 #endif #ifndef GL_NV_explicit_multisample #define GL_SAMPLE_POSITION_NV 0x8E50 #define GL_SAMPLE_MASK_NV 0x8E51 #define GL_SAMPLE_MASK_VALUE_NV 0x8E52 #define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53 #define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54 #define GL_TEXTURE_RENDERBUFFER_NV 0x8E55 #define GL_SAMPLER_RENDERBUFFER_NV 0x8E56 #define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57 #define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58 #define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59 #endif #ifndef GL_NV_transform_feedback2 #define GL_TRANSFORM_FEEDBACK_NV 0x8E22 #define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23 #define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24 #define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25 #endif #ifndef GL_ATI_meminfo #define GL_VBO_FREE_MEMORY_ATI 0x87FB #define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC #define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD #endif #ifndef GL_AMD_performance_monitor #define GL_COUNTER_TYPE_AMD 0x8BC0 #define GL_COUNTER_RANGE_AMD 0x8BC1 #define GL_UNSIGNED_INT64_AMD 0x8BC2 #define GL_PERCENTAGE_AMD 0x8BC3 #define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 #define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 #define GL_PERFMON_RESULT_AMD 0x8BC6 #endif #ifndef GL_AMD_texture_texture4 #endif #ifndef GL_AMD_vertex_shader_tesselator #define GL_SAMPLER_BUFFER_AMD 0x9001 #define GL_INT_SAMPLER_BUFFER_AMD 0x9002 #define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003 #define GL_TESSELLATION_MODE_AMD 0x9004 #define GL_TESSELLATION_FACTOR_AMD 0x9005 #define GL_DISCRETE_AMD 0x9006 #define GL_CONTINUOUS_AMD 0x9007 #endif #ifndef GL_EXT_provoking_vertex #define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C #define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D #define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E #define GL_PROVOKING_VERTEX_EXT 0x8E4F #endif #ifndef GL_EXT_texture_snorm #define GL_ALPHA_SNORM 0x9010 #define GL_LUMINANCE_SNORM 0x9011 #define GL_LUMINANCE_ALPHA_SNORM 0x9012 #define GL_INTENSITY_SNORM 0x9013 #define GL_ALPHA8_SNORM 0x9014 #define GL_LUMINANCE8_SNORM 0x9015 #define GL_LUMINANCE8_ALPHA8_SNORM 0x9016 #define GL_INTENSITY8_SNORM 0x9017 #define GL_ALPHA16_SNORM 0x9018 #define GL_LUMINANCE16_SNORM 0x9019 #define GL_LUMINANCE16_ALPHA16_SNORM 0x901A #define GL_INTENSITY16_SNORM 0x901B /* reuse GL_RED_SNORM */ /* reuse GL_RG_SNORM */ /* reuse GL_RGB_SNORM */ /* reuse GL_RGBA_SNORM */ /* reuse GL_R8_SNORM */ /* reuse GL_RG8_SNORM */ /* reuse GL_RGB8_SNORM */ /* reuse GL_RGBA8_SNORM */ /* reuse GL_R16_SNORM */ /* reuse GL_RG16_SNORM */ /* reuse GL_RGB16_SNORM */ /* reuse GL_RGBA16_SNORM */ /* reuse GL_SIGNED_NORMALIZED */ #endif #ifndef GL_AMD_draw_buffers_blend #endif #ifndef GL_APPLE_texture_range #define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7 #define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8 #define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC #define GL_STORAGE_PRIVATE_APPLE 0x85BD /* reuse GL_STORAGE_CACHED_APPLE */ /* reuse GL_STORAGE_SHARED_APPLE */ #endif #ifndef GL_APPLE_float_pixels #define GL_HALF_APPLE 0x140B #define GL_RGBA_FLOAT32_APPLE 0x8814 #define GL_RGB_FLOAT32_APPLE 0x8815 #define GL_ALPHA_FLOAT32_APPLE 0x8816 #define GL_INTENSITY_FLOAT32_APPLE 0x8817 #define GL_LUMINANCE_FLOAT32_APPLE 0x8818 #define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819 #define GL_RGBA_FLOAT16_APPLE 0x881A #define GL_RGB_FLOAT16_APPLE 0x881B #define GL_ALPHA_FLOAT16_APPLE 0x881C #define GL_INTENSITY_FLOAT16_APPLE 0x881D #define GL_LUMINANCE_FLOAT16_APPLE 0x881E #define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F #define GL_COLOR_FLOAT_APPLE 0x8A0F #endif #ifndef GL_APPLE_vertex_program_evaluators #define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00 #define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01 #define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02 #define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03 #define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04 #define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05 #define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06 #define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07 #define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08 #define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09 #endif #ifndef GL_APPLE_aux_depth_stencil #define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14 #endif #ifndef GL_APPLE_object_purgeable #define GL_BUFFER_OBJECT_APPLE 0x85B3 #define GL_RELEASED_APPLE 0x8A19 #define GL_VOLATILE_APPLE 0x8A1A #define GL_RETAINED_APPLE 0x8A1B #define GL_UNDEFINED_APPLE 0x8A1C #define GL_PURGEABLE_APPLE 0x8A1D #endif #ifndef GL_APPLE_row_bytes #define GL_PACK_ROW_BYTES_APPLE 0x8A15 #define GL_UNPACK_ROW_BYTES_APPLE 0x8A16 #endif #ifndef GL_APPLE_rgb_422 #define GL_RGB_422_APPLE 0x8A1F /* reuse GL_UNSIGNED_SHORT_8_8_APPLE */ /* reuse GL_UNSIGNED_SHORT_8_8_REV_APPLE */ #endif #ifndef GL_NV_video_capture #define GL_VIDEO_BUFFER_NV 0x9020 #define GL_VIDEO_BUFFER_BINDING_NV 0x9021 #define GL_FIELD_UPPER_NV 0x9022 #define GL_FIELD_LOWER_NV 0x9023 #define GL_NUM_VIDEO_CAPTURE_STREAMS_NV 0x9024 #define GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025 #define GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV 0x9026 #define GL_LAST_VIDEO_CAPTURE_STATUS_NV 0x9027 #define GL_VIDEO_BUFFER_PITCH_NV 0x9028 #define GL_VIDEO_COLOR_CONVERSION_MATRIX_NV 0x9029 #define GL_VIDEO_COLOR_CONVERSION_MAX_NV 0x902A #define GL_VIDEO_COLOR_CONVERSION_MIN_NV 0x902B #define GL_VIDEO_COLOR_CONVERSION_OFFSET_NV 0x902C #define GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV 0x902D #define GL_PARTIAL_SUCCESS_NV 0x902E #define GL_SUCCESS_NV 0x902F #define GL_FAILURE_NV 0x9030 #define GL_YCBYCR8_422_NV 0x9031 #define GL_YCBAYCR8A_4224_NV 0x9032 #define GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV 0x9033 #define GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV 0x9034 #define GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV 0x9035 #define GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV 0x9036 #define GL_Z4Y12Z4CB12Z4CR12_444_NV 0x9037 #define GL_VIDEO_CAPTURE_FRAME_WIDTH_NV 0x9038 #define GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV 0x9039 #define GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV 0x903A #define GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B #define GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C #endif #ifndef GL_NV_copy_image #endif #ifndef GL_EXT_separate_shader_objects #define GL_ACTIVE_PROGRAM_EXT 0x8B8D #endif #ifndef GL_NV_parameter_buffer_object2 #endif #ifndef GL_NV_shader_buffer_load #define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D #define GL_GPU_ADDRESS_NV 0x8F34 #define GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35 #endif #ifndef GL_NV_vertex_buffer_unified_memory #define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E #define GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F #define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20 #define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21 #define GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22 #define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23 #define GL_INDEX_ARRAY_ADDRESS_NV 0x8F24 #define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25 #define GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26 #define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27 #define GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28 #define GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29 #define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A #define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B #define GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C #define GL_COLOR_ARRAY_LENGTH_NV 0x8F2D #define GL_INDEX_ARRAY_LENGTH_NV 0x8F2E #define GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F #define GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30 #define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31 #define GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32 #define GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33 #define GL_DRAW_INDIRECT_UNIFIED_NV 0x8F40 #define GL_DRAW_INDIRECT_ADDRESS_NV 0x8F41 #define GL_DRAW_INDIRECT_LENGTH_NV 0x8F42 #endif #ifndef GL_NV_texture_barrier #endif #ifndef GL_AMD_shader_stencil_export #endif #ifndef GL_AMD_seamless_cubemap_per_texture /* reuse GL_TEXTURE_CUBE_MAP_SEAMLESS */ #endif #ifndef GL_AMD_conservative_depth #endif #ifndef GL_EXT_shader_image_load_store #define GL_MAX_IMAGE_UNITS_EXT 0x8F38 #define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT 0x8F39 #define GL_IMAGE_BINDING_NAME_EXT 0x8F3A #define GL_IMAGE_BINDING_LEVEL_EXT 0x8F3B #define GL_IMAGE_BINDING_LAYERED_EXT 0x8F3C #define GL_IMAGE_BINDING_LAYER_EXT 0x8F3D #define GL_IMAGE_BINDING_ACCESS_EXT 0x8F3E #define GL_IMAGE_1D_EXT 0x904C #define GL_IMAGE_2D_EXT 0x904D #define GL_IMAGE_3D_EXT 0x904E #define GL_IMAGE_2D_RECT_EXT 0x904F #define GL_IMAGE_CUBE_EXT 0x9050 #define GL_IMAGE_BUFFER_EXT 0x9051 #define GL_IMAGE_1D_ARRAY_EXT 0x9052 #define GL_IMAGE_2D_ARRAY_EXT 0x9053 #define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054 #define GL_IMAGE_2D_MULTISAMPLE_EXT 0x9055 #define GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9056 #define GL_INT_IMAGE_1D_EXT 0x9057 #define GL_INT_IMAGE_2D_EXT 0x9058 #define GL_INT_IMAGE_3D_EXT 0x9059 #define GL_INT_IMAGE_2D_RECT_EXT 0x905A #define GL_INT_IMAGE_CUBE_EXT 0x905B #define GL_INT_IMAGE_BUFFER_EXT 0x905C #define GL_INT_IMAGE_1D_ARRAY_EXT 0x905D #define GL_INT_IMAGE_2D_ARRAY_EXT 0x905E #define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F #define GL_INT_IMAGE_2D_MULTISAMPLE_EXT 0x9060 #define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9061 #define GL_UNSIGNED_INT_IMAGE_1D_EXT 0x9062 #define GL_UNSIGNED_INT_IMAGE_2D_EXT 0x9063 #define GL_UNSIGNED_INT_IMAGE_3D_EXT 0x9064 #define GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT 0x9065 #define GL_UNSIGNED_INT_IMAGE_CUBE_EXT 0x9066 #define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067 #define GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT 0x9068 #define GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT 0x9069 #define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A #define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT 0x906B #define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x906C #define GL_MAX_IMAGE_SAMPLES_EXT 0x906D #define GL_IMAGE_BINDING_FORMAT_EXT 0x906E #define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT 0x00000001 #define GL_ELEMENT_ARRAY_BARRIER_BIT_EXT 0x00000002 #define GL_UNIFORM_BARRIER_BIT_EXT 0x00000004 #define GL_TEXTURE_FETCH_BARRIER_BIT_EXT 0x00000008 #define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT 0x00000020 #define GL_COMMAND_BARRIER_BIT_EXT 0x00000040 #define GL_PIXEL_BUFFER_BARRIER_BIT_EXT 0x00000080 #define GL_TEXTURE_UPDATE_BARRIER_BIT_EXT 0x00000100 #define GL_BUFFER_UPDATE_BARRIER_BIT_EXT 0x00000200 #define GL_FRAMEBUFFER_BARRIER_BIT_EXT 0x00000400 #define GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT 0x00000800 #define GL_ATOMIC_COUNTER_BARRIER_BIT_EXT 0x00001000 #define GL_ALL_BARRIER_BITS_EXT 0xFFFFFFFF #endif #ifndef GL_EXT_vertex_attrib_64bit /* reuse GL_DOUBLE */ #define GL_DOUBLE_VEC2_EXT 0x8FFC #define GL_DOUBLE_VEC3_EXT 0x8FFD #define GL_DOUBLE_VEC4_EXT 0x8FFE #define GL_DOUBLE_MAT2_EXT 0x8F46 #define GL_DOUBLE_MAT3_EXT 0x8F47 #define GL_DOUBLE_MAT4_EXT 0x8F48 #define GL_DOUBLE_MAT2x3_EXT 0x8F49 #define GL_DOUBLE_MAT2x4_EXT 0x8F4A #define GL_DOUBLE_MAT3x2_EXT 0x8F4B #define GL_DOUBLE_MAT3x4_EXT 0x8F4C #define GL_DOUBLE_MAT4x2_EXT 0x8F4D #define GL_DOUBLE_MAT4x3_EXT 0x8F4E #endif #ifndef GL_NV_gpu_program5 #define GL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV 0x8E5A #define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5B #define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5C #define GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV 0x8E5D #define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5E #define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5F #define GL_MAX_PROGRAM_SUBROUTINE_PARAMETERS_NV 0x8F44 #define GL_MAX_PROGRAM_SUBROUTINE_NUM_NV 0x8F45 #endif #ifndef GL_NV_gpu_shader5 #define GL_INT64_NV 0x140E #define GL_UNSIGNED_INT64_NV 0x140F #define GL_INT8_NV 0x8FE0 #define GL_INT8_VEC2_NV 0x8FE1 #define GL_INT8_VEC3_NV 0x8FE2 #define GL_INT8_VEC4_NV 0x8FE3 #define GL_INT16_NV 0x8FE4 #define GL_INT16_VEC2_NV 0x8FE5 #define GL_INT16_VEC3_NV 0x8FE6 #define GL_INT16_VEC4_NV 0x8FE7 #define GL_INT64_VEC2_NV 0x8FE9 #define GL_INT64_VEC3_NV 0x8FEA #define GL_INT64_VEC4_NV 0x8FEB #define GL_UNSIGNED_INT8_NV 0x8FEC #define GL_UNSIGNED_INT8_VEC2_NV 0x8FED #define GL_UNSIGNED_INT8_VEC3_NV 0x8FEE #define GL_UNSIGNED_INT8_VEC4_NV 0x8FEF #define GL_UNSIGNED_INT16_NV 0x8FF0 #define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1 #define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2 #define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3 #define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5 #define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6 #define GL_UNSIGNED_INT64_VEC4_NV 0x8FF7 #define GL_FLOAT16_NV 0x8FF8 #define GL_FLOAT16_VEC2_NV 0x8FF9 #define GL_FLOAT16_VEC3_NV 0x8FFA #define GL_FLOAT16_VEC4_NV 0x8FFB /* reuse GL_PATCHES */ #endif #ifndef GL_NV_shader_buffer_store #define GL_SHADER_GLOBAL_ACCESS_BARRIER_BIT_NV 0x00000010 /* reuse GL_READ_WRITE */ /* reuse GL_WRITE_ONLY */ #endif #ifndef GL_NV_tessellation_program5 #define GL_MAX_PROGRAM_PATCH_ATTRIBS_NV 0x86D8 #define GL_TESS_CONTROL_PROGRAM_NV 0x891E #define GL_TESS_EVALUATION_PROGRAM_NV 0x891F #define GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV 0x8C74 #define GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV 0x8C75 #endif #ifndef GL_NV_vertex_attrib_integer_64bit /* reuse GL_INT64_NV */ /* reuse GL_UNSIGNED_INT64_NV */ #endif #ifndef GL_NV_multisample_coverage #define GL_COVERAGE_SAMPLES_NV 0x80A9 #define GL_COLOR_SAMPLES_NV 0x8E20 #endif #ifndef GL_AMD_name_gen_delete #define GL_DATA_BUFFER_AMD 0x9151 #define GL_PERFORMANCE_MONITOR_AMD 0x9152 #define GL_QUERY_OBJECT_AMD 0x9153 #define GL_VERTEX_ARRAY_OBJECT_AMD 0x9154 #define GL_SAMPLER_OBJECT_AMD 0x9155 #endif #ifndef GL_AMD_debug_output #define GL_MAX_DEBUG_MESSAGE_LENGTH_AMD 0x9143 #define GL_MAX_DEBUG_LOGGED_MESSAGES_AMD 0x9144 #define GL_DEBUG_LOGGED_MESSAGES_AMD 0x9145 #define GL_DEBUG_SEVERITY_HIGH_AMD 0x9146 #define GL_DEBUG_SEVERITY_MEDIUM_AMD 0x9147 #define GL_DEBUG_SEVERITY_LOW_AMD 0x9148 #define GL_DEBUG_CATEGORY_API_ERROR_AMD 0x9149 #define GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A #define GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B #define GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C #define GL_DEBUG_CATEGORY_PERFORMANCE_AMD 0x914D #define GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD 0x914E #define GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F #define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150 #endif #ifndef GL_NV_vdpau_interop #define GL_SURFACE_STATE_NV 0x86EB #define GL_SURFACE_REGISTERED_NV 0x86FD #define GL_SURFACE_MAPPED_NV 0x8700 #define GL_WRITE_DISCARD_NV 0x88BE #endif #ifndef GL_AMD_transform_feedback3_lines_triangles #endif #ifndef GL_AMD_depth_clamp_separate #define GL_DEPTH_CLAMP_NEAR_AMD 0x901E #define GL_DEPTH_CLAMP_FAR_AMD 0x901F #endif #ifndef GL_EXT_texture_sRGB_decode #define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48 #define GL_DECODE_EXT 0x8A49 #define GL_SKIP_DECODE_EXT 0x8A4A #endif #ifndef GL_NV_texture_multisample #define GL_TEXTURE_COVERAGE_SAMPLES_NV 0x9045 #define GL_TEXTURE_COLOR_SAMPLES_NV 0x9046 #endif #ifndef GL_AMD_blend_minmax_factor #define GL_FACTOR_MIN_AMD 0x901C #define GL_FACTOR_MAX_AMD 0x901D #endif #ifndef GL_AMD_sample_positions #define GL_SUBSAMPLE_DISTANCE_AMD 0x883F #endif #ifndef GL_EXT_x11_sync_object #define GL_SYNC_X11_FENCE_EXT 0x90E1 #endif #ifndef GL_AMD_multi_draw_indirect #endif #ifndef GL_EXT_framebuffer_multisample_blit_scaled #define GL_SCALED_RESOLVE_FASTEST_EXT 0x90BA #define GL_SCALED_RESOLVE_NICEST_EXT 0x90BB #endif #ifndef GL_NV_path_rendering #define GL_PATH_FORMAT_SVG_NV 0x9070 #define GL_PATH_FORMAT_PS_NV 0x9071 #define GL_STANDARD_FONT_NAME_NV 0x9072 #define GL_SYSTEM_FONT_NAME_NV 0x9073 #define GL_FILE_NAME_NV 0x9074 #define GL_PATH_STROKE_WIDTH_NV 0x9075 #define GL_PATH_END_CAPS_NV 0x9076 #define GL_PATH_INITIAL_END_CAP_NV 0x9077 #define GL_PATH_TERMINAL_END_CAP_NV 0x9078 #define GL_PATH_JOIN_STYLE_NV 0x9079 #define GL_PATH_MITER_LIMIT_NV 0x907A #define GL_PATH_DASH_CAPS_NV 0x907B #define GL_PATH_INITIAL_DASH_CAP_NV 0x907C #define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D #define GL_PATH_DASH_OFFSET_NV 0x907E #define GL_PATH_CLIENT_LENGTH_NV 0x907F #define GL_PATH_FILL_MODE_NV 0x9080 #define GL_PATH_FILL_MASK_NV 0x9081 #define GL_PATH_FILL_COVER_MODE_NV 0x9082 #define GL_PATH_STROKE_COVER_MODE_NV 0x9083 #define GL_PATH_STROKE_MASK_NV 0x9084 #define GL_PATH_SAMPLE_QUALITY_NV 0x9085 #define GL_PATH_STROKE_BOUND_NV 0x9086 #define GL_PATH_STROKE_OVERSAMPLE_COUNT_NV 0x9087 #define GL_COUNT_UP_NV 0x9088 #define GL_COUNT_DOWN_NV 0x9089 #define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A #define GL_CONVEX_HULL_NV 0x908B #define GL_MULTI_HULLS_NV 0x908C #define GL_BOUNDING_BOX_NV 0x908D #define GL_TRANSLATE_X_NV 0x908E #define GL_TRANSLATE_Y_NV 0x908F #define GL_TRANSLATE_2D_NV 0x9090 #define GL_TRANSLATE_3D_NV 0x9091 #define GL_AFFINE_2D_NV 0x9092 #define GL_PROJECTIVE_2D_NV 0x9093 #define GL_AFFINE_3D_NV 0x9094 #define GL_PROJECTIVE_3D_NV 0x9095 #define GL_TRANSPOSE_AFFINE_2D_NV 0x9096 #define GL_TRANSPOSE_PROJECTIVE_2D_NV 0x9097 #define GL_TRANSPOSE_AFFINE_3D_NV 0x9098 #define GL_TRANSPOSE_PROJECTIVE_3D_NV 0x9099 #define GL_UTF8_NV 0x909A #define GL_UTF16_NV 0x909B #define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C #define GL_PATH_COMMAND_COUNT_NV 0x909D #define GL_PATH_COORD_COUNT_NV 0x909E #define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F #define GL_PATH_COMPUTED_LENGTH_NV 0x90A0 #define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1 #define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2 #define GL_SQUARE_NV 0x90A3 #define GL_ROUND_NV 0x90A4 #define GL_TRIANGULAR_NV 0x90A5 #define GL_BEVEL_NV 0x90A6 #define GL_MITER_REVERT_NV 0x90A7 #define GL_MITER_TRUNCATE_NV 0x90A8 #define GL_SKIP_MISSING_GLYPH_NV 0x90A9 #define GL_USE_MISSING_GLYPH_NV 0x90AA #define GL_PATH_ERROR_POSITION_NV 0x90AB #define GL_PATH_FOG_GEN_MODE_NV 0x90AC #define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD #define GL_ADJACENT_PAIRS_NV 0x90AE #define GL_FIRST_TO_REST_NV 0x90AF #define GL_PATH_GEN_MODE_NV 0x90B0 #define GL_PATH_GEN_COEFF_NV 0x90B1 #define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2 #define GL_PATH_GEN_COMPONENTS_NV 0x90B3 #define GL_PATH_STENCIL_FUNC_NV 0x90B7 #define GL_PATH_STENCIL_REF_NV 0x90B8 #define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9 #define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD #define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE #define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF #define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4 #define GL_MOVE_TO_RESETS_NV 0x90B5 #define GL_MOVE_TO_CONTINUES_NV 0x90B6 #define GL_CLOSE_PATH_NV 0x00 #define GL_MOVE_TO_NV 0x02 #define GL_RELATIVE_MOVE_TO_NV 0x03 #define GL_LINE_TO_NV 0x04 #define GL_RELATIVE_LINE_TO_NV 0x05 #define GL_HORIZONTAL_LINE_TO_NV 0x06 #define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07 #define GL_VERTICAL_LINE_TO_NV 0x08 #define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09 #define GL_QUADRATIC_CURVE_TO_NV 0x0A #define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B #define GL_CUBIC_CURVE_TO_NV 0x0C #define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D #define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E #define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F #define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10 #define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11 #define GL_SMALL_CCW_ARC_TO_NV 0x12 #define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13 #define GL_SMALL_CW_ARC_TO_NV 0x14 #define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15 #define GL_LARGE_CCW_ARC_TO_NV 0x16 #define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17 #define GL_LARGE_CW_ARC_TO_NV 0x18 #define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19 #define GL_RESTART_PATH_NV 0xF0 #define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2 #define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4 #define GL_RECT_NV 0xF6 #define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8 #define GL_CIRCULAR_CW_ARC_TO_NV 0xFA #define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC #define GL_ARC_TO_NV 0xFE #define GL_RELATIVE_ARC_TO_NV 0xFF #define GL_BOLD_BIT_NV 0x01 #define GL_ITALIC_BIT_NV 0x02 #define GL_GLYPH_WIDTH_BIT_NV 0x01 #define GL_GLYPH_HEIGHT_BIT_NV 0x02 #define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04 #define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08 #define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10 #define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20 #define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40 #define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80 #define GL_GLYPH_HAS_KERNING_NV 0x100 #define GL_FONT_X_MIN_BOUNDS_NV 0x00010000 #define GL_FONT_Y_MIN_BOUNDS_NV 0x00020000 #define GL_FONT_X_MAX_BOUNDS_NV 0x00040000 #define GL_FONT_Y_MAX_BOUNDS_NV 0x00080000 #define GL_FONT_UNITS_PER_EM_NV 0x00100000 #define GL_FONT_ASCENDER_NV 0x00200000 #define GL_FONT_DESCENDER_NV 0x00400000 #define GL_FONT_HEIGHT_NV 0x00800000 #define GL_FONT_MAX_ADVANCE_WIDTH_NV 0x01000000 #define GL_FONT_MAX_ADVANCE_HEIGHT_NV 0x02000000 #define GL_FONT_UNDERLINE_POSITION_NV 0x04000000 #define GL_FONT_UNDERLINE_THICKNESS_NV 0x08000000 #define GL_FONT_HAS_KERNING_NV 0x10000000 #endif #ifndef GL_AMD_pinned_memory #define GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD 0x9160 #endif #ifndef GL_AMD_stencil_operation_extended #define GL_SET_AMD 0x874A #define GL_REPLACE_VALUE_AMD 0x874B #define GL_STENCIL_OP_VALUE_AMD 0x874C #define GL_STENCIL_BACK_OP_VALUE_AMD 0x874D #endif #ifndef GL_AMD_vertex_shader_viewport_index #endif #ifndef GL_AMD_vertex_shader_layer #endif #ifndef GL_NV_bindless_texture #endif #ifndef GL_NV_shader_atomic_float #endif #ifndef GL_AMD_query_buffer_object #define GL_QUERY_BUFFER_AMD 0x9192 #define GL_QUERY_BUFFER_BINDING_AMD 0x9193 #define GL_QUERY_RESULT_NO_WAIT_AMD 0x9194 #endif #ifndef GL_AMD_sparse_texture #define GL_VIRTUAL_PAGE_SIZE_X_AMD 0x9195 #define GL_VIRTUAL_PAGE_SIZE_Y_AMD 0x9196 #define GL_VIRTUAL_PAGE_SIZE_Z_AMD 0x9197 #define GL_MAX_SPARSE_TEXTURE_SIZE_AMD 0x9198 #define GL_MAX_SPARSE_3D_TEXTURE_SIZE_AMD 0x9199 #define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS 0x919A #define GL_MIN_SPARSE_LEVEL_AMD 0x919B #define GL_MIN_LOD_WARNING_AMD 0x919C #define GL_TEXTURE_STORAGE_SPARSE_BIT_AMD 0x00000001 #endif /*************************************************************/ #include #ifndef GL_VERSION_2_0 /* GL type for program/shader text */ typedef char GLchar; #endif #ifndef GL_VERSION_1_5 /* GL types for handling large vertex buffer objects */ typedef ptrdiff_t GLintptr; typedef ptrdiff_t GLsizeiptr; #endif #ifndef GL_ARB_vertex_buffer_object /* GL types for handling large vertex buffer objects */ typedef ptrdiff_t GLintptrARB; typedef ptrdiff_t GLsizeiptrARB; #endif #ifndef GL_ARB_shader_objects /* GL types for program/shader text and shader object handles */ typedef char GLcharARB; typedef unsigned int GLhandleARB; #endif /* GL type for "half" precision (s10e5) float data in host memory */ #ifndef GL_ARB_half_float_pixel typedef unsigned short GLhalfARB; #endif #ifndef GL_NV_half_float typedef unsigned short GLhalfNV; #endif #ifndef GLEXT_64_TYPES_DEFINED /* This code block is duplicated in glxext.h, so must be protected */ #define GLEXT_64_TYPES_DEFINED /* Define int32_t, int64_t, and uint64_t types for UST/MSC */ /* (as used in the GL_EXT_timer_query extension). */ #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #include #elif defined(__sun__) || defined(__digital__) #include #if defined(__STDC__) #if defined(__arch64__) || defined(_LP64) typedef long int int64_t; typedef unsigned long int uint64_t; #else typedef long long int int64_t; typedef unsigned long long int uint64_t; #endif /* __arch64__ */ #endif /* __STDC__ */ #elif defined( __VMS ) || defined(__sgi) #include #elif defined(__SCO__) || defined(__USLC__) #include #elif defined(__UNIXOS2__) || defined(__SOL64__) typedef long int int32_t; typedef long long int int64_t; typedef unsigned long long int uint64_t; #elif defined(_WIN32) && defined(__GNUC__) #include #elif defined(_WIN32) typedef __int32 int32_t; typedef __int64 int64_t; typedef unsigned __int64 uint64_t; #else /* Fallback if nothing above works */ #include #endif #endif #ifndef GL_EXT_timer_query typedef int64_t GLint64EXT; typedef uint64_t GLuint64EXT; #endif #ifndef GL_ARB_sync typedef int64_t GLint64; typedef uint64_t GLuint64; typedef struct __GLsync *GLsync; #endif #ifndef GL_ARB_cl_event /* These incomplete types let us declare types compatible with OpenCL's cl_context and cl_event */ struct _cl_context; struct _cl_event; #endif #ifndef GL_ARB_debug_output typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam); #endif #ifndef GL_AMD_debug_output typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam); #endif #ifndef GL_KHR_debug typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam); #endif #ifndef GL_NV_vdpau_interop typedef GLintptr GLvdpauSurfaceNV; #endif #ifndef GL_VERSION_1_2 #define GL_VERSION_1_2 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); GLAPI void APIENTRY glBlendEquation (GLenum mode); GLAPI void APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); GLAPI void APIENTRY glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); GLAPI void APIENTRY glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); GLAPI void APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); GLAPI void APIENTRY glColorTable (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); GLAPI void APIENTRY glColorTableParameterfv (GLenum target, GLenum pname, const GLfloat *params); GLAPI void APIENTRY glColorTableParameteriv (GLenum target, GLenum pname, const GLint *params); GLAPI void APIENTRY glCopyColorTable (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); GLAPI void APIENTRY glGetColorTable (GLenum target, GLenum format, GLenum type, GLvoid *table); GLAPI void APIENTRY glGetColorTableParameterfv (GLenum target, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetColorTableParameteriv (GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glColorSubTable (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); GLAPI void APIENTRY glCopyColorSubTable (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); GLAPI void APIENTRY glConvolutionFilter1D (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); GLAPI void APIENTRY glConvolutionFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); GLAPI void APIENTRY glConvolutionParameterf (GLenum target, GLenum pname, GLfloat params); GLAPI void APIENTRY glConvolutionParameterfv (GLenum target, GLenum pname, const GLfloat *params); GLAPI void APIENTRY glConvolutionParameteri (GLenum target, GLenum pname, GLint params); GLAPI void APIENTRY glConvolutionParameteriv (GLenum target, GLenum pname, const GLint *params); GLAPI void APIENTRY glCopyConvolutionFilter1D (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); GLAPI void APIENTRY glCopyConvolutionFilter2D (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); GLAPI void APIENTRY glGetConvolutionFilter (GLenum target, GLenum format, GLenum type, GLvoid *image); GLAPI void APIENTRY glGetConvolutionParameterfv (GLenum target, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetConvolutionParameteriv (GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glGetSeparableFilter (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); GLAPI void APIENTRY glSeparableFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); GLAPI void APIENTRY glGetHistogram (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); GLAPI void APIENTRY glGetHistogramParameterfv (GLenum target, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetHistogramParameteriv (GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glGetMinmax (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); GLAPI void APIENTRY glGetMinmaxParameterfv (GLenum target, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetMinmaxParameteriv (GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glHistogram (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); GLAPI void APIENTRY glMinmax (GLenum target, GLenum internalformat, GLboolean sink); GLAPI void APIENTRY glResetHistogram (GLenum target); GLAPI void APIENTRY glResetMinmax (GLenum target); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode); typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); typedef void (APIENTRYP PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); typedef void (APIENTRYP PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); typedef void (APIENTRYP PFNGLRESETHISTOGRAMPROC) (GLenum target); typedef void (APIENTRYP PFNGLRESETMINMAXPROC) (GLenum target); #endif #ifndef GL_VERSION_1_3 #define GL_VERSION_1_3 1 #if 0 //#ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glActiveTexture (GLenum texture); GLAPI void APIENTRY glSampleCoverage (GLfloat value, GLboolean invert); GLAPI void APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); GLAPI void APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); GLAPI void APIENTRY glCompressedTexImage1D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); GLAPI void APIENTRY glCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); GLAPI void APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); GLAPI void APIENTRY glCompressedTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); GLAPI void APIENTRY glGetCompressedTexImage (GLenum target, GLint level, GLvoid *img); GLAPI void APIENTRY glClientActiveTexture (GLenum texture); GLAPI void APIENTRY glMultiTexCoord1d (GLenum target, GLdouble s); GLAPI void APIENTRY glMultiTexCoord1dv (GLenum target, const GLdouble *v); GLAPI void APIENTRY glMultiTexCoord1f (GLenum target, GLfloat s); GLAPI void APIENTRY glMultiTexCoord1fv (GLenum target, const GLfloat *v); GLAPI void APIENTRY glMultiTexCoord1i (GLenum target, GLint s); GLAPI void APIENTRY glMultiTexCoord1iv (GLenum target, const GLint *v); GLAPI void APIENTRY glMultiTexCoord1s (GLenum target, GLshort s); GLAPI void APIENTRY glMultiTexCoord1sv (GLenum target, const GLshort *v); GLAPI void APIENTRY glMultiTexCoord2d (GLenum target, GLdouble s, GLdouble t); GLAPI void APIENTRY glMultiTexCoord2dv (GLenum target, const GLdouble *v); GLAPI void APIENTRY glMultiTexCoord2f (GLenum target, GLfloat s, GLfloat t); GLAPI void APIENTRY glMultiTexCoord2fv (GLenum target, const GLfloat *v); GLAPI void APIENTRY glMultiTexCoord2i (GLenum target, GLint s, GLint t); GLAPI void APIENTRY glMultiTexCoord2iv (GLenum target, const GLint *v); GLAPI void APIENTRY glMultiTexCoord2s (GLenum target, GLshort s, GLshort t); GLAPI void APIENTRY glMultiTexCoord2sv (GLenum target, const GLshort *v); GLAPI void APIENTRY glMultiTexCoord3d (GLenum target, GLdouble s, GLdouble t, GLdouble r); GLAPI void APIENTRY glMultiTexCoord3dv (GLenum target, const GLdouble *v); GLAPI void APIENTRY glMultiTexCoord3f (GLenum target, GLfloat s, GLfloat t, GLfloat r); GLAPI void APIENTRY glMultiTexCoord3fv (GLenum target, const GLfloat *v); GLAPI void APIENTRY glMultiTexCoord3i (GLenum target, GLint s, GLint t, GLint r); GLAPI void APIENTRY glMultiTexCoord3iv (GLenum target, const GLint *v); GLAPI void APIENTRY glMultiTexCoord3s (GLenum target, GLshort s, GLshort t, GLshort r); GLAPI void APIENTRY glMultiTexCoord3sv (GLenum target, const GLshort *v); GLAPI void APIENTRY glMultiTexCoord4d (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); GLAPI void APIENTRY glMultiTexCoord4dv (GLenum target, const GLdouble *v); GLAPI void APIENTRY glMultiTexCoord4f (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); GLAPI void APIENTRY glMultiTexCoord4fv (GLenum target, const GLfloat *v); GLAPI void APIENTRY glMultiTexCoord4i (GLenum target, GLint s, GLint t, GLint r, GLint q); GLAPI void APIENTRY glMultiTexCoord4iv (GLenum target, const GLint *v); GLAPI void APIENTRY glMultiTexCoord4s (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); GLAPI void APIENTRY glMultiTexCoord4sv (GLenum target, const GLshort *v); GLAPI void APIENTRY glLoadTransposeMatrixf (const GLfloat *m); GLAPI void APIENTRY glLoadTransposeMatrixd (const GLdouble *m); GLAPI void APIENTRY glMultTransposeMatrixf (const GLfloat *m); GLAPI void APIENTRY glMultTransposeMatrixd (const GLdouble *m); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img); typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); typedef void (APIENTRYP PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat *m); typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble *m); typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat *m); typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble *m); #endif #ifndef GL_VERSION_1_4 #define GL_VERSION_1_4 1 #if 0 //#ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); GLAPI void APIENTRY glMultiDrawArrays (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); GLAPI void APIENTRY glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei drawcount); GLAPI void APIENTRY glPointParameterf (GLenum pname, GLfloat param); GLAPI void APIENTRY glPointParameterfv (GLenum pname, const GLfloat *params); GLAPI void APIENTRY glPointParameteri (GLenum pname, GLint param); GLAPI void APIENTRY glPointParameteriv (GLenum pname, const GLint *params); GLAPI void APIENTRY glFogCoordf (GLfloat coord); GLAPI void APIENTRY glFogCoordfv (const GLfloat *coord); GLAPI void APIENTRY glFogCoordd (GLdouble coord); GLAPI void APIENTRY glFogCoorddv (const GLdouble *coord); GLAPI void APIENTRY glFogCoordPointer (GLenum type, GLsizei stride, const GLvoid *pointer); GLAPI void APIENTRY glSecondaryColor3b (GLbyte red, GLbyte green, GLbyte blue); GLAPI void APIENTRY glSecondaryColor3bv (const GLbyte *v); GLAPI void APIENTRY glSecondaryColor3d (GLdouble red, GLdouble green, GLdouble blue); GLAPI void APIENTRY glSecondaryColor3dv (const GLdouble *v); GLAPI void APIENTRY glSecondaryColor3f (GLfloat red, GLfloat green, GLfloat blue); GLAPI void APIENTRY glSecondaryColor3fv (const GLfloat *v); GLAPI void APIENTRY glSecondaryColor3i (GLint red, GLint green, GLint blue); GLAPI void APIENTRY glSecondaryColor3iv (const GLint *v); GLAPI void APIENTRY glSecondaryColor3s (GLshort red, GLshort green, GLshort blue); GLAPI void APIENTRY glSecondaryColor3sv (const GLshort *v); GLAPI void APIENTRY glSecondaryColor3ub (GLubyte red, GLubyte green, GLubyte blue); GLAPI void APIENTRY glSecondaryColor3ubv (const GLubyte *v); GLAPI void APIENTRY glSecondaryColor3ui (GLuint red, GLuint green, GLuint blue); GLAPI void APIENTRY glSecondaryColor3uiv (const GLuint *v); GLAPI void APIENTRY glSecondaryColor3us (GLushort red, GLushort green, GLushort blue); GLAPI void APIENTRY glSecondaryColor3usv (const GLushort *v); GLAPI void APIENTRY glSecondaryColorPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); GLAPI void APIENTRY glWindowPos2d (GLdouble x, GLdouble y); GLAPI void APIENTRY glWindowPos2dv (const GLdouble *v); GLAPI void APIENTRY glWindowPos2f (GLfloat x, GLfloat y); GLAPI void APIENTRY glWindowPos2fv (const GLfloat *v); GLAPI void APIENTRY glWindowPos2i (GLint x, GLint y); GLAPI void APIENTRY glWindowPos2iv (const GLint *v); GLAPI void APIENTRY glWindowPos2s (GLshort x, GLshort y); GLAPI void APIENTRY glWindowPos2sv (const GLshort *v); GLAPI void APIENTRY glWindowPos3d (GLdouble x, GLdouble y, GLdouble z); GLAPI void APIENTRY glWindowPos3dv (const GLdouble *v); GLAPI void APIENTRY glWindowPos3f (GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glWindowPos3fv (const GLfloat *v); GLAPI void APIENTRY glWindowPos3i (GLint x, GLint y, GLint z); GLAPI void APIENTRY glWindowPos3iv (const GLint *v); GLAPI void APIENTRY glWindowPos3s (GLshort x, GLshort y, GLshort z); GLAPI void APIENTRY glWindowPos3sv (const GLshort *v); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei drawcount); typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLFOGCOORDFPROC) (GLfloat coord); typedef void (APIENTRYP PFNGLFOGCOORDFVPROC) (const GLfloat *coord); typedef void (APIENTRYP PFNGLFOGCOORDDPROC) (GLdouble coord); typedef void (APIENTRYP PFNGLFOGCOORDDVPROC) (const GLdouble *coord); typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v); typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLWINDOWPOS2DVPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); typedef void (APIENTRYP PFNGLWINDOWPOS2FVPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); typedef void (APIENTRYP PFNGLWINDOWPOS2IVPROC) (const GLint *v); typedef void (APIENTRYP PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); typedef void (APIENTRYP PFNGLWINDOWPOS2SVPROC) (const GLshort *v); typedef void (APIENTRYP PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLWINDOWPOS3DVPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLWINDOWPOS3FVPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); typedef void (APIENTRYP PFNGLWINDOWPOS3IVPROC) (const GLint *v); typedef void (APIENTRYP PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNGLWINDOWPOS3SVPROC) (const GLshort *v); #endif #ifndef GL_VERSION_1_5 #define GL_VERSION_1_5 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGenQueries (GLsizei n, GLuint *ids); GLAPI void APIENTRY glDeleteQueries (GLsizei n, const GLuint *ids); GLAPI GLboolean APIENTRY glIsQuery (GLuint id); GLAPI void APIENTRY glBeginQuery (GLenum target, GLuint id); GLAPI void APIENTRY glEndQuery (GLenum target); GLAPI void APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glGetQueryObjectiv (GLuint id, GLenum pname, GLint *params); GLAPI void APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint *params); GLAPI void APIENTRY glBindBuffer (GLenum target, GLuint buffer); GLAPI void APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers); GLAPI void APIENTRY glGenBuffers (GLsizei n, GLuint *buffers); GLAPI GLboolean APIENTRY glIsBuffer (GLuint buffer); GLAPI void APIENTRY glBufferData (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); GLAPI void APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); GLAPI void APIENTRY glGetBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data); GLAPI GLvoid* APIENTRY glMapBuffer (GLenum target, GLenum access); GLAPI GLboolean APIENTRY glUnmapBuffer (GLenum target); GLAPI void APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, GLvoid* *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids); typedef void (APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids); typedef GLboolean (APIENTRYP PFNGLISQUERYPROC) (GLuint id); typedef void (APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); typedef void (APIENTRYP PFNGLENDQUERYPROC) (GLenum target); typedef void (APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params); typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers); typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers); typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer); typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data); typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target); typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, GLvoid* *params); #endif #ifndef GL_VERSION_2_0 #define GL_VERSION_2_0 1 #if 0 //#ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); GLAPI void APIENTRY glDrawBuffers (GLsizei n, const GLenum *bufs); GLAPI void APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); GLAPI void APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); GLAPI void APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); GLAPI void APIENTRY glAttachShader (GLuint program, GLuint shader); GLAPI void APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name); GLAPI void APIENTRY glCompileShader (GLuint shader); GLAPI GLuint APIENTRY glCreateProgram (void); GLAPI GLuint APIENTRY glCreateShader (GLenum type); GLAPI void APIENTRY glDeleteProgram (GLuint program); GLAPI void APIENTRY glDeleteShader (GLuint shader); GLAPI void APIENTRY glDetachShader (GLuint program, GLuint shader); GLAPI void APIENTRY glDisableVertexAttribArray (GLuint index); GLAPI void APIENTRY glEnableVertexAttribArray (GLuint index); GLAPI void APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); GLAPI void APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); GLAPI void APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj); GLAPI GLint APIENTRY glGetAttribLocation (GLuint program, const GLchar *name); GLAPI void APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params); GLAPI void APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); GLAPI void APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params); GLAPI void APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); GLAPI void APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); GLAPI GLint APIENTRY glGetUniformLocation (GLuint program, const GLchar *name); GLAPI void APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params); GLAPI void APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params); GLAPI void APIENTRY glGetVertexAttribdv (GLuint index, GLenum pname, GLdouble *params); GLAPI void APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params); GLAPI void APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, GLvoid* *pointer); GLAPI GLboolean APIENTRY glIsProgram (GLuint program); GLAPI GLboolean APIENTRY glIsShader (GLuint shader); GLAPI void APIENTRY glLinkProgram (GLuint program); GLAPI void APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar* const *string, const GLint *length); GLAPI void APIENTRY glUseProgram (GLuint program); GLAPI void APIENTRY glUniform1f (GLint location, GLfloat v0); GLAPI void APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1); GLAPI void APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); GLAPI void APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); GLAPI void APIENTRY glUniform1i (GLint location, GLint v0); GLAPI void APIENTRY glUniform2i (GLint location, GLint v0, GLint v1); GLAPI void APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2); GLAPI void APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); GLAPI void APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value); GLAPI void APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value); GLAPI void APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value); GLAPI void APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value); GLAPI void APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value); GLAPI void APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value); GLAPI void APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value); GLAPI void APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value); GLAPI void APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glValidateProgram (GLuint program); GLAPI void APIENTRY glVertexAttrib1d (GLuint index, GLdouble x); GLAPI void APIENTRY glVertexAttrib1dv (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttrib1f (GLuint index, GLfloat x); GLAPI void APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v); GLAPI void APIENTRY glVertexAttrib1s (GLuint index, GLshort x); GLAPI void APIENTRY glVertexAttrib1sv (GLuint index, const GLshort *v); GLAPI void APIENTRY glVertexAttrib2d (GLuint index, GLdouble x, GLdouble y); GLAPI void APIENTRY glVertexAttrib2dv (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y); GLAPI void APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v); GLAPI void APIENTRY glVertexAttrib2s (GLuint index, GLshort x, GLshort y); GLAPI void APIENTRY glVertexAttrib2sv (GLuint index, const GLshort *v); GLAPI void APIENTRY glVertexAttrib3d (GLuint index, GLdouble x, GLdouble y, GLdouble z); GLAPI void APIENTRY glVertexAttrib3dv (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v); GLAPI void APIENTRY glVertexAttrib3s (GLuint index, GLshort x, GLshort y, GLshort z); GLAPI void APIENTRY glVertexAttrib3sv (GLuint index, const GLshort *v); GLAPI void APIENTRY glVertexAttrib4Nbv (GLuint index, const GLbyte *v); GLAPI void APIENTRY glVertexAttrib4Niv (GLuint index, const GLint *v); GLAPI void APIENTRY glVertexAttrib4Nsv (GLuint index, const GLshort *v); GLAPI void APIENTRY glVertexAttrib4Nub (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); GLAPI void APIENTRY glVertexAttrib4Nubv (GLuint index, const GLubyte *v); GLAPI void APIENTRY glVertexAttrib4Nuiv (GLuint index, const GLuint *v); GLAPI void APIENTRY glVertexAttrib4Nusv (GLuint index, const GLushort *v); GLAPI void APIENTRY glVertexAttrib4bv (GLuint index, const GLbyte *v); GLAPI void APIENTRY glVertexAttrib4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); GLAPI void APIENTRY glVertexAttrib4dv (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); GLAPI void APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v); GLAPI void APIENTRY glVertexAttrib4iv (GLuint index, const GLint *v); GLAPI void APIENTRY glVertexAttrib4s (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); GLAPI void APIENTRY glVertexAttrib4sv (GLuint index, const GLshort *v); GLAPI void APIENTRY glVertexAttrib4ubv (GLuint index, const GLubyte *v); GLAPI void APIENTRY glVertexAttrib4uiv (GLuint index, const GLuint *v); GLAPI void APIENTRY glVertexAttrib4usv (GLuint index, const GLushort *v); GLAPI void APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs); typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask); typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name); typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader); typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void); typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type); typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program); typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader); typedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj); typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name); typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params); typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, GLvoid* *pointer); typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program); typedef GLboolean (APIENTRYP PFNGLISSHADERPROC) (GLuint shader); typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program); typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* const *string, const GLint *length); typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program); typedef void (APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); typedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); typedef void (APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); typedef void (APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0); typedef void (APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); typedef void (APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); typedef void (APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); typedef void (APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program); typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); #endif #ifndef GL_VERSION_2_1 #define GL_VERSION_2_1 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); #endif #ifndef GL_VERSION_3_0 #define GL_VERSION_3_0 1 /* OpenGL 3.0 also reuses entry points from these extensions: */ /* ARB_framebuffer_object */ /* ARB_map_buffer_range */ /* ARB_vertex_array_object */ #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glColorMaski (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); GLAPI void APIENTRY glGetBooleani_v (GLenum target, GLuint index, GLboolean *data); GLAPI void APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint *data); GLAPI void APIENTRY glEnablei (GLenum target, GLuint index); GLAPI void APIENTRY glDisablei (GLenum target, GLuint index); GLAPI GLboolean APIENTRY glIsEnabledi (GLenum target, GLuint index); GLAPI void APIENTRY glBeginTransformFeedback (GLenum primitiveMode); GLAPI void APIENTRY glEndTransformFeedback (void); GLAPI void APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); GLAPI void APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer); GLAPI void APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar* const *varyings, GLenum bufferMode); GLAPI void APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); GLAPI void APIENTRY glClampColor (GLenum target, GLenum clamp); GLAPI void APIENTRY glBeginConditionalRender (GLuint id, GLenum mode); GLAPI void APIENTRY glEndConditionalRender (void); GLAPI void APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); GLAPI void APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint *params); GLAPI void APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint *params); GLAPI void APIENTRY glVertexAttribI1i (GLuint index, GLint x); GLAPI void APIENTRY glVertexAttribI2i (GLuint index, GLint x, GLint y); GLAPI void APIENTRY glVertexAttribI3i (GLuint index, GLint x, GLint y, GLint z); GLAPI void APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w); GLAPI void APIENTRY glVertexAttribI1ui (GLuint index, GLuint x); GLAPI void APIENTRY glVertexAttribI2ui (GLuint index, GLuint x, GLuint y); GLAPI void APIENTRY glVertexAttribI3ui (GLuint index, GLuint x, GLuint y, GLuint z); GLAPI void APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); GLAPI void APIENTRY glVertexAttribI1iv (GLuint index, const GLint *v); GLAPI void APIENTRY glVertexAttribI2iv (GLuint index, const GLint *v); GLAPI void APIENTRY glVertexAttribI3iv (GLuint index, const GLint *v); GLAPI void APIENTRY glVertexAttribI4iv (GLuint index, const GLint *v); GLAPI void APIENTRY glVertexAttribI1uiv (GLuint index, const GLuint *v); GLAPI void APIENTRY glVertexAttribI2uiv (GLuint index, const GLuint *v); GLAPI void APIENTRY glVertexAttribI3uiv (GLuint index, const GLuint *v); GLAPI void APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint *v); GLAPI void APIENTRY glVertexAttribI4bv (GLuint index, const GLbyte *v); GLAPI void APIENTRY glVertexAttribI4sv (GLuint index, const GLshort *v); GLAPI void APIENTRY glVertexAttribI4ubv (GLuint index, const GLubyte *v); GLAPI void APIENTRY glVertexAttribI4usv (GLuint index, const GLushort *v); GLAPI void APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint *params); GLAPI void APIENTRY glBindFragDataLocation (GLuint program, GLuint color, const GLchar *name); GLAPI GLint APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name); GLAPI void APIENTRY glUniform1ui (GLint location, GLuint v0); GLAPI void APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1); GLAPI void APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2); GLAPI void APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); GLAPI void APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint *value); GLAPI void APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint *value); GLAPI void APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint *value); GLAPI void APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint *value); GLAPI void APIENTRY glTexParameterIiv (GLenum target, GLenum pname, const GLint *params); GLAPI void APIENTRY glTexParameterIuiv (GLenum target, GLenum pname, const GLuint *params); GLAPI void APIENTRY glGetTexParameterIiv (GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glGetTexParameterIuiv (GLenum target, GLenum pname, GLuint *params); GLAPI void APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint *value); GLAPI void APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint *value); GLAPI void APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat *value); GLAPI void APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); GLAPI const GLubyte * APIENTRY glGetStringi (GLenum name, GLuint index); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOLORMASKIPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data); typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data); typedef void (APIENTRYP PFNGLENABLEIPROC) (GLenum target, GLuint index); typedef void (APIENTRYP PFNGLDISABLEIPROC) (GLenum target, GLuint index); typedef GLboolean (APIENTRYP PFNGLISENABLEDIPROC) (GLenum target, GLuint index); typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode); typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC) (void); typedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); typedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer); typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar* const *varyings, GLenum bufferMode); typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); typedef void (APIENTRYP PFNGLCLAMPCOLORPROC) (GLenum target, GLenum clamp); typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode); typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERPROC) (void); typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint *params); typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IPROC) (GLuint index, GLint x); typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IPROC) (GLuint index, GLint x, GLint y); typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IPROC) (GLuint index, GLint x, GLint y, GLint z); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIPROC) (GLuint index, GLuint x); typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIPROC) (GLuint index, GLuint x, GLuint y); typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVPROC) (GLuint index, const GLbyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVPROC) (GLuint index, const GLushort *v); typedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint *params); typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint color, const GLchar *name); typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar *name); typedef void (APIENTRYP PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0); typedef void (APIENTRYP PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1); typedef void (APIENTRYP PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); typedef void (APIENTRYP PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint *params); typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint *params); typedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint *value); typedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint *value); typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value); typedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index); #endif #ifndef GL_VERSION_3_1 #define GL_VERSION_3_1 1 /* OpenGL 3.1 also reuses entry points from these extensions: */ /* ARB_copy_buffer */ /* ARB_uniform_buffer_object */ #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); GLAPI void APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instancecount); GLAPI void APIENTRY glTexBuffer (GLenum target, GLenum internalformat, GLuint buffer); GLAPI void APIENTRY glPrimitiveRestartIndex (GLuint index); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instancecount); typedef void (APIENTRYP PFNGLTEXBUFFERPROC) (GLenum target, GLenum internalformat, GLuint buffer); typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint index); #endif #ifndef GL_VERSION_3_2 #define GL_VERSION_3_2 1 /* OpenGL 3.2 also reuses entry points from these extensions: */ /* ARB_draw_elements_base_vertex */ /* ARB_provoking_vertex */ /* ARB_sync */ /* ARB_texture_multisample */ #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data); GLAPI void APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params); GLAPI void APIENTRY glFramebufferTexture (GLenum target, GLenum attachment, GLuint texture, GLint level); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data); typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); #endif #ifndef GL_VERSION_3_3 #define GL_VERSION_3_3 1 /* OpenGL 3.3 also reuses entry points from these extensions: */ /* ARB_blend_func_extended */ /* ARB_sampler_objects */ /* ARB_explicit_attrib_location, but it has none */ /* ARB_occlusion_query2 (no entry points) */ /* ARB_shader_bit_encoding (no entry points) */ /* ARB_texture_rgb10_a2ui (no entry points) */ /* ARB_texture_swizzle (no entry points) */ /* ARB_timer_query */ /* ARB_vertex_type_2_10_10_10_rev */ #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor); #endif #ifndef GL_VERSION_4_0 #define GL_VERSION_4_0 1 /* OpenGL 4.0 also reuses entry points from these extensions: */ /* ARB_texture_query_lod (no entry points) */ /* ARB_draw_indirect */ /* ARB_gpu_shader5 (no entry points) */ /* ARB_gpu_shader_fp64 */ /* ARB_shader_subroutine */ /* ARB_tessellation_shader */ /* ARB_texture_buffer_object_rgb32 (no entry points) */ /* ARB_texture_cube_map_array (no entry points) */ /* ARB_texture_gather (no entry points) */ /* ARB_transform_feedback2 */ /* ARB_transform_feedback3 */ #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glMinSampleShading (GLfloat value); GLAPI void APIENTRY glBlendEquationi (GLuint buf, GLenum mode); GLAPI void APIENTRY glBlendEquationSeparatei (GLuint buf, GLenum modeRGB, GLenum modeAlpha); GLAPI void APIENTRY glBlendFunci (GLuint buf, GLenum src, GLenum dst); GLAPI void APIENTRY glBlendFuncSeparatei (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLMINSAMPLESHADINGPROC) (GLfloat value); typedef void (APIENTRYP PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode); typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); typedef void (APIENTRYP PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst); typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); #endif #ifndef GL_VERSION_4_1 #define GL_VERSION_4_1 1 /* OpenGL 4.1 reuses entry points from these extensions: */ /* ARB_ES2_compatibility */ /* ARB_get_program_binary */ /* ARB_separate_shader_objects */ /* ARB_shader_precision (no entry points) */ /* ARB_vertex_attrib_64bit */ /* ARB_viewport_array */ #endif #ifndef GL_VERSION_4_2 #define GL_VERSION_4_2 1 /* OpenGL 4.2 reuses entry points from these extensions: */ /* ARB_base_instance */ /* ARB_shading_language_420pack (no entry points) */ /* ARB_transform_feedback_instanced */ /* ARB_compressed_texture_pixel_storage (no entry points) */ /* ARB_conservative_depth (no entry points) */ /* ARB_internalformat_query */ /* ARB_map_buffer_alignment (no entry points) */ /* ARB_shader_atomic_counters */ /* ARB_shader_image_load_store */ /* ARB_shading_language_packing (no entry points) */ /* ARB_texture_storage */ #endif #ifndef GL_VERSION_4_3 #define GL_VERSION_4_3 1 /* OpenGL 4.3 reuses entry points from these extensions: */ /* ARB_arrays_of_arrays (no entry points, GLSL only) */ /* ARB_fragment_layer_viewport (no entry points, GLSL only) */ /* ARB_shader_image_size (no entry points, GLSL only) */ /* ARB_ES3_compatibility (no entry points) */ /* ARB_clear_buffer_object */ /* ARB_compute_shader */ /* ARB_copy_image */ /* KHR_debug (includes ARB_debug_output commands promoted to KHR without suffixes) */ /* ARB_explicit_uniform_location (no entry points) */ /* ARB_framebuffer_no_attachments */ /* ARB_internalformat_query2 */ /* ARB_invalidate_subdata */ /* ARB_multi_draw_indirect */ /* ARB_program_interface_query */ /* ARB_robust_buffer_access_behavior (no entry points) */ /* ARB_shader_storage_buffer_object */ /* ARB_stencil_texturing (no entry points) */ /* ARB_texture_buffer_range */ /* ARB_texture_query_levels (no entry points) */ /* ARB_texture_storage_multisample */ /* ARB_texture_view */ /* ARB_vertex_attrib_binding */ #endif #ifndef GL_ARB_multitexture #define GL_ARB_multitexture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glActiveTextureARB (GLenum texture); GLAPI void APIENTRY glClientActiveTextureARB (GLenum texture); GLAPI void APIENTRY glMultiTexCoord1dARB (GLenum target, GLdouble s); GLAPI void APIENTRY glMultiTexCoord1dvARB (GLenum target, const GLdouble *v); GLAPI void APIENTRY glMultiTexCoord1fARB (GLenum target, GLfloat s); GLAPI void APIENTRY glMultiTexCoord1fvARB (GLenum target, const GLfloat *v); GLAPI void APIENTRY glMultiTexCoord1iARB (GLenum target, GLint s); GLAPI void APIENTRY glMultiTexCoord1ivARB (GLenum target, const GLint *v); GLAPI void APIENTRY glMultiTexCoord1sARB (GLenum target, GLshort s); GLAPI void APIENTRY glMultiTexCoord1svARB (GLenum target, const GLshort *v); GLAPI void APIENTRY glMultiTexCoord2dARB (GLenum target, GLdouble s, GLdouble t); GLAPI void APIENTRY glMultiTexCoord2dvARB (GLenum target, const GLdouble *v); GLAPI void APIENTRY glMultiTexCoord2fARB (GLenum target, GLfloat s, GLfloat t); GLAPI void APIENTRY glMultiTexCoord2fvARB (GLenum target, const GLfloat *v); GLAPI void APIENTRY glMultiTexCoord2iARB (GLenum target, GLint s, GLint t); GLAPI void APIENTRY glMultiTexCoord2ivARB (GLenum target, const GLint *v); GLAPI void APIENTRY glMultiTexCoord2sARB (GLenum target, GLshort s, GLshort t); GLAPI void APIENTRY glMultiTexCoord2svARB (GLenum target, const GLshort *v); GLAPI void APIENTRY glMultiTexCoord3dARB (GLenum target, GLdouble s, GLdouble t, GLdouble r); GLAPI void APIENTRY glMultiTexCoord3dvARB (GLenum target, const GLdouble *v); GLAPI void APIENTRY glMultiTexCoord3fARB (GLenum target, GLfloat s, GLfloat t, GLfloat r); GLAPI void APIENTRY glMultiTexCoord3fvARB (GLenum target, const GLfloat *v); GLAPI void APIENTRY glMultiTexCoord3iARB (GLenum target, GLint s, GLint t, GLint r); GLAPI void APIENTRY glMultiTexCoord3ivARB (GLenum target, const GLint *v); GLAPI void APIENTRY glMultiTexCoord3sARB (GLenum target, GLshort s, GLshort t, GLshort r); GLAPI void APIENTRY glMultiTexCoord3svARB (GLenum target, const GLshort *v); GLAPI void APIENTRY glMultiTexCoord4dARB (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); GLAPI void APIENTRY glMultiTexCoord4dvARB (GLenum target, const GLdouble *v); GLAPI void APIENTRY glMultiTexCoord4fARB (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); GLAPI void APIENTRY glMultiTexCoord4fvARB (GLenum target, const GLfloat *v); GLAPI void APIENTRY glMultiTexCoord4iARB (GLenum target, GLint s, GLint t, GLint r, GLint q); GLAPI void APIENTRY glMultiTexCoord4ivARB (GLenum target, const GLint *v); GLAPI void APIENTRY glMultiTexCoord4sARB (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); GLAPI void APIENTRY glMultiTexCoord4svARB (GLenum target, const GLshort *v); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLACTIVETEXTUREARBPROC) (GLenum texture); typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); typedef void (APIENTRYP PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); #endif #ifndef GL_ARB_transpose_matrix #define GL_ARB_transpose_matrix 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glLoadTransposeMatrixfARB (const GLfloat *m); GLAPI void APIENTRY glLoadTransposeMatrixdARB (const GLdouble *m); GLAPI void APIENTRY glMultTransposeMatrixfARB (const GLfloat *m); GLAPI void APIENTRY glMultTransposeMatrixdARB (const GLdouble *m); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); #endif #ifndef GL_ARB_multisample #define GL_ARB_multisample 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glSampleCoverageARB (GLfloat value, GLboolean invert); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSAMPLECOVERAGEARBPROC) (GLfloat value, GLboolean invert); #endif #ifndef GL_ARB_texture_env_add #define GL_ARB_texture_env_add 1 #endif #ifndef GL_ARB_texture_cube_map #define GL_ARB_texture_cube_map 1 #endif #ifndef GL_ARB_texture_compression #define GL_ARB_texture_compression 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glCompressedTexImage3DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); GLAPI void APIENTRY glCompressedTexImage2DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); GLAPI void APIENTRY glCompressedTexImage1DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); GLAPI void APIENTRY glCompressedTexSubImage3DARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); GLAPI void APIENTRY glCompressedTexSubImage2DARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); GLAPI void APIENTRY glCompressedTexSubImage1DARB (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum target, GLint level, GLvoid *img); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, GLvoid *img); #endif #ifndef GL_ARB_texture_border_clamp #define GL_ARB_texture_border_clamp 1 #endif #ifndef GL_ARB_point_parameters #define GL_ARB_point_parameters 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPointParameterfARB (GLenum pname, GLfloat param); GLAPI void APIENTRY glPointParameterfvARB (GLenum pname, const GLfloat *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat *params); #endif #ifndef GL_ARB_vertex_blend #define GL_ARB_vertex_blend 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glWeightbvARB (GLint size, const GLbyte *weights); GLAPI void APIENTRY glWeightsvARB (GLint size, const GLshort *weights); GLAPI void APIENTRY glWeightivARB (GLint size, const GLint *weights); GLAPI void APIENTRY glWeightfvARB (GLint size, const GLfloat *weights); GLAPI void APIENTRY glWeightdvARB (GLint size, const GLdouble *weights); GLAPI void APIENTRY glWeightubvARB (GLint size, const GLubyte *weights); GLAPI void APIENTRY glWeightusvARB (GLint size, const GLushort *weights); GLAPI void APIENTRY glWeightuivARB (GLint size, const GLuint *weights); GLAPI void APIENTRY glWeightPointerARB (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); GLAPI void APIENTRY glVertexBlendARB (GLint count); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLWEIGHTBVARBPROC) (GLint size, const GLbyte *weights); typedef void (APIENTRYP PFNGLWEIGHTSVARBPROC) (GLint size, const GLshort *weights); typedef void (APIENTRYP PFNGLWEIGHTIVARBPROC) (GLint size, const GLint *weights); typedef void (APIENTRYP PFNGLWEIGHTFVARBPROC) (GLint size, const GLfloat *weights); typedef void (APIENTRYP PFNGLWEIGHTDVARBPROC) (GLint size, const GLdouble *weights); typedef void (APIENTRYP PFNGLWEIGHTUBVARBPROC) (GLint size, const GLubyte *weights); typedef void (APIENTRYP PFNGLWEIGHTUSVARBPROC) (GLint size, const GLushort *weights); typedef void (APIENTRYP PFNGLWEIGHTUIVARBPROC) (GLint size, const GLuint *weights); typedef void (APIENTRYP PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLVERTEXBLENDARBPROC) (GLint count); #endif #ifndef GL_ARB_matrix_palette #define GL_ARB_matrix_palette 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glCurrentPaletteMatrixARB (GLint index); GLAPI void APIENTRY glMatrixIndexubvARB (GLint size, const GLubyte *indices); GLAPI void APIENTRY glMatrixIndexusvARB (GLint size, const GLushort *indices); GLAPI void APIENTRY glMatrixIndexuivARB (GLint size, const GLuint *indices); GLAPI void APIENTRY glMatrixIndexPointerARB (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index); typedef void (APIENTRYP PFNGLMATRIXINDEXUBVARBPROC) (GLint size, const GLubyte *indices); typedef void (APIENTRYP PFNGLMATRIXINDEXUSVARBPROC) (GLint size, const GLushort *indices); typedef void (APIENTRYP PFNGLMATRIXINDEXUIVARBPROC) (GLint size, const GLuint *indices); typedef void (APIENTRYP PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); #endif #ifndef GL_ARB_texture_env_combine #define GL_ARB_texture_env_combine 1 #endif #ifndef GL_ARB_texture_env_crossbar #define GL_ARB_texture_env_crossbar 1 #endif #ifndef GL_ARB_texture_env_dot3 #define GL_ARB_texture_env_dot3 1 #endif #ifndef GL_ARB_texture_mirrored_repeat #define GL_ARB_texture_mirrored_repeat 1 #endif #ifndef GL_ARB_depth_texture #define GL_ARB_depth_texture 1 #endif #ifndef GL_ARB_shadow #define GL_ARB_shadow 1 #endif #ifndef GL_ARB_shadow_ambient #define GL_ARB_shadow_ambient 1 #endif #ifndef GL_ARB_window_pos #define GL_ARB_window_pos 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glWindowPos2dARB (GLdouble x, GLdouble y); GLAPI void APIENTRY glWindowPos2dvARB (const GLdouble *v); GLAPI void APIENTRY glWindowPos2fARB (GLfloat x, GLfloat y); GLAPI void APIENTRY glWindowPos2fvARB (const GLfloat *v); GLAPI void APIENTRY glWindowPos2iARB (GLint x, GLint y); GLAPI void APIENTRY glWindowPos2ivARB (const GLint *v); GLAPI void APIENTRY glWindowPos2sARB (GLshort x, GLshort y); GLAPI void APIENTRY glWindowPos2svARB (const GLshort *v); GLAPI void APIENTRY glWindowPos3dARB (GLdouble x, GLdouble y, GLdouble z); GLAPI void APIENTRY glWindowPos3dvARB (const GLdouble *v); GLAPI void APIENTRY glWindowPos3fARB (GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glWindowPos3fvARB (const GLfloat *v); GLAPI void APIENTRY glWindowPos3iARB (GLint x, GLint y, GLint z); GLAPI void APIENTRY glWindowPos3ivARB (const GLint *v); GLAPI void APIENTRY glWindowPos3sARB (GLshort x, GLshort y, GLshort z); GLAPI void APIENTRY glWindowPos3svARB (const GLshort *v); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLWINDOWPOS2DVARBPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); typedef void (APIENTRYP PFNGLWINDOWPOS2FVARBPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y); typedef void (APIENTRYP PFNGLWINDOWPOS2IVARBPROC) (const GLint *v); typedef void (APIENTRYP PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); typedef void (APIENTRYP PFNGLWINDOWPOS2SVARBPROC) (const GLshort *v); typedef void (APIENTRYP PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLWINDOWPOS3DVARBPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLWINDOWPOS3FVARBPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); typedef void (APIENTRYP PFNGLWINDOWPOS3IVARBPROC) (const GLint *v); typedef void (APIENTRYP PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNGLWINDOWPOS3SVARBPROC) (const GLshort *v); #endif #ifndef GL_ARB_vertex_program #define GL_ARB_vertex_program 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexAttrib1dARB (GLuint index, GLdouble x); GLAPI void APIENTRY glVertexAttrib1dvARB (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttrib1fARB (GLuint index, GLfloat x); GLAPI void APIENTRY glVertexAttrib1fvARB (GLuint index, const GLfloat *v); GLAPI void APIENTRY glVertexAttrib1sARB (GLuint index, GLshort x); GLAPI void APIENTRY glVertexAttrib1svARB (GLuint index, const GLshort *v); GLAPI void APIENTRY glVertexAttrib2dARB (GLuint index, GLdouble x, GLdouble y); GLAPI void APIENTRY glVertexAttrib2dvARB (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttrib2fARB (GLuint index, GLfloat x, GLfloat y); GLAPI void APIENTRY glVertexAttrib2fvARB (GLuint index, const GLfloat *v); GLAPI void APIENTRY glVertexAttrib2sARB (GLuint index, GLshort x, GLshort y); GLAPI void APIENTRY glVertexAttrib2svARB (GLuint index, const GLshort *v); GLAPI void APIENTRY glVertexAttrib3dARB (GLuint index, GLdouble x, GLdouble y, GLdouble z); GLAPI void APIENTRY glVertexAttrib3dvARB (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttrib3fARB (GLuint index, GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glVertexAttrib3fvARB (GLuint index, const GLfloat *v); GLAPI void APIENTRY glVertexAttrib3sARB (GLuint index, GLshort x, GLshort y, GLshort z); GLAPI void APIENTRY glVertexAttrib3svARB (GLuint index, const GLshort *v); GLAPI void APIENTRY glVertexAttrib4NbvARB (GLuint index, const GLbyte *v); GLAPI void APIENTRY glVertexAttrib4NivARB (GLuint index, const GLint *v); GLAPI void APIENTRY glVertexAttrib4NsvARB (GLuint index, const GLshort *v); GLAPI void APIENTRY glVertexAttrib4NubARB (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); GLAPI void APIENTRY glVertexAttrib4NubvARB (GLuint index, const GLubyte *v); GLAPI void APIENTRY glVertexAttrib4NuivARB (GLuint index, const GLuint *v); GLAPI void APIENTRY glVertexAttrib4NusvARB (GLuint index, const GLushort *v); GLAPI void APIENTRY glVertexAttrib4bvARB (GLuint index, const GLbyte *v); GLAPI void APIENTRY glVertexAttrib4dARB (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); GLAPI void APIENTRY glVertexAttrib4dvARB (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttrib4fARB (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); GLAPI void APIENTRY glVertexAttrib4fvARB (GLuint index, const GLfloat *v); GLAPI void APIENTRY glVertexAttrib4ivARB (GLuint index, const GLint *v); GLAPI void APIENTRY glVertexAttrib4sARB (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); GLAPI void APIENTRY glVertexAttrib4svARB (GLuint index, const GLshort *v); GLAPI void APIENTRY glVertexAttrib4ubvARB (GLuint index, const GLubyte *v); GLAPI void APIENTRY glVertexAttrib4uivARB (GLuint index, const GLuint *v); GLAPI void APIENTRY glVertexAttrib4usvARB (GLuint index, const GLushort *v); GLAPI void APIENTRY glVertexAttribPointerARB (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); GLAPI void APIENTRY glEnableVertexAttribArrayARB (GLuint index); GLAPI void APIENTRY glDisableVertexAttribArrayARB (GLuint index); GLAPI void APIENTRY glProgramStringARB (GLenum target, GLenum format, GLsizei len, const GLvoid *string); GLAPI void APIENTRY glBindProgramARB (GLenum target, GLuint program); GLAPI void APIENTRY glDeleteProgramsARB (GLsizei n, const GLuint *programs); GLAPI void APIENTRY glGenProgramsARB (GLsizei n, GLuint *programs); GLAPI void APIENTRY glProgramEnvParameter4dARB (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); GLAPI void APIENTRY glProgramEnvParameter4dvARB (GLenum target, GLuint index, const GLdouble *params); GLAPI void APIENTRY glProgramEnvParameter4fARB (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); GLAPI void APIENTRY glProgramEnvParameter4fvARB (GLenum target, GLuint index, const GLfloat *params); GLAPI void APIENTRY glProgramLocalParameter4dARB (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); GLAPI void APIENTRY glProgramLocalParameter4dvARB (GLenum target, GLuint index, const GLdouble *params); GLAPI void APIENTRY glProgramLocalParameter4fARB (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); GLAPI void APIENTRY glProgramLocalParameter4fvARB (GLenum target, GLuint index, const GLfloat *params); GLAPI void APIENTRY glGetProgramEnvParameterdvARB (GLenum target, GLuint index, GLdouble *params); GLAPI void APIENTRY glGetProgramEnvParameterfvARB (GLenum target, GLuint index, GLfloat *params); GLAPI void APIENTRY glGetProgramLocalParameterdvARB (GLenum target, GLuint index, GLdouble *params); GLAPI void APIENTRY glGetProgramLocalParameterfvARB (GLenum target, GLuint index, GLfloat *params); GLAPI void APIENTRY glGetProgramivARB (GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glGetProgramStringARB (GLenum target, GLenum pname, GLvoid *string); GLAPI void APIENTRY glGetVertexAttribdvARB (GLuint index, GLenum pname, GLdouble *params); GLAPI void APIENTRY glGetVertexAttribfvARB (GLuint index, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetVertexAttribivARB (GLuint index, GLenum pname, GLint *params); GLAPI void APIENTRY glGetVertexAttribPointervARB (GLuint index, GLenum pname, GLvoid* *pointer); GLAPI GLboolean APIENTRY glIsProgramARB (GLuint program); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); typedef void (APIENTRYP PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const GLvoid *string); typedef void (APIENTRYP PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); typedef void (APIENTRYP PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint *programs); typedef void (APIENTRYP PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint *programs); typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); typedef void (APIENTRYP PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, GLvoid *string); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, GLvoid* *pointer); typedef GLboolean (APIENTRYP PFNGLISPROGRAMARBPROC) (GLuint program); #endif #ifndef GL_ARB_fragment_program #define GL_ARB_fragment_program 1 /* All ARB_fragment_program entry points are shared with ARB_vertex_program. */ #endif #ifndef GL_ARB_vertex_buffer_object #define GL_ARB_vertex_buffer_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBindBufferARB (GLenum target, GLuint buffer); GLAPI void APIENTRY glDeleteBuffersARB (GLsizei n, const GLuint *buffers); GLAPI void APIENTRY glGenBuffersARB (GLsizei n, GLuint *buffers); GLAPI GLboolean APIENTRY glIsBufferARB (GLuint buffer); GLAPI void APIENTRY glBufferDataARB (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage); GLAPI void APIENTRY glBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data); GLAPI void APIENTRY glGetBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data); GLAPI GLvoid* APIENTRY glMapBufferARB (GLenum target, GLenum access); GLAPI GLboolean APIENTRY glUnmapBufferARB (GLenum target); GLAPI void APIENTRY glGetBufferParameterivARB (GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glGetBufferPointervARB (GLenum target, GLenum pname, GLvoid* *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers); typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers); typedef GLboolean (APIENTRYP PFNGLISBUFFERARBPROC) (GLuint buffer); typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage); typedef void (APIENTRYP PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data); typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data); typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERARBPROC) (GLenum target); typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, GLvoid* *params); #endif #ifndef GL_ARB_occlusion_query #define GL_ARB_occlusion_query 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGenQueriesARB (GLsizei n, GLuint *ids); GLAPI void APIENTRY glDeleteQueriesARB (GLsizei n, const GLuint *ids); GLAPI GLboolean APIENTRY glIsQueryARB (GLuint id); GLAPI void APIENTRY glBeginQueryARB (GLenum target, GLuint id); GLAPI void APIENTRY glEndQueryARB (GLenum target); GLAPI void APIENTRY glGetQueryivARB (GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glGetQueryObjectivARB (GLuint id, GLenum pname, GLint *params); GLAPI void APIENTRY glGetQueryObjectuivARB (GLuint id, GLenum pname, GLuint *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint *ids); typedef void (APIENTRYP PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint *ids); typedef GLboolean (APIENTRYP PFNGLISQUERYARBPROC) (GLuint id); typedef void (APIENTRYP PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id); typedef void (APIENTRYP PFNGLENDQUERYARBPROC) (GLenum target); typedef void (APIENTRYP PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint *params); #endif #ifndef GL_ARB_shader_objects #define GL_ARB_shader_objects 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDeleteObjectARB (GLhandleARB obj); GLAPI GLhandleARB APIENTRY glGetHandleARB (GLenum pname); GLAPI void APIENTRY glDetachObjectARB (GLhandleARB containerObj, GLhandleARB attachedObj); GLAPI GLhandleARB APIENTRY glCreateShaderObjectARB (GLenum shaderType); GLAPI void APIENTRY glShaderSourceARB (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length); GLAPI void APIENTRY glCompileShaderARB (GLhandleARB shaderObj); GLAPI GLhandleARB APIENTRY glCreateProgramObjectARB (void); GLAPI void APIENTRY glAttachObjectARB (GLhandleARB containerObj, GLhandleARB obj); GLAPI void APIENTRY glLinkProgramARB (GLhandleARB programObj); GLAPI void APIENTRY glUseProgramObjectARB (GLhandleARB programObj); GLAPI void APIENTRY glValidateProgramARB (GLhandleARB programObj); GLAPI void APIENTRY glUniform1fARB (GLint location, GLfloat v0); GLAPI void APIENTRY glUniform2fARB (GLint location, GLfloat v0, GLfloat v1); GLAPI void APIENTRY glUniform3fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); GLAPI void APIENTRY glUniform4fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); GLAPI void APIENTRY glUniform1iARB (GLint location, GLint v0); GLAPI void APIENTRY glUniform2iARB (GLint location, GLint v0, GLint v1); GLAPI void APIENTRY glUniform3iARB (GLint location, GLint v0, GLint v1, GLint v2); GLAPI void APIENTRY glUniform4iARB (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); GLAPI void APIENTRY glUniform1fvARB (GLint location, GLsizei count, const GLfloat *value); GLAPI void APIENTRY glUniform2fvARB (GLint location, GLsizei count, const GLfloat *value); GLAPI void APIENTRY glUniform3fvARB (GLint location, GLsizei count, const GLfloat *value); GLAPI void APIENTRY glUniform4fvARB (GLint location, GLsizei count, const GLfloat *value); GLAPI void APIENTRY glUniform1ivARB (GLint location, GLsizei count, const GLint *value); GLAPI void APIENTRY glUniform2ivARB (GLint location, GLsizei count, const GLint *value); GLAPI void APIENTRY glUniform3ivARB (GLint location, GLsizei count, const GLint *value); GLAPI void APIENTRY glUniform4ivARB (GLint location, GLsizei count, const GLint *value); GLAPI void APIENTRY glUniformMatrix2fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glUniformMatrix3fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glUniformMatrix4fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glGetObjectParameterfvARB (GLhandleARB obj, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetObjectParameterivARB (GLhandleARB obj, GLenum pname, GLint *params); GLAPI void APIENTRY glGetInfoLogARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); GLAPI void APIENTRY glGetAttachedObjectsARB (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj); GLAPI GLint APIENTRY glGetUniformLocationARB (GLhandleARB programObj, const GLcharARB *name); GLAPI void APIENTRY glGetActiveUniformARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); GLAPI void APIENTRY glGetUniformfvARB (GLhandleARB programObj, GLint location, GLfloat *params); GLAPI void APIENTRY glGetUniformivARB (GLhandleARB programObj, GLint location, GLint *params); GLAPI void APIENTRY glGetShaderSourceARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); typedef GLhandleARB (APIENTRYP PFNGLGETHANDLEARBPROC) (GLenum pname); typedef void (APIENTRYP PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); typedef GLhandleARB (APIENTRYP PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); typedef void (APIENTRYP PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length); typedef void (APIENTRYP PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); typedef GLhandleARB (APIENTRYP PFNGLCREATEPROGRAMOBJECTARBPROC) (void); typedef void (APIENTRYP PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); typedef void (APIENTRYP PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); typedef void (APIENTRYP PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); typedef void (APIENTRYP PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); typedef void (APIENTRYP PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); typedef void (APIENTRYP PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); typedef void (APIENTRYP PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); typedef void (APIENTRYP PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); typedef void (APIENTRYP PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); typedef void (APIENTRYP PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); typedef void (APIENTRYP PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); typedef void (APIENTRYP PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); typedef void (APIENTRYP PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); typedef void (APIENTRYP PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj); typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); typedef void (APIENTRYP PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat *params); typedef void (APIENTRYP PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint *params); typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); #endif #ifndef GL_ARB_vertex_shader #define GL_ARB_vertex_shader 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBindAttribLocationARB (GLhandleARB programObj, GLuint index, const GLcharARB *name); GLAPI void APIENTRY glGetActiveAttribARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); GLAPI GLint APIENTRY glGetAttribLocationARB (GLhandleARB programObj, const GLcharARB *name); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name); typedef void (APIENTRYP PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); #endif #ifndef GL_ARB_fragment_shader #define GL_ARB_fragment_shader 1 #endif #ifndef GL_ARB_shading_language_100 #define GL_ARB_shading_language_100 1 #endif #ifndef GL_ARB_texture_non_power_of_two #define GL_ARB_texture_non_power_of_two 1 #endif #ifndef GL_ARB_point_sprite #define GL_ARB_point_sprite 1 #endif #ifndef GL_ARB_fragment_program_shadow #define GL_ARB_fragment_program_shadow 1 #endif #ifndef GL_ARB_draw_buffers #define GL_ARB_draw_buffers 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawBuffersARB (GLsizei n, const GLenum *bufs); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum *bufs); #endif #ifndef GL_ARB_texture_rectangle #define GL_ARB_texture_rectangle 1 #endif #ifndef GL_ARB_color_buffer_float #define GL_ARB_color_buffer_float 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glClampColorARB (GLenum target, GLenum clamp); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp); #endif #ifndef GL_ARB_half_float_pixel #define GL_ARB_half_float_pixel 1 #endif #ifndef GL_ARB_texture_float #define GL_ARB_texture_float 1 #endif #ifndef GL_ARB_pixel_buffer_object #define GL_ARB_pixel_buffer_object 1 #endif #ifndef GL_ARB_depth_buffer_float #define GL_ARB_depth_buffer_float 1 #endif #ifndef GL_ARB_draw_instanced #define GL_ARB_draw_instanced 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawArraysInstancedARB (GLenum mode, GLint first, GLsizei count, GLsizei primcount); GLAPI void APIENTRY glDrawElementsInstancedARB (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); #endif #ifndef GL_ARB_framebuffer_object #define GL_ARB_framebuffer_object 1 #if 0 //#ifdef GL_GLEXT_PROTOTYPES GLAPI GLboolean APIENTRY glIsRenderbuffer (GLuint renderbuffer); GLAPI void APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); GLAPI void APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers); GLAPI void APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers); GLAPI void APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); GLAPI void APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params); GLAPI GLboolean APIENTRY glIsFramebuffer (GLuint framebuffer); GLAPI void APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); GLAPI void APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers); GLAPI void APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers); GLAPI GLenum APIENTRY glCheckFramebufferStatus (GLenum target); GLAPI void APIENTRY glFramebufferTexture1D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); GLAPI void APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); GLAPI void APIENTRY glFramebufferTexture3D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); GLAPI void APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); GLAPI void APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params); GLAPI void APIENTRY glGenerateMipmap (GLenum target); GLAPI void APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); GLAPI void APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); GLAPI void APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); typedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers); typedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers); typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); typedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers); typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers); typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target); typedef void (APIENTRYP PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); #endif #ifndef GL_ARB_framebuffer_sRGB #define GL_ARB_framebuffer_sRGB 1 #endif #ifndef GL_ARB_geometry_shader4 #define GL_ARB_geometry_shader4 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glProgramParameteriARB (GLuint program, GLenum pname, GLint value); GLAPI void APIENTRY glFramebufferTextureARB (GLenum target, GLenum attachment, GLuint texture, GLint level); GLAPI void APIENTRY glFramebufferTextureLayerARB (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); GLAPI void APIENTRY glFramebufferTextureFaceARB (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIARBPROC) (GLuint program, GLenum pname, GLint value); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); #endif #ifndef GL_ARB_half_float_vertex #define GL_ARB_half_float_vertex 1 #endif #ifndef GL_ARB_instanced_arrays #define GL_ARB_instanced_arrays 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexAttribDivisorARB (GLuint index, GLuint divisor); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor); #endif #ifndef GL_ARB_map_buffer_range #define GL_ARB_map_buffer_range 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLvoid* APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); GLAPI void APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length); #endif #ifndef GL_ARB_texture_buffer_object #define GL_ARB_texture_buffer_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTexBufferARB (GLenum target, GLenum internalformat, GLuint buffer); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXBUFFERARBPROC) (GLenum target, GLenum internalformat, GLuint buffer); #endif #ifndef GL_ARB_texture_compression_rgtc #define GL_ARB_texture_compression_rgtc 1 #endif #ifndef GL_ARB_texture_rg #define GL_ARB_texture_rg 1 #endif #ifndef GL_ARB_vertex_array_object #define GL_ARB_vertex_array_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBindVertexArray (GLuint array); GLAPI void APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays); GLAPI void APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays); GLAPI GLboolean APIENTRY glIsVertexArray (GLuint array); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array); typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays); typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays); typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYPROC) (GLuint array); #endif #ifndef GL_ARB_uniform_buffer_object #define GL_ARB_uniform_buffer_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar* const *uniformNames, GLuint *uniformIndices); GLAPI void APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); GLAPI void APIENTRY glGetActiveUniformName (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName); GLAPI GLuint APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar *uniformBlockName); GLAPI void APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); GLAPI void APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); GLAPI void APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar* const *uniformNames, GLuint *uniformIndices); typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMNAMEPROC) (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName); typedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar *uniformBlockName); typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); typedef void (APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); #endif #ifndef GL_ARB_compatibility #define GL_ARB_compatibility 1 #endif #ifndef GL_ARB_copy_buffer #define GL_ARB_copy_buffer 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); #endif #ifndef GL_ARB_shader_texture_lod #define GL_ARB_shader_texture_lod 1 #endif #ifndef GL_ARB_depth_clamp #define GL_ARB_depth_clamp 1 #endif #ifndef GL_ARB_draw_elements_base_vertex #define GL_ARB_draw_elements_base_vertex 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex); GLAPI void APIENTRY glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex); GLAPI void APIENTRY glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instancecount, GLint basevertex); GLAPI void APIENTRY glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei drawcount, const GLint *basevertex); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex); typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex); typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instancecount, GLint basevertex); typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei drawcount, const GLint *basevertex); #endif #ifndef GL_ARB_fragment_coord_conventions #define GL_ARB_fragment_coord_conventions 1 #endif #ifndef GL_ARB_provoking_vertex #define GL_ARB_provoking_vertex 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glProvokingVertex (GLenum mode); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPROVOKINGVERTEXPROC) (GLenum mode); #endif #ifndef GL_ARB_seamless_cube_map #define GL_ARB_seamless_cube_map 1 #endif #ifndef GL_ARB_sync #define GL_ARB_sync 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLsync APIENTRY glFenceSync (GLenum condition, GLbitfield flags); GLAPI GLboolean APIENTRY glIsSync (GLsync sync); GLAPI void APIENTRY glDeleteSync (GLsync sync); GLAPI GLenum APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); GLAPI void APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); GLAPI void APIENTRY glGetInteger64v (GLenum pname, GLint64 *params); GLAPI void APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC) (GLenum condition, GLbitfield flags); typedef GLboolean (APIENTRYP PFNGLISSYNCPROC) (GLsync sync); typedef void (APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync); typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); typedef void (APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); typedef void (APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *params); typedef void (APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); #endif #ifndef GL_ARB_texture_multisample #define GL_ARB_texture_multisample 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTexImage2DMultisample (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); GLAPI void APIENTRY glTexImage3DMultisample (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); GLAPI void APIENTRY glGetMultisamplefv (GLenum pname, GLuint index, GLfloat *val); GLAPI void APIENTRY glSampleMaski (GLuint index, GLbitfield mask); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat *val); typedef void (APIENTRYP PFNGLSAMPLEMASKIPROC) (GLuint index, GLbitfield mask); #endif #ifndef GL_ARB_vertex_array_bgra #define GL_ARB_vertex_array_bgra 1 #endif #ifndef GL_ARB_draw_buffers_blend #define GL_ARB_draw_buffers_blend 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendEquationiARB (GLuint buf, GLenum mode); GLAPI void APIENTRY glBlendEquationSeparateiARB (GLuint buf, GLenum modeRGB, GLenum modeAlpha); GLAPI void APIENTRY glBlendFunciARB (GLuint buf, GLenum src, GLenum dst); GLAPI void APIENTRY glBlendFuncSeparateiARB (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDEQUATIONIARBPROC) (GLuint buf, GLenum mode); typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIARBPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); typedef void (APIENTRYP PFNGLBLENDFUNCIARBPROC) (GLuint buf, GLenum src, GLenum dst); typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIARBPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); #endif #ifndef GL_ARB_sample_shading #define GL_ARB_sample_shading 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glMinSampleShadingARB (GLfloat value); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLMINSAMPLESHADINGARBPROC) (GLfloat value); #endif #ifndef GL_ARB_texture_cube_map_array #define GL_ARB_texture_cube_map_array 1 #endif #ifndef GL_ARB_texture_gather #define GL_ARB_texture_gather 1 #endif #ifndef GL_ARB_texture_query_lod #define GL_ARB_texture_query_lod 1 #endif #ifndef GL_ARB_shading_language_include #define GL_ARB_shading_language_include 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glNamedStringARB (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string); GLAPI void APIENTRY glDeleteNamedStringARB (GLint namelen, const GLchar *name); GLAPI void APIENTRY glCompileShaderIncludeARB (GLuint shader, GLsizei count, const GLchar* *path, const GLint *length); GLAPI GLboolean APIENTRY glIsNamedStringARB (GLint namelen, const GLchar *name); GLAPI void APIENTRY glGetNamedStringARB (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string); GLAPI void APIENTRY glGetNamedStringivARB (GLint namelen, const GLchar *name, GLenum pname, GLint *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLNAMEDSTRINGARBPROC) (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string); typedef void (APIENTRYP PFNGLDELETENAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name); typedef void (APIENTRYP PFNGLCOMPILESHADERINCLUDEARBPROC) (GLuint shader, GLsizei count, const GLchar* *path, const GLint *length); typedef GLboolean (APIENTRYP PFNGLISNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name); typedef void (APIENTRYP PFNGLGETNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string); typedef void (APIENTRYP PFNGLGETNAMEDSTRINGIVARBPROC) (GLint namelen, const GLchar *name, GLenum pname, GLint *params); #endif #ifndef GL_ARB_texture_compression_bptc #define GL_ARB_texture_compression_bptc 1 #endif #ifndef GL_ARB_blend_func_extended #define GL_ARB_blend_func_extended 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBindFragDataLocationIndexed (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); GLAPI GLint APIENTRY glGetFragDataIndex (GLuint program, const GLchar *name); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); typedef GLint (APIENTRYP PFNGLGETFRAGDATAINDEXPROC) (GLuint program, const GLchar *name); #endif #ifndef GL_ARB_explicit_attrib_location #define GL_ARB_explicit_attrib_location 1 #endif #ifndef GL_ARB_occlusion_query2 #define GL_ARB_occlusion_query2 1 #endif #ifndef GL_ARB_sampler_objects #define GL_ARB_sampler_objects 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGenSamplers (GLsizei count, GLuint *samplers); GLAPI void APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers); GLAPI GLboolean APIENTRY glIsSampler (GLuint sampler); GLAPI void APIENTRY glBindSampler (GLuint unit, GLuint sampler); GLAPI void APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param); GLAPI void APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint *param); GLAPI void APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param); GLAPI void APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat *param); GLAPI void APIENTRY glSamplerParameterIiv (GLuint sampler, GLenum pname, const GLint *param); GLAPI void APIENTRY glSamplerParameterIuiv (GLuint sampler, GLenum pname, const GLuint *param); GLAPI void APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint *params); GLAPI void APIENTRY glGetSamplerParameterIiv (GLuint sampler, GLenum pname, GLint *params); GLAPI void APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetSamplerParameterIuiv (GLuint sampler, GLenum pname, GLuint *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers); typedef void (APIENTRYP PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers); typedef GLboolean (APIENTRYP PFNGLISSAMPLERPROC) (GLuint sampler); typedef void (APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler); typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint *param); typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat *param); typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, const GLint *param); typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, const GLuint *param); typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, GLuint *params); #endif #ifndef GL_ARB_shader_bit_encoding #define GL_ARB_shader_bit_encoding 1 #endif #ifndef GL_ARB_texture_rgb10_a2ui #define GL_ARB_texture_rgb10_a2ui 1 #endif #ifndef GL_ARB_texture_swizzle #define GL_ARB_texture_swizzle 1 #endif #ifndef GL_ARB_timer_query #define GL_ARB_timer_query 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glQueryCounter (GLuint id, GLenum target); GLAPI void APIENTRY glGetQueryObjecti64v (GLuint id, GLenum pname, GLint64 *params); GLAPI void APIENTRY glGetQueryObjectui64v (GLuint id, GLenum pname, GLuint64 *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLQUERYCOUNTERPROC) (GLuint id, GLenum target); typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64 *params); typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64 *params); #endif #ifndef GL_ARB_vertex_type_2_10_10_10_rev #define GL_ARB_vertex_type_2_10_10_10_rev 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexP2ui (GLenum type, GLuint value); GLAPI void APIENTRY glVertexP2uiv (GLenum type, const GLuint *value); GLAPI void APIENTRY glVertexP3ui (GLenum type, GLuint value); GLAPI void APIENTRY glVertexP3uiv (GLenum type, const GLuint *value); GLAPI void APIENTRY glVertexP4ui (GLenum type, GLuint value); GLAPI void APIENTRY glVertexP4uiv (GLenum type, const GLuint *value); GLAPI void APIENTRY glTexCoordP1ui (GLenum type, GLuint coords); GLAPI void APIENTRY glTexCoordP1uiv (GLenum type, const GLuint *coords); GLAPI void APIENTRY glTexCoordP2ui (GLenum type, GLuint coords); GLAPI void APIENTRY glTexCoordP2uiv (GLenum type, const GLuint *coords); GLAPI void APIENTRY glTexCoordP3ui (GLenum type, GLuint coords); GLAPI void APIENTRY glTexCoordP3uiv (GLenum type, const GLuint *coords); GLAPI void APIENTRY glTexCoordP4ui (GLenum type, GLuint coords); GLAPI void APIENTRY glTexCoordP4uiv (GLenum type, const GLuint *coords); GLAPI void APIENTRY glMultiTexCoordP1ui (GLenum texture, GLenum type, GLuint coords); GLAPI void APIENTRY glMultiTexCoordP1uiv (GLenum texture, GLenum type, const GLuint *coords); GLAPI void APIENTRY glMultiTexCoordP2ui (GLenum texture, GLenum type, GLuint coords); GLAPI void APIENTRY glMultiTexCoordP2uiv (GLenum texture, GLenum type, const GLuint *coords); GLAPI void APIENTRY glMultiTexCoordP3ui (GLenum texture, GLenum type, GLuint coords); GLAPI void APIENTRY glMultiTexCoordP3uiv (GLenum texture, GLenum type, const GLuint *coords); GLAPI void APIENTRY glMultiTexCoordP4ui (GLenum texture, GLenum type, GLuint coords); GLAPI void APIENTRY glMultiTexCoordP4uiv (GLenum texture, GLenum type, const GLuint *coords); GLAPI void APIENTRY glNormalP3ui (GLenum type, GLuint coords); GLAPI void APIENTRY glNormalP3uiv (GLenum type, const GLuint *coords); GLAPI void APIENTRY glColorP3ui (GLenum type, GLuint color); GLAPI void APIENTRY glColorP3uiv (GLenum type, const GLuint *color); GLAPI void APIENTRY glColorP4ui (GLenum type, GLuint color); GLAPI void APIENTRY glColorP4uiv (GLenum type, const GLuint *color); GLAPI void APIENTRY glSecondaryColorP3ui (GLenum type, GLuint color); GLAPI void APIENTRY glSecondaryColorP3uiv (GLenum type, const GLuint *color); GLAPI void APIENTRY glVertexAttribP1ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); GLAPI void APIENTRY glVertexAttribP1uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); GLAPI void APIENTRY glVertexAttribP2ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); GLAPI void APIENTRY glVertexAttribP2uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); GLAPI void APIENTRY glVertexAttribP3ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); GLAPI void APIENTRY glVertexAttribP3uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); GLAPI void APIENTRY glVertexAttribP4ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); GLAPI void APIENTRY glVertexAttribP4uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXP2UIPROC) (GLenum type, GLuint value); typedef void (APIENTRYP PFNGLVERTEXP2UIVPROC) (GLenum type, const GLuint *value); typedef void (APIENTRYP PFNGLVERTEXP3UIPROC) (GLenum type, GLuint value); typedef void (APIENTRYP PFNGLVERTEXP3UIVPROC) (GLenum type, const GLuint *value); typedef void (APIENTRYP PFNGLVERTEXP4UIPROC) (GLenum type, GLuint value); typedef void (APIENTRYP PFNGLVERTEXP4UIVPROC) (GLenum type, const GLuint *value); typedef void (APIENTRYP PFNGLTEXCOORDP1UIPROC) (GLenum type, GLuint coords); typedef void (APIENTRYP PFNGLTEXCOORDP1UIVPROC) (GLenum type, const GLuint *coords); typedef void (APIENTRYP PFNGLTEXCOORDP2UIPROC) (GLenum type, GLuint coords); typedef void (APIENTRYP PFNGLTEXCOORDP2UIVPROC) (GLenum type, const GLuint *coords); typedef void (APIENTRYP PFNGLTEXCOORDP3UIPROC) (GLenum type, GLuint coords); typedef void (APIENTRYP PFNGLTEXCOORDP3UIVPROC) (GLenum type, const GLuint *coords); typedef void (APIENTRYP PFNGLTEXCOORDP4UIPROC) (GLenum type, GLuint coords); typedef void (APIENTRYP PFNGLTEXCOORDP4UIVPROC) (GLenum type, const GLuint *coords); typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIPROC) (GLenum texture, GLenum type, GLuint coords); typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIPROC) (GLenum texture, GLenum type, GLuint coords); typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIPROC) (GLenum texture, GLenum type, GLuint coords); typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIPROC) (GLenum texture, GLenum type, GLuint coords); typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); typedef void (APIENTRYP PFNGLNORMALP3UIPROC) (GLenum type, GLuint coords); typedef void (APIENTRYP PFNGLNORMALP3UIVPROC) (GLenum type, const GLuint *coords); typedef void (APIENTRYP PFNGLCOLORP3UIPROC) (GLenum type, GLuint color); typedef void (APIENTRYP PFNGLCOLORP3UIVPROC) (GLenum type, const GLuint *color); typedef void (APIENTRYP PFNGLCOLORP4UIPROC) (GLenum type, GLuint color); typedef void (APIENTRYP PFNGLCOLORP4UIVPROC) (GLenum type, const GLuint *color); typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIPROC) (GLenum type, GLuint color); typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIVPROC) (GLenum type, const GLuint *color); typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); #endif #ifndef GL_ARB_draw_indirect #define GL_ARB_draw_indirect 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawArraysIndirect (GLenum mode, const GLvoid *indirect); GLAPI void APIENTRY glDrawElementsIndirect (GLenum mode, GLenum type, const GLvoid *indirect); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const GLvoid *indirect); typedef void (APIENTRYP PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const GLvoid *indirect); #endif #ifndef GL_ARB_gpu_shader5 #define GL_ARB_gpu_shader5 1 #endif #ifndef GL_ARB_gpu_shader_fp64 #define GL_ARB_gpu_shader_fp64 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glUniform1d (GLint location, GLdouble x); GLAPI void APIENTRY glUniform2d (GLint location, GLdouble x, GLdouble y); GLAPI void APIENTRY glUniform3d (GLint location, GLdouble x, GLdouble y, GLdouble z); GLAPI void APIENTRY glUniform4d (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); GLAPI void APIENTRY glUniform1dv (GLint location, GLsizei count, const GLdouble *value); GLAPI void APIENTRY glUniform2dv (GLint location, GLsizei count, const GLdouble *value); GLAPI void APIENTRY glUniform3dv (GLint location, GLsizei count, const GLdouble *value); GLAPI void APIENTRY glUniform4dv (GLint location, GLsizei count, const GLdouble *value); GLAPI void APIENTRY glUniformMatrix2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glUniformMatrix3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glUniformMatrix4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glUniformMatrix2x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glUniformMatrix2x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glUniformMatrix3x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glUniformMatrix3x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glUniformMatrix4x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glUniformMatrix4x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glGetUniformdv (GLuint program, GLint location, GLdouble *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLUNIFORM1DPROC) (GLint location, GLdouble x); typedef void (APIENTRYP PFNGLUNIFORM2DPROC) (GLint location, GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLUNIFORM3DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLUNIFORM4DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLUNIFORM1DVPROC) (GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP PFNGLUNIFORM2DVPROC) (GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP PFNGLUNIFORM3DVPROC) (GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP PFNGLUNIFORM4DVPROC) (GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLGETUNIFORMDVPROC) (GLuint program, GLint location, GLdouble *params); #endif #ifndef GL_ARB_shader_subroutine #define GL_ARB_shader_subroutine 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLint APIENTRY glGetSubroutineUniformLocation (GLuint program, GLenum shadertype, const GLchar *name); GLAPI GLuint APIENTRY glGetSubroutineIndex (GLuint program, GLenum shadertype, const GLchar *name); GLAPI void APIENTRY glGetActiveSubroutineUniformiv (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values); GLAPI void APIENTRY glGetActiveSubroutineUniformName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); GLAPI void APIENTRY glGetActiveSubroutineName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); GLAPI void APIENTRY glUniformSubroutinesuiv (GLenum shadertype, GLsizei count, const GLuint *indices); GLAPI void APIENTRY glGetUniformSubroutineuiv (GLenum shadertype, GLint location, GLuint *params); GLAPI void APIENTRY glGetProgramStageiv (GLuint program, GLenum shadertype, GLenum pname, GLint *values); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLint (APIENTRYP PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) (GLuint program, GLenum shadertype, const GLchar *name); typedef GLuint (APIENTRYP PFNGLGETSUBROUTINEINDEXPROC) (GLuint program, GLenum shadertype, const GLchar *name); typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values); typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); typedef void (APIENTRYP PFNGLUNIFORMSUBROUTINESUIVPROC) (GLenum shadertype, GLsizei count, const GLuint *indices); typedef void (APIENTRYP PFNGLGETUNIFORMSUBROUTINEUIVPROC) (GLenum shadertype, GLint location, GLuint *params); typedef void (APIENTRYP PFNGLGETPROGRAMSTAGEIVPROC) (GLuint program, GLenum shadertype, GLenum pname, GLint *values); #endif #ifndef GL_ARB_tessellation_shader #define GL_ARB_tessellation_shader 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPatchParameteri (GLenum pname, GLint value); GLAPI void APIENTRY glPatchParameterfv (GLenum pname, const GLfloat *values); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPATCHPARAMETERIPROC) (GLenum pname, GLint value); typedef void (APIENTRYP PFNGLPATCHPARAMETERFVPROC) (GLenum pname, const GLfloat *values); #endif #ifndef GL_ARB_texture_buffer_object_rgb32 #define GL_ARB_texture_buffer_object_rgb32 1 #endif #ifndef GL_ARB_transform_feedback2 #define GL_ARB_transform_feedback2 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBindTransformFeedback (GLenum target, GLuint id); GLAPI void APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint *ids); GLAPI void APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint *ids); GLAPI GLboolean APIENTRY glIsTransformFeedback (GLuint id); GLAPI void APIENTRY glPauseTransformFeedback (void); GLAPI void APIENTRY glResumeTransformFeedback (void); GLAPI void APIENTRY glDrawTransformFeedback (GLenum mode, GLuint id); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id); typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint *ids); typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids); typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id); typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKPROC) (void); typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKPROC) (void); typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKPROC) (GLenum mode, GLuint id); #endif #ifndef GL_ARB_transform_feedback3 #define GL_ARB_transform_feedback3 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawTransformFeedbackStream (GLenum mode, GLuint id, GLuint stream); GLAPI void APIENTRY glBeginQueryIndexed (GLenum target, GLuint index, GLuint id); GLAPI void APIENTRY glEndQueryIndexed (GLenum target, GLuint index); GLAPI void APIENTRY glGetQueryIndexediv (GLenum target, GLuint index, GLenum pname, GLint *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) (GLenum mode, GLuint id, GLuint stream); typedef void (APIENTRYP PFNGLBEGINQUERYINDEXEDPROC) (GLenum target, GLuint index, GLuint id); typedef void (APIENTRYP PFNGLENDQUERYINDEXEDPROC) (GLenum target, GLuint index); typedef void (APIENTRYP PFNGLGETQUERYINDEXEDIVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); #endif #ifndef GL_ARB_ES2_compatibility #define GL_ARB_ES2_compatibility 1 #if 0 //#ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glReleaseShaderCompiler (void); GLAPI void APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const GLvoid *binary, GLsizei length); GLAPI void APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); GLAPI void APIENTRY glDepthRangef (GLfloat n, GLfloat f); GLAPI void APIENTRY glClearDepthf (GLfloat d); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void); typedef void (APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const GLvoid *binary, GLsizei length); typedef void (APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); typedef void (APIENTRYP PFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f); typedef void (APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d); #endif #ifndef GL_ARB_get_program_binary #define GL_ARB_get_program_binary 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary); GLAPI void APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLsizei length); GLAPI void APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary); typedef void (APIENTRYP PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLsizei length); typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value); #endif #ifndef GL_ARB_separate_shader_objects #define GL_ARB_separate_shader_objects 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glUseProgramStages (GLuint pipeline, GLbitfield stages, GLuint program); GLAPI void APIENTRY glActiveShaderProgram (GLuint pipeline, GLuint program); GLAPI GLuint APIENTRY glCreateShaderProgramv (GLenum type, GLsizei count, const GLchar* const *strings); GLAPI void APIENTRY glBindProgramPipeline (GLuint pipeline); GLAPI void APIENTRY glDeleteProgramPipelines (GLsizei n, const GLuint *pipelines); GLAPI void APIENTRY glGenProgramPipelines (GLsizei n, GLuint *pipelines); GLAPI GLboolean APIENTRY glIsProgramPipeline (GLuint pipeline); GLAPI void APIENTRY glGetProgramPipelineiv (GLuint pipeline, GLenum pname, GLint *params); GLAPI void APIENTRY glProgramUniform1i (GLuint program, GLint location, GLint v0); GLAPI void APIENTRY glProgramUniform1iv (GLuint program, GLint location, GLsizei count, const GLint *value); GLAPI void APIENTRY glProgramUniform1f (GLuint program, GLint location, GLfloat v0); GLAPI void APIENTRY glProgramUniform1fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); GLAPI void APIENTRY glProgramUniform1d (GLuint program, GLint location, GLdouble v0); GLAPI void APIENTRY glProgramUniform1dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); GLAPI void APIENTRY glProgramUniform1ui (GLuint program, GLint location, GLuint v0); GLAPI void APIENTRY glProgramUniform1uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); GLAPI void APIENTRY glProgramUniform2i (GLuint program, GLint location, GLint v0, GLint v1); GLAPI void APIENTRY glProgramUniform2iv (GLuint program, GLint location, GLsizei count, const GLint *value); GLAPI void APIENTRY glProgramUniform2f (GLuint program, GLint location, GLfloat v0, GLfloat v1); GLAPI void APIENTRY glProgramUniform2fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); GLAPI void APIENTRY glProgramUniform2d (GLuint program, GLint location, GLdouble v0, GLdouble v1); GLAPI void APIENTRY glProgramUniform2dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); GLAPI void APIENTRY glProgramUniform2ui (GLuint program, GLint location, GLuint v0, GLuint v1); GLAPI void APIENTRY glProgramUniform2uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); GLAPI void APIENTRY glProgramUniform3i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); GLAPI void APIENTRY glProgramUniform3iv (GLuint program, GLint location, GLsizei count, const GLint *value); GLAPI void APIENTRY glProgramUniform3f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); GLAPI void APIENTRY glProgramUniform3fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); GLAPI void APIENTRY glProgramUniform3d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2); GLAPI void APIENTRY glProgramUniform3dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); GLAPI void APIENTRY glProgramUniform3ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); GLAPI void APIENTRY glProgramUniform3uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); GLAPI void APIENTRY glProgramUniform4i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); GLAPI void APIENTRY glProgramUniform4iv (GLuint program, GLint location, GLsizei count, const GLint *value); GLAPI void APIENTRY glProgramUniform4f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); GLAPI void APIENTRY glProgramUniform4fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); GLAPI void APIENTRY glProgramUniform4d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); GLAPI void APIENTRY glProgramUniform4dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); GLAPI void APIENTRY glProgramUniform4ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); GLAPI void APIENTRY glProgramUniform4uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); GLAPI void APIENTRY glProgramUniformMatrix2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniformMatrix3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniformMatrix4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniformMatrix2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glProgramUniformMatrix3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glProgramUniformMatrix4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glProgramUniformMatrix2x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniformMatrix3x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniformMatrix2x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniformMatrix4x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniformMatrix3x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniformMatrix4x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniformMatrix2x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glProgramUniformMatrix3x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glProgramUniformMatrix2x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glProgramUniformMatrix4x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glProgramUniformMatrix3x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glProgramUniformMatrix4x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glValidateProgramPipeline (GLuint pipeline); GLAPI void APIENTRY glGetProgramPipelineInfoLog (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program); typedef void (APIENTRYP PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program); typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar* const *strings); typedef void (APIENTRYP PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline); typedef void (APIENTRYP PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint *pipelines); typedef void (APIENTRYP PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines); typedef GLboolean (APIENTRYP PFNGLISPROGRAMPIPELINEPROC) (GLuint pipeline); typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEIVPROC) (GLuint pipeline, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint v0); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FPROC) (GLuint program, GLint location, GLfloat v0); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DPROC) (GLuint program, GLint location, GLdouble v0); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIPROC) (GLuint program, GLint location, GLuint v0); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IPROC) (GLuint program, GLint location, GLint v0, GLint v1); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEPROC) (GLuint pipeline); typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); #endif #ifndef GL_ARB_vertex_attrib_64bit #define GL_ARB_vertex_attrib_64bit 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexAttribL1d (GLuint index, GLdouble x); GLAPI void APIENTRY glVertexAttribL2d (GLuint index, GLdouble x, GLdouble y); GLAPI void APIENTRY glVertexAttribL3d (GLuint index, GLdouble x, GLdouble y, GLdouble z); GLAPI void APIENTRY glVertexAttribL4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); GLAPI void APIENTRY glVertexAttribL1dv (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttribL2dv (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttribL3dv (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttribL4dv (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttribLPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); GLAPI void APIENTRY glGetVertexAttribLdv (GLuint index, GLenum pname, GLdouble *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DPROC) (GLuint index, GLdouble x); typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DPROC) (GLuint index, GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLDVPROC) (GLuint index, GLenum pname, GLdouble *params); #endif #ifndef GL_ARB_viewport_array #define GL_ARB_viewport_array 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glViewportArrayv (GLuint first, GLsizei count, const GLfloat *v); GLAPI void APIENTRY glViewportIndexedf (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); GLAPI void APIENTRY glViewportIndexedfv (GLuint index, const GLfloat *v); GLAPI void APIENTRY glScissorArrayv (GLuint first, GLsizei count, const GLint *v); GLAPI void APIENTRY glScissorIndexed (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); GLAPI void APIENTRY glScissorIndexedv (GLuint index, const GLint *v); GLAPI void APIENTRY glDepthRangeArrayv (GLuint first, GLsizei count, const GLdouble *v); GLAPI void APIENTRY glDepthRangeIndexed (GLuint index, GLdouble n, GLdouble f); GLAPI void APIENTRY glGetFloati_v (GLenum target, GLuint index, GLfloat *data); GLAPI void APIENTRY glGetDoublei_v (GLenum target, GLuint index, GLdouble *data); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVIEWPORTARRAYVPROC) (GLuint first, GLsizei count, const GLfloat *v); typedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); typedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLSCISSORARRAYVPROC) (GLuint first, GLsizei count, const GLint *v); typedef void (APIENTRYP PFNGLSCISSORINDEXEDPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLSCISSORINDEXEDVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLDEPTHRANGEARRAYVPROC) (GLuint first, GLsizei count, const GLdouble *v); typedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDPROC) (GLuint index, GLdouble n, GLdouble f); typedef void (APIENTRYP PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat *data); typedef void (APIENTRYP PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble *data); #endif #ifndef GL_ARB_cl_event #define GL_ARB_cl_event 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLsync APIENTRY glCreateSyncFromCLeventARB (struct _cl_context * context, struct _cl_event * event, GLbitfield flags); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLsync (APIENTRYP PFNGLCREATESYNCFROMCLEVENTARBPROC) (struct _cl_context * context, struct _cl_event * event, GLbitfield flags); #endif #ifndef GL_ARB_debug_output #define GL_ARB_debug_output 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDebugMessageControlARB (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); GLAPI void APIENTRY glDebugMessageInsertARB (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); GLAPI void APIENTRY glDebugMessageCallbackARB (GLDEBUGPROCARB callback, const GLvoid *userParam); GLAPI GLuint APIENTRY glGetDebugMessageLogARB (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLARBPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTARBPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKARBPROC) (GLDEBUGPROCARB callback, const GLvoid *userParam); typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGARBPROC) (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); #endif #ifndef GL_ARB_robustness #define GL_ARB_robustness 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLenum APIENTRY glGetGraphicsResetStatusARB (void); GLAPI void APIENTRY glGetnMapdvARB (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); GLAPI void APIENTRY glGetnMapfvARB (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); GLAPI void APIENTRY glGetnMapivARB (GLenum target, GLenum query, GLsizei bufSize, GLint *v); GLAPI void APIENTRY glGetnPixelMapfvARB (GLenum map, GLsizei bufSize, GLfloat *values); GLAPI void APIENTRY glGetnPixelMapuivARB (GLenum map, GLsizei bufSize, GLuint *values); GLAPI void APIENTRY glGetnPixelMapusvARB (GLenum map, GLsizei bufSize, GLushort *values); GLAPI void APIENTRY glGetnPolygonStippleARB (GLsizei bufSize, GLubyte *pattern); GLAPI void APIENTRY glGetnColorTableARB (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *table); GLAPI void APIENTRY glGetnConvolutionFilterARB (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *image); GLAPI void APIENTRY glGetnSeparableFilterARB (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, GLvoid *row, GLsizei columnBufSize, GLvoid *column, GLvoid *span); GLAPI void APIENTRY glGetnHistogramARB (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values); GLAPI void APIENTRY glGetnMinmaxARB (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values); GLAPI void APIENTRY glGetnTexImageARB (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, GLvoid *img); GLAPI void APIENTRY glReadnPixelsARB (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data); GLAPI void APIENTRY glGetnCompressedTexImageARB (GLenum target, GLint lod, GLsizei bufSize, GLvoid *img); GLAPI void APIENTRY glGetnUniformfvARB (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); GLAPI void APIENTRY glGetnUniformivARB (GLuint program, GLint location, GLsizei bufSize, GLint *params); GLAPI void APIENTRY glGetnUniformuivARB (GLuint program, GLint location, GLsizei bufSize, GLuint *params); GLAPI void APIENTRY glGetnUniformdvARB (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLenum (APIENTRYP PFNGLGETGRAPHICSRESETSTATUSARBPROC) (void); typedef void (APIENTRYP PFNGLGETNMAPDVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); typedef void (APIENTRYP PFNGLGETNMAPFVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); typedef void (APIENTRYP PFNGLGETNMAPIVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLint *v); typedef void (APIENTRYP PFNGLGETNPIXELMAPFVARBPROC) (GLenum map, GLsizei bufSize, GLfloat *values); typedef void (APIENTRYP PFNGLGETNPIXELMAPUIVARBPROC) (GLenum map, GLsizei bufSize, GLuint *values); typedef void (APIENTRYP PFNGLGETNPIXELMAPUSVARBPROC) (GLenum map, GLsizei bufSize, GLushort *values); typedef void (APIENTRYP PFNGLGETNPOLYGONSTIPPLEARBPROC) (GLsizei bufSize, GLubyte *pattern); typedef void (APIENTRYP PFNGLGETNCOLORTABLEARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *table); typedef void (APIENTRYP PFNGLGETNCONVOLUTIONFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *image); typedef void (APIENTRYP PFNGLGETNSEPARABLEFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, GLvoid *row, GLsizei columnBufSize, GLvoid *column, GLvoid *span); typedef void (APIENTRYP PFNGLGETNHISTOGRAMARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values); typedef void (APIENTRYP PFNGLGETNMINMAXARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values); typedef void (APIENTRYP PFNGLGETNTEXIMAGEARBPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, GLvoid *img); typedef void (APIENTRYP PFNGLREADNPIXELSARBPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data); typedef void (APIENTRYP PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, GLsizei bufSize, GLvoid *img); typedef void (APIENTRYP PFNGLGETNUNIFORMFVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); typedef void (APIENTRYP PFNGLGETNUNIFORMIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); typedef void (APIENTRYP PFNGLGETNUNIFORMUIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params); typedef void (APIENTRYP PFNGLGETNUNIFORMDVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); #endif #ifndef GL_ARB_shader_stencil_export #define GL_ARB_shader_stencil_export 1 #endif #ifndef GL_ARB_base_instance #define GL_ARB_base_instance 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawArraysInstancedBaseInstance (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); GLAPI void APIENTRY glDrawElementsInstancedBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); GLAPI void APIENTRY glDrawElementsInstancedBaseVertexBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); #endif #ifndef GL_ARB_shading_language_420pack #define GL_ARB_shading_language_420pack 1 #endif #ifndef GL_ARB_transform_feedback_instanced #define GL_ARB_transform_feedback_instanced 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawTransformFeedbackInstanced (GLenum mode, GLuint id, GLsizei instancecount); GLAPI void APIENTRY glDrawTransformFeedbackStreamInstanced (GLenum mode, GLuint id, GLuint stream, GLsizei instancecount); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) (GLenum mode, GLuint id, GLsizei instancecount); typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) (GLenum mode, GLuint id, GLuint stream, GLsizei instancecount); #endif #ifndef GL_ARB_compressed_texture_pixel_storage #define GL_ARB_compressed_texture_pixel_storage 1 #endif #ifndef GL_ARB_conservative_depth #define GL_ARB_conservative_depth 1 #endif #ifndef GL_ARB_internalformat_query #define GL_ARB_internalformat_query 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); #endif #ifndef GL_ARB_map_buffer_alignment #define GL_ARB_map_buffer_alignment 1 #endif #ifndef GL_ARB_shader_atomic_counters #define GL_ARB_shader_atomic_counters 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetActiveAtomicCounterBufferiv (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params); #endif #ifndef GL_ARB_shader_image_load_store #define GL_ARB_shader_image_load_store 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBindImageTexture (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); GLAPI void APIENTRY glMemoryBarrier (GLbitfield barriers); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); typedef void (APIENTRYP PFNGLMEMORYBARRIERPROC) (GLbitfield barriers); #endif #ifndef GL_ARB_shading_language_packing #define GL_ARB_shading_language_packing 1 #endif #ifndef GL_ARB_texture_storage #define GL_ARB_texture_storage 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTexStorage1D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); GLAPI void APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); GLAPI void APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); GLAPI void APIENTRY glTextureStorage1DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); GLAPI void APIENTRY glTextureStorage2DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); GLAPI void APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXSTORAGE1DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); typedef void (APIENTRYP PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); typedef void (APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); #endif #ifndef GL_KHR_texture_compression_astc_ldr #define GL_KHR_texture_compression_astc_ldr 1 #endif #ifndef GL_KHR_debug #define GL_KHR_debug 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDebugMessageControl (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); GLAPI void APIENTRY glDebugMessageInsert (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); GLAPI void APIENTRY glDebugMessageCallback (GLDEBUGPROC callback, const void *userParam); GLAPI GLuint APIENTRY glGetDebugMessageLog (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); GLAPI void APIENTRY glPushDebugGroup (GLenum source, GLuint id, GLsizei length, const GLchar *message); GLAPI void APIENTRY glPopDebugGroup (void); GLAPI void APIENTRY glObjectLabel (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); GLAPI void APIENTRY glGetObjectLabel (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); GLAPI void APIENTRY glObjectPtrLabel (const void *ptr, GLsizei length, const GLchar *label); GLAPI void APIENTRY glGetObjectPtrLabel (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam); typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); typedef void (APIENTRYP PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message); typedef void (APIENTRYP PFNGLPOPDEBUGGROUPPROC) (void); typedef void (APIENTRYP PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); typedef void (APIENTRYP PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); typedef void (APIENTRYP PFNGLOBJECTPTRLABELPROC) (const void *ptr, GLsizei length, const GLchar *label); typedef void (APIENTRYP PFNGLGETOBJECTPTRLABELPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); #endif #ifndef GL_ARB_arrays_of_arrays #define GL_ARB_arrays_of_arrays 1 #endif #ifndef GL_ARB_clear_buffer_object #define GL_ARB_clear_buffer_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glClearBufferData (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data); GLAPI void APIENTRY glClearBufferSubData (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); GLAPI void APIENTRY glClearNamedBufferDataEXT (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); GLAPI void APIENTRY glClearNamedBufferSubDataEXT (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, GLsizeiptr offset, GLsizeiptr size, const void *data); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCLEARBUFFERDATAPROC) (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data); typedef void (APIENTRYP PFNGLCLEARBUFFERSUBDATAPROC) (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, GLsizeiptr offset, GLsizeiptr size, const void *data); #endif #ifndef GL_ARB_compute_shader #define GL_ARB_compute_shader 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDispatchCompute (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); GLAPI void APIENTRY glDispatchComputeIndirect (GLintptr indirect); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect); #endif #ifndef GL_ARB_copy_image #define GL_ARB_copy_image 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glCopyImageSubData (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOPYIMAGESUBDATAPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); #endif #ifndef GL_ARB_texture_view #define GL_ARB_texture_view 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTextureView (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXTUREVIEWPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); #endif #ifndef GL_ARB_vertex_attrib_binding #define GL_ARB_vertex_attrib_binding 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBindVertexBuffer (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); GLAPI void APIENTRY glVertexAttribFormat (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); GLAPI void APIENTRY glVertexAttribIFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); GLAPI void APIENTRY glVertexAttribLFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); GLAPI void APIENTRY glVertexAttribBinding (GLuint attribindex, GLuint bindingindex); GLAPI void APIENTRY glVertexBindingDivisor (GLuint bindingindex, GLuint divisor); GLAPI void APIENTRY glVertexArrayBindVertexBufferEXT (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); GLAPI void APIENTRY glVertexArrayVertexAttribFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); GLAPI void APIENTRY glVertexArrayVertexAttribIFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); GLAPI void APIENTRY glVertexArrayVertexAttribLFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); GLAPI void APIENTRY glVertexArrayVertexAttribBindingEXT (GLuint vaobj, GLuint attribindex, GLuint bindingindex); GLAPI void APIENTRY glVertexArrayVertexBindingDivisorEXT (GLuint vaobj, GLuint bindingindex, GLuint divisor); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBINDVERTEXBUFFERPROC) (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); typedef void (APIENTRYP PFNGLVERTEXATTRIBFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); typedef void (APIENTRYP PFNGLVERTEXATTRIBIFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); typedef void (APIENTRYP PFNGLVERTEXATTRIBLFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); typedef void (APIENTRYP PFNGLVERTEXATTRIBBINDINGPROC) (GLuint attribindex, GLuint bindingindex); typedef void (APIENTRYP PFNGLVERTEXBINDINGDIVISORPROC) (GLuint bindingindex, GLuint divisor); typedef void (APIENTRYP PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex); typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor); #endif #ifndef GL_ARB_robustness_isolation #define GL_ARB_robustness_isolation 1 #endif #ifndef GL_ARB_ES3_compatibility #define GL_ARB_ES3_compatibility 1 #endif #ifndef GL_ARB_explicit_uniform_location #define GL_ARB_explicit_uniform_location 1 #endif #ifndef GL_ARB_fragment_layer_viewport #define GL_ARB_fragment_layer_viewport 1 #endif #ifndef GL_ARB_framebuffer_no_attachments #define GL_ARB_framebuffer_no_attachments 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFramebufferParameteri (GLenum target, GLenum pname, GLint param); GLAPI void APIENTRY glGetFramebufferParameteriv (GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glNamedFramebufferParameteriEXT (GLuint framebuffer, GLenum pname, GLint param); GLAPI void APIENTRY glGetNamedFramebufferParameterivEXT (GLuint framebuffer, GLenum pname, GLint *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLFRAMEBUFFERPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC) (GLuint framebuffer, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint *params); #endif #ifndef GL_ARB_internalformat_query2 #define GL_ARB_internalformat_query2 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetInternalformati64v (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGETINTERNALFORMATI64VPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params); #endif #ifndef GL_ARB_invalidate_subdata #define GL_ARB_invalidate_subdata 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glInvalidateTexSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); GLAPI void APIENTRY glInvalidateTexImage (GLuint texture, GLint level); GLAPI void APIENTRY glInvalidateBufferSubData (GLuint buffer, GLintptr offset, GLsizeiptr length); GLAPI void APIENTRY glInvalidateBufferData (GLuint buffer); GLAPI void APIENTRY glInvalidateFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments); GLAPI void APIENTRY glInvalidateSubFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLINVALIDATETEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); typedef void (APIENTRYP PFNGLINVALIDATETEXIMAGEPROC) (GLuint texture, GLint level); typedef void (APIENTRYP PFNGLINVALIDATEBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); typedef void (APIENTRYP PFNGLINVALIDATEBUFFERDATAPROC) (GLuint buffer); typedef void (APIENTRYP PFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments); typedef void (APIENTRYP PFNGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); #endif #ifndef GL_ARB_multi_draw_indirect #define GL_ARB_multi_draw_indirect 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glMultiDrawArraysIndirect (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride); GLAPI void APIENTRY glMultiDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride); typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride); #endif #ifndef GL_ARB_program_interface_query #define GL_ARB_program_interface_query 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetProgramInterfaceiv (GLuint program, GLenum programInterface, GLenum pname, GLint *params); GLAPI GLuint APIENTRY glGetProgramResourceIndex (GLuint program, GLenum programInterface, const GLchar *name); GLAPI void APIENTRY glGetProgramResourceName (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); GLAPI void APIENTRY glGetProgramResourceiv (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); GLAPI GLint APIENTRY glGetProgramResourceLocation (GLuint program, GLenum programInterface, const GLchar *name); GLAPI GLint APIENTRY glGetProgramResourceLocationIndex (GLuint program, GLenum programInterface, const GLchar *name); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint *params); typedef GLuint (APIENTRYP PFNGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name); typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar *name); typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name); #endif #ifndef GL_ARB_robust_buffer_access_behavior #define GL_ARB_robust_buffer_access_behavior 1 #endif #ifndef GL_ARB_shader_image_size #define GL_ARB_shader_image_size 1 #endif #ifndef GL_ARB_shader_storage_buffer_object #define GL_ARB_shader_storage_buffer_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glShaderStorageBlockBinding (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSHADERSTORAGEBLOCKBINDINGPROC) (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); #endif #ifndef GL_ARB_stencil_texturing #define GL_ARB_stencil_texturing 1 #endif #ifndef GL_ARB_texture_buffer_range #define GL_ARB_texture_buffer_range 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTexBufferRange (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); GLAPI void APIENTRY glTextureBufferRangeEXT (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXBUFFERRANGEPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); typedef void (APIENTRYP PFNGLTEXTUREBUFFERRANGEEXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); #endif #ifndef GL_ARB_texture_query_levels #define GL_ARB_texture_query_levels 1 #endif #ifndef GL_ARB_texture_storage_multisample #define GL_ARB_texture_storage_multisample 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTexStorage2DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); GLAPI void APIENTRY glTexStorage3DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); GLAPI void APIENTRY glTextureStorage2DMultisampleEXT (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); GLAPI void APIENTRY glTextureStorage3DMultisampleEXT (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXSTORAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); typedef void (APIENTRYP PFNGLTEXSTORAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); #endif #ifndef GL_EXT_abgr #define GL_EXT_abgr 1 #endif #ifndef GL_EXT_blend_color #define GL_EXT_blend_color 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendColorEXT (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDCOLOREXTPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); #endif #ifndef GL_EXT_polygon_offset #define GL_EXT_polygon_offset 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPolygonOffsetEXT (GLfloat factor, GLfloat bias); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); #endif #ifndef GL_EXT_texture #define GL_EXT_texture 1 #endif #ifndef GL_EXT_texture3D #define GL_EXT_texture3D 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTexImage3DEXT (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); GLAPI void APIENTRY glTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); #endif #ifndef GL_SGIS_texture_filter4 #define GL_SGIS_texture_filter4 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetTexFilterFuncSGIS (GLenum target, GLenum filter, GLfloat *weights); GLAPI void APIENTRY glTexFilterFuncSGIS (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat *weights); typedef void (APIENTRYP PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); #endif #ifndef GL_EXT_subtexture #define GL_EXT_subtexture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); GLAPI void APIENTRY glTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); #endif #ifndef GL_EXT_copy_texture #define GL_EXT_copy_texture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glCopyTexImage1DEXT (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); GLAPI void APIENTRY glCopyTexImage2DEXT (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); GLAPI void APIENTRY glCopyTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); GLAPI void APIENTRY glCopyTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); GLAPI void APIENTRY glCopyTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); #endif #ifndef GL_EXT_histogram #define GL_EXT_histogram 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetHistogramEXT (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); GLAPI void APIENTRY glGetHistogramParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetHistogramParameterivEXT (GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glGetMinmaxEXT (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); GLAPI void APIENTRY glGetMinmaxParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetMinmaxParameterivEXT (GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glHistogramEXT (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); GLAPI void APIENTRY glMinmaxEXT (GLenum target, GLenum internalformat, GLboolean sink); GLAPI void APIENTRY glResetHistogramEXT (GLenum target); GLAPI void APIENTRY glResetMinmaxEXT (GLenum target); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); typedef void (APIENTRYP PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); typedef void (APIENTRYP PFNGLRESETHISTOGRAMEXTPROC) (GLenum target); typedef void (APIENTRYP PFNGLRESETMINMAXEXTPROC) (GLenum target); #endif #ifndef GL_EXT_convolution #define GL_EXT_convolution 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glConvolutionFilter1DEXT (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); GLAPI void APIENTRY glConvolutionFilter2DEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); GLAPI void APIENTRY glConvolutionParameterfEXT (GLenum target, GLenum pname, GLfloat params); GLAPI void APIENTRY glConvolutionParameterfvEXT (GLenum target, GLenum pname, const GLfloat *params); GLAPI void APIENTRY glConvolutionParameteriEXT (GLenum target, GLenum pname, GLint params); GLAPI void APIENTRY glConvolutionParameterivEXT (GLenum target, GLenum pname, const GLint *params); GLAPI void APIENTRY glCopyConvolutionFilter1DEXT (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); GLAPI void APIENTRY glCopyConvolutionFilter2DEXT (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); GLAPI void APIENTRY glGetConvolutionFilterEXT (GLenum target, GLenum format, GLenum type, GLvoid *image); GLAPI void APIENTRY glGetConvolutionParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetConvolutionParameterivEXT (GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glGetSeparableFilterEXT (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); GLAPI void APIENTRY glSeparableFilter2DEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat params); typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint params); typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); #endif #ifndef GL_SGI_color_matrix #define GL_SGI_color_matrix 1 #endif #ifndef GL_SGI_color_table #define GL_SGI_color_table 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glColorTableSGI (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); GLAPI void APIENTRY glColorTableParameterfvSGI (GLenum target, GLenum pname, const GLfloat *params); GLAPI void APIENTRY glColorTableParameterivSGI (GLenum target, GLenum pname, const GLint *params); GLAPI void APIENTRY glCopyColorTableSGI (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); GLAPI void APIENTRY glGetColorTableSGI (GLenum target, GLenum format, GLenum type, GLvoid *table); GLAPI void APIENTRY glGetColorTableParameterfvSGI (GLenum target, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetColorTableParameterivSGI (GLenum target, GLenum pname, GLint *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint *params); #endif #ifndef GL_SGIX_pixel_texture #define GL_SGIX_pixel_texture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPixelTexGenSGIX (GLenum mode); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPIXELTEXGENSGIXPROC) (GLenum mode); #endif #ifndef GL_SGIS_pixel_texture #define GL_SGIS_pixel_texture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPixelTexGenParameteriSGIS (GLenum pname, GLint param); GLAPI void APIENTRY glPixelTexGenParameterivSGIS (GLenum pname, const GLint *params); GLAPI void APIENTRY glPixelTexGenParameterfSGIS (GLenum pname, GLfloat param); GLAPI void APIENTRY glPixelTexGenParameterfvSGIS (GLenum pname, const GLfloat *params); GLAPI void APIENTRY glGetPixelTexGenParameterivSGIS (GLenum pname, GLint *params); GLAPI void APIENTRY glGetPixelTexGenParameterfvSGIS (GLenum pname, GLfloat *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERISGISPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFSGISPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, GLfloat *params); #endif #ifndef GL_SGIS_texture4D #define GL_SGIS_texture4D 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTexImage4DSGIS (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels); GLAPI void APIENTRY glTexSubImage4DSGIS (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels); #endif #ifndef GL_SGI_texture_color_table #define GL_SGI_texture_color_table 1 #endif #ifndef GL_EXT_cmyka #define GL_EXT_cmyka 1 #endif #ifndef GL_EXT_texture_object #define GL_EXT_texture_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLboolean APIENTRY glAreTexturesResidentEXT (GLsizei n, const GLuint *textures, GLboolean *residences); GLAPI void APIENTRY glBindTextureEXT (GLenum target, GLuint texture); GLAPI void APIENTRY glDeleteTexturesEXT (GLsizei n, const GLuint *textures); GLAPI void APIENTRY glGenTexturesEXT (GLsizei n, GLuint *textures); GLAPI GLboolean APIENTRY glIsTextureEXT (GLuint texture); GLAPI void APIENTRY glPrioritizeTexturesEXT (GLsizei n, const GLuint *textures, const GLclampf *priorities); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLboolean (APIENTRYP PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint *textures, GLboolean *residences); typedef void (APIENTRYP PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); typedef void (APIENTRYP PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint *textures); typedef void (APIENTRYP PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint *textures); typedef GLboolean (APIENTRYP PFNGLISTEXTUREEXTPROC) (GLuint texture); typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint *textures, const GLclampf *priorities); #endif #ifndef GL_SGIS_detail_texture #define GL_SGIS_detail_texture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDetailTexFuncSGIS (GLenum target, GLsizei n, const GLfloat *points); GLAPI void APIENTRY glGetDetailTexFuncSGIS (GLenum target, GLfloat *points); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); typedef void (APIENTRYP PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat *points); #endif #ifndef GL_SGIS_sharpen_texture #define GL_SGIS_sharpen_texture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glSharpenTexFuncSGIS (GLenum target, GLsizei n, const GLfloat *points); GLAPI void APIENTRY glGetSharpenTexFuncSGIS (GLenum target, GLfloat *points); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); typedef void (APIENTRYP PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat *points); #endif #ifndef GL_EXT_packed_pixels #define GL_EXT_packed_pixels 1 #endif #ifndef GL_SGIS_texture_lod #define GL_SGIS_texture_lod 1 #endif #ifndef GL_SGIS_multisample #define GL_SGIS_multisample 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glSampleMaskSGIS (GLclampf value, GLboolean invert); GLAPI void APIENTRY glSamplePatternSGIS (GLenum pattern); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); typedef void (APIENTRYP PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); #endif #ifndef GL_EXT_rescale_normal #define GL_EXT_rescale_normal 1 #endif #ifndef GL_EXT_vertex_array #define GL_EXT_vertex_array 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glArrayElementEXT (GLint i); GLAPI void APIENTRY glColorPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); GLAPI void APIENTRY glDrawArraysEXT (GLenum mode, GLint first, GLsizei count); GLAPI void APIENTRY glEdgeFlagPointerEXT (GLsizei stride, GLsizei count, const GLboolean *pointer); GLAPI void APIENTRY glGetPointervEXT (GLenum pname, GLvoid* *params); GLAPI void APIENTRY glIndexPointerEXT (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); GLAPI void APIENTRY glNormalPointerEXT (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); GLAPI void APIENTRY glTexCoordPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); GLAPI void APIENTRY glVertexPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLARRAYELEMENTEXTPROC) (GLint i); typedef void (APIENTRYP PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); typedef void (APIENTRYP PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); typedef void (APIENTRYP PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean *pointer); typedef void (APIENTRYP PFNGLGETPOINTERVEXTPROC) (GLenum pname, GLvoid* *params); typedef void (APIENTRYP PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); typedef void (APIENTRYP PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); typedef void (APIENTRYP PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); typedef void (APIENTRYP PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); #endif #ifndef GL_EXT_misc_attribute #define GL_EXT_misc_attribute 1 #endif #ifndef GL_SGIS_generate_mipmap #define GL_SGIS_generate_mipmap 1 #endif #ifndef GL_SGIX_clipmap #define GL_SGIX_clipmap 1 #endif #ifndef GL_SGIX_shadow #define GL_SGIX_shadow 1 #endif #ifndef GL_SGIS_texture_edge_clamp #define GL_SGIS_texture_edge_clamp 1 #endif #ifndef GL_SGIS_texture_border_clamp #define GL_SGIS_texture_border_clamp 1 #endif #ifndef GL_EXT_blend_minmax #define GL_EXT_blend_minmax 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendEquationEXT (GLenum mode); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); #endif #ifndef GL_EXT_blend_subtract #define GL_EXT_blend_subtract 1 #endif #ifndef GL_EXT_blend_logic_op #define GL_EXT_blend_logic_op 1 #endif #ifndef GL_SGIX_interlace #define GL_SGIX_interlace 1 #endif #ifndef GL_SGIX_pixel_tiles #define GL_SGIX_pixel_tiles 1 #endif #ifndef GL_SGIX_texture_select #define GL_SGIX_texture_select 1 #endif #ifndef GL_SGIX_sprite #define GL_SGIX_sprite 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glSpriteParameterfSGIX (GLenum pname, GLfloat param); GLAPI void APIENTRY glSpriteParameterfvSGIX (GLenum pname, const GLfloat *params); GLAPI void APIENTRY glSpriteParameteriSGIX (GLenum pname, GLint param); GLAPI void APIENTRY glSpriteParameterivSGIX (GLenum pname, const GLint *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, const GLint *params); #endif #ifndef GL_SGIX_texture_multi_buffer #define GL_SGIX_texture_multi_buffer 1 #endif #ifndef GL_EXT_point_parameters #define GL_EXT_point_parameters 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPointParameterfEXT (GLenum pname, GLfloat param); GLAPI void APIENTRY glPointParameterfvEXT (GLenum pname, const GLfloat *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params); #endif #ifndef GL_SGIS_point_parameters #define GL_SGIS_point_parameters 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPointParameterfSGIS (GLenum pname, GLfloat param); GLAPI void APIENTRY glPointParameterfvSGIS (GLenum pname, const GLfloat *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPOINTPARAMETERFSGISPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLPOINTPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); #endif #ifndef GL_SGIX_instruments #define GL_SGIX_instruments 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLint APIENTRY glGetInstrumentsSGIX (void); GLAPI void APIENTRY glInstrumentsBufferSGIX (GLsizei size, GLint *buffer); GLAPI GLint APIENTRY glPollInstrumentsSGIX (GLint *marker_p); GLAPI void APIENTRY glReadInstrumentsSGIX (GLint marker); GLAPI void APIENTRY glStartInstrumentsSGIX (void); GLAPI void APIENTRY glStopInstrumentsSGIX (GLint marker); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLint (APIENTRYP PFNGLGETINSTRUMENTSSGIXPROC) (void); typedef void (APIENTRYP PFNGLINSTRUMENTSBUFFERSGIXPROC) (GLsizei size, GLint *buffer); typedef GLint (APIENTRYP PFNGLPOLLINSTRUMENTSSGIXPROC) (GLint *marker_p); typedef void (APIENTRYP PFNGLREADINSTRUMENTSSGIXPROC) (GLint marker); typedef void (APIENTRYP PFNGLSTARTINSTRUMENTSSGIXPROC) (void); typedef void (APIENTRYP PFNGLSTOPINSTRUMENTSSGIXPROC) (GLint marker); #endif #ifndef GL_SGIX_texture_scale_bias #define GL_SGIX_texture_scale_bias 1 #endif #ifndef GL_SGIX_framezoom #define GL_SGIX_framezoom 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFrameZoomSGIX (GLint factor); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLFRAMEZOOMSGIXPROC) (GLint factor); #endif #ifndef GL_SGIX_tag_sample_buffer #define GL_SGIX_tag_sample_buffer 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTagSampleBufferSGIX (void); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTAGSAMPLEBUFFERSGIXPROC) (void); #endif #ifndef GL_SGIX_polynomial_ffd #define GL_SGIX_polynomial_ffd 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDeformationMap3dSGIX (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points); GLAPI void APIENTRY glDeformationMap3fSGIX (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points); GLAPI void APIENTRY glDeformSGIX (GLbitfield mask); GLAPI void APIENTRY glLoadIdentityDeformationMapSGIX (GLbitfield mask); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDEFORMATIONMAP3DSGIXPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points); typedef void (APIENTRYP PFNGLDEFORMATIONMAP3FSGIXPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points); typedef void (APIENTRYP PFNGLDEFORMSGIXPROC) (GLbitfield mask); typedef void (APIENTRYP PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask); #endif #ifndef GL_SGIX_reference_plane #define GL_SGIX_reference_plane 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glReferencePlaneSGIX (const GLdouble *equation); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLREFERENCEPLANESGIXPROC) (const GLdouble *equation); #endif #ifndef GL_SGIX_flush_raster #define GL_SGIX_flush_raster 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFlushRasterSGIX (void); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLFLUSHRASTERSGIXPROC) (void); #endif #ifndef GL_SGIX_depth_texture #define GL_SGIX_depth_texture 1 #endif #ifndef GL_SGIS_fog_function #define GL_SGIS_fog_function 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFogFuncSGIS (GLsizei n, const GLfloat *points); GLAPI void APIENTRY glGetFogFuncSGIS (GLfloat *points); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat *points); typedef void (APIENTRYP PFNGLGETFOGFUNCSGISPROC) (GLfloat *points); #endif #ifndef GL_SGIX_fog_offset #define GL_SGIX_fog_offset 1 #endif #ifndef GL_HP_image_transform #define GL_HP_image_transform 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glImageTransformParameteriHP (GLenum target, GLenum pname, GLint param); GLAPI void APIENTRY glImageTransformParameterfHP (GLenum target, GLenum pname, GLfloat param); GLAPI void APIENTRY glImageTransformParameterivHP (GLenum target, GLenum pname, const GLint *params); GLAPI void APIENTRY glImageTransformParameterfvHP (GLenum target, GLenum pname, const GLfloat *params); GLAPI void APIENTRY glGetImageTransformParameterivHP (GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glGetImageTransformParameterfvHP (GLenum target, GLenum pname, GLfloat *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat *params); #endif #ifndef GL_HP_convolution_border_modes #define GL_HP_convolution_border_modes 1 #endif #ifndef GL_SGIX_texture_add_env #define GL_SGIX_texture_add_env 1 #endif #ifndef GL_EXT_color_subtable #define GL_EXT_color_subtable 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glColorSubTableEXT (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); GLAPI void APIENTRY glCopyColorSubTableEXT (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); #endif #ifndef GL_PGI_vertex_hints #define GL_PGI_vertex_hints 1 #endif #ifndef GL_PGI_misc_hints #define GL_PGI_misc_hints 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glHintPGI (GLenum target, GLint mode); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLHINTPGIPROC) (GLenum target, GLint mode); #endif #ifndef GL_EXT_paletted_texture #define GL_EXT_paletted_texture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glColorTableEXT (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); GLAPI void APIENTRY glGetColorTableEXT (GLenum target, GLenum format, GLenum type, GLvoid *data); GLAPI void APIENTRY glGetColorTableParameterivEXT (GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glGetColorTableParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); typedef void (APIENTRYP PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *data); typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); #endif #ifndef GL_EXT_clip_volume_hint #define GL_EXT_clip_volume_hint 1 #endif #ifndef GL_SGIX_list_priority #define GL_SGIX_list_priority 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetListParameterfvSGIX (GLuint list, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetListParameterivSGIX (GLuint list, GLenum pname, GLint *params); GLAPI void APIENTRY glListParameterfSGIX (GLuint list, GLenum pname, GLfloat param); GLAPI void APIENTRY glListParameterfvSGIX (GLuint list, GLenum pname, const GLfloat *params); GLAPI void APIENTRY glListParameteriSGIX (GLuint list, GLenum pname, GLint param); GLAPI void APIENTRY glListParameterivSGIX (GLuint list, GLenum pname, const GLint *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGETLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLLISTPARAMETERFSGIXPROC) (GLuint list, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLLISTPARAMETERISGIXPROC) (GLuint list, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, const GLint *params); #endif #ifndef GL_SGIX_ir_instrument1 #define GL_SGIX_ir_instrument1 1 #endif #ifndef GL_SGIX_calligraphic_fragment #define GL_SGIX_calligraphic_fragment 1 #endif #ifndef GL_SGIX_texture_lod_bias #define GL_SGIX_texture_lod_bias 1 #endif #ifndef GL_SGIX_shadow_ambient #define GL_SGIX_shadow_ambient 1 #endif #ifndef GL_EXT_index_texture #define GL_EXT_index_texture 1 #endif #ifndef GL_EXT_index_material #define GL_EXT_index_material 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glIndexMaterialEXT (GLenum face, GLenum mode); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); #endif #ifndef GL_EXT_index_func #define GL_EXT_index_func 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glIndexFuncEXT (GLenum func, GLclampf ref); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLINDEXFUNCEXTPROC) (GLenum func, GLclampf ref); #endif #ifndef GL_EXT_index_array_formats #define GL_EXT_index_array_formats 1 #endif #ifndef GL_EXT_compiled_vertex_array #define GL_EXT_compiled_vertex_array 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glLockArraysEXT (GLint first, GLsizei count); GLAPI void APIENTRY glUnlockArraysEXT (void); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); typedef void (APIENTRYP PFNGLUNLOCKARRAYSEXTPROC) (void); #endif #ifndef GL_EXT_cull_vertex #define GL_EXT_cull_vertex 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glCullParameterdvEXT (GLenum pname, GLdouble *params); GLAPI void APIENTRY glCullParameterfvEXT (GLenum pname, GLfloat *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble *params); typedef void (APIENTRYP PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat *params); #endif #ifndef GL_SGIX_ycrcb #define GL_SGIX_ycrcb 1 #endif #ifndef GL_SGIX_fragment_lighting #define GL_SGIX_fragment_lighting 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFragmentColorMaterialSGIX (GLenum face, GLenum mode); GLAPI void APIENTRY glFragmentLightfSGIX (GLenum light, GLenum pname, GLfloat param); GLAPI void APIENTRY glFragmentLightfvSGIX (GLenum light, GLenum pname, const GLfloat *params); GLAPI void APIENTRY glFragmentLightiSGIX (GLenum light, GLenum pname, GLint param); GLAPI void APIENTRY glFragmentLightivSGIX (GLenum light, GLenum pname, const GLint *params); GLAPI void APIENTRY glFragmentLightModelfSGIX (GLenum pname, GLfloat param); GLAPI void APIENTRY glFragmentLightModelfvSGIX (GLenum pname, const GLfloat *params); GLAPI void APIENTRY glFragmentLightModeliSGIX (GLenum pname, GLint param); GLAPI void APIENTRY glFragmentLightModelivSGIX (GLenum pname, const GLint *params); GLAPI void APIENTRY glFragmentMaterialfSGIX (GLenum face, GLenum pname, GLfloat param); GLAPI void APIENTRY glFragmentMaterialfvSGIX (GLenum face, GLenum pname, const GLfloat *params); GLAPI void APIENTRY glFragmentMaterialiSGIX (GLenum face, GLenum pname, GLint param); GLAPI void APIENTRY glFragmentMaterialivSGIX (GLenum face, GLenum pname, const GLint *params); GLAPI void APIENTRY glGetFragmentLightfvSGIX (GLenum light, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetFragmentLightivSGIX (GLenum light, GLenum pname, GLint *params); GLAPI void APIENTRY glGetFragmentMaterialfvSGIX (GLenum face, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetFragmentMaterialivSGIX (GLenum face, GLenum pname, GLint *params); GLAPI void APIENTRY glLightEnviSGIX (GLenum pname, GLint param); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLLIGHTENVISGIXPROC) (GLenum pname, GLint param); #endif #ifndef GL_IBM_rasterpos_clip #define GL_IBM_rasterpos_clip 1 #endif #ifndef GL_HP_texture_lighting #define GL_HP_texture_lighting 1 #endif #ifndef GL_EXT_draw_range_elements #define GL_EXT_draw_range_elements 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawRangeElementsEXT (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); #endif #ifndef GL_WIN_phong_shading #define GL_WIN_phong_shading 1 #endif #ifndef GL_WIN_specular_fog #define GL_WIN_specular_fog 1 #endif #ifndef GL_EXT_light_texture #define GL_EXT_light_texture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glApplyTextureEXT (GLenum mode); GLAPI void APIENTRY glTextureLightEXT (GLenum pname); GLAPI void APIENTRY glTextureMaterialEXT (GLenum face, GLenum mode); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); typedef void (APIENTRYP PFNGLTEXTURELIGHTEXTPROC) (GLenum pname); typedef void (APIENTRYP PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); #endif #ifndef GL_SGIX_blend_alpha_minmax #define GL_SGIX_blend_alpha_minmax 1 #endif #ifndef GL_EXT_bgra #define GL_EXT_bgra 1 #endif #ifndef GL_SGIX_async #define GL_SGIX_async 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glAsyncMarkerSGIX (GLuint marker); GLAPI GLint APIENTRY glFinishAsyncSGIX (GLuint *markerp); GLAPI GLint APIENTRY glPollAsyncSGIX (GLuint *markerp); GLAPI GLuint APIENTRY glGenAsyncMarkersSGIX (GLsizei range); GLAPI void APIENTRY glDeleteAsyncMarkersSGIX (GLuint marker, GLsizei range); GLAPI GLboolean APIENTRY glIsAsyncMarkerSGIX (GLuint marker); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLASYNCMARKERSGIXPROC) (GLuint marker); typedef GLint (APIENTRYP PFNGLFINISHASYNCSGIXPROC) (GLuint *markerp); typedef GLint (APIENTRYP PFNGLPOLLASYNCSGIXPROC) (GLuint *markerp); typedef GLuint (APIENTRYP PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range); typedef void (APIENTRYP PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); typedef GLboolean (APIENTRYP PFNGLISASYNCMARKERSGIXPROC) (GLuint marker); #endif #ifndef GL_SGIX_async_pixel #define GL_SGIX_async_pixel 1 #endif #ifndef GL_SGIX_async_histogram #define GL_SGIX_async_histogram 1 #endif #ifndef GL_INTEL_parallel_arrays #define GL_INTEL_parallel_arrays 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexPointervINTEL (GLint size, GLenum type, const GLvoid* *pointer); GLAPI void APIENTRY glNormalPointervINTEL (GLenum type, const GLvoid* *pointer); GLAPI void APIENTRY glColorPointervINTEL (GLint size, GLenum type, const GLvoid* *pointer); GLAPI void APIENTRY glTexCoordPointervINTEL (GLint size, GLenum type, const GLvoid* *pointer); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); typedef void (APIENTRYP PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const GLvoid* *pointer); typedef void (APIENTRYP PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); typedef void (APIENTRYP PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); #endif #ifndef GL_HP_occlusion_test #define GL_HP_occlusion_test 1 #endif #ifndef GL_EXT_pixel_transform #define GL_EXT_pixel_transform 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPixelTransformParameteriEXT (GLenum target, GLenum pname, GLint param); GLAPI void APIENTRY glPixelTransformParameterfEXT (GLenum target, GLenum pname, GLfloat param); GLAPI void APIENTRY glPixelTransformParameterivEXT (GLenum target, GLenum pname, const GLint *params); GLAPI void APIENTRY glPixelTransformParameterfvEXT (GLenum target, GLenum pname, const GLfloat *params); GLAPI void APIENTRY glGetPixelTransformParameterivEXT (GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glGetPixelTransformParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); #endif #ifndef GL_EXT_pixel_transform_color_table #define GL_EXT_pixel_transform_color_table 1 #endif #ifndef GL_EXT_shared_texture_palette #define GL_EXT_shared_texture_palette 1 #endif #ifndef GL_EXT_separate_specular_color #define GL_EXT_separate_specular_color 1 #endif #ifndef GL_EXT_secondary_color #define GL_EXT_secondary_color 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glSecondaryColor3bEXT (GLbyte red, GLbyte green, GLbyte blue); GLAPI void APIENTRY glSecondaryColor3bvEXT (const GLbyte *v); GLAPI void APIENTRY glSecondaryColor3dEXT (GLdouble red, GLdouble green, GLdouble blue); GLAPI void APIENTRY glSecondaryColor3dvEXT (const GLdouble *v); GLAPI void APIENTRY glSecondaryColor3fEXT (GLfloat red, GLfloat green, GLfloat blue); GLAPI void APIENTRY glSecondaryColor3fvEXT (const GLfloat *v); GLAPI void APIENTRY glSecondaryColor3iEXT (GLint red, GLint green, GLint blue); GLAPI void APIENTRY glSecondaryColor3ivEXT (const GLint *v); GLAPI void APIENTRY glSecondaryColor3sEXT (GLshort red, GLshort green, GLshort blue); GLAPI void APIENTRY glSecondaryColor3svEXT (const GLshort *v); GLAPI void APIENTRY glSecondaryColor3ubEXT (GLubyte red, GLubyte green, GLubyte blue); GLAPI void APIENTRY glSecondaryColor3ubvEXT (const GLubyte *v); GLAPI void APIENTRY glSecondaryColor3uiEXT (GLuint red, GLuint green, GLuint blue); GLAPI void APIENTRY glSecondaryColor3uivEXT (const GLuint *v); GLAPI void APIENTRY glSecondaryColor3usEXT (GLushort red, GLushort green, GLushort blue); GLAPI void APIENTRY glSecondaryColor3usvEXT (const GLushort *v); GLAPI void APIENTRY glSecondaryColorPointerEXT (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); #endif #ifndef GL_EXT_texture_perturb_normal #define GL_EXT_texture_perturb_normal 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTextureNormalEXT (GLenum mode); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXTURENORMALEXTPROC) (GLenum mode); #endif #ifndef GL_EXT_multi_draw_arrays #define GL_EXT_multi_draw_arrays 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glMultiDrawArraysEXT (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); GLAPI void APIENTRY glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); #endif #ifndef GL_EXT_fog_coord #define GL_EXT_fog_coord 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFogCoordfEXT (GLfloat coord); GLAPI void APIENTRY glFogCoordfvEXT (const GLfloat *coord); GLAPI void APIENTRY glFogCoorddEXT (GLdouble coord); GLAPI void APIENTRY glFogCoorddvEXT (const GLdouble *coord); GLAPI void APIENTRY glFogCoordPointerEXT (GLenum type, GLsizei stride, const GLvoid *pointer); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLFOGCOORDFEXTPROC) (GLfloat coord); typedef void (APIENTRYP PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); typedef void (APIENTRYP PFNGLFOGCOORDDEXTPROC) (GLdouble coord); typedef void (APIENTRYP PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); typedef void (APIENTRYP PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); #endif #ifndef GL_REND_screen_coordinates #define GL_REND_screen_coordinates 1 #endif #ifndef GL_EXT_coordinate_frame #define GL_EXT_coordinate_frame 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTangent3bEXT (GLbyte tx, GLbyte ty, GLbyte tz); GLAPI void APIENTRY glTangent3bvEXT (const GLbyte *v); GLAPI void APIENTRY glTangent3dEXT (GLdouble tx, GLdouble ty, GLdouble tz); GLAPI void APIENTRY glTangent3dvEXT (const GLdouble *v); GLAPI void APIENTRY glTangent3fEXT (GLfloat tx, GLfloat ty, GLfloat tz); GLAPI void APIENTRY glTangent3fvEXT (const GLfloat *v); GLAPI void APIENTRY glTangent3iEXT (GLint tx, GLint ty, GLint tz); GLAPI void APIENTRY glTangent3ivEXT (const GLint *v); GLAPI void APIENTRY glTangent3sEXT (GLshort tx, GLshort ty, GLshort tz); GLAPI void APIENTRY glTangent3svEXT (const GLshort *v); GLAPI void APIENTRY glBinormal3bEXT (GLbyte bx, GLbyte by, GLbyte bz); GLAPI void APIENTRY glBinormal3bvEXT (const GLbyte *v); GLAPI void APIENTRY glBinormal3dEXT (GLdouble bx, GLdouble by, GLdouble bz); GLAPI void APIENTRY glBinormal3dvEXT (const GLdouble *v); GLAPI void APIENTRY glBinormal3fEXT (GLfloat bx, GLfloat by, GLfloat bz); GLAPI void APIENTRY glBinormal3fvEXT (const GLfloat *v); GLAPI void APIENTRY glBinormal3iEXT (GLint bx, GLint by, GLint bz); GLAPI void APIENTRY glBinormal3ivEXT (const GLint *v); GLAPI void APIENTRY glBinormal3sEXT (GLshort bx, GLshort by, GLshort bz); GLAPI void APIENTRY glBinormal3svEXT (const GLshort *v); GLAPI void APIENTRY glTangentPointerEXT (GLenum type, GLsizei stride, const GLvoid *pointer); GLAPI void APIENTRY glBinormalPointerEXT (GLenum type, GLsizei stride, const GLvoid *pointer); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTANGENT3BEXTPROC) (GLbyte tx, GLbyte ty, GLbyte tz); typedef void (APIENTRYP PFNGLTANGENT3BVEXTPROC) (const GLbyte *v); typedef void (APIENTRYP PFNGLTANGENT3DEXTPROC) (GLdouble tx, GLdouble ty, GLdouble tz); typedef void (APIENTRYP PFNGLTANGENT3DVEXTPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLTANGENT3FEXTPROC) (GLfloat tx, GLfloat ty, GLfloat tz); typedef void (APIENTRYP PFNGLTANGENT3FVEXTPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLTANGENT3IEXTPROC) (GLint tx, GLint ty, GLint tz); typedef void (APIENTRYP PFNGLTANGENT3IVEXTPROC) (const GLint *v); typedef void (APIENTRYP PFNGLTANGENT3SEXTPROC) (GLshort tx, GLshort ty, GLshort tz); typedef void (APIENTRYP PFNGLTANGENT3SVEXTPROC) (const GLshort *v); typedef void (APIENTRYP PFNGLBINORMAL3BEXTPROC) (GLbyte bx, GLbyte by, GLbyte bz); typedef void (APIENTRYP PFNGLBINORMAL3BVEXTPROC) (const GLbyte *v); typedef void (APIENTRYP PFNGLBINORMAL3DEXTPROC) (GLdouble bx, GLdouble by, GLdouble bz); typedef void (APIENTRYP PFNGLBINORMAL3DVEXTPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLBINORMAL3FEXTPROC) (GLfloat bx, GLfloat by, GLfloat bz); typedef void (APIENTRYP PFNGLBINORMAL3FVEXTPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLBINORMAL3IEXTPROC) (GLint bx, GLint by, GLint bz); typedef void (APIENTRYP PFNGLBINORMAL3IVEXTPROC) (const GLint *v); typedef void (APIENTRYP PFNGLBINORMAL3SEXTPROC) (GLshort bx, GLshort by, GLshort bz); typedef void (APIENTRYP PFNGLBINORMAL3SVEXTPROC) (const GLshort *v); typedef void (APIENTRYP PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); #endif #ifndef GL_EXT_texture_env_combine #define GL_EXT_texture_env_combine 1 #endif #ifndef GL_APPLE_specular_vector #define GL_APPLE_specular_vector 1 #endif #ifndef GL_APPLE_transform_hint #define GL_APPLE_transform_hint 1 #endif #ifndef GL_SGIX_fog_scale #define GL_SGIX_fog_scale 1 #endif #ifndef GL_SUNX_constant_data #define GL_SUNX_constant_data 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFinishTextureSUNX (void); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLFINISHTEXTURESUNXPROC) (void); #endif #ifndef GL_SUN_global_alpha #define GL_SUN_global_alpha 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGlobalAlphaFactorbSUN (GLbyte factor); GLAPI void APIENTRY glGlobalAlphaFactorsSUN (GLshort factor); GLAPI void APIENTRY glGlobalAlphaFactoriSUN (GLint factor); GLAPI void APIENTRY glGlobalAlphaFactorfSUN (GLfloat factor); GLAPI void APIENTRY glGlobalAlphaFactordSUN (GLdouble factor); GLAPI void APIENTRY glGlobalAlphaFactorubSUN (GLubyte factor); GLAPI void APIENTRY glGlobalAlphaFactorusSUN (GLushort factor); GLAPI void APIENTRY glGlobalAlphaFactoruiSUN (GLuint factor); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); #endif #ifndef GL_SUN_triangle_list #define GL_SUN_triangle_list 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glReplacementCodeuiSUN (GLuint code); GLAPI void APIENTRY glReplacementCodeusSUN (GLushort code); GLAPI void APIENTRY glReplacementCodeubSUN (GLubyte code); GLAPI void APIENTRY glReplacementCodeuivSUN (const GLuint *code); GLAPI void APIENTRY glReplacementCodeusvSUN (const GLushort *code); GLAPI void APIENTRY glReplacementCodeubvSUN (const GLubyte *code); GLAPI void APIENTRY glReplacementCodePointerSUN (GLenum type, GLsizei stride, const GLvoid* *pointer); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint *code); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort *code); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte *code); typedef void (APIENTRYP PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const GLvoid* *pointer); #endif #ifndef GL_SUN_vertex #define GL_SUN_vertex 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glColor4ubVertex2fSUN (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); GLAPI void APIENTRY glColor4ubVertex2fvSUN (const GLubyte *c, const GLfloat *v); GLAPI void APIENTRY glColor4ubVertex3fSUN (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glColor4ubVertex3fvSUN (const GLubyte *c, const GLfloat *v); GLAPI void APIENTRY glColor3fVertex3fSUN (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glColor3fVertex3fvSUN (const GLfloat *c, const GLfloat *v); GLAPI void APIENTRY glNormal3fVertex3fSUN (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glNormal3fVertex3fvSUN (const GLfloat *n, const GLfloat *v); GLAPI void APIENTRY glColor4fNormal3fVertex3fSUN (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glColor4fNormal3fVertex3fvSUN (const GLfloat *c, const GLfloat *n, const GLfloat *v); GLAPI void APIENTRY glTexCoord2fVertex3fSUN (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glTexCoord2fVertex3fvSUN (const GLfloat *tc, const GLfloat *v); GLAPI void APIENTRY glTexCoord4fVertex4fSUN (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); GLAPI void APIENTRY glTexCoord4fVertex4fvSUN (const GLfloat *tc, const GLfloat *v); GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fSUN (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fvSUN (const GLfloat *tc, const GLubyte *c, const GLfloat *v); GLAPI void APIENTRY glTexCoord2fColor3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glTexCoord2fColor3fVertex3fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *v); GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fvSUN (const GLfloat *tc, const GLfloat *n, const GLfloat *v); GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fSUN (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); GLAPI void APIENTRY glReplacementCodeuiVertex3fSUN (GLuint rc, GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glReplacementCodeuiVertex3fvSUN (const GLuint *rc, const GLfloat *v); GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fSUN (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fvSUN (const GLuint *rc, const GLubyte *c, const GLfloat *v); GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fSUN (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fvSUN (const GLuint *rc, const GLfloat *c, const GLfloat *v); GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fSUN (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *n, const GLfloat *v); GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fSUN (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *v); GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte *c, const GLfloat *v); typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte *c, const GLfloat *v); typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *v); typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *v); typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *v); typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat *tc, const GLubyte *c, const GLfloat *v); typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *v); typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *v); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint *rc, const GLubyte *c, const GLfloat *v); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *v); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *v); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); #endif #ifndef GL_EXT_blend_func_separate #define GL_EXT_blend_func_separate 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendFuncSeparateEXT (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); #endif #ifndef GL_INGR_blend_func_separate #define GL_INGR_blend_func_separate 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendFuncSeparateINGR (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINGRPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); #endif #ifndef GL_INGR_color_clamp #define GL_INGR_color_clamp 1 #endif #ifndef GL_INGR_interlace_read #define GL_INGR_interlace_read 1 #endif #ifndef GL_EXT_stencil_wrap #define GL_EXT_stencil_wrap 1 #endif #ifndef GL_EXT_422_pixels #define GL_EXT_422_pixels 1 #endif #ifndef GL_NV_texgen_reflection #define GL_NV_texgen_reflection 1 #endif #ifndef GL_SUN_convolution_border_modes #define GL_SUN_convolution_border_modes 1 #endif #ifndef GL_EXT_texture_env_add #define GL_EXT_texture_env_add 1 #endif #ifndef GL_EXT_texture_lod_bias #define GL_EXT_texture_lod_bias 1 #endif #ifndef GL_EXT_texture_filter_anisotropic #define GL_EXT_texture_filter_anisotropic 1 #endif #ifndef GL_EXT_vertex_weighting #define GL_EXT_vertex_weighting 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexWeightfEXT (GLfloat weight); GLAPI void APIENTRY glVertexWeightfvEXT (const GLfloat *weight); GLAPI void APIENTRY glVertexWeightPointerEXT (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); typedef void (APIENTRYP PFNGLVERTEXWEIGHTFVEXTPROC) (const GLfloat *weight); typedef void (APIENTRYP PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); #endif #ifndef GL_NV_light_max_exponent #define GL_NV_light_max_exponent 1 #endif #ifndef GL_NV_vertex_array_range #define GL_NV_vertex_array_range 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFlushVertexArrayRangeNV (void); GLAPI void APIENTRY glVertexArrayRangeNV (GLsizei length, const GLvoid *pointer); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void); typedef void (APIENTRYP PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, const GLvoid *pointer); #endif #ifndef GL_NV_register_combiners #define GL_NV_register_combiners 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glCombinerParameterfvNV (GLenum pname, const GLfloat *params); GLAPI void APIENTRY glCombinerParameterfNV (GLenum pname, GLfloat param); GLAPI void APIENTRY glCombinerParameterivNV (GLenum pname, const GLint *params); GLAPI void APIENTRY glCombinerParameteriNV (GLenum pname, GLint param); GLAPI void APIENTRY glCombinerInputNV (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); GLAPI void APIENTRY glCombinerOutputNV (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); GLAPI void APIENTRY glFinalCombinerInputNV (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); GLAPI void APIENTRY glGetCombinerInputParameterfvNV (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetCombinerInputParameterivNV (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); GLAPI void APIENTRY glGetCombinerOutputParameterfvNV (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetCombinerOutputParameterivNV (GLenum stage, GLenum portion, GLenum pname, GLint *params); GLAPI void APIENTRY glGetFinalCombinerInputParameterfvNV (GLenum variable, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetFinalCombinerInputParameterivNV (GLenum variable, GLenum pname, GLint *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); typedef void (APIENTRYP PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); typedef void (APIENTRYP PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint *params); #endif #ifndef GL_NV_fog_distance #define GL_NV_fog_distance 1 #endif #ifndef GL_NV_texgen_emboss #define GL_NV_texgen_emboss 1 #endif #ifndef GL_NV_blend_square #define GL_NV_blend_square 1 #endif #ifndef GL_NV_texture_env_combine4 #define GL_NV_texture_env_combine4 1 #endif #ifndef GL_MESA_resize_buffers #define GL_MESA_resize_buffers 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glResizeBuffersMESA (void); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLRESIZEBUFFERSMESAPROC) (void); #endif #ifndef GL_MESA_window_pos #define GL_MESA_window_pos 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glWindowPos2dMESA (GLdouble x, GLdouble y); GLAPI void APIENTRY glWindowPos2dvMESA (const GLdouble *v); GLAPI void APIENTRY glWindowPos2fMESA (GLfloat x, GLfloat y); GLAPI void APIENTRY glWindowPos2fvMESA (const GLfloat *v); GLAPI void APIENTRY glWindowPos2iMESA (GLint x, GLint y); GLAPI void APIENTRY glWindowPos2ivMESA (const GLint *v); GLAPI void APIENTRY glWindowPos2sMESA (GLshort x, GLshort y); GLAPI void APIENTRY glWindowPos2svMESA (const GLshort *v); GLAPI void APIENTRY glWindowPos3dMESA (GLdouble x, GLdouble y, GLdouble z); GLAPI void APIENTRY glWindowPos3dvMESA (const GLdouble *v); GLAPI void APIENTRY glWindowPos3fMESA (GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glWindowPos3fvMESA (const GLfloat *v); GLAPI void APIENTRY glWindowPos3iMESA (GLint x, GLint y, GLint z); GLAPI void APIENTRY glWindowPos3ivMESA (const GLint *v); GLAPI void APIENTRY glWindowPos3sMESA (GLshort x, GLshort y, GLshort z); GLAPI void APIENTRY glWindowPos3svMESA (const GLshort *v); GLAPI void APIENTRY glWindowPos4dMESA (GLdouble x, GLdouble y, GLdouble z, GLdouble w); GLAPI void APIENTRY glWindowPos4dvMESA (const GLdouble *v); GLAPI void APIENTRY glWindowPos4fMESA (GLfloat x, GLfloat y, GLfloat z, GLfloat w); GLAPI void APIENTRY glWindowPos4fvMESA (const GLfloat *v); GLAPI void APIENTRY glWindowPos4iMESA (GLint x, GLint y, GLint z, GLint w); GLAPI void APIENTRY glWindowPos4ivMESA (const GLint *v); GLAPI void APIENTRY glWindowPos4sMESA (GLshort x, GLshort y, GLshort z, GLshort w); GLAPI void APIENTRY glWindowPos4svMESA (const GLshort *v); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); typedef void (APIENTRYP PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); typedef void (APIENTRYP PFNGLWINDOWPOS2IVMESAPROC) (const GLint *v); typedef void (APIENTRYP PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); typedef void (APIENTRYP PFNGLWINDOWPOS2SVMESAPROC) (const GLshort *v); typedef void (APIENTRYP PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); typedef void (APIENTRYP PFNGLWINDOWPOS3IVMESAPROC) (const GLint *v); typedef void (APIENTRYP PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNGLWINDOWPOS3SVMESAPROC) (const GLshort *v); typedef void (APIENTRYP PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); typedef void (APIENTRYP PFNGLWINDOWPOS4IVMESAPROC) (const GLint *v); typedef void (APIENTRYP PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); typedef void (APIENTRYP PFNGLWINDOWPOS4SVMESAPROC) (const GLshort *v); #endif #ifndef GL_IBM_cull_vertex #define GL_IBM_cull_vertex 1 #endif #ifndef GL_IBM_multimode_draw_arrays #define GL_IBM_multimode_draw_arrays 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glMultiModeDrawArraysIBM (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); GLAPI void APIENTRY glMultiModeDrawElementsIBM (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei primcount, GLint modestride); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); typedef void (APIENTRYP PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei primcount, GLint modestride); #endif #ifndef GL_IBM_vertex_array_lists #define GL_IBM_vertex_array_lists 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glColorPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); GLAPI void APIENTRY glSecondaryColorPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); GLAPI void APIENTRY glEdgeFlagPointerListIBM (GLint stride, const GLboolean* *pointer, GLint ptrstride); GLAPI void APIENTRY glFogCoordPointerListIBM (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); GLAPI void APIENTRY glIndexPointerListIBM (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); GLAPI void APIENTRY glNormalPointerListIBM (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); GLAPI void APIENTRY glTexCoordPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); GLAPI void APIENTRY glVertexPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); #endif #ifndef GL_SGIX_subsample #define GL_SGIX_subsample 1 #endif #ifndef GL_SGIX_ycrcba #define GL_SGIX_ycrcba 1 #endif #ifndef GL_SGIX_ycrcb_subsample #define GL_SGIX_ycrcb_subsample 1 #endif #ifndef GL_SGIX_depth_pass_instrument #define GL_SGIX_depth_pass_instrument 1 #endif #ifndef GL_3DFX_texture_compression_FXT1 #define GL_3DFX_texture_compression_FXT1 1 #endif #ifndef GL_3DFX_multisample #define GL_3DFX_multisample 1 #endif #ifndef GL_3DFX_tbuffer #define GL_3DFX_tbuffer 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTbufferMask3DFX (GLuint mask); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTBUFFERMASK3DFXPROC) (GLuint mask); #endif #ifndef GL_EXT_multisample #define GL_EXT_multisample 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glSampleMaskEXT (GLclampf value, GLboolean invert); GLAPI void APIENTRY glSamplePatternEXT (GLenum pattern); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); typedef void (APIENTRYP PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); #endif #ifndef GL_SGIX_vertex_preclip #define GL_SGIX_vertex_preclip 1 #endif #ifndef GL_SGIX_convolution_accuracy #define GL_SGIX_convolution_accuracy 1 #endif #ifndef GL_SGIX_resample #define GL_SGIX_resample 1 #endif #ifndef GL_SGIS_point_line_texgen #define GL_SGIS_point_line_texgen 1 #endif #ifndef GL_SGIS_texture_color_mask #define GL_SGIS_texture_color_mask 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTextureColorMaskSGIS (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); #endif #ifndef GL_SGIX_igloo_interface #define GL_SGIX_igloo_interface 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glIglooInterfaceSGIX (GLenum pname, const GLvoid *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, const GLvoid *params); #endif #ifndef GL_EXT_texture_env_dot3 #define GL_EXT_texture_env_dot3 1 #endif #ifndef GL_ATI_texture_mirror_once #define GL_ATI_texture_mirror_once 1 #endif #ifndef GL_NV_fence #define GL_NV_fence 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDeleteFencesNV (GLsizei n, const GLuint *fences); GLAPI void APIENTRY glGenFencesNV (GLsizei n, GLuint *fences); GLAPI GLboolean APIENTRY glIsFenceNV (GLuint fence); GLAPI GLboolean APIENTRY glTestFenceNV (GLuint fence); GLAPI void APIENTRY glGetFenceivNV (GLuint fence, GLenum pname, GLint *params); GLAPI void APIENTRY glFinishFenceNV (GLuint fence); GLAPI void APIENTRY glSetFenceNV (GLuint fence, GLenum condition); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); typedef void (APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); typedef GLboolean (APIENTRYP PFNGLISFENCENVPROC) (GLuint fence); typedef GLboolean (APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence); typedef void (APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence); typedef void (APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); #endif #ifndef GL_NV_evaluators #define GL_NV_evaluators 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glMapControlPointsNV (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points); GLAPI void APIENTRY glMapParameterivNV (GLenum target, GLenum pname, const GLint *params); GLAPI void APIENTRY glMapParameterfvNV (GLenum target, GLenum pname, const GLfloat *params); GLAPI void APIENTRY glGetMapControlPointsNV (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points); GLAPI void APIENTRY glGetMapParameterivNV (GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glGetMapParameterfvNV (GLenum target, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetMapAttribParameterivNV (GLenum target, GLuint index, GLenum pname, GLint *params); GLAPI void APIENTRY glGetMapAttribParameterfvNV (GLenum target, GLuint index, GLenum pname, GLfloat *params); GLAPI void APIENTRY glEvalMapsNV (GLenum target, GLenum mode); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points); typedef void (APIENTRYP PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points); typedef void (APIENTRYP PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode); #endif #ifndef GL_NV_packed_depth_stencil #define GL_NV_packed_depth_stencil 1 #endif #ifndef GL_NV_register_combiners2 #define GL_NV_register_combiners2 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glCombinerStageParameterfvNV (GLenum stage, GLenum pname, const GLfloat *params); GLAPI void APIENTRY glGetCombinerStageParameterfvNV (GLenum stage, GLenum pname, GLfloat *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat *params); #endif #ifndef GL_NV_texture_compression_vtc #define GL_NV_texture_compression_vtc 1 #endif #ifndef GL_NV_texture_rectangle #define GL_NV_texture_rectangle 1 #endif #ifndef GL_NV_texture_shader #define GL_NV_texture_shader 1 #endif #ifndef GL_NV_texture_shader2 #define GL_NV_texture_shader2 1 #endif #ifndef GL_NV_vertex_array_range2 #define GL_NV_vertex_array_range2 1 #endif #ifndef GL_NV_vertex_program #define GL_NV_vertex_program 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLboolean APIENTRY glAreProgramsResidentNV (GLsizei n, const GLuint *programs, GLboolean *residences); GLAPI void APIENTRY glBindProgramNV (GLenum target, GLuint id); GLAPI void APIENTRY glDeleteProgramsNV (GLsizei n, const GLuint *programs); GLAPI void APIENTRY glExecuteProgramNV (GLenum target, GLuint id, const GLfloat *params); GLAPI void APIENTRY glGenProgramsNV (GLsizei n, GLuint *programs); GLAPI void APIENTRY glGetProgramParameterdvNV (GLenum target, GLuint index, GLenum pname, GLdouble *params); GLAPI void APIENTRY glGetProgramParameterfvNV (GLenum target, GLuint index, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetProgramivNV (GLuint id, GLenum pname, GLint *params); GLAPI void APIENTRY glGetProgramStringNV (GLuint id, GLenum pname, GLubyte *program); GLAPI void APIENTRY glGetTrackMatrixivNV (GLenum target, GLuint address, GLenum pname, GLint *params); GLAPI void APIENTRY glGetVertexAttribdvNV (GLuint index, GLenum pname, GLdouble *params); GLAPI void APIENTRY glGetVertexAttribfvNV (GLuint index, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetVertexAttribivNV (GLuint index, GLenum pname, GLint *params); GLAPI void APIENTRY glGetVertexAttribPointervNV (GLuint index, GLenum pname, GLvoid* *pointer); GLAPI GLboolean APIENTRY glIsProgramNV (GLuint id); GLAPI void APIENTRY glLoadProgramNV (GLenum target, GLuint id, GLsizei len, const GLubyte *program); GLAPI void APIENTRY glProgramParameter4dNV (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); GLAPI void APIENTRY glProgramParameter4dvNV (GLenum target, GLuint index, const GLdouble *v); GLAPI void APIENTRY glProgramParameter4fNV (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); GLAPI void APIENTRY glProgramParameter4fvNV (GLenum target, GLuint index, const GLfloat *v); GLAPI void APIENTRY glProgramParameters4dvNV (GLenum target, GLuint index, GLsizei count, const GLdouble *v); GLAPI void APIENTRY glProgramParameters4fvNV (GLenum target, GLuint index, GLsizei count, const GLfloat *v); GLAPI void APIENTRY glRequestResidentProgramsNV (GLsizei n, const GLuint *programs); GLAPI void APIENTRY glTrackMatrixNV (GLenum target, GLuint address, GLenum matrix, GLenum transform); GLAPI void APIENTRY glVertexAttribPointerNV (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer); GLAPI void APIENTRY glVertexAttrib1dNV (GLuint index, GLdouble x); GLAPI void APIENTRY glVertexAttrib1dvNV (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttrib1fNV (GLuint index, GLfloat x); GLAPI void APIENTRY glVertexAttrib1fvNV (GLuint index, const GLfloat *v); GLAPI void APIENTRY glVertexAttrib1sNV (GLuint index, GLshort x); GLAPI void APIENTRY glVertexAttrib1svNV (GLuint index, const GLshort *v); GLAPI void APIENTRY glVertexAttrib2dNV (GLuint index, GLdouble x, GLdouble y); GLAPI void APIENTRY glVertexAttrib2dvNV (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttrib2fNV (GLuint index, GLfloat x, GLfloat y); GLAPI void APIENTRY glVertexAttrib2fvNV (GLuint index, const GLfloat *v); GLAPI void APIENTRY glVertexAttrib2sNV (GLuint index, GLshort x, GLshort y); GLAPI void APIENTRY glVertexAttrib2svNV (GLuint index, const GLshort *v); GLAPI void APIENTRY glVertexAttrib3dNV (GLuint index, GLdouble x, GLdouble y, GLdouble z); GLAPI void APIENTRY glVertexAttrib3dvNV (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttrib3fNV (GLuint index, GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glVertexAttrib3fvNV (GLuint index, const GLfloat *v); GLAPI void APIENTRY glVertexAttrib3sNV (GLuint index, GLshort x, GLshort y, GLshort z); GLAPI void APIENTRY glVertexAttrib3svNV (GLuint index, const GLshort *v); GLAPI void APIENTRY glVertexAttrib4dNV (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); GLAPI void APIENTRY glVertexAttrib4dvNV (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttrib4fNV (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); GLAPI void APIENTRY glVertexAttrib4fvNV (GLuint index, const GLfloat *v); GLAPI void APIENTRY glVertexAttrib4sNV (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); GLAPI void APIENTRY glVertexAttrib4svNV (GLuint index, const GLshort *v); GLAPI void APIENTRY glVertexAttrib4ubNV (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); GLAPI void APIENTRY glVertexAttrib4ubvNV (GLuint index, const GLubyte *v); GLAPI void APIENTRY glVertexAttribs1dvNV (GLuint index, GLsizei count, const GLdouble *v); GLAPI void APIENTRY glVertexAttribs1fvNV (GLuint index, GLsizei count, const GLfloat *v); GLAPI void APIENTRY glVertexAttribs1svNV (GLuint index, GLsizei count, const GLshort *v); GLAPI void APIENTRY glVertexAttribs2dvNV (GLuint index, GLsizei count, const GLdouble *v); GLAPI void APIENTRY glVertexAttribs2fvNV (GLuint index, GLsizei count, const GLfloat *v); GLAPI void APIENTRY glVertexAttribs2svNV (GLuint index, GLsizei count, const GLshort *v); GLAPI void APIENTRY glVertexAttribs3dvNV (GLuint index, GLsizei count, const GLdouble *v); GLAPI void APIENTRY glVertexAttribs3fvNV (GLuint index, GLsizei count, const GLfloat *v); GLAPI void APIENTRY glVertexAttribs3svNV (GLuint index, GLsizei count, const GLshort *v); GLAPI void APIENTRY glVertexAttribs4dvNV (GLuint index, GLsizei count, const GLdouble *v); GLAPI void APIENTRY glVertexAttribs4fvNV (GLuint index, GLsizei count, const GLfloat *v); GLAPI void APIENTRY glVertexAttribs4svNV (GLuint index, GLsizei count, const GLshort *v); GLAPI void APIENTRY glVertexAttribs4ubvNV (GLuint index, GLsizei count, const GLubyte *v); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLboolean (APIENTRYP PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint *programs, GLboolean *residences); typedef void (APIENTRYP PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); typedef void (APIENTRYP PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); typedef void (APIENTRYP PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat *params); typedef void (APIENTRYP PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint *programs); typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble *params); typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte *program); typedef void (APIENTRYP PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid* *pointer); typedef GLboolean (APIENTRYP PFNGLISPROGRAMNVPROC) (GLuint id); typedef void (APIENTRYP PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte *program); typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLdouble *v); typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *v); typedef void (APIENTRYP PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); typedef void (APIENTRYP PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei count, const GLubyte *v); #endif #ifndef GL_SGIX_texture_coordinate_clamp #define GL_SGIX_texture_coordinate_clamp 1 #endif #ifndef GL_SGIX_scalebias_hint #define GL_SGIX_scalebias_hint 1 #endif #ifndef GL_OML_interlace #define GL_OML_interlace 1 #endif #ifndef GL_OML_subsample #define GL_OML_subsample 1 #endif #ifndef GL_OML_resample #define GL_OML_resample 1 #endif #ifndef GL_NV_copy_depth_to_color #define GL_NV_copy_depth_to_color 1 #endif #ifndef GL_ATI_envmap_bumpmap #define GL_ATI_envmap_bumpmap 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTexBumpParameterivATI (GLenum pname, const GLint *param); GLAPI void APIENTRY glTexBumpParameterfvATI (GLenum pname, const GLfloat *param); GLAPI void APIENTRY glGetTexBumpParameterivATI (GLenum pname, GLint *param); GLAPI void APIENTRY glGetTexBumpParameterfvATI (GLenum pname, GLfloat *param); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, const GLint *param); typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, const GLfloat *param); typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); #endif #ifndef GL_ATI_fragment_shader #define GL_ATI_fragment_shader 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLuint APIENTRY glGenFragmentShadersATI (GLuint range); GLAPI void APIENTRY glBindFragmentShaderATI (GLuint id); GLAPI void APIENTRY glDeleteFragmentShaderATI (GLuint id); GLAPI void APIENTRY glBeginFragmentShaderATI (void); GLAPI void APIENTRY glEndFragmentShaderATI (void); GLAPI void APIENTRY glPassTexCoordATI (GLuint dst, GLuint coord, GLenum swizzle); GLAPI void APIENTRY glSampleMapATI (GLuint dst, GLuint interp, GLenum swizzle); GLAPI void APIENTRY glColorFragmentOp1ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); GLAPI void APIENTRY glColorFragmentOp2ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); GLAPI void APIENTRY glColorFragmentOp3ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); GLAPI void APIENTRY glAlphaFragmentOp1ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); GLAPI void APIENTRY glAlphaFragmentOp2ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); GLAPI void APIENTRY glAlphaFragmentOp3ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); GLAPI void APIENTRY glSetFragmentShaderConstantATI (GLuint dst, const GLfloat *value); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLuint (APIENTRYP PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range); typedef void (APIENTRYP PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id); typedef void (APIENTRYP PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id); typedef void (APIENTRYP PFNGLBEGINFRAGMENTSHADERATIPROC) (void); typedef void (APIENTRYP PFNGLENDFRAGMENTSHADERATIPROC) (void); typedef void (APIENTRYP PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle); typedef void (APIENTRYP PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle); typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); typedef void (APIENTRYP PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat *value); #endif #ifndef GL_ATI_pn_triangles #define GL_ATI_pn_triangles 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPNTrianglesiATI (GLenum pname, GLint param); GLAPI void APIENTRY glPNTrianglesfATI (GLenum pname, GLfloat param); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param); #endif #ifndef GL_ATI_vertex_array_object #define GL_ATI_vertex_array_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLuint APIENTRY glNewObjectBufferATI (GLsizei size, const GLvoid *pointer, GLenum usage); GLAPI GLboolean APIENTRY glIsObjectBufferATI (GLuint buffer); GLAPI void APIENTRY glUpdateObjectBufferATI (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve); GLAPI void APIENTRY glGetObjectBufferfvATI (GLuint buffer, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetObjectBufferivATI (GLuint buffer, GLenum pname, GLint *params); GLAPI void APIENTRY glFreeObjectBufferATI (GLuint buffer); GLAPI void APIENTRY glArrayObjectATI (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); GLAPI void APIENTRY glGetArrayObjectfvATI (GLenum array, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetArrayObjectivATI (GLenum array, GLenum pname, GLint *params); GLAPI void APIENTRY glVariantArrayObjectATI (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); GLAPI void APIENTRY glGetVariantArrayObjectfvATI (GLuint id, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetVariantArrayObjectivATI (GLuint id, GLenum pname, GLint *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLuint (APIENTRYP PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const GLvoid *pointer, GLenum usage); typedef GLboolean (APIENTRYP PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer); typedef void (APIENTRYP PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve); typedef void (APIENTRYP PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer); typedef void (APIENTRYP PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); typedef void (APIENTRYP PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint *params); #endif #ifndef GL_EXT_vertex_shader #define GL_EXT_vertex_shader 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBeginVertexShaderEXT (void); GLAPI void APIENTRY glEndVertexShaderEXT (void); GLAPI void APIENTRY glBindVertexShaderEXT (GLuint id); GLAPI GLuint APIENTRY glGenVertexShadersEXT (GLuint range); GLAPI void APIENTRY glDeleteVertexShaderEXT (GLuint id); GLAPI void APIENTRY glShaderOp1EXT (GLenum op, GLuint res, GLuint arg1); GLAPI void APIENTRY glShaderOp2EXT (GLenum op, GLuint res, GLuint arg1, GLuint arg2); GLAPI void APIENTRY glShaderOp3EXT (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); GLAPI void APIENTRY glSwizzleEXT (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); GLAPI void APIENTRY glWriteMaskEXT (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); GLAPI void APIENTRY glInsertComponentEXT (GLuint res, GLuint src, GLuint num); GLAPI void APIENTRY glExtractComponentEXT (GLuint res, GLuint src, GLuint num); GLAPI GLuint APIENTRY glGenSymbolsEXT (GLenum datatype, GLenum storagetype, GLenum range, GLuint components); GLAPI void APIENTRY glSetInvariantEXT (GLuint id, GLenum type, const GLvoid *addr); GLAPI void APIENTRY glSetLocalConstantEXT (GLuint id, GLenum type, const GLvoid *addr); GLAPI void APIENTRY glVariantbvEXT (GLuint id, const GLbyte *addr); GLAPI void APIENTRY glVariantsvEXT (GLuint id, const GLshort *addr); GLAPI void APIENTRY glVariantivEXT (GLuint id, const GLint *addr); GLAPI void APIENTRY glVariantfvEXT (GLuint id, const GLfloat *addr); GLAPI void APIENTRY glVariantdvEXT (GLuint id, const GLdouble *addr); GLAPI void APIENTRY glVariantubvEXT (GLuint id, const GLubyte *addr); GLAPI void APIENTRY glVariantusvEXT (GLuint id, const GLushort *addr); GLAPI void APIENTRY glVariantuivEXT (GLuint id, const GLuint *addr); GLAPI void APIENTRY glVariantPointerEXT (GLuint id, GLenum type, GLuint stride, const GLvoid *addr); GLAPI void APIENTRY glEnableVariantClientStateEXT (GLuint id); GLAPI void APIENTRY glDisableVariantClientStateEXT (GLuint id); GLAPI GLuint APIENTRY glBindLightParameterEXT (GLenum light, GLenum value); GLAPI GLuint APIENTRY glBindMaterialParameterEXT (GLenum face, GLenum value); GLAPI GLuint APIENTRY glBindTexGenParameterEXT (GLenum unit, GLenum coord, GLenum value); GLAPI GLuint APIENTRY glBindTextureUnitParameterEXT (GLenum unit, GLenum value); GLAPI GLuint APIENTRY glBindParameterEXT (GLenum value); GLAPI GLboolean APIENTRY glIsVariantEnabledEXT (GLuint id, GLenum cap); GLAPI void APIENTRY glGetVariantBooleanvEXT (GLuint id, GLenum value, GLboolean *data); GLAPI void APIENTRY glGetVariantIntegervEXT (GLuint id, GLenum value, GLint *data); GLAPI void APIENTRY glGetVariantFloatvEXT (GLuint id, GLenum value, GLfloat *data); GLAPI void APIENTRY glGetVariantPointervEXT (GLuint id, GLenum value, GLvoid* *data); GLAPI void APIENTRY glGetInvariantBooleanvEXT (GLuint id, GLenum value, GLboolean *data); GLAPI void APIENTRY glGetInvariantIntegervEXT (GLuint id, GLenum value, GLint *data); GLAPI void APIENTRY glGetInvariantFloatvEXT (GLuint id, GLenum value, GLfloat *data); GLAPI void APIENTRY glGetLocalConstantBooleanvEXT (GLuint id, GLenum value, GLboolean *data); GLAPI void APIENTRY glGetLocalConstantIntegervEXT (GLuint id, GLenum value, GLint *data); GLAPI void APIENTRY glGetLocalConstantFloatvEXT (GLuint id, GLenum value, GLfloat *data); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBEGINVERTEXSHADEREXTPROC) (void); typedef void (APIENTRYP PFNGLENDVERTEXSHADEREXTPROC) (void); typedef void (APIENTRYP PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id); typedef GLuint (APIENTRYP PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range); typedef void (APIENTRYP PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id); typedef void (APIENTRYP PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1); typedef void (APIENTRYP PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); typedef void (APIENTRYP PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); typedef void (APIENTRYP PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); typedef void (APIENTRYP PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); typedef void (APIENTRYP PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); typedef void (APIENTRYP PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); typedef GLuint (APIENTRYP PFNGLGENSYMBOLSEXTPROC) (GLenum datatype, GLenum storagetype, GLenum range, GLuint components); typedef void (APIENTRYP PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr); typedef void (APIENTRYP PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr); typedef void (APIENTRYP PFNGLVARIANTBVEXTPROC) (GLuint id, const GLbyte *addr); typedef void (APIENTRYP PFNGLVARIANTSVEXTPROC) (GLuint id, const GLshort *addr); typedef void (APIENTRYP PFNGLVARIANTIVEXTPROC) (GLuint id, const GLint *addr); typedef void (APIENTRYP PFNGLVARIANTFVEXTPROC) (GLuint id, const GLfloat *addr); typedef void (APIENTRYP PFNGLVARIANTDVEXTPROC) (GLuint id, const GLdouble *addr); typedef void (APIENTRYP PFNGLVARIANTUBVEXTPROC) (GLuint id, const GLubyte *addr); typedef void (APIENTRYP PFNGLVARIANTUSVEXTPROC) (GLuint id, const GLushort *addr); typedef void (APIENTRYP PFNGLVARIANTUIVEXTPROC) (GLuint id, const GLuint *addr); typedef void (APIENTRYP PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, const GLvoid *addr); typedef void (APIENTRYP PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); typedef void (APIENTRYP PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); typedef GLuint (APIENTRYP PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value); typedef GLuint (APIENTRYP PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value); typedef GLuint (APIENTRYP PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value); typedef GLuint (APIENTRYP PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value); typedef GLuint (APIENTRYP PFNGLBINDPARAMETEREXTPROC) (GLenum value); typedef GLboolean (APIENTRYP PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap); typedef void (APIENTRYP PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); typedef void (APIENTRYP PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); typedef void (APIENTRYP PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); typedef void (APIENTRYP PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, GLvoid* *data); typedef void (APIENTRYP PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); typedef void (APIENTRYP PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); typedef void (APIENTRYP PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); typedef void (APIENTRYP PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); typedef void (APIENTRYP PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); typedef void (APIENTRYP PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); #endif #ifndef GL_ATI_vertex_streams #define GL_ATI_vertex_streams 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexStream1sATI (GLenum stream, GLshort x); GLAPI void APIENTRY glVertexStream1svATI (GLenum stream, const GLshort *coords); GLAPI void APIENTRY glVertexStream1iATI (GLenum stream, GLint x); GLAPI void APIENTRY glVertexStream1ivATI (GLenum stream, const GLint *coords); GLAPI void APIENTRY glVertexStream1fATI (GLenum stream, GLfloat x); GLAPI void APIENTRY glVertexStream1fvATI (GLenum stream, const GLfloat *coords); GLAPI void APIENTRY glVertexStream1dATI (GLenum stream, GLdouble x); GLAPI void APIENTRY glVertexStream1dvATI (GLenum stream, const GLdouble *coords); GLAPI void APIENTRY glVertexStream2sATI (GLenum stream, GLshort x, GLshort y); GLAPI void APIENTRY glVertexStream2svATI (GLenum stream, const GLshort *coords); GLAPI void APIENTRY glVertexStream2iATI (GLenum stream, GLint x, GLint y); GLAPI void APIENTRY glVertexStream2ivATI (GLenum stream, const GLint *coords); GLAPI void APIENTRY glVertexStream2fATI (GLenum stream, GLfloat x, GLfloat y); GLAPI void APIENTRY glVertexStream2fvATI (GLenum stream, const GLfloat *coords); GLAPI void APIENTRY glVertexStream2dATI (GLenum stream, GLdouble x, GLdouble y); GLAPI void APIENTRY glVertexStream2dvATI (GLenum stream, const GLdouble *coords); GLAPI void APIENTRY glVertexStream3sATI (GLenum stream, GLshort x, GLshort y, GLshort z); GLAPI void APIENTRY glVertexStream3svATI (GLenum stream, const GLshort *coords); GLAPI void APIENTRY glVertexStream3iATI (GLenum stream, GLint x, GLint y, GLint z); GLAPI void APIENTRY glVertexStream3ivATI (GLenum stream, const GLint *coords); GLAPI void APIENTRY glVertexStream3fATI (GLenum stream, GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glVertexStream3fvATI (GLenum stream, const GLfloat *coords); GLAPI void APIENTRY glVertexStream3dATI (GLenum stream, GLdouble x, GLdouble y, GLdouble z); GLAPI void APIENTRY glVertexStream3dvATI (GLenum stream, const GLdouble *coords); GLAPI void APIENTRY glVertexStream4sATI (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); GLAPI void APIENTRY glVertexStream4svATI (GLenum stream, const GLshort *coords); GLAPI void APIENTRY glVertexStream4iATI (GLenum stream, GLint x, GLint y, GLint z, GLint w); GLAPI void APIENTRY glVertexStream4ivATI (GLenum stream, const GLint *coords); GLAPI void APIENTRY glVertexStream4fATI (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); GLAPI void APIENTRY glVertexStream4fvATI (GLenum stream, const GLfloat *coords); GLAPI void APIENTRY glVertexStream4dATI (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); GLAPI void APIENTRY glVertexStream4dvATI (GLenum stream, const GLdouble *coords); GLAPI void APIENTRY glNormalStream3bATI (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); GLAPI void APIENTRY glNormalStream3bvATI (GLenum stream, const GLbyte *coords); GLAPI void APIENTRY glNormalStream3sATI (GLenum stream, GLshort nx, GLshort ny, GLshort nz); GLAPI void APIENTRY glNormalStream3svATI (GLenum stream, const GLshort *coords); GLAPI void APIENTRY glNormalStream3iATI (GLenum stream, GLint nx, GLint ny, GLint nz); GLAPI void APIENTRY glNormalStream3ivATI (GLenum stream, const GLint *coords); GLAPI void APIENTRY glNormalStream3fATI (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); GLAPI void APIENTRY glNormalStream3fvATI (GLenum stream, const GLfloat *coords); GLAPI void APIENTRY glNormalStream3dATI (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); GLAPI void APIENTRY glNormalStream3dvATI (GLenum stream, const GLdouble *coords); GLAPI void APIENTRY glClientActiveVertexStreamATI (GLenum stream); GLAPI void APIENTRY glVertexBlendEnviATI (GLenum pname, GLint param); GLAPI void APIENTRY glVertexBlendEnvfATI (GLenum pname, GLfloat param); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x); typedef void (APIENTRYP PFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x); typedef void (APIENTRYP PFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x); typedef void (APIENTRYP PFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x); typedef void (APIENTRYP PFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); typedef void (APIENTRYP PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); typedef void (APIENTRYP PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); typedef void (APIENTRYP PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); typedef void (APIENTRYP PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); typedef void (APIENTRYP PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); typedef void (APIENTRYP PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords); typedef void (APIENTRYP PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); typedef void (APIENTRYP PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *coords); typedef void (APIENTRYP PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort nx, GLshort ny, GLshort nz); typedef void (APIENTRYP PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); typedef void (APIENTRYP PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint nx, GLint ny, GLint nz); typedef void (APIENTRYP PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); typedef void (APIENTRYP PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); typedef void (APIENTRYP PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); typedef void (APIENTRYP PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); typedef void (APIENTRYP PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); typedef void (APIENTRYP PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream); typedef void (APIENTRYP PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); #endif #ifndef GL_ATI_element_array #define GL_ATI_element_array 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glElementPointerATI (GLenum type, const GLvoid *pointer); GLAPI void APIENTRY glDrawElementArrayATI (GLenum mode, GLsizei count); GLAPI void APIENTRY glDrawRangeElementArrayATI (GLenum mode, GLuint start, GLuint end, GLsizei count); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLELEMENTPOINTERATIPROC) (GLenum type, const GLvoid *pointer); typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count); typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count); #endif #ifndef GL_SUN_mesh_array #define GL_SUN_mesh_array 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawMeshArraysSUN (GLenum mode, GLint first, GLsizei count, GLsizei width); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDRAWMESHARRAYSSUNPROC) (GLenum mode, GLint first, GLsizei count, GLsizei width); #endif #ifndef GL_SUN_slice_accum #define GL_SUN_slice_accum 1 #endif #ifndef GL_NV_multisample_filter_hint #define GL_NV_multisample_filter_hint 1 #endif #ifndef GL_NV_depth_clamp #define GL_NV_depth_clamp 1 #endif #ifndef GL_NV_occlusion_query #define GL_NV_occlusion_query 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGenOcclusionQueriesNV (GLsizei n, GLuint *ids); GLAPI void APIENTRY glDeleteOcclusionQueriesNV (GLsizei n, const GLuint *ids); GLAPI GLboolean APIENTRY glIsOcclusionQueryNV (GLuint id); GLAPI void APIENTRY glBeginOcclusionQueryNV (GLuint id); GLAPI void APIENTRY glEndOcclusionQueryNV (void); GLAPI void APIENTRY glGetOcclusionQueryivNV (GLuint id, GLenum pname, GLint *params); GLAPI void APIENTRY glGetOcclusionQueryuivNV (GLuint id, GLenum pname, GLuint *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint *ids); typedef void (APIENTRYP PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint *ids); typedef GLboolean (APIENTRYP PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); typedef void (APIENTRYP PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); typedef void (APIENTRYP PFNGLENDOCCLUSIONQUERYNVPROC) (void); typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint *params); #endif #ifndef GL_NV_point_sprite #define GL_NV_point_sprite 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPointParameteriNV (GLenum pname, GLint param); GLAPI void APIENTRY glPointParameterivNV (GLenum pname, const GLint *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint *params); #endif #ifndef GL_NV_texture_shader3 #define GL_NV_texture_shader3 1 #endif #ifndef GL_NV_vertex_program1_1 #define GL_NV_vertex_program1_1 1 #endif #ifndef GL_EXT_shadow_funcs #define GL_EXT_shadow_funcs 1 #endif #ifndef GL_EXT_stencil_two_side #define GL_EXT_stencil_two_side 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glActiveStencilFaceEXT (GLenum face); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); #endif #ifndef GL_ATI_text_fragment_shader #define GL_ATI_text_fragment_shader 1 #endif #ifndef GL_APPLE_client_storage #define GL_APPLE_client_storage 1 #endif #ifndef GL_APPLE_element_array #define GL_APPLE_element_array 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glElementPointerAPPLE (GLenum type, const GLvoid *pointer); GLAPI void APIENTRY glDrawElementArrayAPPLE (GLenum mode, GLint first, GLsizei count); GLAPI void APIENTRY glDrawRangeElementArrayAPPLE (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); GLAPI void APIENTRY glMultiDrawElementArrayAPPLE (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); GLAPI void APIENTRY glMultiDrawRangeElementArrayAPPLE (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const GLvoid *pointer); typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); typedef void (APIENTRYP PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); #endif #ifndef GL_APPLE_fence #define GL_APPLE_fence 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGenFencesAPPLE (GLsizei n, GLuint *fences); GLAPI void APIENTRY glDeleteFencesAPPLE (GLsizei n, const GLuint *fences); GLAPI void APIENTRY glSetFenceAPPLE (GLuint fence); GLAPI GLboolean APIENTRY glIsFenceAPPLE (GLuint fence); GLAPI GLboolean APIENTRY glTestFenceAPPLE (GLuint fence); GLAPI void APIENTRY glFinishFenceAPPLE (GLuint fence); GLAPI GLboolean APIENTRY glTestObjectAPPLE (GLenum object, GLuint name); GLAPI void APIENTRY glFinishObjectAPPLE (GLenum object, GLint name); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint *fences); typedef void (APIENTRYP PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint *fences); typedef void (APIENTRYP PFNGLSETFENCEAPPLEPROC) (GLuint fence); typedef GLboolean (APIENTRYP PFNGLISFENCEAPPLEPROC) (GLuint fence); typedef GLboolean (APIENTRYP PFNGLTESTFENCEAPPLEPROC) (GLuint fence); typedef void (APIENTRYP PFNGLFINISHFENCEAPPLEPROC) (GLuint fence); typedef GLboolean (APIENTRYP PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); typedef void (APIENTRYP PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); #endif #ifndef GL_APPLE_vertex_array_object #define GL_APPLE_vertex_array_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBindVertexArrayAPPLE (GLuint array); GLAPI void APIENTRY glDeleteVertexArraysAPPLE (GLsizei n, const GLuint *arrays); GLAPI void APIENTRY glGenVertexArraysAPPLE (GLsizei n, GLuint *arrays); GLAPI GLboolean APIENTRY glIsVertexArrayAPPLE (GLuint array); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays); typedef void (APIENTRYP PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, GLuint *arrays); typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); #endif #ifndef GL_APPLE_vertex_array_range #define GL_APPLE_vertex_array_range 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexArrayRangeAPPLE (GLsizei length, GLvoid *pointer); GLAPI void APIENTRY glFlushVertexArrayRangeAPPLE (GLsizei length, GLvoid *pointer); GLAPI void APIENTRY glVertexArrayParameteriAPPLE (GLenum pname, GLint param); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer); typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer); typedef void (APIENTRYP PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); #endif #ifndef GL_APPLE_ycbcr_422 #define GL_APPLE_ycbcr_422 1 #endif #ifndef GL_S3_s3tc #define GL_S3_s3tc 1 #endif #ifndef GL_ATI_draw_buffers #define GL_ATI_draw_buffers 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawBuffersATI (GLsizei n, const GLenum *bufs); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum *bufs); #endif #ifndef GL_ATI_pixel_format_float #define GL_ATI_pixel_format_float 1 /* This is really a WGL extension, but defines some associated GL enums. * ATI does not export "GL_ATI_pixel_format_float" in the GL_EXTENSIONS string. */ #endif #ifndef GL_ATI_texture_env_combine3 #define GL_ATI_texture_env_combine3 1 #endif #ifndef GL_ATI_texture_float #define GL_ATI_texture_float 1 #endif #ifndef GL_NV_float_buffer #define GL_NV_float_buffer 1 #endif #ifndef GL_NV_fragment_program #define GL_NV_fragment_program 1 /* Some NV_fragment_program entry points are shared with ARB_vertex_program. */ #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glProgramNamedParameter4fNV (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); GLAPI void APIENTRY glProgramNamedParameter4dNV (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); GLAPI void APIENTRY glProgramNamedParameter4fvNV (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v); GLAPI void APIENTRY glProgramNamedParameter4dvNV (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v); GLAPI void APIENTRY glGetProgramNamedParameterfvNV (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params); GLAPI void APIENTRY glGetProgramNamedParameterdvNV (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v); typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v); typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params); typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params); #endif #ifndef GL_NV_half_float #define GL_NV_half_float 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertex2hNV (GLhalfNV x, GLhalfNV y); GLAPI void APIENTRY glVertex2hvNV (const GLhalfNV *v); GLAPI void APIENTRY glVertex3hNV (GLhalfNV x, GLhalfNV y, GLhalfNV z); GLAPI void APIENTRY glVertex3hvNV (const GLhalfNV *v); GLAPI void APIENTRY glVertex4hNV (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); GLAPI void APIENTRY glVertex4hvNV (const GLhalfNV *v); GLAPI void APIENTRY glNormal3hNV (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); GLAPI void APIENTRY glNormal3hvNV (const GLhalfNV *v); GLAPI void APIENTRY glColor3hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue); GLAPI void APIENTRY glColor3hvNV (const GLhalfNV *v); GLAPI void APIENTRY glColor4hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); GLAPI void APIENTRY glColor4hvNV (const GLhalfNV *v); GLAPI void APIENTRY glTexCoord1hNV (GLhalfNV s); GLAPI void APIENTRY glTexCoord1hvNV (const GLhalfNV *v); GLAPI void APIENTRY glTexCoord2hNV (GLhalfNV s, GLhalfNV t); GLAPI void APIENTRY glTexCoord2hvNV (const GLhalfNV *v); GLAPI void APIENTRY glTexCoord3hNV (GLhalfNV s, GLhalfNV t, GLhalfNV r); GLAPI void APIENTRY glTexCoord3hvNV (const GLhalfNV *v); GLAPI void APIENTRY glTexCoord4hNV (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); GLAPI void APIENTRY glTexCoord4hvNV (const GLhalfNV *v); GLAPI void APIENTRY glMultiTexCoord1hNV (GLenum target, GLhalfNV s); GLAPI void APIENTRY glMultiTexCoord1hvNV (GLenum target, const GLhalfNV *v); GLAPI void APIENTRY glMultiTexCoord2hNV (GLenum target, GLhalfNV s, GLhalfNV t); GLAPI void APIENTRY glMultiTexCoord2hvNV (GLenum target, const GLhalfNV *v); GLAPI void APIENTRY glMultiTexCoord3hNV (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); GLAPI void APIENTRY glMultiTexCoord3hvNV (GLenum target, const GLhalfNV *v); GLAPI void APIENTRY glMultiTexCoord4hNV (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); GLAPI void APIENTRY glMultiTexCoord4hvNV (GLenum target, const GLhalfNV *v); GLAPI void APIENTRY glFogCoordhNV (GLhalfNV fog); GLAPI void APIENTRY glFogCoordhvNV (const GLhalfNV *fog); GLAPI void APIENTRY glSecondaryColor3hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue); GLAPI void APIENTRY glSecondaryColor3hvNV (const GLhalfNV *v); GLAPI void APIENTRY glVertexWeighthNV (GLhalfNV weight); GLAPI void APIENTRY glVertexWeighthvNV (const GLhalfNV *weight); GLAPI void APIENTRY glVertexAttrib1hNV (GLuint index, GLhalfNV x); GLAPI void APIENTRY glVertexAttrib1hvNV (GLuint index, const GLhalfNV *v); GLAPI void APIENTRY glVertexAttrib2hNV (GLuint index, GLhalfNV x, GLhalfNV y); GLAPI void APIENTRY glVertexAttrib2hvNV (GLuint index, const GLhalfNV *v); GLAPI void APIENTRY glVertexAttrib3hNV (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); GLAPI void APIENTRY glVertexAttrib3hvNV (GLuint index, const GLhalfNV *v); GLAPI void APIENTRY glVertexAttrib4hNV (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); GLAPI void APIENTRY glVertexAttrib4hvNV (GLuint index, const GLhalfNV *v); GLAPI void APIENTRY glVertexAttribs1hvNV (GLuint index, GLsizei n, const GLhalfNV *v); GLAPI void APIENTRY glVertexAttribs2hvNV (GLuint index, GLsizei n, const GLhalfNV *v); GLAPI void APIENTRY glVertexAttribs3hvNV (GLuint index, GLsizei n, const GLhalfNV *v); GLAPI void APIENTRY glVertexAttribs4hvNV (GLuint index, GLsizei n, const GLhalfNV *v); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEX2HNVPROC) (GLhalfNV x, GLhalfNV y); typedef void (APIENTRYP PFNGLVERTEX2HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEX3HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z); typedef void (APIENTRYP PFNGLVERTEX3HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEX4HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); typedef void (APIENTRYP PFNGLVERTEX4HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLNORMAL3HNVPROC) (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); typedef void (APIENTRYP PFNGLNORMAL3HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); typedef void (APIENTRYP PFNGLCOLOR3HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLCOLOR4HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); typedef void (APIENTRYP PFNGLCOLOR4HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLTEXCOORD1HNVPROC) (GLhalfNV s); typedef void (APIENTRYP PFNGLTEXCOORD1HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLTEXCOORD2HNVPROC) (GLhalfNV s, GLhalfNV t); typedef void (APIENTRYP PFNGLTEXCOORD2HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLTEXCOORD3HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r); typedef void (APIENTRYP PFNGLTEXCOORD3HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLTEXCOORD4HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); typedef void (APIENTRYP PFNGLTEXCOORD4HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalfNV s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalfNV *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalfNV *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalfNV *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalfNV *v); typedef void (APIENTRYP PFNGLFOGCOORDHNVPROC) (GLhalfNV fog); typedef void (APIENTRYP PFNGLFOGCOORDHVNVPROC) (const GLhalfNV *fog); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXWEIGHTHNVPROC) (GLhalfNV weight); typedef void (APIENTRYP PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalfNV *weight); typedef void (APIENTRYP PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalfNV x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); #endif #ifndef GL_NV_pixel_data_range #define GL_NV_pixel_data_range 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPixelDataRangeNV (GLenum target, GLsizei length, const GLvoid *pointer); GLAPI void APIENTRY glFlushPixelDataRangeNV (GLenum target); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, const GLvoid *pointer); typedef void (APIENTRYP PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); #endif #ifndef GL_NV_primitive_restart #define GL_NV_primitive_restart 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPrimitiveRestartNV (void); GLAPI void APIENTRY glPrimitiveRestartIndexNV (GLuint index); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPRIMITIVERESTARTNVPROC) (void); typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index); #endif #ifndef GL_NV_texture_expand_normal #define GL_NV_texture_expand_normal 1 #endif #ifndef GL_NV_vertex_program2 #define GL_NV_vertex_program2 1 #endif #ifndef GL_ATI_map_object_buffer #define GL_ATI_map_object_buffer 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLvoid* APIENTRY glMapObjectBufferATI (GLuint buffer); GLAPI void APIENTRY glUnmapObjectBufferATI (GLuint buffer); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLvoid* (APIENTRYP PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer); typedef void (APIENTRYP PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer); #endif #ifndef GL_ATI_separate_stencil #define GL_ATI_separate_stencil 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glStencilOpSeparateATI (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); GLAPI void APIENTRY glStencilFuncSeparateATI (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); #endif #ifndef GL_ATI_vertex_attrib_array_object #define GL_ATI_vertex_attrib_array_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexAttribArrayObjectATI (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); GLAPI void APIENTRY glGetVertexAttribArrayObjectfvATI (GLuint index, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetVertexAttribArrayObjectivATI (GLuint index, GLenum pname, GLint *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint *params); #endif #ifndef GL_OES_read_format #define GL_OES_read_format 1 #endif #ifndef GL_EXT_depth_bounds_test #define GL_EXT_depth_bounds_test 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDepthBoundsEXT (GLclampd zmin, GLclampd zmax); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax); #endif #ifndef GL_EXT_texture_mirror_clamp #define GL_EXT_texture_mirror_clamp 1 #endif #ifndef GL_EXT_blend_equation_separate #define GL_EXT_blend_equation_separate 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendEquationSeparateEXT (GLenum modeRGB, GLenum modeAlpha); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha); #endif #ifndef GL_MESA_pack_invert #define GL_MESA_pack_invert 1 #endif #ifndef GL_MESA_ycbcr_texture #define GL_MESA_ycbcr_texture 1 #endif #ifndef GL_EXT_pixel_buffer_object #define GL_EXT_pixel_buffer_object 1 #endif #ifndef GL_NV_fragment_program_option #define GL_NV_fragment_program_option 1 #endif #ifndef GL_NV_fragment_program2 #define GL_NV_fragment_program2 1 #endif #ifndef GL_NV_vertex_program2_option #define GL_NV_vertex_program2_option 1 #endif #ifndef GL_NV_vertex_program3 #define GL_NV_vertex_program3 1 #endif #ifndef GL_EXT_framebuffer_object #define GL_EXT_framebuffer_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLboolean APIENTRY glIsRenderbufferEXT (GLuint renderbuffer); GLAPI void APIENTRY glBindRenderbufferEXT (GLenum target, GLuint renderbuffer); GLAPI void APIENTRY glDeleteRenderbuffersEXT (GLsizei n, const GLuint *renderbuffers); GLAPI void APIENTRY glGenRenderbuffersEXT (GLsizei n, GLuint *renderbuffers); GLAPI void APIENTRY glRenderbufferStorageEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); GLAPI void APIENTRY glGetRenderbufferParameterivEXT (GLenum target, GLenum pname, GLint *params); GLAPI GLboolean APIENTRY glIsFramebufferEXT (GLuint framebuffer); GLAPI void APIENTRY glBindFramebufferEXT (GLenum target, GLuint framebuffer); GLAPI void APIENTRY glDeleteFramebuffersEXT (GLsizei n, const GLuint *framebuffers); GLAPI void APIENTRY glGenFramebuffersEXT (GLsizei n, GLuint *framebuffers); GLAPI GLenum APIENTRY glCheckFramebufferStatusEXT (GLenum target); GLAPI void APIENTRY glFramebufferTexture1DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); GLAPI void APIENTRY glFramebufferTexture2DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); GLAPI void APIENTRY glFramebufferTexture3DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); GLAPI void APIENTRY glFramebufferRenderbufferEXT (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); GLAPI void APIENTRY glGetFramebufferAttachmentParameterivEXT (GLenum target, GLenum attachment, GLenum pname, GLint *params); GLAPI void APIENTRY glGenerateMipmapEXT (GLenum target); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers); typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers); typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers); typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers); typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGENERATEMIPMAPEXTPROC) (GLenum target); #endif #ifndef GL_GREMEDY_string_marker #define GL_GREMEDY_string_marker 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glStringMarkerGREMEDY (GLsizei len, const GLvoid *string); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const GLvoid *string); #endif #ifndef GL_EXT_packed_depth_stencil #define GL_EXT_packed_depth_stencil 1 #endif #ifndef GL_EXT_stencil_clear_tag #define GL_EXT_stencil_clear_tag 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glStencilClearTagEXT (GLsizei stencilTagBits, GLuint stencilClearTag); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSTENCILCLEARTAGEXTPROC) (GLsizei stencilTagBits, GLuint stencilClearTag); #endif #ifndef GL_EXT_texture_sRGB #define GL_EXT_texture_sRGB 1 #endif #ifndef GL_EXT_framebuffer_blit #define GL_EXT_framebuffer_blit 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); #endif #ifndef GL_EXT_framebuffer_multisample #define GL_EXT_framebuffer_multisample 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); #endif #ifndef GL_MESAX_texture_stack #define GL_MESAX_texture_stack 1 #endif #ifndef GL_EXT_timer_query #define GL_EXT_timer_query 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetQueryObjecti64vEXT (GLuint id, GLenum pname, GLint64EXT *params); GLAPI void APIENTRY glGetQueryObjectui64vEXT (GLuint id, GLenum pname, GLuint64EXT *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64EXT *params); typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64EXT *params); #endif #ifndef GL_EXT_gpu_program_parameters #define GL_EXT_gpu_program_parameters 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glProgramEnvParameters4fvEXT (GLenum target, GLuint index, GLsizei count, const GLfloat *params); GLAPI void APIENTRY glProgramLocalParameters4fvEXT (GLenum target, GLuint index, GLsizei count, const GLfloat *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params); typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params); #endif #ifndef GL_APPLE_flush_buffer_range #define GL_APPLE_flush_buffer_range 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBufferParameteriAPPLE (GLenum target, GLenum pname, GLint param); GLAPI void APIENTRY glFlushMappedBufferRangeAPPLE (GLenum target, GLintptr offset, GLsizeiptr size); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size); #endif #ifndef GL_NV_gpu_program4 #define GL_NV_gpu_program4 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glProgramLocalParameterI4iNV (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); GLAPI void APIENTRY glProgramLocalParameterI4ivNV (GLenum target, GLuint index, const GLint *params); GLAPI void APIENTRY glProgramLocalParametersI4ivNV (GLenum target, GLuint index, GLsizei count, const GLint *params); GLAPI void APIENTRY glProgramLocalParameterI4uiNV (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); GLAPI void APIENTRY glProgramLocalParameterI4uivNV (GLenum target, GLuint index, const GLuint *params); GLAPI void APIENTRY glProgramLocalParametersI4uivNV (GLenum target, GLuint index, GLsizei count, const GLuint *params); GLAPI void APIENTRY glProgramEnvParameterI4iNV (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); GLAPI void APIENTRY glProgramEnvParameterI4ivNV (GLenum target, GLuint index, const GLint *params); GLAPI void APIENTRY glProgramEnvParametersI4ivNV (GLenum target, GLuint index, GLsizei count, const GLint *params); GLAPI void APIENTRY glProgramEnvParameterI4uiNV (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); GLAPI void APIENTRY glProgramEnvParameterI4uivNV (GLenum target, GLuint index, const GLuint *params); GLAPI void APIENTRY glProgramEnvParametersI4uivNV (GLenum target, GLuint index, GLsizei count, const GLuint *params); GLAPI void APIENTRY glGetProgramLocalParameterIivNV (GLenum target, GLuint index, GLint *params); GLAPI void APIENTRY glGetProgramLocalParameterIuivNV (GLenum target, GLuint index, GLuint *params); GLAPI void APIENTRY glGetProgramEnvParameterIivNV (GLenum target, GLuint index, GLint *params); GLAPI void APIENTRY glGetProgramEnvParameterIuivNV (GLenum target, GLuint index, GLuint *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); #endif #ifndef GL_NV_geometry_program4 #define GL_NV_geometry_program4 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glProgramVertexLimitNV (GLenum target, GLint limit); GLAPI void APIENTRY glFramebufferTextureEXT (GLenum target, GLenum attachment, GLuint texture, GLint level); GLAPI void APIENTRY glFramebufferTextureLayerEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); GLAPI void APIENTRY glFramebufferTextureFaceEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); #endif #ifndef GL_EXT_geometry_shader4 #define GL_EXT_geometry_shader4 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glProgramParameteriEXT (GLuint program, GLenum pname, GLint value); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); #endif #ifndef GL_NV_vertex_program4 #define GL_NV_vertex_program4 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexAttribI1iEXT (GLuint index, GLint x); GLAPI void APIENTRY glVertexAttribI2iEXT (GLuint index, GLint x, GLint y); GLAPI void APIENTRY glVertexAttribI3iEXT (GLuint index, GLint x, GLint y, GLint z); GLAPI void APIENTRY glVertexAttribI4iEXT (GLuint index, GLint x, GLint y, GLint z, GLint w); GLAPI void APIENTRY glVertexAttribI1uiEXT (GLuint index, GLuint x); GLAPI void APIENTRY glVertexAttribI2uiEXT (GLuint index, GLuint x, GLuint y); GLAPI void APIENTRY glVertexAttribI3uiEXT (GLuint index, GLuint x, GLuint y, GLuint z); GLAPI void APIENTRY glVertexAttribI4uiEXT (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); GLAPI void APIENTRY glVertexAttribI1ivEXT (GLuint index, const GLint *v); GLAPI void APIENTRY glVertexAttribI2ivEXT (GLuint index, const GLint *v); GLAPI void APIENTRY glVertexAttribI3ivEXT (GLuint index, const GLint *v); GLAPI void APIENTRY glVertexAttribI4ivEXT (GLuint index, const GLint *v); GLAPI void APIENTRY glVertexAttribI1uivEXT (GLuint index, const GLuint *v); GLAPI void APIENTRY glVertexAttribI2uivEXT (GLuint index, const GLuint *v); GLAPI void APIENTRY glVertexAttribI3uivEXT (GLuint index, const GLuint *v); GLAPI void APIENTRY glVertexAttribI4uivEXT (GLuint index, const GLuint *v); GLAPI void APIENTRY glVertexAttribI4bvEXT (GLuint index, const GLbyte *v); GLAPI void APIENTRY glVertexAttribI4svEXT (GLuint index, const GLshort *v); GLAPI void APIENTRY glVertexAttribI4ubvEXT (GLuint index, const GLubyte *v); GLAPI void APIENTRY glVertexAttribI4usvEXT (GLuint index, const GLushort *v); GLAPI void APIENTRY glVertexAttribIPointerEXT (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); GLAPI void APIENTRY glGetVertexAttribIivEXT (GLuint index, GLenum pname, GLint *params); GLAPI void APIENTRY glGetVertexAttribIuivEXT (GLuint index, GLenum pname, GLuint *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x); typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y); typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x); typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y); typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params); #endif #ifndef GL_EXT_gpu_shader4 #define GL_EXT_gpu_shader4 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetUniformuivEXT (GLuint program, GLint location, GLuint *params); GLAPI void APIENTRY glBindFragDataLocationEXT (GLuint program, GLuint color, const GLchar *name); GLAPI GLint APIENTRY glGetFragDataLocationEXT (GLuint program, const GLchar *name); GLAPI void APIENTRY glUniform1uiEXT (GLint location, GLuint v0); GLAPI void APIENTRY glUniform2uiEXT (GLint location, GLuint v0, GLuint v1); GLAPI void APIENTRY glUniform3uiEXT (GLint location, GLuint v0, GLuint v1, GLuint v2); GLAPI void APIENTRY glUniform4uiEXT (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); GLAPI void APIENTRY glUniform1uivEXT (GLint location, GLsizei count, const GLuint *value); GLAPI void APIENTRY glUniform2uivEXT (GLint location, GLsizei count, const GLuint *value); GLAPI void APIENTRY glUniform3uivEXT (GLint location, GLsizei count, const GLuint *value); GLAPI void APIENTRY glUniform4uivEXT (GLint location, GLsizei count, const GLuint *value); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params); typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name); typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name); typedef void (APIENTRYP PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0); typedef void (APIENTRYP PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1); typedef void (APIENTRYP PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); typedef void (APIENTRYP PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); typedef void (APIENTRYP PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); #endif #ifndef GL_EXT_draw_instanced #define GL_EXT_draw_instanced 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count, GLsizei primcount); GLAPI void APIENTRY glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); #endif #ifndef GL_EXT_packed_float #define GL_EXT_packed_float 1 #endif #ifndef GL_EXT_texture_array #define GL_EXT_texture_array 1 #endif #ifndef GL_EXT_texture_buffer_object #define GL_EXT_texture_buffer_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTexBufferEXT (GLenum target, GLenum internalformat, GLuint buffer); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer); #endif #ifndef GL_EXT_texture_compression_latc #define GL_EXT_texture_compression_latc 1 #endif #ifndef GL_EXT_texture_compression_rgtc #define GL_EXT_texture_compression_rgtc 1 #endif #ifndef GL_EXT_texture_shared_exponent #define GL_EXT_texture_shared_exponent 1 #endif #ifndef GL_NV_depth_buffer_float #define GL_NV_depth_buffer_float 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDepthRangedNV (GLdouble zNear, GLdouble zFar); GLAPI void APIENTRY glClearDepthdNV (GLdouble depth); GLAPI void APIENTRY glDepthBoundsdNV (GLdouble zmin, GLdouble zmax); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar); typedef void (APIENTRYP PFNGLCLEARDEPTHDNVPROC) (GLdouble depth); typedef void (APIENTRYP PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax); #endif #ifndef GL_NV_fragment_program4 #define GL_NV_fragment_program4 1 #endif #ifndef GL_NV_framebuffer_multisample_coverage #define GL_NV_framebuffer_multisample_coverage 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glRenderbufferStorageMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); #endif #ifndef GL_EXT_framebuffer_sRGB #define GL_EXT_framebuffer_sRGB 1 #endif #ifndef GL_NV_geometry_shader4 #define GL_NV_geometry_shader4 1 #endif #ifndef GL_NV_parameter_buffer_object #define GL_NV_parameter_buffer_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glProgramBufferParametersfvNV (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params); GLAPI void APIENTRY glProgramBufferParametersIivNV (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params); GLAPI void APIENTRY glProgramBufferParametersIuivNV (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params); typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params); typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params); #endif #ifndef GL_EXT_draw_buffers2 #define GL_EXT_draw_buffers2 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glColorMaskIndexedEXT (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); GLAPI void APIENTRY glGetBooleanIndexedvEXT (GLenum target, GLuint index, GLboolean *data); GLAPI void APIENTRY glGetIntegerIndexedvEXT (GLenum target, GLuint index, GLint *data); GLAPI void APIENTRY glEnableIndexedEXT (GLenum target, GLuint index); GLAPI void APIENTRY glDisableIndexedEXT (GLenum target, GLuint index); GLAPI GLboolean APIENTRY glIsEnabledIndexedEXT (GLenum target, GLuint index); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); typedef void (APIENTRYP PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum target, GLuint index, GLboolean *data); typedef void (APIENTRYP PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLint *data); typedef void (APIENTRYP PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index); typedef void (APIENTRYP PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index); typedef GLboolean (APIENTRYP PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index); #endif #ifndef GL_NV_transform_feedback #define GL_NV_transform_feedback 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBeginTransformFeedbackNV (GLenum primitiveMode); GLAPI void APIENTRY glEndTransformFeedbackNV (void); GLAPI void APIENTRY glTransformFeedbackAttribsNV (GLuint count, const GLint *attribs, GLenum bufferMode); GLAPI void APIENTRY glBindBufferRangeNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); GLAPI void APIENTRY glBindBufferOffsetNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset); GLAPI void APIENTRY glBindBufferBaseNV (GLenum target, GLuint index, GLuint buffer); GLAPI void APIENTRY glTransformFeedbackVaryingsNV (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); GLAPI void APIENTRY glActiveVaryingNV (GLuint program, const GLchar *name); GLAPI GLint APIENTRY glGetVaryingLocationNV (GLuint program, const GLchar *name); GLAPI void APIENTRY glGetActiveVaryingNV (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); GLAPI void APIENTRY glGetTransformFeedbackVaryingNV (GLuint program, GLuint index, GLint *location); GLAPI void APIENTRY glTransformFeedbackStreamAttribsNV (GLsizei count, const GLint *attribs, GLsizei nbuffers, const GLint *bufstreams, GLenum bufferMode); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode); typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKNVPROC) (void); typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode); typedef void (APIENTRYP PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); typedef void (APIENTRYP PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer); typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); typedef void (APIENTRYP PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name); typedef GLint (APIENTRYP PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name); typedef void (APIENTRYP PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location); typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC) (GLsizei count, const GLint *attribs, GLsizei nbuffers, const GLint *bufstreams, GLenum bufferMode); #endif #ifndef GL_EXT_bindable_uniform #define GL_EXT_bindable_uniform 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glUniformBufferEXT (GLuint program, GLint location, GLuint buffer); GLAPI GLint APIENTRY glGetUniformBufferSizeEXT (GLuint program, GLint location); GLAPI GLintptr APIENTRY glGetUniformOffsetEXT (GLuint program, GLint location); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer); typedef GLint (APIENTRYP PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location); typedef GLintptr (APIENTRYP PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location); #endif #ifndef GL_EXT_texture_integer #define GL_EXT_texture_integer 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTexParameterIivEXT (GLenum target, GLenum pname, const GLint *params); GLAPI void APIENTRY glTexParameterIuivEXT (GLenum target, GLenum pname, const GLuint *params); GLAPI void APIENTRY glGetTexParameterIivEXT (GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glGetTexParameterIuivEXT (GLenum target, GLenum pname, GLuint *params); GLAPI void APIENTRY glClearColorIiEXT (GLint red, GLint green, GLint blue, GLint alpha); GLAPI void APIENTRY glClearColorIuiEXT (GLuint red, GLuint green, GLuint blue, GLuint alpha); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params); typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params); typedef void (APIENTRYP PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha); typedef void (APIENTRYP PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha); #endif #ifndef GL_GREMEDY_frame_terminator #define GL_GREMEDY_frame_terminator 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFrameTerminatorGREMEDY (void); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLFRAMETERMINATORGREMEDYPROC) (void); #endif #ifndef GL_NV_conditional_render #define GL_NV_conditional_render 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBeginConditionalRenderNV (GLuint id, GLenum mode); GLAPI void APIENTRY glEndConditionalRenderNV (void); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode); typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERNVPROC) (void); #endif #ifndef GL_NV_present_video #define GL_NV_present_video 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPresentFrameKeyedNV (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1); GLAPI void APIENTRY glPresentFrameDualFillNV (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3); GLAPI void APIENTRY glGetVideoivNV (GLuint video_slot, GLenum pname, GLint *params); GLAPI void APIENTRY glGetVideouivNV (GLuint video_slot, GLenum pname, GLuint *params); GLAPI void APIENTRY glGetVideoi64vNV (GLuint video_slot, GLenum pname, GLint64EXT *params); GLAPI void APIENTRY glGetVideoui64vNV (GLuint video_slot, GLenum pname, GLuint64EXT *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPRESENTFRAMEKEYEDNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1); typedef void (APIENTRYP PFNGLPRESENTFRAMEDUALFILLNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3); typedef void (APIENTRYP PFNGLGETVIDEOIVNVPROC) (GLuint video_slot, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETVIDEOUIVNVPROC) (GLuint video_slot, GLenum pname, GLuint *params); typedef void (APIENTRYP PFNGLGETVIDEOI64VNVPROC) (GLuint video_slot, GLenum pname, GLint64EXT *params); typedef void (APIENTRYP PFNGLGETVIDEOUI64VNVPROC) (GLuint video_slot, GLenum pname, GLuint64EXT *params); #endif #ifndef GL_EXT_transform_feedback #define GL_EXT_transform_feedback 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBeginTransformFeedbackEXT (GLenum primitiveMode); GLAPI void APIENTRY glEndTransformFeedbackEXT (void); GLAPI void APIENTRY glBindBufferRangeEXT (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); GLAPI void APIENTRY glBindBufferOffsetEXT (GLenum target, GLuint index, GLuint buffer, GLintptr offset); GLAPI void APIENTRY glBindBufferBaseEXT (GLenum target, GLuint index, GLuint buffer); GLAPI void APIENTRY glTransformFeedbackVaryingsEXT (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode); GLAPI void APIENTRY glGetTransformFeedbackVaryingEXT (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKEXTPROC) (GLenum primitiveMode); typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKEXTPROC) (void); typedef void (APIENTRYP PFNGLBINDBUFFERRANGEEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); typedef void (APIENTRYP PFNGLBINDBUFFERBASEEXTPROC) (GLenum target, GLuint index, GLuint buffer); typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode); typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); #endif #ifndef GL_EXT_direct_state_access #define GL_EXT_direct_state_access 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glClientAttribDefaultEXT (GLbitfield mask); GLAPI void APIENTRY glPushClientAttribDefaultEXT (GLbitfield mask); GLAPI void APIENTRY glMatrixLoadfEXT (GLenum mode, const GLfloat *m); GLAPI void APIENTRY glMatrixLoaddEXT (GLenum mode, const GLdouble *m); GLAPI void APIENTRY glMatrixMultfEXT (GLenum mode, const GLfloat *m); GLAPI void APIENTRY glMatrixMultdEXT (GLenum mode, const GLdouble *m); GLAPI void APIENTRY glMatrixLoadIdentityEXT (GLenum mode); GLAPI void APIENTRY glMatrixRotatefEXT (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glMatrixRotatedEXT (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); GLAPI void APIENTRY glMatrixScalefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glMatrixScaledEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z); GLAPI void APIENTRY glMatrixTranslatefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glMatrixTranslatedEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z); GLAPI void APIENTRY glMatrixFrustumEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); GLAPI void APIENTRY glMatrixOrthoEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); GLAPI void APIENTRY glMatrixPopEXT (GLenum mode); GLAPI void APIENTRY glMatrixPushEXT (GLenum mode); GLAPI void APIENTRY glMatrixLoadTransposefEXT (GLenum mode, const GLfloat *m); GLAPI void APIENTRY glMatrixLoadTransposedEXT (GLenum mode, const GLdouble *m); GLAPI void APIENTRY glMatrixMultTransposefEXT (GLenum mode, const GLfloat *m); GLAPI void APIENTRY glMatrixMultTransposedEXT (GLenum mode, const GLdouble *m); GLAPI void APIENTRY glTextureParameterfEXT (GLuint texture, GLenum target, GLenum pname, GLfloat param); GLAPI void APIENTRY glTextureParameterfvEXT (GLuint texture, GLenum target, GLenum pname, const GLfloat *params); GLAPI void APIENTRY glTextureParameteriEXT (GLuint texture, GLenum target, GLenum pname, GLint param); GLAPI void APIENTRY glTextureParameterivEXT (GLuint texture, GLenum target, GLenum pname, const GLint *params); GLAPI void APIENTRY glTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); GLAPI void APIENTRY glTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); GLAPI void APIENTRY glTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); GLAPI void APIENTRY glTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); GLAPI void APIENTRY glCopyTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); GLAPI void APIENTRY glCopyTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); GLAPI void APIENTRY glCopyTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); GLAPI void APIENTRY glCopyTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); GLAPI void APIENTRY glGetTextureImageEXT (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); GLAPI void APIENTRY glGetTextureParameterfvEXT (GLuint texture, GLenum target, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetTextureParameterivEXT (GLuint texture, GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glGetTextureLevelParameterfvEXT (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetTextureLevelParameterivEXT (GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params); GLAPI void APIENTRY glTextureImage3DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); GLAPI void APIENTRY glTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); GLAPI void APIENTRY glCopyTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); GLAPI void APIENTRY glMultiTexParameterfEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat param); GLAPI void APIENTRY glMultiTexParameterfvEXT (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); GLAPI void APIENTRY glMultiTexParameteriEXT (GLenum texunit, GLenum target, GLenum pname, GLint param); GLAPI void APIENTRY glMultiTexParameterivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params); GLAPI void APIENTRY glMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); GLAPI void APIENTRY glMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); GLAPI void APIENTRY glMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); GLAPI void APIENTRY glMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); GLAPI void APIENTRY glCopyMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); GLAPI void APIENTRY glCopyMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); GLAPI void APIENTRY glCopyMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); GLAPI void APIENTRY glCopyMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); GLAPI void APIENTRY glGetMultiTexImageEXT (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); GLAPI void APIENTRY glGetMultiTexParameterfvEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetMultiTexParameterivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glGetMultiTexLevelParameterfvEXT (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetMultiTexLevelParameterivEXT (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params); GLAPI void APIENTRY glMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); GLAPI void APIENTRY glMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); GLAPI void APIENTRY glCopyMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); GLAPI void APIENTRY glBindMultiTextureEXT (GLenum texunit, GLenum target, GLuint texture); GLAPI void APIENTRY glEnableClientStateIndexedEXT (GLenum array, GLuint index); GLAPI void APIENTRY glDisableClientStateIndexedEXT (GLenum array, GLuint index); GLAPI void APIENTRY glMultiTexCoordPointerEXT (GLenum texunit, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); GLAPI void APIENTRY glMultiTexEnvfEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat param); GLAPI void APIENTRY glMultiTexEnvfvEXT (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); GLAPI void APIENTRY glMultiTexEnviEXT (GLenum texunit, GLenum target, GLenum pname, GLint param); GLAPI void APIENTRY glMultiTexEnvivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params); GLAPI void APIENTRY glMultiTexGendEXT (GLenum texunit, GLenum coord, GLenum pname, GLdouble param); GLAPI void APIENTRY glMultiTexGendvEXT (GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params); GLAPI void APIENTRY glMultiTexGenfEXT (GLenum texunit, GLenum coord, GLenum pname, GLfloat param); GLAPI void APIENTRY glMultiTexGenfvEXT (GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params); GLAPI void APIENTRY glMultiTexGeniEXT (GLenum texunit, GLenum coord, GLenum pname, GLint param); GLAPI void APIENTRY glMultiTexGenivEXT (GLenum texunit, GLenum coord, GLenum pname, const GLint *params); GLAPI void APIENTRY glGetMultiTexEnvfvEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetMultiTexEnvivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glGetMultiTexGendvEXT (GLenum texunit, GLenum coord, GLenum pname, GLdouble *params); GLAPI void APIENTRY glGetMultiTexGenfvEXT (GLenum texunit, GLenum coord, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetMultiTexGenivEXT (GLenum texunit, GLenum coord, GLenum pname, GLint *params); GLAPI void APIENTRY glGetFloatIndexedvEXT (GLenum target, GLuint index, GLfloat *data); GLAPI void APIENTRY glGetDoubleIndexedvEXT (GLenum target, GLuint index, GLdouble *data); GLAPI void APIENTRY glGetPointerIndexedvEXT (GLenum target, GLuint index, GLvoid* *data); GLAPI void APIENTRY glCompressedTextureImage3DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits); GLAPI void APIENTRY glCompressedTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits); GLAPI void APIENTRY glCompressedTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits); GLAPI void APIENTRY glCompressedTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits); GLAPI void APIENTRY glCompressedTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits); GLAPI void APIENTRY glCompressedTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits); GLAPI void APIENTRY glGetCompressedTextureImageEXT (GLuint texture, GLenum target, GLint lod, GLvoid *img); GLAPI void APIENTRY glCompressedMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits); GLAPI void APIENTRY glCompressedMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits); GLAPI void APIENTRY glCompressedMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits); GLAPI void APIENTRY glCompressedMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits); GLAPI void APIENTRY glCompressedMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits); GLAPI void APIENTRY glCompressedMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits); GLAPI void APIENTRY glGetCompressedMultiTexImageEXT (GLenum texunit, GLenum target, GLint lod, GLvoid *img); GLAPI void APIENTRY glNamedProgramStringEXT (GLuint program, GLenum target, GLenum format, GLsizei len, const GLvoid *string); GLAPI void APIENTRY glNamedProgramLocalParameter4dEXT (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); GLAPI void APIENTRY glNamedProgramLocalParameter4dvEXT (GLuint program, GLenum target, GLuint index, const GLdouble *params); GLAPI void APIENTRY glNamedProgramLocalParameter4fEXT (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); GLAPI void APIENTRY glNamedProgramLocalParameter4fvEXT (GLuint program, GLenum target, GLuint index, const GLfloat *params); GLAPI void APIENTRY glGetNamedProgramLocalParameterdvEXT (GLuint program, GLenum target, GLuint index, GLdouble *params); GLAPI void APIENTRY glGetNamedProgramLocalParameterfvEXT (GLuint program, GLenum target, GLuint index, GLfloat *params); GLAPI void APIENTRY glGetNamedProgramivEXT (GLuint program, GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glGetNamedProgramStringEXT (GLuint program, GLenum target, GLenum pname, GLvoid *string); GLAPI void APIENTRY glNamedProgramLocalParameters4fvEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params); GLAPI void APIENTRY glNamedProgramLocalParameterI4iEXT (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); GLAPI void APIENTRY glNamedProgramLocalParameterI4ivEXT (GLuint program, GLenum target, GLuint index, const GLint *params); GLAPI void APIENTRY glNamedProgramLocalParametersI4ivEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint *params); GLAPI void APIENTRY glNamedProgramLocalParameterI4uiEXT (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); GLAPI void APIENTRY glNamedProgramLocalParameterI4uivEXT (GLuint program, GLenum target, GLuint index, const GLuint *params); GLAPI void APIENTRY glNamedProgramLocalParametersI4uivEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint *params); GLAPI void APIENTRY glGetNamedProgramLocalParameterIivEXT (GLuint program, GLenum target, GLuint index, GLint *params); GLAPI void APIENTRY glGetNamedProgramLocalParameterIuivEXT (GLuint program, GLenum target, GLuint index, GLuint *params); GLAPI void APIENTRY glTextureParameterIivEXT (GLuint texture, GLenum target, GLenum pname, const GLint *params); GLAPI void APIENTRY glTextureParameterIuivEXT (GLuint texture, GLenum target, GLenum pname, const GLuint *params); GLAPI void APIENTRY glGetTextureParameterIivEXT (GLuint texture, GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glGetTextureParameterIuivEXT (GLuint texture, GLenum target, GLenum pname, GLuint *params); GLAPI void APIENTRY glMultiTexParameterIivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params); GLAPI void APIENTRY glMultiTexParameterIuivEXT (GLenum texunit, GLenum target, GLenum pname, const GLuint *params); GLAPI void APIENTRY glGetMultiTexParameterIivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glGetMultiTexParameterIuivEXT (GLenum texunit, GLenum target, GLenum pname, GLuint *params); GLAPI void APIENTRY glProgramUniform1fEXT (GLuint program, GLint location, GLfloat v0); GLAPI void APIENTRY glProgramUniform2fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1); GLAPI void APIENTRY glProgramUniform3fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); GLAPI void APIENTRY glProgramUniform4fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); GLAPI void APIENTRY glProgramUniform1iEXT (GLuint program, GLint location, GLint v0); GLAPI void APIENTRY glProgramUniform2iEXT (GLuint program, GLint location, GLint v0, GLint v1); GLAPI void APIENTRY glProgramUniform3iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); GLAPI void APIENTRY glProgramUniform4iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); GLAPI void APIENTRY glProgramUniform1fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); GLAPI void APIENTRY glProgramUniform2fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); GLAPI void APIENTRY glProgramUniform3fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); GLAPI void APIENTRY glProgramUniform4fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); GLAPI void APIENTRY glProgramUniform1ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); GLAPI void APIENTRY glProgramUniform2ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); GLAPI void APIENTRY glProgramUniform3ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); GLAPI void APIENTRY glProgramUniform4ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); GLAPI void APIENTRY glProgramUniformMatrix2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniformMatrix3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniformMatrix4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniformMatrix2x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniformMatrix3x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniformMatrix2x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniformMatrix4x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniformMatrix3x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniformMatrix4x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniform1uiEXT (GLuint program, GLint location, GLuint v0); GLAPI void APIENTRY glProgramUniform2uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1); GLAPI void APIENTRY glProgramUniform3uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); GLAPI void APIENTRY glProgramUniform4uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); GLAPI void APIENTRY glProgramUniform1uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); GLAPI void APIENTRY glProgramUniform2uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); GLAPI void APIENTRY glProgramUniform3uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); GLAPI void APIENTRY glProgramUniform4uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); GLAPI void APIENTRY glNamedBufferDataEXT (GLuint buffer, GLsizeiptr size, const GLvoid *data, GLenum usage); GLAPI void APIENTRY glNamedBufferSubDataEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, const GLvoid *data); GLAPI GLvoid* APIENTRY glMapNamedBufferEXT (GLuint buffer, GLenum access); GLAPI GLboolean APIENTRY glUnmapNamedBufferEXT (GLuint buffer); GLAPI GLvoid* APIENTRY glMapNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); GLAPI void APIENTRY glFlushMappedNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length); GLAPI void APIENTRY glNamedCopyBufferSubDataEXT (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); GLAPI void APIENTRY glGetNamedBufferParameterivEXT (GLuint buffer, GLenum pname, GLint *params); GLAPI void APIENTRY glGetNamedBufferPointervEXT (GLuint buffer, GLenum pname, GLvoid* *params); GLAPI void APIENTRY glGetNamedBufferSubDataEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, GLvoid *data); GLAPI void APIENTRY glTextureBufferEXT (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer); GLAPI void APIENTRY glMultiTexBufferEXT (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer); GLAPI void APIENTRY glNamedRenderbufferStorageEXT (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); GLAPI void APIENTRY glGetNamedRenderbufferParameterivEXT (GLuint renderbuffer, GLenum pname, GLint *params); GLAPI GLenum APIENTRY glCheckNamedFramebufferStatusEXT (GLuint framebuffer, GLenum target); GLAPI void APIENTRY glNamedFramebufferTexture1DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); GLAPI void APIENTRY glNamedFramebufferTexture2DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); GLAPI void APIENTRY glNamedFramebufferTexture3DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); GLAPI void APIENTRY glNamedFramebufferRenderbufferEXT (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); GLAPI void APIENTRY glGetNamedFramebufferAttachmentParameterivEXT (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); GLAPI void APIENTRY glGenerateTextureMipmapEXT (GLuint texture, GLenum target); GLAPI void APIENTRY glGenerateMultiTexMipmapEXT (GLenum texunit, GLenum target); GLAPI void APIENTRY glFramebufferDrawBufferEXT (GLuint framebuffer, GLenum mode); GLAPI void APIENTRY glFramebufferDrawBuffersEXT (GLuint framebuffer, GLsizei n, const GLenum *bufs); GLAPI void APIENTRY glFramebufferReadBufferEXT (GLuint framebuffer, GLenum mode); GLAPI void APIENTRY glGetFramebufferParameterivEXT (GLuint framebuffer, GLenum pname, GLint *params); GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleEXT (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleCoverageEXT (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); GLAPI void APIENTRY glNamedFramebufferTextureEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); GLAPI void APIENTRY glNamedFramebufferTextureLayerEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); GLAPI void APIENTRY glNamedFramebufferTextureFaceEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face); GLAPI void APIENTRY glTextureRenderbufferEXT (GLuint texture, GLenum target, GLuint renderbuffer); GLAPI void APIENTRY glMultiTexRenderbufferEXT (GLenum texunit, GLenum target, GLuint renderbuffer); GLAPI void APIENTRY glProgramUniform1dEXT (GLuint program, GLint location, GLdouble x); GLAPI void APIENTRY glProgramUniform2dEXT (GLuint program, GLint location, GLdouble x, GLdouble y); GLAPI void APIENTRY glProgramUniform3dEXT (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z); GLAPI void APIENTRY glProgramUniform4dEXT (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); GLAPI void APIENTRY glProgramUniform1dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); GLAPI void APIENTRY glProgramUniform2dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); GLAPI void APIENTRY glProgramUniform3dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); GLAPI void APIENTRY glProgramUniform4dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); GLAPI void APIENTRY glProgramUniformMatrix2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glProgramUniformMatrix3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glProgramUniformMatrix4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glProgramUniformMatrix2x3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glProgramUniformMatrix2x4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glProgramUniformMatrix3x2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glProgramUniformMatrix3x4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glProgramUniformMatrix4x2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glProgramUniformMatrix4x3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); typedef void (APIENTRYP PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); typedef void (APIENTRYP PFNGLMATRIXLOADFEXTPROC) (GLenum mode, const GLfloat *m); typedef void (APIENTRYP PFNGLMATRIXLOADDEXTPROC) (GLenum mode, const GLdouble *m); typedef void (APIENTRYP PFNGLMATRIXMULTFEXTPROC) (GLenum mode, const GLfloat *m); typedef void (APIENTRYP PFNGLMATRIXMULTDEXTPROC) (GLenum mode, const GLdouble *m); typedef void (APIENTRYP PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum mode); typedef void (APIENTRYP PFNGLMATRIXROTATEFEXTPROC) (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLMATRIXROTATEDEXTPROC) (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLMATRIXSCALEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLMATRIXSCALEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLMATRIXFRUSTUMEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); typedef void (APIENTRYP PFNGLMATRIXORTHOEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); typedef void (APIENTRYP PFNGLMATRIXPOPEXTPROC) (GLenum mode); typedef void (APIENTRYP PFNGLMATRIXPUSHEXTPROC) (GLenum mode); typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m); typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m); typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m); typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m); typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); typedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLGETTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLMULTITEXPARAMETERFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); typedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLGETMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLBINDMULTITEXTUREEXTPROC) (GLenum texunit, GLenum target, GLuint texture); typedef void (APIENTRYP PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); typedef void (APIENTRYP PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); typedef void (APIENTRYP PFNGLMULTITEXCOORDPOINTEREXTPROC) (GLenum texunit, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLMULTITEXENVFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLMULTITEXENVIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLMULTITEXGENDEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble param); typedef void (APIENTRYP PFNGLMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params); typedef void (APIENTRYP PFNGLMULTITEXGENFEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLMULTITEXGENIEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLGETMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble *params); typedef void (APIENTRYP PFNGLGETMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum target, GLuint index, GLfloat *data); typedef void (APIENTRYP PFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum target, GLuint index, GLdouble *data); typedef void (APIENTRYP PFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLvoid* *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits); typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint lod, GLvoid *img); typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits); typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits); typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits); typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits); typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits); typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits); typedef void (APIENTRYP PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint lod, GLvoid *img); typedef void (APIENTRYP PFNGLNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum format, GLsizei len, const GLvoid *string); typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLdouble *params); typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLfloat *params); typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble *params); typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat *params); typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMIVEXTPROC) (GLuint program, GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum pname, GLvoid *string); typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params); typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLint *params); typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint *params); typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLuint *params); typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint *params); typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLint *params); typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint *params); typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLuint *params); typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint *params); typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLuint *params); typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLuint *params); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLsizeiptr size, const GLvoid *data, GLenum usage); typedef void (APIENTRYP PFNGLNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const GLvoid *data); typedef GLvoid* (APIENTRYP PFNGLMAPNAMEDBUFFEREXTPROC) (GLuint buffer, GLenum access); typedef GLboolean (APIENTRYP PFNGLUNMAPNAMEDBUFFEREXTPROC) (GLuint buffer); typedef GLvoid* (APIENTRYP PFNGLMAPNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); typedef void (APIENTRYP PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); typedef void (APIENTRYP PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) (GLuint buffer, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPOINTERVEXTPROC) (GLuint buffer, GLenum pname, GLvoid* *params); typedef void (APIENTRYP PFNGLGETNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLvoid *data); typedef void (APIENTRYP PFNGLTEXTUREBUFFEREXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer); typedef void (APIENTRYP PFNGLMULTITEXBUFFEREXTPROC) (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer); typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) (GLuint renderbuffer, GLenum pname, GLint *params); typedef GLenum (APIENTRYP PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) (GLuint framebuffer, GLenum target); typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGENERATETEXTUREMIPMAPEXTPROC) (GLuint texture, GLenum target); typedef void (APIENTRYP PFNGLGENERATEMULTITEXMIPMAPEXTPROC) (GLenum texunit, GLenum target); typedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); typedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) (GLuint framebuffer, GLsizei n, const GLenum *bufs); typedef void (APIENTRYP PFNGLFRAMEBUFFERREADBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face); typedef void (APIENTRYP PFNGLTEXTURERENDERBUFFEREXTPROC) (GLuint texture, GLenum target, GLuint renderbuffer); typedef void (APIENTRYP PFNGLMULTITEXRENDERBUFFEREXTPROC) (GLenum texunit, GLenum target, GLuint renderbuffer); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DEXTPROC) (GLuint program, GLint location, GLdouble x); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); #endif #ifndef GL_EXT_vertex_array_bgra #define GL_EXT_vertex_array_bgra 1 #endif #ifndef GL_EXT_texture_swizzle #define GL_EXT_texture_swizzle 1 #endif #ifndef GL_NV_explicit_multisample #define GL_NV_explicit_multisample 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetMultisamplefvNV (GLenum pname, GLuint index, GLfloat *val); GLAPI void APIENTRY glSampleMaskIndexedNV (GLuint index, GLbitfield mask); GLAPI void APIENTRY glTexRenderbufferNV (GLenum target, GLuint renderbuffer); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVNVPROC) (GLenum pname, GLuint index, GLfloat *val); typedef void (APIENTRYP PFNGLSAMPLEMASKINDEXEDNVPROC) (GLuint index, GLbitfield mask); typedef void (APIENTRYP PFNGLTEXRENDERBUFFERNVPROC) (GLenum target, GLuint renderbuffer); #endif #ifndef GL_NV_transform_feedback2 #define GL_NV_transform_feedback2 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBindTransformFeedbackNV (GLenum target, GLuint id); GLAPI void APIENTRY glDeleteTransformFeedbacksNV (GLsizei n, const GLuint *ids); GLAPI void APIENTRY glGenTransformFeedbacksNV (GLsizei n, GLuint *ids); GLAPI GLboolean APIENTRY glIsTransformFeedbackNV (GLuint id); GLAPI void APIENTRY glPauseTransformFeedbackNV (void); GLAPI void APIENTRY glResumeTransformFeedbackNV (void); GLAPI void APIENTRY glDrawTransformFeedbackNV (GLenum mode, GLuint id); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKNVPROC) (GLenum target, GLuint id); typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSNVPROC) (GLsizei n, const GLuint *ids); typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSNVPROC) (GLsizei n, GLuint *ids); typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKNVPROC) (GLuint id); typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKNVPROC) (void); typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKNVPROC) (void); typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKNVPROC) (GLenum mode, GLuint id); #endif #ifndef GL_ATI_meminfo #define GL_ATI_meminfo 1 #endif #ifndef GL_AMD_performance_monitor #define GL_AMD_performance_monitor 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, GLuint *groups); GLAPI void APIENTRY glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); GLAPI void APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); GLAPI void APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); GLAPI void APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, GLvoid *data); GLAPI void APIENTRY glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors); GLAPI void APIENTRY glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors); GLAPI void APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList); GLAPI void APIENTRY glBeginPerfMonitorAMD (GLuint monitor); GLAPI void APIENTRY glEndPerfMonitorAMD (GLuint monitor); GLAPI void APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups); typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, GLvoid *data); typedef void (APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); typedef void (APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); typedef void (APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList); typedef void (APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); typedef void (APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); #endif #ifndef GL_AMD_texture_texture4 #define GL_AMD_texture_texture4 1 #endif #ifndef GL_AMD_vertex_shader_tesselator #define GL_AMD_vertex_shader_tesselator 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTessellationFactorAMD (GLfloat factor); GLAPI void APIENTRY glTessellationModeAMD (GLenum mode); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTESSELLATIONFACTORAMDPROC) (GLfloat factor); typedef void (APIENTRYP PFNGLTESSELLATIONMODEAMDPROC) (GLenum mode); #endif #ifndef GL_EXT_provoking_vertex #define GL_EXT_provoking_vertex 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glProvokingVertexEXT (GLenum mode); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPROVOKINGVERTEXEXTPROC) (GLenum mode); #endif #ifndef GL_EXT_texture_snorm #define GL_EXT_texture_snorm 1 #endif #ifndef GL_AMD_draw_buffers_blend #define GL_AMD_draw_buffers_blend 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendFuncIndexedAMD (GLuint buf, GLenum src, GLenum dst); GLAPI void APIENTRY glBlendFuncSeparateIndexedAMD (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); GLAPI void APIENTRY glBlendEquationIndexedAMD (GLuint buf, GLenum mode); GLAPI void APIENTRY glBlendEquationSeparateIndexedAMD (GLuint buf, GLenum modeRGB, GLenum modeAlpha); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDFUNCINDEXEDAMDPROC) (GLuint buf, GLenum src, GLenum dst); typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); typedef void (APIENTRYP PFNGLBLENDEQUATIONINDEXEDAMDPROC) (GLuint buf, GLenum mode); typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); #endif #ifndef GL_APPLE_texture_range #define GL_APPLE_texture_range 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTextureRangeAPPLE (GLenum target, GLsizei length, const GLvoid *pointer); GLAPI void APIENTRY glGetTexParameterPointervAPPLE (GLenum target, GLenum pname, GLvoid* *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, const GLvoid *pointer); typedef void (APIENTRYP PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC) (GLenum target, GLenum pname, GLvoid* *params); #endif #ifndef GL_APPLE_float_pixels #define GL_APPLE_float_pixels 1 #endif #ifndef GL_APPLE_vertex_program_evaluators #define GL_APPLE_vertex_program_evaluators 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glEnableVertexAttribAPPLE (GLuint index, GLenum pname); GLAPI void APIENTRY glDisableVertexAttribAPPLE (GLuint index, GLenum pname); GLAPI GLboolean APIENTRY glIsVertexAttribEnabledAPPLE (GLuint index, GLenum pname); GLAPI void APIENTRY glMapVertexAttrib1dAPPLE (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); GLAPI void APIENTRY glMapVertexAttrib1fAPPLE (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); GLAPI void APIENTRY glMapVertexAttrib2dAPPLE (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); GLAPI void APIENTRY glMapVertexAttrib2fAPPLE (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); typedef GLboolean (APIENTRYP PFNGLISVERTEXATTRIBENABLEDAPPLEPROC) (GLuint index, GLenum pname); typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB1DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB1FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB2DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB2FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); #endif #ifndef GL_APPLE_aux_depth_stencil #define GL_APPLE_aux_depth_stencil 1 #endif #ifndef GL_APPLE_object_purgeable #define GL_APPLE_object_purgeable 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLenum APIENTRY glObjectPurgeableAPPLE (GLenum objectType, GLuint name, GLenum option); GLAPI GLenum APIENTRY glObjectUnpurgeableAPPLE (GLenum objectType, GLuint name, GLenum option); GLAPI void APIENTRY glGetObjectParameterivAPPLE (GLenum objectType, GLuint name, GLenum pname, GLint *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLenum (APIENTRYP PFNGLOBJECTPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); typedef GLenum (APIENTRYP PFNGLOBJECTUNPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVAPPLEPROC) (GLenum objectType, GLuint name, GLenum pname, GLint *params); #endif #ifndef GL_APPLE_row_bytes #define GL_APPLE_row_bytes 1 #endif #ifndef GL_APPLE_rgb_422 #define GL_APPLE_rgb_422 1 #endif #ifndef GL_NV_video_capture #define GL_NV_video_capture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBeginVideoCaptureNV (GLuint video_capture_slot); GLAPI void APIENTRY glBindVideoCaptureStreamBufferNV (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset); GLAPI void APIENTRY glBindVideoCaptureStreamTextureNV (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture); GLAPI void APIENTRY glEndVideoCaptureNV (GLuint video_capture_slot); GLAPI void APIENTRY glGetVideoCaptureivNV (GLuint video_capture_slot, GLenum pname, GLint *params); GLAPI void APIENTRY glGetVideoCaptureStreamivNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params); GLAPI void APIENTRY glGetVideoCaptureStreamfvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetVideoCaptureStreamdvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params); GLAPI GLenum APIENTRY glVideoCaptureNV (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time); GLAPI void APIENTRY glVideoCaptureStreamParameterivNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params); GLAPI void APIENTRY glVideoCaptureStreamParameterfvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params); GLAPI void APIENTRY glVideoCaptureStreamParameterdvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBEGINVIDEOCAPTURENVPROC) (GLuint video_capture_slot); typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset); typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture); typedef void (APIENTRYP PFNGLENDVIDEOCAPTURENVPROC) (GLuint video_capture_slot); typedef void (APIENTRYP PFNGLGETVIDEOCAPTUREIVNVPROC) (GLuint video_capture_slot, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params); typedef GLenum (APIENTRYP PFNGLVIDEOCAPTURENVPROC) (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time); typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params); #endif #ifndef GL_NV_copy_image #define GL_NV_copy_image 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glCopyImageSubDataNV (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOPYIMAGESUBDATANVPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); #endif #ifndef GL_EXT_separate_shader_objects #define GL_EXT_separate_shader_objects 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glUseShaderProgramEXT (GLenum type, GLuint program); GLAPI void APIENTRY glActiveProgramEXT (GLuint program); GLAPI GLuint APIENTRY glCreateShaderProgramEXT (GLenum type, const GLchar *string); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLUSESHADERPROGRAMEXTPROC) (GLenum type, GLuint program); typedef void (APIENTRYP PFNGLACTIVEPROGRAMEXTPROC) (GLuint program); typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMEXTPROC) (GLenum type, const GLchar *string); #endif #ifndef GL_NV_parameter_buffer_object2 #define GL_NV_parameter_buffer_object2 1 #endif #ifndef GL_NV_shader_buffer_load #define GL_NV_shader_buffer_load 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glMakeBufferResidentNV (GLenum target, GLenum access); GLAPI void APIENTRY glMakeBufferNonResidentNV (GLenum target); GLAPI GLboolean APIENTRY glIsBufferResidentNV (GLenum target); GLAPI void APIENTRY glMakeNamedBufferResidentNV (GLuint buffer, GLenum access); GLAPI void APIENTRY glMakeNamedBufferNonResidentNV (GLuint buffer); GLAPI GLboolean APIENTRY glIsNamedBufferResidentNV (GLuint buffer); GLAPI void APIENTRY glGetBufferParameterui64vNV (GLenum target, GLenum pname, GLuint64EXT *params); GLAPI void APIENTRY glGetNamedBufferParameterui64vNV (GLuint buffer, GLenum pname, GLuint64EXT *params); GLAPI void APIENTRY glGetIntegerui64vNV (GLenum value, GLuint64EXT *result); GLAPI void APIENTRY glUniformui64NV (GLint location, GLuint64EXT value); GLAPI void APIENTRY glUniformui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); GLAPI void APIENTRY glGetUniformui64vNV (GLuint program, GLint location, GLuint64EXT *params); GLAPI void APIENTRY glProgramUniformui64NV (GLuint program, GLint location, GLuint64EXT value); GLAPI void APIENTRY glProgramUniformui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLMAKEBUFFERRESIDENTNVPROC) (GLenum target, GLenum access); typedef void (APIENTRYP PFNGLMAKEBUFFERNONRESIDENTNVPROC) (GLenum target); typedef GLboolean (APIENTRYP PFNGLISBUFFERRESIDENTNVPROC) (GLenum target); typedef void (APIENTRYP PFNGLMAKENAMEDBUFFERRESIDENTNVPROC) (GLuint buffer, GLenum access); typedef void (APIENTRYP PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC) (GLuint buffer); typedef GLboolean (APIENTRYP PFNGLISNAMEDBUFFERRESIDENTNVPROC) (GLuint buffer); typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERUI64VNVPROC) (GLenum target, GLenum pname, GLuint64EXT *params); typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC) (GLuint buffer, GLenum pname, GLuint64EXT *params); typedef void (APIENTRYP PFNGLGETINTEGERUI64VNVPROC) (GLenum value, GLuint64EXT *result); typedef void (APIENTRYP PFNGLUNIFORMUI64NVPROC) (GLint location, GLuint64EXT value); typedef void (APIENTRYP PFNGLUNIFORMUI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); typedef void (APIENTRYP PFNGLGETUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLuint64EXT *params); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64NVPROC) (GLuint program, GLint location, GLuint64EXT value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); #endif #ifndef GL_NV_vertex_buffer_unified_memory #define GL_NV_vertex_buffer_unified_memory 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBufferAddressRangeNV (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length); GLAPI void APIENTRY glVertexFormatNV (GLint size, GLenum type, GLsizei stride); GLAPI void APIENTRY glNormalFormatNV (GLenum type, GLsizei stride); GLAPI void APIENTRY glColorFormatNV (GLint size, GLenum type, GLsizei stride); GLAPI void APIENTRY glIndexFormatNV (GLenum type, GLsizei stride); GLAPI void APIENTRY glTexCoordFormatNV (GLint size, GLenum type, GLsizei stride); GLAPI void APIENTRY glEdgeFlagFormatNV (GLsizei stride); GLAPI void APIENTRY glSecondaryColorFormatNV (GLint size, GLenum type, GLsizei stride); GLAPI void APIENTRY glFogCoordFormatNV (GLenum type, GLsizei stride); GLAPI void APIENTRY glVertexAttribFormatNV (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride); GLAPI void APIENTRY glVertexAttribIFormatNV (GLuint index, GLint size, GLenum type, GLsizei stride); GLAPI void APIENTRY glGetIntegerui64i_vNV (GLenum value, GLuint index, GLuint64EXT *result); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBUFFERADDRESSRANGENVPROC) (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length); typedef void (APIENTRYP PFNGLVERTEXFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); typedef void (APIENTRYP PFNGLNORMALFORMATNVPROC) (GLenum type, GLsizei stride); typedef void (APIENTRYP PFNGLCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); typedef void (APIENTRYP PFNGLINDEXFORMATNVPROC) (GLenum type, GLsizei stride); typedef void (APIENTRYP PFNGLTEXCOORDFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); typedef void (APIENTRYP PFNGLEDGEFLAGFORMATNVPROC) (GLsizei stride); typedef void (APIENTRYP PFNGLSECONDARYCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); typedef void (APIENTRYP PFNGLFOGCOORDFORMATNVPROC) (GLenum type, GLsizei stride); typedef void (APIENTRYP PFNGLVERTEXATTRIBFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride); typedef void (APIENTRYP PFNGLVERTEXATTRIBIFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride); typedef void (APIENTRYP PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT *result); #endif #ifndef GL_NV_texture_barrier #define GL_NV_texture_barrier 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTextureBarrierNV (void); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXTUREBARRIERNVPROC) (void); #endif #ifndef GL_AMD_shader_stencil_export #define GL_AMD_shader_stencil_export 1 #endif #ifndef GL_AMD_seamless_cubemap_per_texture #define GL_AMD_seamless_cubemap_per_texture 1 #endif #ifndef GL_AMD_conservative_depth #define GL_AMD_conservative_depth 1 #endif #ifndef GL_EXT_shader_image_load_store #define GL_EXT_shader_image_load_store 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBindImageTextureEXT (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format); GLAPI void APIENTRY glMemoryBarrierEXT (GLbitfield barriers); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREEXTPROC) (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format); typedef void (APIENTRYP PFNGLMEMORYBARRIEREXTPROC) (GLbitfield barriers); #endif #ifndef GL_EXT_vertex_attrib_64bit #define GL_EXT_vertex_attrib_64bit 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexAttribL1dEXT (GLuint index, GLdouble x); GLAPI void APIENTRY glVertexAttribL2dEXT (GLuint index, GLdouble x, GLdouble y); GLAPI void APIENTRY glVertexAttribL3dEXT (GLuint index, GLdouble x, GLdouble y, GLdouble z); GLAPI void APIENTRY glVertexAttribL4dEXT (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); GLAPI void APIENTRY glVertexAttribL1dvEXT (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttribL2dvEXT (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttribL3dvEXT (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttribL4dvEXT (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttribLPointerEXT (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); GLAPI void APIENTRY glGetVertexAttribLdvEXT (GLuint index, GLenum pname, GLdouble *params); GLAPI void APIENTRY glVertexArrayVertexAttribLOffsetEXT (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DEXTPROC) (GLuint index, GLdouble x); typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DEXTPROC) (GLuint index, GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DVEXTPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DVEXTPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DVEXTPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DVEXTPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLDVEXTPROC) (GLuint index, GLenum pname, GLdouble *params); typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); #endif #ifndef GL_NV_gpu_program5 #define GL_NV_gpu_program5 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glProgramSubroutineParametersuivNV (GLenum target, GLsizei count, const GLuint *params); GLAPI void APIENTRY glGetProgramSubroutineParameteruivNV (GLenum target, GLuint index, GLuint *param); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPROGRAMSUBROUTINEPARAMETERSUIVNVPROC) (GLenum target, GLsizei count, const GLuint *params); typedef void (APIENTRYP PFNGLGETPROGRAMSUBROUTINEPARAMETERUIVNVPROC) (GLenum target, GLuint index, GLuint *param); #endif #ifndef GL_NV_gpu_shader5 #define GL_NV_gpu_shader5 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glUniform1i64NV (GLint location, GLint64EXT x); GLAPI void APIENTRY glUniform2i64NV (GLint location, GLint64EXT x, GLint64EXT y); GLAPI void APIENTRY glUniform3i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); GLAPI void APIENTRY glUniform4i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); GLAPI void APIENTRY glUniform1i64vNV (GLint location, GLsizei count, const GLint64EXT *value); GLAPI void APIENTRY glUniform2i64vNV (GLint location, GLsizei count, const GLint64EXT *value); GLAPI void APIENTRY glUniform3i64vNV (GLint location, GLsizei count, const GLint64EXT *value); GLAPI void APIENTRY glUniform4i64vNV (GLint location, GLsizei count, const GLint64EXT *value); GLAPI void APIENTRY glUniform1ui64NV (GLint location, GLuint64EXT x); GLAPI void APIENTRY glUniform2ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y); GLAPI void APIENTRY glUniform3ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); GLAPI void APIENTRY glUniform4ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); GLAPI void APIENTRY glUniform1ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); GLAPI void APIENTRY glUniform2ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); GLAPI void APIENTRY glUniform3ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); GLAPI void APIENTRY glUniform4ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); GLAPI void APIENTRY glGetUniformi64vNV (GLuint program, GLint location, GLint64EXT *params); GLAPI void APIENTRY glProgramUniform1i64NV (GLuint program, GLint location, GLint64EXT x); GLAPI void APIENTRY glProgramUniform2i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y); GLAPI void APIENTRY glProgramUniform3i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); GLAPI void APIENTRY glProgramUniform4i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); GLAPI void APIENTRY glProgramUniform1i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); GLAPI void APIENTRY glProgramUniform2i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); GLAPI void APIENTRY glProgramUniform3i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); GLAPI void APIENTRY glProgramUniform4i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); GLAPI void APIENTRY glProgramUniform1ui64NV (GLuint program, GLint location, GLuint64EXT x); GLAPI void APIENTRY glProgramUniform2ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y); GLAPI void APIENTRY glProgramUniform3ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); GLAPI void APIENTRY glProgramUniform4ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); GLAPI void APIENTRY glProgramUniform1ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); GLAPI void APIENTRY glProgramUniform2ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); GLAPI void APIENTRY glProgramUniform3ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); GLAPI void APIENTRY glProgramUniform4ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLUNIFORM1I64NVPROC) (GLint location, GLint64EXT x); typedef void (APIENTRYP PFNGLUNIFORM2I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y); typedef void (APIENTRYP PFNGLUNIFORM3I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); typedef void (APIENTRYP PFNGLUNIFORM4I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); typedef void (APIENTRYP PFNGLUNIFORM1I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); typedef void (APIENTRYP PFNGLUNIFORM2I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); typedef void (APIENTRYP PFNGLUNIFORM3I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); typedef void (APIENTRYP PFNGLUNIFORM4I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); typedef void (APIENTRYP PFNGLUNIFORM1UI64NVPROC) (GLint location, GLuint64EXT x); typedef void (APIENTRYP PFNGLUNIFORM2UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y); typedef void (APIENTRYP PFNGLUNIFORM3UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); typedef void (APIENTRYP PFNGLUNIFORM4UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); typedef void (APIENTRYP PFNGLUNIFORM1UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); typedef void (APIENTRYP PFNGLUNIFORM2UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); typedef void (APIENTRYP PFNGLUNIFORM3UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); typedef void (APIENTRYP PFNGLUNIFORM4UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); typedef void (APIENTRYP PFNGLGETUNIFORMI64VNVPROC) (GLuint program, GLint location, GLint64EXT *params); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64NVPROC) (GLuint program, GLint location, GLint64EXT x); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); #endif #ifndef GL_NV_shader_buffer_store #define GL_NV_shader_buffer_store 1 #endif #ifndef GL_NV_tessellation_program5 #define GL_NV_tessellation_program5 1 #endif #ifndef GL_NV_vertex_attrib_integer_64bit #define GL_NV_vertex_attrib_integer_64bit 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexAttribL1i64NV (GLuint index, GLint64EXT x); GLAPI void APIENTRY glVertexAttribL2i64NV (GLuint index, GLint64EXT x, GLint64EXT y); GLAPI void APIENTRY glVertexAttribL3i64NV (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z); GLAPI void APIENTRY glVertexAttribL4i64NV (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); GLAPI void APIENTRY glVertexAttribL1i64vNV (GLuint index, const GLint64EXT *v); GLAPI void APIENTRY glVertexAttribL2i64vNV (GLuint index, const GLint64EXT *v); GLAPI void APIENTRY glVertexAttribL3i64vNV (GLuint index, const GLint64EXT *v); GLAPI void APIENTRY glVertexAttribL4i64vNV (GLuint index, const GLint64EXT *v); GLAPI void APIENTRY glVertexAttribL1ui64NV (GLuint index, GLuint64EXT x); GLAPI void APIENTRY glVertexAttribL2ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y); GLAPI void APIENTRY glVertexAttribL3ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); GLAPI void APIENTRY glVertexAttribL4ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); GLAPI void APIENTRY glVertexAttribL1ui64vNV (GLuint index, const GLuint64EXT *v); GLAPI void APIENTRY glVertexAttribL2ui64vNV (GLuint index, const GLuint64EXT *v); GLAPI void APIENTRY glVertexAttribL3ui64vNV (GLuint index, const GLuint64EXT *v); GLAPI void APIENTRY glVertexAttribL4ui64vNV (GLuint index, const GLuint64EXT *v); GLAPI void APIENTRY glGetVertexAttribLi64vNV (GLuint index, GLenum pname, GLint64EXT *params); GLAPI void APIENTRY glGetVertexAttribLui64vNV (GLuint index, GLenum pname, GLuint64EXT *params); GLAPI void APIENTRY glVertexAttribLFormatNV (GLuint index, GLint size, GLenum type, GLsizei stride); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXATTRIBL1I64NVPROC) (GLuint index, GLint64EXT x); typedef void (APIENTRYP PFNGLVERTEXATTRIBL2I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y); typedef void (APIENTRYP PFNGLVERTEXATTRIBL3I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z); typedef void (APIENTRYP PFNGLVERTEXATTRIBL4I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); typedef void (APIENTRYP PFNGLVERTEXATTRIBL1I64VNVPROC) (GLuint index, const GLint64EXT *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBL2I64VNVPROC) (GLuint index, const GLint64EXT *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBL3I64VNVPROC) (GLuint index, const GLint64EXT *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBL4I64VNVPROC) (GLuint index, const GLint64EXT *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64NVPROC) (GLuint index, GLuint64EXT x); typedef void (APIENTRYP PFNGLVERTEXATTRIBL2UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y); typedef void (APIENTRYP PFNGLVERTEXATTRIBL3UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); typedef void (APIENTRYP PFNGLVERTEXATTRIBL4UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64VNVPROC) (GLuint index, const GLuint64EXT *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBL2UI64VNVPROC) (GLuint index, const GLuint64EXT *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBL3UI64VNVPROC) (GLuint index, const GLuint64EXT *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBL4UI64VNVPROC) (GLuint index, const GLuint64EXT *v); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLI64VNVPROC) (GLuint index, GLenum pname, GLint64EXT *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLUI64VNVPROC) (GLuint index, GLenum pname, GLuint64EXT *params); typedef void (APIENTRYP PFNGLVERTEXATTRIBLFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride); #endif #ifndef GL_NV_multisample_coverage #define GL_NV_multisample_coverage 1 #endif #ifndef GL_AMD_name_gen_delete #define GL_AMD_name_gen_delete 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGenNamesAMD (GLenum identifier, GLuint num, GLuint *names); GLAPI void APIENTRY glDeleteNamesAMD (GLenum identifier, GLuint num, const GLuint *names); GLAPI GLboolean APIENTRY glIsNameAMD (GLenum identifier, GLuint name); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGENNAMESAMDPROC) (GLenum identifier, GLuint num, GLuint *names); typedef void (APIENTRYP PFNGLDELETENAMESAMDPROC) (GLenum identifier, GLuint num, const GLuint *names); typedef GLboolean (APIENTRYP PFNGLISNAMEAMDPROC) (GLenum identifier, GLuint name); #endif #ifndef GL_AMD_debug_output #define GL_AMD_debug_output 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDebugMessageEnableAMD (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); GLAPI void APIENTRY glDebugMessageInsertAMD (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf); GLAPI void APIENTRY glDebugMessageCallbackAMD (GLDEBUGPROCAMD callback, GLvoid *userParam); GLAPI GLuint APIENTRY glGetDebugMessageLogAMD (GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDEBUGMESSAGEENABLEAMDPROC) (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTAMDPROC) (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf); typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKAMDPROC) (GLDEBUGPROCAMD callback, GLvoid *userParam); typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGAMDPROC) (GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message); #endif #ifndef GL_NV_vdpau_interop #define GL_NV_vdpau_interop 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVDPAUInitNV (const GLvoid *vdpDevice, const GLvoid *getProcAddress); GLAPI void APIENTRY glVDPAUFiniNV (void); GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterVideoSurfaceNV (const GLvoid *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterOutputSurfaceNV (GLvoid *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); GLAPI void APIENTRY glVDPAUIsSurfaceNV (GLvdpauSurfaceNV surface); GLAPI void APIENTRY glVDPAUUnregisterSurfaceNV (GLvdpauSurfaceNV surface); GLAPI void APIENTRY glVDPAUGetSurfaceivNV (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); GLAPI void APIENTRY glVDPAUSurfaceAccessNV (GLvdpauSurfaceNV surface, GLenum access); GLAPI void APIENTRY glVDPAUMapSurfacesNV (GLsizei numSurfaces, const GLvdpauSurfaceNV *surfaces); GLAPI void APIENTRY glVDPAUUnmapSurfacesNV (GLsizei numSurface, const GLvdpauSurfaceNV *surfaces); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVDPAUINITNVPROC) (const GLvoid *vdpDevice, const GLvoid *getProcAddress); typedef void (APIENTRYP PFNGLVDPAUFININVPROC) (void); typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTERVIDEOSURFACENVPROC) (const GLvoid *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC) (GLvoid *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); typedef void (APIENTRYP PFNGLVDPAUISSURFACENVPROC) (GLvdpauSurfaceNV surface); typedef void (APIENTRYP PFNGLVDPAUUNREGISTERSURFACENVPROC) (GLvdpauSurfaceNV surface); typedef void (APIENTRYP PFNGLVDPAUGETSURFACEIVNVPROC) (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); typedef void (APIENTRYP PFNGLVDPAUSURFACEACCESSNVPROC) (GLvdpauSurfaceNV surface, GLenum access); typedef void (APIENTRYP PFNGLVDPAUMAPSURFACESNVPROC) (GLsizei numSurfaces, const GLvdpauSurfaceNV *surfaces); typedef void (APIENTRYP PFNGLVDPAUUNMAPSURFACESNVPROC) (GLsizei numSurface, const GLvdpauSurfaceNV *surfaces); #endif #ifndef GL_AMD_transform_feedback3_lines_triangles #define GL_AMD_transform_feedback3_lines_triangles 1 #endif #ifndef GL_AMD_depth_clamp_separate #define GL_AMD_depth_clamp_separate 1 #endif #ifndef GL_EXT_texture_sRGB_decode #define GL_EXT_texture_sRGB_decode 1 #endif #ifndef GL_NV_texture_multisample #define GL_NV_texture_multisample 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTexImage2DMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); GLAPI void APIENTRY glTexImage3DMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); GLAPI void APIENTRY glTextureImage2DMultisampleNV (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); GLAPI void APIENTRY glTextureImage3DMultisampleNV (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); GLAPI void APIENTRY glTextureImage2DMultisampleCoverageNV (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); GLAPI void APIENTRY glTextureImage3DMultisampleCoverageNV (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); #endif #ifndef GL_AMD_blend_minmax_factor #define GL_AMD_blend_minmax_factor 1 #endif #ifndef GL_AMD_sample_positions #define GL_AMD_sample_positions 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glSetMultisamplefvAMD (GLenum pname, GLuint index, const GLfloat *val); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSETMULTISAMPLEFVAMDPROC) (GLenum pname, GLuint index, const GLfloat *val); #endif #ifndef GL_EXT_x11_sync_object #define GL_EXT_x11_sync_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLsync APIENTRY glImportSyncEXT (GLenum external_sync_type, GLintptr external_sync, GLbitfield flags); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLsync (APIENTRYP PFNGLIMPORTSYNCEXTPROC) (GLenum external_sync_type, GLintptr external_sync, GLbitfield flags); #endif #ifndef GL_AMD_multi_draw_indirect #define GL_AMD_multi_draw_indirect 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glMultiDrawArraysIndirectAMD (GLenum mode, const GLvoid *indirect, GLsizei primcount, GLsizei stride); GLAPI void APIENTRY glMultiDrawElementsIndirectAMD (GLenum mode, GLenum type, const GLvoid *indirect, GLsizei primcount, GLsizei stride); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC) (GLenum mode, const GLvoid *indirect, GLsizei primcount, GLsizei stride); typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC) (GLenum mode, GLenum type, const GLvoid *indirect, GLsizei primcount, GLsizei stride); #endif #ifndef GL_EXT_framebuffer_multisample_blit_scaled #define GL_EXT_framebuffer_multisample_blit_scaled 1 #endif #ifndef GL_NV_path_rendering #define GL_NV_path_rendering 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLuint APIENTRY glGenPathsNV (GLsizei range); GLAPI void APIENTRY glDeletePathsNV (GLuint path, GLsizei range); GLAPI GLboolean APIENTRY glIsPathNV (GLuint path); GLAPI void APIENTRY glPathCommandsNV (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const GLvoid *coords); GLAPI void APIENTRY glPathCoordsNV (GLuint path, GLsizei numCoords, GLenum coordType, const GLvoid *coords); GLAPI void APIENTRY glPathSubCommandsNV (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const GLvoid *coords); GLAPI void APIENTRY glPathSubCoordsNV (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const GLvoid *coords); GLAPI void APIENTRY glPathStringNV (GLuint path, GLenum format, GLsizei length, const GLvoid *pathString); GLAPI void APIENTRY glPathGlyphsNV (GLuint firstPathName, GLenum fontTarget, const GLvoid *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const GLvoid *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); GLAPI void APIENTRY glPathGlyphRangeNV (GLuint firstPathName, GLenum fontTarget, const GLvoid *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); GLAPI void APIENTRY glWeightPathsNV (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights); GLAPI void APIENTRY glCopyPathNV (GLuint resultPath, GLuint srcPath); GLAPI void APIENTRY glInterpolatePathsNV (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight); GLAPI void APIENTRY glTransformPathNV (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues); GLAPI void APIENTRY glPathParameterivNV (GLuint path, GLenum pname, const GLint *value); GLAPI void APIENTRY glPathParameteriNV (GLuint path, GLenum pname, GLint value); GLAPI void APIENTRY glPathParameterfvNV (GLuint path, GLenum pname, const GLfloat *value); GLAPI void APIENTRY glPathParameterfNV (GLuint path, GLenum pname, GLfloat value); GLAPI void APIENTRY glPathDashArrayNV (GLuint path, GLsizei dashCount, const GLfloat *dashArray); GLAPI void APIENTRY glPathStencilFuncNV (GLenum func, GLint ref, GLuint mask); GLAPI void APIENTRY glPathStencilDepthOffsetNV (GLfloat factor, GLfloat units); GLAPI void APIENTRY glStencilFillPathNV (GLuint path, GLenum fillMode, GLuint mask); GLAPI void APIENTRY glStencilStrokePathNV (GLuint path, GLint reference, GLuint mask); GLAPI void APIENTRY glStencilFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const GLvoid *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues); GLAPI void APIENTRY glStencilStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const GLvoid *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues); GLAPI void APIENTRY glPathCoverDepthFuncNV (GLenum func); GLAPI void APIENTRY glPathColorGenNV (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat *coeffs); GLAPI void APIENTRY glPathTexGenNV (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat *coeffs); GLAPI void APIENTRY glPathFogGenNV (GLenum genMode); GLAPI void APIENTRY glCoverFillPathNV (GLuint path, GLenum coverMode); GLAPI void APIENTRY glCoverStrokePathNV (GLuint path, GLenum coverMode); GLAPI void APIENTRY glCoverFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const GLvoid *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); GLAPI void APIENTRY glCoverStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const GLvoid *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); GLAPI void APIENTRY glGetPathParameterivNV (GLuint path, GLenum pname, GLint *value); GLAPI void APIENTRY glGetPathParameterfvNV (GLuint path, GLenum pname, GLfloat *value); GLAPI void APIENTRY glGetPathCommandsNV (GLuint path, GLubyte *commands); GLAPI void APIENTRY glGetPathCoordsNV (GLuint path, GLfloat *coords); GLAPI void APIENTRY glGetPathDashArrayNV (GLuint path, GLfloat *dashArray); GLAPI void APIENTRY glGetPathMetricsNV (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const GLvoid *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics); GLAPI void APIENTRY glGetPathMetricRangeNV (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics); GLAPI void APIENTRY glGetPathSpacingNV (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const GLvoid *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing); GLAPI void APIENTRY glGetPathColorGenivNV (GLenum color, GLenum pname, GLint *value); GLAPI void APIENTRY glGetPathColorGenfvNV (GLenum color, GLenum pname, GLfloat *value); GLAPI void APIENTRY glGetPathTexGenivNV (GLenum texCoordSet, GLenum pname, GLint *value); GLAPI void APIENTRY glGetPathTexGenfvNV (GLenum texCoordSet, GLenum pname, GLfloat *value); GLAPI GLboolean APIENTRY glIsPointInFillPathNV (GLuint path, GLuint mask, GLfloat x, GLfloat y); GLAPI GLboolean APIENTRY glIsPointInStrokePathNV (GLuint path, GLfloat x, GLfloat y); GLAPI GLfloat APIENTRY glGetPathLengthNV (GLuint path, GLsizei startSegment, GLsizei numSegments); GLAPI GLboolean APIENTRY glPointAlongPathNV (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLuint (APIENTRYP PFNGLGENPATHSNVPROC) (GLsizei range); typedef void (APIENTRYP PFNGLDELETEPATHSNVPROC) (GLuint path, GLsizei range); typedef GLboolean (APIENTRYP PFNGLISPATHNVPROC) (GLuint path); typedef void (APIENTRYP PFNGLPATHCOMMANDSNVPROC) (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const GLvoid *coords); typedef void (APIENTRYP PFNGLPATHCOORDSNVPROC) (GLuint path, GLsizei numCoords, GLenum coordType, const GLvoid *coords); typedef void (APIENTRYP PFNGLPATHSUBCOMMANDSNVPROC) (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const GLvoid *coords); typedef void (APIENTRYP PFNGLPATHSUBCOORDSNVPROC) (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const GLvoid *coords); typedef void (APIENTRYP PFNGLPATHSTRINGNVPROC) (GLuint path, GLenum format, GLsizei length, const GLvoid *pathString); typedef void (APIENTRYP PFNGLPATHGLYPHSNVPROC) (GLuint firstPathName, GLenum fontTarget, const GLvoid *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const GLvoid *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); typedef void (APIENTRYP PFNGLPATHGLYPHRANGENVPROC) (GLuint firstPathName, GLenum fontTarget, const GLvoid *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); typedef void (APIENTRYP PFNGLWEIGHTPATHSNVPROC) (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights); typedef void (APIENTRYP PFNGLCOPYPATHNVPROC) (GLuint resultPath, GLuint srcPath); typedef void (APIENTRYP PFNGLINTERPOLATEPATHSNVPROC) (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight); typedef void (APIENTRYP PFNGLTRANSFORMPATHNVPROC) (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues); typedef void (APIENTRYP PFNGLPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, const GLint *value); typedef void (APIENTRYP PFNGLPATHPARAMETERINVPROC) (GLuint path, GLenum pname, GLint value); typedef void (APIENTRYP PFNGLPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, const GLfloat *value); typedef void (APIENTRYP PFNGLPATHPARAMETERFNVPROC) (GLuint path, GLenum pname, GLfloat value); typedef void (APIENTRYP PFNGLPATHDASHARRAYNVPROC) (GLuint path, GLsizei dashCount, const GLfloat *dashArray); typedef void (APIENTRYP PFNGLPATHSTENCILFUNCNVPROC) (GLenum func, GLint ref, GLuint mask); typedef void (APIENTRYP PFNGLPATHSTENCILDEPTHOFFSETNVPROC) (GLfloat factor, GLfloat units); typedef void (APIENTRYP PFNGLSTENCILFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask); typedef void (APIENTRYP PFNGLSTENCILSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask); typedef void (APIENTRYP PFNGLSTENCILFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const GLvoid *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues); typedef void (APIENTRYP PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const GLvoid *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues); typedef void (APIENTRYP PFNGLPATHCOVERDEPTHFUNCNVPROC) (GLenum func); typedef void (APIENTRYP PFNGLPATHCOLORGENNVPROC) (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat *coeffs); typedef void (APIENTRYP PFNGLPATHTEXGENNVPROC) (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat *coeffs); typedef void (APIENTRYP PFNGLPATHFOGGENNVPROC) (GLenum genMode); typedef void (APIENTRYP PFNGLCOVERFILLPATHNVPROC) (GLuint path, GLenum coverMode); typedef void (APIENTRYP PFNGLCOVERSTROKEPATHNVPROC) (GLuint path, GLenum coverMode); typedef void (APIENTRYP PFNGLCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const GLvoid *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); typedef void (APIENTRYP PFNGLCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const GLvoid *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); typedef void (APIENTRYP PFNGLGETPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, GLint *value); typedef void (APIENTRYP PFNGLGETPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, GLfloat *value); typedef void (APIENTRYP PFNGLGETPATHCOMMANDSNVPROC) (GLuint path, GLubyte *commands); typedef void (APIENTRYP PFNGLGETPATHCOORDSNVPROC) (GLuint path, GLfloat *coords); typedef void (APIENTRYP PFNGLGETPATHDASHARRAYNVPROC) (GLuint path, GLfloat *dashArray); typedef void (APIENTRYP PFNGLGETPATHMETRICSNVPROC) (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const GLvoid *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics); typedef void (APIENTRYP PFNGLGETPATHMETRICRANGENVPROC) (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics); typedef void (APIENTRYP PFNGLGETPATHSPACINGNVPROC) (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const GLvoid *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing); typedef void (APIENTRYP PFNGLGETPATHCOLORGENIVNVPROC) (GLenum color, GLenum pname, GLint *value); typedef void (APIENTRYP PFNGLGETPATHCOLORGENFVNVPROC) (GLenum color, GLenum pname, GLfloat *value); typedef void (APIENTRYP PFNGLGETPATHTEXGENIVNVPROC) (GLenum texCoordSet, GLenum pname, GLint *value); typedef void (APIENTRYP PFNGLGETPATHTEXGENFVNVPROC) (GLenum texCoordSet, GLenum pname, GLfloat *value); typedef GLboolean (APIENTRYP PFNGLISPOINTINFILLPATHNVPROC) (GLuint path, GLuint mask, GLfloat x, GLfloat y); typedef GLboolean (APIENTRYP PFNGLISPOINTINSTROKEPATHNVPROC) (GLuint path, GLfloat x, GLfloat y); typedef GLfloat (APIENTRYP PFNGLGETPATHLENGTHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments); typedef GLboolean (APIENTRYP PFNGLPOINTALONGPATHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY); #endif #ifndef GL_AMD_pinned_memory #define GL_AMD_pinned_memory 1 #endif #ifndef GL_AMD_stencil_operation_extended #define GL_AMD_stencil_operation_extended 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glStencilOpValueAMD (GLenum face, GLuint value); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSTENCILOPVALUEAMDPROC) (GLenum face, GLuint value); #endif #ifndef GL_AMD_vertex_shader_viewport_index #define GL_AMD_vertex_shader_viewport_index 1 #endif #ifndef GL_AMD_vertex_shader_layer #define GL_AMD_vertex_shader_layer 1 #endif #ifndef GL_NV_bindless_texture #define GL_NV_bindless_texture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLuint64 APIENTRY glGetTextureHandleNV (GLuint texture); GLAPI GLuint64 APIENTRY glGetTextureSamplerHandleNV (GLuint texture, GLuint sampler); GLAPI void APIENTRY glMakeTextureHandleResidentNV (GLuint64 handle); GLAPI void APIENTRY glMakeTextureHandleNonResidentNV (GLuint64 handle); GLAPI GLuint64 APIENTRY glGetImageHandleNV (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); GLAPI void APIENTRY glMakeImageHandleResidentNV (GLuint64 handle, GLenum access); GLAPI void APIENTRY glMakeImageHandleNonResidentNV (GLuint64 handle); GLAPI void APIENTRY glUniformHandleui64NV (GLint location, GLuint64 value); GLAPI void APIENTRY glUniformHandleui64vNV (GLint location, GLsizei count, const GLuint64 *value); GLAPI void APIENTRY glProgramUniformHandleui64NV (GLuint program, GLint location, GLuint64 value); GLAPI void APIENTRY glProgramUniformHandleui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64 *values); GLAPI GLboolean APIENTRY glIsTextureHandleResidentNV (GLuint64 handle); GLAPI GLboolean APIENTRY glIsImageHandleResidentNV (GLuint64 handle); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLuint64 (APIENTRYP PFNGLGETTEXTUREHANDLENVPROC) (GLuint texture); typedef GLuint64 (APIENTRYP PFNGLGETTEXTURESAMPLERHANDLENVPROC) (GLuint texture, GLuint sampler); typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle); typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC) (GLuint64 handle); typedef GLuint64 (APIENTRYP PFNGLGETIMAGEHANDLENVPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle, GLenum access); typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC) (GLuint64 handle); typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64NVPROC) (GLint location, GLuint64 value); typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64VNVPROC) (GLint location, GLsizei count, const GLuint64 *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC) (GLuint program, GLint location, GLuint64 value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values); typedef GLboolean (APIENTRYP PFNGLISTEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle); typedef GLboolean (APIENTRYP PFNGLISIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle); #endif #ifndef GL_NV_shader_atomic_float #define GL_NV_shader_atomic_float 1 #endif #ifndef GL_AMD_query_buffer_object #define GL_AMD_query_buffer_object 1 #endif #ifndef GL_AMD_sparse_texture #define GL_AMD_sparse_texture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTexStorageSparseAMD (GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); GLAPI void APIENTRY glTextureStorageSparseAMD (GLuint texture, GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXSTORAGESPARSEAMDPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); typedef void (APIENTRYP PFNGLTEXTURESTORAGESPARSEAMDPROC) (GLuint texture, GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); #endif #ifdef __cplusplus } #endif #endif mupen64plus-core/src/r4300/r4300_core.h000664 001750 001750 00000005026 12655644434 020342 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - r4300_core.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_R4300_R4300_CORE_H #define M64P_R4300_R4300_CORE_H #include "cp0.h" #include "interupt.h" #include "mi_controller.h" #include "tlb.h" #include struct r4300_core { struct mi_controller mi; }; void init_r4300(struct r4300_core* r4300); int64_t* r4300_regs(void); int64_t* r4300_mult_hi(void); int64_t* r4300_mult_lo(void); unsigned int* r4300_llbit(void); uint32_t* r4300_pc(void); uint32_t* r4300_last_addr(void); unsigned int* r4300_next_interrupt(void); unsigned int get_r4300_emumode(void); /* Allow cached/dynarec r4300 implementations to invalidate * their cached code at [address, address+size] * * If size == 0, r4300 implementation should invalidate * all cached code. */ void invalidate_r4300_cached_code(uint32_t address, size_t size); /* Jump to the given address. This works for all r4300 emulator, but is slower. * Use this for common code which can be executed from any r4300 emulator. */ void generic_jump_to(unsigned int address); void savestates_load_set_pc(uint32_t pc); #endif glide2gl/src/Glide64/ucode.h000664 001750 001750 00000275011 12655644434 016653 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** #ifndef _GLIDE64_UCODE_GENERIC_H #define _GLIDE64_UCODE_GENERIC_H #define ucode_Fast3D 0 // ** F3D ** #define ucode_F3DEX 1 // ** F3DEX ** #define ucode_F3DEX2 2 // ** F3DEX2 ** #define ucode_WaveRace 3 // ** WRUS ** #define ucode_StarWars 4 // ** SWSE ** #define ucode_DiddyKong 5 // ** F3DDKR ** #define ucode_S2DEX 6 // ** S2DEX ** #define ucode_PerfectDark 7 // ** F3DPD ** #define ucode_CBFD 8 // ** F3DCBFD ** #define ucode_zSort 9 // ** ZSORT ** #define ucode_Turbo3d 21 // ** TURBO3D ** // ** F3D ** #define F3D_MTX_STACKSIZE 10 #define F3D_MTX_MODELVIEW 0x00 #define F3D_MTX_PROJECTION 0x01 #define F3D_MTX_MUL 0x00 #define F3D_MTX_LOAD 0x02 #define F3D_MTX_NOPUSH 0x00 #define F3D_MTX_PUSH 0x04 #define F3D_TEXTURE_ENABLE 0x00000002 #define F3D_SHADING_SMOOTH 0x00000200 #define F3D_CULL_FRONT 0x00001000 #define F3D_CULL_BACK 0x00002000 #define F3D_CULL_BOTH 0x00003000 #define F3D_CLIPPING 0x00000000 #define F3D_MV_VIEWPORT 0x80 #define F3D_MWO_aLIGHT_1 0x00 #define F3D_MWO_bLIGHT_1 0x04 #define F3D_MWO_aLIGHT_2 0x20 #define F3D_MWO_bLIGHT_2 0x24 #define F3D_MWO_aLIGHT_3 0x40 #define F3D_MWO_bLIGHT_3 0x44 #define F3D_MWO_aLIGHT_4 0x60 #define F3D_MWO_bLIGHT_4 0x64 #define F3D_MWO_aLIGHT_5 0x80 #define F3D_MWO_bLIGHT_5 0x84 #define F3D_MWO_aLIGHT_6 0xa0 #define F3D_MWO_bLIGHT_6 0xa4 #define F3D_MWO_aLIGHT_7 0xc0 #define F3D_MWO_bLIGHT_7 0xc4 #define F3D_MWO_aLIGHT_8 0xe0 #define F3D_MWO_bLIGHT_8 0xe4 // FAST3D commands #define F3D_SPNOOP 0x00 #define F3D_MTX 0x01 #define F3D_RESERVED0 0x02 #define F3D_MOVEMEM 0x03 #define F3D_VTX 0x04 #define F3D_RESERVED1 0x05 #define F3D_DL 0x06 #define F3D_RESERVED2 0x07 #define F3D_RESERVED3 0x08 #define F3D_SPRITE2D_BASE 0x09 #define F3D_TRI1 0xBF #define F3D_CULLDL 0xBE #define F3D_POPMTX 0xBD #define F3D_MOVEWORD 0xBC #define F3D_TEXTURE 0xBB #define F3D_SETOTHERMODE_H 0xBA #define F3D_SETOTHERMODE_L 0xB9 #define F3D_ENDDL 0xB8 #define F3D_SETGEOMETRYMODE 0xB7 #define F3D_CLEARGEOMETRYMODE 0xB6 //#define F3D_LINE3D 0xB5 // Only used in Line3D #define F3D_QUAD 0xB5 #define F3D_RDPHALF_1 0xB4 #define F3D_RDPHALF_2 0xB3 #define F3D_RDPHALF_CONT 0xB2 #define F3D_TRI4 0xB1 #define F3D_TRI_UNKNOWN 0xC0 // ** F3DEX2 ** // #define F3DEX2_MTX_STACKSIZE 18 #define F3DEX2_MTX_MODELVIEW 0x00 #define F3DEX2_MTX_PROJECTION 0x04 #define F3DEX2_MTX_MUL 0x00 #define F3DEX2_MTX_LOAD 0x02 #define F3DEX2_MTX_NOPUSH 0x00 #define F3DEX2_MTX_PUSH 0x01 #define F3DEX2_TEXTURE_ENABLE 0x00000000 #define F3DEX2_SHADING_SMOOTH 0x00200000 #define F3DEX2_CULL_FRONT 0x00000200 #define F3DEX2_CULL_BACK 0x00000400 #define F3DEX2_CULL_BOTH 0x00000600 #define F3DEX2_CLIPPING 0x00800000 #define F3DEX2_MV_VIEWPORT 8 #define F3DEX2_MWO_aLIGHT_1 0x00 #define F3DEX2_MWO_bLIGHT_1 0x04 #define F3DEX2_MWO_aLIGHT_2 0x18 #define F3DEX2_MWO_bLIGHT_2 0x1c #define F3DEX2_MWO_aLIGHT_3 0x30 #define F3DEX2_MWO_bLIGHT_3 0x34 #define F3DEX2_MWO_aLIGHT_4 0x48 #define F3DEX2_MWO_bLIGHT_4 0x4c #define F3DEX2_MWO_aLIGHT_5 0x60 #define F3DEX2_MWO_bLIGHT_5 0x64 #define F3DEX2_MWO_aLIGHT_6 0x78 #define F3DEX2_MWO_bLIGHT_6 0x7c #define F3DEX2_MWO_aLIGHT_7 0x90 #define F3DEX2_MWO_bLIGHT_7 0x94 #define F3DEX2_MWO_aLIGHT_8 0xa8 #define F3DEX2_MWO_bLIGHT_8 0xac #define F3DEX2_RDPHALF_2 0xF1 #define F3DEX2_SETOTHERMODE_H 0xE3 #define F3DEX2_SETOTHERMODE_L 0xE2 #define F3DEX2_RDPHALF_1 0xE1 #define F3DEX2_SPNOOP 0xE0 #define F3DEX2_ENDDL 0xDF #define F3DEX2_DL 0xDE #define F3DEX2_LOAD_UCODE 0xDD #define F3DEX2_MOVEMEM 0xDC #define F3DEX2_MOVEWORD 0xDB #define F3DEX2_MTX 0xDA #define F3DEX2_GEOMETRYMODE 0xD9 #define F3DEX2_POPMTX 0xD8 #define F3DEX2_TEXTURE 0xD7 #define F3DEX2_DMA_IO 0xD6 #define F3DEX2_SPECIAL_1 0xD5 #define F3DEX2_SPECIAL_2 0xD4 #define F3DEX2_SPECIAL_3 0xD3 #define F3DEX2_VTX 0x01 #define F3DEX2_MODIFYVTX 0x02 #define F3DEX2_CULLDL 0x03 #define F3DEX2_BRANCH_Z 0x04 #define F3DEX2_TRI1 0x05 #define F3DEX2_TRI2 0x06 #define F3DEX2_QUAD 0x07 #define F3DEX2_LINE3D 0x08 // ** RDP graphics functions ** static void rdp_texrect(uint32_t w0, uint32_t w1); static void rdp_setscissor(uint32_t w0, uint32_t w1); static void rdp_setothermode(uint32_t w0, uint32_t w1); static void rdp_loadtlut(uint32_t w0, uint32_t w1); static void rdp_settilesize(uint32_t w0, uint32_t w1); static void rdp_loadblock(uint32_t w0, uint32_t w1); static void rdp_loadtile(uint32_t w0, uint32_t w1); static void rdp_settile(uint32_t w0, uint32_t w1); static void rdp_fillrect(uint32_t w0, uint32_t w1); static void rdp_setprimcolor(uint32_t w0, uint32_t w1); static void rdp_setcombine(uint32_t w0, uint32_t w1); static void rdp_settextureimage(uint32_t w0, uint32_t w1); static void rdp_setdepthimage(uint32_t w0, uint32_t w1); static void rdp_setcolorimage(uint32_t w0, uint32_t w1); static void rdp_trifill(uint32_t w0, uint32_t w1); static void rdp_trishade(uint32_t w0, uint32_t w1); static void rdp_tritxtr(uint32_t w0, uint32_t w1); static void rdp_trishadetxtr(uint32_t w0, uint32_t w1); static void rdp_trifillz(uint32_t w0, uint32_t w1); static void rdp_trishadez(uint32_t w0, uint32_t w1); static void rdp_tritxtrz(uint32_t w0, uint32_t w1); static void rdp_trishadetxtrz(uint32_t w0, uint32_t w1); static void rdphalf_1(uint32_t w0, uint32_t w1); static void rdphalf_2(uint32_t w0, uint32_t w1); static void rdphalf_cont(uint32_t w0, uint32_t w1); static void rsp_reserved0(uint32_t w0, uint32_t w1); static void rsp_uc5_reserved0(uint32_t w0, uint32_t w1); static void rsp_reserved1(uint32_t w0, uint32_t w1); static void rsp_reserved2(uint32_t w0, uint32_t w1); static void rsp_reserved3(uint32_t w0, uint32_t w1); static void ys_memrect(uint32_t w0, uint32_t w1); static void uc6_obj_sprite(uint32_t w0, uint32_t w1); static void modelview_load (float m[4][4]); static void modelview_mul (float m[4][4]); static void modelview_push(void); static void modelview_load_push (float m[4][4]); static void modelview_mul_push (float m[4][4]); static void projection_load (float m[4][4]); static void projection_mul (float m[4][4]); static void load_matrix (float m[4][4], uint32_t addr); static float set_sprite_combine_mode(void); //ucode 00 static void uc0_vertex(uint32_t w0, uint32_t w1); static void uc0_matrix(uint32_t w0, uint32_t w1); static void uc0_movemem(uint32_t w0, uint32_t w1); static void uc0_displaylist(uint32_t w0, uint32_t w1); static void uc0_tri1(uint32_t w0, uint32_t w1); static void uc0_tri1_mischief(uint32_t w0, uint32_t w1); static void uc0_enddl(uint32_t w0, uint32_t w1); static void uc0_culldl(uint32_t w0, uint32_t w1); static void uc0_popmatrix(uint32_t w0, uint32_t w1); static void uc0_moveword(uint32_t w0, uint32_t w1); static void uc0_texture(uint32_t w0, uint32_t w1); static void uc0_setothermode_h(uint32_t w0, uint32_t w1); static void uc0_setothermode_l(uint32_t w0, uint32_t w1); static void uc0_setgeometrymode(uint32_t w0, uint32_t w1); static void uc0_cleargeometrymode(uint32_t w0, uint32_t w1); static void uc0_line3d(uint32_t w0, uint32_t w1); static void uc0_tri4(uint32_t w0, uint32_t w1); //ucode01 static void uc1_vertex(uint32_t w0, uint32_t w1); static void uc1_tri1(uint32_t w0, uint32_t w1); static void uc1_tri2(uint32_t w0, uint32_t w1); static void uc1_line3d(uint32_t w0, uint32_t w1); static void uc1_rdphalf_1(uint32_t w0, uint32_t w1); static void uc1_branch_z(uint32_t w0, uint32_t w1); static void uc6_select_dl(uint32_t w0, uint32_t w1); static void uc6_obj_rendermode(uint32_t w0, uint32_t w1); static void uc6_bg_1cyc(uint32_t w0, uint32_t w1); static void uc6_bg_copy(uint32_t w0, uint32_t w1); static void uc6_loaducode(uint32_t w0, uint32_t w1); static void uc6_sprite2d(uint32_t w0, uint32_t w1); static void uc6_obj_loadtxtr(uint32_t w0, uint32_t w1); static void uc6_obj_rectangle(uint32_t w0, uint32_t w1); static void uc6_obj_ldtx_sprite(uint32_t w0, uint32_t w1); static void uc6_obj_ldtx_rect(uint32_t w0, uint32_t w1); static void uc6_ldtx_rect_r(uint32_t w0, uint32_t w1); static void uc6_obj_rectangle_r(uint32_t w0, uint32_t w1); static void uc6_obj_movemem(uint32_t w0, uint32_t w1); //ucode02 static void calc_point_light (VERTEX *v, float * vpos); static void uc2_quad(uint32_t w0, uint32_t w1); static void uc2_vertex_neon(uint32_t w0, uint32_t w1); static void uc2_vertex(uint32_t w0, uint32_t w1); static void uc2_modifyvtx(uint32_t w0, uint32_t w1); static void uc2_culldl(uint32_t w0, uint32_t w1); static void uc2_tri1(uint32_t w0, uint32_t w1); static void uc2_line3d(uint32_t w0, uint32_t w1); static void uc2_special3(uint32_t w0, uint32_t w1); static void uc2_special2(uint32_t w0, uint32_t w1); static void uc2_dma_io(uint32_t w0, uint32_t w1); static void uc2_pop_matrix(uint32_t w0, uint32_t w1); static void uc2_geom_mode(uint32_t w0, uint32_t w1); static void uc2_matrix(uint32_t w0, uint32_t w1); static void uc2_moveword(uint32_t w0, uint32_t w1); static void uc2_movemem(uint32_t w0, uint32_t w1); static void uc2_load_ucode(uint32_t w0, uint32_t w1); static void uc2_rdphalf_2(uint32_t w0, uint32_t w1); static void uc2_dlist_cnt(uint32_t w0, uint32_t w1); //ucode03 static void uc3_vertex(uint32_t w0, uint32_t w1); static void uc3_tri1(uint32_t w0, uint32_t w1); static void uc3_tri2(uint32_t w0, uint32_t w1); static void uc3_quad3d(uint32_t w0, uint32_t w1); //ucode04 static void uc4_vertex(uint32_t w0, uint32_t w1); static void uc4_tri1(uint32_t w0, uint32_t w1); static void uc4_quad3d(uint32_t w0, uint32_t w1); //ucode05 static void uc5_dma_offsets(uint32_t w0, uint32_t w1); static void uc5_matrix(uint32_t w0, uint32_t w1); static void uc5_vertex(uint32_t w0, uint32_t w1); static void uc5_tridma(uint32_t w0, uint32_t w1); static void uc5_dl_in_mem(uint32_t w0, uint32_t w1); static void uc5_moveword(uint32_t w0, uint32_t w1); static void uc5_setgeometrymode(uint32_t w0, uint32_t w1); static void uc5_cleargeometrymode(uint32_t w0, uint32_t w1); //ucode07 static void uc7_colorbase(uint32_t w0, uint32_t w1); static void uc7_vertex(uint32_t w0, uint32_t w1); //ucode08 static void uc8_vertex(uint32_t w0, uint32_t w1); static void uc8_moveword(uint32_t w0, uint32_t w1); static void uc8_movemem(uint32_t w0, uint32_t w1); static void uc8_tri4(uint32_t w0, uint32_t w1); //ucode09 static void uc9_rpdcmd(uint32_t w0, uint32_t w1); static void uc9_draw_object (uint8_t * addr, uint32_t type); static uint32_t uc9_load_object (uint32_t zHeader, uint32_t * rdpcmds); static void uc9_object(uint32_t w0, uint32_t w1); static void uc9_mix(uint32_t w0, uint32_t w1); static void uc9_fmlight(uint32_t w0, uint32_t w1); static void uc9_light(uint32_t w0, uint32_t w1); static void uc9_mtxtrnsp(uint32_t w0, uint32_t w1); static void uc9_mtxcat(uint32_t w0, uint32_t w1); static void uc9_mult_mpmtx(uint32_t w0, uint32_t w1); static void uc9_link_subdl(uint32_t w0, uint32_t w1); static void uc9_set_subdl(uint32_t w0, uint32_t w1); static void uc9_wait_signal(uint32_t w0, uint32_t w1); static void uc9_send_signal(uint32_t w0, uint32_t w1); static void uc9_movemem(uint32_t w0, uint32_t w1); static void uc9_setscissor(uint32_t w0, uint32_t w1); typedef void (*rdp_instr)(uint32_t w1, uint32_t w2); // RDP graphic instructions pointer table static rdp_instr gfx_instruction[10][256] = { { // uCode 0 - RSP SW 2.0X // 00-3f // games: Super Mario 64, Tetrisphere, Demos gdp_no_op, uc0_matrix, rsp_reserved0, uc0_movemem, uc0_vertex, rsp_reserved1, uc0_displaylist, rsp_reserved2, rsp_reserved3, uc6_sprite2d, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, // 40-7f: Unused gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, // 80-bf: Immediate commands gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, uc0_tri4, rdphalf_cont, rdphalf_2, rdphalf_1, uc0_line3d, uc0_cleargeometrymode, uc0_setgeometrymode, uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, uc0_moveword, uc0_popmatrix, uc0_culldl, uc0_tri1, // c0-ff: RDP commands gdp_no_op, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, rdp_texrect, rdp_texrect, gdp_load_sync, gdp_pipe_sync, gdp_tile_sync, gdp_full_sync, gdp_set_key_gb, gdp_set_key_r, gdp_set_convert, rdp_setscissor, gdp_set_prim_depth, rdp_setothermode, rdp_loadtlut, gdp_invalid, rdp_settilesize, rdp_loadblock, rdp_loadtile, rdp_settile, rdp_fillrect, gdp_set_fill_color, gdp_set_fog_color, gdp_set_blend_color, rdp_setprimcolor, gdp_set_env_color, rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage }, // uCode 1 - F3DEX 1.XX // 00-3f // games: Mario Kart, Star Fox { gdp_no_op, uc0_matrix, rsp_reserved0, uc0_movemem, uc1_vertex, rsp_reserved1, uc0_displaylist, rsp_reserved2, rsp_reserved3, uc6_sprite2d, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, // 40-7f: unused gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, // 80-bf: Immediate commands gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, uc6_loaducode, uc1_branch_z, uc1_tri2, uc2_modifyvtx, rdphalf_2, uc1_rdphalf_1, uc1_line3d, uc0_cleargeometrymode, uc0_setgeometrymode, uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, uc0_moveword, uc0_popmatrix, uc2_culldl, uc1_tri1, // c0-ff: RDP commands gdp_no_op, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, rdp_texrect, rdp_texrect, gdp_load_sync, gdp_pipe_sync, gdp_tile_sync, gdp_full_sync, gdp_set_key_gb, gdp_set_key_r, gdp_set_convert, rdp_setscissor, gdp_set_prim_depth, rdp_setothermode, rdp_loadtlut, gdp_invalid, rdp_settilesize, rdp_loadblock, rdp_loadtile, rdp_settile, rdp_fillrect, gdp_set_fill_color, gdp_set_fog_color, gdp_set_blend_color, rdp_setprimcolor, gdp_set_env_color, rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage }, // uCode 2 - F3DEX 2.XX // games: Zelda 64 { // 00-3f gdp_no_op, uc2_vertex, uc2_modifyvtx, uc2_culldl, uc1_branch_z, uc2_tri1, uc2_quad, uc2_quad, uc2_line3d, uc6_bg_1cyc, uc6_bg_copy, uc6_obj_rendermode/*gdp_invalid*/, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, // 40-7f: unused gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, // 80-bf: unused gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, // c0-ff: RDP commands mixed with uc2 commands gdp_no_op, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, gdp_invalid, gdp_invalid, gdp_invalid, uc2_special3, uc2_special2, uc2_dlist_cnt, uc2_dma_io, uc0_texture, uc2_pop_matrix, uc2_geom_mode, uc2_matrix, uc2_moveword, uc2_movemem, uc2_load_ucode, uc0_displaylist, uc0_enddl, gdp_no_op, uc1_rdphalf_1, uc0_setothermode_l, uc0_setothermode_h, rdp_texrect, rdp_texrect, gdp_load_sync, gdp_pipe_sync, gdp_tile_sync, gdp_full_sync, gdp_set_key_gb, gdp_set_key_r, gdp_set_convert, rdp_setscissor, gdp_set_prim_depth, rdp_setothermode, rdp_loadtlut, uc2_rdphalf_2, rdp_settilesize, rdp_loadblock, rdp_loadtile, rdp_settile, rdp_fillrect, gdp_set_fill_color, gdp_set_fog_color, gdp_set_blend_color, rdp_setprimcolor, gdp_set_env_color, rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage }, // uCode 3 - "RSP SW 2.0D", but not really // 00-3f // games: Wave Race // ** Added by Gonetz ** { gdp_no_op, uc0_matrix, rsp_reserved0, uc0_movemem, uc3_vertex, rsp_reserved1, uc0_displaylist, rsp_reserved2, rsp_reserved3, uc6_sprite2d, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, // 40-7f: unused gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, // 80-bf: Immediate commands gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, uc3_tri2, rdphalf_cont, rdphalf_2, rdphalf_1, uc3_quad3d, uc0_cleargeometrymode, uc0_setgeometrymode, uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, uc0_moveword, uc0_popmatrix, uc0_culldl, uc3_tri1, // c0-ff: RDP commands gdp_no_op, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, rdp_texrect, rdp_texrect, gdp_load_sync, gdp_pipe_sync, gdp_tile_sync, gdp_full_sync, gdp_set_key_gb, gdp_set_key_r, gdp_set_convert, rdp_setscissor, gdp_set_prim_depth, rdp_setothermode, rdp_loadtlut, gdp_invalid, rdp_settilesize, rdp_loadblock, rdp_loadtile, rdp_settile, rdp_fillrect, gdp_set_fill_color, gdp_set_fog_color, gdp_set_blend_color, rdp_setprimcolor, gdp_set_env_color, rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage }, { // uCode 4 - RSP SW 2.0D EXT // 00-3f // games: Star Wars: Shadows of the Empire gdp_no_op, uc0_matrix, rsp_reserved0, uc0_movemem, uc4_vertex, rsp_reserved1, uc0_displaylist, rsp_reserved2, rsp_reserved3, uc6_sprite2d, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, // 40-7f: Unused gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, // 80-bf: Immediate commands gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, uc0_tri4, rdphalf_cont, rdphalf_2, rdphalf_1, uc4_quad3d, uc0_cleargeometrymode, uc0_setgeometrymode, uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, uc0_moveword, uc0_popmatrix, uc0_culldl, uc4_tri1, // c0-ff: RDP commands gdp_no_op, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, rdp_texrect, rdp_texrect, gdp_load_sync, gdp_pipe_sync, gdp_tile_sync, gdp_full_sync, gdp_set_key_gb, gdp_set_key_r, gdp_set_convert, rdp_setscissor, gdp_set_prim_depth, rdp_setothermode, rdp_loadtlut, gdp_invalid, rdp_settilesize, rdp_loadblock, rdp_loadtile, rdp_settile, rdp_fillrect, gdp_set_fill_color, gdp_set_fog_color, gdp_set_blend_color, rdp_setprimcolor, gdp_set_env_color, rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage }, { // uCode 5 - RSP SW 2.0 Diddy // 00-3f // games: Diddy Kong Racing gdp_no_op, uc5_matrix, rsp_uc5_reserved0, uc0_movemem, uc5_vertex, uc5_tridma, uc0_displaylist, uc5_dl_in_mem, rsp_reserved3, uc6_sprite2d, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, // 40-7f: Unused gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, // 80-bf: Immediate commands gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, uc0_tri4, rdphalf_cont, rdphalf_2, rdphalf_1, uc0_line3d, uc5_cleargeometrymode, uc5_setgeometrymode, uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, uc5_moveword, uc0_popmatrix, uc0_culldl, uc5_dma_offsets, // c0-ff: RDP commands gdp_no_op, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, rdp_texrect, rdp_texrect, gdp_load_sync, gdp_pipe_sync, gdp_tile_sync, gdp_full_sync, gdp_set_key_gb, gdp_set_key_r, gdp_set_convert, rdp_setscissor, gdp_set_prim_depth, rdp_setothermode, rdp_loadtlut, gdp_invalid, rdp_settilesize, rdp_loadblock, rdp_loadtile, rdp_settile, rdp_fillrect, gdp_set_fill_color, gdp_set_fog_color, gdp_set_blend_color, rdp_setprimcolor, gdp_set_env_color, rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage }, // uCode 6 - S2DEX 1.XX // games: Yoshi's Story { gdp_no_op, uc6_bg_1cyc, uc6_bg_copy, uc6_obj_rectangle, uc6_obj_sprite, uc6_obj_movemem, uc0_displaylist, rsp_reserved2, rsp_reserved3, gdp_invalid/*uc6_sprite2d*/, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, // 40-7f: unused gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, // 80-bf: Immediate commands gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, uc6_loaducode, uc6_select_dl, uc6_obj_rendermode, uc6_obj_rectangle_r, rdphalf_2, rdphalf_1, uc1_line3d, uc0_cleargeometrymode, uc0_setgeometrymode, uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, uc0_moveword, uc0_popmatrix, uc2_culldl, uc1_tri1, // c0-ff: RDP commands gdp_no_op, uc6_obj_loadtxtr, uc6_obj_ldtx_sprite, uc6_obj_ldtx_rect, uc6_ldtx_rect_r, gdp_invalid, gdp_invalid, gdp_invalid, rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, rdp_texrect, rdp_texrect, gdp_load_sync, gdp_pipe_sync, gdp_tile_sync, gdp_full_sync, gdp_set_key_gb, gdp_set_key_r, gdp_set_convert, rdp_setscissor, gdp_set_prim_depth, rdp_setothermode, rdp_loadtlut, gdp_invalid, rdp_settilesize, rdp_loadblock, rdp_loadtile, rdp_settile, rdp_fillrect, gdp_set_fill_color, gdp_set_fog_color, gdp_set_blend_color, rdp_setprimcolor, gdp_set_env_color, rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage }, // uCode 7 - unknown // games: Perfect Dark { // 00-3f gdp_no_op, uc0_matrix, rsp_reserved0, uc0_movemem, uc7_vertex, rsp_reserved1, uc0_displaylist, uc7_colorbase, rsp_reserved3, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, // 40-7f: unused gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, // 80-bf: unused gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, uc0_tri4, rdphalf_cont, rdphalf_2, rdphalf_1, uc1_tri2, uc0_cleargeometrymode, uc0_setgeometrymode, uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, uc0_moveword, uc0_popmatrix, uc0_culldl, uc0_tri1, // c0-ff: RDP commands mixed with uc2 commands gdp_no_op, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, rdp_texrect, rdp_texrect, gdp_load_sync, gdp_pipe_sync, gdp_tile_sync, gdp_full_sync, gdp_set_key_gb, gdp_set_key_r, gdp_set_convert, rdp_setscissor, gdp_set_prim_depth, rdp_setothermode, rdp_loadtlut, rdphalf_2, rdp_settilesize, rdp_loadblock, rdp_loadtile, rdp_settile, rdp_fillrect, gdp_set_fill_color, gdp_set_fog_color, gdp_set_blend_color, rdp_setprimcolor, gdp_set_env_color, rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage }, // uCode 8 - unknown // games: Conker's Bad Fur Day { // 00-3f gdp_no_op, uc8_vertex, uc2_modifyvtx, uc2_culldl, uc1_branch_z, uc2_tri1, uc2_quad, uc2_quad, uc2_line3d, uc6_bg_1cyc, uc6_bg_copy, uc6_obj_rendermode/*gdp_invalid*/, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, // 40-7f: unused gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, // 80-bf: unused gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, // c0-ff: RDP commands mixed with uc2 commands gdp_no_op, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, gdp_invalid, gdp_invalid, gdp_invalid, uc2_special3, uc2_special2, uc2_dlist_cnt, uc2_dma_io, uc0_texture, uc2_pop_matrix, uc2_geom_mode, uc2_matrix, uc8_moveword, uc8_movemem, uc2_load_ucode, uc0_displaylist, uc0_enddl, gdp_no_op, rdphalf_1, uc0_setothermode_l, uc0_setothermode_h, rdp_texrect, rdp_texrect, gdp_load_sync, gdp_pipe_sync, gdp_tile_sync, gdp_full_sync, gdp_set_key_gb, gdp_set_key_r, gdp_set_convert, rdp_setscissor, gdp_set_prim_depth, rdp_setothermode, rdp_loadtlut, uc2_rdphalf_2, rdp_settilesize, rdp_loadblock, rdp_loadtile, rdp_settile, rdp_fillrect, gdp_set_fill_color, gdp_set_fog_color, gdp_set_blend_color, rdp_setprimcolor, gdp_set_env_color, rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage }, { // uCode 9 - gzsort // games: Telefoot Soccer // 00-3f gdp_no_op, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, // 40-7f: Unused gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, // 80-bf: Immediate commands uc9_object, uc9_rpdcmd, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, rdphalf_1, gdp_invalid, uc0_cleargeometrymode, uc0_setgeometrymode, uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, uc0_moveword, gdp_invalid, uc0_culldl, gdp_invalid, // c0-ff: RDP commands gdp_no_op, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, gdp_invalid, rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, uc9_mix, uc9_fmlight, uc9_light, gdp_invalid, uc9_mtxtrnsp, uc9_mtxcat, uc9_mult_mpmtx, uc9_link_subdl, uc9_set_subdl, uc9_wait_signal, uc9_send_signal, uc0_moveword, uc9_movemem, gdp_invalid, uc0_displaylist, uc0_enddl, gdp_invalid, gdp_invalid, uc0_setothermode_l, uc0_setothermode_h, rdp_texrect, rdp_texrect, gdp_load_sync, gdp_pipe_sync, gdp_tile_sync, gdp_full_sync, gdp_set_key_gb, gdp_set_key_r, gdp_set_convert, uc9_setscissor, gdp_set_prim_depth, rdp_setothermode, rdp_loadtlut, rdphalf_2, rdp_settilesize, rdp_loadblock, rdp_loadtile, rdp_settile, rdp_fillrect, gdp_set_fill_color, gdp_set_fog_color, gdp_set_blend_color, rdp_setprimcolor, gdp_set_env_color, rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage }, }; #endif glide2gl/src/Glide64/TexCache.h000664 001750 001750 00000003757 12655644434 017246 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** #ifndef TEXCACHE_H #define TEXCACHE_H void TexCacheInit(void); void TexCache(void); void ClearCache(void); extern uint8_t * texture_buffer; #endif //TEXCACHE_H gles2rice/src/OGLExtCombiner.cpp000664 001750 001750 00000027050 12655644434 017656 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "osal_opengl.h" #include "OGLDebug.h" #include "OGLExtCombiner.h" #include "OGLExtRender.h" #include "OGLDecodedMux.h" #include "OGLTexture.h" #define GL_MODULATE_ADD_ATI 0x8744 #define GL_MODULATE_SUBTRACT_ATI 0x8746 //======================================================================== COGLColorCombiner4::COGLColorCombiner4(CRender *pRender) :COGLColorCombiner(pRender), m_maxTexUnits(0), m_lastIndex(-1), m_dwLastMux0(0), m_dwLastMux1(0) { m_bSupportModAdd_ATI = false; m_bSupportModSub_ATI = false; delete m_pDecodedMux; m_pDecodedMux = new COGLExtDecodedMux; } ////////////////////////////////////////////////////////////////////////// bool COGLColorCombiner4::Initialize(void) { m_bSupportModAdd_ATI = false; m_bSupportModSub_ATI = false; m_maxTexUnits = 1; return true; } //======================================================================== void COGLColorCombiner4::InitCombinerCycleFill(void) { for( int i=0; iEnableTexUnit(i, false); } } ////////////////////////////////////////////////////////////////////////// void COGLColorCombiner4::InitCombinerCycle12(void) { #ifdef DEBUGGER if( debuggerDropCombiners ) { UpdateCombiner(m_pDecodedMux->m_dwMux0,m_pDecodedMux->m_dwMux1); m_vCompiledSettings.clear(); m_dwLastMux0 = m_dwLastMux1 = 0; debuggerDropCombiners = false; } #endif m_pOGLRender->EnableMultiTexture(); bool combinerIsChanged = false; if( m_pDecodedMux->m_dwMux0 != m_dwLastMux0 || m_pDecodedMux->m_dwMux1 != m_dwLastMux1 || m_lastIndex < 0 ) { combinerIsChanged = true; m_lastIndex = FindCompiledMux(); if( m_lastIndex < 0 ) // Can not found { m_lastIndex = ParseDecodedMux(); #ifdef DEBUGGER DisplaySimpleMuxString(); #endif } m_dwLastMux0 = m_pDecodedMux->m_dwMux0; m_dwLastMux1 = m_pDecodedMux->m_dwMux1; } if( m_bCycleChanged || combinerIsChanged || gRDP.texturesAreReloaded || gRDP.colorsAreReloaded ) { if( m_bCycleChanged || combinerIsChanged ) { GenerateCombinerSettingConstants(m_lastIndex); GenerateCombinerSetting(m_lastIndex); } else if( gRDP.colorsAreReloaded ) { GenerateCombinerSettingConstants(m_lastIndex); } m_pOGLRender->SetAllTexelRepeatFlag(); gRDP.colorsAreReloaded = false; gRDP.texturesAreReloaded = false; } else { m_pOGLRender->SetAllTexelRepeatFlag(); } } ////////////////////////////////////////////////////////////////////////// int COGLColorCombiner4::ParseDecodedMux() { return 0; } int COGLColorCombiner4::ParseDecodedMux2Units() { OGLExtCombinerSaveType res; for( int k=0; k<8; k++ ) res.units[k].tex = -1; res.numOfUnits = 2; for( int i=0; isplitType[i]; N64CombinerType &m = m_pDecodedMux->m_n64Combiners[i]; comb.arg0 = comb.arg1 = comb.arg2 = MUX_0; switch( type ) { case CM_FMT_TYPE_NOT_USED: comb.arg0 = MUX_COMBINED; unit.ops[i%2] = GL_REPLACE; break; case CM_FMT_TYPE_D: // = A comb.arg0 = m.d; unit.ops[i%2] = GL_REPLACE; break; default: comb.arg0 = m.a; comb.arg1 = m.b; comb.arg2 = m.c; unit.ops[i%2] = GL_INTERPOLATE; break; } } if( m_pDecodedMux->splitType[2] == CM_FMT_TYPE_NOT_USED && m_pDecodedMux->splitType[3] == CM_FMT_TYPE_NOT_USED && !m_bTex1Enabled ) { res.numOfUnits = 1; } res.units[0].tex = 0; res.units[1].tex = 1; return SaveParsedResult(res); } const char* COGLColorCombiner4::GetOpStr(GLenum op) { switch( op ) { case GL_REPLACE: return "REPLACE"; case GL_MODULATE_ADD_ATI: return "MULADD"; default: return "SUB"; } } int COGLColorCombiner4::SaveParsedResult(OGLExtCombinerSaveType &result) { result.dwMux0 = m_pDecodedMux->m_dwMux0; result.dwMux1 = m_pDecodedMux->m_dwMux1; for( int n=0; n= GL_TEXTURE0 && val <= GL_TEXTURE7 ) return true; else return false; } #ifdef DEBUGGER extern const char *translatedCombTypes[]; void COGLColorCombiner4::DisplaySimpleMuxString(void) { char buf0[30], buf1[30], buf2[30]; OGLExtCombinerSaveType &result = m_vCompiledSettings[m_lastIndex]; COGLColorCombiner::DisplaySimpleMuxString(); DebuggerAppendMsg("OpenGL 1.2: %d Stages", result.numOfUnits); for( int i=0; im_dwMux0 && m_vCompiledSettings[i].dwMux1 == m_pDecodedMux->m_dwMux1 ) return (int)i; } return -1; } //======================================================================== GLint COGLColorCombiner4::RGBArgsMap4[] = { GL_TEXTURE0, //MUX_TEXEL0, GL_TEXTURE0, //MUX_T0_ALPHA, }; //======================================================================== GLint COGLColorCombiner4::MapRGBArgs(uint8_t arg) { return RGBArgsMap4[arg&MUX_MASK]; } GLint COGLColorCombiner4::MapRGBArgFlags(uint8_t arg) { if( (arg & MUX_ALPHAREPLICATE) && (arg & MUX_COMPLEMENT) ) { return GL_ONE_MINUS_SRC_ALPHA; } else if( (arg & MUX_ALPHAREPLICATE) ) { return GL_SRC_ALPHA; } else if(arg & MUX_COMPLEMENT) { return GL_ONE_MINUS_SRC_COLOR; } else return GL_SRC_COLOR; } GLint COGLColorCombiner4::MapAlphaArgs(uint8_t arg) { return RGBArgsMap4[arg&MUX_MASK]; } GLint COGLColorCombiner4::MapAlphaArgFlags(uint8_t arg) { if(arg & MUX_COMPLEMENT) { return GL_ONE_MINUS_SRC_ALPHA; } else return GL_SRC_ALPHA; } //======================================================================== void ApplyFor1Unit(OGLExtCombinerType &unit) { } ////////////////////////////////////////////////////////////////////////// void COGLColorCombiner4::GenerateCombinerSetting(int index) { OGLExtCombinerSaveType &res = m_vCompiledSettings[index]; // Texture unit 0 COGLTexture* pTexture = NULL; COGLTexture* pTexture1 = NULL; if( m_bTex0Enabled || m_bTex1Enabled || gRDP.otherMode.cycle_type == CYCLE_TYPE_COPY ) { if( m_bTex0Enabled || gRDP.otherMode.cycle_type == CYCLE_TYPE_COPY ) { pTexture = g_textures[gRSP.curTile].m_pCOGLTexture; if( pTexture ) m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0); } if( m_bTex1Enabled ) { pTexture1 = g_textures[(gRSP.curTile+1)&7].m_pCOGLTexture; if( pTexture1 ) m_pOGLRender->BindTexture(pTexture1->m_dwTextureName, 1); } } for( int i=0; iEnableTexUnit(i, true); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); OPENGL_CHECK_ERRORS; ApplyFor1Unit(res.units[i]); } if( res.numOfUnits < m_maxTexUnits ) { for( int i=res.numOfUnits; iDisBindTexture(0, i); m_pOGLRender->EnableTexUnit(i, false); } } } void COGLColorCombiner4::GenerateCombinerSettingConstants(int index) { OGLExtCombinerSaveType &res = m_vCompiledSettings[index]; float *fv; float tempf[4]; bool isUsed = true; if( res.primIsUsed ) { fv = GetPrimitiveColorfv(); // CONSTANT COLOR } else if( res.envIsUsed ) { fv = GetEnvColorfv(); // CONSTANT COLOR } else if( res.lodFracIsUsed ) { float frac = gRDP.LODFrac / 255.0f; tempf[0] = tempf[1] = tempf[2] = tempf[3] = frac; fv = &tempf[0]; } else { isUsed = false; } if( isUsed ) { for( int i=0; imi); } int64_t* r4300_regs(void) { return reg; } int64_t* r4300_mult_hi(void) { return &hi; } int64_t* r4300_mult_lo(void) { return &lo; } unsigned int* r4300_llbit(void) { return &llbit; } uint32_t* r4300_pc(void) { #ifdef NEW_DYNAREC return (r4300emu == CORE_DYNAREC) ? (uint32_t*)&pcaddr : &PC->addr; #else return &PC->addr; #endif } uint32_t* r4300_last_addr(void) { return &last_addr; } unsigned int* r4300_next_interrupt(void) { return &next_interupt; } unsigned int get_r4300_emumode(void) { return r4300emu; } void invalidate_r4300_cached_code(uint32_t address, size_t size) { if (r4300emu != CORE_PURE_INTERPRETER) { #ifdef NEW_DYNAREC if (r4300emu == CORE_DYNAREC) { invalidate_cached_code_new_dynarec(address, size); } else #endif { invalidate_cached_code_hacktarux(address, size); } } } /* XXX: not really a good interface but it gets the job done... */ void savestates_load_set_pc(uint32_t pc) { #ifdef NEW_DYNAREC if (r4300emu == CORE_DYNAREC) { pcaddr = pc; pending_exception = 1; invalidate_all_pages(); } else #endif { generic_jump_to(pc); invalidate_r4300_cached_code(0,0); } } mupen64plus-core/src/r4300/hacktarux_dynarec/rjump.c000664 001750 001750 00000020120 12655644434 023401 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - rjump.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2007 Richard Goedeken (Richard42) * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include "assemble.h" #include "api/m64p_types.h" #include "api/callbacks.h" #include "r4300/cached_interp.h" #include "r4300/recomp.h" #include "r4300/r4300.h" #include "r4300/macros.h" #include "r4300/ops.h" #include "r4300/recomph.h" /* that's where the dynarec will restart when going back from a C function */ #if defined(__x86_64__) static uint64_t *return_address; static int64_t save_rsp = 0; static int64_t save_rip = 0; #else #ifdef __GNUC__ # define ASM_NAME(name) __asm(name) #else # define ASM_NAME(name) #endif static int32_t save_ebp ASM_NAME("save_ebp") = 0; static int32_t save_ebx ASM_NAME("save_ebx") = 0; static int32_t save_esi ASM_NAME("save_esi") = 0; static int32_t save_edi ASM_NAME("save_edi") = 0; static int32_t save_esp ASM_NAME("save_esp") = 0; static int32_t save_eip ASM_NAME("save_eip") = 0; static uint32_t *return_address ASM_NAME("return_address"); #endif void dyna_jump(void) { if (stop == 1) { dyna_stop(); return; } if (PC->reg_cache_infos.need_map) *return_address = (native_type)(PC->reg_cache_infos.jump_wrapper); else *return_address = (native_type)(actual->code + PC->local_addr); } #if !defined(__x86_64__) #if defined(WIN32) && !defined(__GNUC__) /* this warning disable only works if placed outside of the scope of a function */ #pragma warning(disable:4731) /* frame pointer register 'ebp' modified by inline assembly code */ #endif #endif void dyna_start(void *code) { /* save the base and stack pointers */ /* make a call and a pop to retrieve the instruction pointer and save it too */ /* then call the code(), which should theoretically never return. */ /* When dyna_stop() sets the *return_address to the saved RIP (x86_64) / EIP (x86), * the emulator thread will come back here. */ /* It will jump to label 2, restore the base and stack pointers, and exit this function */ #if defined(__x86_64__) #if defined(__GNUC__) asm volatile (" push %%rbx \n" /* we must push an even # of registers to keep stack 16-byte aligned */ " push %%r12 \n" " push %%r13 \n" " push %%r14 \n" " push %%r15 \n" " push %%rbp \n" " mov %%rsp, %[save_rsp] \n" " lea %[reg], %%r15 \n" /* store the base location of the r4300 registers in r15 for addressing */ " call 1f \n" " jmp 2f \n" "1: \n" " pop %%rax \n" " mov %%rax, %[save_rip] \n" " sub $0x10, %%rsp \n" " and $-16, %%rsp \n" /* ensure that stack is 16-byte aligned */ " mov %%rsp, %%rax \n" " sub $8, %%rax \n" " mov %%rax, %[return_address]\n" " call *%%rbx \n" "2: \n" " mov %[save_rsp], %%rsp \n" " pop %%rbp \n" " pop %%r15 \n" " pop %%r14 \n" " pop %%r13 \n" " pop %%r12 \n" " pop %%rbx \n" : [save_rsp]"=m"(save_rsp), [save_rip]"=m"(save_rip), [return_address]"=m"(return_address) : "b" (code), [reg]"m"(*reg) : "%rax", "memory" ); #endif /* clear the registers so we don't return here a second time; that would be a bug */ save_rsp=0; save_rip=0; #else #if defined(WIN32) && !defined(__GNUC__) __asm { mov save_ebp, ebp mov save_esp, esp mov save_ebx, ebx mov save_esi, esi mov save_edi, edi call point1 jmp point2 point1: pop eax mov save_eip, eax sub esp, 0x10 and esp, 0xfffffff0 mov return_address, esp sub return_address, 4 mov eax, code call eax point2: mov ebp, save_ebp mov esp, save_esp mov ebx, save_ebx mov esi, save_esi mov edi, save_edi } #elif defined(__GNUC__) && defined(__i386__) #if defined(__PIC__) #ifndef __GNUC_PREREQ # if defined __GNUC__ && defined __GNUC_MINOR__ # define __GNUC_PREREQ(maj, min) \ ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) # else # define __GNUC_PREREQ(maj, min) 0 # endif #endif /* for -fPIC (shared libraries) */ #if defined(ANDROID_X86) || __GNUC_PREREQ (4, 7) # define GET_PC_THUNK_STR(reg) "__x86.get_pc_thunk." #reg #else # define GET_PC_THUNK_STR(reg) "__i686.get_pc_thunk." #reg #endif #define STORE_EBX #define LOAD_EBX "call " GET_PC_THUNK_STR(bx) " \n" \ "addl $_GLOBAL_OFFSET_TABLE_, %%ebx \n" #else /* for non-PIC binaries */ #define STORE_EBX "movl %%ebx, %[save_ebx] \n" #define LOAD_EBX "movl %[save_ebx], %%ebx \n" #endif __asm(STORE_EBX " movl %%ebp, %[save_ebp] \n" " movl %%esp, %[save_esp] \n" " movl %%esi, %[save_esi] \n" " movl %%edi, %[save_edi] \n" " call 1f \n" " jmp 2f \n" "1: \n" " popl %%eax \n" " movl %%eax, %[save_eip] \n" " subl $16, %%esp \n" /* save 16 bytes of padding just in case */ " andl $-16, %%esp \n" /* align stack on 16-byte boundary for OSX */ " movl %%esp, %[return_address] \n" " subl $4, %[return_address] \n" " call *%[codeptr] \n" "2: \n" LOAD_EBX " movl %[save_ebp], %%ebp \n" " movl %[save_esp], %%esp \n" " movl %[save_esi], %%esi \n" " movl %[save_edi], %%edi \n" : [save_ebp]"=m"(save_ebp), [save_esp]"=m"(save_esp), [save_ebx]"=m"(save_ebx), [save_esi]"=m"(save_esi), [save_edi]"=m"(save_edi), [save_eip]"=m"(save_eip), [return_address]"=m"(return_address) : [codeptr]"r"(code) : "eax", "ecx", "edx", "memory" ); #endif /* clear the registers so we don't return here a second time; that would be a bug */ /* this is also necessary to prevent compiler from optimizing out the static variables */ save_edi=0; save_esi=0; save_ebx=0; save_ebp=0; save_esp=0; save_eip=0; #endif } void dyna_stop(void) { #if defined(__x86_64__) if (save_rip != 0) { *return_address = (native_type)save_rip; return; } #else if (save_eip != 0) { *return_address = (native_type) save_eip; return; } #endif DebugMessage(M64MSG_WARNING, "Instruction pointer is 0 at dyna_stop()"); } mupen64plus-video-gliden64/src/GLideNHQ/TxCache.h000664 001750 001750 00000004105 12655644434 022451 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __TXCACHE_H__ #define __TXCACHE_H__ #include "TxInternal.h" #include "TxUtil.h" #include #include class TxCache { private: std::list _cachelist; uint8 *_gzdest0; uint8 *_gzdest1; uint32 _gzdestLen; protected: int _options; tx_wstring _ident; tx_wstring _path; dispInfoFuncExt _callback; TxUtil *_txUtil; struct TXCACHE { int size; GHQTexInfo info; std::list::iterator it; }; int _totalSize; int _cacheSize; std::map _cache; boolean save(const wchar_t *path, const wchar_t *filename, const int config); boolean load(const wchar_t *path, const wchar_t *filename, const int config); boolean del(uint64 checksum); /* checksum hi:palette low:texture */ boolean is_cached(uint64 checksum); /* checksum hi:palette low:texture */ void clear(); public: ~TxCache(); TxCache(int options, int cachesize, const wchar_t *path, const wchar_t *ident, dispInfoFuncExt callback); boolean add(uint64 checksum, /* checksum hi:palette low:texture */ GHQTexInfo *info, int dataSize = 0); boolean get(uint64 checksum, /* checksum hi:palette low:texture */ GHQTexInfo *info); }; #endif /* __TXCACHE_H__ */ glide2gl/src/Glide64/TexCache.c000664 001750 001750 00000173565 12655644434 017246 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** #include "Gfx_1.3.h" #include "TexCache.h" #include "TexLoad.h" #include "Combine.h" #include "Util.h" #include "GBI.h" #include "libretro.h" #include "MiClWr.h" extern retro_log_printf_t log_cb; static void LoadTex (int id, int tmu); uint8_t tex1[2048*2048*4]; // temporary texture uint8_t tex2[2048*2048*4]; uint8_t *texture; uint8_t *texture_buffer = tex1; #include "CRC.h" typedef struct TEXINFO_t { int real_image_width, real_image_height; // FOR ALIGNMENT PURPOSES ONLY!!! int tile_width, tile_height; int mask_width, mask_height; int width, height; int wid_64, line; uint32_t crc; uint32_t flags; int splitheight; } TEXINFO; TEXINFO texinfo[2]; int tex_found[2][MAX_TMU]; //**************************************************************** // List functions typedef struct NODE_t { uint32_t crc; uintptr_t data; int tmu; int number; struct NODE_t *pNext; } NODE; NODE *cachelut[65536]; static void AddToList (NODE **list, uint32_t crc, uintptr_t data, int tmu, int number) { NODE *node = (NODE*)malloc(sizeof(NODE)); node->crc = crc; node->data = data; node->tmu = tmu; node->number = number; node->pNext = *list; *list = node; rdp.n_cached[tmu] ++; rdp.n_cached[tmu^1] = rdp.n_cached[tmu]; } static void DeleteList (NODE **list) { while (*list) { NODE *next = (*list)->pNext; free(*list); *list = next; } } void TexCacheInit(void) { int i; for (i = 0; i < 65536; i++) cachelut[i] = NULL; } // Clear the texture cache for both TMUs // TMU : Texture Memory Unit (3Dfx Voodoo term) void ClearCache(void) { int i; voodoo.tmem_ptr[0] = offset_textures; rdp.n_cached[0] = 0; voodoo.tmem_ptr[1] = offset_textures; rdp.n_cached[1] = 0; for (i = 0; i < 65536; i++) DeleteList(&cachelut[i]); } //**************************************************************** static uint32_t textureCRC(uint32_t crc, uint8_t *addr, int width, int height, int line) { const size_t len = sizeof(uint32_t) * 2 * width; while (height--) { crc = CRC32(crc, addr, len); addr += len + line; } return crc; } // Gets information for either t0 or t1, checks if in cache & fills tex_found static void GetTexInfo (int id, int tile) { int t, tile_width, tile_height, mask_width, mask_height, width, height, wid_64, line; int real_image_width, real_image_height, crc_height; uint32_t crc, flags, mod, modcolor, modcolor1, modcolor2, modfactor, mod_mask; NODE *node; CACHE_LUT *cache; TEXINFO *info; FRDP (" | |-+ GetTexInfo (id: %d, tile: %d)\n", id, tile); // this is the NEW cache searching, searches only textures with similar crc's for (t = 0; t < MAX_TMU; t++) tex_found[id][t] = -1; info = (TEXINFO*)&texinfo[id]; // Get width and height tile_width = g_gdp.tile[tile].sl - g_gdp.tile[tile].sh + 1; tile_height = g_gdp.tile[tile].tl - g_gdp.tile[tile].th + 1; mask_width = (g_gdp.tile[tile].mask_s==0)?(tile_width):(1 << g_gdp.tile[tile].mask_s); mask_height = (g_gdp.tile[tile].mask_t==0)?(tile_height):(1 << g_gdp.tile[tile].mask_t); if (settings.alt_tex_size) { // ** ALTERNATE TEXTURE SIZE METHOD ** // Helps speed in some games that loaded weird-sized textures, but could break other // textures. // wrap all the way width = min(mask_width, tile_width); // changed from mask_width only rdp.tiles[tile].width = width; // Get the width/height to load if ((g_gdp.tile[tile].cs && tile_width <= 256) || (mask_width > 256)) { // actual width rdp.tiles[tile].width = tile_width; } height = min(mask_height, tile_height); rdp.tiles[tile].height = height; if ((g_gdp.tile[tile].ct && tile_height <= 256) || (mask_height > 256)) { // actual height rdp.tiles[tile].height = tile_height; } } else { // ** NORMAL TEXTURE SIZE METHOD ** // This is the 'correct' method for determining texture size, but may cause certain // textures to load too large & make the whole game go slow. if (mask_width > 256 && mask_height > 256) { mask_width = tile_width; mask_height = tile_height; } width = mask_width; rdp.tiles[tile].width = mask_width; // Get the width/height to load if ((g_gdp.tile[tile].cs && tile_width <= 256) )//|| (mask_width > 256)) { // loading width width = min(mask_width, tile_width); // actual width rdp.tiles[tile].width = tile_width; } height = mask_height; rdp.tiles[tile].height = mask_height; if ((g_gdp.tile[tile].ct && tile_height <= 256) || (mask_height > 256)) { // loading height height = min(mask_height, tile_height); // actual height rdp.tiles[tile].height = tile_height; } } // without any large texture fixing-up; for alignment real_image_width = rdp.tiles[tile].width; real_image_height = rdp.tiles[tile].height; crc_height = height; if (rdp.timg.set_by == 1) crc_height = tile_height; #ifndef NDEBUG LRDP(" | | |-+ Texture approved:\n"); FRDP (" | | | |- tmem: %08lx\n", g_gdp.tile[tile].tmem); FRDP (" | | | |- load width: %d\n", width); FRDP (" | | | |- load height: %d\n", height); FRDP (" | | | |- actual width: %d\n", rdp.tiles[tile].width); FRDP (" | | | |- actual height: %d\n", rdp.tiles[tile].height); FRDP (" | | | |- size: %d\n", g_gdp.tile[tile].size); FRDP (" | | | +- format: %d\n", g_gdp.tile[tile].format); LRDP(" | | |- Calculating CRC... "); #endif // ** CRC CHECK wid_64 = width << (g_gdp.tile[tile].size) >> 1; if (g_gdp.tile[tile].size == G_IM_SIZ_32b) { if (wid_64 & 15) wid_64 += 16; wid_64 &= 0xFFFFFFF0; } else { if (wid_64 & 7) wid_64 += 8; // round up } wid_64 = wid_64>>3; // Texture too big for tmem & needs to wrap? (trees in mm) if (g_gdp.tile[tile].tmem + min(height, tile_height) * (g_gdp.tile[tile].line << 3) > 4096) { int y, shift; LRDP("TEXTURE WRAPS TMEM!!! "); // calculate the y value that intersects at 4096 bytes y = (4096 - g_gdp.tile[tile].tmem) / (g_gdp.tile[tile].line<<3); g_gdp.tile[tile].ct = 0; g_gdp.tile[tile].tl = g_gdp.tile[tile].th + y - 1; // calc mask for (shift=0; (1< 0) // Check the CRC { if (g_gdp.tile[tile].size < 3) crc = textureCRC(crc, addr, wid_64, crc_height, line); else //32b texture { int line_2, wid_64_2; line_2 = line >> 1; wid_64_2 = max(1, wid_64 >> 1); crc = textureCRC(crc, addr, wid_64_2, crc_height, line_2); crc = textureCRC(crc, addr+0x800, wid_64_2, crc_height, line_2); } } } FRDP ("Done. CRC is: %08lx.\n", crc); flags = (g_gdp.tile[tile].cs << 23) | (g_gdp.tile[tile].ms << 22) | (g_gdp.tile[tile].mask_s << 18) | (g_gdp.tile[tile].ct << 17) | (g_gdp.tile[tile].mt << 16) | (g_gdp.tile[tile].mask_t << 12); info->real_image_width = real_image_width; info->real_image_height = real_image_height; info->tile_width = tile_width; info->tile_height = tile_height; info->mask_width = mask_width; info->mask_height = mask_height; info->width = width; info->height = height; info->wid_64 = wid_64; info->line = line; info->crc = crc; info->flags = flags; // Search the texture cache for this texture LRDP(" | | |-+ Checking cache...\n"); if (rdp.noise == NOISE_MODE_TEXTURE) return; if (id == 0) { mod = cmb.mod_0; modcolor = cmb.modcolor_0; modcolor1 = cmb.modcolor1_0; modcolor2 = cmb.modcolor2_0; modfactor = cmb.modfactor_0; } else { mod = cmb.mod_1; modcolor = cmb.modcolor_1; modcolor1 = cmb.modcolor1_1; modcolor2 = cmb.modcolor2_1; modfactor = cmb.modfactor_1; } node = (NODE*)cachelut[crc>>16]; mod_mask = (g_gdp.tile[tile].format == G_IM_FMT_CI) ? 0xFFFFFFFF : 0xF0F0F0F0; while (node) { if (node->crc == crc) { cache = (CACHE_LUT*)node->data; if (/*tex_found[id][node->tmu] == -1 && g_gdp.tile[tile].palette == cache->palette && g_gdp.tile[tile].format == cache->format && g_gdp.tile[tile].size == cache->size &&*/ rdp.tiles[tile].width == cache->width && rdp.tiles[tile].height == cache->height && flags == cache->flags) { if (!(mod+cache->mod) || (cache->mod == mod && (cache->mod_color&mod_mask) == (modcolor&mod_mask) && (cache->mod_color1&mod_mask) == (modcolor1&mod_mask) && (cache->mod_color2&mod_mask) == (modcolor2&mod_mask) && abs((int)(cache->mod_factor - modfactor)) < 8)) { FRDP (" | | | |- Texture found in cache (tmu=%d).\n", node->tmu); tex_found[id][node->tmu] = node->number; tex_found[id][node->tmu^1] = node->number; return; } } } node = node->pNext; } LRDP(" | | | +- Done.\n | | +- GetTexInfo end\n"); } #define TMUMODE_NORMAL 0 #define TMUMODE_PASSTHRU 1 #define TMUMODE_NONE 2 int SwapTextureBuffer(void); //forward decl // Does texture loading after combiner is set void TexCache(void) { int i, tmu_0_mode, tmu_1_mode, tmu_0, tmu_1; LRDP(" |-+ TexCache called\n"); if (rdp.tex & 1) GetTexInfo (0, rdp.cur_tile); if (rdp.tex & 2) GetTexInfo (1, rdp.cur_tile+1); tmu_0_mode = 0; tmu_1_mode = 0; // Select the best TMUs to use (removed 3 tmu support, unnecessary) if (rdp.tex == 3) // T0 and T1 { tmu_0 = 0; tmu_1 = 1; } else if (rdp.tex == 2) // T1 { if (tex_found[1][0] != -1) // T1 found in tmu 0 tmu_1 = 0; else if (tex_found[1][1] != -1) // T1 found in tmu 1 tmu_1 = 1; else // T1 not found tmu_1 = 0; tmu_0 = !tmu_1; tmu_0_mode = (tmu_0==1)?TMUMODE_NONE:TMUMODE_PASSTHRU; } else if (rdp.tex == 1) // T0 { if (tex_found[0][0] != -1) // T0 found in tmu 0 tmu_0 = 0; else if (tex_found[0][1] != -1) // T0 found in tmu 1 tmu_0 = 1; else // T0 not found tmu_0 = 0; tmu_1 = !tmu_0; tmu_1_mode = (tmu_1==1)?TMUMODE_NONE:TMUMODE_PASSTHRU; } else // no texture { tmu_0 = 0; tmu_0_mode = TMUMODE_NONE; tmu_1 = 0; tmu_1_mode = TMUMODE_NONE; } FRDP (" | |-+ Modes set:\n | | |- tmu_0 = %d\n | | |- tmu_1 = %d\n", tmu_0, tmu_1); FRDP (" | | |- tmu_0_mode = %d\n | | |- tmu_1_mode = %d\n", tmu_0_mode, tmu_1_mode); if (tmu_0_mode == TMUMODE_PASSTHRU) { cmb.tmu0_func = cmb.tmu0_a_func = GR_COMBINE_FUNCTION_SCALE_OTHER; cmb.tmu0_fac = cmb.tmu0_a_fac = GR_COMBINE_FACTOR_ONE; if (cmb.tex_cmb_ext_use) { cmb.t0c_ext_a = GR_CMBX_OTHER_TEXTURE_RGB; cmb.t0c_ext_a_mode = GR_FUNC_MODE_X; cmb.t0c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; cmb.t0c_ext_b_mode = GR_FUNC_MODE_ZERO; cmb.t0c_ext_c = GR_CMBX_ZERO; cmb.t0c_ext_c_invert = 1; cmb.t0c_ext_d = GR_CMBX_ZERO; cmb.t0c_ext_d_invert = 0; cmb.t0a_ext_a = GR_CMBX_OTHER_TEXTURE_ALPHA; cmb.t0a_ext_a_mode = GR_FUNC_MODE_X; cmb.t0a_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA; cmb.t0a_ext_b_mode = GR_FUNC_MODE_ZERO; cmb.t0a_ext_c = GR_CMBX_ZERO; cmb.t0a_ext_c_invert = 1; cmb.t0a_ext_d = GR_CMBX_ZERO; cmb.t0a_ext_d_invert = 0; } } else if (tmu_0_mode == TMUMODE_NONE) { cmb.tmu0_func = cmb.tmu0_a_func = GR_COMBINE_FUNCTION_NONE; cmb.tmu0_fac = cmb.tmu0_a_fac = GR_COMBINE_FACTOR_NONE; if (cmb.tex_cmb_ext_use) { cmb.t0c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB; cmb.t0c_ext_a_mode = GR_FUNC_MODE_ZERO; cmb.t0c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; cmb.t0c_ext_b_mode = GR_FUNC_MODE_ZERO; cmb.t0c_ext_c = GR_CMBX_ZERO; cmb.t0c_ext_c_invert = 0; cmb.t0c_ext_d = GR_CMBX_ZERO; cmb.t0c_ext_d_invert = 0; cmb.t0a_ext_a = GR_CMBX_LOCAL_TEXTURE_ALPHA; cmb.t0a_ext_a_mode = GR_FUNC_MODE_ZERO; cmb.t0a_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA; cmb.t0a_ext_b_mode = GR_FUNC_MODE_ZERO; cmb.t0a_ext_c = GR_CMBX_ZERO; cmb.t0a_ext_c_invert = 0; cmb.t0a_ext_d = GR_CMBX_ZERO; cmb.t0a_ext_d_invert = 0; } } if (tmu_1_mode == TMUMODE_PASSTHRU) { cmb.tmu1_func = cmb.tmu1_a_func = GR_COMBINE_FUNCTION_SCALE_OTHER; cmb.tmu1_fac = cmb.tmu1_a_fac = GR_COMBINE_FACTOR_ONE; if (cmb.tex_cmb_ext_use) { cmb.t1c_ext_a = GR_CMBX_OTHER_TEXTURE_RGB; cmb.t1c_ext_a_mode = GR_FUNC_MODE_X; cmb.t1c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; cmb.t1c_ext_b_mode = GR_FUNC_MODE_ZERO; cmb.t1c_ext_c = GR_CMBX_ZERO; cmb.t1c_ext_c_invert = 1; cmb.t1c_ext_d = GR_CMBX_ZERO; cmb.t1c_ext_d_invert = 0; cmb.t1a_ext_a = GR_CMBX_OTHER_TEXTURE_ALPHA; cmb.t1a_ext_a_mode = GR_FUNC_MODE_X; cmb.t1a_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA; cmb.t1a_ext_b_mode = GR_FUNC_MODE_ZERO; cmb.t1a_ext_c = GR_CMBX_ZERO; cmb.t1a_ext_c_invert = 1; cmb.t1a_ext_d = GR_CMBX_ZERO; cmb.t1a_ext_d_invert = 0; } } else if (tmu_1_mode == TMUMODE_NONE) { cmb.tmu1_func = cmb.tmu1_a_func = GR_COMBINE_FUNCTION_NONE; cmb.tmu1_fac = cmb.tmu1_a_fac = GR_COMBINE_FACTOR_NONE; if (cmb.tex_cmb_ext_use) { cmb.t1c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB; cmb.t1c_ext_a_mode = GR_FUNC_MODE_ZERO; cmb.t1c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; cmb.t1c_ext_b_mode = GR_FUNC_MODE_ZERO; cmb.t1c_ext_c = GR_CMBX_ZERO; cmb.t1c_ext_c_invert = 0; cmb.t1c_ext_d = GR_CMBX_ZERO; cmb.t1c_ext_d_invert = 0; cmb.t1a_ext_a = GR_CMBX_LOCAL_TEXTURE_ALPHA; cmb.t1a_ext_a_mode = GR_FUNC_MODE_ZERO; cmb.t1a_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA; cmb.t1a_ext_b_mode = GR_FUNC_MODE_ZERO; cmb.t1a_ext_c = GR_CMBX_ZERO; cmb.t1a_ext_c_invert = 0; cmb.t1a_ext_d = GR_CMBX_ZERO; cmb.t1a_ext_d_invert = 0; } } rdp.t0 = tmu_0; rdp.t1 = tmu_1; // SET the combiner { if (rdp.allow_combine) { // Now actually combine if (cmb.cmb_ext_use) { LRDP(" | | | |- combiner extension\n"); if (!(cmb.cmb_ext_use & COMBINE_EXT_COLOR)) ColorCombinerToExtension (); if (!(cmb.cmb_ext_use & COMBINE_EXT_ALPHA)) AlphaCombinerToExtension (); grColorCombineExt(cmb.c_ext_a, cmb.c_ext_a_mode, cmb.c_ext_b, cmb.c_ext_b_mode, cmb.c_ext_c, cmb.c_ext_c_invert, cmb.c_ext_d, cmb.c_ext_d_invert, 0, 0); grAlphaCombineExt(cmb.a_ext_a, cmb.a_ext_a_mode, cmb.a_ext_b, cmb.a_ext_b_mode, cmb.a_ext_c, cmb.a_ext_c_invert, cmb.a_ext_d, cmb.a_ext_d_invert, 0, 0); } else { grColorCombine (cmb.c_fnc, cmb.c_fac, cmb.c_loc, cmb.c_oth, FXFALSE); grAlphaCombine (cmb.a_fnc, cmb.a_fac, cmb.a_loc, cmb.a_oth, FXFALSE); } grConstantColorValue (cmb.ccolor); grAlphaBlendFunction (cmb.abf1, cmb.abf2, GR_BLEND_ZERO, GR_BLEND_ZERO); if (!rdp.tex) //nothing more to do return; } if (tmu_1 < NUM_TMU) { if (cmb.tex_cmb_ext_use) { LRDP(" | | | |- combiner extension tmu1\n"); if (!(cmb.tex_cmb_ext_use & TEX_COMBINE_EXT_COLOR)) TexColorCombinerToExtension (GR_TMU1); if (!(cmb.tex_cmb_ext_use & TEX_COMBINE_EXT_ALPHA)) TexAlphaCombinerToExtension (GR_TMU1); grTexColorCombineExt(tmu_1, cmb.t1c_ext_a, cmb.t1c_ext_a_mode, cmb.t1c_ext_b, cmb.t1c_ext_b_mode, cmb.t1c_ext_c, cmb.t1c_ext_c_invert, cmb.t1c_ext_d, cmb.t1c_ext_d_invert, 0, 0); grTexAlphaCombineExt(tmu_1, cmb.t1a_ext_a, cmb.t1a_ext_a_mode, cmb.t1a_ext_b, cmb.t1a_ext_b_mode, cmb.t1a_ext_c, cmb.t1a_ext_c_invert, cmb.t1a_ext_d, cmb.t1a_ext_d_invert, 0, 0, cmb.tex_ccolor); } else grTexCombine (tmu_1, cmb.tmu1_func, cmb.tmu1_fac, cmb.tmu1_a_func, cmb.tmu1_a_fac, cmb.tmu1_invert, cmb.tmu1_a_invert); grTexDetailControl (tmu_1, cmb.dc1_lodbias, cmb.dc1_detailscale, cmb.dc1_detailmax); } if (tmu_0 < NUM_TMU) { if (cmb.tex_cmb_ext_use) { LRDP(" | | | |- combiner extension tmu0\n"); if (!(cmb.tex_cmb_ext_use & TEX_COMBINE_EXT_COLOR)) TexColorCombinerToExtension (GR_TMU0); if (!(cmb.tex_cmb_ext_use & TEX_COMBINE_EXT_ALPHA)) TexAlphaCombinerToExtension (GR_TMU0); grTexColorCombineExt(tmu_0, cmb.t0c_ext_a, cmb.t0c_ext_a_mode, cmb.t0c_ext_b, cmb.t0c_ext_b_mode, cmb.t0c_ext_c, cmb.t0c_ext_c_invert, cmb.t0c_ext_d, cmb.t0c_ext_d_invert, 0, 0); grTexAlphaCombineExt(tmu_0, cmb.t0a_ext_a, cmb.t0a_ext_a_mode, cmb.t0a_ext_b, cmb.t0a_ext_b_mode, cmb.t0a_ext_c, cmb.t0a_ext_c_invert, cmb.t0a_ext_d, cmb.t0a_ext_d_invert, 0, 0, cmb.tex_ccolor); } else grTexCombine (tmu_0, cmb.tmu0_func, cmb.tmu0_fac, cmb.tmu0_a_func, cmb.tmu0_a_fac, cmb.tmu0_invert, cmb.tmu0_a_invert); grTexDetailControl (tmu_0, cmb.dc0_lodbias, cmb.dc0_detailscale, cmb.dc0_detailmax); } } if ((rdp.tex & 1) && tmu_0 < NUM_TMU) { if (tex_found[0][tmu_0] != -1) { CACHE_LUT *cache; LRDP(" | |- T0 found in cache.\n"); cache = (CACHE_LUT*)&rdp.cache[0][tex_found[0][0]]; rdp.cur_cache[0] = cache; rdp.cur_cache[0]->last_used = frame_count; rdp.cur_cache[0]->uses = 0; grTexSource (tmu_0, cache->tmem_addr, GR_MIPMAPLEVELMASK_BOTH, &cache->t_info, false); } else LoadTex (0, tmu_0); } if ((rdp.tex & 2) && tmu_1 < NUM_TMU) { if (tex_found[1][tmu_1] != -1) { CACHE_LUT *cache; LRDP(" | |- T1 found in cache.\n"); cache = (CACHE_LUT*)&rdp.cache[0][tex_found[1][0]]; rdp.cur_cache[1] = cache; rdp.cur_cache[1]->last_used = frame_count; rdp.cur_cache[1]->uses = 0; grTexSource (tmu_1, cache->tmem_addr, GR_MIPMAPLEVELMASK_BOTH, &cache->t_info, false); } else LoadTex (1, tmu_1); } { int tmu_v[2]; tmu_v[0] = tmu_0; tmu_v[1] = tmu_1; for (i = 0; i < NUM_TMU; i++) { int tile; const int tmu = tmu_v[i]; if (tmu >= NUM_TMU) continue; tile = rdp.cur_tile + i; if (rdp.cur_cache[i]) { uint32_t mode_s, mode_t; int cs, ct, filter; if (rdp.force_wrap && !rdp.texrecting) { cs = g_gdp.tile[tile].cs && g_gdp.tile[tile].sl - g_gdp.tile[tile].sh < 256; ct = g_gdp.tile[tile].ct && g_gdp.tile[tile].tl - g_gdp.tile[tile].th < 256; } else { cs = (g_gdp.tile[tile].cs || g_gdp.tile[tile].mask_s == 0) && g_gdp.tile[tile].sl - g_gdp.tile[tile].sh < 256; ct = (g_gdp.tile[tile].ct || g_gdp.tile[tile].mask_t == 0) && g_gdp.tile[tile].tl - g_gdp.tile[tile].th < 256; } mode_s = GR_TEXTURECLAMP_WRAP; mode_t = GR_TEXTURECLAMP_WRAP; if (cs) mode_s = GR_TEXTURECLAMP_CLAMP; else if (g_gdp.tile[tile].ms) mode_s = GR_TEXTURECLAMP_MIRROR_EXT; if (ct) mode_t = GR_TEXTURECLAMP_CLAMP; else if (g_gdp.tile[tile].mt) mode_t = GR_TEXTURECLAMP_MIRROR_EXT; if (settings.filtering == 0) filter = (rdp.filter_mode!=2)?GR_TEXTUREFILTER_POINT_SAMPLED:GR_TEXTUREFILTER_3POINT_LINEAR; else filter = (settings.filtering==1)? GR_TEXTUREFILTER_3POINT_LINEAR : (settings.filtering==2)?GR_TEXTUREFILTER_POINT_SAMPLED:GR_TEXTUREFILTER_BILINEAR; grTexFilterClampMode (tmu, mode_s, mode_t, filter, filter); } } } LRDP(" | +- TexCache End\n"); } // Does the actual texture loading after everything is prepared static void LoadTex(int id, int tmu) { int td, lod, aspect, shift, size_max, wid, hei, modifyPalette; uint32_t size_x, size_y, real_x, real_y, result; uint32_t mod, modcolor, modcolor1, modcolor2, modfactor; CACHE_LUT *cache; FRDP (" | |-+ LoadTex (id: %d, tmu: %d)\n", id, tmu); td = rdp.cur_tile + id; if (texinfo[id].width < 0 || texinfo[id].height < 0) return; // Clear the cache if it's full if (rdp.n_cached[tmu] >= MAX_CACHE) { LRDP("Cache count reached, clearing...\n"); ClearCache (); if (id == 1 && rdp.tex == 3) LoadTex (0, rdp.t0); } // Get this cache object cache = &rdp.cache[0][rdp.n_cached[0]]; rdp.cur_cache[id] = cache; //!Hackalert //GoldenEye water texture. It has CI format in fact, but the game set it to RGBA if ((settings.hacks&hack_GoldenEye) && g_gdp.tile[td].format == G_IM_FMT_RGBA && rdp.tlut_mode == 2 && g_gdp.tile[td].size == G_IM_SIZ_16b) { g_gdp.tile[td].format = G_IM_FMT_CI; g_gdp.tile[td].size = G_IM_SIZ_8b; } // Set the data cache->line = g_gdp.tile[td].line; cache->addr = rdp.addr[g_gdp.tile[td].tmem]; cache->crc = texinfo[id].crc; cache->palette = g_gdp.tile[td].palette; cache->width = rdp.tiles[td].width; cache->height = rdp.tiles[td].height; cache->format = g_gdp.tile[td].format; cache->size = g_gdp.tile[td].size; cache->tmem_addr = voodoo.tmem_ptr[tmu]; cache->set_by = rdp.timg.set_by; cache->texrecting = rdp.texrecting; cache->last_used = frame_count; cache->uses = 0; cache->flags = texinfo[id].flags; // Add this cache to the list AddToList (&cachelut[cache->crc>>16], cache->crc, (uintptr_t)(cache), tmu, rdp.n_cached[tmu]); // temporary cache->t_info.format = GR_TEXFMT_ARGB_1555; // Calculate lod and aspect size_x = rdp.tiles[td].width; size_y = rdp.tiles[td].height; for (shift=0; (1<scale = 256.0f; break; case 2: lod = GR_LOD_LOG2_2; cache->scale = 128.0f; break; case 4: lod = GR_LOD_LOG2_4; cache->scale = 64.0f; break; case 8: lod = GR_LOD_LOG2_8; cache->scale = 32.0f; break; case 16: lod = GR_LOD_LOG2_16; cache->scale = 16.0f; break; case 32: lod = GR_LOD_LOG2_32; cache->scale = 8.0f; break; case 64: lod = GR_LOD_LOG2_64; cache->scale = 4.0f; break; case 128: lod = GR_LOD_LOG2_128; cache->scale = 2.0f; break; case 256: lod = GR_LOD_LOG2_256; cache->scale = 1.0f; break; case 512: lod = GR_LOD_LOG2_512; cache->scale = 0.5f; break; default: lod = GR_LOD_LOG2_1024; cache->scale = 0.25f; break; } // Calculate the aspect ratio if (size_x >= size_y) { int ratio = size_x / size_y; switch (ratio) { case 1: aspect = GR_ASPECT_LOG2_1x1; cache->scale_x = 1.0f; cache->scale_y = 1.0f; break; case 2: aspect = GR_ASPECT_LOG2_2x1; cache->scale_x = 1.0f; cache->scale_y = 0.5f; real_y >>= 1; break; case 4: aspect = GR_ASPECT_LOG2_4x1; cache->scale_x = 1.0f; cache->scale_y = 0.25f; real_y >>= 2; break; default: aspect = GR_ASPECT_LOG2_8x1; cache->scale_x = 1.0f; cache->scale_y = 0.125f; real_y >>= 3; break; } } else { int ratio = size_y / size_x; switch (ratio) { case 2: aspect = GR_ASPECT_LOG2_1x2; cache->scale_x = 0.5f; cache->scale_y = 1.0f; real_x >>= 1; break; case 4: aspect = GR_ASPECT_LOG2_1x4; cache->scale_x = 0.25f; cache->scale_y = 1.0f; real_x >>= 2; break; default: aspect = GR_ASPECT_LOG2_1x8; cache->scale_x = 0.125f; cache->scale_y = 1.0f; real_x >>= 3; break; } } if (real_x != cache->width || real_y != cache->height) { cache->scale_x *= (float)cache->width / (float)real_x; cache->scale_y *= (float)cache->height / (float)real_y; } cache->splitheight = real_y; if (cache->splitheight < texinfo[id].splitheight) cache->splitheight = texinfo[id].splitheight; // ** Calculate alignment values wid = cache->width; hei = cache->height; cache->c_off = cache->scale * 0.5f; if (wid != 1) cache->c_scl_x = cache->scale; else cache->c_scl_x = 0.0f; if (hei != 1) cache->c_scl_y = cache->scale; else cache->c_scl_y = 0.0f; // ** if (id == 0) { mod = cmb.mod_0; modcolor = cmb.modcolor_0; modcolor1 = cmb.modcolor1_0; modcolor2 = cmb.modcolor2_0; modfactor = cmb.modfactor_0; } else { mod = cmb.mod_1; modcolor = cmb.modcolor_1; modcolor1 = cmb.modcolor1_1; modcolor2 = cmb.modcolor2_1; modfactor = cmb.modfactor_1; } modifyPalette = (mod && (cache->format == G_IM_FMT_CI) && (rdp.tlut_mode == 2)); if (modifyPalette) { uint16_t tmp_pal[256]; uint8_t cr0 = ((modcolor >> 24) & 0xFF); uint8_t cg0 = ((modcolor >> 16) & 0xFF); uint8_t cb0 = ((modcolor >> 8) & 0xFF); uint8_t ca0 = (modcolor & 0xFF); uint8_t cr1 = ((modcolor1 >> 24) & 0xFF); uint8_t cg1 = ((modcolor1 >> 16) & 0xFF); uint8_t cb1 = ((modcolor1 >> 8) & 0xFF); int32_t size = 256; float percent_r = ((modcolor1 >> 24) & 0xFF) / 255.0f; float percent_g = ((modcolor1 >> 16) & 0xFF) / 255.0f; float percent_b = ((modcolor1 >> 8) & 0xFF) / 255.0f; uint16_t *col = (uint16_t*)&rdp.pal_8[0]; memcpy(tmp_pal, rdp.pal_8, 512); switch (mod) { case TMOD_TEX_INTER_COLOR_USING_FACTOR: percent_r = percent_g = percent_b = modfactor / 255.0f; case TMOD_TEX_INTER_COL_USING_COL1: do { uint8_t a = (*col & 0x0001); uint8_t r = (uint8_t) ((1-percent_r) * (((*col & 0xF800) >> 11)) + percent_r * cr0); uint8_t g = (uint8_t) ((1-percent_g) * (((*col & 0x07C0) >> 6)) + percent_g * cg0); uint8_t b = (uint8_t) ((1-percent_b) * (((*col & 0x003E) >> 1)) + percent_b * cb0); *col++ = (uint16_t)(((uint16_t)(r >> 3) << 11) | ((uint16_t)(g >> 3) << 6) | ((uint16_t)(b >> 3) << 1) | ((uint16_t)(a ) << 0)); }while(--size); break; case TMOD_FULL_COLOR_SUB_TEX: do { uint8_t a = ca0 - (*col & 0x0001); uint8_t r = cr0 - (((*col & 0xF800) >> 11)); uint8_t g = cg0 - (((*col & 0x07C0) >> 6)); uint8_t b = cb0 - (((*col & 0x003E) >> 1)); *col++ = (uint16_t)(((uint16_t)(r >> 3) << 11) | ((uint16_t)(g >> 3) << 6) | ((uint16_t)(b >> 3) << 1) | ((uint16_t)(a ) << 0)); }while(--size); break; case TMOD_TEX_SUB_COL: do { uint8_t a = (*col & 0x0001); uint8_t r = (((*col & 0xF800) >> 11)) - cr0; uint8_t g = (((*col & 0x07C0) >> 6)) - cg0; uint8_t b = (((*col & 0x003E) >> 1)) - cb0; *col++ = (uint16_t)(((uint16_t)(r >> 3) << 11) | ((uint16_t)(g >> 3) << 6) | ((uint16_t)(b >> 3) << 1) | ((uint16_t)(a ) << 0)); }while(--size); break; case TMOD_COL_INTER_COL1_USING_TEX: do { float percent_r = ((*col & 0xF800) >> 11) / 31.0f; float percent_g = ((*col & 0x07C0) >> 6) / 31.0f; float percent_b = ((*col & 0x003E) >> 1) / 31.0f; uint8_t a = (*col & 0x0001); uint8_t r = (uint8_t)((1.0f-percent_r) * cr0 + percent_r * cr1); uint8_t g = (uint8_t)((1.0f-percent_g) * cg0 + percent_g * cg1); uint8_t b = (uint8_t)((1.0f-percent_b) * cb0 + percent_b * cb1); *col++ = (uint16_t)(((uint16_t)(r >> 3) << 11) | ((uint16_t)(g >> 3) << 6) | ((uint16_t)(b >> 3) << 1) | ((uint16_t)(a ) << 0)); }while(--size); break; case TMOD_TEX_SUB_COL_MUL_FAC_ADD_TEX: { float percent = modfactor / 255.0f; do { uint8_t a = (*col & 0x0001); float r = (uint8_t)((float)((*col & 0xF800) >> 11)); float g = (uint8_t)((float)((*col & 0x07C0) >> 6)); float b = (uint8_t)((float)((*col & 0x003E) >> 1)); r = (r - cr0) * percent + r; if (r > 255.0f) r = 255.0f; if (r < 0.0f) r = 0.0f; g = (g - cg0) * percent + g; if (g > 255.0f) g = 255.0f; if (g < 0.0f) g = 0.0f; b = (b - cb0) * percent + b; if (b > 255.0f) g = 255.0f; if (b < 0.0f) b = 0.0f; *col++ = (uint16_t)(((uint16_t)((uint8_t)(r) >> 3) << 11) | ((uint16_t)((uint8_t)(g) >> 3) << 6) | ((uint16_t)((uint8_t)(b) >> 3) << 1) | (uint16_t)(a) ); }while(--size); } break; case TMOD_TEX_SUB_COL_MUL_FAC: { float percent = modfactor / 255.0f; do { uint8_t a = (*col & 0x0001); float r = (((float)((*col & 0xF800) >> 11)) - cr0) * percent; float g = (((float)((*col & 0x07C0) >> 6)) - cg0) * percent; float b = ((float)((*col & 0x003E) >> 1) - cb0) * percent; if (r > 255.0f) r = 255.0f; if (r < 0.0f) r = 0.0f; if (g > 255.0f) g = 255.0f; if (g < 0.0f) g = 0.0f; if (b > 255.0f) g = 255.0f; if (b < 0.0f) b = 0.0f; *col++ = (uint16_t)(((uint16_t)((uint8_t)(r) >> 3) << 11) | ((uint16_t)((uint8_t)(g) >> 3) << 6) | ((uint16_t)((uint8_t)(b) >> 3) << 1) | (uint16_t)(a) ); }while(--size); } case TMOD_TEX_SCALE_COL_ADD_COL: percent_r = ((modcolor1 >> 24) & 0xFF) / 255.0f; percent_g = ((modcolor1 >> 16) & 0xFF) / 255.0f; percent_b = ((modcolor1 >> 8) & 0xFF) / 255.0f; do { uint8_t a = (*col & 0x0001); uint8_t r = (uint8_t)(percent_r * ((*col & 0xF800) >> 11)) + cr0; uint8_t g = (uint8_t)(percent_g * ((*col & 0x07C0) >> 6)) + cg0; uint8_t b = (uint8_t)(percent_b * ((*col & 0x003E) >> 1)) + cb0; *col++ = (uint16_t)(((uint16_t)(r >> 3) << 11) | ((uint16_t)(g >> 3) << 6) | ((uint16_t)(b >> 3) << 1) | ((uint16_t)(a ) << 0)); }while(--size); break; case TMOD_TEX_ADD_COL: do { uint8_t a = (*col & 0x0001); uint8_t r = cr0 + (((*col & 0xF800) >> 11)); uint8_t g = cg0 + (((*col & 0x07C0) >> 6)); uint8_t b = cb0 + (((*col & 0x003E) >> 1)); *col++ = (uint16_t)(((uint16_t)(r >> 3) << 11) | ((uint16_t)(g >> 3) << 6) | ((uint16_t)(b >> 3) << 1) | ((uint16_t)(a ) << 0)); }while(--size); break; case TMOD_COL_INTER_TEX_USING_COL1: do { uint8_t a = (*col & 0x0001); uint8_t r = (uint8_t) (uint8_t)(percent_r * ((*col & 0xF800) >> 11) + (1-percent_r) * cr0); uint8_t g = (uint8_t)(percent_g * ((*col & 0x07C0) >> 6) + (1-percent_g) * cg0); uint8_t b = (uint8_t)(percent_b * ((*col & 0x003E) >> 1) + (1-percent_b) * cb0); *col++ = (uint16_t)(((uint16_t)(r >> 3) << 11) | ((uint16_t)(g >> 3) << 6) | ((uint16_t)(b >> 3) << 1) | ((uint16_t)(a ) << 0)); }while(--size); break; case TMOD_TEX_INTER_COL_USING_TEXA: { uint8_t r = (uint8_t)(((modcolor >> 24) & 0xFF) / 255.f * 31.f); uint8_t g = (uint8_t)(((modcolor >> 16) & 0xFF) / 255.f * 31.f); uint8_t b = (uint8_t)(((modcolor >> 8) & 0xFF) / 255.f * 31.f); uint8_t a = (modcolor & 0xFF) ? 1 : 0; uint16_t col16 = ((r << 11)|(g << 6)|(b << 1) | a); do { *col = (*col & 1) ? col16 : *col; *col++; }while(--size); } break; case TMOD_TEX_MUL_COL: do { uint8_t a = (*col & 0x0001); uint8_t r = (((*col & 0xF800) >> 11) * cr0); uint8_t g = (((*col & 0x07C0) >> 6) * cg0); uint8_t b = (((*col & 0x003E) >> 1) * cb0); *col++ = (uint16_t)(((uint16_t)(r >> 3) << 11) | ((uint16_t)(g >> 3) << 6) | ((uint16_t)(b >> 3) << 1) | ((uint16_t)(a ) << 0)); }while(--size); break; } memcpy(rdp.pal_8, tmp_pal, 512); } cache->mod = mod; cache->mod_color = modcolor; cache->mod_color1 = modcolor1; cache->mod_factor = modfactor; result = 0; // keep =0 so it doesn't mess up on the first split texture = tex1; { uint32_t size; int min_x, min_y; result = load_table[g_gdp.tile[td].size][g_gdp.tile[td].format] ((uintptr_t)(texture), (uintptr_t)(g_gdp.tmem)+(g_gdp.tile[td].tmem<<3), texinfo[id].wid_64, texinfo[id].height, texinfo[id].line, real_x, td); size = HIWORD(result); if (g_gdp.tile[td].mask_s != 0) min_x = min((int)real_x, 1 << g_gdp.tile[td].mask_s); else min_x = real_x; if (g_gdp.tile[td].mask_t != 0) min_y = min((int)real_y, 1 << g_gdp.tile[td].mask_t); else min_y = real_y; // Load using mirroring/clamping if (min_x > texinfo[id].width && (signed)real_x > texinfo[id].width) /* real_x unsigned just for right shift */ ClampTex(texture, texinfo[id].width, min_x, real_x, texinfo[id].height, size); if (texinfo[id].width < (int)real_x) { bool cond_true = g_gdp.tile[td].mask_s != 0 && (real_x > (1U << g_gdp.tile[td].mask_s)); if (g_gdp.tile[td].ms && cond_true) { MirrorTex((texture), g_gdp.tile[td].mask_s, real_x, real_x, texinfo[id].height, size); } else if (cond_true) { // Horizontal Wrap (like mirror) ** UNTESTED ** uint8_t *tex = (uint8_t*)texture; uint32_t max_height = texinfo[id].height; uint8_t shift_a = (size == 0) ? 2 : (size == 1) ? 1 : 0; uint32_t mask_width = (1 << g_gdp.tile[td].mask_s); uint32_t mask_mask = (mask_width-1) >> shift_a; int32_t count = (real_x - mask_width) >> shift_a; int32_t line_full = real_x << size; int32_t line = line_full - (count << 2); uint8_t *start = (uint8_t*)(tex + (mask_width << size)); uint32_t *v7 = (uint32_t *)start; do { int v9 = 0; do { *v7++ = *(uint32_t *)&tex[4 * (mask_mask & v9++)]; }while ( v9 != count ); v7 = (uint32_t *)((int8_t*)v7 + line); tex += line_full; }while (--max_height); } } if (min_y > texinfo[id].height) { // Vertical Clamp int32_t line_full = real_x << size; uint8_t *dst = (uint8_t*)(texture + texinfo[id].height * line_full); uint8_t *const_line = (uint8_t*)(dst - line_full); int y = texinfo[id].height; for (; y < min_y; y++) { memcpy ((void*)dst, (void*)const_line, line_full); dst += line_full; } } if (texinfo[id].height < (int)real_y) { if (g_gdp.tile[td].mt) { // Vertical Mirror if (g_gdp.tile[td].mask_t != 0 && (real_y > (1U << g_gdp.tile[td].mask_t))) { uint32_t mask_height = (1 << g_gdp.tile[td].mask_t); uint32_t mask_mask = mask_height-1; int32_t line_full = real_x << size; uint8_t *dst = (uint8_t*)(texture + mask_height * line_full); uint32_t y = mask_height; for (; y < real_y; y++) { if (y & mask_height) // mirrored memcpy ((void*)dst, (void*)(texture + (mask_mask - (y & mask_mask)) * line_full), line_full); else // not mirrored memcpy ((void*)dst, (void*)(texture + (y & mask_mask) * line_full), line_full); dst += line_full; } } } else if (g_gdp.tile[td].mask_t != 0 && real_y > (1U << g_gdp.tile[td].mask_t)) { // Vertical Wrap uint32_t wrap_size = size; uint32_t mask_height = (1 << g_gdp.tile[td].mask_t); uint32_t y = mask_height; uint32_t mask_mask = mask_height-1; int32_t line_full = real_x << wrap_size; uint8_t *dst = (uint8_t*)(texture + mask_height * line_full); if (wrap_size == 1) wrap_size = 0; for ( ;y < real_y; y++) { // not mirrored memcpy ((void*)dst, (void*)(texture + (y & mask_mask) * (line_full >> wrap_size)), (line_full >> wrap_size)); dst += line_full; } } } } if (mod && !modifyPalette) { int size = real_x * real_y; uint32_t *src = (uint32_t*)texture; uint32_t *dst = (uint32_t*)tex2; // Convert the texture to ARGB 4444 if (LOWORD(result) == GR_TEXFMT_ARGB_1555) { // 2 pixels are converted in one loop // NOTE: width * height must be a multiple of 2 size >>= 1; while (size--) { uint32_t col = *src++; *dst++ = ((col & 0x1E001E) >> 1) | ((col & 0x3C003C0) >> 2) | ((col & 0x78007800) >> 3) | ((col & 0x80008000) >> 3) | ((col & 0x80008000) >> 2) | ((col & 0x80008000) >> 1) | (col & 0x80008000); } texture = tex2; } else if (LOWORD(result) == GR_TEXFMT_ALPHA_INTENSITY_88) { // 2 pixels are converted in one loop // NOTE: width * height must be a multiple of 2 size >>= 1; while (size--) { uint32_t col = *src++; *dst++ = (16 * (col & 0xF000F0) >> 8) | (col & 0xF000F0) | (16 * (col & 0xF000F0)) | (col & 0xF000F000); } texture = tex2; } else if (LOWORD(result) == GR_TEXFMT_ALPHA_INTENSITY_44) { // 4 pixels are converted in one loop // NOTE: width * height must be a multiple of 4 size >>= 2; while (size--) { uint32_t col = *src++; *dst++ = ((((uint16_t)col << 8) & 0xFF00 & 0xF00u) >> 8) | ((((uint16_t)col << 8) & 0xFF00 & 0xF00u) >> 4) | (uint16_t)(((uint16_t)col << 8) & 0xFF00) | (((col << 16) & 0xF000000) >> 8) | (((col << 16) & 0xF000000) >> 4) | ((col << 16) & 0xFF000000); *dst++ = (((col >> 8) & 0xF00) >> 8) | (((col >> 8) & 0xF00) >> 4) | ((col >> 8) & 0xFF00) | ((col & 0xF000000) >> 8) | ((col & 0xF000000) >> 4) | (col & 0xFF000000); } texture = tex2; } else if (LOWORD(result) == GR_TEXFMT_ALPHA_8) { // 4 pixels are converted in one loop // NOTE: width * height must be a multiple of 4 size >>= 2; while (size--) { uint32_t col = *src++; *dst++ = ((col & 0xF0) << 8 >> 12) | (uint8_t)(col & 0xF0) | (16 * (uint8_t)(col & 0xF0) & 0xFFFFFFF) | ((uint8_t)(col & 0xF0) << 8) | (16 * (uint16_t)(col & 0xF000) & 0xFFFFF) | (((uint16_t)(col & 0xF000) << 8) & 0xFFFFFF) | (((uint16_t)(col & 0xF000) << 12) & 0xFFFFFFF) | ((uint16_t)(col & 0xF000) << 16); *dst++ = ((col & 0xF00000) >> 20) | ((col & 0xF00000) >> 16) | ((col & 0xF00000) >> 12) | ((col & 0xF00000) >> 8) | ((col & 0xF0000000) >> 12) | ((col & 0xF0000000) >> 8) | ((col & 0xF0000000) >> 4) | (col & 0xF0000000); } texture = tex2; } result = (1 << 16) | GR_TEXFMT_ARGB_4444; // Now convert the color to the same modcolor = ((modcolor & 0xF0000000) >> 16) | ((modcolor & 0x00F00000) >> 12) | ((modcolor & 0x0000F000) >> 8) | ((modcolor & 0x000000F0) >> 4); modcolor1 = ((modcolor1 & 0xF0000000) >> 16) | ((modcolor1 & 0x00F00000) >> 12) | ((modcolor1 & 0x0000F000) >> 8) | ((modcolor1 & 0x000000F0) >> 4); modcolor2 = ((modcolor2 & 0xF0000000) >> 16) | ((modcolor2 & 0x00F00000) >> 12) | ((modcolor2 & 0x0000F000) >> 8) | ((modcolor2 & 0x000000F0) >> 4); { size = (real_x * real_y) << 1; uint16_t *dst = (uint16_t*)texture; uint32_t cr0 = (modcolor >> 12) & 0xF; uint32_t cg0 = (modcolor >> 8) & 0xF; uint32_t cb0 = (modcolor >> 4) & 0xF; uint32_t cr1 = (modcolor1 >> 12) & 0xF; uint32_t cg1 = (modcolor1 >> 8) & 0xF; uint32_t cb1 = (modcolor1 >> 4) & 0xF; uint32_t cr2 = (modcolor2 >> 12) & 0xF; uint32_t cg2 = (modcolor2 >> 8) & 0xF; uint32_t cb2 = (modcolor2 >> 4) & 0xF; switch (mod) { case TMOD_TEX_INTER_COLOR_USING_FACTOR: { float percent = modfactor / 255.0f; while (size--) { uint8_t r = (uint8_t) ((1 - percent) * (((*dst) >> 8) & 0xF) + percent * cr0); uint8_t g = (uint8_t) ((1 - percent) * (((*dst) >> 4) & 0xF) + percent * cg0); uint8_t b = (uint8_t) ((1 - percent) * ((*dst) & 0xF) + percent * cb0); *dst = (*dst & 0xF000) | (r << 8) | (g << 4) | b; dst++; } } break; case TMOD_TEX_INTER_COL_USING_COL1: { float percent_r = cr1 / 15.0f; float percent_g = cg1 / 15.0f; float percent_b = cb1 / 15.0f; while (size--) { uint8_t r = (uint8_t) ((1 - percent_r) * (((*dst) >> 8) & 0xF) + percent_r * cr0); uint8_t g = (uint8_t) ((1 - percent_g) * (((*dst) >> 4) & 0xF) + percent_g * cg0); uint8_t b = (uint8_t) ((1 - percent_b) * ((*dst) & 0xF) + percent_b * cb0); *dst = (*dst & 0xF000) | (r << 8) | (g << 4) | b; dst++; } } break; case TMOD_FULL_COLOR_SUB_TEX: { while (size--) { uint8_t a = ((modcolor & 0xF) - (((*dst) >> 12) & 0xF)); uint8_t r = (cr0 - (((*dst) >> 8) & 0xF)); uint8_t g = (cg0 - (((*dst) >> 4) & 0xF)); uint8_t b = (cb0 - (*dst & 0xF)); *dst = (a << 12) | (r << 8) | (g << 4) | b; dst++; } } break; case TMOD_COL_INTER_COL1_USING_TEX: while (size--) { float percent_r = (((*dst) >> 8) & 0xF) / 15.0f; float percent_g = (((*dst) >> 4) & 0xF) / 15.0f; float percent_b = ((*dst) & 0xF) / 15.0f; uint8_t r = (uint8_t)((1.0f-percent_r) * cr0 + percent_r * cr1 + 0.0001f); uint8_t g = (uint8_t)((1.0f-percent_g) * cg0 + percent_g * cg1 + 0.0001f); uint8_t b = (uint8_t)((1.0f-percent_b) * cb0 + percent_b * cb1 + 0.0001f); *dst = (*dst & 0xF000) | (r << 8) | (g << 4) | b; dst++; } break; case TMOD_COL_INTER_COL1_USING_TEXA: case TMOD_COL_INTER_COL1_USING_TEXA__MUL_TEX: { if (mod == TMOD_COL_INTER_COL1_USING_TEXA__MUL_TEX) { while (size--) { float percent = ((*dst & 0xF000) >> 12) / 15.0f; uint8_t r = (uint8_t) ((((1 - percent) * cr0 + percent * cr1) / 15.0f) * ((((*dst) & 0x0F00) >> 8) / 15.0f) * 15.0f); uint8_t g = (uint8_t) ((((1 - percent) * cg0 + percent * cg1) / 15.0f) * ((((*dst) & 0x00F0) >> 4) / 15.0f) * 15.0f); uint8_t b = (uint8_t) ((((1 - percent) * cb0 + percent * cb1) / 15.0f) * (((*dst) & 0x000F) / 15.0f) * 15.0f); *dst = (*dst & 0xF000) | (r << 8) | (g << 4) | b; dst++; } } else { while (size--) { float percent = ((*dst & 0xF000) >> 12) / 15.0f; uint8_t r = (uint8_t)((1 - percent)*cr0 + percent*cr1); uint8_t g = (uint8_t)((1 - percent)*cg0 + percent*cg1); uint8_t b = (uint8_t)((1 - percent)*cb0 + percent*cb1); *dst = (*dst & 0xF000) | (r << 8) | (g << 4) | b; dst++; } } } break; case TMOD_COL_INTER_TEX_USING_TEX: case TMOD_COL_INTER_TEX_USING_TEXA: { if (mod == TMOD_COL_INTER_TEX_USING_TEX) { while (size--) { float percent_r = (((*dst) >> 8) & 0xF) / 15.0f; float percent_g = (((*dst) >> 4) & 0xF) / 15.0f; float percent_b = ((*dst) & 0xF) / 15.0f; uint8_t r = (uint8_t) ((1.0f-percent_r) * cr0 + percent_r * (((*dst) & 0x0F00) >> 8)); uint8_t g = (uint8_t) ((1.0f-percent_g) * cg0 + percent_g * (((*dst) & 0x00F0) >> 4)); uint8_t b = (uint8_t) ((1.0f-percent_b) * cb0 + percent_b * ((*dst) & 0x000F)); *dst = (*dst & 0xF000) | (r << 8) | (g << 4) | b; dst++; } } else { while (size--) { float percent = ((*dst & 0xF000) >> 12) / 15.0f; uint8_t r = (uint8_t) ((1 - percent)*cr0 + percent*((*dst & 0x0F00) >> 8)); uint8_t g = (uint8_t) ((1 - percent)*cg0 + percent*((*dst & 0x00F0) >> 4)); uint8_t b = (uint8_t) ((1 - percent)*cb0 + percent*(*dst & 0x000F)); *dst = (*dst & 0xF000) | (r << 8) | (g << 4) | b; dst++; } } } break; case TMOD_COL2_INTER__COL_INTER_COL1_USING_TEX__USING_TEXA: { while (size--) { float percent_a = ((*dst & 0xF000) >> 12) / 15.0f; float percent_r = (((*dst) >> 8) & 0xF) / 15.0f; float percent_g = (((*dst) >> 4) & 0xF) / 15.0f; float percent_b = (*dst & 0xF) / 15.0f; uint8_t r = (uint8_t) (((1.0f-percent_r)*cr0 + percent_r*cr1)*percent_a + cr2*(1.0f-percent_a)); uint8_t g = (uint8_t) (((1.0f-percent_g)*cg0 + percent_g*cg1)*percent_a + cg2*(1.0f-percent_a)); uint8_t b = (uint8_t) (((1.0f-percent_b)*cb0 + percent_b*cb1)*percent_a + cb2*(1.0f-percent_a)); *dst = (*dst & 0xF000) | (r << 8) | (g << 4) | b; dst++; } } break; case TMOD_TEX_SCALE_FAC_ADD_FAC: { float base_a_plus_percent = ((1.0f - (modfactor / 255.0f)) * 15.0f) + (modfactor / 255.0f); while (size--) { *dst = ((uint16_t)(base_a_plus_percent * ((*dst) >> 12)) << 12) | ((*dst) & 0x0FFF); dst++; } } break; case TMOD_TEX_SUB_COL_MUL_FAC_ADD_TEX: { float percent = modfactor / 255.0f; while (size--) { float r, g, b; r = (float)(((*dst) >> 8) & 0xF); r = (r - cr0) * percent + r; if (r > 15.0f) r = 15.0f; if (r < 0.0f) r = 0.0f; g = (float)(((*dst) >> 4) & 0xF); g = (g - cg0) * percent + g; if (g > 15.0f) g = 15.0f; if (g < 0.0f) g = 0.0f; b = (float)(*dst & 0xF); b = (b - cb0) * percent + b; if (b > 15.0f) b = 15.0f; if (b < 0.0f) b = 0.0f; *dst = (*dst & 0xF000) | ((uint16_t)r << 8) | ((uint16_t)g << 4) | (uint16_t)b; dst++; } } break; case TMOD_TEX_SCALE_COL_ADD_COL: while (size--) { float percent_r = (((*dst) >> 8) & 0xF) / 15.0f; float percent_g = (((*dst) >> 4) & 0xF) / 15.0f; float percent_b = ((*dst) & 0xF) / 15.0f; uint8_t r = (uint8_t)(percent_r * cr0 + cr1 + 0.0001f); uint8_t g = (uint8_t)(percent_g * cg0 + cg1 + 0.0001f); uint8_t b = (uint8_t)(percent_b * cb0 + cb1 + 0.0001f); *dst = (*dst & 0xF000) | (r << 8) | (g << 4) | b; dst++; } break; case TMOD_TEX_ADD_COL: while (size--) { uint8_t r = (uint8_t)(cr0 + (((*dst) >> 8) & 0xF))&0xF; uint8_t g = (uint8_t)(cg0 + (((*dst) >> 4) & 0xF))&0xF; uint8_t b = (uint8_t)(cb0 + ((*dst) & 0xF))&0xF; *dst = ((((*dst) >> 12) & 0xF) << 12) | (r << 8) | (g << 4) | b; dst++; } break; case TMOD_TEX_SUB_COL: { while (size--) { uint8_t r = (((*dst) >> 8) & 0xF) - cr0; uint8_t g = (((*dst) >> 4) & 0xF) - cg0; uint8_t b = (((*dst) & 0xF) - cb0) - cb0; *dst = (((*dst) & 0xF000) << 12) | (r << 8) | (g << 4) | b; dst++; } } break; case TMOD_TEX_SUB_COL_MUL_FAC: { float percent = modfactor / 255.0f; while (size--) { float r = ((float)(((*dst) >> 8) & 0xF) - cr0) * percent; float g = ((float)(((*dst) >> 4) & 0xF) - cg0) * percent; float b = ((float)(*dst & 0xF) - cb0) * percent; if (r > 15.0f) r = 15.0f; if (r < 0.0f) r = 0.0f; if (g > 15.0f) g = 15.0f; if (g < 0.0f) g = 0.0f; if (b > 15.0f) b = 15.0f; if (b < 0.0f) b = 0.0f; *dst = ((((*dst) >> 12) & 0xF) << 12) | ((uint16_t)r << 8) | ((uint16_t)g << 4) | (uint16_t)b; dst++; } } break; case TMOD_COL_INTER_TEX_USING_COL1: { float percent_r = cr1 / 15.0f; float percent_g = cg1 / 15.0f; float percent_b = cb1 / 15.0f; while (size--) { uint8_t r = (uint8_t) (percent_r * (((*dst) >> 8) & 0xF) + (1 - percent_r) * cr0); uint8_t g = (uint8_t) (percent_g * (((*dst) >> 4) & 0xF) + (1 - percent_g) * cg0); uint8_t b = (uint8_t) (percent_b * ((*dst) & 0xF) + (1 - percent_b) * cb0); *dst = ((((*dst) >> 12) & 0xF) << 12) | (r << 8) | (g << 4) | b; dst++; } } break; case TMOD_COL_MUL_TEXA_ADD_TEX: while (size--) { float factor = ((*dst & 0xF000) >> 12) / 15.0f; uint8_t r = (uint8_t)(cr0 * factor + (((*dst) >> 8) & 0xF))&0xF; uint8_t g = (uint8_t)(cg0 * factor + (((*dst) >> 4) & 0xF))&0xF; uint8_t b = (uint8_t)(cb0 * factor + ((*dst) & 0xF))&0xF; *dst = (*dst & 0xF000) | (r << 8) | (g << 4) | b; dst++; } break; case TMOD_TEX_INTER_NOISE_USING_COL: { float percent_r = cr0 / 15.0f; float percent_g = cg0 / 15.0f; float percent_b = cb0 / 15.0f; while (size--) { uint8_t noise = rand()%16; uint8_t r = (uint8_t) ((1 - percent_r)*(((*dst) >> 8) & 0xF) + percent_r*noise); uint8_t g = (uint8_t) ((1 - percent_g)*(((*dst) >> 4) & 0xF) + percent_g*noise); uint8_t b = (uint8_t) ((1 - percent_b)*(*dst & 0xF) + percent_b*noise); *dst = (*dst & 0xF000) | (r << 8) | (g << 4) | b; dst++; } } break; case TMOD_TEX_INTER_COL_USING_TEXA: while (size--) { float percent = ((*dst & 0xF000) >> 12) / 15.0f; uint8_t r = (uint8_t) (percent*cr0 + (1 - percent)*((*dst & 0x0F00) >> 8)); uint8_t g = (uint8_t) (percent*cg0 + (1 - percent)*((*dst & 0x00F0) >> 4)); uint8_t b = (uint8_t) (percent*cb0 + (1 - percent)*(*dst & 0x000F)); *dst = (*dst & 0xF000) | (r << 8) | (g << 4) | b; dst++; } break; case TMOD_TEX_MUL_COL: while (size--) { uint8_t r = (cr0 * ((*dst & 0x0F00) >> 8)); uint8_t g = (cg0 * ((*dst & 0x00F0) >> 4)); uint8_t b = (cb0 * (*dst & 0x000F)); *dst = (*dst & 0xF000) | (r << 8) | (g << 4) | b; dst++; } break; case TMOD_TEX_SCALE_FAC_ADD_COL: { float percent = modfactor / 255.0f; while (size--) { uint8_t r = (uint8_t)(cr0 + percent*(((*dst) >> 8) & 0xF)); uint8_t g = (uint8_t)(cg0 + percent*(((*dst) >> 4) & 0xF)); uint8_t b = (uint8_t)(cb0 + percent*(((*dst) >> 0) & 0xF)); *dst = (*dst & 0xF000) | (r << 8) | (g << 4) | b; dst++; } } break; } } } cache->t_info.format = LOWORD(result); cache->realwidth = real_x; cache->realheight = real_y; cache->lod = lod; cache->aspect = aspect; { uint32_t texture_size, tex_addr; GrTexInfo *t_info; // Load the texture into texture memory t_info = (GrTexInfo*)&cache->t_info; t_info->data = texture; t_info->smallLodLog2 = lod; t_info->largeLodLog2 = lod; t_info->aspectRatioLog2 = aspect; texture_size = grTexCalcMemRequired (t_info->largeLodLog2, t_info->aspectRatioLog2, t_info->format); // Check for end of memory (too many textures to fit, clear cache) if (voodoo.tmem_ptr[tmu]+texture_size >= voodoo.tex_max_addr) { LRDP("Cache size reached, clearing...\n"); ClearCache (); if (id == 1 && rdp.tex == 3) LoadTex (0, rdp.t0); LoadTex (id, tmu); return; // DON'T CONTINUE (already done) } tex_addr = GetTexAddrUMA(tmu, texture_size); grTexSource (tmu, tex_addr, GR_MIPMAPLEVELMASK_BOTH, t_info, true); } LRDP(" | | +- LoadTex end\n"); } gles2rice/src/RenderExt.cpp000664 001750 001750 00000076612 12655644434 017005 0ustar00sergiosergio000000 000000 /* Copyright (C) 2002 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "osal_opengl.h" #include "OGLDebug.h" #include "FrameBuffer.h" #include "Render.h" extern uObjMtxReal gObjMtxReal; extern Matrix g_MtxReal; //======================================================================== void CRender::LoadFrameBuffer(bool useVIreg, uint32_t left, uint32_t top, uint32_t width, uint32_t height) { uint32_t VIwidth = *gfx_info.VI_WIDTH_REG; uint32_t *rdram_u32 = (uint32_t*)gfx_info.RDRAM; TxtrInfo gti; gti.clampS = gti.clampT = 0; gti.maskS = gti.maskT = gti.mirrorS = gti.mirrorT = 0; gti.TLutFmt = TLUT_FMT_RGBA16; //RGBA16 gti.bSwapped = FALSE; gti.Palette = 0; if( useVIreg && *gfx_info.VI_ORIGIN_REG > VIwidth*2 ) { gti.Format = 0; gti.Size = 2; gti.Address = (*gfx_info.VI_ORIGIN_REG & (g_dwRamSize-1) ) - VIwidth*2; gti.LeftToLoad = 0; gti.TopToLoad = 0; gti.PalAddress = (uint8_t *) &g_wRDPTlut[0]; gti.WidthToCreate = windowSetting.uViWidth;; gti.HeightToCreate = windowSetting.uViHeight; if( gti.WidthToCreate == 0 || gti.HeightToCreate == 0 ) { TRACE0("Loading frame buffer: size = 0 x 0"); return; } gti.Pitch = VIwidth << gti.Size >> 1; } else { gti.Format = g_CI.dwFormat; gti.Size = g_CI.dwSize; gti.PalAddress = (uint8_t *) &g_wRDPTlut[0]; gti.Address = RSPSegmentAddr(g_CI.dwAddr); if( width == 0 || height == 0 ) { gti.LeftToLoad = 0; gti.TopToLoad = 0; gti.WidthToCreate = g_CI.dwWidth; gti.HeightToCreate = g_CI.dwWidth*3/4; } else { gti.LeftToLoad = left; gti.TopToLoad = top; gti.WidthToCreate = width; gti.HeightToCreate = height; } if( gti.Size == TXT_SIZE_4b ) { gti.Pitch = g_CI.dwWidth >> 1; } else { gti.Pitch = g_CI.dwWidth << (gti.Size-1); } } if( gti.Address + gti.Pitch*gti.HeightToCreate > g_dwRamSize ) { TRACE0("Skip frame buffer loading, memory out of bound"); return; } #ifdef DEBUGGER if( pauseAtNext ) { DebuggerAppendMsg("Load Frame Buffer Imag at: %08X, (%d, %d) - (%d, %d)", gti.Address, gti.LeftToLoad, gti.TopToLoad, gti.WidthToCreate, gti.HeightToCreate ); } #endif gti.HeightToLoad = gti.HeightToCreate; gti.WidthToLoad = gti.WidthToCreate; gti.pPhysicalAddress = ((uint8_t*)rdram_u32) + gti.Address; gti.tileNo = -1; TxtrCacheEntry *pEntry = gTextureManager.GetTexture(>i, false, true, false); if( pEntry ) SetCurrentTexture( 0, pEntry->pTexture, pEntry->ti.WidthToCreate, pEntry->ti.HeightToCreate, pEntry); } void CRender::LoadTextureFromMemory(void *buf, uint32_t left, uint32_t top, uint32_t width, uint32_t height, uint32_t pitch, uint32_t format) { TxtrInfo gti; gti.Format = g_CI.dwFormat; gti.Size = g_CI.dwSize; gti.Palette = 0; gti.TLutFmt = TLUT_FMT_RGBA16; //RGBA16 gti.PalAddress = 0; gti.bSwapped = FALSE; gti.Address = 0; gti.LeftToLoad = 0; gti.TopToLoad = 0; gti.WidthToCreate = width; gti.HeightToCreate = height; gti.Pitch = pitch; gti.HeightToLoad = height; gti.WidthToLoad = width; gti.pPhysicalAddress = (uint8_t*)buf; gti.tileNo = -1; TxtrCacheEntry *pEntry = gTextureManager.GetTexture(>i, false, true, false); //Upto here, the texture is loaded wrong because the format is wrong DrawInfo info; if( pEntry->pTexture->StartUpdate(&info) ) { for( uint32_t i=0; ipTexture->EndUpdate(&info); } SetCurrentTexture( 0, pEntry->pTexture, width, height, pEntry); } void CRender::LoadObjBGCopy(uObjBg &info) { uint32_t *rdram_u32 = (uint32_t*)gfx_info.RDRAM; TxtrInfo gti; gti.Format = info.imageFmt; gti.Size = info.imageSiz; gti.Address = RSPSegmentAddr(info.imagePtr); gti.LeftToLoad = 0; gti.TopToLoad = 0; gti.Palette = info.imagePal; gti.PalAddress = (uint8_t *) &g_wRDPTlut[0]; gti.bSwapped = FALSE; gti.TLutFmt = TLUT_FMT_RGBA16; //RGBA16 gti.WidthToCreate = info.imageW/4; gti.HeightToCreate = info.imageH/4; if( options.bEnableHacks ) { if( g_CI.dwWidth == 0x200 && gti.Format == g_CI.dwFormat && gti.Size == g_CI.dwSize && gti.WidthToCreate == 0x200 ) { // Hack for RE2 uint32_t w = *gfx_info.VI_WIDTH_REG & 0xFFF; gti.HeightToCreate = (gti.WidthToCreate*gti.HeightToCreate)/w; gti.WidthToCreate = w; } } gti.Pitch = gti.WidthToCreate << gti.Size >> 1; gti.Pitch = (gti.Pitch>>3)<<3; // Align to 8 bytes if( gti.Address + gti.Pitch*gti.HeightToCreate > g_dwRamSize ) { TRACE0("Skip BG copy loading, memory out of bound"); return; } gti.HeightToLoad = gti.HeightToCreate; gti.WidthToLoad = gti.WidthToCreate; gti.pPhysicalAddress = ((uint8_t*)rdram_u32)+gti.Address; gti.tileNo = -1; TxtrCacheEntry *pEntry = gTextureManager.GetTexture(>i, false, true, false); SetCurrentTexture(0,pEntry); DEBUGGER_IF_DUMP((pauseAtNext && (eventToPause == NEXT_OBJ_TXT_CMD||eventToPause == NEXT_FLUSH_TRI||eventToPause == NEXT_OBJ_BG)), { TRACE0("Load Obj BG Copy:\n"); DebuggerAppendMsg("Addr=0x%08X, W=%d, H=%d, Left=%d, Top=%d\n", gti.Address, gti.WidthToCreate, gti.HeightToCreate, gti.LeftToLoad, gti.TopToLoad); DebuggerAppendMsg("Fmt=%s-%db, Pal=%d\n", pszImgFormat[gti.Format], pnImgSize[gti.Size], gti.Palette); } ); } void CRender::LoadTxtrBufIntoTexture(void) { TxtrInfo gti; uint32_t *rdram_u32 = (uint32_t*)gfx_info.RDRAM; gti.Format = g_pRenderTextureInfo->CI_Info.dwFormat; gti.Size = g_pRenderTextureInfo->CI_Info.dwSize; gti.Address = RSPSegmentAddr(g_pRenderTextureInfo->CI_Info.dwAddr); gti.LeftToLoad = 0; gti.TopToLoad = 0; gti.Palette = 0; gti.PalAddress = (uint8_t *) &g_wRDPTlut[0]; gti.bSwapped = FALSE; gti.WidthToCreate = g_pRenderTextureInfo->N64Width; gti.HeightToCreate = g_pRenderTextureInfo->N64Height; gti.TLutFmt = TLUT_FMT_RGBA16; //RGBA16 gti.Pitch = gti.WidthToCreate << (gti.Size-1); gti.HeightToLoad = gti.HeightToCreate; gti.WidthToLoad = gti.WidthToCreate; gti.pPhysicalAddress = ((uint8_t*)rdram_u32)+gti.Address; gti.tileNo = -1; TxtrCacheEntry *pEntry = gTextureManager.GetTexture(>i, false, true, false); SetCurrentTexture(0,pEntry); } void CRender::LoadSprite2D(Sprite2DInfo &info, uint32_t ucode) { TxtrInfo gti; uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; uint32_t *rdram_u32 = (uint32_t*)gfx_info.RDRAM; gti.Format = info.spritePtr->SourceImageType; gti.Size = info.spritePtr->SourceImageBitSize; gti.Address = RSPSegmentAddr(info.spritePtr->SourceImagePointer); gti.Palette = 0; gti.PalAddress = (uint8_t *) (rdram_u8 + RSPSegmentAddr(info.spritePtr->TlutPointer)); if( options.enableHackForGames == HACK_FOR_NITRO ) { gti.WidthToCreate = (uint32_t)(info.spritePtr->SubImageWidth/info.scaleX); gti.HeightToCreate = (uint32_t)(info.spritePtr->SubImageHeight/info.scaleY); gti.LeftToLoad = (uint32_t)(info.spritePtr->SourceImageOffsetS/info.scaleX); gti.TopToLoad = (uint32_t)(info.spritePtr->SourceImageOffsetT/info.scaleY); gti.Pitch = info.spritePtr->Stride << gti.Size >> 1; gti.Pitch = (uint32_t)(gti.Pitch*info.scaleY); } else { gti.WidthToCreate = info.spritePtr->SubImageWidth; gti.HeightToCreate = info.spritePtr->SubImageHeight; gti.LeftToLoad = info.spritePtr->SourceImageOffsetS; gti.TopToLoad = info.spritePtr->SourceImageOffsetT; gti.Pitch = info.spritePtr->Stride << gti.Size >> 1; } if( gti.Address + gti.Pitch*gti.HeightToCreate > g_dwRamSize ) { TRACE0("Skip Sprite image decompress, memory out of bound"); return; } gti.HeightToLoad = gti.HeightToCreate; gti.WidthToLoad = gti.WidthToCreate; gti.TLutFmt = TLUT_FMT_RGBA16; //RGBA16 gti.bSwapped = FALSE; gti.pPhysicalAddress = ((uint8_t*)rdram_u32) + gti.Address; gti.tileNo = -1; TxtrCacheEntry *pEntry = gTextureManager.GetTexture(>i, false, true, false); SetCurrentTexture(0,pEntry); DEBUGGER_IF_DUMP((pauseAtNext && (eventToPause == NEXT_OBJ_TXT_CMD||eventToPause == NEXT_FLUSH_TRI||eventToPause == NEXT_SPRITE_2D)), { TRACE0("Load Sprite 2D\n"); DebuggerAppendMsg("Addr=0x%08X, W=%d, H=%d, Left=%d, Top=%d\n", gti.Address, gti.WidthToCreate, gti.HeightToCreate, gti.LeftToLoad, gti.TopToLoad); DebuggerAppendMsg("Fmt=%s-%db, Pal=%d, Pitch=%d\n", pszImgFormat[gti.Format], pnImgSize[gti.Size], gti.Palette, gti.Pitch); } ); } void CRender::DrawSprite2D(Sprite2DInfo &info, uint32_t ucode) { if( !status.bCIBufferIsRendered ) g_pFrameBufferManager->ActiveTextureBuffer(); if( status.bHandleN64RenderTexture ) { g_pRenderTextureInfo->maxUsedHeight = g_pRenderTextureInfo->N64Height; if( !status.bDirectWriteIntoRDRAM ) { status.bFrameBufferIsDrawn = true; status.bFrameBufferDrawnByTriangles = true; } } LoadSprite2D(info, ucode); info.scaleX = 1/info.scaleX; info.scaleY = 1/info.scaleY; int x0, y0, x1, y1; float t0, s0, t1, s1; if( info.flipX ) { //x0 = info.px*info.scaleX + info.spritePtr->SubImageWidth*info.scaleX; //x1 = info.px*info.scaleX; x0 = info.px + int(info.spritePtr->SubImageWidth*info.scaleX); x1 = info.px; } else { //x0 = info.px*info.scaleX; //x1 = info.px*info.scaleX + info.spritePtr->SubImageWidth*info.scaleX; x0 = info.px; x1 = info.px + int(info.spritePtr->SubImageWidth*info.scaleX); } if( info.flipY ) { //y0 = info.py*info.scaleY + info.spritePtr->SubImageHeight*info.scaleY; //y1 = info.py*info.scaleY; y0 = info.py + int(info.spritePtr->SubImageHeight*info.scaleY); y1 = info.py; } else { //y0 = info.py*info.scaleY; //y1 = info.py*info.scaleY + info.spritePtr->SubImageHeight*info.scaleY; y0 = info.py; y1 = info.py + int(info.spritePtr->SubImageHeight*info.scaleY); } t0 = s0 = 0; if( options.enableHackForGames == HACK_FOR_NITRO ) { t1 = info.spritePtr->SubImageWidth*info.scaleX/g_textures[0].m_fTexWidth; s1 = info.spritePtr->SubImageHeight*info.scaleY/g_textures[0].m_fTexHeight; } else { t1 = info.spritePtr->SubImageWidth/g_textures[0].m_fTexWidth; s1 = info.spritePtr->SubImageHeight/g_textures[0].m_fTexHeight; } //InitCombinerBlenderForSimpleTextureDraw(0); SetCombinerAndBlender(); SetAddressUAllStages( 0, TEXTURE_UV_FLAG_CLAMP ); SetAddressVAllStages( 0, TEXTURE_UV_FLAG_CLAMP ); COLOR speColor = PostProcessSpecularColor(); COLOR difColor = PostProcessDiffuseColor(0xffffffff); float depth = ( gRDP.otherMode.depth_source == 1 ) ? gRDP.fPrimitiveDepth : 0; DrawSimple2DTexture((float)x0, (float)y0, (float)x1, (float)y1, t0, s0, t1, s1, speColor, difColor, depth, 1.0f); } void CRender::DrawSpriteR(uObjTxSprite &sprite, bool initCombiner, uint32_t tile, uint32_t left, uint32_t top, uint32_t width, uint32_t height) // With Rotation { if( !status.bCIBufferIsRendered ) g_pFrameBufferManager->ActiveTextureBuffer(); if( status.bHandleN64RenderTexture ) { g_pRenderTextureInfo->maxUsedHeight = g_pRenderTextureInfo->N64Height; if( !status.bDirectWriteIntoRDRAM ) { status.bFrameBufferIsDrawn = true; status.bFrameBufferDrawnByTriangles = true; } } SetCombinerAndBlender(); float scaleX = sprite.sprite.scaleW/1024.0f; float scaleY = sprite.sprite.scaleH/1024.0f; if( width == 0 || height == 0 ) { width = g_textures[tile].m_dwTileWidth; height = g_textures[tile].m_dwTileHeight; } //RECT src = {left,top,width, height}; float depth = 0.0; if (gRDP.otherMode.depth_source==1) depth = gRDP.fPrimitiveDepth; float x0 = sprite.sprite.objX/4.0f; float y0 = sprite.sprite.objY/4.0f; float x1 = sprite.sprite.imageW / 32.0f / scaleX + x0; float y1 = sprite.sprite.imageH / 32.0f / scaleY + y0; if( sprite.sprite.imageFlags&1 ) { float temp = x0; x0 = x1; x1 = temp; } // flip X if( sprite.sprite.imageFlags&0x10 ) { float temp = y0; y0 = y1; y1 = temp; } // flip Y g_texRectTVtx[0].x = (gObjMtxReal.A*x0 + gObjMtxReal.B*y0 + gObjMtxReal.X)*windowSetting.fMultX; g_texRectTVtx[0].y = (gObjMtxReal.C*x0 + gObjMtxReal.D*y0 + gObjMtxReal.Y)*windowSetting.fMultY; g_texRectTVtx[0].z = depth; g_texRectTVtx[0].rhw = 1; g_texRectTVtx[1].x = (gObjMtxReal.A*x1 + gObjMtxReal.B*y0 + gObjMtxReal.X)*windowSetting.fMultX; g_texRectTVtx[1].y = (gObjMtxReal.C*x1 + gObjMtxReal.D*y0 + gObjMtxReal.Y)*windowSetting.fMultY; g_texRectTVtx[1].z = depth; g_texRectTVtx[1].rhw = 1; g_texRectTVtx[2].x = (gObjMtxReal.A*x1 + gObjMtxReal.B*y1 + gObjMtxReal.X)*windowSetting.fMultX; g_texRectTVtx[2].y = (gObjMtxReal.C*x1 + gObjMtxReal.D*y1 + gObjMtxReal.Y)*windowSetting.fMultY; g_texRectTVtx[2].z = depth; g_texRectTVtx[2].rhw = 1; g_texRectTVtx[3].x = (gObjMtxReal.A*x0 + gObjMtxReal.B*y1 + gObjMtxReal.X)*windowSetting.fMultX; g_texRectTVtx[3].y = (gObjMtxReal.C*x0 + gObjMtxReal.D*y1 + gObjMtxReal.Y)*windowSetting.fMultY; g_texRectTVtx[3].z = depth; g_texRectTVtx[3].rhw = 1; g_texRectTVtx[0].tcord[0].u = left/g_textures[tile].m_fTexWidth; g_texRectTVtx[0].tcord[0].v = top/g_textures[tile].m_fTexHeight; g_texRectTVtx[1].tcord[0].u = (left+width)/g_textures[tile].m_fTexWidth; g_texRectTVtx[1].tcord[0].v = top/g_textures[tile].m_fTexHeight; g_texRectTVtx[2].tcord[0].u = (left+width)/g_textures[tile].m_fTexWidth; g_texRectTVtx[2].tcord[0].v = (top+height)/g_textures[tile].m_fTexHeight; g_texRectTVtx[3].tcord[0].u = left/g_textures[tile].m_fTexWidth; g_texRectTVtx[3].tcord[0].v = (top+height)/g_textures[tile].m_fTexHeight; //COLOR speColor = PostProcessSpecularColor(); COLOR difColor = PostProcessDiffuseColor(0xffffffff); g_texRectTVtx[0].dcDiffuse = g_texRectTVtx[1].dcDiffuse = g_texRectTVtx[2].dcDiffuse = g_texRectTVtx[3].dcDiffuse = difColor; g_texRectTVtx[0].dcSpecular = g_texRectTVtx[1].dcSpecular = g_texRectTVtx[2].dcSpecular = g_texRectTVtx[3].dcSpecular = difColor; DrawSpriteR_Render(); } void CRender::DrawFrameBuffer(bool useVIreg, uint32_t left, uint32_t top, uint32_t width, uint32_t height) { BeginRendering(); LoadFrameBuffer(useVIreg, left, top, width, height); m_pColorCombiner->InitCombinerBlenderForSimpleTextureDraw(0); ZBufferEnable(FALSE); SetZUpdate(FALSE); if( left == 0 ) SetAlphaTestEnable(FALSE); else SetAlphaTestEnable(TRUE); // use Alpha Test for partial frame buffer draw, for Dr. Mario 64 m_pAlphaBlender->Disable(); CTexture *pTexture = g_textures[0].m_pCTexture; if( pTexture ) { if( useVIreg ) { // Draw the whole frame buffer DrawSimple2DTexture(0, 0, windowSetting.uViWidth, windowSetting.uViHeight, 0, 0, 1/pTexture->m_fXScale, 1/pTexture->m_fYScale, 0xFFFFFFFF, 0xFFFFFFFF, 0, 1); } else { // Draw a small texture in frame buffer DrawSimple2DTexture((float)left, (float)top, (float)(left+width), (float)(top+height), 0, 0, 1/pTexture->m_fXScale, 1/pTexture->m_fYScale, 0xFFFFFFFF, 0xFFFFFFFF, 0, 1); } } TXTRBUF_OR_CI_DUMP(TRACE0("Draw Frame Buffer Img")); #ifdef DEBUGGER if( pauseAtNext && ( eventToPause == NEXT_FRAME || eventToPause == NEXT_FLUSH_TRI ) ) { TRACE0("Draw Frame Buffer Img"); debuggerPause = true; DebuggerPause(); } #endif EndRendering(); } void CRender::DrawObjBGCopy(uObjBg &info) { if( !status.bCIBufferIsRendered ) g_pFrameBufferManager->ActiveTextureBuffer(); if( status.bHandleN64RenderTexture ) { g_pRenderTextureInfo->maxUsedHeight = g_pRenderTextureInfo->N64Height; if( !status.bDirectWriteIntoRDRAM ) { status.bFrameBufferIsDrawn = true; status.bFrameBufferDrawnByTriangles = true; } } SetCombinerAndBlender(); uint32_t frameH = info.frameH; uint32_t frameW = info.frameW; uint32_t imageH = info.imageH; uint32_t imageW = info.imageW; if( options.bEnableHacks ) { if( g_CI.dwWidth == 0x200 && info.imageFmt == g_CI.dwFormat && info.imageSiz == g_CI.dwSize && frameW == 0x800 ) { // Hack for RE2 uint32_t width = *gfx_info.VI_WIDTH_REG & 0xFFF; imageH = frameH = (frameW/4*frameH/4)/width*4; imageW = frameW = width*4; } } float x0 = info.frameX / 4.0f; float y0 = info.frameY / 4.0f; float x1 = frameW / 4.0f + x0; float y1 = frameH / 4.0f + y0; float s0 = info.imageX / 32.0f; float t0 = info.imageY / 32.0f; float texwidth = imageW/4.0f; float texheight = imageH/4.0f; float u0 = s0/g_textures[0].m_fTexWidth; float v0 = t0/g_textures[0].m_fTexHeight; float maxu = texwidth/g_textures[0].m_fTexWidth; float maxv = texheight/g_textures[0].m_fTexHeight; float x2 = x0 + (texwidth-s0); float y2 = y0 + (texheight-t0); float u1 = (x1-x2)/g_textures[0].m_fTexWidth; float v1 = (y1-y2)/g_textures[0].m_fTexHeight; float depth = (gRDP.otherMode.depth_source == 1 ? gRDP.fPrimitiveDepth : 0.0f); COLOR speColor = PostProcessSpecularColor(); COLOR difColor = PostProcessDiffuseColor(0xffffffff); if( options.enableHackForGames == HACK_FOR_COMMANDCONQUER ) { float s1 = (x1-x0) + s0; float t1 = (y1-y0) + t0; DrawSimple2DTexture(x0, y0, x1, y1, u0, v0, s1/g_textures[0].m_fTexWidth, t1/g_textures[0].m_fTexHeight, difColor, speColor, depth, 1); } else if( x2 >= x1 ) { float s1 = (x1-x0) + s0; if( y2 >= y1 ) { float t1 = (y1-y0) + t0; DrawSimple2DTexture(x0, y0, x1, y1, u0, v0, s1/g_textures[0].m_fTexWidth, t1/g_textures[0].m_fTexHeight, difColor, speColor, depth, 1); } else { DrawSimple2DTexture(x0, y0, x1, y2, u0, v0, s1/g_textures[0].m_fTexWidth, maxv, difColor, speColor, depth, 1); DrawSimple2DTexture(x0, y2, x1, y1, u0, 0, s1/g_textures[0].m_fTexWidth, v1, difColor, speColor, depth, 1); } } else { if( y2 >= y1 ) { float t1 = (y1-y0) + t0; DrawSimple2DTexture(x0, y0, x2, y1, u0, v0, maxu, t1/g_textures[0].m_fTexHeight, difColor, speColor, depth, 1); DrawSimple2DTexture(x2, y0, x1, y1, 0, v0, u1, t1/g_textures[0].m_fTexHeight, difColor, speColor, depth, 1); } else { DrawSimple2DTexture(x0, y0, x2, y2, u0, v0, maxu, maxv, difColor, speColor, depth, 1); DrawSimple2DTexture(x2, y0, x1, y2, 0, v0, u1, maxv, difColor, speColor, depth, 1); DrawSimple2DTexture(x0, y2, x2, y1, u0, 0, maxu, v1, difColor, speColor, depth, 1); DrawSimple2DTexture(x2, y2, x1, y1, 0, 0, u1, v1, difColor, speColor, depth, 1); } } DEBUGGER_PAUSE_AT_COND_AND_DUMP_COUNT_N( (pauseAtNext&&(eventToPause==NEXT_OBJ_BG||eventToPause==NEXT_FLUSH_TRI||eventToPause==NEXT_OBJ_TXT_CMD)), { TRACE0("Pause ObjBG Copy"); } ); } void CRender::DrawObjBG1CYC(uObjScaleBg &bg, bool scaled) // Without Rotation { if( !status.bCIBufferIsRendered ) g_pFrameBufferManager->ActiveTextureBuffer(); if( g_curRomInfo.bDisableObjBG ) return; if( status.bHandleN64RenderTexture ) { g_pRenderTextureInfo->maxUsedHeight = g_pRenderTextureInfo->N64Height; if( !status.bDirectWriteIntoRDRAM ) { status.bFrameBufferIsDrawn = true; status.bFrameBufferDrawnByTriangles = true; } } SetCombinerAndBlender(); float depth = (gRDP.otherMode.depth_source == 1 ? gRDP.fPrimitiveDepth : 0.0f); float x0 = bg.frameX / 4.0f; float y0 = bg.frameY / 4.0f; float x1 = bg.frameW / 4.0f + x0; float y1 = bg.frameH / 4.0f + y0; float s0 = bg.imageX / 32.0f; float t0 = bg.imageY / 32.0f; float scaleX = bg.scaleW/1024.0f; float scaleY = bg.scaleH/1024.0f; float texwidth = bg.imageW/4.0f; float texheight = bg.imageH/4.0f; float u0 = s0/g_textures[0].m_fTexWidth; float v0 = t0/g_textures[0].m_fTexHeight; float maxu = texwidth/g_textures[0].m_fTexWidth; float maxv = texheight/g_textures[0].m_fTexHeight; float x2 = x0 + (texwidth-s0)/scaleX; float y2 = y0 + (texheight-t0)/scaleY; float u1 = (x1-x2)*scaleX/g_textures[0].m_fTexWidth; float v1 = (y1-y2)*scaleY/g_textures[0].m_fTexHeight; COLOR speColor = PostProcessSpecularColor(); COLOR difColor = PostProcessDiffuseColor(0xffffffff); SetAlphaTestEnable(FALSE); if( options.enableHackForGames != HACK_FOR_YOSHI ) { float s1 = (x1-x0)*scaleX + s0; float t1 = (y1-y0)*scaleY + t0; DrawSimple2DTexture(x0, y0, x1, y1, u0, v0, s1/g_textures[0].m_fTexWidth, t1/g_textures[0].m_fTexHeight, difColor, speColor, depth, 1); } else if( x2 >= x1 ) { float s1 = (x1-x0)*scaleX + s0; if( y2 >= y1 ) { float t1 = (y1-y0)*scaleY + t0; DrawSimple2DTexture(x0, y0, x1, y1, u0, v0, s1/g_textures[0].m_fTexWidth, t1/g_textures[0].m_fTexHeight, difColor, speColor, depth, 1); } else { DrawSimple2DTexture(x0, y0, x1, y2, u0, v0, s1/g_textures[0].m_fTexWidth, maxv, difColor, speColor, depth, 1); DrawSimple2DTexture(x0, y2, x1, y1, u0, 0, s1/g_textures[0].m_fTexWidth, v1, difColor, speColor, depth, 1); } } else { if( y2 >= y1 ) { float t1 = (y1-y0)*scaleY + t0; DrawSimple2DTexture(x0, y0, x2, y1, u0, v0, maxu, t1/g_textures[0].m_fTexHeight, difColor, speColor, depth, 1); DrawSimple2DTexture(x2, y0, x1, y1, 0, v0, u1, t1/g_textures[0].m_fTexHeight, difColor, speColor, depth, 1); } else { DrawSimple2DTexture(x0, y0, x2, y2, u0, v0, maxu, maxv, difColor, speColor, depth, 1); DrawSimple2DTexture(x2, y0, x1, y2, 0, v0, u1, maxv, difColor, speColor, depth, 1); DrawSimple2DTexture(x0, y2, x2, y1, u0, 0, maxu, v1, difColor, speColor, depth, 1); DrawSimple2DTexture(x2, y2, x1, y1, 0, 0, u1, v1, difColor, speColor, depth, 1); } } DEBUGGER_PAUSE_AT_COND_AND_DUMP_COUNT_N( (pauseAtNext&&(eventToPause==NEXT_OBJ_BG||eventToPause==NEXT_FLUSH_TRI||eventToPause==NEXT_OBJ_TXT_CMD)), { DebuggerAppendMsg("Pause BG 1CYC: (%.0f,%.0f - %.0f,%.0f), \ntex (%.2f,%.2f), scale (%.2f,%.2f)",x0,y0,x1,y1,s0,t0,scaleX,scaleY); } ); } void CRender::DrawSprite(uObjTxSprite &sprite, bool rectR) // Without Rotation { if( !status.bCIBufferIsRendered ) g_pFrameBufferManager->ActiveTextureBuffer(); if( status.bHandleN64RenderTexture ) { g_pRenderTextureInfo->maxUsedHeight = g_pRenderTextureInfo->N64Height; if( !status.bDirectWriteIntoRDRAM ) { status.bFrameBufferIsDrawn = true; status.bFrameBufferDrawnByTriangles = true; } } SetCombinerAndBlender(); COLOR speColor = PostProcessSpecularColor(); COLOR difColor = PostProcessDiffuseColor(0xffffffff); float objX = sprite.sprite.objX/4.0f; float objY = sprite.sprite.objY/4.0f; float width = sprite.sprite.imageW / 32.0f; float high = sprite.sprite.imageH / 32.0f; float scaleW = sprite.sprite.scaleW/1024.0f; float scaleH = sprite.sprite.scaleH/1024.0f; if( g_curRomInfo.bIncTexRectEdge ) { width++; high++; } float x0, y0, x1, y1; if( rectR ) { // Upper-left coordinate // ( X + objX / BaseScaleX, Y+objY/BaseScaleY ) // Lower-right coordinate // ( X + (objX + imageW / scaleW) / BaseScaleX - 1, Y + (objY + imageH / scaleH) / BaseScaleY - 1 ) x0 = gObjMtxReal.X + objX/gObjMtxReal.BaseScaleX; y0 = gObjMtxReal.Y + objY/gObjMtxReal.BaseScaleY; x1 = gObjMtxReal.X + (objX + width / scaleW) / gObjMtxReal.BaseScaleX; y1 = gObjMtxReal.Y + (objY + high / scaleH) / gObjMtxReal.BaseScaleY; } else { // (objX, objY) - ( objX+imageW/scaleW-1, objY+imageH/scaleH-1) x0 = objX; y0 = objY; x1 = objX + width / scaleW; y1 = objY + high / scaleH; if( (sprite.sprite.imageFlags&1) ) // flipX { float temp = x0; x0 = x1; x1 = temp; } if( (sprite.sprite.imageFlags&0x10) ) // flipY { float temp = y0; y0 = y1; y1 = temp; } } // save the current clamp type GLint iClampS, iClampT; glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, &iClampS); OPENGL_CHECK_ERRORS; glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, &iClampT); OPENGL_CHECK_ERRORS; // force clamp type to CLAMP_EDGE (experiments show sometimes this is set to hex 0x2901 - invalid value) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); OPENGL_CHECK_ERRORS; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); OPENGL_CHECK_ERRORS; // draw the 2D sprite as 2 triangles float depth = (gRDP.otherMode.depth_source == 1 ? gRDP.fPrimitiveDepth : 0.0f); CTexture *pTexture = g_textures[0].m_pCTexture; DrawSimple2DTexture(x0, y0, x1, y1, 0, 0, 1/pTexture->m_fXScale, 1/pTexture->m_fYScale, difColor, speColor, depth, 1); // return clamp type to original setting glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampS); OPENGL_CHECK_ERRORS; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampT); OPENGL_CHECK_ERRORS; } void CRender::LoadObjBG1CYC(uObjScaleBg &bg) { uint32_t *rdram_u32 = (uint32_t*)gfx_info.RDRAM; uint32_t imageWidth = bg.imageW/4; uint32_t imageHeight = bg.imageH/4; TxtrInfo gti; gti.Format = bg.imageFmt; gti.Size = bg.imageSiz; uint8_t *palAddr = (uint8_t *) &g_wRDPTlut[0]; gti.Address = RSPSegmentAddr(bg.imagePtr); gti.LeftToLoad = 0; gti.TopToLoad = 0; gti.WidthToCreate = imageWidth; gti.HeightToCreate = imageHeight; gti.clampS = gti.clampT = 1; gti.maskS = gti.maskT = 0; gti.Palette = bg.imagePal; gti.PalAddress = palAddr; gti.Pitch = imageWidth << gti.Size >> 1; gti.Pitch = (gti.Pitch>>3)<<3; // Align to 8 bytes if( gti.Address + gti.Pitch*gti.HeightToCreate > g_dwRamSize ) { TRACE0("Skip BG 1CYC loading, memory out of bound"); return; } gti.TLutFmt = TLUT_FMT_RGBA16; //RGBA16 gti.bSwapped = FALSE; gti.HeightToLoad = gti.HeightToCreate; gti.WidthToLoad = gti.WidthToCreate; gti.pPhysicalAddress = ((uint8_t*)rdram_u32) + gti.Address; gti.tileNo = -1; TxtrCacheEntry *pEntry = gTextureManager.GetTexture(>i, false, true, false); SetCurrentTexture(0,pEntry); DEBUGGER_IF_DUMP((pauseAtNext && (eventToPause == NEXT_OBJ_TXT_CMD||eventToPause == NEXT_FLUSH_TRI||eventToPause == NEXT_OBJ_BG)), { TRACE0("Load Obj BG 1CYC:\n"); DebuggerAppendMsg("Addr=0x%08X, W=%d, H=%d, Left=%d, Top=%d\n", gti.Address, gti.WidthToCreate, gti.HeightToCreate, gti.LeftToLoad, gti.TopToLoad); DebuggerAppendMsg("Fmt=%s-%db, Pal=%d\n", pszImgFormat[gti.Format], pnImgSize[gti.Size], gti.Palette); } ); } void CRender::LoadObjSprite(uObjTxSprite &sprite, bool useTIAddr) { TxtrInfo gti; uint32_t *rdram_u32 = (uint32_t*)gfx_info.RDRAM; gti.Format = sprite.sprite.imageFmt; gti.Size = sprite.sprite.imageSiz; uint8_t *palAddr = (uint8_t *) &g_wRDPTlut[0]; gti.Address = RSPSegmentAddr(sprite.txtr.block.image); gti.Address += sprite.sprite.imageAdrs<<3; gti.LeftToLoad = 0; gti.TopToLoad = 0; gti.Palette = sprite.sprite.imagePal; gti.PalAddress = palAddr; if( sprite.txtr.block.type == S2DEX_OBJLT_TXTRBLOCK ) { gti.WidthToCreate = sprite.sprite.imageW/32; if( sprite.sprite.imageW >= 0x8000 ) { gti.WidthToCreate = (0x10000-sprite.sprite.imageW)/32; } gti.HeightToCreate = sprite.sprite.imageH/32; if( sprite.sprite.imageH >= 0x8000 ) { gti.HeightToCreate = (0x10000-sprite.sprite.imageH)/32; } gti.Pitch = (2047/(sprite.txtr.block.tline-1)) << 3; } else if( sprite.txtr.block.type == S2DEX_OBJLT_TXTRTILE ) { //#define GS_PIX2TMEM(pix, siz) ((pix)>>(4-(siz))) //#define GS_TT_TWIDTH(pix,siz) ((GS_PIX2TMEM((pix), (siz))<<2)-1) //#define GS_TT_THEIGHT(pix,siz) (((pix)<<2)-1) gti.WidthToCreate = ((sprite.txtr.tile.twidth+1)>>2)<<(4-gti.Size); gti.HeightToCreate = (sprite.txtr.tile.theight+1)>>2; if( gti.Size == TXT_SIZE_4b ) { gti.Pitch = gti.WidthToCreate >> 1; } else { //gti.Pitch = (sprite.txtr.tile.twidth+1) << 3; gti.Pitch = gti.WidthToCreate << (gti.Size-1); } } if( gti.Address + gti.Pitch*gti.HeightToCreate > g_dwRamSize ) { TRACE0("Skip Obj sprite loading, memory out of bound"); return; } gti.TLutFmt = TLUT_FMT_RGBA16; //RGBA16 gti.bSwapped = FALSE; gti.HeightToLoad = gti.HeightToCreate; gti.WidthToLoad = gti.WidthToCreate; gti.pPhysicalAddress = ((uint8_t*)rdram_u32) + gti.Address; gti.tileNo = -1; TxtrCacheEntry *pEntry = gTextureManager.GetTexture(>i, false, true, false); SetCurrentTexture(0,pEntry); } mupen64plus-core/src/r4300/exception.h000664 001750 001750 00000003323 12655644434 020556 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - exception.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_R4300_EXCEPTION_H #define M64P_R4300_EXCEPTION_H #include void TLB_refill_exception(uint32_t addresse, int w); void exception_general(void); #endif /* M64P_R4300_EXCEPTION_H */ mupen64plus-core/src/plugin/audio_libretro/audio_resampler_driver.h000664 001750 001750 00000014667 12655644434 027054 0ustar00sergiosergio000000 000000 /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2015 - Daniel De Matteis * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. * * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with RetroArch. * If not, see . */ #ifndef __AUDIO_RESAMPLER_DRIVER_H #define __AUDIO_RESAMPLER_DRIVER_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include #ifndef M_PI #define M_PI 3.14159265358979323846264338327 #endif #define RESAMPLER_SIMD_SSE (1 << 0) #define RESAMPLER_SIMD_SSE2 (1 << 1) #define RESAMPLER_SIMD_VMX (1 << 2) #define RESAMPLER_SIMD_VMX128 (1 << 3) #define RESAMPLER_SIMD_AVX (1 << 4) #define RESAMPLER_SIMD_NEON (1 << 5) #define RESAMPLER_SIMD_SSE3 (1 << 6) #define RESAMPLER_SIMD_SSSE3 (1 << 7) #define RESAMPLER_SIMD_MMX (1 << 8) #define RESAMPLER_SIMD_MMXEXT (1 << 9) #define RESAMPLER_SIMD_SSE4 (1 << 10) #define RESAMPLER_SIMD_SSE42 (1 << 11) #define RESAMPLER_SIMD_AVX2 (1 << 12) #define RESAMPLER_SIMD_VFPU (1 << 13) #define RESAMPLER_SIMD_PS (1 << 14) /* A bit-mask of all supported SIMD instruction sets. * Allows an implementation to pick different * resampler_implementation structs. */ typedef unsigned resampler_simd_mask_t; #define RESAMPLER_API_VERSION 1 struct resampler_data { const float *data_in; float *data_out; size_t input_frames; size_t output_frames; double ratio; }; /* Returns true if config key was found. Otherwise, * returns false, and sets value to default value. */ typedef int (*resampler_config_get_float_t)(void *userdata, const char *key, float *value, float default_value); typedef int (*resampler_config_get_int_t)(void *userdata, const char *key, int *value, int default_value); /* Allocates an array with values. free() with resampler_config_free_t. */ typedef int (*resampler_config_get_float_array_t)(void *userdata, const char *key, float **values, unsigned *out_num_values, const float *default_values, unsigned num_default_values); typedef int (*resampler_config_get_int_array_t)(void *userdata, const char *key, int **values, unsigned *out_num_values, const int *default_values, unsigned num_default_values); typedef int (*resampler_config_get_string_t)(void *userdata, const char *key, char **output, const char *default_output); /* Calls free() in host runtime. Sometimes needed on Windows. * free() on NULL is fine. */ typedef void (*resampler_config_free_t)(void *ptr); struct resampler_config { resampler_config_get_float_t get_float; resampler_config_get_int_t get_int; resampler_config_get_float_array_t get_float_array; resampler_config_get_int_array_t get_int_array; resampler_config_get_string_t get_string; /* Avoid problems where resampler plug and host are * linked against different C runtimes. */ resampler_config_free_t free; }; /* Bandwidth factor. Will be < 1.0 for downsampling, > 1.0 for upsampling. * Corresponds to expected resampling ratio. */ typedef void *(*resampler_init_t)(const struct resampler_config *config, double bandwidth_mod, resampler_simd_mask_t mask); /* Frees the handle. */ typedef void (*resampler_free_t)(void *data); /* Processes input data. */ typedef void (*resampler_process_t)(void *_data, struct resampler_data *data); typedef struct rarch_resampler { resampler_init_t init; resampler_process_t process; resampler_free_t free; /* Must be RESAMPLER_API_VERSION */ unsigned api_version; /* Human readable identifier of implementation. */ const char *ident; /* Computer-friendly short version of ident. * Lower case, no spaces and special characters, etc. */ const char *short_ident; } rarch_resampler_t; typedef struct audio_frame_float { float l; float r; } audio_frame_float_t; extern rarch_resampler_t sinc_resampler; extern rarch_resampler_t CC_resampler; extern rarch_resampler_t nearest_resampler; #ifndef DONT_HAVE_STRING_LIST /** * config_get_audio_resampler_driver_options: * * Get an enumerated list of all resampler driver names, separated by '|'. * * Returns: string listing of all resampler driver names, separated by '|'. **/ const char* config_get_audio_resampler_driver_options(void); #endif /** * audio_resampler_driver_find_handle: * @index : index of driver to get handle to. * * Returns: handle to audio resampler driver at index. Can be NULL * if nothing found. **/ const void *audio_resampler_driver_find_handle(int index); /** * audio_resampler_driver_find_ident: * @index : index of driver to get handle to. * * Returns: Human-readable identifier of audio resampler driver at index. * Can be NULL if nothing found. **/ const char *audio_resampler_driver_find_ident(int index); /** * rarch_resampler_realloc: * @re : Resampler handle * @backend : Resampler backend that is about to be set. * @ident : Identifier name for resampler we want. * @bw_ratio : Bandwidth ratio. * * Reallocates resampler. Will free previous handle before * allocating a new one. If ident is NULL, first resampler will be used. * * Returns: true (1) if successful, otherwise false (0). **/ bool rarch_resampler_realloc(void **re, const rarch_resampler_t **backend, const char *ident, double bw_ratio); /* Convenience macros. * freep makes sure to set handles to NULL to avoid double-free * in rarch_resampler_realloc. */ #define rarch_resampler_freep(backend, handle) do { \ if (*(backend) && *(handle)) \ (*backend)->free(*handle); \ *backend = NULL; \ *handle = NULL; \ } while(0) #define rarch_resampler_process(backend, handle, data) do { \ (backend)->process(handle, data); \ } while(0) #ifndef RARCH_INTERNAL #include "libretro.h" extern retro_get_cpu_features_t perf_get_cpu_features_cb; #endif #ifdef __cplusplus } #endif #endif mupen64plus-core/src/r4300/exception.c000664 001750 001750 00000010455 12655644434 020555 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - exception.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "api/m64p_types.h" #include "api/callbacks.h" #include "memory/memory.h" #include "exception.h" #include "r4300.h" #include "cp0_private.h" #include "recomph.h" #include "tlb.h" static void exception_common(void) { if(delay_slot==1 || delay_slot==3) { g_cp0_regs[CP0_CAUSE_REG] |= 0x80000000; g_cp0_regs[CP0_EPC_REG] -= 4; } else { g_cp0_regs[CP0_CAUSE_REG] &= 0x7FFFFFFF; } last_addr = PC->addr; if (r4300emu == CORE_DYNAREC) { dyna_jump(); if (!dyna_interp) delay_slot = 0; } if (r4300emu != CORE_DYNAREC || dyna_interp) { dyna_interp = 0; if (delay_slot) { skip_jump = PC->addr; // The interpreters and the Old Dynarec need this. next_interupt = 0; } } } void TLB_refill_exception(uint32_t address, int mode) { if (r4300emu != CORE_DYNAREC && mode != TLB_FAST_READ) cp0_update_count(); if (mode == TLB_WRITE) g_cp0_regs[CP0_CAUSE_REG] = (UINT32_C(3) << 2); else g_cp0_regs[CP0_CAUSE_REG] = (UINT32_C(2) << 2); g_cp0_regs[CP0_BADVADDR_REG] = address; g_cp0_regs[CP0_CONTEXT_REG] = (g_cp0_regs[CP0_CONTEXT_REG] & UINT32_C(0xFF80000F)) | ((address >> 9) & UINT32_C(0x007FFFF0)); g_cp0_regs[CP0_ENTRYHI_REG] = address & UINT32_C(0xFFFFE000); if (g_cp0_regs[CP0_STATUS_REG] & 0x2) // Test de EXL { generic_jump_to(UINT32_C(0x80000180)); if(delay_slot==1 || delay_slot==3) g_cp0_regs[CP0_CAUSE_REG] |= UINT32_C(0x80000000); else g_cp0_regs[CP0_CAUSE_REG] &= UINT32_C(0x7FFFFFFF); } else { int usual_handler = 0, i; if (r4300emu != CORE_PURE_INTERPRETER) { if (mode != TLB_FAST_READ) g_cp0_regs[CP0_EPC_REG] = PC->addr; else g_cp0_regs[CP0_EPC_REG] = address; } else g_cp0_regs[CP0_EPC_REG] = PC->addr; g_cp0_regs[CP0_CAUSE_REG] &= ~UINT32_C(0x80000000); g_cp0_regs[CP0_STATUS_REG] |= UINT32_C(0x2); //EXL=1 if (address >= UINT32_C(0x80000000) && address < UINT32_C(0xc0000000)) usual_handler = 1; for (i=0; i<32; i++) { if (/*tlb_e[i].v_even &&*/ address >= tlb_e[i].start_even && address <= tlb_e[i].end_even) usual_handler = 1; if (/*tlb_e[i].v_odd &&*/ address >= tlb_e[i].start_odd && address <= tlb_e[i].end_odd) usual_handler = 1; } if (usual_handler) generic_jump_to(UINT32_C(0x80000180)); else generic_jump_to(UINT32_C(0x80000000)); } if(mode != TLB_FAST_READ) g_cp0_regs[CP0_EPC_REG] -= 4; exception_common(); } void exception_general(void) { cp0_update_count(); g_cp0_regs[CP0_STATUS_REG] |= 2; g_cp0_regs[CP0_EPC_REG] = PC->addr; generic_jump_to(UINT32_C(0x80000180)); exception_common(); } mupen64plus-rsp-hle/src/musyx.c000664 001750 001750 00000100623 12655644434 017613 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-rsp-hle - musyx.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2013 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include "common.h" #include "arithmetics.h" #include "audio.h" #include "hle_external.h" #include "hle_internal.h" #include "memory.h" /* various constants */ enum { SUBFRAME_SIZE = 192 }; enum { MAX_VOICES = 32 }; enum { SAMPLE_BUFFER_SIZE = 0x200 }; enum { SFD_VOICE_COUNT = 0x0, SFD_SFX_INDEX = 0x2, SFD_VOICE_BITMASK = 0x4, SFD_STATE_PTR = 0x8, SFD_SFX_PTR = 0xc, SFD_VOICES = 0x10, /* v2 only */ SFD2_10_PTR = 0x10, SFD2_14_BITMASK = 0x14, SFD2_15_BITMASK = 0x15, SFD2_16_BITMASK = 0x16, SFD2_18_PTR = 0x18, SFD2_1C_PTR = 0x1c, SFD2_20_PTR = 0x20, SFD2_24_PTR = 0x24, SFD2_VOICES = 0x28 }; enum { VOICE_ENV_BEGIN = 0x00, VOICE_ENV_STEP = 0x10, VOICE_PITCH_Q16 = 0x20, VOICE_PITCH_SHIFT = 0x22, VOICE_CATSRC_0 = 0x24, VOICE_CATSRC_1 = 0x30, VOICE_ADPCM_FRAMES = 0x3c, VOICE_SKIP_SAMPLES = 0x3e, /* for PCM16 */ VOICE_U16_40 = 0x40, VOICE_U16_42 = 0x42, /* for ADPCM */ VOICE_ADPCM_TABLE_PTR = 0x40, VOICE_INTERLEAVED_PTR = 0x44, VOICE_END_POINT = 0x48, VOICE_RESTART_POINT = 0x4a, VOICE_U16_4C = 0x4c, VOICE_U16_4E = 0x4e, VOICE_SIZE = 0x50 }; enum { CATSRC_PTR1 = 0x00, CATSRC_PTR2 = 0x04, CATSRC_SIZE1 = 0x08, CATSRC_SIZE2 = 0x0a }; enum { STATE_LAST_SAMPLE = 0x0, STATE_BASE_VOL = 0x100, STATE_CC0 = 0x110, STATE_740_LAST4_V1 = 0x290, STATE_740_LAST4_V2 = 0x110 }; enum { SFX_CBUFFER_PTR = 0x00, SFX_CBUFFER_LENGTH = 0x04, SFX_TAP_COUNT = 0x08, SFX_FIR4_HGAIN = 0x0a, SFX_TAP_DELAYS = 0x0c, SFX_TAP_GAINS = 0x2c, SFX_U16_3C = 0x3c, SFX_U16_3E = 0x3e, SFX_FIR4_HCOEFFS = 0x40 }; /* struct definition */ typedef struct { /* internal subframes */ int16_t left[SUBFRAME_SIZE]; int16_t right[SUBFRAME_SIZE]; int16_t cc0[SUBFRAME_SIZE]; int16_t e50[SUBFRAME_SIZE]; /* internal subframes base volumes */ int32_t base_vol[4]; /* */ int16_t subframe_740_last4[4]; } musyx_t; typedef void (*mix_sfx_with_main_subframes_t)(musyx_t *musyx, const int16_t *subframe, const uint16_t* gains); /* helper functions prototypes */ static void load_base_vol(struct hle_t* hle, int32_t *base_vol, uint32_t address); static void save_base_vol(struct hle_t* hle, const int32_t *base_vol, uint32_t address); static void update_base_vol(struct hle_t* hle, int32_t *base_vol, uint32_t voice_mask, uint32_t last_sample_ptr, uint8_t mask_15, uint32_t ptr_24); static void init_subframes_v1(musyx_t *musyx); static void init_subframes_v2(musyx_t *musyx); static uint32_t voice_stage(struct hle_t* hle, musyx_t *musyx, uint32_t voice_ptr, uint32_t last_sample_ptr); static void dma_cat8(struct hle_t* hle, uint8_t *dst, uint32_t catsrc_ptr); static void dma_cat16(struct hle_t* hle, uint16_t *dst, uint32_t catsrc_ptr); static void load_samples_PCM16(struct hle_t* hle, uint32_t voice_ptr, int16_t *samples, unsigned *segbase, unsigned *offset); static void load_samples_ADPCM(struct hle_t* hle, uint32_t voice_ptr, int16_t *samples, unsigned *segbase, unsigned *offset); static void adpcm_decode_frames(struct hle_t* hle, int16_t *dst, const uint8_t *src, const int16_t *table, uint8_t count, uint8_t skip_samples); static void adpcm_predict_frame(int16_t *dst, const uint8_t *src, const uint8_t *nibbles, unsigned int rshift); static void mix_voice_samples(struct hle_t* hle, musyx_t *musyx, uint32_t voice_ptr, const int16_t *samples, unsigned segbase, unsigned offset, uint32_t last_sample_ptr); static void sfx_stage(struct hle_t* hle, mix_sfx_with_main_subframes_t mix_sfx_with_main_subframes, musyx_t *musyx, uint32_t sfx_ptr, uint16_t idx); static void mix_sfx_with_main_subframes_v1(musyx_t *musyx, const int16_t *subframe, const uint16_t* gains); static void mix_sfx_with_main_subframes_v2(musyx_t *musyx, const int16_t *subframe, const uint16_t* gains); static void mix_subframes(int16_t *y, const int16_t *x, int16_t hgain); static void mix_fir4(int16_t *y, const int16_t *x, int16_t hgain, const int16_t *hcoeffs); static void interleave_stage_v1(struct hle_t* hle, musyx_t *musyx, uint32_t output_ptr); static void interleave_stage_v2(struct hle_t* hle, musyx_t *musyx, uint16_t mask_16, uint32_t ptr_18, uint32_t ptr_1c, uint32_t output_ptr); static int32_t dot4(const int16_t *x, const int16_t *y) { size_t i; int32_t accu = 0; for (i = 0; i < 4; ++i) accu = clamp_s16(accu + (((int32_t)x[i] * (int32_t)y[i]) >> 15)); return accu; } /************************************************************************** * MusyX v1 audio ucode **************************************************************************/ void musyx_v1_task(struct hle_t* hle) { uint32_t sfd_ptr = *dmem_u32(hle, TASK_DATA_PTR); uint32_t sfd_count = *dmem_u32(hle, TASK_DATA_SIZE); uint32_t state_ptr; musyx_t musyx; HleVerboseMessage(hle->user_defined, "musyx_v1_task: *data=%x, #SF=%d", sfd_ptr, sfd_count); state_ptr = *dram_u32(hle, sfd_ptr + SFD_STATE_PTR); /* load initial state */ load_base_vol(hle, musyx.base_vol, state_ptr + STATE_BASE_VOL); dram_load_u16(hle, (uint16_t *)musyx.cc0, state_ptr + STATE_CC0, SUBFRAME_SIZE); dram_load_u16(hle, (uint16_t *)musyx.subframe_740_last4, state_ptr + STATE_740_LAST4_V1, 4); for (;;) { /* parse SFD structure */ uint16_t sfx_index = *dram_u16(hle, sfd_ptr + SFD_SFX_INDEX); uint32_t voice_mask = *dram_u32(hle, sfd_ptr + SFD_VOICE_BITMASK); uint32_t sfx_ptr = *dram_u32(hle, sfd_ptr + SFD_SFX_PTR); uint32_t voice_ptr = sfd_ptr + SFD_VOICES; uint32_t last_sample_ptr = state_ptr + STATE_LAST_SAMPLE; uint32_t output_ptr; /* initialize internal subframes using updated base volumes */ update_base_vol(hle, musyx.base_vol, voice_mask, last_sample_ptr, 0, 0); init_subframes_v1(&musyx); /* active voices get mixed into L,R,cc0,e50 subframes (optional) */ output_ptr = voice_stage(hle, &musyx, voice_ptr, last_sample_ptr); /* apply delay-based effects (optional) */ sfx_stage(hle, mix_sfx_with_main_subframes_v1, &musyx, sfx_ptr, sfx_index); /* emit interleaved L,R subframes */ interleave_stage_v1(hle, &musyx, output_ptr); --sfd_count; if (sfd_count == 0) break; sfd_ptr += SFD_VOICES + MAX_VOICES * VOICE_SIZE; state_ptr = *dram_u32(hle, sfd_ptr + SFD_STATE_PTR); } /* writeback updated state */ save_base_vol(hle, musyx.base_vol, state_ptr + STATE_BASE_VOL); dram_store_u16(hle, (uint16_t *)musyx.cc0, state_ptr + STATE_CC0, SUBFRAME_SIZE); dram_store_u16(hle, (uint16_t *)musyx.subframe_740_last4, state_ptr + STATE_740_LAST4_V1, 4); } /************************************************************************** * MusyX v2 audio ucode **************************************************************************/ void musyx_v2_task(struct hle_t* hle) { uint32_t sfd_ptr = *dmem_u32(hle, TASK_DATA_PTR); uint32_t sfd_count = *dmem_u32(hle, TASK_DATA_SIZE); musyx_t musyx; HleVerboseMessage(hle->user_defined, "musyx_v2_task: *data=%x, #SF=%d", sfd_ptr, sfd_count); for (;;) { /* parse SFD structure */ uint16_t sfx_index = *dram_u16(hle, sfd_ptr + SFD_SFX_INDEX); uint32_t voice_mask = *dram_u32(hle, sfd_ptr + SFD_VOICE_BITMASK); uint32_t state_ptr = *dram_u32(hle, sfd_ptr + SFD_STATE_PTR); uint32_t sfx_ptr = *dram_u32(hle, sfd_ptr + SFD_SFX_PTR); uint32_t voice_ptr = sfd_ptr + SFD2_VOICES; uint32_t ptr_10 = *dram_u32(hle, sfd_ptr + SFD2_10_PTR); uint8_t mask_14 = *dram_u8 (hle, sfd_ptr + SFD2_14_BITMASK); uint8_t mask_15 = *dram_u8 (hle, sfd_ptr + SFD2_15_BITMASK); uint16_t mask_16 = *dram_u16(hle, sfd_ptr + SFD2_16_BITMASK); uint32_t ptr_18 = *dram_u32(hle, sfd_ptr + SFD2_18_PTR); uint32_t ptr_1c = *dram_u32(hle, sfd_ptr + SFD2_1C_PTR); uint32_t ptr_20 = *dram_u32(hle, sfd_ptr + SFD2_20_PTR); uint32_t ptr_24 = *dram_u32(hle, sfd_ptr + SFD2_24_PTR); uint32_t last_sample_ptr = state_ptr + STATE_LAST_SAMPLE; uint32_t output_ptr; /* load state */ load_base_vol(hle, musyx.base_vol, state_ptr + STATE_BASE_VOL); dram_load_u16(hle, (uint16_t *)musyx.subframe_740_last4, state_ptr + STATE_740_LAST4_V2, 4); /* initialize internal subframes using updated base volumes */ update_base_vol(hle, musyx.base_vol, voice_mask, last_sample_ptr, mask_15, ptr_24); init_subframes_v2(&musyx); if (ptr_10) { /* TODO */ HleWarnMessage(hle->user_defined, "ptr_10=%08x mask_14=%02x ptr_24=%08x", ptr_10, mask_14, ptr_24); } /* active voices get mixed into L,R,cc0,e50 subframes (optional) */ output_ptr = voice_stage(hle, &musyx, voice_ptr, last_sample_ptr); /* apply delay-based effects (optional) */ sfx_stage(hle, mix_sfx_with_main_subframes_v2, &musyx, sfx_ptr, sfx_index); dram_store_u16(hle, (uint16_t*)musyx.left, output_ptr , SUBFRAME_SIZE); dram_store_u16(hle, (uint16_t*)musyx.right, output_ptr + 2*SUBFRAME_SIZE, SUBFRAME_SIZE); dram_store_u16(hle, (uint16_t*)musyx.cc0, output_ptr + 4*SUBFRAME_SIZE, SUBFRAME_SIZE); /* store state */ save_base_vol(hle, musyx.base_vol, state_ptr + STATE_BASE_VOL); dram_store_u16(hle, (uint16_t*)musyx.subframe_740_last4, state_ptr + STATE_740_LAST4_V2, 4); if (mask_16) interleave_stage_v2(hle, &musyx, mask_16, ptr_18, ptr_1c, ptr_20); --sfd_count; if (sfd_count == 0) break; sfd_ptr += SFD2_VOICES + MAX_VOICES * VOICE_SIZE; } } static void load_base_vol(struct hle_t* hle, int32_t *base_vol, uint32_t address) { base_vol[0] = ((uint32_t)(*dram_u16(hle, address)) << 16) | (*dram_u16(hle, address + 8)); base_vol[1] = ((uint32_t)(*dram_u16(hle, address + 2)) << 16) | (*dram_u16(hle, address + 10)); base_vol[2] = ((uint32_t)(*dram_u16(hle, address + 4)) << 16) | (*dram_u16(hle, address + 12)); base_vol[3] = ((uint32_t)(*dram_u16(hle, address + 6)) << 16) | (*dram_u16(hle, address + 14)); } static void save_base_vol(struct hle_t* hle, const int32_t *base_vol, uint32_t address) { unsigned k; for (k = 0; k < 4; ++k) { *dram_u16(hle, address) = (uint16_t)(base_vol[k] >> 16); address += 2; } for (k = 0; k < 4; ++k) { *dram_u16(hle, address) = (uint16_t)(base_vol[k]); address += 2; } } static void update_base_vol(struct hle_t* hle, int32_t *base_vol, uint32_t voice_mask, uint32_t last_sample_ptr, uint8_t mask_15, uint32_t ptr_24) { unsigned i, k; uint32_t mask; HleVerboseMessage(hle->user_defined, "base_vol voice_mask = %08x", voice_mask); HleVerboseMessage(hle->user_defined, "BEFORE: base_vol = %08x %08x %08x %08x", base_vol[0], base_vol[1], base_vol[2], base_vol[3]); /* optim: skip voices contributions entirely if voice_mask is empty */ if (voice_mask != 0) { for (i = 0, mask = 1; i < MAX_VOICES; ++i, mask <<= 1, last_sample_ptr += 8) { if ((voice_mask & mask) == 0) continue; for (k = 0; k < 4; ++k) base_vol[k] += (int16_t)*dram_u16(hle, last_sample_ptr + k * 2); } } /* optim: skip contributions entirely if mask_15 is empty */ if (mask_15 != 0) { for(i = 0, mask = 1; i < 4; ++i, mask <<= 1, ptr_24 += 8) { if ((mask_15 & mask) == 0) continue; for(k = 0; k < 4; ++k) base_vol[k] += (int16_t)*dram_u16(hle, ptr_24 + k * 2); } } /* apply 3% decay */ for (k = 0; k < 4; ++k) base_vol[k] = (base_vol[k] * 0x0000f850) >> 16; HleVerboseMessage(hle->user_defined, "AFTER: base_vol = %08x %08x %08x %08x", base_vol[0], base_vol[1], base_vol[2], base_vol[3]); } static void init_subframes_v1(musyx_t *musyx) { unsigned i; int16_t base_cc0 = clamp_s16(musyx->base_vol[2]); int16_t base_e50 = clamp_s16(musyx->base_vol[3]); int16_t *left = musyx->left; int16_t *right = musyx->right; int16_t *cc0 = musyx->cc0; int16_t *e50 = musyx->e50; for (i = 0; i < SUBFRAME_SIZE; ++i) { *(e50++) = base_e50; *(left++) = clamp_s16(*cc0 + base_cc0); *(right++) = clamp_s16(-*cc0 - base_cc0); *(cc0++) = 0; } } static void init_subframes_v2(musyx_t *musyx) { unsigned i,k; int16_t values[4]; int16_t* subframes[4]; for(k = 0; k < 4; ++k) values[k] = clamp_s16(musyx->base_vol[k]); subframes[0] = musyx->left; subframes[1] = musyx->right; subframes[2] = musyx->cc0; subframes[3] = musyx->e50; for (i = 0; i < SUBFRAME_SIZE; ++i) { for(k = 0; k < 4; ++k) *(subframes[k]++) = values[k]; } } /* Process voices, and returns interleaved subframe destination address */ static uint32_t voice_stage(struct hle_t* hle, musyx_t *musyx, uint32_t voice_ptr, uint32_t last_sample_ptr) { uint32_t output_ptr; /* voice stage can be skipped if first voice has no samples */ if (*dram_u16(hle, voice_ptr + VOICE_CATSRC_0 + CATSRC_SIZE1) == 0) { HleVerboseMessage(hle->user_defined, "Skipping Voice stage"); output_ptr = *dram_u32(hle, voice_ptr + VOICE_INTERLEAVED_PTR); } else { unsigned i = 0; /* otherwise process voices until a non null output_ptr is encountered */ for (;;) { /* load voice samples (PCM16 or APDCM) */ int16_t samples[SAMPLE_BUFFER_SIZE]; unsigned segbase; unsigned offset; HleVerboseMessage(hle->user_defined, "Processing Voice #%d", i); if (*dram_u8(hle, voice_ptr + VOICE_ADPCM_FRAMES) == 0) load_samples_PCM16(hle, voice_ptr, samples, &segbase, &offset); else load_samples_ADPCM(hle, voice_ptr, samples, &segbase, &offset); /* mix them with each internal subframes */ mix_voice_samples(hle, musyx, voice_ptr, samples, segbase, offset, last_sample_ptr + i * 8); /* check break condition */ output_ptr = *dram_u32(hle, voice_ptr + VOICE_INTERLEAVED_PTR); if (output_ptr != 0) break; /* next voice */ ++i; voice_ptr += VOICE_SIZE; } } return output_ptr; } static void dma_cat8(struct hle_t* hle, uint8_t *dst, uint32_t catsrc_ptr) { uint32_t ptr1 = *dram_u32(hle, catsrc_ptr + CATSRC_PTR1); uint32_t ptr2 = *dram_u32(hle, catsrc_ptr + CATSRC_PTR2); uint16_t size1 = *dram_u16(hle, catsrc_ptr + CATSRC_SIZE1); uint16_t size2 = *dram_u16(hle, catsrc_ptr + CATSRC_SIZE2); size_t count1 = size1; size_t count2 = size2; HleVerboseMessage(hle->user_defined, "dma_cat: %08x %08x %04x %04x", ptr1, ptr2, size1, size2); dram_load_u8(hle, dst, ptr1, count1); if (size2 != 0) dram_load_u8(hle, dst + count1, ptr2, count2); } static void dma_cat16(struct hle_t* hle, uint16_t *dst, uint32_t catsrc_ptr) { uint32_t ptr1 = *dram_u32(hle, catsrc_ptr + CATSRC_PTR1); uint32_t ptr2 = *dram_u32(hle, catsrc_ptr + CATSRC_PTR2); uint16_t size1 = *dram_u16(hle, catsrc_ptr + CATSRC_SIZE1); uint16_t size2 = *dram_u16(hle, catsrc_ptr + CATSRC_SIZE2); size_t count1 = size1 >> 1; size_t count2 = size2 >> 1; HleVerboseMessage(hle->user_defined, "dma_cat: %08x %08x %04x %04x", ptr1, ptr2, size1, size2); dram_load_u16(hle, dst, ptr1, count1); if (size2 != 0) dram_load_u16(hle, dst + count1, ptr2, count2); } static void load_samples_PCM16(struct hle_t* hle, uint32_t voice_ptr, int16_t *samples, unsigned *segbase, unsigned *offset) { uint8_t u8_3e = *dram_u8(hle, voice_ptr + VOICE_SKIP_SAMPLES); uint16_t u16_40 = *dram_u16(hle, voice_ptr + VOICE_U16_40); uint16_t u16_42 = *dram_u16(hle, voice_ptr + VOICE_U16_42); unsigned count = align(u16_40 + u8_3e, 4); HleVerboseMessage(hle->user_defined, "Format: PCM16"); *segbase = SAMPLE_BUFFER_SIZE - count; *offset = u8_3e; dma_cat16(hle, (uint16_t *)samples + *segbase, voice_ptr + VOICE_CATSRC_0); if (u16_42 != 0) dma_cat16(hle, (uint16_t *)samples, voice_ptr + VOICE_CATSRC_1); } static void load_samples_ADPCM(struct hle_t* hle, uint32_t voice_ptr, int16_t *samples, unsigned *segbase, unsigned *offset) { /* decompressed samples cannot exceed 0x400 bytes; * ADPCM has a compression ratio of 5/16 */ uint8_t buffer[SAMPLE_BUFFER_SIZE * 2 * 5 / 16]; int16_t adpcm_table[128]; uint8_t u8_3c = *dram_u8(hle, voice_ptr + VOICE_ADPCM_FRAMES ); uint8_t u8_3d = *dram_u8(hle, voice_ptr + VOICE_ADPCM_FRAMES + 1); uint8_t u8_3e = *dram_u8(hle, voice_ptr + VOICE_SKIP_SAMPLES ); uint8_t u8_3f = *dram_u8(hle, voice_ptr + VOICE_SKIP_SAMPLES + 1); uint32_t adpcm_table_ptr = *dram_u32(hle, voice_ptr + VOICE_ADPCM_TABLE_PTR); unsigned count; HleVerboseMessage(hle->user_defined, "Format: ADPCM"); HleVerboseMessage(hle->user_defined, "Loading ADPCM table: %08x", adpcm_table_ptr); dram_load_u16(hle, (uint16_t *)adpcm_table, adpcm_table_ptr, 128); count = u8_3c << 5; *segbase = SAMPLE_BUFFER_SIZE - count; *offset = u8_3e & 0x1f; dma_cat8(hle, buffer, voice_ptr + VOICE_CATSRC_0); adpcm_decode_frames(hle, samples + *segbase, buffer, adpcm_table, u8_3c, u8_3e); if (u8_3d == 0) return; dma_cat8(hle, buffer, voice_ptr + VOICE_CATSRC_1); adpcm_decode_frames(hle, samples, buffer, adpcm_table, u8_3d, u8_3f); } static void adpcm_decode_frames(struct hle_t* hle, int16_t *dst, const uint8_t *src, const int16_t *table, uint8_t count, uint8_t skip_samples) { unsigned i; int16_t frame[32]; const uint8_t *nibbles = src + 8; bool jump_gap = false; HleVerboseMessage(hle->user_defined, "ADPCM decode: count=%d, skip=%d", count, skip_samples); if (skip_samples >= 32) { jump_gap = true; nibbles += 16; src += 4; } for (i = 0; i < count; ++i) { uint8_t c2 = nibbles[0]; const int16_t *book = (c2 & 0xf0) + table; unsigned int rshift = (c2 & 0x0f); adpcm_predict_frame(frame, src, nibbles, rshift); memcpy(dst, frame, 2 * sizeof(frame[0])); adpcm_compute_residuals(dst + 2, frame + 2, book, dst , 6); adpcm_compute_residuals(dst + 8, frame + 8, book, dst + 6, 8); adpcm_compute_residuals(dst + 16, frame + 16, book, dst + 14, 8); adpcm_compute_residuals(dst + 24, frame + 24, book, dst + 22, 8); if (jump_gap) { nibbles += 8; src += 32; } jump_gap = !jump_gap; nibbles += 16; src += 4; dst += 32; } } static void adpcm_predict_frame(int16_t *dst, const uint8_t *src, const uint8_t *nibbles, unsigned int rshift) { unsigned int i; *(dst++) = (src[0] << 8) | src[1]; *(dst++) = (src[2] << 8) | src[3]; for (i = 1; i < 16; ++i) { uint8_t byte = nibbles[i]; *(dst++) = adpcm_predict_sample(byte, 0xf0, 8, rshift); *(dst++) = adpcm_predict_sample(byte, 0x0f, 12, rshift); } } static void mix_voice_samples(struct hle_t* hle, musyx_t *musyx, uint32_t voice_ptr, const int16_t *samples, unsigned segbase, unsigned offset, uint32_t last_sample_ptr) { int i, k; int32_t v4_env[4]; int32_t v4_env_step[4]; int16_t *v4_dst[4]; int16_t v4[4]; /* parse VOICE structure */ const uint16_t pitch_q16 = *dram_u16(hle, voice_ptr + VOICE_PITCH_Q16); const uint16_t pitch_shift = *dram_u16(hle, voice_ptr + VOICE_PITCH_SHIFT); /* Q4.12 */ const uint16_t end_point = *dram_u16(hle, voice_ptr + VOICE_END_POINT); const uint16_t restart_point = *dram_u16(hle, voice_ptr + VOICE_RESTART_POINT); const uint16_t u16_4e = *dram_u16(hle, voice_ptr + VOICE_U16_4E); /* init values and pointers */ const int16_t *sample = samples + segbase + offset + u16_4e; const int16_t *const sample_end = samples + segbase + end_point; const int16_t *const sample_restart = samples + (restart_point & 0x7fff) + (((restart_point & 0x8000) != 0) ? 0x000 : segbase); uint32_t pitch_accu = pitch_q16; uint32_t pitch_step = pitch_shift << 4; dram_load_u32(hle, (uint32_t *)v4_env, voice_ptr + VOICE_ENV_BEGIN, 4); dram_load_u32(hle, (uint32_t *)v4_env_step, voice_ptr + VOICE_ENV_STEP, 4); v4_dst[0] = musyx->left; v4_dst[1] = musyx->right; v4_dst[2] = musyx->cc0; v4_dst[3] = musyx->e50; HleVerboseMessage(hle->user_defined, "Voice debug: segbase=%d" "\tu16_4e=%04x\n" "\tpitch: frac0=%04x shift=%04x\n" "\tend_point=%04x restart_point=%04x\n" "\tenv = %08x %08x %08x %08x\n" "\tenv_step = %08x %08x %08x %08x\n", segbase, u16_4e, pitch_q16, pitch_shift, end_point, restart_point, v4_env[0], v4_env[1], v4_env[2], v4_env[3], v4_env_step[0], v4_env_step[1], v4_env_step[2], v4_env_step[3]); for (i = 0; i < SUBFRAME_SIZE; ++i) { int dist; int16_t v; /* update sample and lut pointers and then pitch_accu */ const int16_t *lut = (RESAMPLE_LUT + ((pitch_accu & 0xfc00) >> 8)); sample += (pitch_accu >> 16); pitch_accu &= 0xffff; pitch_accu += pitch_step; /* handle end/restart points */ dist = sample - sample_end; if (dist >= 0) sample = sample_restart + dist; /* apply resample filter */ v = clamp_s16(dot4(sample, lut)); for (k = 0; k < 4; ++k) { /* envmix */ int32_t accu = (v * (v4_env[k] >> 16)) >> 15; v4[k] = clamp_s16(accu); *(v4_dst[k]) = clamp_s16(accu + *(v4_dst[k])); /* update envelopes and dst pointers */ ++(v4_dst[k]); v4_env[k] += v4_env_step[k]; } } /* save last resampled sample */ dram_store_u16(hle, (uint16_t *)v4, last_sample_ptr, 4); HleVerboseMessage(hle->user_defined, "last_sample = %04x %04x %04x %04x", v4[0], v4[1], v4[2], v4[3]); } static void sfx_stage(struct hle_t* hle, mix_sfx_with_main_subframes_t mix_sfx_with_main_subframes, musyx_t *musyx, uint32_t sfx_ptr, uint16_t idx) { uint32_t cbuffer_ptr; uint32_t cbuffer_length; uint16_t tap_count; int16_t fir4_hgain; uint16_t sfx_gains[2]; unsigned int i; int16_t buffer[SUBFRAME_SIZE + 4]; uint32_t tap_delays[8]; int16_t tap_gains[8]; int16_t fir4_hcoeffs[4]; int16_t delayed[SUBFRAME_SIZE]; int16_t *subframe = buffer + 4; const uint32_t pos = idx * SUBFRAME_SIZE; HleVerboseMessage(hle->user_defined, "SFX: %08x, idx=%d", sfx_ptr, idx); if (sfx_ptr == 0) return; /* load sfx parameters */ cbuffer_ptr = *dram_u32(hle, sfx_ptr + SFX_CBUFFER_PTR); cbuffer_length = *dram_u32(hle, sfx_ptr + SFX_CBUFFER_LENGTH); tap_count = *dram_u16(hle, sfx_ptr + SFX_TAP_COUNT); dram_load_u32(hle, tap_delays, sfx_ptr + SFX_TAP_DELAYS, 8); dram_load_u16(hle, (uint16_t *)tap_gains, sfx_ptr + SFX_TAP_GAINS, 8); fir4_hgain = *dram_u16(hle, sfx_ptr + SFX_FIR4_HGAIN); dram_load_u16(hle, (uint16_t *)fir4_hcoeffs, sfx_ptr + SFX_FIR4_HCOEFFS, 4); sfx_gains[0] = *dram_u16(hle, sfx_ptr + SFX_U16_3C); sfx_gains[1] = *dram_u16(hle, sfx_ptr + SFX_U16_3E); HleVerboseMessage(hle->user_defined, "cbuffer: ptr=%08x length=%x", cbuffer_ptr, cbuffer_length); HleVerboseMessage(hle->user_defined, "fir4: hgain=%04x hcoeff=%04x %04x %04x %04x", fir4_hgain, fir4_hcoeffs[0], fir4_hcoeffs[1], fir4_hcoeffs[2], fir4_hcoeffs[3]); HleVerboseMessage(hle->user_defined, "tap count=%d\n" "delays: %08x %08x %08x %08x %08x %08x %08x %08x\n" "gains: %04x %04x %04x %04x %04x %04x %04x %04x", tap_count, tap_delays[0], tap_delays[1], tap_delays[2], tap_delays[3], tap_delays[4], tap_delays[5], tap_delays[6], tap_delays[7], tap_gains[0], tap_gains[1], tap_gains[2], tap_gains[3], tap_gains[4], tap_gains[5], tap_gains[6], tap_gains[7]); HleVerboseMessage(hle->user_defined, "sfx_gains=%04x %04x", sfx_gains[0], sfx_gains[1]); /* mix up to 8 delayed subframes */ memset(subframe, 0, SUBFRAME_SIZE * sizeof(subframe[0])); for (i = 0; i < tap_count; ++i) { int dlength; int dpos = pos - tap_delays[i]; if (dpos <= 0) dpos += cbuffer_length; dlength = SUBFRAME_SIZE; if ((uint32_t)(dpos + SUBFRAME_SIZE) > cbuffer_length) { dlength = cbuffer_length - dpos; dram_load_u16(hle, (uint16_t *)delayed + dlength, cbuffer_ptr, SUBFRAME_SIZE - dlength); } dram_load_u16(hle, (uint16_t *)delayed, cbuffer_ptr + dpos * 2, dlength); mix_subframes(subframe, delayed, tap_gains[i]); } /* add resulting subframe to main subframes */ mix_sfx_with_main_subframes(musyx, subframe, sfx_gains); /* apply FIR4 filter and writeback filtered result */ memcpy(buffer, musyx->subframe_740_last4, 4 * sizeof(int16_t)); memcpy(musyx->subframe_740_last4, subframe + SUBFRAME_SIZE - 4, 4 * sizeof(int16_t)); mix_fir4(musyx->e50, buffer + 1, fir4_hgain, fir4_hcoeffs); dram_store_u16(hle, (uint16_t *)musyx->e50, cbuffer_ptr + pos * 2, SUBFRAME_SIZE); } static void mix_sfx_with_main_subframes_v1(musyx_t *musyx, const int16_t *subframe, const uint16_t* UNUSED(gains)) { unsigned i; for (i = 0; i < SUBFRAME_SIZE; ++i) { int16_t v = subframe[i]; musyx->left[i] = clamp_s16(musyx->left[i] + v); musyx->right[i] = clamp_s16(musyx->right[i] + v); } } static void mix_sfx_with_main_subframes_v2(musyx_t *musyx, const int16_t *subframe, const uint16_t* gains) { unsigned i; for (i = 0; i < SUBFRAME_SIZE; ++i) { int16_t v = subframe[i]; int16_t v1 = (int32_t)(v * gains[0]) >> 16; int16_t v2 = (int32_t)(v * gains[1]) >> 16; musyx->left[i] = clamp_s16(musyx->left[i] + v1); musyx->right[i] = clamp_s16(musyx->right[i] + v1); musyx->cc0[i] = clamp_s16(musyx->cc0[i] + v2); } } #define mix_samples(y, x, hgain) (clamp_s16(*(y) + (((x) * (hgain) + 0x4000) >> 15))) static void mix_subframes(int16_t *y, const int16_t *x, int16_t hgain) { unsigned int i; for (i = 0; i < SUBFRAME_SIZE; ++i) y[i] = mix_samples(&y[i], x[i], hgain); } static void mix_fir4(int16_t *y, const int16_t *x, int16_t hgain, const int16_t *hcoeffs) { unsigned int i; int32_t h[4]; h[0] = (hgain * hcoeffs[0]) >> 15; h[1] = (hgain * hcoeffs[1]) >> 15; h[2] = (hgain * hcoeffs[2]) >> 15; h[3] = (hgain * hcoeffs[3]) >> 15; for (i = 0; i < SUBFRAME_SIZE; ++i) { int32_t v = (h[0] * x[i] + h[1] * x[i + 1] + h[2] * x[i + 2] + h[3] * x[i + 3]) >> 15; y[i] = clamp_s16(y[i] + v); } } static void interleave_stage_v1(struct hle_t* hle, musyx_t *musyx, uint32_t output_ptr) { size_t i; int16_t base_left = clamp_s16(musyx->base_vol[0]); int16_t base_right = clamp_s16(musyx->base_vol[1]); int16_t *left = musyx->left; int16_t *right = musyx->right; uint32_t *dst = dram_u32(hle, output_ptr); #ifndef NDEBUG HleVerboseMessage(hle->user_defined, "interleave: %08x", output_ptr); #endif for (i = 0; i < SUBFRAME_SIZE; ++i) { uint16_t l = clamp_s16(*(left++) + base_left); uint16_t r = clamp_s16(*(right++) + base_right); *(dst++) = (l << 16) | r; } } static void interleave_stage_v2(struct hle_t* hle, musyx_t *musyx, uint16_t mask_16, uint32_t ptr_18, uint32_t ptr_1c, uint32_t output_ptr) { unsigned i, k; int16_t subframe[SUBFRAME_SIZE]; uint32_t *dst; uint16_t mask; #ifndef NDEBUG HleVerboseMessage(hle->user_defined, "mask_16=%04x ptr_18=%08x ptr_1c=%08x output_ptr=%08x", mask_16, ptr_18, ptr_1c, output_ptr); #endif /* compute L_total, R_total and update subframe @ptr_1c */ memset(subframe, 0, SUBFRAME_SIZE*sizeof(subframe[0])); for(i = 0; i < SUBFRAME_SIZE; ++i) { int16_t v = *dram_u16(hle, ptr_1c + i*2); musyx->left[i] = v; musyx->right[i] = clamp_s16(-v); } for (k = 0, mask = 1; k < 8; ++k, mask <<= 1, ptr_18 += 8) { int16_t hgain; uint32_t address; if ((mask_16 & mask) == 0) continue; address = *dram_u32(hle, ptr_18); hgain = *dram_u16(hle, ptr_18 + 4); for(i = 0; i < SUBFRAME_SIZE; ++i, address += 2) { musyx->left[i] = mix_samples(&musyx->left[i], *dram_u16(hle, address), hgain); musyx->right[i] = mix_samples(&musyx->right[i], *dram_u16(hle, address + 2*SUBFRAME_SIZE), hgain); subframe[i] = mix_samples(&subframe[i], *dram_u16(hle, address + 4*SUBFRAME_SIZE), hgain); } } /* interleave L_total and R_total */ dst = dram_u32(hle, output_ptr); for(i = 0; i < SUBFRAME_SIZE; ++i) { uint16_t l = musyx->left[i]; uint16_t r = musyx->right[i]; *(dst++) = (l << 16) | r; } /* writeback subframe @ptr_1c */ dram_store_u16(hle, (uint16_t*)subframe, ptr_1c, SUBFRAME_SIZE); } mupen64plus-core/src/plugin/audio_libretro/audio_resampler_driver.c000664 001750 001750 00000011014 12655644434 027026 0ustar00sergiosergio000000 000000 /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2015 - Daniel De Matteis * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. * * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with RetroArch. * If not, see . */ #include "audio_resampler_driver.h" #include "api/libretro.h" #include /* strcasecmp not implemented in MSVC */ #include "api/msvc_compat.h" static const rarch_resampler_t *resampler_drivers[] = { &CC_resampler, &sinc_resampler, &nearest_resampler, NULL, }; /** * find_resampler_driver_index: * @ident : Identifier of resampler driver to find. * * Finds resampler driver index by @ident name. * * Returns: resampler driver index if resampler driver was found, otherwise * -1. **/ static int find_resampler_driver_index(const char *ident) { unsigned i; for (i = 0; resampler_drivers[i]; i++) if (strcasecmp(ident, resampler_drivers[i]->ident) == 0) return i; return -1; } /** * audio_resampler_driver_find_handle: * @idx : index of driver to get handle to. * * Returns: handle to audio resampler driver at index. Can be NULL * if nothing found. **/ const void *audio_resampler_driver_find_handle(int idx) { const void *drv = resampler_drivers[idx]; if (!drv) return NULL; return drv; } /** * audio_resampler_driver_find_ident: * @idx : index of driver to get handle to. * * Returns: Human-readable identifier of audio resampler driver at index. * Can be NULL if nothing found. **/ const char *audio_resampler_driver_find_ident(int idx) { const rarch_resampler_t *drv = resampler_drivers[idx]; if (!drv) return NULL; return drv->ident; } /** * find_resampler_driver: * @ident : Identifier of resampler driver to find. * * Finds resampler by @ident name. * * Returns: resampler driver if resampler driver was found, otherwise * NULL. **/ static const rarch_resampler_t *find_resampler_driver(const char *ident) { int i = find_resampler_driver_index(ident); if (i >= 0) return resampler_drivers[i]; return resampler_drivers[0]; } #ifndef RARCH_INTERNAL #ifdef __cplusplus extern "C" { #endif retro_get_cpu_features_t perf_get_cpu_features_cb; #ifdef __cplusplus } #endif #endif resampler_simd_mask_t resampler_get_cpu_features(void) { #ifdef RARCH_INTERNAL return rarch_get_cpu_features(); #else /* no features if interface isn't implemented */ return perf_get_cpu_features_cb ? perf_get_cpu_features_cb() : 0; #endif } /** * resampler_append_plugs: * @re : Resampler handle * @backend : Resampler backend that is about to be set. * @bw_ratio : Bandwidth ratio. * * Initializes resampler driver based on queried CPU features. * * Returns: true (1) if successfully initialized, otherwise false (0). **/ static bool resampler_append_plugs(void **re, const rarch_resampler_t **backend, double bw_ratio) { resampler_simd_mask_t mask = resampler_get_cpu_features(); *re = (*backend)->init(NULL, bw_ratio, mask); if (!*re) return false; return true; } /** * rarch_resampler_realloc: * @re : Resampler handle * @backend : Resampler backend that is about to be set. * @ident : Identifier name for resampler we want. * @bw_ratio : Bandwidth ratio. * * Reallocates resampler. Will free previous handle before * allocating a new one. If ident is NULL, first resampler will be used. * * Returns: true (1) if successful, otherwise false (0). **/ bool rarch_resampler_realloc(void **re, const rarch_resampler_t **backend, const char *ident, double bw_ratio) { if (*re && *backend) (*backend)->free(*re); *re = NULL; *backend = find_resampler_driver(ident); if (!resampler_append_plugs(re, backend, bw_ratio)) goto error; return true; error: if (!*re) *backend = NULL; return false; } glide2gl/src/Glide64/MiClWr.h000664 001750 001750 00000000501 12655644434 016677 0ustar00sergiosergio000000 000000 #ifndef _GLIDE64_MICLWR_H #define _GLIDE64_MICLWR_H void ClampTex(uint8_t *tex, uint32_t width, uint32_t clamp_to, uint32_t real_width, uint32_t real_height, uint32_t size); void MirrorTex (uint8_t *tex, uint32_t mask, uint32_t max_width, uint32_t real_width, uint32_t height, uint32_t size); #endif glide2gl/src/Glide64/MiClWr.c000664 001750 001750 00000015762 12655644434 016711 0ustar00sergiosergio000000 000000 /* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators // Project started on December 29th, 2001 // // Authors: // Dave2001, original author, founded the project in 2001, left it in 2002 // Gugaman, joined the project in 2002, left it in 2002 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 // //**************************************************************** // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // //**************************************************************** #include #include /* 8-bit Horizontal Mirror */ static void Mirror8bS (uint8_t *tex, uint32_t mask, uint32_t max_width, uint32_t real_width, uint32_t height) { uint32_t mask_width = (1 << mask); uint32_t mask_mask = (mask_width-1); int32_t count = max_width - mask_width; int32_t line_full = real_width; int32_t line = line_full - (count); uint8_t *start = (uint8_t*)(tex + (mask_width)); do { int v10 = 0; do { if ( mask_width & (v10 + mask_width) ) *start++ = *(&tex[mask_mask] - (mask_mask & v10)); else *start++ = tex[mask_mask & v10]; }while ( ++v10 != count ); start += line; tex += line_full; }while ( --height); } /* 8-bit Horizontal Clamp */ static void Clamp8bS (uint8_t *tex, uint32_t width, uint32_t clamp_to, uint32_t real_width, uint32_t real_height) { uint8_t *dest = tex + (width); uint8_t *constant = dest-1; int32_t count = clamp_to - width; int32_t line_full = real_width; int32_t line = width; do { unsigned i = count; do { *dest++ = *constant; }while(--i); constant += line_full; dest += line; }while (--real_height); } /* 16-bit Horizontal Mirror */ static void Mirror16bS (uint8_t *tex, uint32_t mask, uint32_t max_width, uint32_t real_width, uint32_t height) { uint32_t mask_width = (1 << mask); uint32_t mask_mask = (mask_width-1) << 1; int32_t count = max_width - mask_width; int32_t line_full = real_width << 1; int32_t line = line_full - (count << 1); uint16_t *v8 = (uint16_t *)(uint8_t*)(tex + (mask_width << 1)); do { int v10 = 0; do { if ( mask_width & (v10 + mask_width) ) *v8++ = *(uint16_t *)(&tex[mask_mask] - (mask_mask & 2 * v10)); else *v8++ = *(uint16_t *)&tex[mask_mask & 2 * v10]; }while ( ++v10 != count ); v8 = (uint16_t *)((int8_t*)v8 + line); tex += line_full; }while (--height); } /* 16-bit Horizontal Clamp */ static void Clamp16bS (uint8_t *tex, uint32_t width, uint32_t clamp_to, uint32_t real_width, uint32_t real_height) { uint8_t *dest = (uint8_t*)(tex + (width << 1)); uint8_t *constant = (uint8_t*)(dest-2); int32_t count = clamp_to - width; int32_t line_full = real_width << 1; int32_t line = width << 1; uint16_t *v6 = (uint16_t *)constant; uint16_t *v7 = (uint16_t *)dest; do { int v10 = count; do { *v7++ = *v6; }while (--v10 ); v6 = (uint16_t *)((int8_t*)v6 + line_full); v7 = (uint16_t *)((int8_t*)v7 + line); }while(--real_height); } static INLINE void clamp32bS(uint8_t *tex, uint8_t *constant, int height, int line, int full, int count) { uint32_t *v6 = (uint32_t *)constant; uint32_t *v7 = (uint32_t *)tex; do { int v10 = count; do { *v7++ = *v6; }while (--v10); v6 = (uint32_t *)((int8_t*)v6 + full); v7 = (uint32_t *)((int8_t*)v7 + line); }while (--height); } /* 32-bit Horizontal Mirror */ static void Mirror32bS (uint8_t *tex, uint32_t mask, uint32_t max_width, uint32_t real_width, uint32_t height) { uint32_t mask_width = (1 << mask); uint32_t mask_mask = (mask_width-1) << 2; int32_t count = max_width - mask_width; int32_t line_full = real_width << 2; int32_t line = line_full - (count << 2); uint8_t *start = (uint8_t*)(tex + (mask_width << 2)); uint32_t *v8 = (uint32_t *)start; do { int v10 = 0; do { if ( mask_width & (v10 + mask_width) ) *v8++ = *(uint32_t *)(&tex[mask_mask] - (mask_mask & 4 * v10)); else *v8++ = *(uint32_t *)&tex[mask_mask & 4 * v10]; }while (++v10 != count ); v8 = (uint32_t *)((int8_t*)v8 + line); tex += line_full; }while (--height); } void MirrorTex (uint8_t *tex, uint32_t mask, uint32_t max_width, uint32_t real_width, uint32_t height, uint32_t size) { if (size == 1) Mirror16bS (tex, mask, max_width, real_width, height); else if (size == 2) Mirror32bS (tex, mask, max_width, real_width, height); else Mirror8bS (tex, mask, max_width, real_width, height); } //**************************************************************** // 32-bit Horizontal Clamp static void Clamp32bS (uint8_t *tex, uint32_t width, uint32_t clamp_to, uint32_t real_width, uint32_t real_height) { uint8_t *dest = (uint8_t*)(tex + (width << 2)); uint8_t *constant = (uint8_t*)(dest-4); int32_t count = clamp_to - width; int32_t line_full = real_width << 2; int32_t line = width << 2; if (real_width > width) clamp32bS (dest, constant, real_height, line, line_full, count); } void ClampTex(uint8_t *tex, uint32_t width, uint32_t clamp_to, uint32_t real_width, uint32_t real_height, uint32_t size) { if (size == 1) Clamp16bS (tex, width, clamp_to, real_width, real_height); else if (size == 2) Clamp32bS (tex, width, clamp_to, real_width, real_height); else Clamp8bS (tex, width, clamp_to, real_width, real_height); } mupen64plus-video-gliden64/src/GLideNHQ/Ext_TxFilter.cpp000664 001750 001750 00000012006 12655644434 024045 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include "Ext_TxFilter.h" typedef boolean (*txfilter_init)(int maxwidth, int maxheight, int maxbpp, int options, int cachesize, const wchar_t *path, const wchar_t *ident, dispInfoFuncExt callback); typedef void (*txfilter_shutdown)(void); typedef boolean (*txfilter_filter)(unsigned char *src, int srcwidth, int srcheight, unsigned short srcformat, uint64 g64crc, GHQTexInfo *info); typedef boolean (*txfilter_hirestex)(uint64 g64crc, uint64 r_crc64, unsigned short *palette, GHQTexInfo *info); typedef uint64 (*txfilter_checksum)(unsigned char *src, int width, int height, int size, int rowStride, unsigned char *palette); typedef boolean (*txfilter_dmptx)(unsigned char *src, int width, int height, int rowStridePixel, unsigned short gfmt, unsigned short n64fmt, uint64 r_crc64); typedef boolean (*txfilter_reloadhirestex)(); static struct { TXHMODULE lib; txfilter_init init; txfilter_shutdown shutdown; txfilter_filter filter; txfilter_hirestex hirestex; txfilter_checksum checksum; txfilter_dmptx dmptx; txfilter_reloadhirestex reloadhirestex; } txfilter; void ext_ghq_shutdown(void) { if (txfilter.shutdown) (*txfilter.shutdown)(); if (txfilter.lib) { DLCLOSE(txfilter.lib); memset(&txfilter, 0, sizeof(txfilter)); } } boolean ext_ghq_init(int maxwidth, int maxheight, int maxbpp, int options, int cachesize, const wchar_t *path, const wchar_t *ident, dispInfoFuncExt callback) { boolean bRet = 0; if (!txfilter.lib) { wchar_t curpath[MAX_PATH]; wcscpy(curpath, path); #ifdef WIN32 #ifdef GHQCHK wcscat(curpath, wst("\\ghqchk.dll")); #else wcscat(curpath, wst("\\GlideHQ.dll")); #endif txfilter.lib = DLOPEN(curpath); #else char cbuf[MAX_PATH]; #ifdef GHQCHK wcscat(curpath, wst("/ghqchk.so")); #else wcscat(curpath, wst("/GlideHQ.so")); #endif wcstombs(cbuf, curpath, MAX_PATH); txfilter.lib = DLOPEN(cbuf); #endif } if (txfilter.lib) { if (!txfilter.init) txfilter.init = (txfilter_init)DLSYM(txfilter.lib, "txfilter_init"); if (!txfilter.shutdown) txfilter.shutdown = (txfilter_shutdown)DLSYM(txfilter.lib, "txfilter_shutdown"); if (!txfilter.filter) txfilter.filter = (txfilter_filter)DLSYM(txfilter.lib, "txfilter_filter"); if (!txfilter.hirestex) txfilter.hirestex = (txfilter_hirestex)DLSYM(txfilter.lib, "txfilter_hirestex"); if (!txfilter.checksum) txfilter.checksum = (txfilter_checksum)DLSYM(txfilter.lib, "txfilter_checksum"); if (!txfilter.dmptx) txfilter.dmptx = (txfilter_dmptx)DLSYM(txfilter.lib, "txfilter_dmptx"); if (!txfilter.reloadhirestex) txfilter.reloadhirestex = (txfilter_reloadhirestex)DLSYM(txfilter.lib, "txfilter_reloadhirestex"); } if (txfilter.init && txfilter.shutdown && txfilter.filter && txfilter.hirestex && txfilter.checksum /*&& txfilter.dmptx && txfilter.reloadhirestex */) bRet = (*txfilter.init)(maxwidth, maxheight, maxbpp, options, cachesize, path, ident, callback); else ext_ghq_shutdown(); return bRet; } boolean ext_ghq_txfilter(unsigned char *src, int srcwidth, int srcheight, unsigned short srcformat, uint64 g64crc, GHQTexInfo *info) { boolean ret = 0; if (txfilter.filter) ret = (*txfilter.filter)(src, srcwidth, srcheight, srcformat, g64crc, info); return ret; } boolean ext_ghq_hirestex(uint64 g64crc, uint64 r_crc64, unsigned short *palette, GHQTexInfo *info) { boolean ret = 0; if (txfilter.hirestex) ret = (*txfilter.hirestex)(g64crc, r_crc64, palette, info); return ret; } uint64 ext_ghq_checksum(unsigned char *src, int width, int height, int size, int rowStride, unsigned char *palette) { uint64 ret = 0; if (txfilter.checksum) ret = (*txfilter.checksum)(src, width, height, size, rowStride, palette); return ret; } boolean ext_ghq_dmptx(unsigned char *src, int width, int height, int rowStridePixel, unsigned short gfmt, unsigned short n64fmt, uint64 r_crc64) { boolean ret = 0; if (txfilter.dmptx) ret = (*txfilter.dmptx)(src, width, height, rowStridePixel, gfmt, n64fmt, r_crc64); return ret; } boolean ext_ghq_reloadhirestex() { boolean ret = 0; if (txfilter.reloadhirestex) ret = (*txfilter.reloadhirestex)(); return ret; } mupen64plus-core/src/r4300/fpu.h000664 001750 001750 00000034226 12655644434 017360 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - fpu.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2010 Ari64 * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_R4300_FPU_H #define M64P_R4300_FPU_H #include #include #include "r4300.h" #include "cp1_private.h" #ifdef _MSC_VER #define M64P_FPU_INLINE static __inline #include typedef enum { FE_TONEAREST = 0, FE_TOWARDZERO, FE_UPWARD, FE_DOWNWARD } eRoundType; static void fesetround(eRoundType RoundType) { static const unsigned int msRound[4] = { _RC_NEAR, _RC_CHOP, _RC_UP, _RC_DOWN }; unsigned int oldX87, oldSSE2; __control87_2(msRound[RoundType], _MCW_RC, &oldX87, &oldSSE2); } static __inline double round(double x) { return floor(x + 0.5); } static __inline float roundf(float x) { return (float) floor(x + 0.5); } static __inline double trunc(double x) { return (double) (int) x; } static __inline float truncf(float x) { return (float) (int) x; } #define isnan _isnan #else #define M64P_FPU_INLINE static inline #include #endif #define FCR31_CMP_BIT UINT32_C(0x800000) M64P_FPU_INLINE void set_rounding(void) { switch(FCR31 & 3) { case 0x33F: fesetround(FE_TONEAREST); break; case 0xF3F: fesetround(FE_TOWARDZERO); break; case 0xB3F: fesetround(FE_UPWARD); break; case 0x73F: fesetround(FE_DOWNWARD); break; } } M64P_FPU_INLINE void cvt_s_w(const int32_t *source,float *dest) { set_rounding(); *dest = (float) *source; } M64P_FPU_INLINE void cvt_d_w(const int32_t *source,double *dest) { *dest = (double) *source; } M64P_FPU_INLINE void cvt_s_l(const int64_t *source,float *dest) { set_rounding(); *dest = (float) *source; } M64P_FPU_INLINE void cvt_d_l(const int64_t *source,double *dest) { set_rounding(); *dest = (double) *source; } M64P_FPU_INLINE void cvt_d_s(const float *source,double *dest) { *dest = (double) *source; } M64P_FPU_INLINE void cvt_s_d(const double *source,float *dest) { set_rounding(); *dest = (float) *source; } M64P_FPU_INLINE void round_l_s(const float *source,int64_t *dest) { *dest = (int64_t) roundf(*source); } M64P_FPU_INLINE void round_w_s(const float *source,int32_t *dest) { *dest = (int32_t) roundf(*source); } M64P_FPU_INLINE void trunc_l_s(const float *source,int64_t *dest) { *dest = (int64_t) truncf(*source); } M64P_FPU_INLINE void trunc_w_s(const float *source,int32_t *dest) { *dest = (int32_t) truncf(*source); } M64P_FPU_INLINE void ceil_l_s(const float *source,int64_t *dest) { *dest = (int64_t) ceilf(*source); } M64P_FPU_INLINE void ceil_w_s(const float *source,int32_t *dest) { *dest = (int32_t) ceilf(*source); } M64P_FPU_INLINE void floor_l_s(const float *source,int64_t *dest) { *dest = (int64_t) floorf(*source); } M64P_FPU_INLINE void floor_w_s(const float *source,int32_t *dest) { *dest = (int32_t) floorf(*source); } M64P_FPU_INLINE void round_l_d(const double *source,int64_t *dest) { *dest = (int64_t) round(*source); } M64P_FPU_INLINE void round_w_d(const double *source,int32_t *dest) { *dest = (int32_t) round(*source); } M64P_FPU_INLINE void trunc_l_d(const double *source,int64_t *dest) { *dest = (int64_t) trunc(*source); } M64P_FPU_INLINE void trunc_w_d(const double *source,int32_t *dest) { *dest = (int32_t) trunc(*source); } M64P_FPU_INLINE void ceil_l_d(const double *source,int64_t *dest) { *dest = (int64_t) ceil(*source); } M64P_FPU_INLINE void ceil_w_d(const double *source,int32_t *dest) { *dest = (int32_t) ceil(*source); } M64P_FPU_INLINE void floor_l_d(const double *source,int64_t *dest) { *dest = (int64_t) floor(*source); } M64P_FPU_INLINE void floor_w_d(const double *source,int32_t *dest) { *dest = (int32_t) floor(*source); } M64P_FPU_INLINE void cvt_w_s(const float *source,int32_t *dest) { switch(FCR31&3) { case 0: round_w_s(source,dest);return; case 1: trunc_w_s(source,dest);return; case 2: ceil_w_s(source,dest);return; case 3: floor_w_s(source,dest);return; } } M64P_FPU_INLINE void cvt_w_d(const double *source,int32_t *dest) { switch(FCR31&3) { case 0: round_w_d(source,dest);return; case 1: trunc_w_d(source,dest);return; case 2: ceil_w_d(source,dest);return; case 3: floor_w_d(source,dest);return; } } M64P_FPU_INLINE void cvt_l_s(const float *source,int64_t *dest) { switch(FCR31&3) { case 0: round_l_s(source,dest);return; case 1: trunc_l_s(source,dest);return; case 2: ceil_l_s(source,dest);return; case 3: floor_l_s(source,dest);return; } } M64P_FPU_INLINE void cvt_l_d(const double *source,int64_t *dest) { switch(FCR31&3) { case 0: round_l_d(source,dest);return; case 1: trunc_l_d(source,dest);return; case 2: ceil_l_d(source,dest);return; case 3: floor_l_d(source,dest);return; } } M64P_FPU_INLINE void c_f_s() { FCR31 &= ~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_un_s(const float *source,const float *target) { FCR31=(isnan(*source) || isnan(*target)) ? FCR31|FCR31_CMP_BIT : FCR31&~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_eq_s(const float *source,const float *target) { if (isnan(*source) || isnan(*target)) {FCR31&=~FCR31_CMP_BIT;return;} FCR31 = *source==*target ? FCR31|FCR31_CMP_BIT : FCR31&~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_ueq_s(const float *source,const float *target) { if (isnan(*source) || isnan(*target)) {FCR31|=FCR31_CMP_BIT;return;} FCR31 = *source==*target ? FCR31|FCR31_CMP_BIT : FCR31&~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_olt_s(const float *source,const float *target) { if (isnan(*source) || isnan(*target)) {FCR31&=~FCR31_CMP_BIT;return;} FCR31 = *source<*target ? FCR31|FCR31_CMP_BIT : FCR31&~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_ult_s(const float *source,const float *target) { if (isnan(*source) || isnan(*target)) {FCR31|=FCR31_CMP_BIT;return;} FCR31 = *source<*target ? FCR31|FCR31_CMP_BIT : FCR31&~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_ole_s(const float *source,const float *target) { if (isnan(*source) || isnan(*target)) {FCR31&=~FCR31_CMP_BIT;return;} FCR31 = *source<=*target ? FCR31|FCR31_CMP_BIT : FCR31&~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_ule_s(const float *source,const float *target) { if (isnan(*source) || isnan(*target)) {FCR31|=FCR31_CMP_BIT;return;} FCR31 = *source<=*target ? FCR31|FCR31_CMP_BIT : FCR31&~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_sf_s(const float *source,const float *target) { //if (isnan(*source) || isnan(*target)) // FIXME - exception FCR31&=~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_ngle_s(const float *source,const float *target) { //if (isnan(*source) || isnan(*target)) // FIXME - exception FCR31&=~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_seq_s(const float *source,const float *target) { //if (isnan(*source) || isnan(*target)) // FIXME - exception FCR31 = *source==*target ? FCR31|FCR31_CMP_BIT : FCR31&~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_ngl_s(const float *source,const float *target) { //if (isnan(*source) || isnan(*target)) // FIXME - exception FCR31 = *source==*target ? FCR31|FCR31_CMP_BIT : FCR31&~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_lt_s(const float *source,const float *target) { //if (isnan(*source) || isnan(*target)) // FIXME - exception FCR31 = *source<*target ? FCR31|FCR31_CMP_BIT : FCR31&~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_nge_s(const float *source,const float *target) { //if (isnan(*source) || isnan(*target)) // FIXME - exception FCR31 = *source<*target ? FCR31|FCR31_CMP_BIT : FCR31&~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_le_s(const float *source,const float *target) { //if (isnan(*source) || isnan(*target)) // FIXME - exception FCR31 = *source<=*target ? FCR31|FCR31_CMP_BIT : FCR31&~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_ngt_s(const float *source,const float *target) { //if (isnan(*source) || isnan(*target)) // FIXME - exception FCR31 = *source<=*target ? FCR31|FCR31_CMP_BIT : FCR31&~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_f_d() { FCR31 &= ~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_un_d(const double *source,const double *target) { FCR31=(isnan(*source) || isnan(*target)) ? FCR31|FCR31_CMP_BIT : FCR31&~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_eq_d(const double *source,const double *target) { if (isnan(*source) || isnan(*target)) {FCR31&=~FCR31_CMP_BIT;return;} FCR31 = *source==*target ? FCR31|FCR31_CMP_BIT : FCR31&~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_ueq_d(const double *source,const double *target) { if (isnan(*source) || isnan(*target)) {FCR31|=FCR31_CMP_BIT;return;} FCR31 = *source==*target ? FCR31|FCR31_CMP_BIT : FCR31&~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_olt_d(const double *source,const double *target) { if (isnan(*source) || isnan(*target)) {FCR31&=~FCR31_CMP_BIT;return;} FCR31 = *source<*target ? FCR31|FCR31_CMP_BIT : FCR31&~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_ult_d(const double *source,const double *target) { if (isnan(*source) || isnan(*target)) {FCR31|=FCR31_CMP_BIT;return;} FCR31 = *source<*target ? FCR31|FCR31_CMP_BIT : FCR31&~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_ole_d(const double *source,const double *target) { if (isnan(*source) || isnan(*target)) {FCR31&=~FCR31_CMP_BIT;return;} FCR31 = *source<=*target ? FCR31|FCR31_CMP_BIT : FCR31&~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_ule_d(const double *source,const double *target) { if (isnan(*source) || isnan(*target)) {FCR31|=FCR31_CMP_BIT;return;} FCR31 = *source<=*target ? FCR31|FCR31_CMP_BIT : FCR31&~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_sf_d(const double *source,const double *target) { //if (isnan(*source) || isnan(*target)) // FIXME - exception FCR31&=~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_ngle_d(const double *source,const double *target) { //if (isnan(*source) || isnan(*target)) // FIXME - exception FCR31&=~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_seq_d(const double *source,const double *target) { //if (isnan(*source) || isnan(*target)) // FIXME - exception FCR31 = *source==*target ? FCR31|FCR31_CMP_BIT : FCR31&~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_ngl_d(const double *source,const double *target) { //if (isnan(*source) || isnan(*target)) // FIXME - exception FCR31 = *source==*target ? FCR31|FCR31_CMP_BIT : FCR31&~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_lt_d(const double *source,const double *target) { //if (isnan(*source) || isnan(*target)) // FIXME - exception FCR31 = *source<*target ? FCR31|FCR31_CMP_BIT : FCR31&~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_nge_d(const double *source,const double *target) { //if (isnan(*source) || isnan(*target)) // FIXME - exception FCR31 = *source<*target ? FCR31|FCR31_CMP_BIT : FCR31&~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_le_d(const double *source,const double *target) { //if (isnan(*source) || isnan(*target)) // FIXME - exception FCR31 = *source<=*target ? FCR31|FCR31_CMP_BIT : FCR31&~FCR31_CMP_BIT; } M64P_FPU_INLINE void c_ngt_d(const double *source,const double *target) { //if (isnan(*source) || isnan(*target)) // FIXME - exception FCR31 = *source<=*target ? FCR31|FCR31_CMP_BIT : FCR31&~FCR31_CMP_BIT; } M64P_FPU_INLINE void add_s(const float *source1,const float *source2,float *target) { set_rounding(); *target=(*source1)+(*source2); } M64P_FPU_INLINE void sub_s(const float *source1,const float *source2,float *target) { set_rounding(); *target=(*source1)-(*source2); } M64P_FPU_INLINE void mul_s(const float *source1,const float *source2,float *target) { set_rounding(); *target=(*source1)*(*source2); } M64P_FPU_INLINE void div_s(const float *source1,const float *source2,float *target) { set_rounding(); *target=(*source1)/(*source2); } M64P_FPU_INLINE void sqrt_s(const float *source,float *target) { set_rounding(); *target=sqrtf(*source); } M64P_FPU_INLINE void abs_s(const float *source,float *target) { *target=fabsf(*source); } M64P_FPU_INLINE void mov_s(const float *source,float *target) { *target=*source; } M64P_FPU_INLINE void neg_s(const float *source,float *target) { *target=-(*source); } M64P_FPU_INLINE void add_d(const double *source1,const double *source2,double *target) { set_rounding(); *target=(*source1)+(*source2); } M64P_FPU_INLINE void sub_d(const double *source1,const double *source2,double *target) { set_rounding(); *target=(*source1)-(*source2); } M64P_FPU_INLINE void mul_d(const double *source1,const double *source2,double *target) { set_rounding(); *target=(*source1)*(*source2); } M64P_FPU_INLINE void div_d(const double *source1,const double *source2,double *target) { set_rounding(); *target=(*source1)/(*source2); } M64P_FPU_INLINE void sqrt_d(const double *source,double *target) { set_rounding(); *target=sqrt(*source); } M64P_FPU_INLINE void abs_d(const double *source,double *target) { *target=fabs(*source); } M64P_FPU_INLINE void mov_d(const double *source,double *target) { *target=*source; } M64P_FPU_INLINE void neg_d(const double *source,double *target) { *target=-(*source); } #endif /* M64P_R4300_FPU_H */ gles2rice/src/RSP_GBI1.h000664 001750 001750 00000030524 12655644434 015750 0ustar00sergiosergio000000 000000 /* Copyright (C) 2002 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "Render.h" #include "Timing.h" void RSP_GBI1_Vtx(Gfx *gfx) { uint32_t addr = RSPSegmentAddr((gfx->gbi1vtx.addr)); uint32_t v0 = gfx->gbi1vtx.v0; uint32_t n = gfx->gbi1vtx.n; LOG_UCODE(" Address 0x%08x, v0: %d, Num: %d, Length: 0x%04x", addr, v0, n, gfx->gbi1vtx.len); if (addr > g_dwRamSize) { TRACE0(" Address out of range - ignoring load"); return; } if ((v0 + n) > 80) { TRACE5("Warning, invalid vertex positions, N=%d, v0=%d, Addr=0x%08X, Cmd=%08X-%08X", n, v0, addr, gfx->words.w0, gfx->words.w1); return; } ProcessVertexData(addr, v0, n); status.dwNumVertices += n; DisplayVertexInfo(addr, v0, n); } void RSP_GBI1_ModifyVtx(Gfx *gfx) { SP_Timing(RSP_GBI1_ModifyVtx); if( gRSP.ucode == 5 && ((gfx->words.w0)&0x00FFFFFF) == 0 && ((gfx->words.w1)&0xFF000000) == 0x80000000 ) { DLParser_Bomberman2TextRect(gfx); } else { uint32_t dwWhere = ((gfx->words.w0) >> 16) & 0xFF; uint32_t dwVert = (((gfx->words.w0) ) & 0xFFFF) / 2; uint32_t dwValue = (gfx->words.w1); if( dwVert > 80 ) { RSP_RDP_NOIMPL("RSP_GBI1_ModifyVtx: Invalid vertex number: %d", dwVert, 0); return; } // Data for other commands? switch (dwWhere) { case RSP_MV_WORD_OFFSET_POINT_RGBA: // Modify RGBA case RSP_MV_WORD_OFFSET_POINT_XYSCREEN: // Modify X,Y case RSP_MV_WORD_OFFSET_POINT_ZSCREEN: // Modify C case RSP_MV_WORD_OFFSET_POINT_ST: // Texture ModifyVertexInfo(dwWhere, dwVert, dwValue); break; default: RSP_RDP_NOIMPL("RSP_GBI1_ModifyVtx: Setting unk value: 0x%02x, 0x%08x", dwWhere, dwValue); break; } } } void RSP_GBI1_Tri2(Gfx *gfx) { status.primitiveType = PRIM_TRI2; bool bTrisAdded = false; bool bTexturesAreEnabled = CRender::g_pRender->IsTextureEnabled(); // While the next command pair is Tri2, add vertices uint32_t dwPC = gDlistStack[gDlistStackPointer].pc; do { // Vertex indices are multiplied by 10 for Mario64, by 2 for MarioKart uint32_t dwV0 = gfx->gbi1tri2.v0/gRSP.vertexMult; uint32_t dwV1 = gfx->gbi1tri2.v1/gRSP.vertexMult; uint32_t dwV2 = gfx->gbi1tri2.v2/gRSP.vertexMult; uint32_t dwV3 = gfx->gbi1tri2.v3/gRSP.vertexMult; uint32_t dwV4 = gfx->gbi1tri2.v4/gRSP.vertexMult; uint32_t dwV5 = gfx->gbi1tri2.v5/gRSP.vertexMult; // Do first tri if (IsTriangleVisible(dwV0, dwV1, dwV2)) { DEBUG_DUMP_VERTEXES("Tri2 1/2", dwV0, dwV1, dwV2); if (!bTrisAdded) { if( bTexturesAreEnabled ) { PrepareTextures(); InitVertexTextureConstants(); } CRender::g_pRender->SetCombinerAndBlender(); bTrisAdded = true; } PrepareTriangle(dwV0, dwV1, dwV2); } // Do second tri if (IsTriangleVisible(dwV3, dwV4, dwV5)) { DEBUG_DUMP_VERTEXES("Tri2 2/2", dwV3, dwV4, dwV5); if (!bTrisAdded) { if( bTexturesAreEnabled ) { PrepareTextures(); InitVertexTextureConstants(); } CRender::g_pRender->SetCombinerAndBlender(); bTrisAdded = true; } PrepareTriangle(dwV3, dwV4, dwV5); } gfx++; dwPC += 8; #ifdef DEBUGGER } while (!(pauseAtNext && eventToPause==NEXT_TRIANGLE) && gfx->words.cmd == (uint8_t)RSP_TRI2); #else } while( gfx->words.cmd == (uint8_t)RSP_TRI2); #endif gDlistStack[gDlistStackPointer].pc = dwPC-8; if (bTrisAdded) { CRender::g_pRender->DrawTriangles(); } DEBUG_TRIANGLE(TRACE0("Pause at GBI1 TRI1")); } extern XVECTOR4 g_vtxNonTransformed[MAX_VERTS]; void RSP_GBI1_BranchZ(Gfx *gfx) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; SP_Timing(RSP_GBI1_BranchZ); uint32_t vtx = ((gfx->words.w0)&0xFFF)>>1; float vtxdepth = g_vecProjected[vtx].z/g_vecProjected[vtx].w; #ifdef DEBUGGER if( debuggerEnableZBuffer==FALSE || vtxdepth <= (int32_t)gfx->words.w1 || g_curRomInfo.bForceDepthBuffer ) #else if( vtxdepth <= (int32_t)(gfx->words.w1) || g_curRomInfo.bForceDepthBuffer ) #endif { uint32_t dwPC = gDlistStack[gDlistStackPointer].pc; // This points to the next instruction uint32_t dwDL = *(uint32_t *)(rdram_u8 + dwPC-12); uint32_t dwAddr = RSPSegmentAddr(dwDL); LOG_UCODE("BranchZ to DisplayList 0x%08x", dwAddr); gDlistStack[gDlistStackPointer].pc = dwAddr; gDlistStack[gDlistStackPointer].countdown = MAX_DL_COUNT; } } #ifdef DEBUGGER void DumpUcodeInfo(UcodeInfo &info) { DebuggerAppendMsg("Loading Unknown Ucode:\n%08X-%08X-%08X-%08X, Size=0x%X, CRC=0x%08X\nCode:\n", info.ucDWORD1, info.ucDWORD2, info.ucDWORD3, info.ucDWORD4, info.ucSize, info.ucCRC); DumpHex(info.ucStart,20); TRACE0("Data:\n"); DumpHex(info.ucDStart,20); } #endif void RSP_GBI1_LoadUCode(Gfx *gfx) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; SP_Timing(RSP_GBI1_LoadUCode); //TRACE0("Load ucode"); uint32_t dwPC = gDlistStack[gDlistStackPointer].pc; uint32_t dwUcStart = RSPSegmentAddr((gfx->words.w1)); uint32_t dwSize = ((gfx->words.w0)&0xFFFF)+1; uint32_t dwUcDStart = RSPSegmentAddr(*(uint32_t *)(rdram_u8 + dwPC-12)); uint32_t ucode = DLParser_CheckUcode(dwUcStart, dwUcDStart, dwSize, 8); RSP_SetUcode(ucode, dwUcStart, dwUcDStart, dwSize); DEBUGGER_PAUSE_AND_DUMP(NEXT_SWITCH_UCODE,{DebuggerAppendMsg("Pause at loading ucode");}); } void RSP_GFX_Force_Matrix(uint32_t dwAddr) { if (dwAddr + 64 > g_dwRamSize) { DebuggerAppendMsg("ForceMtx: Address invalid (0x%08x)", dwAddr); return; } // Load matrix from dwAddr LoadMatrix(dwAddr); CRender::g_pRender->SetWorldProjectMatrix(matToLoad); DEBUGGER_PAUSE_AND_DUMP(NEXT_MATRIX_CMD,{TRACE0("Paused at ModMatrix Cmd");}); } void DisplayVertexInfo(uint32_t dwAddr, uint32_t dwV0, uint32_t dwN) { #ifdef DEBUGGER uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; int8_t *pcSrc = (int8_t *)(rdram_u8 + dwAddr); short *psSrc = (short *)(rdram_u8 + dwAddr); for (uint32_t dwV = dwV0; dwV < dwV0 + dwN; dwV++) { float x = (float)psSrc[0^0x1]; float y = (float)psSrc[1^0x1]; float z = (float)psSrc[2^0x1]; //uint32_t wFlags = g_dwVtxFlags[dwV]; //(uint16_t)psSrc[3^0x1]; uint32_t wFlags = 0; uint8_t a = pcSrc[12^0x3]; uint8_t b = pcSrc[13^0x3]; uint8_t c = pcSrc[14^0x3]; uint8_t d = pcSrc[15^0x3]; //int nTU = (int)(short)(psSrc[4^0x1]<<4); //int nTV = (int)(short)(psSrc[5^0x1]<<4); //float tu = (float)(nTU>>4); //float tv = (float)(nTV>>4); float tu = (float)(short)(psSrc[4^0x1]); float tv = (float)(short)(psSrc[5^0x1]); XVECTOR4 & t = g_vecProjected[dwV]; psSrc += 8; // Increase by 16 bytes pcSrc += 16; LOG_UCODE(" #%02d Flags: 0x%04x Pos: {% 6f,% 6f,% 6f} Tex: {%+7.2f,%+7.2f}, Extra: %02x %02x %02x %02x (transf: {% 6f,% 6f,% 6f})", dwV, wFlags, x, y, z, tu, tv, a, b, c, d, t.x, t.y, t.z ); } #endif } void RSP_MoveMemLight(uint32_t dwLight, uint32_t dwAddr) { if( dwLight >= 16 ) { DebuggerAppendMsg("Warning: invalid light # = %d", dwLight); return; } int8_t *rdram_s8 = (int8_t*)gfx_info.RDRAM; int8_t * pcBase = rdram_s8 + dwAddr; uint32_t * pdwBase = (uint32_t *)pcBase; float range = 0, x, y, z; if( options.enableHackForGames == HACK_FOR_ZELDA_MM && (pdwBase[0]&0xFF) == 0x08 && (pdwBase[1]&0xFF) == 0xFF ) { gRSPn64lights[dwLight].dwRGBA = pdwBase[0]; gRSPn64lights[dwLight].dwRGBACopy = pdwBase[1]; short* pdwBase16 = (short*)pcBase; x = pdwBase16[5]; y = pdwBase16[4]; z = pdwBase16[7]; range = pdwBase16[6]; } else { gRSPn64lights[dwLight].dwRGBA = pdwBase[0]; gRSPn64lights[dwLight].dwRGBACopy = pdwBase[1]; x = pcBase[8 ^ 0x3]; y = pcBase[9 ^ 0x3]; z = pcBase[10 ^ 0x3]; } LOG_UCODE(" RGBA: 0x%08x, RGBACopy: 0x%08x, x: %d, y: %d, z: %d", gRSPn64lights[dwLight].dwRGBA, gRSPn64lights[dwLight].dwRGBACopy, x, y, z); LIGHT_DUMP(TRACE3("Move Light: %08X, %08X, %08X", pdwBase[0], pdwBase[1], pdwBase[2])); if (dwLight == gRSP.ambientLightIndex) { LOG_UCODE(" (Ambient Light)"); uint32_t dwCol = COLOR_RGBA( (gRSPn64lights[dwLight].dwRGBA >> 24)&0xFF, (gRSPn64lights[dwLight].dwRGBA >> 16)&0xFF, (gRSPn64lights[dwLight].dwRGBA >> 8)&0xFF, 0xff); SetAmbientLight( dwCol ); } else { LOG_UCODE(" (Normal Light)"); SetLightCol(dwLight, gRSPn64lights[dwLight].dwRGBA); if (pdwBase[2] == 0) // Direction is 0! { LOG_UCODE(" Light is invalid"); } SetLightDirection(dwLight, x, y, z, range); } } void RSP_MoveMemViewport(uint32_t dwAddr) { uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; if( dwAddr+16 >= g_dwRamSize ) { TRACE0("MoveMem Viewport, invalid memory"); return; } short scale[4]; short trans[4]; // dwAddr is offset into RD_RAM of 8 x 16bits of data... scale[0] = *(short *)(rdram_u8 + ((dwAddr+(0*2))^0x2)); scale[1] = *(short *)(rdram_u8 + ((dwAddr+(1*2))^0x2)); scale[2] = *(short *)(rdram_u8 + ((dwAddr+(2*2))^0x2)); scale[3] = *(short *)(rdram_u8 + ((dwAddr+(3*2))^0x2)); trans[0] = *(short *)(rdram_u8 + ((dwAddr+(4*2))^0x2)); trans[1] = *(short *)(rdram_u8 + ((dwAddr+(5*2))^0x2)); trans[2] = *(short *)(rdram_u8 + ((dwAddr+(6*2))^0x2)); trans[3] = *(short *)(rdram_u8 + ((dwAddr+(7*2))^0x2)); int nCenterX = trans[0]/4; int nCenterY = trans[1]/4; int nWidth = scale[0]/4; int nHeight = scale[1]/4; // Check for some strange games if( nWidth < 0 ) nWidth = -nWidth; if( nHeight < 0 ) nHeight = -nHeight; int nLeft = nCenterX - nWidth; int nTop = nCenterY - nHeight; int nRight= nCenterX + nWidth; int nBottom= nCenterY + nHeight; //int maxZ = scale[2]; int maxZ = 0x3FF; CRender::g_pRender->SetViewport(nLeft, nTop, nRight, nBottom, maxZ); LOG_UCODE(" Scale: %d %d %d %d = %d,%d", scale[0], scale[1], scale[2], scale[3], nWidth, nHeight); LOG_UCODE(" Trans: %d %d %d %d = %d,%d", trans[0], trans[1], trans[2], trans[3], nCenterX, nCenterY); } // S2DEX uses this - 0xc1 void RSP_S2DEX_SPObjLoadTxtr_Ucode1(Gfx *gfx) { SP_Timing(RSP_S2DEX_SPObjLoadTxtr_Ucode1); // Add S2DEX ucode supporting to F3DEX, see game DT and others status.bUseModifiedUcodeMap = true; RSP_SetUcode(1, 0, 0, 0); memcpy( &LoadedUcodeMap, &ucodeMap1, sizeof(UcodeMap)); LoadedUcodeMap[S2DEX_OBJ_MOVEMEM] = &RSP_S2DEX_OBJ_MOVEMEM; LoadedUcodeMap[S2DEX_OBJ_LOADTXTR] = &RSP_S2DEX_SPObjLoadTxtr; LoadedUcodeMap[S2DEX_OBJ_LDTX_SPRITE] = &RSP_S2DEX_SPObjLoadTxSprite; LoadedUcodeMap[S2DEX_OBJ_LDTX_RECT] = &RSP_S2DEX_SPObjLoadTxRect; LoadedUcodeMap[S2DEX_OBJ_LDTX_RECT_R] = &RSP_S2DEX_SPObjLoadTxRectR; RSP_S2DEX_SPObjLoadTxtr(gfx); } mupen64plus-video-gliden64/src/GLideNHQ/TxDbg.cpp000664 001750 001750 00000004001 12655644434 022470 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #define DBG_LEVEL 80 #include "TxDbg.h" #include #include #ifdef ANDROID #include #include TxDbg::TxDbg() { _level = DBG_LEVEL; } TxDbg::~TxDbg() {} void TxDbg::output(const int level, const wchar_t *format, ...) { if (level > _level) return; char fmt[2048]; wcstombs(fmt, format, 2048); va_list ap; va_start(ap, format); __android_log_vprint(ANDROID_LOG_DEBUG, "GLideN64", fmt, ap); va_end(ap); } #else // ANDROID TxDbg::TxDbg() { _level = DBG_LEVEL; if (!_dbgfile) #ifdef GHQCHK _dbgfile = fopen("ghqchk.txt", "w"); #else _dbgfile = fopen("glidenhq.dbg", "w"); #endif } TxDbg::~TxDbg() { if (_dbgfile) { fclose(_dbgfile); _dbgfile = 0; } _level = DBG_LEVEL; } void TxDbg::output(const int level, const wchar_t *format, ...) { if (level > _level) return; va_list args; wchar_t newformat[4095]; va_start(args, format); tx_swprintf(newformat, 4095, wst("%d:\t"), level); wcscat(newformat, format); vfwprintf(_dbgfile, newformat, args); fflush(_dbgfile); #ifdef GHQCHK //vwprintf(newformat, args); vwprintf(newformat.c_str(), args); #endif va_end(args); } #endif // ANDROID mupen64plus-core/src/debugger/debugger.h000664 001750 001750 00000004142 12655644434 021360 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - debugger.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2008 DarkJeztr * * Copyright (C) 2002 davFr * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef __DEBUGGER_H__ #define __DEBUGGER_H__ extern int g_DebuggerActive; /* True if the debugger is running */ /* State of the Emulation Thread: 0 -> pause, 1 -> step, 2 -> run. */ extern int run; extern uint32 previousPC; #ifndef __LIBRETRO__ //No debugger void init_debugger(void); void update_debugger(uint32 pc); void destroy_debugger(void); void debugger_step(void); #else #define init_debugger() #define update_debugger(a) #define destroy_debugger() #define debugger_step() #endif #endif /* __DEBUGGER_H__ */ mupen64plus-video-gliden64/src/GLideNHQ/TxHiResCache.cpp000664 001750 001750 00000054310 12655644434 023742 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* 2007 Gonetz * Added callback to display hires texture info. */ #ifdef __MSC__ #pragma warning(disable: 4786) #endif /* dump processed hirestextures to disk * (0:disable, 1:enable) */ #define DUMP_CACHE 1 /* use power of 2 texture size * (0:disable, 1:enable, 2:3dfx) */ #define POW2_TEXTURES 0 /* hack to reduce texture footprint to achieve * better performace on midrange gfx cards. * (0:disable, 1:enable) */ #define REDUCE_TEXTURE_FOOTPRINT 0 /* use aggressive format assumption for quantization * (0:disable, 1:enable, 2:extreme) */ #define AGGRESSIVE_QUANTIZATION 1 #include "TxHiResCache.h" #include "TxDbg.h" #include #include #include #include #include TxHiResCache::~TxHiResCache() { #if DUMP_CACHE if ((_options & DUMP_HIRESTEXCACHE) && !_haveCache && !_abortLoad) { /* dump cache to disk */ tx_wstring filename = _ident + wst("_HIRESTEXTURES.") + TEXCACHE_EXT; tx_wstring cachepath(_path); cachepath += OSAL_DIR_SEPARATOR_STR; cachepath += wst("cache"); int config = _options & (HIRESTEXTURES_MASK|TILE_HIRESTEX|FORCE16BPP_HIRESTEX|GZ_HIRESTEXCACHE|LET_TEXARTISTS_FLY); TxCache::save(cachepath.c_str(), filename.c_str(), config); } #endif delete _txImage; delete _txQuantize; delete _txReSample; } TxHiResCache::TxHiResCache(int maxwidth, int maxheight, int maxbpp, int options, const wchar_t *cachePath, const wchar_t *texPackPath, const wchar_t *ident, dispInfoFuncExt callback ) : TxCache((options & ~GZ_TEXCACHE), 0, cachePath, ident, callback) { _txImage = new TxImage(); _txQuantize = new TxQuantize(); _txReSample = new TxReSample(); _maxwidth = maxwidth; _maxheight = maxheight; _maxbpp = maxbpp; _abortLoad = 0; _haveCache = 0; if (texPackPath) _texPackPath.assign(texPackPath); if (_path.empty() || _ident.empty()) { _options &= ~DUMP_HIRESTEXCACHE; return; } #if DUMP_CACHE /* read in hires texture cache */ if (_options & DUMP_HIRESTEXCACHE) { /* find it on disk */ tx_wstring filename = _ident + wst("_HIRESTEXTURES.") + TEXCACHE_EXT; tx_wstring cachepath(_path); cachepath += OSAL_DIR_SEPARATOR_STR; cachepath += wst("cache"); int config = _options & (HIRESTEXTURES_MASK|TILE_HIRESTEX|FORCE16BPP_HIRESTEX|GZ_HIRESTEXCACHE|LET_TEXARTISTS_FLY); _haveCache = TxCache::load(cachepath.c_str(), filename.c_str(), config); } #endif /* read in hires textures */ if (!_haveCache) TxHiResCache::load(0); } boolean TxHiResCache::empty() { return _cache.empty(); } boolean TxHiResCache::load(boolean replace) /* 0 : reload, 1 : replace partial */ { if (!_texPackPath.empty() && !_ident.empty()) { if (!replace) TxCache::clear(); tx_wstring dir_path(_texPackPath); switch (_options & HIRESTEXTURES_MASK) { case GHQ_HIRESTEXTURES: break; case RICE_HIRESTEXTURES: INFO(80, wst("-----\n")); INFO(80, wst("using Rice hires texture format...\n")); INFO(80, wst(" must be one of the following;\n")); INFO(80, wst(" 1) *_rgb.png + *_a.png\n")); INFO(80, wst(" 2) *_all.png\n")); INFO(80, wst(" 3) *_ciByRGBA.png\n")); INFO(80, wst(" 4) *_allciByRGBA.png\n")); INFO(80, wst(" 5) *_ci.bmp\n")); INFO(80, wst(" usage of only 2) and 3) highly recommended!\n")); INFO(80, wst(" folder names must be in US-ASCII characters!\n")); dir_path += OSAL_DIR_SEPARATOR_STR; dir_path += _ident; loadHiResTextures(dir_path.c_str(), replace); break; case JABO_HIRESTEXTURES: ; } return 1; } return 0; } boolean TxHiResCache::loadHiResTextures(const wchar_t * dir_path, boolean replace) { DBG_INFO(80, wst("-----\n")); DBG_INFO(80, wst("path: %ls\n"), dir_path); /* find it on disk */ if (!osal_path_existsW(dir_path)) { INFO(80, wst("Error: path not found!\n")); return 0; } /* XXX: deal with UNICODE fiasco! * stupidity flows forth beneath this... * * I opted to use chdir in order to use fopen() for windows 9x. */ #ifdef WIN32 wchar_t curpath[MAX_PATH]; GETCWD(MAX_PATH, curpath); CHDIR(dir_path); #else char curpath[MAX_PATH]; char cbuf[MAX_PATH]; wcstombs(cbuf, dir_path, MAX_PATH); GETCWD(MAX_PATH, curpath); CHDIR(cbuf); #endif void *dir = osal_search_dir_open(dir_path); const wchar_t *foundfilename; // the path of the texture tx_wstring texturefilename; do { if (KBHIT(0x1B)) { _abortLoad = 1; if (_callback) (*_callback)(wst("Aborted loading hiresolution texture!\n")); INFO(80, wst("Error: aborted loading hiresolution texture!\n")); } if (_abortLoad) break; foundfilename = osal_search_dir_read_next(dir); // The array is empty, break the current operation if (foundfilename == NULL) break; // The current file is a hidden one if (wccmp(foundfilename, wst("."))) // These files we don't need continue; texturefilename.assign(dir_path); texturefilename += OSAL_DIR_SEPARATOR_STR; texturefilename += foundfilename; /* recursive read into sub-directory */ if (osal_is_directory(texturefilename.c_str())) { loadHiResTextures(texturefilename.c_str(), replace); continue; } DBG_INFO(80, wst("-----\n")); DBG_INFO(80, wst("file: %ls\n"), foundfilename); int width = 0, height = 0; uint16 format = 0; uint8 *tex = NULL; int tmpwidth = 0, tmpheight = 0; uint16 tmpformat = 0; uint8 *tmptex= NULL; uint16 destformat = 0; /* Rice hi-res textures: begin */ uint32 chksum = 0, fmt = 0, siz = 0, palchksum = 0; char *pfname = NULL, fname[MAX_PATH]; std::string ident; FILE *fp = NULL; wcstombs(fname, _ident.c_str(), MAX_PATH); /* XXX case sensitivity fiasco! * files must use _a, _rgb, _all, _allciByRGBA, _ciByRGBA, _ci * and file extensions must be in lower case letters! */ #ifdef WIN32 { unsigned int i; for (i = 0; i < strlen(fname); i++) fname[i] = tolower(fname[i]); } #endif ident.assign(fname); /* read in Rice's file naming convention */ #define CRCFMTSIZ_LEN 13 #define PALCRC_LEN 9 wcstombs(fname, foundfilename, MAX_PATH); /* XXX case sensitivity fiasco! * files must use _a, _rgb, _all, _allciByRGBA, _ciByRGBA, _ci * and file extensions must be in lower case letters! */ #ifdef WIN32 { unsigned int i; for (i = 0; i < strlen(fname); i++) fname[i] = tolower(fname[i]); } #endif pfname = fname + strlen(fname) - 4; if (!(pfname == strstr(fname, ".png") || pfname == strstr(fname, ".bmp") || pfname == strstr(fname, ".dds"))) { #if !DEBUG INFO(80, wst("-----\n")); INFO(80, wst("path: %ls\n"), dir_path.string().c_str()); INFO(80, wst("file: %ls\n"), it->path().leaf().c_str()); #endif INFO(80, wst("Error: not png or bmp or dds!\n")); continue; } pfname = strstr(fname, ident.c_str()); if (pfname != fname) pfname = 0; if (pfname) { if (sscanf(pfname + ident.size(), "#%08lX#%01lX#%01lX#%08lX", &chksum, &fmt, &siz, &palchksum) == 4) pfname += (ident.size() + CRCFMTSIZ_LEN + PALCRC_LEN); else if (sscanf(pfname + ident.size(), "#%08lX#%01lX#%01lX", &chksum, &fmt, &siz) == 3) pfname += (ident.size() + CRCFMTSIZ_LEN); else pfname = 0; } if (!pfname) { #if !DEBUG INFO(80, wst("-----\n")); INFO(80, wst("path: %ls\n", dir_path)); INFO(80, wst("file: %ls\n", foundfilename)); #endif INFO(80, wst("Error: not Rice texture naming convention!\n")); continue; } if (!chksum) { #if !DEBUG INFO(80, wst("-----\n")); INFO(80, wst("path: %ls\n"), dir_path.string().c_str()); INFO(80, wst("file: %ls\n"), it->path().leaf().c_str()); #endif INFO(80, wst("Error: crc32 = 0!\n")); continue; } /* check if we already have it in hires texture cache */ if (!replace) { uint64 chksum64 = (uint64)palchksum; chksum64 <<= 32; chksum64 |= (uint64)chksum; if (TxCache::is_cached(chksum64)) { #if !DEBUG INFO(80, wst("-----\n")); INFO(80, wst("path: %ls\n"), dir_path.string().c_str()); INFO(80, wst("file: %ls\n"), it->path().leaf().c_str()); #endif INFO(80, wst("Error: already cached! duplicate texture!\n")); continue; } } DBG_INFO(80, wst("rom: %ls chksum:%08X %08X fmt:%x size:%x\n"), _ident.c_str(), chksum, palchksum, fmt, siz); /* Deal with the wackiness some texture packs utilize Rice format. * Read in the following order: _a.* + _rgb.*, _all.png _ciByRGBA.png, * _allciByRGBA.png, and _ci.bmp. PNG are prefered over BMP. * * For some reason there are texture packs that include them all. Some * even have RGB textures named as _all.* and ARGB textures named as * _rgb.*... Someone pleeeez write a GOOD guideline for the texture * designers!!! * * We allow hires textures to have higher bpp than the N64 originals. */ /* N64 formats * Format: 0 - RGBA, 1 - YUV, 2 - CI, 3 - IA, 4 - I * Size: 0 - 4bit, 1 - 8bit, 2 - 16bit, 3 - 32 bit */ /* * read in _rgb.* and _a.* */ if (pfname == strstr(fname, "_rgb.") || pfname == strstr(fname, "_a.")) { strcpy(pfname, "_rgb.png"); if (!osal_path_existsA(fname)) { strcpy(pfname, "_rgb.bmp"); if (!osal_path_existsA(fname)) { #if !DEBUG INFO(80, wst("-----\n")); INFO(80, wst("path: %ls\n"), dir_path.string().c_str()); INFO(80, wst("file: %ls\n"), it->path().leaf().c_str()); #endif INFO(80, wst("Error: missing _rgb.*! _a.* must be paired with _rgb.*!\n")); continue; } } /* _a.png */ strcpy(pfname, "_a.png"); if ((fp = fopen(fname, "rb")) != NULL) { tmptex = _txImage->readPNG(fp, &tmpwidth, &tmpheight, &tmpformat); fclose(fp); } if (!tmptex) { /* _a.bmp */ strcpy(pfname, "_a.bmp"); if ((fp = fopen(fname, "rb")) != NULL) { tmptex = _txImage->readBMP(fp, &tmpwidth, &tmpheight, &tmpformat); fclose(fp); } } /* _rgb.png */ strcpy(pfname, "_rgb.png"); if ((fp = fopen(fname, "rb")) != NULL) { tex = _txImage->readPNG(fp, &width, &height, &format); fclose(fp); } if (!tex) { /* _rgb.bmp */ strcpy(pfname, "_rgb.bmp"); if ((fp = fopen(fname, "rb")) != NULL) { tex = _txImage->readBMP(fp, &width, &height, &format); fclose(fp); } } if (tmptex) { /* check if _rgb.* and _a.* have matching size and format. */ if (!tex || width != tmpwidth || height != tmpheight || format != GL_RGBA8 || tmpformat != GL_RGBA8) { #if !DEBUG INFO(80, wst("-----\n")); INFO(80, wst("path: %ls\n"), dir_path.string().c_str()); INFO(80, wst("file: %ls\n"), it->path().leaf().c_str()); #endif if (!tex) { INFO(80, wst("Error: missing _rgb.*!\n")); } else if (width != tmpwidth || height != tmpheight) { INFO(80, wst("Error: _rgb.* and _a.* have mismatched width or height!\n")); } else if (format != GL_RGBA8 || tmpformat != GL_RGBA8) { INFO(80, wst("Error: _rgb.* or _a.* not in 32bit color!\n")); } if (tex) free(tex); if (tmptex) free(tmptex); tex = NULL; tmptex = NULL; continue; } } /* make adjustments */ if (tex) { if (tmptex) { /* merge (A)RGB and A comp */ DBG_INFO(80, wst("merge (A)RGB and A comp\n")); int i; for (i = 0; i < height * width; i++) { #if 1 /* use R comp for alpha. this is what Rice uses. sigh... */ ((uint32*)tex)[i] &= 0x00ffffff; ((uint32*)tex)[i] |= ((((uint32*)tmptex)[i] & 0xff) << 24); #endif #if 0 /* use libpng style grayscale conversion */ uint32 texel = ((uint32*)tmptex)[i]; uint32 acomp = (((texel >> 16) & 0xff) * 6969 + ((texel >> 8) & 0xff) * 23434 + ((texel ) & 0xff) * 2365) / 32768; ((uint32*)tex)[i] = (acomp << 24) | (((uint32*)tex)[i] & 0x00ffffff); #endif #if 0 /* use the standard NTSC gray scale conversion */ uint32 texel = ((uint32*)tmptex)[i]; uint32 acomp = (((texel >> 16) & 0xff) * 299 + ((texel >> 8) & 0xff) * 587 + ((texel ) & 0xff) * 114) / 1000; ((uint32*)tex)[i] = (acomp << 24) | (((uint32*)tex)[i] & 0x00ffffff); #endif } free(tmptex); tmptex = NULL; } else { /* clobber A comp. never a question of alpha. only RGB used. */ #if !DEBUG INFO(80, wst("-----\n")); INFO(80, wst("path: %ls\n"), dir_path.string().c_str()); INFO(80, wst("file: %ls\n"), it->path().leaf().c_str()); #endif INFO(80, wst("Warning: missing _a.*! only using _rgb.*. treat as opaque texture.\n")); int i; for (i = 0; i < height * width; i++) { ((uint32*)tex)[i] |= 0xff000000; } } } } else /* * read in _all.png, _all.dds, _allciByRGBA.png, _allciByRGBA.dds * _ciByRGBA.png, _ciByRGBA.dds, _ci.bmp */ if (pfname == strstr(fname, "_all.png") || pfname == strstr(fname, "_all.dds") || #ifdef WIN32 pfname == strstr(fname, "_allcibyrgba.png") || pfname == strstr(fname, "_allcibyrgba.dds") || pfname == strstr(fname, "_cibyrgba.png") || pfname == strstr(fname, "_cibyrgba.dds") || #else pfname == strstr(fname, "_allciByRGBA.png") || pfname == strstr(fname, "_allciByRGBA.dds") || pfname == strstr(fname, "_ciByRGBA.png") || pfname == strstr(fname, "_ciByRGBA.dds") || #endif pfname == strstr(fname, "_ci.bmp")) { if ((fp = fopen(fname, "rb")) != NULL) { if (strstr(fname, ".png")) tex = _txImage->readPNG(fp, &width, &height, &format); else tex = _txImage->readBMP(fp, &width, &height, &format); fclose(fp); } } /* if we do not have a texture at this point we are screwed */ if (!tex) { #if !DEBUG INFO(80, wst("-----\n")); INFO(80, wst("path: %ls\n"), dir_path.string().c_str()); INFO(80, wst("file: %ls\n"), it->path().leaf().c_str()); #endif INFO(80, wst("Error: load failed!\n")); continue; } DBG_INFO(80, wst("read in as %d x %d gfmt:%x\n"), tmpwidth, tmpheight, tmpformat); /* check if size and format are OK */ if (!(format == GL_RGBA8 || format == GL_COLOR_INDEX8_EXT ) || (width * height) < 4) { /* TxQuantize requirement: width * height must be 4 or larger. */ free(tex); tex = NULL; #if !DEBUG INFO(80, wst("-----\n")); INFO(80, wst("path: %ls\n"), dir_path.string().c_str()); INFO(80, wst("file: %ls\n"), it->path().leaf().c_str()); #endif INFO(80, wst("Error: not width * height > 4 or 8bit palette color or 32bpp or dxt1 or dxt3 or dxt5!\n")); continue; } /* analyze and determine best format to quantize */ if (format == GL_RGBA8) { int i; int alphabits = 0; int fullalpha = 0; boolean intensity = 1; if (!(_options & LET_TEXARTISTS_FLY)) { /* HACK ALERT! */ /* Account for Rice's weirdness with fmt:0 siz:2 textures. * Although the conditions are relaxed with other formats, * the D3D RGBA5551 surface is used for this format in certain * cases. See Nintemod's SuperMario64 life gauge and power * meter. The same goes for fmt:2 textures. See Mollymutt's * PaperMario text. */ if ((fmt == 0 && siz == 2) || fmt == 2) { DBG_INFO(80, wst("Remove black, white, etc borders along the alpha edges.\n")); /* round A comp */ for (i = 0; i < height * width; i++) { uint32 texel = ((uint32*)tex)[i]; ((uint32*)tex)[i] = ((texel & 0xff000000) == 0xff000000 ? 0xff000000 : 0) | (texel & 0x00ffffff); } /* Substitute texel color with the average of the surrounding * opaque texels. This removes borders regardless of hardware * texture filtering (bilinear, etc). */ int j; for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { uint32 texel = ((uint32*)tex)[i * width + j]; if ((texel & 0xff000000) != 0xff000000) { uint32 tmptexel[8]; uint32 k, numtexel, r, g, b; numtexel = r = g = b = 0; memset(&tmptexel, 0, sizeof(tmptexel)); if (i > 0) { tmptexel[0] = ((uint32*)tex)[(i - 1) * width + j]; /* north */ if (j > 0) tmptexel[1] = ((uint32*)tex)[(i - 1) * width + j - 1]; /* north-west */ if (j < width - 1) tmptexel[2] = ((uint32*)tex)[(i - 1) * width + j + 1]; /* north-east */ } if (i < height - 1) { tmptexel[3] = ((uint32*)tex)[(i + 1) * width + j]; /* south */ if (j > 0) tmptexel[4] = ((uint32*)tex)[(i + 1) * width + j - 1]; /* south-west */ if (j < width - 1) tmptexel[5] = ((uint32*)tex)[(i + 1) * width + j + 1]; /* south-east */ } if (j > 0) tmptexel[6] = ((uint32*)tex)[i * width + j - 1]; /* west */ if (j < width - 1) tmptexel[7] = ((uint32*)tex)[i * width + j + 1]; /* east */ for (k = 0; k < 8; k++) { if ((tmptexel[k] & 0xff000000) == 0xff000000) { b += ((tmptexel[k] & 0x00ff0000) >> 16); g += ((tmptexel[k] & 0x0000ff00) >> 8); r += ((tmptexel[k] & 0x000000ff) ); numtexel++; } } if (numtexel) { ((uint32*)tex)[i * width + j] = ((b / numtexel) << 16) | ((g / numtexel) << 8) | ((r / numtexel) ); } else { ((uint32*)tex)[i * width + j] = texel & 0x00ffffff; } } } } } } /* simple analysis of texture */ for (i = 0; i < height * width; i++) { uint32 texel = ((uint32*)tex)[i]; if (alphabits != 8) { #if AGGRESSIVE_QUANTIZATION if ((texel & 0xff000000) < 0x00000003) { alphabits = 1; fullalpha++; } else if ((texel & 0xff000000) < 0xfe000000) { alphabits = 8; } #else if ((texel & 0xff000000) == 0x00000000) { alphabits = 1; fullalpha++; } else if ((texel & 0xff000000) != 0xff000000) { alphabits = 8; } #endif } if (intensity) { int rcomp = (texel >> 16) & 0xff; int gcomp = (texel >> 8) & 0xff; int bcomp = (texel ) & 0xff; #if AGGRESSIVE_QUANTIZATION if (abs(rcomp - gcomp) > 8 || abs(rcomp - bcomp) > 8 || abs(gcomp - bcomp) > 8) intensity = 0; #else if (rcomp != gcomp || rcomp != bcomp || gcomp != bcomp) intensity = 0; #endif } if (!intensity && alphabits == 8) break; } DBG_INFO(80, wst("required alpha bits:%d zero acomp texels:%d rgb as intensity:%d\n"), alphabits, fullalpha, intensity); /* preparations based on above analysis */ #if !REDUCE_TEXTURE_FOOTPRINT if (_maxbpp < 32 || _options & FORCE16BPP_HIRESTEX) { #endif if (alphabits == 0) destformat = GL_RGB; else if (alphabits == 1) destformat = GL_RGB5_A1; else destformat = GL_RGBA8; #if !REDUCE_TEXTURE_FOOTPRINT } else { destformat = GL_RGBA8; } #endif if (fmt == 4 && alphabits == 0) { destformat = GL_RGBA8; /* Rice I format; I = (R + G + B) / 3 */ for (i = 0; i < height * width; i++) { uint32 texel = ((uint32*)tex)[i]; uint32 icomp = (((texel >> 16) & 0xff) + ((texel >> 8) & 0xff) + ((texel ) & 0xff)) / 3; ((uint32*)tex)[i] = (icomp << 24) | (texel & 0x00ffffff); } } DBG_INFO(80, wst("best gfmt:%x\n"), destformat); } /* * Rice hi-res textures: end */ /* XXX: only RGBA8888 for now. comeback to this later... */ if (format == GL_RGBA8) { /* minification */ if (width > _maxwidth || height > _maxheight) { int ratio = 1; if (width / _maxwidth > height / _maxheight) { ratio = (int)ceil((double)width / _maxwidth); } else { ratio = (int)ceil((double)height / _maxheight); } if (!_txReSample->minify(&tex, &width, &height, ratio)) { free(tex); tex = NULL; DBG_INFO(80, wst("Error: minification failed!\n")); continue; } } #if POW2_TEXTURES #if (POW2_TEXTURES == 2) /* 3dfx Glide3x aspect ratio (8:1 - 1:8) */ if (!_txReSample->nextPow2(&tex, &width , &height, 32, 1)) { #else /* normal pow2 expansion */ if (!_txReSample->nextPow2(&tex, &width , &height, 32, 0)) { #endif free(tex); tex = NULL; DBG_INFO(80, wst("Error: aspect ratio adjustment failed!\n")); continue; } #endif /* quantize */ { tmptex = (uint8 *)malloc(_txUtil->sizeofTx(width, height, destformat)); if (tmptex) { switch (destformat) { case GL_RGBA8: case GL_RGBA4: #if !REDUCE_TEXTURE_FOOTPRINT if (_maxbpp < 32 || _options & FORCE16BPP_HIRESTEX) #endif destformat = GL_RGBA4; break; case GL_RGB5_A1: #if !REDUCE_TEXTURE_FOOTPRINT if (_maxbpp < 32 || _options & FORCE16BPP_HIRESTEX) #endif destformat = GL_RGB5_A1; break; case GL_RGB: #if !REDUCE_TEXTURE_FOOTPRINT if (_maxbpp < 32 || _options & FORCE16BPP_HIRESTEX) #endif destformat = GL_RGB; break; } if (_txQuantize->quantize(tex, tmptex, width, height, GL_RGBA8, destformat, 0)) { format = destformat; free(tex); tex = tmptex; } else free(tmptex); tmptex = NULL; } } } /* last minute validations */ if (!tex || !chksum || !width || !height || !format || width > _maxwidth || height > _maxheight) { #if !DEBUG INFO(80, wst("-----\n")); INFO(80, wst("path: %ls\n"), dir_path.string().c_str()); INFO(80, wst("file: %ls\n"), it->path().leaf().c_str()); #endif if (tex) { free(tex); tex = NULL; INFO(80, wst("Error: bad format or size! %d x %d gfmt:%x\n"), width, height, format); } else { INFO(80, wst("Error: load failed!!\n")); } continue; } /* load it into hires texture cache. */ { uint64 chksum64 = (uint64)palchksum; chksum64 <<= 32; chksum64 |= (uint64)chksum; GHQTexInfo tmpInfo; tmpInfo.data = tex; tmpInfo.width = width; tmpInfo.height = height; tmpInfo.is_hires_tex = 1; setTextureFormat(format, &tmpInfo); /* remove redundant in cache */ if (replace && TxCache::del(chksum64)) { DBG_INFO(80, wst("removed duplicate old cache.\n")); } /* add to cache */ if (TxCache::add(chksum64, &tmpInfo)) { /* Callback to display hires texture info. * Gonetz */ if (_callback) { wchar_t tmpbuf[MAX_PATH]; mbstowcs(tmpbuf, fname, MAX_PATH); (*_callback)(wst("[%d] total mem:%.2fmb - %ls\n"), _cache.size(), (float)_totalSize/1000000, tmpbuf); } DBG_INFO(80, wst("texture loaded!\n")); } free(tex); } } while (foundfilename != NULL); osal_search_dir_close(dir); CHDIR(curpath); return 1; } mupen64plus-video-gliden64/src/GLES2/000700 001750 001750 00000000000 12656647145 020231 5ustar00sergiosergio000000 000000 mupen64plus-video-gliden64/src/mupenplus/video_api_export.ver000664 001750 001750 00000000466 12655644434 025542 0ustar00sergiosergio000000 000000 { global: PluginStartup; PluginShutdown; PluginGetVersion; ChangeWindow; InitiateGFX; MoveScreen; ProcessDList; ProcessRDPList; RomClosed; RomOpen; ShowCFB; UpdateScreen; ViStatusChanged; ViWidthChanged; ReadScreen2; SetRenderingCallback; ResizeVideoOutput; FBRead; FBWrite; FBGetFrameBufferInfo; local: *; }; mupen64plus-core/src/debugger/debugger.c000664 001750 001750 00000006564 12655644434 021365 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - debugger.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2008 DarkJeztr * * Copyright (C) 2002 davFr * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include "api/debugger.h" #include "dbg_types.h" #include "debugger.h" #include "dbg_breakpoints.h" #include "dbg_memory.h" // State of the Emulation Thread: // 0 -> pause, 2 -> run. int g_DebuggerActive = 0; // whether the debugger is enabled or not int run; static SDL_cond *debugger_done_cond; static SDL_mutex *mutex; uint32 previousPC; //]=-=-=-=-=-=-=-=-=-=-=[ Initialisation du Debugger ]=-=-=-=-=-=-=-=-=-=-=-=[ void init_debugger() { g_DebuggerActive = 1; run = 0; DebuggerCallback(DEBUG_UI_INIT, 0); /* call front-end to initialize user interface */ init_host_disassembler(); mutex = SDL_CreateMutex(); debugger_done_cond = SDL_CreateCond(); } void destroy_debugger() { SDL_DestroyMutex(mutex); mutex = NULL; SDL_DestroyCond(debugger_done_cond); debugger_done_cond = NULL; g_DebuggerActive = 0; } //]=-=-=-=-=-=-=-=-=-=-=-=-=[ Mise-a-Jour Debugger ]=-=-=-=-=-=-=-=-=-=-=-=-=[ void update_debugger(uint32 pc) // Update debugger state and display. // Should be called after each R4300 instruction // Checks for breakpoint hits on PC { int bpt; if(run!=0) {//check if we hit a breakpoint bpt = check_breakpoints(pc); if( bpt!=-1 ) { run = 0; if(BPT_CHECK_FLAG(g_Breakpoints[bpt], BPT_FLAG_LOG)) log_breakpoint(pc, BPT_FLAG_EXEC, 0); } } if(run!=2) { DebuggerCallback(DEBUG_UI_UPDATE, pc); /* call front-end to notify user interface to update */ } if(run==0) { // Emulation thread is blocked until a button is clicked. SDL_mutexP(mutex); SDL_CondWait(debugger_done_cond, mutex); SDL_mutexV(mutex); } previousPC = pc; } void debugger_step() { SDL_CondSignal(debugger_done_cond); } mupen64plus-video-gliden64/src/F3DEX2CBFD.cpp000664 001750 001750 00000006753 12655644434 021457 0ustar00sergiosergio000000 000000 #include "GLideN64.h" #include "Debug.h" #include "F3D.h" #include "F3DEX.h" #include "F3DEX2.h" #include "F3DEX2CBFD.h" #include "N64.h" #include "RSP.h" #include "RDP.h" #include "gSP.h" #include "gDP.h" #include "GBI.h" #include "OpenGL.h" void F3DEX2CBFD_Vtx( u32 w0, u32 w1 ) { u32 n = _SHIFTR( w0, 12, 8 ); gSPCBFDVertex( w1, n, _SHIFTR( w0, 1, 7 ) - n ); } void F3DEX2CBFD_MoveWord( u32 w0, u32 w1 ) { switch (_SHIFTR( w0, 16, 8 )) { case G_MW_NUMLIGHT: gSPNumLights( w1 / 48 ); break; case G_MW_CLIP: gSPClipRatio( w1 ); break; case G_MW_SEGMENT: gSPSegment( _SHIFTR( w0, 0, 16 ) >> 2, w1 & 0x00FFFFFF ); break; case G_MW_FOG: gSPFogFactor( (s16)_SHIFTR( w1, 16, 16 ), (s16)_SHIFTR( w1, 0, 16 ) ); break; case G_MW_PERSPNORM: gSPPerspNormalize( w1 ); break; case G_MW_COORD_MOD: gSPCoordMod( w0, w1 ); break; } } void F3DEX2CBFD_MoveMem( u32 w0, u32 w1 ) { switch (_SHIFTR( w0, 0, 8 )) { case F3DEX2_MV_VIEWPORT: gSPViewport( w1 ); break; case G_MV_LIGHT: { const u32 offset = _SHIFTR(w0, 5, 14); const u32 n = offset / 48; if (n < 2) gSPLookAt(w1, n); else gSPLightCBFD(w1, n - 2); } break; case G_MV_NORMALES: gSPSetVertexNormaleBase(w1); break; } } void F3DEX2CBFD_Tri4( u32 w0, u32 w1 ) { gSP4Triangles( _SHIFTR( w0, 23, 5 ), _SHIFTR( w0, 18, 5 ), (_SHIFTR( w0, 15, 3 )<<2)|_SHIFTR( w1, 30, 2 ), _SHIFTR( w0, 10, 5 ), _SHIFTR( w0, 5, 5 ), _SHIFTR( w0, 0, 5 ), _SHIFTR( w1, 25, 5 ), _SHIFTR( w1, 20, 5 ), _SHIFTR( w1, 15, 5 ), _SHIFTR( w1, 10, 5 ), _SHIFTR( w1, 5, 5 ), _SHIFTR( w1, 0, 5 ) ); } void F3DEX2CBFD_Init() { gSPSetupFunctions(); // Set GeometryMode flags GBI_InitFlags( F3DEX2 ); GBI.PCStackSize = 18; // GBI Command Command Value Command Function GBI_SetGBI( G_RDPHALF_2, F3DEX2_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_SETOTHERMODE_H, F3DEX2_SETOTHERMODE_H, F3DEX2_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3DEX2_SETOTHERMODE_L, F3DEX2_SetOtherMode_L ); GBI_SetGBI( G_RDPHALF_1, F3DEX2_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_SPNOOP, F3DEX2_SPNOOP, F3D_SPNoOp ); GBI_SetGBI( G_ENDDL, F3DEX2_ENDDL, F3D_EndDL ); GBI_SetGBI( G_DL, F3DEX2_DL, F3D_DList ); GBI_SetGBI( G_LOAD_UCODE, F3DEX2_LOAD_UCODE, F3DEX_Load_uCode ); GBI_SetGBI( G_MOVEMEM, F3DEX2_MOVEMEM, F3DEX2CBFD_MoveMem ); GBI_SetGBI( G_MOVEWORD, F3DEX2_MOVEWORD, F3DEX2CBFD_MoveWord ); GBI_SetGBI( G_MTX, F3DEX2_MTX, F3DEX2_Mtx ); GBI_SetGBI( G_GEOMETRYMODE, F3DEX2_GEOMETRYMODE, F3DEX2_GeometryMode ); GBI_SetGBI( G_POPMTX, F3DEX2_POPMTX, F3DEX2_PopMtx ); GBI_SetGBI( G_TEXTURE, F3DEX2_TEXTURE, F3DEX2_Texture ); GBI_SetGBI( G_DMA_IO, F3DEX2_DMA_IO, F3DEX2_DMAIO ); GBI_SetGBI( G_SPECIAL_1, F3DEX2_SPECIAL_1, F3DEX2_Special_1 ); GBI_SetGBI( G_SPECIAL_2, F3DEX2_SPECIAL_2, F3DEX2_Special_2 ); GBI_SetGBI( G_SPECIAL_3, F3DEX2_SPECIAL_3, F3DEX2_Special_3 ); GBI_SetGBI( G_VTX, F3DEX2_VTX, F3DEX2CBFD_Vtx ); GBI_SetGBI( G_MODIFYVTX, F3DEX2_MODIFYVTX, F3DEX_ModifyVtx ); GBI_SetGBI( G_CULLDL, F3DEX2_CULLDL, F3DEX_CullDL ); GBI_SetGBI( G_BRANCH_Z, F3DEX2_BRANCH_Z, F3DEX_Branch_Z ); GBI_SetGBI( G_TRI1, F3DEX2_TRI1, F3DEX2_Tri1 ); GBI_SetGBI( G_TRI2, F3DEX2_TRI2, F3DEX_Tri2 ); GBI_SetGBI( G_QUAD, F3DEX2_QUAD, F3DEX2_Quad ); GBI_SetGBI( G_LINE3D, F3DEX2_LINE3D, F3DEX2_Line3D ); for (u32 i = 0; i < 16; ++i) GBI.cmd[F3DEX2CBFD_TRI4+i] = F3DEX2CBFD_Tri4; } glide2gl/src/Glitch64/uthash.h000664 001750 001750 00000111202 12655644434 017225 0ustar00sergiosergio000000 000000 /* Copyright (c) 2003-2014, Troy D. Hanson http://troydhanson.github.com/uthash/ All rights reserved. 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. 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 COPYRIGHT OWNER 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. */ #ifndef UTHASH_H #define UTHASH_H #include /* memcmp,strlen */ #include /* ptrdiff_t */ #include /* exit() */ /* These macros use decltype or the earlier __typeof GNU extension. As decltype is only available in newer compilers (VS2010 or gcc 4.3+ when compiling c++ source) this code uses whatever method is needed or, for VS2008 where neither is available, uses casting workarounds. */ #ifdef _MSC_VER /* MS compiler */ #if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ #define DECLTYPE(x) (decltype(x)) #else /* VS2008 or older (or VS2010 in C mode) */ #define NO_DECLTYPE #define DECLTYPE(x) #endif #else /* GNU, Sun and other compilers */ #define DECLTYPE(x) (__typeof(x)) #endif #ifdef NO_DECLTYPE #define DECLTYPE_ASSIGN(dst,src) \ do { \ char **_da_dst = (char**)(&(dst)); \ *_da_dst = (char*)(src); \ } while(0) #else #define DECLTYPE_ASSIGN(dst,src) \ do { \ (dst) = DECLTYPE(dst)(src); \ } while(0) #endif /* a number of the hash function use uint32_t which isn't defined on win32 */ #ifdef _MSC_VER typedef unsigned int uint32_t; typedef unsigned char uint8_t; #else #include /* uint32_t */ #endif #define UTHASH_VERSION 1.9.9 #ifndef uthash_fatal #define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */ #endif /* initial number of buckets */ #define HASH_INITIAL_NUM_BUCKETS 32 /* initial number of buckets */ #define HASH_INITIAL_NUM_BUCKETS_LOG2 5 /* lg2 of initial number of buckets */ #define HASH_BKT_CAPACITY_THRESH 10 /* expand when bucket count reaches */ /* calculate the element whose hash handle address is hhe */ #define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho))) #define HASH_FIND(hh,head,keyptr,keylen,out) \ do { \ out=NULL; \ if (head) { \ unsigned _hf_bkt, _hf_hashv; \ HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \ HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \ keyptr,keylen,out); \ } \ } while (0) #define HASH_MAKE_TABLE(hh,head) \ do { \ (head)->hh.tbl = (UT_hash_table*)malloc( \ sizeof(UT_hash_table)); \ if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \ memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \ (head)->hh.tbl->tail = &((head)->hh); \ (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ (head)->hh.tbl->buckets = (UT_hash_bucket*)malloc( \ HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \ memset((head)->hh.tbl->buckets, 0, \ HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ } while(0) #define HASH_ADD(hh,head,fieldname,keylen_in,add) \ HASH_ADD_KEYPTR(hh,head,&((add)->fieldname),keylen_in,add) #define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced) \ do { \ replaced=NULL; \ HASH_FIND(hh,head,&((add)->fieldname),keylen_in,replaced); \ if (replaced!=NULL) { \ HASH_DELETE(hh,head,replaced); \ }; \ HASH_ADD(hh,head,fieldname,keylen_in,add); \ } while(0) #define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ do { \ unsigned _ha_bkt; \ (add)->hh.next = NULL; \ (add)->hh.key = (char*)(keyptr); \ (add)->hh.keylen = (unsigned)(keylen_in); \ if (!(head)) { \ head = (add); \ (head)->hh.prev = NULL; \ HASH_MAKE_TABLE(hh,head); \ } else { \ (head)->hh.tbl->tail->next = (add); \ (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ (head)->hh.tbl->tail = &((add)->hh); \ } \ (head)->hh.tbl->num_items++; \ (add)->hh.tbl = (head)->hh.tbl; \ HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets, \ (add)->hh.hashv, _ha_bkt); \ HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \ } while(0) #define HASH_TO_BKT( hashv, num_bkts, bkt ) \ do { \ bkt = ((hashv) & ((num_bkts) - 1)); \ } while(0) /* delete "delptr" from the hash table. * "the usual" patch-up process for the app-order doubly-linked-list. * The use of _hd_hh_del below deserves special explanation. * These used to be expressed using (delptr) but that led to a bug * if someone used the same symbol for the head and deletee, like * HASH_DELETE(hh,users,users); * We want that to work, but by changing the head (users) below * we were forfeiting our ability to further refer to the deletee (users) * in the patch-up process. Solution: use scratch space to * copy the deletee pointer, then the latter references are via that * scratch pointer rather than through the repointed (users) symbol. */ #define HASH_DELETE(hh,head,delptr) \ do { \ struct UT_hash_handle *_hd_hh_del; \ if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \ free((head)->hh.tbl->buckets); \ free((head)->hh.tbl); \ head = NULL; \ } else { \ unsigned _hd_bkt; \ _hd_hh_del = &((delptr)->hh); \ if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \ (head)->hh.tbl->tail = \ (UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \ (head)->hh.tbl->hho); \ } \ if ((delptr)->hh.prev) { \ ((UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \ (head)->hh.tbl->hho))->next = (delptr)->hh.next; \ } else { \ DECLTYPE_ASSIGN(head,(delptr)->hh.next); \ } \ if (_hd_hh_del->next) { \ ((UT_hash_handle*)((ptrdiff_t)_hd_hh_del->next + \ (head)->hh.tbl->hho))->prev = \ _hd_hh_del->prev; \ } \ HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ (head)->hh.tbl->num_items--; \ } \ } while (0) /* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ #define HASH_FIND_STR(head,findstr,out) \ HASH_FIND(hh,head,findstr,strlen(findstr),out) #define HASH_ADD_STR(head,strfield,add) \ HASH_ADD(hh,head,strfield[0],strlen(add->strfield),add) #define HASH_REPLACE_STR(head,strfield,add,replaced) \ HASH_REPLACE(hh,head,strfield[0],strlen(add->strfield),add,replaced) #define HASH_FIND_INT(head,findint,out) \ HASH_FIND(hh,head,findint,sizeof(int),out) #define HASH_ADD_INT(head,intfield,add) \ HASH_ADD(hh,head,intfield,sizeof(int),add) #define HASH_REPLACE_INT(head,intfield,add,replaced) \ HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced) #define HASH_FIND_PTR(head,findptr,out) \ HASH_FIND(hh,head,findptr,sizeof(void *),out) #define HASH_ADD_PTR(head,ptrfield,add) \ HASH_ADD(hh,head,ptrfield,sizeof(void *),add) #define HASH_REPLACE_PTR(head,ptrfield,add,replaced) \ HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced) #define HASH_DEL(head,delptr) \ HASH_DELETE(hh,head,delptr) /* default to Jenkin's hash */ #define HASH_FCN HASH_JEN /* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */ #define HASH_BER(key,keylen,num_bkts,hashv,bkt) \ do { \ unsigned _hb_keylen=keylen; \ char *_hb_key=(char*)(key); \ (hashv) = 0; \ while (_hb_keylen--) { (hashv) = (((hashv) << 5) + (hashv)) + *_hb_key++; } \ bkt = (hashv) & (num_bkts-1); \ } while (0) /* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ #define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \ do { \ unsigned _sx_i; \ char *_hs_key=(char*)(key); \ hashv = 0; \ for(_sx_i=0; _sx_i < keylen; _sx_i++) \ hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ bkt = hashv & (num_bkts-1); \ } while (0) /* FNV-1a variation */ #define HASH_FNV(key,keylen,num_bkts,hashv,bkt) \ do { \ unsigned _fn_i; \ char *_hf_key=(char*)(key); \ hashv = 2166136261UL; \ for(_fn_i=0; _fn_i < keylen; _fn_i++) \ hashv = hashv ^ _hf_key[_fn_i]; \ hashv = hashv * 16777619; \ bkt = hashv & (num_bkts-1); \ } while(0) #define HASH_OAT(key,keylen,num_bkts,hashv,bkt) \ do { \ unsigned _ho_i; \ char *_ho_key=(char*)(key); \ hashv = 0; \ for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ hashv += _ho_key[_ho_i]; \ hashv += (hashv << 10); \ hashv ^= (hashv >> 6); \ } \ hashv += (hashv << 3); \ hashv ^= (hashv >> 11); \ hashv += (hashv << 15); \ bkt = hashv & (num_bkts-1); \ } while(0) #define HASH_JEN_MIX(a,b,c) \ do { \ a -= b; a -= c; a ^= ( c >> 13 ); \ b -= c; b -= a; b ^= ( a << 8 ); \ c -= a; c -= b; c ^= ( b >> 13 ); \ a -= b; a -= c; a ^= ( c >> 12 ); \ b -= c; b -= a; b ^= ( a << 16 ); \ c -= a; c -= b; c ^= ( b >> 5 ); \ a -= b; a -= c; a ^= ( c >> 3 ); \ b -= c; b -= a; b ^= ( a << 10 ); \ c -= a; c -= b; c ^= ( b >> 15 ); \ } while (0) #define HASH_JEN(key,keylen,num_bkts,hashv,bkt) \ do { \ unsigned _hj_i,_hj_j,_hj_k; \ unsigned char *_hj_key=(unsigned char*)(key); \ hashv = 0xfeedbeef; \ _hj_i = _hj_j = 0x9e3779b9; \ _hj_k = (unsigned)(keylen); \ while (_hj_k >= 12) { \ _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ + ( (unsigned)_hj_key[2] << 16 ) \ + ( (unsigned)_hj_key[3] << 24 ) ); \ _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ + ( (unsigned)_hj_key[6] << 16 ) \ + ( (unsigned)_hj_key[7] << 24 ) ); \ hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ + ( (unsigned)_hj_key[10] << 16 ) \ + ( (unsigned)_hj_key[11] << 24 ) ); \ \ HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ \ _hj_key += 12; \ _hj_k -= 12; \ } \ hashv += keylen; \ switch ( _hj_k ) { \ case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); \ case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); \ case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); \ case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); \ case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); \ case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); \ case 5: _hj_j += _hj_key[4]; \ case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); \ case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); \ case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); \ case 1: _hj_i += _hj_key[0]; \ } \ HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ bkt = hashv & (num_bkts-1); \ } while(0) #ifdef HASH_USING_NO_STRICT_ALIASING /* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads. * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error. * MurmurHash uses the faster approach only on CPU's where we know it's safe. * * Note the preprocessor built-in defines can be emitted using: * * gcc -m64 -dM -E - < /dev/null (on gcc) * cc -## a.c (where a.c is a simple test file) (Sun Studio) */ #if (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86)) #define MUR_GETBLOCK(p,i) p[i] #else /* non intel */ #define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 0x3) == 0) #define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 0x3) == 1) #define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 0x3) == 2) #define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 0x3) == 3) #define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL)) #if (defined(MSB_FIRST) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__)) #define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24)) #define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16)) #define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8)) #else /* assume little endian non-intel */ #define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24)) #define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16)) #define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8)) #endif #define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \ (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \ (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \ MUR_ONE_THREE(p)))) #endif #define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) #define MUR_FMIX(_h) \ do { \ _h ^= _h >> 16; \ _h *= 0x85ebca6b; \ _h ^= _h >> 13; \ _h *= 0xc2b2ae35l; \ _h ^= _h >> 16; \ } while(0) #define HASH_MUR(key,keylen,num_bkts,hashv,bkt) \ do { \ const uint8_t *_mur_data = (const uint8_t*)(key); \ const int _mur_nblocks = (keylen) / 4; \ uint32_t _mur_h1 = 0xf88D5353; \ uint32_t _mur_c1 = 0xcc9e2d51; \ uint32_t _mur_c2 = 0x1b873593; \ uint32_t _mur_k1 = 0; \ const uint8_t *_mur_tail; \ const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+_mur_nblocks*4); \ int _mur_i; \ for(_mur_i = -_mur_nblocks; _mur_i; _mur_i++) { \ _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \ _mur_k1 *= _mur_c1; \ _mur_k1 = MUR_ROTL32(_mur_k1,15); \ _mur_k1 *= _mur_c2; \ \ _mur_h1 ^= _mur_k1; \ _mur_h1 = MUR_ROTL32(_mur_h1,13); \ _mur_h1 = _mur_h1*5+0xe6546b64; \ } \ _mur_tail = (const uint8_t*)(_mur_data + _mur_nblocks*4); \ _mur_k1=0; \ switch((keylen) & 3) { \ case 3: _mur_k1 ^= _mur_tail[2] << 16; \ case 2: _mur_k1 ^= _mur_tail[1] << 8; \ case 1: _mur_k1 ^= _mur_tail[0]; \ _mur_k1 *= _mur_c1; \ _mur_k1 = MUR_ROTL32(_mur_k1,15); \ _mur_k1 *= _mur_c2; \ _mur_h1 ^= _mur_k1; \ } \ _mur_h1 ^= (keylen); \ MUR_FMIX(_mur_h1); \ hashv = _mur_h1; \ bkt = hashv & (num_bkts-1); \ } while(0) #endif /* HASH_USING_NO_STRICT_ALIASING */ /* key comparison function; return 0 if keys equal */ #define HASH_KEYCMP(a,b,len) memcmp(a,b,len) /* iterate over items in a known bucket to find desired item */ #define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \ do { \ if (head.hh_head) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,head.hh_head)); \ else out=NULL; \ while (out) { \ if ((out)->hh.keylen == keylen_in) { \ if ((HASH_KEYCMP((out)->hh.key,keyptr,keylen_in)) == 0) break; \ } \ if ((out)->hh.hh_next) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,(out)->hh.hh_next)); \ else out = NULL; \ } \ } while(0) /* add an item to a bucket */ #define HASH_ADD_TO_BKT(head,addhh) \ do { \ head.count++; \ (addhh)->hh_next = head.hh_head; \ (addhh)->hh_prev = NULL; \ if (head.hh_head) { (head).hh_head->hh_prev = (addhh); } \ (head).hh_head=addhh; \ if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH) \ && (addhh)->tbl->noexpand != 1) { \ HASH_EXPAND_BUCKETS((addhh)->tbl); \ } \ } while(0) /* remove an item from a given bucket */ #define HASH_DEL_IN_BKT(hh,head,hh_del) \ (head).count--; \ if ((head).hh_head == hh_del) { \ (head).hh_head = hh_del->hh_next; \ } \ if (hh_del->hh_prev) { \ hh_del->hh_prev->hh_next = hh_del->hh_next; \ } \ if (hh_del->hh_next) { \ hh_del->hh_next->hh_prev = hh_del->hh_prev; \ } /* Bucket expansion has the effect of doubling the number of buckets * and redistributing the items into the new buckets. Ideally the * items will distribute more or less evenly into the new buckets * (the extent to which this is true is a measure of the quality of * the hash function as it applies to the key domain). * * With the items distributed into more buckets, the chain length * (item count) in each bucket is reduced. Thus by expanding buckets * the hash keeps a bound on the chain length. This bounded chain * length is the essence of how a hash provides constant time lookup. * * The calculation of tbl->ideal_chain_maxlen below deserves some * explanation. First, keep in mind that we're calculating the ideal * maximum chain length based on the *new* (doubled) bucket count. * In fractions this is just n/b (n=number of items,b=new num buckets). * Since the ideal chain length is an integer, we want to calculate * ceil(n/b). We don't depend on floating point arithmetic in this * hash, so to calculate ceil(n/b) with integers we could write * * ceil(n/b) = (n/b) + ((n%b)?1:0) * * and in fact a previous version of this hash did just that. * But now we have improved things a bit by recognizing that b is * always a power of two. We keep its base 2 log handy (call it lb), * so now we can write this with a bit shift and logical AND: * * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) * */ #define HASH_EXPAND_BUCKETS(tbl) \ do { \ unsigned _he_bkt; \ unsigned _he_bkt_i; \ struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ _he_new_buckets = (UT_hash_bucket*)malloc( \ 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \ memset(_he_new_buckets, 0, \ 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ tbl->ideal_chain_maxlen = \ (tbl->num_items >> (tbl->log2_num_buckets+1)) + \ ((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0); \ tbl->nonideal_items = 0; \ for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \ { \ _he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \ while (_he_thh) { \ _he_hh_nxt = _he_thh->hh_next; \ HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt); \ _he_newbkt = &(_he_new_buckets[ _he_bkt ]); \ if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \ tbl->nonideal_items++; \ _he_newbkt->expand_mult = _he_newbkt->count / \ tbl->ideal_chain_maxlen; \ } \ _he_thh->hh_prev = NULL; \ _he_thh->hh_next = _he_newbkt->hh_head; \ if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev = \ _he_thh; \ _he_newbkt->hh_head = _he_thh; \ _he_thh = _he_hh_nxt; \ } \ } \ free( tbl->buckets); \ tbl->num_buckets *= 2; \ tbl->log2_num_buckets++; \ tbl->buckets = _he_new_buckets; \ tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \ (tbl->ineff_expands+1) : 0; \ if (tbl->ineff_expands > 1) { \ tbl->noexpand=1; \ } \ } while(0) #define HASH_CLEAR(hh,head) \ do { \ if (head) { \ free((head)->hh.tbl->buckets); \ free((head)->hh.tbl); \ (head)=NULL; \ } \ } while(0) #define HASH_OVERHEAD(hh,head) \ (size_t)((((head)->hh.tbl->num_items * sizeof(UT_hash_handle)) + \ ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket)) + \ (sizeof(UT_hash_table)) #ifdef NO_DECLTYPE #define HASH_ITER(hh,head,el,tmp) \ for((el)=(head), (*(char**)(&(tmp)))=(char*)((head)?(head)->hh.next:NULL); \ el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL)) #else #define HASH_ITER(hh,head,el,tmp) \ for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL); \ el; (el)=(tmp),(tmp)=DECLTYPE(el)((tmp)?(tmp)->hh.next:NULL)) #endif /* obtain a count of items in the hash */ #define HASH_COUNT(head) HASH_CNT(hh,head) #define HASH_CNT(hh,head) ((head)?((head)->hh.tbl->num_items):0) typedef struct UT_hash_bucket { struct UT_hash_handle *hh_head; unsigned count; /* expand_mult is normally set to 0. In this situation, the max chain length * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If * the bucket's chain exceeds this length, bucket expansion is triggered). * However, setting expand_mult to a non-zero value delays bucket expansion * (that would be triggered by additions to this particular bucket) * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. * (The multiplier is simply expand_mult+1). The whole idea of this * multiplier is to reduce bucket expansions, since they are expensive, in * situations where we know that a particular bucket tends to be overused. * It is better to let its chain length grow to a longer yet-still-bounded * value, than to do an O(n) bucket expansion too often. */ unsigned expand_mult; } UT_hash_bucket; typedef struct UT_hash_table { UT_hash_bucket *buckets; unsigned num_buckets, log2_num_buckets; unsigned num_items; struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ /* in an ideal situation (all buckets used equally), no bucket would have * more than ceil(#items/#buckets) items. that's the ideal chain length. */ unsigned ideal_chain_maxlen; /* nonideal_items is the number of items in the hash whose chain position * exceeds the ideal chain maxlen. these items pay the penalty for an uneven * hash distribution; reaching them in a chain traversal takes >ideal steps */ unsigned nonideal_items; /* ineffective expands occur when a bucket doubling was performed, but * afterward, more than half the items in the hash had nonideal chain * positions. If this happens on two consecutive expansions we inhibit any * further expansion, as it's not helping; this happens when the hash * function isn't a good fit for the key domain. When expansion is inhibited * the hash will still work, albeit no longer in constant time. */ unsigned ineff_expands, noexpand; } UT_hash_table; typedef struct UT_hash_handle { struct UT_hash_table *tbl; void *prev; /* prev element in app order */ void *next; /* next element in app order */ struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ struct UT_hash_handle *hh_next; /* next hh in bucket order */ void *key; /* ptr to enclosing struct's key */ unsigned keylen; /* enclosing struct's key len */ unsigned hashv; /* result of hash-fcn(key) */ } UT_hash_handle; #endif /* UTHASH_H */ mupen64plus-video-gliden64/src/windows/000700 001750 001750 00000000000 12656647145 021107 5ustar00sergiosergio000000 000000 gles2rice/src/OGLRender.cpp000664 001750 001750 00000070676 12655644434 016672 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "osal_opengl.h" #include "OGLES2FragmentShaders.h" #include "OGLDebug.h" #include "OGLRender.h" #include "OGLGraphicsContext.h" #include "OGLTexture.h" #include "TextureManager.h" // FIXME: Use OGL internal L/T and matrix stack // FIXME: Use OGL lookupAt function // FIXME: Use OGL DisplayList UVFlagMap OGLXUVFlagMaps[] = { {TEXTURE_UV_FLAG_WRAP, GL_REPEAT}, {TEXTURE_UV_FLAG_MIRROR, GL_MIRRORED_REPEAT}, {TEXTURE_UV_FLAG_CLAMP, GL_CLAMP}, }; //=================================================================== OGLRender::OGLRender() { m_bSupportClampToEdge = false; for( int i=0; i<8; i++ ) { m_curBoundTex[i]=0; m_texUnitEnabled[i]=FALSE; } m_bEnableMultiTexture = false; } OGLRender::~OGLRender() { ClearDeviceObjects(); } bool OGLRender::InitDeviceObjects() { // enable Z-buffer by default ZBufferEnable(true); return true; } bool OGLRender::ClearDeviceObjects() { return true; } void OGLRender::Initialize(void) { glMatrixMode(GL_MODELVIEW); OPENGL_CHECK_ERRORS; glLoadIdentity(); OPENGL_CHECK_ERRORS; glViewportWrapper(0, 0, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight, true); OPENGL_CHECK_ERRORS; OGLXUVFlagMaps[TEXTURE_UV_FLAG_MIRROR].realFlag = GL_MIRRORED_REPEAT; m_bSupportClampToEdge = true; OGLXUVFlagMaps[TEXTURE_UV_FLAG_CLAMP].realFlag = GL_CLAMP_TO_EDGE; glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0])); OPENGL_CHECK_ERRORS; glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u)); OPENGL_CHECK_ERRORS; glVertexAttribPointer(VS_TEXCOORD1,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[1].u)); OPENGL_CHECK_ERRORS; glVertexAttribPointer(VS_FOG,1,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][4])); OPENGL_CHECK_ERRORS; glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8_t)*4, &(g_oglVtxColors[0][0]) ); OPENGL_CHECK_ERRORS; } //=================================================================== TextureFilterMap OglTexFilterMap[2]= { {FILTER_POINT, GL_NEAREST}, {FILTER_LINEAR, GL_LINEAR}, }; void OGLRender::ApplyTextureFilter() { static uint32_t minflag=0xFFFF, magflag=0xFFFF; static uint32_t mtex; if( m_texUnitEnabled[0] ) { if( mtex != m_curBoundTex[0] ) { mtex = m_curBoundTex[0]; minflag = m_dwMinFilter; magflag = m_dwMagFilter; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, OglTexFilterMap[m_dwMinFilter].realFilter); OPENGL_CHECK_ERRORS; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, OglTexFilterMap[m_dwMagFilter].realFilter); OPENGL_CHECK_ERRORS; } else { if( minflag != (unsigned int)m_dwMinFilter ) { minflag = m_dwMinFilter; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, OglTexFilterMap[m_dwMinFilter].realFilter); OPENGL_CHECK_ERRORS; } if( magflag != (unsigned int)m_dwMagFilter ) { magflag = m_dwMagFilter; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, OglTexFilterMap[m_dwMagFilter].realFilter); OPENGL_CHECK_ERRORS; } } } } void OGLRender::SetShadeMode(RenderShadeMode mode) { } void OGLRender::ZBufferEnable(bool bZBuffer) { gRSP.bZBufferEnabled = bZBuffer; if( g_curRomInfo.bForceDepthBuffer ) bZBuffer = TRUE; if( bZBuffer ) { glDepthMask(GL_TRUE); OPENGL_CHECK_ERRORS; //glEnable(GL_DEPTH_TEST); glDepthFunc( GL_LEQUAL ); OPENGL_CHECK_ERRORS; } else { glDepthMask(GL_FALSE); OPENGL_CHECK_ERRORS; //glDisable(GL_DEPTH_TEST); glDepthFunc( GL_ALWAYS ); OPENGL_CHECK_ERRORS; } } void OGLRender::ClearBuffer(bool cbuffer, bool zbuffer) { uint32_t flag=0; if( cbuffer ) flag |= GL_COLOR_BUFFER_BIT; if( zbuffer ) flag |= GL_DEPTH_BUFFER_BIT; float depth = ((gRDP.originalFillColor&0xFFFF)>>2)/(float)0x3FFF; glClearDepth(depth); OPENGL_CHECK_ERRORS; glClear(flag); OPENGL_CHECK_ERRORS; } void OGLRender::ClearZBuffer(float depth) { uint32_t flag=GL_DEPTH_BUFFER_BIT; glClearDepth(depth); OPENGL_CHECK_ERRORS; glClear(flag); OPENGL_CHECK_ERRORS; } void OGLRender::SetZCompare(bool bZCompare) { if( g_curRomInfo.bForceDepthBuffer ) bZCompare = TRUE; gRSP.bZBufferEnabled = bZCompare; if( bZCompare == TRUE ) { //glEnable(GL_DEPTH_TEST); glDepthFunc( GL_LEQUAL ); OPENGL_CHECK_ERRORS; } else { //glDisable(GL_DEPTH_TEST); glDepthFunc( GL_ALWAYS ); OPENGL_CHECK_ERRORS; } } void OGLRender::SetZUpdate(bool bZUpdate) { if( g_curRomInfo.bForceDepthBuffer ) bZUpdate = TRUE; if( bZUpdate ) { //glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); OPENGL_CHECK_ERRORS; } else { glDepthMask(GL_FALSE); OPENGL_CHECK_ERRORS; } } void OGLRender::ApplyZBias(int bias) { static int old_bias; float f1 = bias > 0 ? -3.0f : 0.0f; // z offset = -3.0 * max(abs(dz/dx),abs(dz/dy)) per pixel delta z slope float f2 = bias > 0 ? -3.0f : 0.0f; // z offset += -3.0 * 1 bit if (bias == old_bias) return; old_bias = bias; if (bias > 0) { glEnable(GL_POLYGON_OFFSET_FILL); // enable z offsets OPENGL_CHECK_ERRORS; } else { glDisable(GL_POLYGON_OFFSET_FILL); // disable z offsets OPENGL_CHECK_ERRORS; } glPolygonOffset(f1, f2); // set bias functions OPENGL_CHECK_ERRORS; } void OGLRender::SetZBias(int bias) { #if defined(DEBUGGER) if( pauseAtNext == true ) DebuggerAppendMsg("Set zbias = %d", bias); #endif // set member variable and apply the setting in opengl m_dwZBias = bias; ApplyZBias(bias); } void OGLRender::SetAlphaRef(uint32_t dwAlpha) { if (m_dwAlpha != dwAlpha) { m_dwAlpha = dwAlpha; } } void OGLRender::ForceAlphaRef(uint32_t dwAlpha) { m_dwAlpha = dwAlpha; } void OGLRender::SetFillMode(FillMode mode) { } void OGLRender::SetCullMode(bool bCullFront, bool bCullBack) { CRender::SetCullMode(bCullFront, bCullBack); if( bCullFront && bCullBack ) { glCullFace(GL_FRONT_AND_BACK); OPENGL_CHECK_ERRORS; glEnable(GL_CULL_FACE); OPENGL_CHECK_ERRORS; } else if( bCullFront ) { glCullFace(GL_FRONT); OPENGL_CHECK_ERRORS; glEnable(GL_CULL_FACE); OPENGL_CHECK_ERRORS; } else if( bCullBack ) { glCullFace(GL_BACK); OPENGL_CHECK_ERRORS; glEnable(GL_CULL_FACE); OPENGL_CHECK_ERRORS; } else { glDisable(GL_CULL_FACE); OPENGL_CHECK_ERRORS; } } bool OGLRender::SetCurrentTexture(int tile, CTexture *handler,uint32_t dwTileWidth, uint32_t dwTileHeight, TxtrCacheEntry *pTextureEntry) { RenderTexture &texture = g_textures[tile]; texture.pTextureEntry = pTextureEntry; if( handler!= NULL && texture.m_lpsTexturePtr != handler->GetTexture() ) { texture.m_pCTexture = handler; texture.m_lpsTexturePtr = handler->GetTexture(); texture.m_dwTileWidth = dwTileWidth; texture.m_dwTileHeight = dwTileHeight; if( handler->m_bIsEnhancedTexture ) { texture.m_fTexWidth = (float)pTextureEntry->pTexture->m_dwCreatedTextureWidth; texture.m_fTexHeight = (float)pTextureEntry->pTexture->m_dwCreatedTextureHeight; } else { texture.m_fTexWidth = (float)handler->m_dwCreatedTextureWidth; texture.m_fTexHeight = (float)handler->m_dwCreatedTextureHeight; } } return true; } bool OGLRender::SetCurrentTexture(int tile, TxtrCacheEntry *pEntry) { if (pEntry != NULL && pEntry->pTexture != NULL) { SetCurrentTexture( tile, pEntry->pTexture, pEntry->ti.WidthToCreate, pEntry->ti.HeightToCreate, pEntry); return true; } else { SetCurrentTexture( tile, NULL, 64, 64, NULL ); return false; } return true; } void OGLRender::SetAddressUAllStages(uint32_t dwTile, TextureUVFlag dwFlag) { SetTextureUFlag(dwFlag, dwTile); } void OGLRender::SetAddressVAllStages(uint32_t dwTile, TextureUVFlag dwFlag) { SetTextureVFlag(dwFlag, dwTile); } void OGLRender::SetTexWrapS(int unitno,GLuint flag) { static GLuint mflag; static GLuint mtex; #ifdef DEBUGGER if( unitno != 0 ) { DebuggerAppendMsg("Check me, unitno != 0 in base ogl"); } #endif if( m_curBoundTex[0] != mtex || mflag != flag ) { mtex = m_curBoundTex[0]; mflag = flag; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, flag); OPENGL_CHECK_ERRORS; } } void OGLRender::SetTexWrapT(int unitno,GLuint flag) { static GLuint mflag; static GLuint mtex; if( m_curBoundTex[0] != mtex || mflag != flag ) { mtex = m_curBoundTex[0]; mflag = flag; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, flag); OPENGL_CHECK_ERRORS; } } void OGLRender::SetTextureUFlag(TextureUVFlag dwFlag, uint32_t dwTile) { TileUFlags[dwTile] = dwFlag; if( dwTile == gRSP.curTile ) // For basic OGL, only support the 1st texel { COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture; if( pTexture ) { EnableTexUnit(0, true); BindTexture(pTexture->m_dwTextureName, 0); } SetTexWrapS(0, OGLXUVFlagMaps[dwFlag].realFlag); } } void OGLRender::SetTextureVFlag(TextureUVFlag dwFlag, uint32_t dwTile) { TileVFlags[dwTile] = dwFlag; if( dwTile == gRSP.curTile ) // For basic OGL, only support the 1st texel { COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture; if( pTexture ) { EnableTexUnit(0, true); BindTexture(pTexture->m_dwTextureName, 0); } SetTexWrapT(0, OGLXUVFlagMaps[dwFlag].realFlag); } } // Basic render drawing functions bool OGLRender::RenderTexRect() { glViewportWrapper(0, 0, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight, true); OPENGL_CHECK_ERRORS; GLboolean cullface = glIsEnabled(GL_CULL_FACE); glDisable(GL_CULL_FACE); OPENGL_CHECK_ERRORS; float depth = -(g_texRectTVtx[3].z*2-1); GLfloat colour[] = { g_texRectTVtx[3].r, g_texRectTVtx[3].g, g_texRectTVtx[3].b, g_texRectTVtx[3].a, g_texRectTVtx[2].r, g_texRectTVtx[2].g, g_texRectTVtx[2].b, g_texRectTVtx[2].a, g_texRectTVtx[1].r, g_texRectTVtx[1].g, g_texRectTVtx[1].b, g_texRectTVtx[1].a, g_texRectTVtx[0].r, g_texRectTVtx[0].g, g_texRectTVtx[0].b, g_texRectTVtx[0].a }; GLfloat tex[] = { g_texRectTVtx[3].tcord[0].u,g_texRectTVtx[3].tcord[0].v, g_texRectTVtx[2].tcord[0].u,g_texRectTVtx[2].tcord[0].v, g_texRectTVtx[1].tcord[0].u,g_texRectTVtx[1].tcord[0].v, g_texRectTVtx[0].tcord[0].u,g_texRectTVtx[0].tcord[0].v }; GLfloat tex2[] = { g_texRectTVtx[3].tcord[1].u,g_texRectTVtx[3].tcord[1].v, g_texRectTVtx[2].tcord[1].u,g_texRectTVtx[2].tcord[1].v, g_texRectTVtx[1].tcord[1].u,g_texRectTVtx[1].tcord[1].v, g_texRectTVtx[0].tcord[1].u,g_texRectTVtx[0].tcord[1].v }; float w = windowSetting.uDisplayWidth / 2.0f, h = windowSetting.uDisplayHeight / 2.0f, inv = 1.0f; GLfloat vertices[] = { -inv + g_texRectTVtx[3].x / w, inv - g_texRectTVtx[3].y / h, depth, 1, -inv + g_texRectTVtx[2].x / w, inv - g_texRectTVtx[2].y / h, depth, 1, -inv + g_texRectTVtx[1].x / w, inv - g_texRectTVtx[1].y / h, depth, 1, -inv + g_texRectTVtx[0].x / w, inv - g_texRectTVtx[0].y / h, depth, 1 }; glVertexAttribPointer(VS_COLOR, 4, GL_FLOAT,GL_TRUE, 0, &colour ); glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,0,&vertices); glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, 0, &tex); glVertexAttribPointer(VS_TEXCOORD1,2,GL_FLOAT,GL_FALSE, 0, &tex2); OPENGL_CHECK_ERRORS; glDrawArrays(GL_TRIANGLE_FAN,0,4); OPENGL_CHECK_ERRORS; //Restore old pointers glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8_t)*4, &(g_oglVtxColors[0][0]) ); glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0])); glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u)); glVertexAttribPointer(VS_TEXCOORD1,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[1].u)); if( cullface ) glEnable(GL_CULL_FACE); OPENGL_CHECK_ERRORS; return true; } bool OGLRender::RenderFillRect(uint32_t dwColor, float depth) { float a = (dwColor>>24)/255.0f; float r = ((dwColor>>16)&0xFF)/255.0f; float g = ((dwColor>>8)&0xFF)/255.0f; float b = (dwColor&0xFF)/255.0f; glViewportWrapper(0, 0, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight, true); OPENGL_CHECK_ERRORS; GLboolean cullface = glIsEnabled(GL_CULL_FACE); glDisable(GL_CULL_FACE); OPENGL_CHECK_ERRORS; GLfloat colour[] = { r,g,b,a, r,g,b,a, r,g,b,a, r,g,b,a}; float w = windowSetting.uDisplayWidth / 2.0f, h = windowSetting.uDisplayHeight / 2.0f, inv = 1.0f; GLfloat vertices[] = { -inv + m_fillRectVtx[0].x / w, inv - m_fillRectVtx[1].y / h, depth, 1, -inv + m_fillRectVtx[1].x / w, inv - m_fillRectVtx[1].y / h, depth, 1, -inv + m_fillRectVtx[1].x / w, inv - m_fillRectVtx[0].y / h, depth, 1, -inv + m_fillRectVtx[0].x / w, inv - m_fillRectVtx[0].y / h, depth, 1 }; glVertexAttribPointer(VS_COLOR, 4, GL_FLOAT,GL_FALSE, 0, &colour ); glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,0,&vertices); glDisableVertexAttribArray(VS_TEXCOORD0); glDisableVertexAttribArray(VS_TEXCOORD1); OPENGL_CHECK_ERRORS; glDrawArrays(GL_TRIANGLE_FAN,0,4); OPENGL_CHECK_ERRORS; //Restore old pointers glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8_t)*4, &(g_oglVtxColors[0][0]) ); glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0])); glEnableVertexAttribArray(VS_TEXCOORD0); glEnableVertexAttribArray(VS_TEXCOORD1); if( cullface ) glEnable(GL_CULL_FACE); OPENGL_CHECK_ERRORS; return true; } bool OGLRender::RenderLine3D() { return true; } extern FiddledVtx * g_pVtxBase; // This is so weird that I can not do vertex transform by myself. I have to use // OpenGL internal transform bool OGLRender::RenderFlushTris() { if( !gRDP.bFogEnableInBlender && gRSP.bFogEnabled ) { TurnFogOnOff(false); } ApplyZBias(m_dwZBias); // set the bias factors glViewportWrapper(windowSetting.vpLeftW, windowSetting.uDisplayHeight - windowSetting.vpTopW - windowSetting.vpHeightW, windowSetting.vpWidthW, windowSetting.vpHeightW, false); OPENGL_CHECK_ERRORS; //if options.bOGLVertexClipper == FALSE ) { glDrawElements( GL_TRIANGLES, gRSP.numVertices, GL_UNSIGNED_SHORT, g_vtxIndex ); OPENGL_CHECK_ERRORS; } if( !gRDP.bFogEnableInBlender && gRSP.bFogEnabled ) { TurnFogOnOff(true); } return true; } void OGLRender::DrawSimple2DTexture(float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, COLOR dif, COLOR spe, float z, float rhw) { if( status.bVIOriginIsUpdated == true && currentRomOptions.screenUpdateSetting==SCREEN_UPDATE_AT_1ST_PRIMITIVE ) { status.bVIOriginIsUpdated=false; CGraphicsContext::Get()->UpdateFrame(false); DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_SET_CIMG,{DebuggerAppendMsg("Screen Update at 1st Simple2DTexture");}); } StartDrawSimple2DTexture(x0, y0, x1, y1, u0, v0, u1, v1, dif, spe, z, rhw); GLboolean cullface = glIsEnabled(GL_CULL_FACE); glDisable(GL_CULL_FACE); OPENGL_CHECK_ERRORS; glViewportWrapper(0, 0, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight, true); OPENGL_CHECK_ERRORS; float a = (g_texRectTVtx[0].dcDiffuse >>24)/255.0f; float r = ((g_texRectTVtx[0].dcDiffuse>>16)&0xFF)/255.0f; float g = ((g_texRectTVtx[0].dcDiffuse>>8)&0xFF)/255.0f; float b = (g_texRectTVtx[0].dcDiffuse&0xFF)/255.0f; GLfloat colour[] = { r,g,b,a, r,g,b,a, r,g,b,a, r,g,b,a, r,g,b,a, r,g,b,a }; GLfloat tex[] = { g_texRectTVtx[0].tcord[0].u,g_texRectTVtx[0].tcord[0].v, g_texRectTVtx[1].tcord[0].u,g_texRectTVtx[1].tcord[0].v, g_texRectTVtx[2].tcord[0].u,g_texRectTVtx[2].tcord[0].v, g_texRectTVtx[0].tcord[0].u,g_texRectTVtx[0].tcord[0].v, g_texRectTVtx[2].tcord[0].u,g_texRectTVtx[2].tcord[0].v, g_texRectTVtx[3].tcord[0].u,g_texRectTVtx[3].tcord[0].v, }; GLfloat tex2[] = { g_texRectTVtx[0].tcord[1].u,g_texRectTVtx[0].tcord[1].v, g_texRectTVtx[1].tcord[1].u,g_texRectTVtx[1].tcord[1].v, g_texRectTVtx[2].tcord[1].u,g_texRectTVtx[2].tcord[1].v, g_texRectTVtx[0].tcord[1].u,g_texRectTVtx[0].tcord[1].v, g_texRectTVtx[2].tcord[1].u,g_texRectTVtx[2].tcord[1].v, g_texRectTVtx[3].tcord[1].u,g_texRectTVtx[3].tcord[1].v, }; float w = windowSetting.uDisplayWidth / 2.0f, h = windowSetting.uDisplayHeight / 2.0f, inv = 1.0f; GLfloat vertices[] = { -inv + g_texRectTVtx[0].x/ w, inv - g_texRectTVtx[0].y/ h, -g_texRectTVtx[0].z,1, -inv + g_texRectTVtx[1].x/ w, inv - g_texRectTVtx[1].y/ h, -g_texRectTVtx[1].z,1, -inv + g_texRectTVtx[2].x/ w, inv - g_texRectTVtx[2].y/ h, -g_texRectTVtx[2].z,1, -inv + g_texRectTVtx[0].x/ w, inv - g_texRectTVtx[0].y/ h, -g_texRectTVtx[0].z,1, -inv + g_texRectTVtx[2].x/ w, inv - g_texRectTVtx[2].y/ h, -g_texRectTVtx[2].z,1, -inv + g_texRectTVtx[3].x/ w, inv - g_texRectTVtx[3].y/ h, -g_texRectTVtx[3].z,1 }; glVertexAttribPointer(VS_COLOR, 4, GL_FLOAT,GL_FALSE, 0, &colour ); glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,0,&vertices); glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, 0, &tex); glVertexAttribPointer(VS_TEXCOORD1,2,GL_FLOAT,GL_FALSE, 0, &tex2); OPENGL_CHECK_ERRORS; glDrawArrays(GL_TRIANGLES,0,6); OPENGL_CHECK_ERRORS; //Restore old pointers glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8_t)*4, &(g_oglVtxColors[0][0]) ); glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0])); glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u)); glVertexAttribPointer(VS_TEXCOORD1,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[1].u)); if( cullface ) glEnable(GL_CULL_FACE); OPENGL_CHECK_ERRORS; } void OGLRender::DrawSimpleRect(int nX0, int nY0, int nX1, int nY1, uint32_t dwColor, float depth, float rhw) { StartDrawSimpleRect(nX0, nY0, nX1, nY1, dwColor, depth, rhw); GLboolean cullface = glIsEnabled(GL_CULL_FACE); glDisable(GL_CULL_FACE); OPENGL_CHECK_ERRORS; float a = (dwColor>>24)/255.0f; float r = ((dwColor>>16)&0xFF)/255.0f; float g = ((dwColor>>8)&0xFF)/255.0f; float b = (dwColor&0xFF)/255.0f; GLfloat colour[] = { r,g,b,a, r,g,b,a, r,g,b,a, r,g,b,a}; float w = windowSetting.uDisplayWidth / 2.0f, h = windowSetting.uDisplayHeight / 2.0f, inv = 1.0f; GLfloat vertices[] = { -inv + m_simpleRectVtx[1].x / w, inv - m_simpleRectVtx[0].y / h, -depth, 1, -inv + m_simpleRectVtx[1].x / w, inv - m_simpleRectVtx[1].y / h, -depth, 1, -inv + m_simpleRectVtx[0].x / w, inv - m_simpleRectVtx[1].y / h, -depth, 1, -inv + m_simpleRectVtx[0].x / w, inv - m_simpleRectVtx[0].y / h, -depth, 1 }; glVertexAttribPointer(VS_COLOR, 4, GL_FLOAT,GL_FALSE, 0, &colour ); glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,0,&vertices); glDisableVertexAttribArray(VS_TEXCOORD0); glDisableVertexAttribArray(VS_TEXCOORD1); OPENGL_CHECK_ERRORS; glDrawArrays(GL_TRIANGLE_FAN,0,4); OPENGL_CHECK_ERRORS; //Restore old pointers glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8_t)*4, &(g_oglVtxColors[0][0]) ); glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0])); glEnableVertexAttribArray(VS_TEXCOORD0); glEnableVertexAttribArray(VS_TEXCOORD1); if( cullface ) glEnable(GL_CULL_FACE); OPENGL_CHECK_ERRORS; } #if 0 void OGLRender::InitCombinerBlenderForSimpleRectDraw(uint32_t tile) { //glEnable(GL_CULL_FACE); EnableTexUnit(0, false); OPENGL_CHECK_ERRORS; glEnable(GL_BLEND); OPENGL_CHECK_ERRORS; glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); OPENGL_CHECK_ERRORS; //glEnable(GL_ALPHA_TEST); } #endif COLOR OGLRender::PostProcessDiffuseColor(COLOR curDiffuseColor) { uint32_t color = curDiffuseColor; uint32_t colorflag = m_pColorCombiner->m_pDecodedMux->m_dwShadeColorChannelFlag; uint32_t alphaflag = m_pColorCombiner->m_pDecodedMux->m_dwShadeAlphaChannelFlag; if( colorflag+alphaflag != MUX_0 ) { if( (colorflag & 0xFFFFFF00) == 0 && (alphaflag & 0xFFFFFF00) == 0 ) { color = (m_pColorCombiner->GetConstFactor(colorflag, alphaflag, curDiffuseColor)); } else color = (CalculateConstFactor(colorflag, alphaflag, curDiffuseColor)); } //return (color<<8)|(color>>24); return color; } COLOR OGLRender::PostProcessSpecularColor() { return 0; } void OGLRender::SetViewportRender() { glViewportWrapper(windowSetting.vpLeftW, windowSetting.uDisplayHeight - windowSetting.vpTopW - windowSetting.vpHeightW, windowSetting.vpWidthW, windowSetting.vpHeightW, true); OPENGL_CHECK_ERRORS; } void OGLRender::RenderReset() { CRender::RenderReset(); glMatrixMode(GL_PROJECTION); OPENGL_CHECK_ERRORS; glLoadIdentity(); OPENGL_CHECK_ERRORS; glOrtho(0, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight, 0, -1, 1); OPENGL_CHECK_ERRORS; // position viewer glMatrixMode(GL_MODELVIEW); OPENGL_CHECK_ERRORS; glLoadIdentity(); OPENGL_CHECK_ERRORS; } void OGLRender::SetAlphaTestEnable(bool bAlphaTestEnable) { #ifdef DEBUGGER if( bAlphaTestEnable && debuggerEnableAlphaTest ) #else COGL_FragmentProgramCombiner* frag = (COGL_FragmentProgramCombiner*)m_pColorCombiner; frag->SetAlphaTestState(bAlphaTestEnable); #endif } void OGLRender::BindTexture(GLuint texture, int unitno) { #ifdef DEBUGGER if( unitno != 0 ) { DebuggerAppendMsg("Check me, base ogl bind texture, unit no != 0"); } #endif if( m_curBoundTex[0] != texture ) { glBindTexture(GL_TEXTURE_2D,texture); OPENGL_CHECK_ERRORS; m_curBoundTex[0] = texture; } } void OGLRender::DisBindTexture(GLuint texture, int unitno) { //EnableTexUnit(0, false); //glBindTexture(GL_TEXTURE_2D, 0); //Not to bind any texture } void OGLRender::EnableTexUnit(int unitno, bool flag) { #ifdef DEBUGGER if( unitno != 0 ) { DebuggerAppendMsg("Check me, in the base OpenGL render, unitno!=0"); } #endif if( m_texUnitEnabled[0] != flag ) { m_texUnitEnabled[0] = flag; } } void OGLRender::TexCoord2f(float u, float v) { glTexCoord2f(u, v); } void OGLRender::TexCoord(TLITVERTEX &vtxInfo) { glTexCoord2f(vtxInfo.tcord[0].u, vtxInfo.tcord[0].v); } void OGLRender::UpdateScissor() { if( options.bEnableHacks && g_CI.dwWidth == 0x200 && gRDP.scissor.right == 0x200 && g_CI.dwWidth>(*gfx_info.VI_WIDTH_REG & 0xFFF) ) { // Hack for RE2 uint32_t width = *gfx_info.VI_WIDTH_REG & 0xFFF; uint32_t height = (gRDP.scissor.right*gRDP.scissor.bottom)/width; glEnable(GL_SCISSOR_TEST); OPENGL_CHECK_ERRORS; glScissor(0, int(height * windowSetting.fMultY), int(width*windowSetting.fMultX), int(height*windowSetting.fMultY) ); OPENGL_CHECK_ERRORS; } else { UpdateScissorWithClipRatio(); } } void OGLRender::ApplyRDPScissor(bool force) { if( !force && status.curScissor == RDP_SCISSOR ) return; if( options.bEnableHacks && g_CI.dwWidth == 0x200 && gRDP.scissor.right == 0x200 && g_CI.dwWidth>(*gfx_info.VI_WIDTH_REG & 0xFFF) ) { // Hack for RE2 uint32_t width = *gfx_info.VI_WIDTH_REG & 0xFFF; uint32_t height = (gRDP.scissor.right*gRDP.scissor.bottom)/width; glEnable(GL_SCISSOR_TEST); OPENGL_CHECK_ERRORS; glScissor(0, int(height * windowSetting.fMultY), int(width*windowSetting.fMultX), int(height*windowSetting.fMultY) ); OPENGL_CHECK_ERRORS; } else { glScissor(int(gRDP.scissor.left*windowSetting.fMultX), int((windowSetting.uViHeight-gRDP.scissor.bottom)*windowSetting.fMultY), int((gRDP.scissor.right-gRDP.scissor.left)*windowSetting.fMultX), int((gRDP.scissor.bottom-gRDP.scissor.top)*windowSetting.fMultY )); OPENGL_CHECK_ERRORS; } status.curScissor = RDP_SCISSOR; } void OGLRender::ApplyScissorWithClipRatio(bool force) { if( !force && status.curScissor == RSP_SCISSOR ) return; glEnable(GL_SCISSOR_TEST); OPENGL_CHECK_ERRORS; glScissor(windowSetting.clipping.left, int((windowSetting.uViHeight-gRSP.real_clip_scissor_bottom)*windowSetting.fMultY), windowSetting.clipping.width, windowSetting.clipping.height); OPENGL_CHECK_ERRORS; status.curScissor = RSP_SCISSOR; } void OGLRender::SetFogMinMax(float fMin, float fMax) { } void OGLRender::TurnFogOnOff(bool flag) { ((COGL_FragmentProgramCombiner*)m_pColorCombiner)->SetFogState(flag); OPENGL_CHECK_ERRORS; } void OGLRender::SetFogEnable(bool bEnable) { DEBUGGER_IF_DUMP( (gRSP.bFogEnabled != (bEnable==TRUE) && logFog ), TRACE1("Set Fog %s", bEnable? "enable":"disable")); gRSP.bFogEnabled = bEnable; // If force fog if(options.fogMethod == 2) { gRSP.bFogEnabled = true; } ((COGL_FragmentProgramCombiner*)m_pColorCombiner)->SetFogState(gRSP.bFogEnabled); OPENGL_CHECK_ERRORS; } void OGLRender::SetFogColor(uint32_t r, uint32_t g, uint32_t b, uint32_t a) { gRDP.fogColor = COLOR_RGBA(r, g, b, a); gRDP.fvFogColor[0] = r/255.0f; //r gRDP.fvFogColor[1] = g/255.0f; //g gRDP.fvFogColor[2] = b/255.0f; //b gRDP.fvFogColor[3] = a/255.0f; //a OPENGL_CHECK_ERRORS; } void OGLRender::DisableMultiTexture() { pglActiveTexture(GL_TEXTURE1); OPENGL_CHECK_ERRORS; EnableTexUnit(1, false); pglActiveTexture(GL_TEXTURE0); OPENGL_CHECK_ERRORS; EnableTexUnit(0, false); pglActiveTexture(GL_TEXTURE0); OPENGL_CHECK_ERRORS; EnableTexUnit(0, true); } void OGLRender::EndRendering(void) { if( CRender::gRenderReferenceCount > 0 ) CRender::gRenderReferenceCount--; } void OGLRender::glViewportWrapper(GLint x, GLint y, GLsizei width, GLsizei height, bool flag) { static GLint mx=0,my=0; static GLsizei m_width=0, m_height=0; static bool mflag=true; if( x!=mx || y!=my || width!=m_width || height!=m_height || mflag!=flag) { mx=x; my=y; m_width=width; m_height=height; mflag=flag; glMatrixMode(GL_PROJECTION); OPENGL_CHECK_ERRORS; glLoadIdentity(); OPENGL_CHECK_ERRORS; if( flag ) glOrtho(0, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight, 0, -1, 1); OPENGL_CHECK_ERRORS; glViewport(x,y,width,height); OPENGL_CHECK_ERRORS; } } mupen64plus-core/src/r4300/hacktarux_dynarec/gbc.c000664 001750 001750 00000017231 12655644434 023010 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - gbc.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2007 Richard Goedeken (Richard42) * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include "assemble.h" #include "interpret.h" #include "r4300/cached_interp.h" #include "r4300/recomph.h" #include "r4300/r4300.h" #include "r4300/ops.h" #include "r4300/cp1_private.h" static void genbc1f_test(void) { #if defined(__x86_64__) test_m32rel_imm32((uint32_t*)&FCR31, 0x800000); sete_m8rel((uint8_t *) &branch_taken); #else test_m32_imm32((uint32_t*)&FCR31, 0x800000); jne_rj(12); mov_m32_imm32((uint32_t*)(&branch_taken), 1); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((uint32_t*)(&branch_taken), 0); // 10 #endif } static void genbc1t_test(void) { #if defined(__x86_64__) test_m32rel_imm32((uint32_t*)&FCR31, 0x800000); setne_m8rel((uint8_t *) &branch_taken); #else test_m32_imm32((uint32_t*)&FCR31, 0x800000); je_rj(12); mov_m32_imm32((uint32_t*)(&branch_taken), 1); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((uint32_t*)(&branch_taken), 0); // 10 #endif } void genbc1f(void) { #ifdef INTERPRET_BC1F gencallinterp((native_type)cached_interpreter_table.BC1F, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BC1F, 1); return; } gencheck_cop1_unusable(); genbc1f_test(); gendelayslot(); gentest(); #endif } void genbc1f_out(void) { #ifdef INTERPRET_BC1F_OUT gencallinterp((native_type)cached_interpreter_table.BC1F_OUT, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BC1F_OUT, 1); return; } gencheck_cop1_unusable(); genbc1f_test(); gendelayslot(); gentest_out(); #endif } void genbc1f_idle(void) { #ifdef INTERPRET_BC1F_IDLE gencallinterp((native_type)cached_interpreter_table.BC1F_IDLE, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BC1F_IDLE, 1); return; } gencheck_cop1_unusable(); genbc1f_test(); gentest_idle(); genbc1f(); #endif } void genbc1t(void) { #ifdef INTERPRET_BC1T gencallinterp((native_type)cached_interpreter_table.BC1T, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BC1T, 1); return; } gencheck_cop1_unusable(); genbc1t_test(); gendelayslot(); gentest(); #endif } void genbc1t_out(void) { #ifdef INTERPRET_BC1T_OUT gencallinterp((native_type)cached_interpreter_table.BC1T_OUT, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BC1T_OUT, 1); return; } gencheck_cop1_unusable(); genbc1t_test(); gendelayslot(); gentest_out(); #endif } void genbc1t_idle(void) { #ifdef INTERPRET_BC1T_IDLE gencallinterp((native_type)cached_interpreter_table.BC1T_IDLE, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BC1T_IDLE, 1); return; } gencheck_cop1_unusable(); genbc1t_test(); gentest_idle(); genbc1t(); #endif } void genbc1fl(void) { #ifdef INTERPRET_BC1FL gencallinterp((native_type)cached_interpreter_table.BC1FL, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BC1FL, 1); return; } gencheck_cop1_unusable(); genbc1f_test(); free_all_registers(); gentestl(); #endif } void genbc1fl_out(void) { #ifdef INTERPRET_BC1FL_OUT gencallinterp((native_type)cached_interpreter_table.BC1FL_OUT, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BC1FL_OUT, 1); return; } gencheck_cop1_unusable(); genbc1f_test(); free_all_registers(); gentestl_out(); #endif } void genbc1fl_idle(void) { #ifdef INTERPRET_BC1FL_IDLE gencallinterp((native_type)cached_interpreter_table.BC1FL_IDLE, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BC1FL_IDLE, 1); return; } gencheck_cop1_unusable(); genbc1f_test(); gentest_idle(); genbc1fl(); #endif } void genbc1tl(void) { #ifdef INTERPRET_BC1TL gencallinterp((native_type)cached_interpreter_table.BC1TL, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BC1TL, 1); return; } gencheck_cop1_unusable(); genbc1t_test(); free_all_registers(); gentestl(); #endif } void genbc1tl_out(void) { #ifdef INTERPRET_BC1TL_OUT gencallinterp((native_type)cached_interpreter_table.BC1TL_OUT, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BC1TL_OUT, 1); return; } gencheck_cop1_unusable(); genbc1t_test(); free_all_registers(); gentestl_out(); #endif } void genbc1tl_idle(void) { #ifdef INTERPRET_BC1TL_IDLE gencallinterp((native_type)cached_interpreter_table.BC1TL_IDLE, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((native_type)cached_interpreter_table.BC1TL_IDLE, 1); return; } gencheck_cop1_unusable(); genbc1t_test(); gentest_idle(); genbc1tl(); #endif } mupen64plus-video-gliden64/licenses/Glow/LICENSE000664 001750 001750 00000002540 12655644434 022362 0ustar00sergiosergio000000 000000 Nutty Software Open WebGL Framework Copyright (C) 2012 Nathaniel Meyer Nutty Software, http://www.nutty.ca All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 1. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 2. Redistributions in binary or minimized form must reproduce the above copyright notice and this list of conditions in the documentation and/or other materials provided with the distribution. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.mupen64plus-video-gliden64/000700 001750 001750 00000000000 12656647145 016626 5ustar00sergiosergio000000 000000 gles2rice/src/Blender.h000664 001750 001750 00000003340 12655644434 016111 0ustar00sergiosergio000000 000000 /* Copyright (C) 2003 Rice1964 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _BLENDER_H_ #define _BLENDER_H_ #include "typedefs.h" class CRender; class CBlender { public: virtual ~CBlender() {} virtual void InitBlenderMode(void); virtual void NormalAlphaBlender(void)=0; virtual void DisableAlphaBlender(void)=0; virtual void BlendFunc(uint32_t srcFunc, uint32_t desFunc)=0; virtual void Enable()=0; virtual void Disable()=0; protected: CBlender(CRender *pRender) : m_pRender(pRender) {} CRender *m_pRender; }; typedef enum _BLEND { BLEND_ZERO = 1, BLEND_ONE = 2, BLEND_SRCCOLOR = 3, BLEND_INVSRCCOLOR = 4, BLEND_SRCALPHA = 5, BLEND_INVSRCALPHA = 6, BLEND_DESTALPHA = 7, BLEND_INVDESTALPHA = 8, BLEND_DESTCOLOR = 9, BLEND_INVDESTCOLOR = 10, BLEND_SRCALPHASAT = 11, BLEND_BOTHSRCALPHA = 12, BLEND_BOTHINVSRCALPHA = 13, BLEND_BLENDFACTOR = 14, BLEND_INVBLENDFACTOR = 15, BLEND_FORCE_DWORD = 0x7fffffff } BLEND; #endif gles2rice/src/Video.cpp000664 001750 001750 00000062667 12655644434 016160 0ustar00sergiosergio000000 000000 /* Copyright (C) 2002 Rice1964 Copyright (C) 2009-2011 Richard Goedeken This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include "osal_opengl.h" #define M64P_PLUGIN_PROTOTYPES 1 #include "m64p_types.h" #include "m64p_common.h" #include "m64p_plugin.h" #include "Config.h" #include "Debugger.h" #include "DeviceBuilder.h" #include "FrameBuffer.h" #include "GraphicsContext.h" #include "Render.h" #include "RSP_Parser.h" #include "TextureManager.h" #include "Video.h" #include "version.h" //======================================================= // local variables static void (*l_DebugCallback)(void *, int, const char *) = NULL; static void *l_DebugCallContext = NULL; static int l_PluginInit = 0; //======================================================= // global variables PluginStatus status; unsigned int g_dwRamSize = 0x400000; M64P_RECT frameWriteByCPURect; std::vector frameWriteByCPURects; M64P_RECT frameWriteByCPURectArray[20][20]; bool frameWriteByCPURectFlag[20][20]; std::vector frameWriteRecord; void (*renderCallback)(int) = NULL; #ifdef __LIBRETRO__ // Prefix API #define VIDEO_TAG(X) rice##X #define ReadScreen2 VIDEO_TAG(ReadScreen2) #define PluginStartup VIDEO_TAG(PluginStartup) #define PluginShutdown VIDEO_TAG(PluginShutdown) #define PluginGetVersion VIDEO_TAG(PluginGetVersion) #define CaptureScreen VIDEO_TAG(CaptureScreen) #define ChangeWindow VIDEO_TAG(ChangeWindow) #define CloseDLL VIDEO_TAG(CloseDLL) #define DllTest VIDEO_TAG(DllTest) #define DrawScreen VIDEO_TAG(DrawScreen) #define GetDllInfo VIDEO_TAG(GetDllInfo) #define InitiateGFX VIDEO_TAG(InitiateGFX) #define MoveScreen VIDEO_TAG(MoveScreen) #define RomClosed VIDEO_TAG(RomClosed) #define RomOpen VIDEO_TAG(RomOpen) #define ShowCFB VIDEO_TAG(ShowCFB) #define SetRenderingCallback VIDEO_TAG(SetRenderingCallback) #define UpdateScreen VIDEO_TAG(UpdateScreen) #define ViStatusChanged VIDEO_TAG(ViStatusChanged) #define ViWidthChanged VIDEO_TAG(ViWidthChanged) #define ReadScreen VIDEO_TAG(ReadScreen) #define FBGetFrameBufferInfo VIDEO_TAG(FBGetFrameBufferInfo) #define FBRead VIDEO_TAG(FBRead) #define FBWrite VIDEO_TAG(FBWrite) #define ProcessDList VIDEO_TAG(ProcessDList) #define ProcessRDPList VIDEO_TAG(ProcessRDPList) #define ResizeVideoOutput VIDEO_TAG(ResizeVideoOutput) #endif //--------------------------------------------------------------------------------------- // Forward function declarations extern "C" EXPORT void CALL RomClosed(void); //--------------------------------------------------------------------------------------- static void ResizeStep2(void) { // Delete all OpenGL textures gTextureManager.CleanUp(); RDP_Cleanup(); // delete our opengl renderer CDeviceBuilder::GetBuilder()->DeleteRender(); // call video extension function with updated width, height (this creates a new OpenGL context) windowSetting.uDisplayWidth = status.gNewResizeWidth; windowSetting.uDisplayHeight = status.gNewResizeHeight; //CoreVideo_ResizeWindow(windowSetting.uDisplayWidth, windowSetting.uDisplayHeight); // re-initialize our OpenGL graphics context state bool res = CGraphicsContext::Get()->ResizeInitialize(windowSetting.uDisplayWidth, windowSetting.uDisplayHeight); if (res) { // re-create the OpenGL renderer CDeviceBuilder::GetBuilder()->CreateRender(); CRender::GetRender()->Initialize(); DLParser_Init(); } status.ToResize = false; } static void UpdateScreenStep2 (void) { status.bVIOriginIsUpdated = false; if (status.ToResize && status.gDlistCount > 0) { ResizeStep2(); return; } if( status.bHandleN64RenderTexture ) g_pFrameBufferManager->CloseRenderTexture(true); g_pFrameBufferManager->SetAddrBeDisplayed(*gfx_info.VI_ORIGIN_REG); if( status.gDlistCount == 0 ) { // CPU frame buffer update uint32_t width = *gfx_info.VI_WIDTH_REG; if( (*gfx_info.VI_ORIGIN_REG & (g_dwRamSize-1) ) > width*2 && *gfx_info.VI_H_START_REG != 0 && width != 0 ) { SetVIScales(); CRender::GetRender()->DrawFrameBuffer(true, 0, 0, 0, 0); CGraphicsContext::Get()->UpdateFrame(false); } return; } TXTRBUF_DETAIL_DUMP(TRACE1("VI ORIG is updated to %08X", *gfx_info.VI_ORIGIN_REG)); if( currentRomOptions.screenUpdateSetting == SCREEN_UPDATE_AT_VI_UPDATE ) { CGraphicsContext::Get()->UpdateFrame(false); DEBUGGER_IF_DUMP( pauseAtNext, TRACE1("Update Screen: VIORIG=%08X", *gfx_info.VI_ORIGIN_REG)); DEBUGGER_PAUSE_COUNT_N_WITHOUT_UPDATE(NEXT_FRAME); DEBUGGER_PAUSE_COUNT_N_WITHOUT_UPDATE(NEXT_SET_CIMG); return; } TXTRBUF_DETAIL_DUMP(TRACE1("VI ORIG is updated to %08X", *gfx_info.VI_ORIGIN_REG)); if( currentRomOptions.screenUpdateSetting == SCREEN_UPDATE_AT_VI_UPDATE_AND_DRAWN ) { if( status.bScreenIsDrawn ) { CGraphicsContext::Get()->UpdateFrame(false); DEBUGGER_IF_DUMP( pauseAtNext, TRACE1("Update Screen: VIORIG=%08X", *gfx_info.VI_ORIGIN_REG)); } else { DEBUGGER_IF_DUMP( pauseAtNext, TRACE1("Skip Screen Update: VIORIG=%08X", *gfx_info.VI_ORIGIN_REG)); } DEBUGGER_PAUSE_COUNT_N_WITHOUT_UPDATE(NEXT_FRAME); DEBUGGER_PAUSE_COUNT_N_WITHOUT_UPDATE(NEXT_SET_CIMG); return; } if( currentRomOptions.screenUpdateSetting==SCREEN_UPDATE_AT_VI_CHANGE ) { if( *gfx_info.VI_ORIGIN_REG != status.curVIOriginReg ) { if( *gfx_info.VI_ORIGIN_REG < status.curDisplayBuffer || *gfx_info.VI_ORIGIN_REG > status.curDisplayBuffer+0x2000 ) { status.curDisplayBuffer = *gfx_info.VI_ORIGIN_REG; status.curVIOriginReg = status.curDisplayBuffer; //status.curRenderBuffer = NULL; CGraphicsContext::Get()->UpdateFrame(false); DEBUGGER_IF_DUMP( pauseAtNext, TRACE1("Update Screen: VIORIG=%08X", *gfx_info.VI_ORIGIN_REG)); DEBUGGER_PAUSE_COUNT_N_WITHOUT_UPDATE(NEXT_FRAME); DEBUGGER_PAUSE_COUNT_N_WITHOUT_UPDATE(NEXT_SET_CIMG); } else { status.curDisplayBuffer = *gfx_info.VI_ORIGIN_REG; status.curVIOriginReg = status.curDisplayBuffer; DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_FRAME, {DebuggerAppendMsg("Skip Screen Update, closed to the display buffer, VIORIG=%08X", *gfx_info.VI_ORIGIN_REG);}); } } else { DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_FRAME, {DebuggerAppendMsg("Skip Screen Update, the same VIORIG=%08X", *gfx_info.VI_ORIGIN_REG);}); } return; } if( currentRomOptions.screenUpdateSetting >= SCREEN_UPDATE_AT_1ST_CI_CHANGE ) { status.bVIOriginIsUpdated=true; DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_FRAME, {DebuggerAppendMsg("VI ORIG is updated to %08X", *gfx_info.VI_ORIGIN_REG);}); return; } DEBUGGER_IF_DUMP( pauseAtNext, TRACE1("VI is updated, No screen update: VIORIG=%08X", *gfx_info.VI_ORIGIN_REG)); DEBUGGER_PAUSE_COUNT_N_WITHOUT_UPDATE(NEXT_FRAME); DEBUGGER_PAUSE_COUNT_N_WITHOUT_UPDATE(NEXT_SET_CIMG); } static void ProcessDListStep2(void) { if( status.toShowCFB ) { CRender::GetRender()->DrawFrameBuffer(true, 0, 0, 0, 0); status.toShowCFB = false; } DLParser_Process((OSTask *)(gfx_info.DMEM + 0x0FC0)); } static bool StartVideo(void) { windowSetting.dps = windowSetting.fps = -1; windowSetting.lastSecDlistCount = windowSetting.lastSecFrameCount = 0xFFFFFFFF; memcpy(&g_curRomInfo.romheader, gfx_info.HEADER, sizeof(ROMHeader)); unsigned char *puc = (unsigned char *) &g_curRomInfo.romheader; unsigned int i; unsigned char temp; for (i = 0; i < sizeof(ROMHeader); i += 4) /* byte-swap the ROM header */ { temp = puc[i]; puc[i] = puc[i+3]; puc[i+3] = temp; temp = puc[i+1]; puc[i+1] = puc[i+2]; puc[i+2] = temp; } ROM_GetRomNameFromHeader(g_curRomInfo.szGameName, &g_curRomInfo.romheader); Ini_GetRomOptions(&g_curRomInfo); char *p = (char *) g_curRomInfo.szGameName + (strlen((char *) g_curRomInfo.szGameName) -1); // -1 to skip null while (p >= (char *) g_curRomInfo.szGameName) { if( *p == ':' || *p == '\\' || *p == '/' ) *p = '-'; p--; } GenerateCurrentRomOptions(); status.dwTvSystem = CountryCodeToTVSystem(g_curRomInfo.romheader.nCountryID); if( status.dwTvSystem == TV_SYSTEM_NTSC ) status.fRatio = 0.75f; else status.fRatio = 9/11.0f;; CDeviceBuilder::GetBuilder()->CreateGraphicsContext(); CGraphicsContext::InitWindowInfo(); bool res = CGraphicsContext::Get()->Initialize(windowSetting.uDisplayWidth, windowSetting.uDisplayHeight); if (!res) { return false; } CDeviceBuilder::GetBuilder()->CreateRender(); CRender::GetRender()->Initialize(); DLParser_Init(); status.bGameIsRunning = true; return true; } static void StopVideo() { status.bGameIsRunning = false; // Kill all textures? gTextureManager.RecycleAllTextures(); gTextureManager.CleanUp(); RDP_Cleanup(); CDeviceBuilder::GetBuilder()->DeleteRender(); CGraphicsContext::Get()->CleanUp(); CDeviceBuilder::GetBuilder()->DeleteGraphicsContext(); windowSetting.dps = windowSetting.fps = -1; windowSetting.lastSecDlistCount = windowSetting.lastSecFrameCount = 0xFFFFFFFF; status.gDlistCount = status.gFrameCount = 0; } //--------------------------------------------------------------------------------------- // Global functions, for use by other source files in this plugin void SetVIScales() { if( g_curRomInfo.VIHeight>0 && g_curRomInfo.VIWidth>0 ) { windowSetting.fViWidth = windowSetting.uViWidth = g_curRomInfo.VIWidth; windowSetting.fViHeight = windowSetting.uViHeight = g_curRomInfo.VIHeight; } else if( g_curRomInfo.UseCIWidthAndRatio && g_CI.dwWidth ) { windowSetting.fViWidth = windowSetting.uViWidth = g_CI.dwWidth; windowSetting.fViHeight = windowSetting.uViHeight = g_curRomInfo.UseCIWidthAndRatio == USE_CI_WIDTH_AND_RATIO_FOR_NTSC ? g_CI.dwWidth/4*3 : g_CI.dwWidth/11*9; } else { float xscale, yscale; uint32_t val = *gfx_info.VI_X_SCALE_REG & 0xFFF; xscale = (float)val / (1<<10); uint32_t start = *gfx_info.VI_H_START_REG >> 16; uint32_t end = *gfx_info.VI_H_START_REG&0xFFFF; uint32_t width = *gfx_info.VI_WIDTH_REG; windowSetting.fViWidth = (end-start)*xscale; if( abs((int)(windowSetting.fViWidth - width) ) < 8 ) { windowSetting.fViWidth = (float)width; } else { DebuggerAppendMsg("fViWidth = %f, Width Reg=%d", windowSetting.fViWidth, width); } val = (*gfx_info.VI_Y_SCALE_REG & 0xFFF);// - ((*gfx_info.VI_Y_SCALE_REG>>16) & 0xFFF); if( val == 0x3FF ) val = 0x400; yscale = (float)val / (1<<10); start = *gfx_info.VI_V_START_REG >> 16; end = *gfx_info.VI_V_START_REG&0xFFFF; windowSetting.fViHeight = (end-start)/2*yscale; if( yscale == 0 ) { windowSetting.fViHeight = windowSetting.fViWidth*status.fRatio; } else { if( *gfx_info.VI_WIDTH_REG > 0x300 ) windowSetting.fViHeight *= 2; if( windowSetting.fViWidth*status.fRatio > windowSetting.fViHeight && (*gfx_info.VI_X_SCALE_REG & 0xFF) != 0 ) { if( abs(int(windowSetting.fViWidth*status.fRatio - windowSetting.fViHeight)) < 8 ) { windowSetting.fViHeight = windowSetting.fViWidth*status.fRatio; } /* else { if( abs(windowSetting.fViWidth*status.fRatio-windowSetting.fViHeight) > windowSetting.fViWidth*0.1f ) { if( status.fRatio > 0.8 ) windowSetting.fViHeight = windowSetting.fViWidth*3/4; //windowSetting.fViHeight = (*gfx_info.VI_V_SYNC_REG - 0x2C)/2; } } */ } if( windowSetting.fViHeight<100 || windowSetting.fViWidth<100 ) { //At sometime, value in VI_H_START_REG or VI_V_START_REG are 0 windowSetting.fViWidth = (float)*gfx_info.VI_WIDTH_REG; windowSetting.fViHeight = windowSetting.fViWidth*status.fRatio; } } windowSetting.uViWidth = (unsigned short)(windowSetting.fViWidth/4); windowSetting.fViWidth = windowSetting.uViWidth *= 4; windowSetting.uViHeight = (unsigned short)(windowSetting.fViHeight/4); windowSetting.fViHeight = windowSetting.uViHeight *= 4; uint16_t optimizeHeight = (uint16_t)(windowSetting.uViWidth*status.fRatio); optimizeHeight &= ~3; uint16_t optimizeHeight2 = (uint16_t)(windowSetting.uViWidth*3/4); optimizeHeight2 &= ~3; if( windowSetting.uViHeight != optimizeHeight && windowSetting.uViHeight != optimizeHeight2 ) { if( abs(windowSetting.uViHeight-optimizeHeight) <= 8 ) windowSetting.fViHeight = windowSetting.uViHeight = optimizeHeight; else if( abs(windowSetting.uViHeight-optimizeHeight2) <= 8 ) windowSetting.fViHeight = windowSetting.uViHeight = optimizeHeight2; } if( gRDP.scissor.left == 0 && gRDP.scissor.top == 0 && gRDP.scissor.right != 0 ) { if( (*gfx_info.VI_X_SCALE_REG & 0xFF) != 0x0 && gRDP.scissor.right == windowSetting.uViWidth ) { // Mario Tennis if( abs(int( windowSetting.fViHeight - gRDP.scissor.bottom )) < 8 ) { windowSetting.fViHeight = windowSetting.uViHeight = gRDP.scissor.bottom; } else if( windowSetting.fViHeight < gRDP.scissor.bottom ) { windowSetting.fViHeight = windowSetting.uViHeight = gRDP.scissor.bottom; } windowSetting.fViHeight = windowSetting.uViHeight = gRDP.scissor.bottom; } else if( gRDP.scissor.right == windowSetting.uViWidth - 1 && gRDP.scissor.bottom != 0 ) { if( windowSetting.uViHeight != optimizeHeight && windowSetting.uViHeight != optimizeHeight2 ) { if( status.fRatio != 0.75 && windowSetting.fViHeight > optimizeHeight/2 ) { windowSetting.fViHeight = windowSetting.uViHeight = gRDP.scissor.bottom + gRDP.scissor.top + 1; } } } else if( gRDP.scissor.right == windowSetting.uViWidth && gRDP.scissor.bottom != 0 && status.fRatio != 0.75 ) { if( windowSetting.uViHeight != optimizeHeight && windowSetting.uViHeight != optimizeHeight2 ) { if( status.fRatio != 0.75 && windowSetting.fViHeight > optimizeHeight/2 ) { windowSetting.fViHeight = windowSetting.uViHeight = gRDP.scissor.bottom + gRDP.scissor.top + 1; } } } } } SetScreenMult(windowSetting.uDisplayWidth/windowSetting.fViWidth, windowSetting.uDisplayHeight/windowSetting.fViHeight); } void TriggerDPInterrupt(void) { *(gfx_info.MI_INTR_REG) |= MI_INTR_DP; gfx_info.CheckInterrupts(); } void TriggerSPInterrupt(void) { *(gfx_info.MI_INTR_REG) |= MI_INTR_SP; gfx_info.CheckInterrupts(); } void _VIDEO_DisplayTemporaryMessage(const char *Message) { } void DebugMessage(int level, const char *message, ...) { char msgbuf[1024]; va_list args; if (l_DebugCallback == NULL) return; va_start(args, message); vsprintf(msgbuf, message, args); (*l_DebugCallback)(l_DebugCallContext, level, msgbuf); va_end(args); } //--------------------------------------------------------------------------------------- // Global functions, exported for use by the core library // since these functions are exported, they need to have C-style names #ifdef __cplusplus extern "C" { #endif /* Mupen64Plus plugin functions */ EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context, void (*DebugCallback)(void *, int, const char *)) { if (l_PluginInit) return M64ERR_ALREADY_INIT; /* first thing is to set the callback function for debug info */ l_DebugCallback = DebugCallback; l_DebugCallContext = Context; /* open config section handles and set parameter default values */ if (!InitConfiguration()) return M64ERR_INTERNAL; l_PluginInit = 1; return M64ERR_SUCCESS; } EXPORT m64p_error CALL PluginShutdown(void) { if (!l_PluginInit) return M64ERR_NOT_INIT; if( status.bGameIsRunning ) { RomClosed(); } #if 0 if (bIniIsChanged) { WriteIniFile(); TRACE0("Write back INI file"); } #endif /* reset some local variables */ l_DebugCallback = NULL; l_DebugCallContext = NULL; l_PluginInit = 0; return M64ERR_SUCCESS; } EXPORT m64p_error CALL PluginGetVersion(m64p_plugin_type *PluginType, int *PluginVersion, int *APIVersion, const char **PluginNamePtr, int *Capabilities) { /* set version info */ if (PluginType != NULL) *PluginType = M64PLUGIN_GFX; if (PluginVersion != NULL) *PluginVersion = PLUGIN_VERSION; if (APIVersion != NULL) *APIVersion = VIDEO_PLUGIN_API_VERSION; if (PluginNamePtr != NULL) *PluginNamePtr = PLUGIN_NAME; if (Capabilities != NULL) { *Capabilities = 0; } return M64ERR_SUCCESS; } //------------------------------------------------------------------------------------- EXPORT void CALL ChangeWindow (void) { } //--------------------------------------------------------------------------------------- EXPORT void CALL MoveScreen (int xpos, int ypos) { } //--------------------------------------------------------------------------------------- EXPORT void CALL RomClosed(void) { TRACE0("To stop video"); Ini_StoreRomOptions(&g_curRomInfo); StopVideo(); TRACE0("Video is stopped"); } EXPORT int CALL RomOpen(void) { /* Read RiceVideoLinux.ini file, set up internal variables by reading values from core configuration API */ LoadConfiguration(); status.bDisableFPS=false; g_dwRamSize = 0x800000; #ifdef DEBUGGER if( debuggerPause ) { debuggerPause = FALSE; usleep(100 * 1000); } #endif if (!StartVideo()) return 0; return 1; } //--------------------------------------------------------------------------------------- EXPORT void CALL UpdateScreen(void) { UpdateScreenStep2(); } //--------------------------------------------------------------------------------------- EXPORT void CALL ViStatusChanged(void) { SetVIScales(); CRender::g_pRender->UpdateClipRectangle(); } //--------------------------------------------------------------------------------------- EXPORT void CALL ViWidthChanged(void) { SetVIScales(); CRender::g_pRender->UpdateClipRectangle(); } EXPORT int CALL InitiateGFX(GFX_INFO Gfx_Info) { memset(&status, 0, sizeof(status)); windowSetting.fViWidth = 320; windowSetting.fViHeight = 240; status.ToResize = false; status.bDisableFPS=false; if (!InitConfiguration()) { DebugMessage(M64MSG_ERROR, "Failed to read configuration data"); return FALSE; } CGraphicsContext::InitWindowInfo(); CGraphicsContext::InitDeviceParameters(); return(TRUE); } EXPORT void CALL ResizeVideoOutput(int width, int height) { // save the new window resolution. actual resizing operation is asynchronous (it happens later) status.gNewResizeWidth = width; status.gNewResizeHeight = height; status.ToResize = true; } //--------------------------------------------------------------------------------------- EXPORT void CALL ProcessRDPList(void) { RDP_DLParser_Process(); } EXPORT void CALL ProcessDList(void) { ProcessDListStep2(); } //--------------------------------------------------------------------------------------- /****************************************************************** Function: FrameBufferRead Purpose: This function is called to notify the dll that the frame buffer memory is beening read at the given address. DLL should copy content from its render buffer to the frame buffer in N64 RDRAM DLL is responsible to maintain its own frame buffer memory addr list DLL should copy 4KB block content back to RDRAM frame buffer. Emulator should not call this function again if other memory is read within the same 4KB range Since depth buffer is also being watched, the reported addr may belong to depth buffer input: addr rdram address val val size 1 = uint8_t, 2 = uint16_t, 4 = uint32_t output: none *******************************************************************/ EXPORT void CALL FBRead(uint32_t addr) { g_pFrameBufferManager->FrameBufferReadByCPU(addr); } /****************************************************************** Function: FrameBufferWrite Purpose: This function is called to notify the dll that the frame buffer has been modified by CPU at the given address. Since depth buffer is also being watched, the reported addr may belong to depth buffer input: addr rdram address val val size 1 = uint8_t, 2 = uint16_t, 4 = uint32_t output: none *******************************************************************/ EXPORT void CALL FBWrite(uint32_t addr, uint32_t size) { g_pFrameBufferManager->FrameBufferWriteByCPU(addr, size); } /************************************************************************ Function: FBGetFrameBufferInfo Purpose: This function is called by the emulator core to retrieve frame buffer information from the video plugin in order to be able to notify the video plugin about CPU frame buffer read/write operations size: = 1 byte = 2 word (16 bit) <-- this is N64 default depth buffer format = 4 dword (32 bit) when frame buffer information is not available yet, set all values in the FrameBufferInfo structure to 0 input: FrameBufferInfo pinfo[6] pinfo is pointed to a FrameBufferInfo structure which to be filled in by this function output: Values are return in the FrameBufferInfo structure Plugin can return up to 6 frame buffer info ************************************************************************/ EXPORT void CALL FBGetFrameBufferInfo(void *p) { FrameBufferInfo * pinfo = (FrameBufferInfo *)p; memset(pinfo,0,sizeof(FrameBufferInfo)*6); //if( g_ZI.dwAddr == 0 ) //{ // memset(pinfo,0,sizeof(FrameBufferInfo)*6); //} //else { for (int i=0; i<5; i++ ) { if( status.gDlistCount-g_RecentCIInfo[i].lastUsedFrame > 30 || g_RecentCIInfo[i].lastUsedFrame == 0 ) { //memset(&pinfo[i],0,sizeof(FrameBufferInfo)); } else { pinfo[i].addr = g_RecentCIInfo[i].dwAddr; pinfo[i].size = 2; pinfo[i].width = g_RecentCIInfo[i].dwWidth; pinfo[i].height = g_RecentCIInfo[i].dwHeight; TXTRBUF_DETAIL_DUMP(TRACE3("Protect 0x%08X (%d,%d)", g_RecentCIInfo[i].dwAddr, g_RecentCIInfo[i].dwWidth, g_RecentCIInfo[i].dwHeight)); pinfo[5].width = g_RecentCIInfo[i].dwWidth; pinfo[5].height = g_RecentCIInfo[i].dwHeight; } } pinfo[5].addr = g_ZI.dwAddr; //pinfo->size = g_RecentCIInfo[5].dwSize; pinfo[5].size = 2; TXTRBUF_DETAIL_DUMP(TRACE3("Protect 0x%08X (%d,%d)", pinfo[5].addr, pinfo[5].width, pinfo[5].height)); } } // Plugin spec 1.3 functions EXPORT void CALL ShowCFB(void) { status.toShowCFB = true; } //void ReadScreen2( void *dest, int *width, int *height, int bFront ) EXPORT void CALL ReadScreen2(void *dest, int *width, int *height, int bFront) { if (width == NULL || height == NULL) return; *width = windowSetting.uDisplayWidth; *height = windowSetting.uDisplayHeight; if (dest == NULL) return; } EXPORT void CALL SetRenderingCallback(void (*callback)(int)) { renderCallback = callback; } #ifdef __cplusplus } #endif mupen64plus-core/src/debugger/dbg_memory.h000664 001750 001750 00000005047 12655644434 021725 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - dbg_memory.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2008 DarkJeztr * * Copyright (C) 2002 davFr * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef __DEBUGGER_MEMORY_H__ #define __DEBUGGER_MEMORY_H__ #define MAX_DISASSEMBLY 64 void init_host_disassembler(void); char* get_recompiled_opcode( uint32 address, int index ); char* get_recompiled_args( uint32 address, int index ); void* get_recompiled_addr( uint32 address, int index ); int get_num_recompiled( uint32 address ); int get_has_recompiled( uint32 address ); uint64 read_memory_64(uint32 addr); uint64 read_memory_64_unaligned(uint32 addr); void write_memory_64(uint32 addr, uint64 value); void write_memory_64_unaligned(uint32 addr, uint64 value); uint32 read_memory_32(uint32); uint32 read_memory_32_unaligned(uint32 addr); void write_memory_32(uint32, uint32); void write_memory_32_unaligned(uint32 addr, uint32 value); uint16 read_memory_16(uint32 addr); void write_memory_16(uint32 addr, uint16 value); uint8 read_memory_8(uint32 addr); void write_memory_8(uint32 addr, uint8 value); uint32 get_memory_flags(uint32); #endif /* __DEBUGGER_MEMORY_H__ */ gles2rice/000700 001750 001750 00000000000 12656647145 013565 5ustar00sergiosergio000000 000000 gles2n64/src/convert.h000664 001750 001750 00000015104 12655644434 015704 0ustar00sergiosergio000000 000000 #ifndef CONVERT_H #define CONVERT_H #if !defined(__MACH__) && !defined(__ppc__) && defined(__GNUC__) #define HAVE_BSWAP #endif #ifdef HAVE_BSWAP #define bswap_32 __builtin_bswap32 #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) #include #define bswap_32(x) _byteswap_ulong(x) #else #define bswap_32(x) (((x) << 24) & 0xff000000) \ | (((x) << 8) & 0xff0000) \ | (((x) >> 8) & 0xff00) \ | (((x) >> 24) & 0xff ) #endif #include "Types.h" static const volatile unsigned char Five2Eight[32] = { 0, // 00000 = 00000000 8, // 00001 = 00001000 16, // 00010 = 00010000 25, // 00011 = 00011001 33, // 00100 = 00100001 41, // 00101 = 00101001 49, // 00110 = 00110001 58, // 00111 = 00111010 66, // 01000 = 01000010 74, // 01001 = 01001010 82, // 01010 = 01010010 90, // 01011 = 01011010 99, // 01100 = 01100011 107, // 01101 = 01101011 115, // 01110 = 01110011 123, // 01111 = 01111011 132, // 10000 = 10000100 140, // 10001 = 10001100 148, // 10010 = 10010100 156, // 10011 = 10011100 165, // 10100 = 10100101 173, // 10101 = 10101101 181, // 10110 = 10110101 189, // 10111 = 10111101 197, // 11000 = 11000101 206, // 11001 = 11001110 214, // 11010 = 11010110 222, // 11011 = 11011110 230, // 11100 = 11100110 239, // 11101 = 11101111 247, // 11110 = 11110111 255 // 11111 = 11111111 }; static const volatile unsigned char Four2Eight[16] = { 0, // 0000 = 00000000 17, // 0001 = 00010001 34, // 0010 = 00100010 51, // 0011 = 00110011 68, // 0100 = 01000100 85, // 0101 = 01010101 102, // 0110 = 01100110 119, // 0111 = 01110111 136, // 1000 = 10001000 153, // 1001 = 10011001 170, // 1010 = 10101010 187, // 1011 = 10111011 204, // 1100 = 11001100 221, // 1101 = 11011101 238, // 1110 = 11101110 255 // 1111 = 11111111 }; static const volatile unsigned char Three2Four[8] = { 0, // 000 = 0000 2, // 001 = 0010 4, // 010 = 0100 6, // 011 = 0110 9, // 100 = 1001 11, // 101 = 1011 13, // 110 = 1101 15, // 111 = 1111 }; static const volatile unsigned char Three2Eight[8] = { 0, // 000 = 00000000 36, // 001 = 00100100 73, // 010 = 01001001 109, // 011 = 01101101 146, // 100 = 10010010 182, // 101 = 10110110 219, // 110 = 11011011 255, // 111 = 11111111 }; static const volatile unsigned char Two2Eight[4] = { 0, // 00 = 00000000 85, // 01 = 01010101 170, // 10 = 10101010 255 // 11 = 11111111 }; static const volatile unsigned char One2Four[2] = { 0, // 0 = 0000 15, // 1 = 1111 }; static const volatile unsigned char One2Eight[2] = { 0, // 0 = 00000000 255, // 1 = 11111111 }; static INLINE void UnswapCopyWrap(const u8 *src, u32 srcIdx, u8 *dest, u32 destIdx, u32 destMask, u32 numBytes) { // copy leading bytes u32 leadingBytes = srcIdx & 3; if (leadingBytes != 0) { unsigned i; leadingBytes = 4 - leadingBytes; if ((u32)leadingBytes > numBytes) leadingBytes = numBytes; numBytes -= leadingBytes; srcIdx ^= 3; for (i = 0; i < leadingBytes; i++) { dest[destIdx&destMask] = src[srcIdx]; ++destIdx; --srcIdx; } srcIdx += 5; } // copy dwords int numDWords = numBytes >> 2; while (numDWords--) { dest[(destIdx + 3) & destMask] = src[srcIdx++]; dest[(destIdx + 2) & destMask] = src[srcIdx++]; dest[(destIdx + 1) & destMask] = src[srcIdx++]; dest[(destIdx + 0) & destMask] = src[srcIdx++]; destIdx += 4; } // copy trailing bytes int trailingBytes = numBytes & 3; if (trailingBytes) { unsigned i; srcIdx ^= 3; for (i = 0; i < trailingBytes; i++) { dest[destIdx&destMask] = src[srcIdx]; ++destIdx; --srcIdx; } } } static INLINE void DWordInterleaveWrap(u32 *src, u32 srcIdx, u32 srcMask, u32 numQWords) { u32 tmp; while (numQWords--) { tmp = src[srcIdx & srcMask]; src[srcIdx & srcMask] = src[(srcIdx + 1) & srcMask]; ++srcIdx; src[srcIdx & srcMask] = tmp; ++srcIdx; } } static INLINE u16 swapword( u16 value ) { return (value << 8) | (value >> 8); } #define RGBA8888_RGBA4444(color) (((color & 0x000000f0) << 8) | ((color & 0x0000f000) >> 4) | ((color & 0x00f00000) >> 16) | ((color & 0xf0000000) >> 28)) static INLINE u32 RGBA5551_RGBA8888( u16 color ) { u8 r, g, b, a; color = swapword( color ); r = Five2Eight[color >> 11]; g = Five2Eight[(color >> 6) & 0x001f]; b = Five2Eight[(color >> 1) & 0x001f]; a = One2Eight [(color ) & 0x0001]; return (a << 24) | (b << 16) | (g << 8) | r; } // Just swaps the word #define RGBA5551_RGBA5551(color) (swapword( color )) static INLINE u32 IA88_RGBA8888( u16 color ) { u8 a = color >> 8; u8 i = color & 0x00FF; return (a << 24) | (i << 16) | (i << 8) | i; } static INLINE u16 IA88_RGBA4444( u16 color ) { u8 i = color >> 12; u8 a = (color >> 4) & 0x000F; return (i << 12) | (i << 8) | (i << 4) | a; } #define IA44_RGBA4444(color) (((color & 0xf0) << 8) | ((color & 0xf0) << 4) | (color)) static INLINE u32 IA44_RGBA8888( u8 color ) { u8 i = Four2Eight[color >> 4]; u8 a = Four2Eight[color & 0x0F]; return (a << 24) | (i << 16) | (i << 8) | i; } static INLINE u16 IA44_IA88( u8 color ) { u8 i = Four2Eight[color >> 4]; u8 a = Four2Eight[color & 0x0F]; return (a << 8) | i; } static INLINE u16 IA31_RGBA4444( u8 color ) { u8 i = Three2Four[color >> 1]; u8 a = One2Four[color & 0x01]; return (i << 12) | (i << 8) | (i << 4) | a; } static INLINE u16 IA31_IA88( u8 color ) { u8 i = Three2Eight[color >> 1]; u8 a = One2Eight[color & 0x01]; return (a << 8) | i; } static INLINE u32 IA31_RGBA8888( u8 color ) { u8 i = Three2Eight[color >> 1]; u8 a = One2Eight[color & 0x01]; return (i << 24) | (i << 16) | (i << 8) | a; } static INLINE u16 I8_RGBA4444( u8 color ) { u8 c = color >> 4; return (c << 12) | (c << 8) | (c << 4) | c; } #define I8_RGBA8888(color) ((color << 24) | (color << 16) | (color << 8) | color) static INLINE u16 I4_RGBA4444( u8 color ) { u16 ret = color & 0x0f; ret |= ret << 4; ret |= ret << 8; return ret; } #define I4_I8(color) (Four2Eight[color & 0x0f]) static INLINE u16 I4_IA88( u8 color ) { u32 c = Four2Eight[color & 0x0f]; return (c << 8) | c; } #define I8_IA88(color) ((color << 8) | color) static INLINE u16 IA88_IA88( u16 color ) { u8 a = (color&0xFF); u8 i = (color>>8); return (i << 8) | a; } static INLINE u32 I4_RGBA8888( u8 color ) { u8 c = Four2Eight[color]; c |= c << 4; return (c << 24) | (c << 16) | (c << 8) | c; } #endif // CONVERT_H mupen64plus-core/src/r4300/r4300.h000664 001750 001750 00000005230 12655644434 017327 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - r4300.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_R4300_R4300_H #define M64P_R4300_R4300_H #include "ops.h" #include "r4300_core.h" #include "recomp.h" #include "tlb.h" extern precomp_instr *PC; extern int stop, rompause; extern unsigned int llbit; extern int64_t reg[32], hi, lo; extern int64_t local_rs; extern unsigned int delay_slot; extern uint32_t skip_jump; extern unsigned int dyna_interp; extern unsigned int r4300emu; extern uint32_t next_interupt; extern uint32_t last_addr; extern unsigned int count_per_op; extern cpu_instruction_table current_instruction_table; void r4300_reset_hard(void); void r4300_reset_soft(void); void r4300_init(void); void r4300_deinit(void); void r4300_execute(void); /* r4300 emulators */ #define CORE_PURE_INTERPRETER 0 #define CORE_INTERPRETER 1 #define CORE_DYNAREC 2 // profiling #define ALL_SECTION 0 #define GFX_SECTION 1 #define AUDIO_SECTION 2 #define COMPILER_SECTION 3 #define IDLE_SECTION 4 #ifdef PROFILE void start_section(int section_type); void end_section(int section_type); void refresh_stat(void); #else #define start_section(a) #define end_section(a) #define refresh_stat() #endif #endif /* M64P_R4300_R4300_H */ mupen64plus-core/src/rdp_common/000700 001750 001750 00000000000 12656647145 017762 5ustar00sergiosergio000000 000000 mupen64plus-core/src/debugger/dbg_memory.c000664 001750 001750 00000033077 12655644434 021724 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - dbg_memory.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2008 DarkJeztr * * Copyright (C) 2002 Blight * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include "dbg_types.h" #include "dbg_memory.h" #include "dbg_breakpoints.h" #incldue "../ai/ai_controller.h" #include "../api/m64p_types.h" #include "../api/callbacks.h" #include "../main/main.h" #include "../main/rom.h" #include "../memory/memory.h" #include "../pi/pi_controller.h" #include "../r4300/cached_interp.h" #include "../r4300/ops.h" #include "../r4300/r4300.h" #include "../r4300/r4300_core.h" #include "../rdp/rdp_core.h" #include "../rsp/rsp_core.h" #include "../ri/ri_controller.h" #include "../si/si_controller.h" #include "../vi/vi_controller.h" #if !defined(NO_ASM) && (defined(__i386__) || defined(__x86_64__)) #include #include static int lines_recompiled; static uint32 addr_recompiled; static int num_decoded; static char opcode_recompiled[564][MAX_DISASSEMBLY]; static char args_recompiled[564][MAX_DISASSEMBLY*4]; static void *opaddr_recompiled[564]; static disassemble_info dis_info; #define CHECK_MEM(address) invalidate_r4300_cached_code(address, 4); static void process_opcode_out(void *strm, const char *fmt, ...){ va_list ap; va_start(ap, fmt); char *arg; char buff[256]; if(num_decoded==0) { if(strcmp(fmt,"%s")==0) { arg = va_arg(ap, char*); strcpy(opcode_recompiled[lines_recompiled],arg); } else strcpy(opcode_recompiled[lines_recompiled],"OPCODE-X"); num_decoded++; *(args_recompiled[lines_recompiled])=0; } else { vsprintf(buff, fmt, ap); sprintf(args_recompiled[lines_recompiled],"%s%s", args_recompiled[lines_recompiled],buff); } va_end(ap); } // Callback function that will be called by libopcodes to read the // bytes to disassemble ('read_memory_func' member of 'disassemble_info'). static int read_memory_func(bfd_vma memaddr, bfd_byte *myaddr, unsigned int length, disassemble_info *info) { char* from = (char*)(long)(memaddr); char* to = (char*)myaddr; while (length-- != 0) { *to++ = *from++; } return (0); } void init_host_disassembler(void){ INIT_DISASSEMBLE_INFO(dis_info, stderr, process_opcode_out); dis_info.fprintf_func = (fprintf_ftype) process_opcode_out; dis_info.stream = stderr; dis_info.bytes_per_line=1; dis_info.endian = 1; dis_info.mach = bfd_mach_i386_i8086; dis_info.disassembler_options = (char*) "i386,suffix"; dis_info.read_memory_func = read_memory_func; } static void decode_recompiled(uint32 addr) { unsigned char *assemb, *end_addr; lines_recompiled=0; if(blocks[addr>>12] == NULL) return; if(blocks[addr>>12]->block[(addr&0xFFF)/4].ops == current_instruction_table.NOTCOMPILED) // recompile_block((int *) g_sp_mem, blocks[addr>>12], addr); { strcpy(opcode_recompiled[0],"INVLD"); strcpy(args_recompiled[0],"NOTCOMPILED"); opaddr_recompiled[0] = (void *) 0; addr_recompiled=0; lines_recompiled++; return; } assemb = (blocks[addr>>12]->code) + (blocks[addr>>12]->block[(addr&0xFFF)/4].local_addr); end_addr = blocks[addr>>12]->code; if( (addr & 0xFFF) >= 0xFFC) end_addr += blocks[addr>>12]->code_length; else end_addr += blocks[addr>>12]->block[(addr&0xFFF)/4+1].local_addr; while(assemb < end_addr) { opaddr_recompiled[lines_recompiled] = assemb; num_decoded=0; assemb += print_insn_i386((bfd_vma)(long) assemb, &dis_info); lines_recompiled++; } addr_recompiled = addr; } char* get_recompiled_opcode(uint32 addr, int index) { if(addr != addr_recompiled) decode_recompiled(addr); if(index < lines_recompiled) return opcode_recompiled[index]; else return NULL; } char* get_recompiled_args(uint32 addr, int index) { if(addr != addr_recompiled) decode_recompiled(addr); if(index < lines_recompiled) return args_recompiled[index]; else return NULL; } void * get_recompiled_addr(uint32 addr, int index) { if(addr != addr_recompiled) decode_recompiled(addr); if(index < lines_recompiled) return opaddr_recompiled[index]; else return 0; } int get_num_recompiled(uint32 addr) { if(addr != addr_recompiled) decode_recompiled(addr); return lines_recompiled; } int get_has_recompiled(uint32 addr) { unsigned char *assemb, *end_addr; if(r4300emu != CORE_DYNAREC || blocks[addr>>12] == NULL) return FALSE; assemb = (blocks[addr>>12]->code) + (blocks[addr>>12]->block[(addr&0xFFF)/4].local_addr); end_addr = blocks[addr>>12]->code; if( (addr & 0xFFF) >= 0xFFC) end_addr += blocks[addr>>12]->code_length; else end_addr += blocks[addr>>12]->block[(addr&0xFFF)/4+1].local_addr; if(assemb==end_addr) return FALSE; return TRUE; } #else #define CHECK_MEM(address) int get_num_recompiled(uint32 addr) { return 0; } char* get_recompiled_opcode(uint32 addr, int index) { return NULL; } char* get_recompiled_args(uint32 addr, int index) { return NULL; } void * get_recompiled_addr(uint32 addr, int index) { return 0; } int get_has_recompiled(uint32 addr) { return 0; } void init_host_disassembler(void) { } #endif uint64 read_memory_64(uint32 addr) { return ((uint64)read_memory_32(addr) << 32) | (uint64)read_memory_32(addr + 4); } uint64 read_memory_64_unaligned(uint32 addr) { uint64 w[2]; w[0] = read_memory_32_unaligned(addr); w[1] = read_memory_32_unaligned(addr + 4); return (w[0] << 32) | w[1]; } void write_memory_64(uint32 addr, uint64 value) { write_memory_32(addr, (uint32) (value >> 32)); write_memory_32(addr + 4, (uint32) (value & 0xFFFFFFFF)); } void write_memory_64_unaligned(uint32 addr, uint64 value) { write_memory_32_unaligned(addr, (uint32) (value >> 32)); write_memory_32_unaligned(addr + 4, (uint32) (value & 0xFFFFFFFF)); } uint32 read_memory_32(uint32 addr){ uint32_t offset; switch(get_memory_type(addr)) { case M64P_MEM_NOMEM: if(tlb_LUT_r[addr>>12]) return read_memory_32((tlb_LUT_r[addr>>12]&0xFFFFF000)|(addr&0xFFF)); return M64P_MEM_INVALID; case M64P_MEM_RDRAM: return g_rdram[rdram_dram_address(addr)]; case M64P_MEM_RSPMEM: return g_sp.mem[rsp_mem_address(addr)]; case M64P_MEM_ROM: return *((uint32 *)(g_rom + rom_address(addr))); case M64P_MEM_RDRAMREG: offset = RDRAM_REG(addr); if (offset < RDRAM_REGS_COUNT) return g_ri.rdram.regs[offset]; break; case M64P_MEM_RSPREG: offset = RSP_REG(addr); if (offset < SP_REGS_COUNT) return g_sp.regs[offset]; break; case M64P_MEM_RSP: offset = rsp_reg2(addr); if (offset < SP_REGS2_COUNT) return g_sp.regs2[offset]; break; case M64P_MEM_DP: offset = DPC_REG(addr); if (offset < DPC_REGS_COUNT) return g_dpc.regs[offset]; break; case M64P_MEM_DPS: if (addrlow < 0x10) return *(readdps[addrlow&0xfffc]); break; case M64P_MEM_VI: offset = VI_REG(addr); if (offset < VI_REGS_COUNT) return g_vi.regs[offset]; break; case M64P_MEM_AI: offset = AI_REG((addr); if (offset < AI_REGS_COUNT) return g_ai.regs[offset]; break; case M64P_MEM_PI: offset = PI_REG((addr); if (offset < PI_REGS_COUNT) return g_pi.regs[offset]; break; case M64P_MEM_RI: offset = RI_REG(addr); if (offset < RI_REGS_COUNT) return g_ri.regs[offset]; break; case M64P_MEM_SI: offset = SI_REG(addr); if (offset < SI_REGS_COUNT) return g_si.regs[offset]; break; case M64P_MEM_PIF: offset = pif_ram_address(addr); if (offset < PIF_RAM_SIZE) return sl((*((uint32_t*)&g_si.pif.ram[offset]))); break; case M64P_MEM_MI: offset = MI_REG(addr); if (offset < MI_REGS_COUNT) return g_r4300.mi.regs[offset]; break; default: break; } return M64P_MEM_INVALID; } uint32 read_memory_32_unaligned(uint32 addr) { uint8 i, b[4]; for(i=0; i<4; i++) b[i] = read_memory_8(addr + i); return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]; } void write_memory_32(uint32 addr, uint32 value){ switch(get_memory_type(addr)) { case M64P_MEM_RDRAM: g_rdram[(addr & 0xFFFFFF) >> 2] = value; CHECK_MEM(addr) break; } } void write_memory_32_unaligned(uint32 addr, uint32 value) { write_memory_8(addr + 0, value >> 24); write_memory_8(addr + 1, (value >> 16) & 0xFF); write_memory_8(addr + 2, (value >> 8) & 0xFF); write_memory_8(addr + 3, value & 0xFF); } //read_memory_16_unaligned and write_memory_16_unaligned don't exist because //read_memory_16 and write_memory_16 work unaligned already. uint16 read_memory_16(uint32 addr) { return ((uint16)read_memory_8(addr) << 8) | (uint16)read_memory_8(addr+1); //cough cough hack hack } void write_memory_16(uint32 addr, uint16 value) { write_memory_8(addr, value >> 8); //this isn't much better write_memory_8(addr + 1, value & 0xFF); //then again, it works unaligned } uint8 read_memory_8(uint32 addr) { uint32 word; word = read_memory_32(addr & ~3); return (word >> ((3 - (addr & 3)) * 8)) & 0xFF; } void write_memory_8(uint32 addr, uint8 value) { uint32 word, mask; word = read_memory_32(addr & ~3); mask = 0xFF << ((3 - (addr & 3)) * 8); word = (word & ~mask) | (value << ((3 - (addr & 3)) * 8)); write_memory_32(addr & ~3, word); } uint32 get_memory_flags(uint32 addr) { int type=get_memory_type(addr); const uint32 addrlow = (addr & 0xFFFF); uint32 flags = 0; switch(type) { case M64P_MEM_NOMEM: if(tlb_LUT_r[addr>>12]) flags = M64P_MEM_FLAG_READABLE | M64P_MEM_FLAG_WRITABLE_EMUONLY; break; case M64P_MEM_NOTHING: if (((addr >> 16) == 0x8801 || (addr >> 16 == 0xA801)) && addrlow == 0) flags = M64P_MEM_FLAG_WRITABLE_EMUONLY; // for flashram command break; case M64P_MEM_RDRAM: flags = M64P_MEM_FLAG_WRITABLE; case M64P_MEM_ROM: flags |= M64P_MEM_FLAG_READABLE; break; case M64P_MEM_RDRAMREG: if (addrlow < 0x28) flags = M64P_MEM_FLAG_READABLE | M64P_MEM_FLAG_WRITABLE_EMUONLY; break; case M64P_MEM_RSPMEM: if (addrlow < 0x2000) flags = M64P_MEM_FLAG_READABLE | M64P_MEM_FLAG_WRITABLE_EMUONLY; break; case M64P_MEM_RSPREG: if (addrlow < 0x20) flags = M64P_MEM_FLAG_READABLE | M64P_MEM_FLAG_WRITABLE_EMUONLY; break; case M64P_MEM_RSP: if (addrlow < 0x8) flags = M64P_MEM_FLAG_READABLE | M64P_MEM_FLAG_WRITABLE_EMUONLY; break; case M64P_MEM_DP: if (addrlow < 0x20) flags = M64P_MEM_FLAG_READABLE | M64P_MEM_FLAG_WRITABLE_EMUONLY; break; case M64P_MEM_DPS: if (addrlow < 0x10) flags = M64P_MEM_FLAG_READABLE | M64P_MEM_FLAG_WRITABLE_EMUONLY; break; case M64P_MEM_VI: if (addrlow < 0x38) flags = M64P_MEM_FLAG_READABLE | M64P_MEM_FLAG_WRITABLE_EMUONLY; break; case M64P_MEM_AI: if (addrlow < 0x18) flags = M64P_MEM_FLAG_READABLE | M64P_MEM_FLAG_WRITABLE_EMUONLY; break; case M64P_MEM_PI: if (addrlow < 0x34) flags = M64P_MEM_FLAG_READABLE | M64P_MEM_FLAG_WRITABLE_EMUONLY; break; case M64P_MEM_RI: if (addrlow < 0x20) flags = M64P_MEM_FLAG_READABLE | M64P_MEM_FLAG_WRITABLE_EMUONLY; break; case M64P_MEM_SI: if (addrlow < 0x1c) flags = M64P_MEM_FLAG_READABLE | M64P_MEM_FLAG_WRITABLE_EMUONLY; break; case M64P_MEM_FLASHRAMSTAT: if (addrlow == 0) flags = M64P_MEM_FLAG_READABLE_EMUONLY; break; case M64P_MEM_PIF: if (addrlow >= 0x7C0 && addrlow <= 0x7FF) flags = M64P_MEM_FLAG_READABLE | M64P_MEM_FLAG_WRITABLE_EMUONLY; break; case M64P_MEM_MI: if (addrlow < 0x10) flags = M64P_MEM_FLAG_READABLE | M64P_MEM_FLAG_WRITABLE_EMUONLY; break; default: break; } return flags; } mupen64plus-core/src/api/frontend.c000664 001750 001750 00000024202 12655644434 020372 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-core - api/frontend.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2012 CasualJames * * Copyright (C) 2009 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file contains the Core front-end functions which will be exported * outside of the core library. */ #include #include #include #define M64P_CORE_PROTOTYPES 1 #include "m64p_types.h" #include "callbacks.h" #include "m64p_config.h" #include "m64p_frontend.h" #include "audio_backend.h" #include "config.h" #include "vidext.h" #include "../main/cheat.h" #include "main/main.h" #include "main/rom.h" #include "main/version.h" #include "main/util.h" #include "dd/dd_rom.h" #include "dd/dd_disk.h" #include "plugin/plugin.h" /* some local state variables */ static int l_CoreInit = 0; static int l_ROMOpen = 0; static int l_DDROMOpen = 0; static int l_DDDiskOpen = 0; /* functions exported outside of libmupen64plus to front-end application */ EXPORT m64p_error CALL CoreStartup(int APIVersion, const char *ConfigPath, const char *DataPath, void *Context, void (*DebugCallback)(void *, int, const char *), void *Context2, void (*StateCallback)(void *, m64p_core_param, int)) { if (l_CoreInit) return M64ERR_ALREADY_INIT; /* very first thing is to set the callback functions for debug info and state changing*/ SetDebugCallback(DebugCallback, Context); SetStateCallback(StateCallback, Context2); /* check front-end's API version */ if ((APIVersion & 0xffff0000) != (FRONTEND_API_VERSION & 0xffff0000)) { DebugMessage(M64MSG_ERROR, "CoreStartup(): Front-end (API version %i.%i.%i) is incompatible with this core (API %i.%i.%i)", VERSION_PRINTF_SPLIT(APIVersion), VERSION_PRINTF_SPLIT(FRONTEND_API_VERSION)); return M64ERR_INCOMPATIBLE; } /* next, start up the configuration handling code by loading and parsing the config file */ if (ConfigInit(ConfigPath, DataPath) != M64ERR_SUCCESS) return M64ERR_INTERNAL; /* set default configuration parameter values for Core */ if (ConfigOpenSection("Core", &g_CoreConfig) != M64ERR_SUCCESS || g_CoreConfig == NULL) return M64ERR_INTERNAL; if (!main_set_core_defaults()) return M64ERR_INTERNAL; l_CoreInit = 1; return M64ERR_SUCCESS; } EXPORT m64p_error CALL CoreShutdown(void) { if (!l_CoreInit) return M64ERR_NOT_INIT; ConfigShutdown(); l_CoreInit = 0; return M64ERR_SUCCESS; } EXPORT m64p_error CALL CoreDoCommand(m64p_command Command, int ParamInt, void *ParamPtr) { m64p_error rval; int keysym, keymod; (void)keysym; (void)keymod; if (!l_CoreInit) return M64ERR_NOT_INIT; switch(Command) { case M64CMD_NOP: return M64ERR_SUCCESS; case M64CMD_ROM_OPEN: if (g_EmulatorRunning || l_ROMOpen) return M64ERR_INVALID_STATE; if (ParamPtr == NULL || ParamInt < 4096) return M64ERR_INPUT_ASSERT; rval = open_rom((const unsigned char *) ParamPtr, ParamInt); if (rval == M64ERR_SUCCESS) { l_ROMOpen = 1; } return rval; case M64CMD_ROM_CLOSE: if (g_EmulatorRunning || !l_ROMOpen) return M64ERR_INVALID_STATE; l_ROMOpen = 0; return close_rom(); case M64CMD_ROM_GET_HEADER: if (!l_ROMOpen) return M64ERR_INVALID_STATE; if (ParamPtr == NULL) return M64ERR_INPUT_ASSERT; if (sizeof(m64p_rom_header) < ParamInt) ParamInt = sizeof(m64p_rom_header); memmove(ParamPtr, &ROM_HEADER, ParamInt); // Mupen64Plus used to keep a m64p_rom_header with a clean ROM name // Keep returning a clean ROM name for backwards compatibility if (ParamInt >= 0x20) { int size = (ParamInt >= 0x20 + 20) ? 20 : (ParamInt - 0x20); memcpy((char *)ParamPtr + 0x20, ROM_PARAMS.headername, size); } return M64ERR_SUCCESS; case M64CMD_ROM_GET_SETTINGS: if (!l_ROMOpen) return M64ERR_INVALID_STATE; if (ParamPtr == NULL) return M64ERR_INPUT_ASSERT; if (sizeof(m64p_rom_settings) < ParamInt) ParamInt = sizeof(m64p_rom_settings); memcpy(ParamPtr, &ROM_SETTINGS, ParamInt); return M64ERR_SUCCESS; case M64CMD_EXECUTE: if (g_EmulatorRunning || !l_ROMOpen) return M64ERR_INVALID_STATE; /* the main_run() function will not return until the player has quit the game */ return main_init(); case M64CMD_STOP: if (!g_EmulatorRunning) return M64ERR_INVALID_STATE; /* this stop function is asynchronous. The emulator may not terminate until later */ return main_core_state_set(M64CORE_EMU_STATE, M64EMU_STOPPED); case M64CMD_PAUSE: if (!g_EmulatorRunning) return M64ERR_INVALID_STATE; return main_core_state_set(M64CORE_EMU_STATE, M64EMU_PAUSED); case M64CMD_RESUME: if (!g_EmulatorRunning) return M64ERR_INVALID_STATE; return main_core_state_set(M64CORE_EMU_STATE, M64EMU_RUNNING); case M64CMD_CORE_STATE_QUERY: if (ParamPtr == NULL) return M64ERR_INPUT_ASSERT; return main_core_state_query((m64p_core_param) ParamInt, (int *) ParamPtr); case M64CMD_CORE_STATE_SET: if (ParamPtr == NULL) return M64ERR_INPUT_ASSERT; return main_core_state_set((m64p_core_param) ParamInt, *((int *)ParamPtr)); case M64CMD_SET_FRAME_CALLBACK: g_FrameCallback = (m64p_frame_callback) ParamPtr; return M64ERR_SUCCESS; case M64CMD_READ_SCREEN: if (!g_EmulatorRunning) return M64ERR_INVALID_STATE; if (ParamPtr == NULL) return M64ERR_INPUT_ASSERT; if (ParamInt < 0 || ParamInt > 1) return M64ERR_INPUT_INVALID; return main_read_screen(ParamPtr, ParamInt); case M64CMD_RESET: if (!g_EmulatorRunning) return M64ERR_INVALID_STATE; if (ParamInt < 0 || ParamInt > 1) return M64ERR_INPUT_INVALID; return main_reset(ParamInt); case M64CMD_DDROM_OPEN: if (g_EmulatorRunning || l_DDROMOpen) return M64ERR_INVALID_STATE; if (ParamPtr == NULL || ParamInt < 4096) return M64ERR_INPUT_ASSERT; rval = open_ddrom((const unsigned char *)ParamPtr, ParamInt); if (rval == M64ERR_SUCCESS) l_DDROMOpen = 1; return rval; case M64CMD_DISK_OPEN: if (g_EmulatorRunning || l_DDDiskOpen) return M64ERR_INVALID_STATE; if (ParamPtr == NULL || ParamInt < 4096) return M64ERR_INPUT_ASSERT; rval = open_dd_disk((const unsigned char *)ParamPtr, ParamInt); if (rval == M64ERR_SUCCESS) l_DDDiskOpen = 1; return rval; case M64CMD_DISK_CLOSE: if (g_EmulatorRunning || !l_DDDiskOpen) return M64ERR_INVALID_STATE; l_DDDiskOpen = 0; return close_dd_disk(); default: return M64ERR_INPUT_INVALID; } return M64ERR_INTERNAL; } EXPORT m64p_error CALL CoreSetAudioInterfaceBackend(const struct m64p_audio_backend* backend) { return M64ERR_SUCCESS; } EXPORT m64p_error CALL CoreAddCheat(const char *CheatName, m64p_cheat_code *CodeList, int NumCodes) { if (!l_CoreInit) return M64ERR_NOT_INIT; if (CheatName == NULL || CodeList == NULL) return M64ERR_INPUT_ASSERT; if (strlen(CheatName) < 1 || NumCodes < 1) return M64ERR_INPUT_INVALID; if (cheat_add_new(CheatName, CodeList, NumCodes)) return M64ERR_SUCCESS; return M64ERR_INPUT_INVALID; } EXPORT m64p_error CALL CoreCheatEnabled(const char *CheatName, int Enabled) { if (!l_CoreInit) return M64ERR_NOT_INIT; if (CheatName == NULL) return M64ERR_INPUT_ASSERT; if (cheat_set_enabled(CheatName, Enabled)) return M64ERR_SUCCESS; return M64ERR_INPUT_INVALID; } EXPORT m64p_error CALL CoreCheatClearAll(void) { if (!l_CoreInit) return M64ERR_NOT_INIT; cheat_delete_all(); return M64ERR_SUCCESS; } EXPORT m64p_error CALL CoreGetRomSettings(m64p_rom_settings *RomSettings, int RomSettingsLength, int Crc1, int Crc2) { return M64ERR_SUCCESS; } mupen64plus-core/src/r4300/r4300.c000664 001750 001750 00000023557 12655644434 017336 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - r4300.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #define M64P_CORE_PROTOTYPES 1 #include "../ai/ai_controller.h" #include "../api/m64p_config.h" #include "../api/m64p_types.h" #include "../api/callbacks.h" #include "../api/debugger.h" #include "../memory/memory.h" #include "../main/main.h" #include "../main/rom.h" #include "../pi/pi_controller.h" #include "../rsp/rsp_core.h" #include "../si/si_controller.h" #include "../vi/vi_controller.h" #include "../dd/dd_rom.h" #include "r4300.h" #include "r4300_core.h" #include "cached_interp.h" #include "cp0_private.h" #include "cp1_private.h" #include "ops.h" #include "interupt.h" #include "macros.h" #include "pure_interp.h" #include "recomp.h" #include "recomph.h" #include "tlb.h" #include "new_dynarec/new_dynarec.h" #include "rsp/rsp_core.h" #ifdef DBG #include "debugger/dbg_types.h" #include "debugger/debugger.h" #endif unsigned int r4300emu = 0; unsigned int count_per_op = 2; int rompause; unsigned int llbit; #if NEW_DYNAREC != NEW_DYNAREC_ARM int stop; int64_t reg[32], hi, lo; uint32_t next_interupt; precomp_instr *PC; #endif int64_t local_rs; unsigned int delay_slot; uint32_t skip_jump = 0; unsigned int dyna_interp = 0; uint32_t last_addr; cpu_instruction_table current_instruction_table; void generic_jump_to(uint32_t address) { if (r4300emu == CORE_PURE_INTERPRETER) PC->addr = address; else { #ifdef NEW_DYNAREC if (r4300emu == CORE_DYNAREC) last_addr = pcaddr; else #endif jump_to(address); } } /* this hard reset function simulates the boot-up state of the R4300 CPU */ void r4300_reset_hard(void) { unsigned int i; // clear r4300 registers and TLB entries for (i = 0; i < 32; i++) { reg[i]=0; g_cp0_regs[i]=0; reg_cop1_fgr_64[i]=0; // --------------tlb------------------------ tlb_e[i].mask=0; tlb_e[i].vpn2=0; tlb_e[i].g=0; tlb_e[i].asid=0; tlb_e[i].pfn_even=0; tlb_e[i].c_even=0; tlb_e[i].d_even=0; tlb_e[i].v_even=0; tlb_e[i].pfn_odd=0; tlb_e[i].c_odd=0; tlb_e[i].d_odd=0; tlb_e[i].v_odd=0; tlb_e[i].r=0; //tlb_e[i].check_parity_mask=0x1000; tlb_e[i].start_even=0; tlb_e[i].end_even=0; tlb_e[i].phys_even=0; tlb_e[i].start_odd=0; tlb_e[i].end_odd=0; tlb_e[i].phys_odd=0; } for (i=0; i<0x100000; i++) { tlb_LUT_r[i] = 0; tlb_LUT_w[i] = 0; } llbit = 0; hi = 0; lo = 0; FCR0 = UINT32_C(0x511); FCR31 = 0; // set COP0 registers g_cp0_regs[CP0_RANDOM_REG] = UINT32_C(31); g_cp0_regs[CP0_STATUS_REG] = UINT32_C(0x34000000); set_fpr_pointers(g_cp0_regs[CP0_STATUS_REG]); g_cp0_regs[CP0_CONFIG_REG] = UINT32_C(0x6e463); g_cp0_regs[CP0_PREVID_REG] = UINT32_C(0xb00); g_cp0_regs[CP0_COUNT_REG] = UINT32_C(0x5000); g_cp0_regs[CP0_CAUSE_REG] = UINT32_C(0x5C); g_cp0_regs[CP0_CONTEXT_REG] = UINT32_C(0x7FFFF0); g_cp0_regs[CP0_EPC_REG] = UINT32_C(0xFFFFFFFF); g_cp0_regs[CP0_BADVADDR_REG] = UINT32_C(0xFFFFFFFF); g_cp0_regs[CP0_ERROREPC_REG] = UINT32_C(0xFFFFFFFF); update_x86_rounding_mode(FCR31); } static unsigned int get_tv_type(void) { switch(ROM_PARAMS.systemtype) { default: case SYSTEM_NTSC: return 1; case SYSTEM_PAL: return 0; case SYSTEM_MPAL: return 2; } } /* Simulates end result of PIFBootROM execution */ void r4300_reset_soft(void) { uint32_t bsd_dom1_config; unsigned int rom_type = 0; /* 0:Cart, 1:DD */ unsigned int reset_type = 0; /* 0:ColdReset, 1:NMI */ unsigned int s7 = 0; /* ??? */ unsigned int tv_type = get_tv_type(); /* 0:PAL, 1:NTSC, 2:MPAL */ if ((ConfigGetParamInt(g_CoreConfig, "BootDevice") != 0) && (g_ddrom != NULL) && (g_ddrom_size != 0)) { bsd_dom1_config = *(uint32_t*)g_ddrom; rom_type = 1; } else bsd_dom1_config = *(uint32_t*)g_rom; g_cp0_regs[CP0_STATUS_REG] = 0x34000000; g_cp0_regs[CP0_CONFIG_REG] = 0x0006e463; g_sp.regs[SP_STATUS_REG] = 1; g_sp.regs2[SP_PC_REG] = 0; g_pi.regs[PI_BSD_DOM1_LAT_REG] = (bsd_dom1_config ) & 0xff; g_pi.regs[PI_BSD_DOM1_PWD_REG] = (bsd_dom1_config >> 8) & 0xff; g_pi.regs[PI_BSD_DOM1_PGS_REG] = (bsd_dom1_config >> 16) & 0x0f; g_pi.regs[PI_BSD_DOM1_RLS_REG] = (bsd_dom1_config >> 20) & 0x03; g_pi.regs[PI_STATUS_REG] = 0; g_ai.regs[AI_DRAM_ADDR_REG] = 0; g_ai.regs[AI_LEN_REG] = 0; g_vi.regs[VI_V_INTR_REG] = 1023; g_vi.regs[VI_CURRENT_REG] = 0; g_vi.regs[VI_H_START_REG] = 0; g_r4300.mi.regs[MI_INTR_REG] &= ~(MI_INTR_PI | MI_INTR_VI | MI_INTR_AI | MI_INTR_SP); if ((ConfigGetParamInt(g_CoreConfig, "BootDevice") != 0) && (g_ddrom != NULL) && (g_ddrom_size != 0)) memcpy((unsigned char*)g_sp.mem+0x40, g_ddrom+0x40, 0xfc0); else memcpy((unsigned char*)g_sp.mem+0x40, g_rom+0x40, 0xfc0); reg[19] = rom_type; /* s3 */ reg[20] = tv_type; /* s4 */ reg[21] = reset_type; /* s5 */ reg[22] = g_si.pif.cic.seed; /* s6 */ reg[23] = s7; /* s7 */ if ((ConfigGetParamInt(g_CoreConfig, "BootDevice") != 0) && (g_ddrom != NULL) && (g_ddrom_size != 0)) reg[22] = 0xdd; /* required by CIC x105 */ g_sp.mem[0x1000/4] = 0x3c0dbfc0; g_sp.mem[0x1004/4] = 0x8da807fc; g_sp.mem[0x1008/4] = 0x25ad07c0; g_sp.mem[0x100c/4] = 0x31080080; g_sp.mem[0x1010/4] = 0x5500fffc; g_sp.mem[0x1014/4] = 0x3c0dbfc0; g_sp.mem[0x1018/4] = 0x8da80024; g_sp.mem[0x101c/4] = 0x3c0bb000; /* required by CIC x105 */ reg[11] = 0xffffffffa4000040ULL; /* t3 */ reg[29] = 0xffffffffa4001ff0ULL; /* sp */ reg[31] = 0xffffffffa4001550ULL; /* ra */ /* ready to execute IPL3 */ } #if !defined(NO_ASM) && defined(DYNAREC) static void dynarec_setup_code(void) { // The dynarec jumps here after we call dyna_start and it prepares // Here we need to prepare the initial code block and jump to it jump_to(UINT32_C(0xa4000040)); // Prevent segfault on failed jump_to if (!actual->block || !actual->code) dyna_stop(); } #endif void r4300_init(void) { current_instruction_table = cached_interpreter_table; delay_slot=0; stop = 0; rompause = 0; last_addr = 0xa4000040; next_interupt = 624999; init_interupt(); if (r4300emu == CORE_PURE_INTERPRETER) { DebugMessage(M64MSG_INFO, "Starting R4300 emulator: Pure Interpreter"); r4300emu = CORE_PURE_INTERPRETER; pure_interpreter_init(); } #if defined(DYNAREC) else if (r4300emu >= 2) { DebugMessage(M64MSG_INFO, "Starting R4300 emulator: Dynamic Recompiler"); { r4300emu = CORE_DYNAREC; init_blocks(); #ifdef NEW_DYNAREC new_dynarec_init(); #elif !defined(NO_ASM) && defined(DYNAREC) dyna_start(dynarec_setup_code); #endif } } #endif else /* if (r4300emu == CORE_INTERPRETER) */ { DebugMessage(M64MSG_INFO, "Starting R4300 emulator: Cached Interpreter"); r4300emu = CORE_INTERPRETER; init_blocks(); jump_to(UINT32_C(0xa4000040)); /* Prevent segfault on failed jump_to */ if (!actual->block) return; last_addr = PC->addr; } } void r4300_deinit(void) { DebugMessage(M64MSG_INFO, "R4300 emulator finished."); if (r4300emu == CORE_PURE_INTERPRETER) { } #if defined(DYNAREC) else if (r4300emu >= 2) { #ifdef NEW_DYNAREC new_dynarec_cleanup(); free_blocks(); #else PC++; #endif } #endif else /* if (r4300emu == CORE_INTERPRETER) */ { free_blocks(); } } static void (*r4300_step)(void); #if defined(DYNAREC) static void dyna_start_wrapper(void) { #ifdef NEW_DYNAREC new_dyna_start(); #else dyna_start(dyna_jump); #endif } #endif static void pc_ops_wrapper(void) { #ifdef COMPARE_CORE if (PC->ops == cached_interpreter_table.FIN_BLOCK && (PC->addr < 0x80000000 || PC->addr >= 0xc0000000)) virtual_to_physical_address(PC->addr, TLB_FAST_READ); CoreCompareCallback(); #endif #ifdef DBG if (g_DebuggerActive) update_debugger(PC->addr); #endif PC->ops(); } void r4300_execute(void) { if (r4300emu == CORE_PURE_INTERPRETER) r4300_step = pure_interpreter; else if (r4300emu == CORE_INTERPRETER) r4300_step = pc_ops_wrapper; #if defined(DYNAREC) else if (r4300emu >= 2) r4300_step = dyna_start_wrapper; #endif while (!stop) r4300_step(); } mupen64plus-core/src/r4300/cached_interp.h000664 001750 001750 00000004342 12655644434 021352 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - cached_interp.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_R4300_CACHED_INTERP_H #define M64P_R4300_CACHED_INTERP_H #include "ops.h" /* FIXME: use forward declaration for precomp_block */ #include "recomp.h" #include #include extern char invalid_code[0x100000]; extern precomp_block *blocks[0x100000]; extern precomp_block *actual; extern uint32_t jump_to_address; extern const cpu_instruction_table cached_interpreter_table; void init_blocks(void); void free_blocks(void); void jump_to_func(void); void invalidate_cached_code_hacktarux(uint32_t address, size_t size); /* Jumps to the given address. This is for the cached interpreter / dynarec. */ #define jump_to(a) { jump_to_address = a; jump_to_func(); } #endif /* M64P_R4300_CACHED_INTERP_H */ mupen64plus-video-gliden64/src/F3DEX2CBFD.h000664 001750 001750 00000000167 12655644434 021115 0ustar00sergiosergio000000 000000 #ifndef F3DEX2CBFD_H #define F3DEX2CBFD_H #define F3DEX2CBFD_TRI4 16 void F3DEX2CBFD_Init(); #endif // F3DEX2CBFD_H mupen64plus-core/src/r4300/cached_interp.c000664 001750 001750 00000031010 12655644434 021335 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - cached_interp.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #define __STDC_FORMAT_MACROS #include #include "cached_interp.h" #include "api/m64p_types.h" #include "api/callbacks.h" #include "api/debugger.h" #include "main/main.h" #include "memory/memory.h" #include "r4300.h" #include "cp0_private.h" #include "cp1_private.h" #include "ops.h" #include "exception.h" #include "interupt.h" #include "macros.h" #include "recomp.h" #ifdef DBG #include "debugger/dbg_types.h" #include "debugger/debugger.h" #endif /* global variables */ char invalid_code[0x100000]; precomp_block *blocks[0x100000]; precomp_block *actual; unsigned int jump_to_address; uint32_t adler32(uint32_t adler, void *buf, int len); // ----------------------------------------------------------- // Cached interpreter functions (and fallback for dynarec). // ----------------------------------------------------------- #ifdef DBG #define UPDATE_DEBUGGER() if (g_DebuggerActive) update_debugger(PC->addr) #else #define UPDATE_DEBUGGER() do { } while(0) #endif #define PCADDR PC->addr #define ADD_TO_PC(x) PC += x; #define DECLARE_INSTRUCTION(name) static void name(void) #define DECLARE_JUMP(name, destination, condition, link, likely, cop1) \ static void name(void) \ { \ const int take_jump = (condition); \ const uint32_t jump_target = (destination); \ int64_t *link_register = (int64_t*)(link); \ if (cop1 && check_cop1_unusable()) \ return; \ if (link_register != ®[0]) \ *link_register = SE32(PC->addr + 8); \ PC++; \ if (!likely || take_jump) \ { \ delay_slot=1; \ UPDATE_DEBUGGER(); \ PC->ops(); \ cp0_update_count(); \ delay_slot=0; \ if (take_jump && !skip_jump) \ PC=actual->block+((jump_target-actual->start)>>2); \ } \ else \ { \ PC++; \ cp0_update_count(); \ } \ last_addr = PC->addr; \ if (next_interupt <= g_cp0_regs[CP0_COUNT_REG]) gen_interupt(); \ } \ static void name##_OUT(void) \ { \ const int take_jump = (condition); \ const uint32_t jump_target = (destination); \ int64_t *link_register = (int64_t*)(link); \ if (cop1 && check_cop1_unusable()) \ return; \ if (link_register != ®[0]) \ *link_register = SE32(PC->addr + 8); \ PC++; \ if (!likely || take_jump) \ { \ delay_slot=1; \ UPDATE_DEBUGGER(); \ PC->ops(); \ cp0_update_count(); \ delay_slot=0; \ if (take_jump && !skip_jump) \ jump_to(jump_target); \ } \ else \ { \ PC++; \ cp0_update_count(); \ } \ last_addr = PC->addr; \ if (next_interupt <= g_cp0_regs[CP0_COUNT_REG]) gen_interupt(); \ } \ static void name##_IDLE(void) \ { \ const int take_jump = (condition); \ if (cop1 && check_cop1_unusable()) return; \ if (take_jump) \ { \ int skip; \ cp0_update_count(); \ skip = next_interupt - g_cp0_regs[CP0_COUNT_REG]; \ if (skip > 3) g_cp0_regs[CP0_COUNT_REG] += (skip & UINT32_C(0xFFFFFFFC)); \ else name(); \ } \ else name(); \ } #define CHECK_MEMORY() \ if (!invalid_code[address>>12]) \ if (blocks[address>>12]->block[(address&0xFFF)/4].ops != \ current_instruction_table.NOTCOMPILED) \ invalid_code[address>>12] = 1; // two functions are defined from the macros above but never used // these prototype declarations will prevent a warning #if defined(__GNUC__) static void JR_IDLE(void) __attribute__((used)); static void JALR_IDLE(void) __attribute__((used)); #endif #include "interpreter.c" // ----------------------------------------------------------- // Flow control 'fake' instructions // ----------------------------------------------------------- static void FIN_BLOCK(void) { if (!delay_slot) { jump_to((PC-1)->addr+4); #if 0 #ifdef DBG if (g_DebuggerActive) update_debugger(PC->addr); #endif // Used by dynarec only, check should be unnecessary #endif PC->ops(); if (r4300emu == CORE_DYNAREC) dyna_jump(); } else { precomp_block *blk = actual; precomp_instr *inst = PC; jump_to((PC-1)->addr+4); #if 0 #ifdef DBG if (g_DebuggerActive) update_debugger(PC->addr); #endif // Used by dynarec only, check should be unnecessary #endif PC->ops(); if (!skip_jump) { actual = blk; PC = inst+1; } if (r4300emu == CORE_DYNAREC) dyna_jump(); } } static void NOTCOMPILED(void) { uint32_t *mem = fast_mem_access(blocks[PC->addr>>12]->start); #ifdef CORE_DBG DebugMessage(M64MSG_INFO, "NOTCOMPILED: addr = %x ops = %lx", PC->addr, (long) PC->ops); #endif if (mem) recompile_block(mem, blocks[PC->addr >> 12], PC->addr); else DebugMessage(M64MSG_ERROR, "not compiled exception"); #if 0 #ifdef DBG if (g_DebuggerActive) update_debugger(PC->addr); #endif // The preceeding update_debugger SHOULD be unnecessary since it should have been // called before NOTCOMPILED would have been executed #endif PC->ops(); if (r4300emu == CORE_DYNAREC) dyna_jump(); } static void NOTCOMPILED2(void) { NOTCOMPILED(); } // ----------------------------------------------------------- // Cached interpreter instruction table // ----------------------------------------------------------- const cpu_instruction_table cached_interpreter_table = { LB, LBU, LH, LHU, LW, LWL, LWR, SB, SH, SW, SWL, SWR, LD, LDL, LDR, LL, LWU, SC, SD, SDL, SDR, SYNC, ADDI, ADDIU, SLTI, SLTIU, ANDI, ORI, XORI, LUI, DADDI, DADDIU, ADD, ADDU, SUB, SUBU, SLT, SLTU, AND, OR, XOR, NOR, DADD, DADDU, DSUB, DSUBU, MULT, MULTU, DIV, DIVU, MFHI, MTHI, MFLO, MTLO, DMULT, DMULTU, DDIV, DDIVU, J, J_OUT, J_IDLE, JAL, JAL_OUT, JAL_IDLE, // Use the _OUT versions of JR and JALR, since we don't know // until runtime if they're going to jump inside or outside the block JR_OUT, JALR_OUT, BEQ, BEQ_OUT, BEQ_IDLE, BNE, BNE_OUT, BNE_IDLE, BLEZ, BLEZ_OUT, BLEZ_IDLE, BGTZ, BGTZ_OUT, BGTZ_IDLE, BLTZ, BLTZ_OUT, BLTZ_IDLE, BGEZ, BGEZ_OUT, BGEZ_IDLE, BLTZAL, BLTZAL_OUT, BLTZAL_IDLE, BGEZAL, BGEZAL_OUT, BGEZAL_IDLE, BEQL, BEQL_OUT, BEQL_IDLE, BNEL, BNEL_OUT, BNEL_IDLE, BLEZL, BLEZL_OUT, BLEZL_IDLE, BGTZL, BGTZL_OUT, BGTZL_IDLE, BLTZL, BLTZL_OUT, BLTZL_IDLE, BGEZL, BGEZL_OUT, BGEZL_IDLE, BLTZALL, BLTZALL_OUT, BLTZALL_IDLE, BGEZALL, BGEZALL_OUT, BGEZALL_IDLE, BC1TL, BC1TL_OUT, BC1TL_IDLE, BC1FL, BC1FL_OUT, BC1FL_IDLE, SLL, SRL, SRA, SLLV, SRLV, SRAV, DSLL, DSRL, DSRA, DSLLV, DSRLV, DSRAV, DSLL32, DSRL32, DSRA32, MTC0, MFC0, TLBR, TLBWI, TLBWR, TLBP, CACHE, ERET, LWC1, SWC1, MTC1, MFC1, CTC1, CFC1, BC1T, BC1T_OUT, BC1T_IDLE, BC1F, BC1F_OUT, BC1F_IDLE, DMFC1, DMTC1, LDC1, SDC1, CVT_S_D, CVT_S_W, CVT_S_L, CVT_D_S, CVT_D_W, CVT_D_L, CVT_W_S, CVT_W_D, CVT_L_S, CVT_L_D, ROUND_W_S, ROUND_W_D, ROUND_L_S, ROUND_L_D, TRUNC_W_S, TRUNC_W_D, TRUNC_L_S, TRUNC_L_D, CEIL_W_S, CEIL_W_D, CEIL_L_S, CEIL_L_D, FLOOR_W_S, FLOOR_W_D, FLOOR_L_S, FLOOR_L_D, ADD_S, ADD_D, SUB_S, SUB_D, MUL_S, MUL_D, DIV_S, DIV_D, ABS_S, ABS_D, MOV_S, MOV_D, NEG_S, NEG_D, SQRT_S, SQRT_D, C_F_S, C_F_D, C_UN_S, C_UN_D, C_EQ_S, C_EQ_D, C_UEQ_S, C_UEQ_D, C_OLT_S, C_OLT_D, C_ULT_S, C_ULT_D, C_OLE_S, C_OLE_D, C_ULE_S, C_ULE_D, C_SF_S, C_SF_D, C_NGLE_S, C_NGLE_D, C_SEQ_S, C_SEQ_D, C_NGL_S, C_NGL_D, C_LT_S, C_LT_D, C_NGE_S, C_NGE_D, C_LE_S, C_LE_D, C_NGT_S, C_NGT_D, SYSCALL, TEQ, NOP, RESERVED, NI, FIN_BLOCK, NOTCOMPILED, NOTCOMPILED2 }; static unsigned int update_invalid_addr(unsigned int addr) { if (addr >= 0x80000000 && addr < 0xc0000000) { if (invalid_code[addr>>12]) invalid_code[(addr^0x20000000)>>12] = 1; if (invalid_code[(addr^0x20000000)>>12]) invalid_code[addr>>12] = 1; return addr; } else { unsigned int paddr = virtual_to_physical_address(addr, TLB_FAST_READ); if (paddr) { unsigned int beg_paddr = paddr - (addr - (addr&~0xFFF)); update_invalid_addr(paddr); if (invalid_code[(beg_paddr+0x000)>>12]) invalid_code[addr>>12] = 1; if (invalid_code[(beg_paddr+0xFFC)>>12]) invalid_code[addr>>12] = 1; if (invalid_code[addr>>12]) invalid_code[(beg_paddr+0x000)>>12] = 1; if (invalid_code[addr>>12]) invalid_code[(beg_paddr+0xFFC)>>12] = 1; } return paddr; } } #define addr jump_to_address void jump_to_func(void) { unsigned int paddr; if (skip_jump) return; paddr = update_invalid_addr(addr); if (!paddr) return; actual = blocks[addr>>12]; if (invalid_code[addr>>12]) { if (!blocks[addr>>12]) { blocks[addr>>12] = (precomp_block *) malloc(sizeof(precomp_block)); actual = blocks[addr>>12]; blocks[addr>>12]->code = NULL; blocks[addr>>12]->block = NULL; blocks[addr>>12]->jumps_table = NULL; blocks[addr>>12]->riprel_table = NULL; } blocks[addr>>12]->start = addr & ~0xFFF; blocks[addr>>12]->end = (addr & ~0xFFF) + 0x1000; init_block(blocks[addr>>12]); } PC=actual->block+((addr-actual->start)>>2); if (r4300emu == CORE_DYNAREC) dyna_jump(); } #undef addr void init_blocks(void) { int i; for (i=0; i<0x100000; i++) { invalid_code[i] = 1; blocks[i] = NULL; } } void free_blocks(void) { int i; for (i=0; i<0x100000; i++) { if (blocks[i]) { free_block(blocks[i]); free(blocks[i]); blocks[i] = NULL; } } } void invalidate_cached_code_hacktarux(uint32_t address, size_t size) { if (size == 0) { /* invalidate everthing */ memset(invalid_code, 1, 0x100000); } else { uint32_t addr; /* invalidate blocks (if necessary) */ size_t addr_max = address+size; for(addr = address; addr < addr_max; addr += 4) { size_t i = (addr >> 12); if (invalid_code[i] == 0) { if (blocks[i] == NULL || blocks[i]->block[(addr & 0xfff) / 4].ops != current_instruction_table.NOTCOMPILED) { invalid_code[i] = 1; /* go directly to next i */ addr &= ~0xfff; addr |= 0xffc; } } else { /* go directly to next i */ addr &= ~0xfff; addr |= 0xffc; } } } } libretro-common/include/glsym/000700 001750 001750 00000000000 12656647145 017574 5ustar00sergiosergio000000 000000 mupen64plus-video-gliden64/src/glState.cpp000664 001750 001750 00000002123 12655644434 021533 0ustar00sergiosergio000000 000000 #include "OpenGL.h" #ifdef GLSTATE_H void GLState::reset() { cached_ActiveTexture_texture = 0; cached_BlendFunc_sfactor = 0; cached_BlendFunc_dfactor = 0; cached_ReadBufferMode = 0; cached_glPixelStorei_target = 0; cached_glPixelStorei_param = 0; cached_ClearColor_red = 0; cached_ClearColor_green = 0; cached_ClearColor_blue = 0; cached_ClearColor_alpha = 0; cached_CullFace_mode = 0; cached_DepthFunc_func = 0; cached_DepthMask_flag = 0; cached_BLEND = false; cached_CULL_FACE = false; cached_DEPTH_TEST = false; cached_DEPTH_CLAMP = false; cached_CLIP_DISTANCE0 = false; cached_DITHER = false; cached_POLYGON_OFFSET_FILL = false; cached_SAMPLE_ALPHA_TO_COVERAGE = false; cached_SAMPLE_COVERAGE = false; cached_SCISSOR_TEST = false; cached_PolygonOffset_factor = 0; cached_PolygonOffset_units = 0; cached_Scissor_x = 0; cached_Scissor_y = 0; cached_Scissor_width = 0; cached_Scissor_height = 0; cached_UseProgram_program = -1; cached_Viewport_x = 0; cached_Viewport_y = 0; cached_Viewport_width = 0; cached_Viewport_height = 0; } GLState glState; #endif // GLSTATE_H mupen64plus-core/src/main/version.h000664 001750 001750 00000003674 12655644434 020432 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - version.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2008-2012 Richard42 DarkJeztr Tillin9 * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Version macros automatically replaced by Makefiles. */ #ifndef __VERSION_H__ #define __VERSION_H__ #define MUPEN_CORE_NAME "Mupen64Plus Core" #define MUPEN_CORE_VERSION 0x016305 #define FRONTEND_API_VERSION 0x020101 #define CONFIG_API_VERSION 0x020200 #define DEBUG_API_VERSION 0x020000 #define VIDEXT_API_VERSION 0x030000 #define VERSION_PRINTF_SPLIT(x) (((x) >> 16) & 0xffff), (((x) >> 8) & 0xff), ((x) & 0xff) #endif /* __VERSION_H__ */ mupen64plus-core/src/r4300/reset.h000664 001750 001750 00000003444 12655644434 017706 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - reset.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2011 CasualJames * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_R4300_RESET_H #define M64P_R4300_RESET_H /* For hard reset, set reset_hard_job and next interrupt will cause hard reset. * For soft reset, call reset_soft() at any time. */ extern int reset_hard_job; void reset_hard(); void reset_soft(); #endif /* M64P_R4300_RESET_H */ mupen64plus-core/src/debugger/dbg_types.h000664 001750 001750 00000003331 12655644434 021553 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - dbg_types.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 davFr * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef __TYPES_H__ #define __TYPES_H__ typedef unsigned char uint8; typedef unsigned short uint16; typedef unsigned int uint32; typedef unsigned long long uint64; #endif /* __TYPES_H__ */ mupen64plus-core/src/r4300/reset.c000664 001750 001750 00000004637 12655644434 017706 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - reset.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2011 CasualJames * * Copyright (C) 2008-2009 Richard Goedeken * * Copyright (C) 2008 Ebenblues Nmn Okaygo Tillin9 * * Hard reset based on code by hacktarux. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include "r4300/reset.h" #include "r4300/r4300.h" #include "r4300/interupt.h" #include "memory/memory.h" #include "r4300/cached_interp.h" int reset_hard_job = 0; void reset_hard(void) { init_memory(); r4300_reset_hard(); r4300_reset_soft(); last_addr = UINT32_C(0xa4000040); next_interupt = 624999; init_interupt(); if(r4300emu != CORE_PURE_INTERPRETER) { free_blocks(); init_blocks(); } generic_jump_to(last_addr); } void reset_soft(void) { add_interupt_event(HW2_INT, 0); /* Hardware 2 Interrupt immediately */ add_interupt_event(NMI_INT, 50000000); /* Non maskable Interrupt after 1/2 second */ } mupen64plus-core/src/r4300/interpreter.c000664 001750 001750 00000151142 12655644434 021121 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - interpreter.def * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2002 Hacktarux * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Before #including this file, the following macros should be defined: * * PCADDR: Program counter (memory address of the current instruction). * * ADD_TO_PC(x): Increment the program counter in 'x' instructions. * This is only used for small changes to PC, so the new program counter * is guaranteed to fall in the current cached interpreter or dynarec block. * * DECLARE_INSTRUCTION(name) * Declares an instruction function which is not a jump. * Followed by a block of code. * * DECLARE_JUMP(name, destination, condition, link, likely, cop1) * name is the name of the jump or branch instruction. * destination is the destination memory address of the jump. * If condition is nonzero, the jump is taken. * link is a pointer to a variable where (PC+8) is written unconditionally. * To avoid linking, pass ®[0] * If likely is nonzero, the delay slot is only executed if the jump is taken. * If cop1 is nonzero, a COP1 unusable check will be done. * * CHECK_MEMORY(): A snippet to be run after a store instruction, * to check if the store affected executable blocks. * The memory address of the store is in the 'address' global. */ #include "fpu.h" DECLARE_INSTRUCTION(NI) { DebugMessage(M64MSG_ERROR, "NI() @ 0x%x", PCADDR); DebugMessage(M64MSG_ERROR, "opcode not implemented: %x:%x", PCADDR, *fast_mem_access(PCADDR)); stop=1; } DECLARE_INSTRUCTION(RESERVED) { DebugMessage(M64MSG_ERROR, "reserved opcode: %x:%x", PCADDR, *fast_mem_access(PCADDR)); stop=1; } // R4300 DECLARE_JUMP(J, (jinst_index << 2) | ((PCADDR+4) & UINT32_C(0xF0000000)), 1, ®[0], 0, 0) DECLARE_JUMP(JAL, (jinst_index << 2) | ((PCADDR+4) & UINT32_C(0xF0000000)), 1, ®[31], 0, 0) DECLARE_JUMP(BEQ, PCADDR + (iimmediate+1)*4, irs == irt, ®[0], 0, 0) DECLARE_JUMP(BNE, PCADDR + (iimmediate+1)*4, irs != irt, ®[0], 0, 0) DECLARE_JUMP(BLEZ, PCADDR + (iimmediate+1)*4, irs <= 0, ®[0], 0, 0) DECLARE_JUMP(BGTZ, PCADDR + (iimmediate+1)*4, irs > 0, ®[0], 0, 0) DECLARE_INSTRUCTION(ADDI) { irt = SE32(irs32 + iimmediate); ADD_TO_PC(1); } DECLARE_INSTRUCTION(ADDIU) { irt = SE32(irs32 + iimmediate); ADD_TO_PC(1); } DECLARE_INSTRUCTION(SLTI) { if (irs < iimmediate) irt = 1; else irt = 0; ADD_TO_PC(1); } DECLARE_INSTRUCTION(SLTIU) { if ((uint64_t)irs < (uint64_t)((int64_t)iimmediate)) irt = 1; else irt = 0; ADD_TO_PC(1); } DECLARE_INSTRUCTION(ANDI) { irt = irs & (uint16_t)iimmediate; ADD_TO_PC(1); } DECLARE_INSTRUCTION(ORI) { irt = irs | (uint16_t)iimmediate; ADD_TO_PC(1); } DECLARE_INSTRUCTION(XORI) { irt = irs ^ (uint16_t)iimmediate; ADD_TO_PC(1); } DECLARE_INSTRUCTION(LUI) { irt = SE32(iimmediate << 16); ADD_TO_PC(1); } DECLARE_JUMP(BEQL, PCADDR + (iimmediate+1)*4, irs == irt, ®[0], 1, 0) DECLARE_JUMP(BNEL, PCADDR + (iimmediate+1)*4, irs != irt, ®[0], 1, 0) DECLARE_JUMP(BLEZL, PCADDR + (iimmediate+1)*4, irs <= 0, ®[0], 1, 0) DECLARE_JUMP(BGTZL, PCADDR + (iimmediate+1)*4, irs > 0, ®[0], 1, 0) DECLARE_INSTRUCTION(DADDI) { irt = irs + iimmediate; ADD_TO_PC(1); } DECLARE_INSTRUCTION(DADDIU) { irt = irs + iimmediate; ADD_TO_PC(1); } // TODOXXX refactor the following functions to remove the // lsaddr and lsrpt locals. this may lead to a small speedup too DECLARE_INSTRUCTION(LDL) { const uint32_t lsaddr = irs32 + iimmediate; int64_t *lsrtp = (int64_t*)&irt; uint64_t word = 0; ADD_TO_PC(1); switch ((lsaddr) & 7) { case 0: address = lsaddr; rdword = (uint64_t*)lsrtp; read_dword_in_memory(); break; case 1: address = lsaddr & 0xFFFFFFF8; rdword = &word; read_dword_in_memory(); if(address) *lsrtp = (*lsrtp & 0xFF) | (word << 8); break; case 2: address = lsaddr & 0xFFFFFFF8; rdword = &word; read_dword_in_memory(); if(address) *lsrtp = (*lsrtp & 0xFFFF) | (word << 16); break; case 3: address = lsaddr & 0xFFFFFFF8; rdword = &word; read_dword_in_memory(); if(address) *lsrtp = (*lsrtp & 0xFFFFFF) | (word << 24); break; case 4: address = lsaddr & 0xFFFFFFF8; rdword = &word; read_dword_in_memory(); if(address) *lsrtp = (*lsrtp & 0xFFFFFFFF) | (word << 32); break; case 5: address = lsaddr & 0xFFFFFFF8; rdword = &word; read_dword_in_memory(); if(address) *lsrtp = (*lsrtp & 0xFFFFFFFFFFLL) | (word << 40); break; case 6: address = lsaddr & 0xFFFFFFF8; rdword = &word; read_dword_in_memory(); if(address) *lsrtp = (*lsrtp & 0xFFFFFFFFFFFFLL) | (word << 48); break; case 7: address = lsaddr & 0xFFFFFFF8; rdword = &word; read_dword_in_memory(); if(address) *lsrtp = (*lsrtp & 0xFFFFFFFFFFFFFFLL) | (word << 56); break; } } DECLARE_INSTRUCTION(LDR) { const uint32_t lsaddr = irs32 + iimmediate; int64_t *lsrtp = (int64_t*)&irt; uint64_t word = 0; ADD_TO_PC(1); switch ((lsaddr) & 7) { case 0: address = lsaddr & 0xFFFFFFF8; rdword = &word; read_dword_in_memory(); if(address) *lsrtp = (*lsrtp & 0xFFFFFFFFFFFFFF00LL) | (word >> 56); break; case 1: address = lsaddr & 0xFFFFFFF8; rdword = &word; read_dword_in_memory(); if(address) *lsrtp = (*lsrtp & 0xFFFFFFFFFFFF0000LL) | (word >> 48); break; case 2: address = lsaddr & 0xFFFFFFF8; rdword = &word; read_dword_in_memory(); if(address) *lsrtp = (*lsrtp & 0xFFFFFFFFFF000000LL) | (word >> 40); break; case 3: address = lsaddr & 0xFFFFFFF8; rdword = &word; read_dword_in_memory(); if(address) *lsrtp = (*lsrtp & 0xFFFFFFFF00000000LL) | (word >> 32); break; case 4: address = lsaddr & 0xFFFFFFF8; rdword = &word; read_dword_in_memory(); if(address) *lsrtp = (*lsrtp & 0xFFFFFF0000000000LL) | (word >> 24); break; case 5: address = lsaddr & 0xFFFFFFF8; rdword = &word; read_dword_in_memory(); if(address) *lsrtp = (*lsrtp & 0xFFFF000000000000LL) | (word >> 16); break; case 6: address = lsaddr & 0xFFFFFFF8; rdword = &word; read_dword_in_memory(); if(address) *lsrtp = (*lsrtp & 0xFF00000000000000LL) | (word >> 8); break; case 7: address = lsaddr & 0xFFFFFFF8; rdword = (uint64_t*) lsrtp; read_dword_in_memory(); break; } } DECLARE_INSTRUCTION(LB) { const uint32_t lsaddr = irs32 + iimmediate; int64_t *lsrtp = (int64_t*)&irt; ADD_TO_PC(1); address = lsaddr; rdword = (uint64_t*)lsrtp; read_byte_in_memory(); if (address) *lsrtp = SE8(*lsrtp); } DECLARE_INSTRUCTION(LH) { const uint32_t lsaddr = irs32 + iimmediate; int64_t *lsrtp = (int64_t*)&irt; ADD_TO_PC(1); address = lsaddr; rdword = (uint64_t*) lsrtp; read_hword_in_memory(); if (address) *lsrtp = SE16(*lsrtp); } DECLARE_INSTRUCTION(LWL) { const uint32_t lsaddr = irs32 + iimmediate; int64_t *lsrtp = (int64_t*)&irt; uint64_t word = 0; ADD_TO_PC(1); switch ((lsaddr) & 3) { case 0: address = lsaddr; rdword = (uint64_t*) lsrtp; read_word_in_memory(); break; case 1: address = lsaddr & 0xFFFFFFFC; rdword = &word; read_word_in_memory(); if(address) *lsrtp = (*lsrtp & 0xFF) | (word << 8); break; case 2: address = lsaddr & 0xFFFFFFFC; rdword = &word; read_word_in_memory(); if(address) *lsrtp = (*lsrtp & 0xFFFF) | (word << 16); break; case 3: address = lsaddr & 0xFFFFFFFC; rdword = &word; read_word_in_memory(); if(address) *lsrtp = (*lsrtp & 0xFFFFFF) | (word << 24); break; } if(address) *lsrtp = SE32(*lsrtp); } DECLARE_INSTRUCTION(LW) { const uint32_t lsaddr = irs32 + iimmediate; int64_t *lsrtp = (int64_t*)&irt; ADD_TO_PC(1); address = lsaddr; rdword = (uint64_t*) lsrtp; read_word_in_memory(); if (address) *lsrtp = SE32(*lsrtp); } DECLARE_INSTRUCTION(LBU) { const uint32_t lsaddr = irs32 + iimmediate; int64_t *lsrtp = (int64_t*)&irt; ADD_TO_PC(1); address = lsaddr; rdword = (uint64_t*) lsrtp; read_byte_in_memory(); } DECLARE_INSTRUCTION(LHU) { const uint32_t lsaddr = irs32 + iimmediate; int64_t *lsrtp = (int64_t*)&irt; ADD_TO_PC(1); address = lsaddr; rdword = (uint64_t*) lsrtp; read_hword_in_memory(); } DECLARE_INSTRUCTION(LWR) { const uint32_t lsaddr = irs32 + iimmediate; int64_t *lsrtp = (int64_t*)&irt; uint64_t word = 0; ADD_TO_PC(1); switch ((lsaddr) & 3) { case 0: address = lsaddr & 0xFFFFFFFC; rdword = &word; read_word_in_memory(); if(address) *lsrtp = (*lsrtp & 0xFFFFFFFFFFFFFF00LL) | ((word >> 24) & 0xFF); break; case 1: address = lsaddr & 0xFFFFFFFC; rdword = &word; read_word_in_memory(); if(address) *lsrtp = (*lsrtp & 0xFFFFFFFFFFFF0000LL) | ((word >> 16) & 0xFFFF); break; case 2: address = lsaddr & 0xFFFFFFFC; rdword = &word; read_word_in_memory(); if(address) *lsrtp = (*lsrtp & 0xFFFFFFFFFF000000LL) | ((word >> 8) & 0XFFFFFF); break; case 3: address = lsaddr & 0xFFFFFFFC; rdword = (uint64_t*) lsrtp; read_word_in_memory(); if(address) *lsrtp = SE32(*lsrtp); } } DECLARE_INSTRUCTION(LWU) { const uint32_t lsaddr = irs32 + iimmediate; int64_t *lsrtp = (int64_t*)&irt; ADD_TO_PC(1); address = lsaddr; rdword = (uint64_t*) lsrtp; read_word_in_memory(); } DECLARE_INSTRUCTION(SB) { const uint32_t lsaddr = irs32 + iimmediate; int64_t *lsrtp = (int64_t*)&irt; ADD_TO_PC(1); address = lsaddr; cpu_byte = (uint8_t)(*lsrtp & 0xFF); write_byte_in_memory(); CHECK_MEMORY(); } DECLARE_INSTRUCTION(SH) { const uint32_t lsaddr = irs32 + iimmediate; int64_t *lsrtp = (int64_t*)&irt; ADD_TO_PC(1); address = lsaddr; hword = (uint16_t)(*lsrtp & 0xFFFF); write_hword_in_memory(); CHECK_MEMORY(); } DECLARE_INSTRUCTION(SWL) { const uint32_t lsaddr = irs32 + iimmediate; int64_t *lsrtp = (int64_t*)&irt; uint64_t old_word = 0; ADD_TO_PC(1); switch ((lsaddr) & 3) { case 0: address = lsaddr & 0xFFFFFFFC; word = (uint32_t)*lsrtp; write_word_in_memory(); CHECK_MEMORY(); break; case 1: address = lsaddr & 0xFFFFFFFC; rdword = &old_word; read_word_in_memory(); if(address) { word = ((uint32_t)*lsrtp >> 8) | ((uint32_t) old_word & 0xFF000000); write_word_in_memory(); CHECK_MEMORY(); } break; case 2: address = lsaddr & 0xFFFFFFFC; rdword = &old_word; read_word_in_memory(); if(address) { word = ((uint32_t)*lsrtp >> 16) | ((uint32_t) old_word & 0xFFFF0000); write_word_in_memory(); CHECK_MEMORY(); } break; case 3: address = lsaddr; cpu_byte = (uint8_t)(*lsrtp >> 24); write_byte_in_memory(); CHECK_MEMORY(); break; } } DECLARE_INSTRUCTION(SW) { const uint32_t lsaddr = irs32 + iimmediate; int64_t *lsrtp = (int64_t*)&irt; ADD_TO_PC(1); address = lsaddr; word = (uint32_t)(*lsrtp & 0xFFFFFFFF); write_word_in_memory(); CHECK_MEMORY(); } DECLARE_INSTRUCTION(SDL) { const uint32_t lsaddr = (uint32_t)(iimmediate + irs32); int64_t *lsrtp = (int64_t*)&irt; uint64_t old_word = 0; ADD_TO_PC(1); switch ((lsaddr) & 7) { case 0: address = lsaddr & 0xFFFFFFF8; dword = *lsrtp; write_dword_in_memory(); CHECK_MEMORY(); break; case 1: address = lsaddr & 0xFFFFFFF8; rdword = &old_word; read_dword_in_memory(); if(address) { dword = ((uint64_t)*lsrtp >> 8)|(old_word & 0xFF00000000000000LL); write_dword_in_memory(); CHECK_MEMORY(); } break; case 2: address = lsaddr & 0xFFFFFFF8; rdword = &old_word; read_dword_in_memory(); if(address) { dword = ((uint64_t)*lsrtp >> 16)|(old_word & 0xFFFF000000000000LL); write_dword_in_memory(); CHECK_MEMORY(); } break; case 3: address = lsaddr & 0xFFFFFFF8; rdword = &old_word; read_dword_in_memory(); if(address) { dword = ((uint64_t)*lsrtp >> 24)|(old_word & 0xFFFFFF0000000000LL); write_dword_in_memory(); CHECK_MEMORY(); } break; case 4: address = lsaddr & 0xFFFFFFF8; rdword = &old_word; read_dword_in_memory(); if(address) { dword = ((uint64_t)*lsrtp >> 32)|(old_word & 0xFFFFFFFF00000000LL); write_dword_in_memory(); CHECK_MEMORY(); } break; case 5: address = lsaddr & 0xFFFFFFF8; rdword = &old_word; read_dword_in_memory(); if(address) { dword = ((uint64_t)*lsrtp >> 40)|(old_word & 0xFFFFFFFFFF000000LL); write_dword_in_memory(); CHECK_MEMORY(); } break; case 6: address = lsaddr & 0xFFFFFFF8; rdword = &old_word; read_dword_in_memory(); if(address) { dword = ((uint64_t)*lsrtp >> 48)|(old_word & 0xFFFFFFFFFFFF0000LL); write_dword_in_memory(); CHECK_MEMORY(); } break; case 7: address = lsaddr & 0xFFFFFFF8; rdword = &old_word; read_dword_in_memory(); if(address) { dword = ((uint64_t)*lsrtp >> 56)|(old_word & 0xFFFFFFFFFFFFFF00LL); write_dword_in_memory(); CHECK_MEMORY(); } break; } } DECLARE_INSTRUCTION(SDR) { const uint32_t lsaddr = irs32 + iimmediate; int64_t *lsrtp = (int64_t*)&irt; uint64_t old_word = 0; ADD_TO_PC(1); switch ((lsaddr) & 7) { case 0: address = lsaddr; rdword = &old_word; read_dword_in_memory(); if(address) { dword = (*lsrtp << 56) | (old_word & 0x00FFFFFFFFFFFFFFLL); write_dword_in_memory(); CHECK_MEMORY(); } break; case 1: address = lsaddr & 0xFFFFFFF8; rdword = &old_word; read_dword_in_memory(); if(address) { dword = (*lsrtp << 48) | (old_word & 0x0000FFFFFFFFFFFFLL); write_dword_in_memory(); CHECK_MEMORY(); } break; case 2: address = lsaddr & 0xFFFFFFF8; rdword = &old_word; read_dword_in_memory(); if(address) { dword = (*lsrtp << 40) | (old_word & 0x000000FFFFFFFFFFLL); write_dword_in_memory(); CHECK_MEMORY(); } break; case 3: address = ((uint32_t) lsaddr) & 0xFFFFFFF8; rdword = &old_word; read_dword_in_memory(); if(address) { dword = (*lsrtp << 32) | (old_word & 0x00000000FFFFFFFFLL); write_dword_in_memory(); CHECK_MEMORY(); } break; case 4: address = ((uint32_t) lsaddr) & 0xFFFFFFF8; rdword = &old_word; read_dword_in_memory(); if(address) { dword = (*lsrtp << 24) | (old_word & 0x0000000000FFFFFFLL); write_dword_in_memory(); CHECK_MEMORY(); } break; case 5: address = ((uint32_t) lsaddr) & 0xFFFFFFF8; rdword = &old_word; read_dword_in_memory(); if(address) { dword = (*lsrtp << 16) | (old_word & 0x000000000000FFFFLL); write_dword_in_memory(); CHECK_MEMORY(); } break; case 6: address = ((uint32_t) lsaddr) & 0xFFFFFFF8; rdword = &old_word; read_dword_in_memory(); if(address) { dword = (*lsrtp << 8) | (old_word & 0x00000000000000FFLL); write_dword_in_memory(); CHECK_MEMORY(); } break; case 7: address = ((uint32_t) lsaddr) & 0xFFFFFFF8; dword = *lsrtp; write_dword_in_memory(); CHECK_MEMORY(); break; } } DECLARE_INSTRUCTION(SWR) { const uint32_t lsaddr = irs32 + iimmediate; int64_t *lsrtp = (int64_t*)&irt; uint64_t old_word = 0; ADD_TO_PC(1); switch ((lsaddr) & 3) { case 0: address = lsaddr; rdword = &old_word; read_word_in_memory(); if(address) { word = ((uint32_t)*lsrtp << 24) | ((uint32_t)old_word & 0x00FFFFFF); write_word_in_memory(); CHECK_MEMORY(); } break; case 1: address = lsaddr & 0xFFFFFFFC; rdword = &old_word; read_word_in_memory(); if(address) { word = ((uint32_t)*lsrtp << 16) | ((uint32_t)old_word & 0x0000FFFF); write_word_in_memory(); CHECK_MEMORY(); } break; case 2: address = lsaddr & 0xFFFFFFFC; rdword = &old_word; read_word_in_memory(); if(address) { word = ((uint32_t)*lsrtp << 8) | ((uint32_t) old_word & 0x000000FF); write_word_in_memory(); CHECK_MEMORY(); } break; case 3: address = lsaddr & 0xFFFFFFFC; word = (uint32_t)*lsrtp; write_word_in_memory(); CHECK_MEMORY(); break; } } DECLARE_INSTRUCTION(CACHE) { ADD_TO_PC(1); } DECLARE_INSTRUCTION(LL) { const uint32_t lsaddr = irs32 + iimmediate; int64_t *lsrtp = (int64_t*)&irt; ADD_TO_PC(1); address = lsaddr; rdword = (uint64_t*) lsrtp; read_word_in_memory(); if (address) { *lsrtp = SE32(*lsrtp); llbit = 1; } } DECLARE_INSTRUCTION(LWC1) { const uint8_t lslfft = lfft; const uint32_t lslfaddr = (uint32_t)(lfoffset + reg[lfbase]); uint64_t temp; if (check_cop1_unusable()) return; ADD_TO_PC(1); address = lslfaddr; rdword = &temp; read_word_in_memory(); if (address) *((uint32_t*)reg_cop1_simple[lslfft]) = (uint32_t) *rdword; } DECLARE_INSTRUCTION(LDC1) { const uint8_t lslfft = lfft; const uint32_t lslfaddr = (uint32_t)(lfoffset + reg[lfbase]); if (check_cop1_unusable()) return; ADD_TO_PC(1); address = lslfaddr; rdword = (uint64_t*)reg_cop1_double[lslfft]; read_dword_in_memory(); } DECLARE_INSTRUCTION(LD) { const uint32_t lsaddr = irs32 + iimmediate; int64_t *lsrtp = (int64_t*)&irt; ADD_TO_PC(1); address = lsaddr; rdword = (uint64_t*) lsrtp; read_dword_in_memory(); } DECLARE_INSTRUCTION(SC) { const uint32_t lsaddr = irs32 + iimmediate; int64_t *lsrtp = (int64_t*)&irt; ADD_TO_PC(1); if(llbit) { address = lsaddr; word = (uint32_t)(*lsrtp & 0xFFFFFFFF); write_word_in_memory(); CHECK_MEMORY(); llbit = 0; *lsrtp = 1; } else *lsrtp = 0; } DECLARE_INSTRUCTION(SWC1) { const uint8_t lslfft = lfft; const uint32_t lslfaddr = (uint32_t)(lfoffset + reg[lfbase]); if (check_cop1_unusable()) return; ADD_TO_PC(1); address = lslfaddr; word = *((uint32_t*)reg_cop1_simple[lslfft]); write_word_in_memory(); CHECK_MEMORY(); } DECLARE_INSTRUCTION(SDC1) { const uint8_t lslfft = lfft; const uint32_t lslfaddr = (uint32_t)(lfoffset + reg[lfbase]); if (check_cop1_unusable()) return; ADD_TO_PC(1); address = lslfaddr; dword = *((uint64_t*)reg_cop1_double[lslfft]); write_dword_in_memory(); CHECK_MEMORY(); } DECLARE_INSTRUCTION(SD) { const uint32_t lsaddr = (uint32_t)(iimmediate + irs32); int64_t *lsrtp = (int64_t*)&irt; ADD_TO_PC(1); address = lsaddr; dword = *lsrtp; write_dword_in_memory(); CHECK_MEMORY(); } // COP0 DECLARE_INSTRUCTION(MFC0) { switch(rfs) { case 1: DebugMessage(M64MSG_ERROR, "MFC0 instruction reading un-implemented Random register"); stop=1; case CP0_COUNT_REG: cp0_update_count(); default: rrt = SE32(g_cp0_regs[rfs]); } ADD_TO_PC(1); } DECLARE_INSTRUCTION(MTC0) { switch(rfs) { case CP0_INDEX_REG: g_cp0_regs[CP0_INDEX_REG] = rrt32 & UINT32_C(0x8000003F); if ((g_cp0_regs[CP0_INDEX_REG] & UINT32_C(0x3F)) > UINT32_C(31)) { DebugMessage(M64MSG_ERROR, "MTC0 instruction writing Index register with TLB index > 31"); stop=1; } break; case CP0_RANDOM_REG: break; case CP0_ENTRYLO0_REG: g_cp0_regs[CP0_ENTRYLO0_REG] = rrt32 & UINT32_C(0x3FFFFFFF); break; case CP0_ENTRYLO1_REG: g_cp0_regs[CP0_ENTRYLO1_REG] = rrt32 & UINT32_C(0x3FFFFFFF); break; case CP0_CONTEXT_REG: g_cp0_regs[CP0_CONTEXT_REG] = (rrt32 & UINT32_C(0xFF800000)) | (g_cp0_regs[CP0_CONTEXT_REG] & UINT32_C(0x007FFFF0)); break; case CP0_PAGEMASK_REG: g_cp0_regs[CP0_PAGEMASK_REG] = rrt32 & 0x01FFE000; break; case CP0_WIRED_REG: g_cp0_regs[CP0_WIRED_REG] = rrt32; g_cp0_regs[CP0_RANDOM_REG] = UINT32_C(31); break; case CP0_BADVADDR_REG: break; case CP0_COUNT_REG: cp0_update_count(); interupt_unsafe_state = 1; if (next_interupt <= g_cp0_regs[CP0_COUNT_REG]) gen_interupt(); interupt_unsafe_state = 0; translate_event_queue(rrt32); g_cp0_regs[CP0_COUNT_REG] = rrt32; break; case CP0_ENTRYHI_REG: g_cp0_regs[CP0_ENTRYHI_REG] = rrt32 & UINT32_C(0xFFFFE0FF); break; case CP0_COMPARE_REG: cp0_update_count(); remove_event(COMPARE_INT); add_interupt_event_count(COMPARE_INT, rrt32); g_cp0_regs[CP0_COMPARE_REG] = rrt32; g_cp0_regs[CP0_CAUSE_REG] &= UINT32_C(0xFFFF7FFF); //Timer interupt is clear break; case CP0_STATUS_REG: if((rrt32 & UINT32_C(0x04000000)) != (g_cp0_regs[CP0_STATUS_REG] & UINT32_C(0x04000000))) { shuffle_fpr_data(g_cp0_regs[CP0_STATUS_REG], rrt32); set_fpr_pointers(rrt32); } g_cp0_regs[CP0_STATUS_REG] = rrt32; cp0_update_count(); ADD_TO_PC(1); check_interupt(); interupt_unsafe_state = 1; if (next_interupt <= g_cp0_regs[CP0_COUNT_REG]) gen_interupt(); interupt_unsafe_state = 0; ADD_TO_PC(-1); break; case CP0_CAUSE_REG: if (rrt32 != 0) { DebugMessage(M64MSG_ERROR, "MTC0 instruction trying to write Cause register with non-0 value"); stop = 1; } else g_cp0_regs[CP0_CAUSE_REG] = rrt32; break; case CP0_EPC_REG: g_cp0_regs[CP0_EPC_REG] = rrt32; break; case CP0_PREVID_REG: break; case CP0_CONFIG_REG: g_cp0_regs[CP0_CONFIG_REG] = rrt32; break; case CP0_WATCHLO_REG: g_cp0_regs[CP0_WATCHLO_REG] = rrt32; break; case CP0_WATCHHI_REG: g_cp0_regs[CP0_WATCHHI_REG] = rrt32; break; case 27: // CacheErr break; case CP0_TAGLO_REG: g_cp0_regs[CP0_TAGLO_REG] = rrt32 & UINT32_C(0x0FFFFFC0); break; case CP0_TAGHI_REG: g_cp0_regs[CP0_TAGHI_REG] = 0; break; default: DebugMessage(M64MSG_ERROR, "Unknown MTC0 write: %d", rfs); stop=1; } ADD_TO_PC(1); } // COP1 DECLARE_JUMP(BC1F, PCADDR + (iimmediate+1)*4, (FCR31 & FCR31_CMP_BIT)==0, ®[0], 0, 1) DECLARE_JUMP(BC1T, PCADDR + (iimmediate+1)*4, (FCR31 & FCR31_CMP_BIT)!=0, ®[0], 0, 1) DECLARE_JUMP(BC1FL, PCADDR + (iimmediate+1)*4, (FCR31 & FCR31_CMP_BIT)==0, ®[0], 1, 1) DECLARE_JUMP(BC1TL, PCADDR + (iimmediate+1)*4, (FCR31 & FCR31_CMP_BIT)!=0, ®[0], 1, 1) DECLARE_INSTRUCTION(MFC1) { if (check_cop1_unusable()) return; rrt = SE32(*((int32_t*)reg_cop1_simple[rfs])); ADD_TO_PC(1); } DECLARE_INSTRUCTION(DMFC1) { if (check_cop1_unusable()) return; rrt = *((int64_t*)reg_cop1_double[rfs]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(CFC1) { if (check_cop1_unusable()) return; switch (rfs) { case 31: rrt32 = SE32(FCR31); break; case 0: rrt32 = SE32(FCR0); break; } ADD_TO_PC(1); } DECLARE_INSTRUCTION(MTC1) { if (check_cop1_unusable()) return; *((int32_t*)reg_cop1_simple[rfs]) = rrt32; ADD_TO_PC(1); } DECLARE_INSTRUCTION(DMTC1) { if (check_cop1_unusable()) return; *((int64_t*)reg_cop1_double[rfs]) = rrt; ADD_TO_PC(1); } DECLARE_INSTRUCTION(CTC1) { if (check_cop1_unusable()) return; if (rfs==31) { FCR31 = rrt32; update_x86_rounding_mode(rrt32); } //if ((FCR31 >> 7) & 0x1F) printf("FPU Exception enabled : %x\n", // (int)((FCR31 >> 7) & 0x1F)); ADD_TO_PC(1); } // COP1_D DECLARE_INSTRUCTION(ADD_D) { if (check_cop1_unusable()) return; add_d(reg_cop1_double[cffs], reg_cop1_double[cfft], reg_cop1_double[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(SUB_D) { if (check_cop1_unusable()) return; sub_d(reg_cop1_double[cffs], reg_cop1_double[cfft], reg_cop1_double[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(MUL_D) { if (check_cop1_unusable()) return; mul_d(reg_cop1_double[cffs], reg_cop1_double[cfft], reg_cop1_double[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(DIV_D) { if (check_cop1_unusable()) return; if((FCR31 & UINT32_C(0x400)) && *reg_cop1_double[cfft] == 0) { //FCR31 |= 0x8020; /*FCR31 |= 0x8000; g_cp0_regs[CP0_CAUSE_REG] = 15 << 2; exception_general();*/ DebugMessage(M64MSG_ERROR, "DIV_D by 0"); //return; } div_d(reg_cop1_double[cffs], reg_cop1_double[cfft], reg_cop1_double[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(SQRT_D) { if (check_cop1_unusable()) return; sqrt_d(reg_cop1_double[cffs], reg_cop1_double[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(ABS_D) { if (check_cop1_unusable()) return; abs_d(reg_cop1_double[cffs], reg_cop1_double[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(MOV_D) { if (check_cop1_unusable()) return; mov_d(reg_cop1_double[cffs], reg_cop1_double[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(NEG_D) { if (check_cop1_unusable()) return; neg_d(reg_cop1_double[cffs], reg_cop1_double[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(ROUND_L_D) { if (check_cop1_unusable()) return; round_l_d(reg_cop1_double[cffs], (int64_t*)(reg_cop1_double[cffd])); ADD_TO_PC(1); } DECLARE_INSTRUCTION(TRUNC_L_D) { if (check_cop1_unusable()) return; trunc_l_d(reg_cop1_double[cffs], (int64_t*)(reg_cop1_double[cffd])); ADD_TO_PC(1); } DECLARE_INSTRUCTION(CEIL_L_D) { if (check_cop1_unusable()) return; ceil_l_d(reg_cop1_double[cffs], (int64_t*)(reg_cop1_double[cffd])); ADD_TO_PC(1); } DECLARE_INSTRUCTION(FLOOR_L_D) { if (check_cop1_unusable()) return; floor_l_d(reg_cop1_double[cffs], (int64_t*)(reg_cop1_double[cffd])); ADD_TO_PC(1); } DECLARE_INSTRUCTION(ROUND_W_D) { if (check_cop1_unusable()) return; round_w_d(reg_cop1_double[cffs], (int32_t*)reg_cop1_simple[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(TRUNC_W_D) { if (check_cop1_unusable()) return; trunc_w_d(reg_cop1_double[cffs], (int32_t*)reg_cop1_simple[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(CEIL_W_D) { if (check_cop1_unusable()) return; ceil_w_d(reg_cop1_double[cffs], (int32_t*)reg_cop1_simple[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(FLOOR_W_D) { if (check_cop1_unusable()) return; floor_w_d(reg_cop1_double[cffs], (int32_t*)reg_cop1_simple[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(CVT_S_D) { if (check_cop1_unusable()) return; cvt_s_d(reg_cop1_double[cffs], reg_cop1_simple[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(CVT_W_D) { if (check_cop1_unusable()) return; cvt_w_d(reg_cop1_double[cffs], (int32_t*)reg_cop1_simple[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(CVT_L_D) { if (check_cop1_unusable()) return; cvt_l_d(reg_cop1_double[cffs], (int64_t*)(reg_cop1_double[cffd])); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_F_D) { if (check_cop1_unusable()) return; c_f_d(); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_UN_D) { if (check_cop1_unusable()) return; c_un_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_EQ_D) { if (check_cop1_unusable()) return; c_eq_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_UEQ_D) { if (check_cop1_unusable()) return; c_ueq_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_OLT_D) { if (check_cop1_unusable()) return; c_olt_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_ULT_D) { if (check_cop1_unusable()) return; c_ult_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_OLE_D) { if (check_cop1_unusable()) return; c_ole_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_ULE_D) { if (check_cop1_unusable()) return; c_ule_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_SF_D) { if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft])) { DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); stop=1; } c_sf_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_NGLE_D) { if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft])) { DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); stop=1; } c_ngle_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_SEQ_D) { if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft])) { DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); stop=1; } c_seq_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_NGL_D) { if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft])) { DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); stop=1; } c_ngl_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_LT_D) { if (check_cop1_unusable()) return; if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft])) { DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); stop=1; } c_lt_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_NGE_D) { if (check_cop1_unusable()) return; if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft])) { DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); stop=1; } c_nge_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_LE_D) { if (check_cop1_unusable()) return; if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft])) { DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); stop=1; } c_le_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_NGT_D) { if (check_cop1_unusable()) return; if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft])) { DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); stop=1; } c_ngt_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); ADD_TO_PC(1); } // COP1_L DECLARE_INSTRUCTION(CVT_S_L) { if (check_cop1_unusable()) return; cvt_s_l((int64_t*)(reg_cop1_double[cffs]), reg_cop1_simple[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(CVT_D_L) { if (check_cop1_unusable()) return; cvt_d_l((int64_t*)(reg_cop1_double[cffs]), reg_cop1_double[cffd]); ADD_TO_PC(1); } // COP1_S DECLARE_INSTRUCTION(ADD_S) { if (check_cop1_unusable()) return; add_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft], reg_cop1_simple[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(SUB_S) { if (check_cop1_unusable()) return; sub_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft], reg_cop1_simple[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(MUL_S) { if (check_cop1_unusable()) return; mul_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft], reg_cop1_simple[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(DIV_S) { if (check_cop1_unusable()) return; if((FCR31 & 0x400) && *reg_cop1_simple[cfft] == 0) { DebugMessage(M64MSG_ERROR, "DIV_S by 0"); } div_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft], reg_cop1_simple[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(SQRT_S) { if (check_cop1_unusable()) return; sqrt_s(reg_cop1_simple[cffs], reg_cop1_simple[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(ABS_S) { if (check_cop1_unusable()) return; abs_s(reg_cop1_simple[cffs], reg_cop1_simple[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(MOV_S) { if (check_cop1_unusable()) return; mov_s(reg_cop1_simple[cffs], reg_cop1_simple[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(NEG_S) { if (check_cop1_unusable()) return; neg_s(reg_cop1_simple[cffs], reg_cop1_simple[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(ROUND_L_S) { if (check_cop1_unusable()) return; round_l_s(reg_cop1_simple[cffs], (int64_t*)(reg_cop1_double[cffd])); ADD_TO_PC(1); } DECLARE_INSTRUCTION(TRUNC_L_S) { if (check_cop1_unusable()) return; trunc_l_s(reg_cop1_simple[cffs], (int64_t*)(reg_cop1_double[cffd])); ADD_TO_PC(1); } DECLARE_INSTRUCTION(CEIL_L_S) { if (check_cop1_unusable()) return; ceil_l_s(reg_cop1_simple[cffs], (int64_t*)(reg_cop1_double[cffd])); ADD_TO_PC(1); } DECLARE_INSTRUCTION(FLOOR_L_S) { if (check_cop1_unusable()) return; floor_l_s(reg_cop1_simple[cffs], (int64_t*)(reg_cop1_double[cffd])); ADD_TO_PC(1); } DECLARE_INSTRUCTION(ROUND_W_S) { if (check_cop1_unusable()) return; round_w_s(reg_cop1_simple[cffs], (int32_t*)reg_cop1_simple[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(TRUNC_W_S) { if (check_cop1_unusable()) return; trunc_w_s(reg_cop1_simple[cffs], (int32_t*)reg_cop1_simple[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(CEIL_W_S) { if (check_cop1_unusable()) return; ceil_w_s(reg_cop1_simple[cffs], (int32_t*)reg_cop1_simple[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(FLOOR_W_S) { if (check_cop1_unusable()) return; floor_w_s(reg_cop1_simple[cffs], (int32_t*)reg_cop1_simple[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(CVT_D_S) { if (check_cop1_unusable()) return; cvt_d_s(reg_cop1_simple[cffs], reg_cop1_double[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(CVT_W_S) { if (check_cop1_unusable()) return; cvt_w_s(reg_cop1_simple[cffs], (int32_t*)reg_cop1_simple[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(CVT_L_S) { if (check_cop1_unusable()) return; cvt_l_s(reg_cop1_simple[cffs], (int64_t*)(reg_cop1_double[cffd])); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_F_S) { if (check_cop1_unusable()) return; c_f_s(); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_UN_S) { if (check_cop1_unusable()) return; c_un_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_EQ_S) { if (check_cop1_unusable()) return; c_eq_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_UEQ_S) { if (check_cop1_unusable()) return; c_ueq_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_OLT_S) { if (check_cop1_unusable()) return; c_olt_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_ULT_S) { if (check_cop1_unusable()) return; c_ult_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_OLE_S) { if (check_cop1_unusable()) return; c_ole_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_ULE_S) { if (check_cop1_unusable()) return; c_ule_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_SF_S) { if (check_cop1_unusable()) return; if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft])) { DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); stop=1; } c_sf_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_NGLE_S) { if (check_cop1_unusable()) return; if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft])) { DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); stop=1; } c_ngle_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_SEQ_S) { if (check_cop1_unusable()) return; if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft])) { DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); stop=1; } c_seq_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_NGL_S) { if (check_cop1_unusable()) return; if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft])) { DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); stop=1; } c_ngl_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_LT_S) { if (check_cop1_unusable()) return; if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft])) { DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); stop=1; } c_lt_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_NGE_S) { if (check_cop1_unusable()) return; if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft])) { DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); stop=1; } c_nge_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_LE_S) { if (check_cop1_unusable()) return; if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft])) { DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); stop=1; } c_le_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(C_NGT_S) { if (check_cop1_unusable()) return; if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft])) { DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); stop=1; } c_ngt_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); ADD_TO_PC(1); } // COP1_W DECLARE_INSTRUCTION(CVT_S_W) { if (check_cop1_unusable()) return; cvt_s_w((int32_t*)reg_cop1_simple[cffs], reg_cop1_simple[cffd]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(CVT_D_W) { if (check_cop1_unusable()) return; cvt_d_w((int32_t*)reg_cop1_simple[cffs], reg_cop1_double[cffd]); ADD_TO_PC(1); } // regimm DECLARE_JUMP(BLTZ, PCADDR + (iimmediate+1)*4, irs < 0, ®[0], 0, 0) DECLARE_JUMP(BGEZ, PCADDR + (iimmediate+1)*4, irs >= 0, ®[0], 0, 0) DECLARE_JUMP(BLTZL, PCADDR + (iimmediate+1)*4, irs < 0, ®[0], 1, 0) DECLARE_JUMP(BGEZL, PCADDR + (iimmediate+1)*4, irs >= 0, ®[0], 1, 0) DECLARE_JUMP(BLTZAL, PCADDR + (iimmediate+1)*4, irs < 0, ®[31], 0, 0) DECLARE_JUMP(BGEZAL, PCADDR + (iimmediate+1)*4, irs >= 0, ®[31], 0, 0) DECLARE_JUMP(BLTZALL, PCADDR + (iimmediate+1)*4, irs < 0, ®[31], 1, 0) DECLARE_JUMP(BGEZALL, PCADDR + (iimmediate+1)*4, irs >= 0, ®[31], 1, 0) // special DECLARE_INSTRUCTION(NOP) { ADD_TO_PC(1); } DECLARE_INSTRUCTION(SLL) { rrd = SE32((uint32_t)(rrt32) << rsa); ADD_TO_PC(1); } DECLARE_INSTRUCTION(SRL) { rrd = SE32((uint32_t)rrt32 >> rsa); ADD_TO_PC(1); } DECLARE_INSTRUCTION(SRA) { rrd = SE32((int32_t)rrt32 >> rsa); ADD_TO_PC(1); } DECLARE_INSTRUCTION(SLLV) { rrd = SE32((uint32_t)(rrt32) << (rrs32 & 0x1F)); ADD_TO_PC(1); } DECLARE_INSTRUCTION(SRLV) { rrd = SE32((uint32_t)rrt32 >> (rrs32 & 0x1F)); ADD_TO_PC(1); } DECLARE_INSTRUCTION(SRAV) { rrd = SE32((int32_t)rrt32 >> (rrs32 & 0x1F)); ADD_TO_PC(1); } DECLARE_JUMP(JR, irs32, 1, ®[0], 0, 0) DECLARE_JUMP(JALR, irs32, 1, &rrd, 0, 0) DECLARE_INSTRUCTION(SYSCALL) { g_cp0_regs[CP0_CAUSE_REG] = UINT32_C(8) << 2; exception_general(); } DECLARE_INSTRUCTION(SYNC) { ADD_TO_PC(1); } DECLARE_INSTRUCTION(MFHI) { rrd = hi; ADD_TO_PC(1); } DECLARE_INSTRUCTION(MTHI) { hi = rrs; ADD_TO_PC(1); } DECLARE_INSTRUCTION(MFLO) { rrd = lo; ADD_TO_PC(1); } DECLARE_INSTRUCTION(MTLO) { lo = rrs; ADD_TO_PC(1); } DECLARE_INSTRUCTION(DSLLV) { rrd = rrt << (rrs32&0x3F); ADD_TO_PC(1); } DECLARE_INSTRUCTION(DSRLV) { rrd = (uint64_t)rrt >> (rrs32 & 0x3F); ADD_TO_PC(1); } DECLARE_INSTRUCTION(DSRAV) { rrd = (int64_t)rrt >> (rrs32 & 0x3F); ADD_TO_PC(1); } DECLARE_INSTRUCTION(MULT) { int64_t temp = rrs * rrt; hi = temp >> 32; lo = SE32(temp); ADD_TO_PC(1); } DECLARE_INSTRUCTION(MULTU) { uint64_t temp = (uint32_t)rrs * (uint64_t)((uint32_t)rrt); hi = (int64_t)temp >> 32; lo = SE32(temp); ADD_TO_PC(1); } DECLARE_INSTRUCTION(DIV) { if (rrt32) { lo = SE32(rrs32 / rrt32); hi = SE32(rrs32 % rrt32); } else DebugMessage(M64MSG_ERROR, "DIV: divide by 0"); ADD_TO_PC(1); } DECLARE_INSTRUCTION(DIVU) { if (rrt32) { lo = SE32((uint32_t)rrs32 / (uint32_t)rrt32); hi = SE32((uint32_t)rrs32 % (uint32_t)rrt32); } else DebugMessage(M64MSG_ERROR, "DIVU: divide by 0"); ADD_TO_PC(1); } DECLARE_INSTRUCTION(DMULT) { uint64_t op1, op2, op3, op4; uint64_t result1, result2, result3, result4; uint64_t temp1, temp2, temp3, temp4; int sign = 0; if (rrs < 0) { op2 = -rrs; sign = 1 - sign; } else op2 = rrs; if (rrt < 0) { op4 = -rrt; sign = 1 - sign; } else op4 = rrt; op1 = op2 & 0xFFFFFFFF; op2 = (op2 >> 32) & 0xFFFFFFFF; op3 = op4 & 0xFFFFFFFF; op4 = (op4 >> 32) & 0xFFFFFFFF; temp1 = op1 * op3; temp2 = (temp1 >> 32) + op1 * op4; temp3 = op2 * op3; temp4 = (temp3 >> 32) + op2 * op4; result1 = temp1 & 0xFFFFFFFF; result2 = temp2 + (temp3 & 0xFFFFFFFF); result3 = (result2 >> 32) + temp4; result4 = (result3 >> 32); lo = result1 | (result2 << 32); hi = (result3 & 0xFFFFFFFF) | (result4 << 32); if (sign) { hi = ~hi; if (!lo) hi++; else lo = ~lo + 1; } ADD_TO_PC(1); } DECLARE_INSTRUCTION(DMULTU) { uint64_t op1 = rrs & 0xFFFFFFFF; uint64_t op2 = (rrs >> 32) & 0xFFFFFFFF; uint64_t op3 = rrt & 0xFFFFFFFF; uint64_t op4 = (rrt >> 32) & 0xFFFFFFFF; uint64_t temp1 = op1 * op3; uint64_t temp2 = (temp1 >> 32) + op1 * op4; uint64_t temp3 = op2 * op3; uint64_t temp4 = (temp3 >> 32) + op2 * op4; uint64_t result1 = temp1 & 0xFFFFFFFF; uint64_t result2 = temp2 + (temp3 & 0xFFFFFFFF); uint64_t result3 = (result2 >> 32) + temp4; uint64_t result4 = (result3 >> 32); lo = result1 | (result2 << 32); hi = (result3 & 0xFFFFFFFF) | (result4 << 32); ADD_TO_PC(1); } DECLARE_INSTRUCTION(DDIV) { if (rrt) { lo = (int64_t)rrs / (int64_t)rrt; hi = (int64_t)rrs % (int64_t)rrt; } else DebugMessage(M64MSG_ERROR, "DDIV: divide by 0"); ADD_TO_PC(1); } DECLARE_INSTRUCTION(DDIVU) { if (rrt) { lo = (uint64_t)rrs / (uint64_t)rrt; hi = (uint64_t)rrs % (uint64_t)rrt; } else DebugMessage(M64MSG_ERROR, "DDIVU: divide by 0"); ADD_TO_PC(1); } DECLARE_INSTRUCTION(ADD) { rrd = SE32(rrs32 + rrt32); ADD_TO_PC(1); } DECLARE_INSTRUCTION(ADDU) { rrd = SE32(rrs32 + rrt32); ADD_TO_PC(1); } DECLARE_INSTRUCTION(SUB) { rrd = SE32(rrs32 - rrt32); ADD_TO_PC(1); } DECLARE_INSTRUCTION(SUBU) { rrd = SE32(rrs32 - rrt32); ADD_TO_PC(1); } DECLARE_INSTRUCTION(AND) { rrd = rrs & rrt; ADD_TO_PC(1); } DECLARE_INSTRUCTION(OR) { rrd = rrs | rrt; ADD_TO_PC(1); } DECLARE_INSTRUCTION(XOR) { rrd = rrs ^ rrt; ADD_TO_PC(1); } DECLARE_INSTRUCTION(NOR) { rrd = ~(rrs | rrt); ADD_TO_PC(1); } DECLARE_INSTRUCTION(SLT) { if (rrs < rrt) rrd = 1; else rrd = 0; ADD_TO_PC(1); } DECLARE_INSTRUCTION(SLTU) { if ((uint64_t)rrs < (uint64_t)rrt) rrd = 1; else rrd = 0; ADD_TO_PC(1); } DECLARE_INSTRUCTION(DADD) { rrd = rrs + rrt; ADD_TO_PC(1); } DECLARE_INSTRUCTION(DADDU) { rrd = rrs + rrt; ADD_TO_PC(1); } DECLARE_INSTRUCTION(DSUB) { rrd = rrs - rrt; ADD_TO_PC(1); } DECLARE_INSTRUCTION(DSUBU) { rrd = rrs - rrt; ADD_TO_PC(1); } DECLARE_INSTRUCTION(TEQ) { if (rrs == rrt) { DebugMessage(M64MSG_ERROR, "trap exception in TEQ"); stop=1; } ADD_TO_PC(1); } DECLARE_INSTRUCTION(DSLL) { rrd = rrt << rsa; ADD_TO_PC(1); } DECLARE_INSTRUCTION(DSRL) { rrd = (uint64_t)rrt >> rsa; ADD_TO_PC(1); } DECLARE_INSTRUCTION(DSRA) { rrd = rrt >> rsa; ADD_TO_PC(1); } DECLARE_INSTRUCTION(DSLL32) { rrd = rrt << (32+rsa); ADD_TO_PC(1); } DECLARE_INSTRUCTION(DSRL32) { rrd = (uint64_t)rrt >> (32+rsa); ADD_TO_PC(1); } DECLARE_INSTRUCTION(DSRA32) { rrd = (int64_t)rrt >> (32+rsa); ADD_TO_PC(1); } // TLB DECLARE_INSTRUCTION(TLBR) { int index; index = g_cp0_regs[CP0_INDEX_REG] & UINT32_C(0x1F); g_cp0_regs[CP0_PAGEMASK_REG] = tlb_e[index].mask << 13; g_cp0_regs[CP0_ENTRYHI_REG] = ((tlb_e[index].vpn2 << 13) | tlb_e[index].asid); g_cp0_regs[CP0_ENTRYLO0_REG] = (tlb_e[index].pfn_even << 6) | (tlb_e[index].c_even << 3) | (tlb_e[index].d_even << 2) | (tlb_e[index].v_even << 1) | tlb_e[index].g; g_cp0_regs[CP0_ENTRYLO1_REG] = (tlb_e[index].pfn_odd << 6) | (tlb_e[index].c_odd << 3) | (tlb_e[index].d_odd << 2) | (tlb_e[index].v_odd << 1) | tlb_e[index].g; ADD_TO_PC(1); } static void TLBWrite(unsigned int idx) { if (r4300emu != CORE_PURE_INTERPRETER) { unsigned int i; if (tlb_e[idx].v_even) { for (i=tlb_e[idx].start_even>>12; i<=tlb_e[idx].end_even>>12; i++) { if(!invalid_code[i] &&(invalid_code[tlb_LUT_r[i]>>12] || invalid_code[(tlb_LUT_r[i]>>12)+0x20000])) invalid_code[i] = 1; if (!invalid_code[i]) { blocks[i]->adler32 = adler32(0, (uint8_t*)&g_rdram[(tlb_LUT_r[i]&0x7FF000)/4], 0x1000); invalid_code[i] = 1; } else if (blocks[i]) { blocks[i]->adler32 = 0; } } } if (tlb_e[idx].v_odd) { for (i=tlb_e[idx].start_odd>>12; i<=tlb_e[idx].end_odd>>12; i++) { if(!invalid_code[i] &&(invalid_code[tlb_LUT_r[i]>>12] || invalid_code[(tlb_LUT_r[i]>>12)+0x20000])) invalid_code[i] = 1; if (!invalid_code[i]) { blocks[i]->adler32 = adler32(0, (uint8_t*)&g_rdram[(tlb_LUT_r[i]&0x7FF000)/4], 0x1000); invalid_code[i] = 1; } else if (blocks[i]) { blocks[i]->adler32 = 0; } } } } tlb_unmap(&tlb_e[idx]); tlb_e[idx].g = (g_cp0_regs[CP0_ENTRYLO0_REG] & g_cp0_regs[CP0_ENTRYLO1_REG] & 1); tlb_e[idx].pfn_even = (g_cp0_regs[CP0_ENTRYLO0_REG] & UINT32_C(0x3FFFFFC0)) >> 6; tlb_e[idx].pfn_odd = (g_cp0_regs[CP0_ENTRYLO1_REG] & UINT32_C(0x3FFFFFC0)) >> 6; tlb_e[idx].c_even = (g_cp0_regs[CP0_ENTRYLO0_REG] & UINT32_C(0x38)) >> 3; tlb_e[idx].c_odd = (g_cp0_regs[CP0_ENTRYLO1_REG] & UINT32_C(0x38)) >> 3; tlb_e[idx].d_even = (g_cp0_regs[CP0_ENTRYLO0_REG] & UINT32_C(0x4)) >> 2; tlb_e[idx].d_odd = (g_cp0_regs[CP0_ENTRYLO1_REG] & UINT32_C(0x4)) >> 2; tlb_e[idx].v_even = (g_cp0_regs[CP0_ENTRYLO0_REG] & UINT32_C(0x2)) >> 1; tlb_e[idx].v_odd = (g_cp0_regs[CP0_ENTRYLO1_REG] & UINT32_C(0x2)) >> 1; tlb_e[idx].asid = (g_cp0_regs[CP0_ENTRYHI_REG] & UINT32_C(0xFF)); tlb_e[idx].vpn2 = (g_cp0_regs[CP0_ENTRYHI_REG] & UINT32_C(0xFFFFE000)) >> 13; //tlb_e[idx].r = (g_cp0_regs[CP0_ENTRYHI_REG] & 0xC000000000000000LL) >> 62; tlb_e[idx].mask = (g_cp0_regs[CP0_PAGEMASK_REG] & UINT32_C(0x1FFE000)) >> 13; tlb_e[idx].start_even = tlb_e[idx].vpn2 << 13; tlb_e[idx].end_even = tlb_e[idx].start_even+ (tlb_e[idx].mask << 12) + UINT32_C(0xFFF); tlb_e[idx].phys_even = tlb_e[idx].pfn_even << 12; tlb_e[idx].start_odd = tlb_e[idx].end_even+1; tlb_e[idx].end_odd = tlb_e[idx].start_odd+ (tlb_e[idx].mask << 12) + UINT32_C(0xFFF); tlb_e[idx].phys_odd = tlb_e[idx].pfn_odd << 12; tlb_map(&tlb_e[idx]); if (r4300emu != CORE_PURE_INTERPRETER) { unsigned int i; if (tlb_e[idx].v_even) { for (i=tlb_e[idx].start_even>>12; i<=tlb_e[idx].end_even>>12; i++) { if(blocks[i] && blocks[i]->adler32) { if(blocks[i]->adler32 == adler32(0,(uint8_t*)&g_rdram[(tlb_LUT_r[i]&0x7FF000)/4],0x1000)) invalid_code[i] = 0; } } } if (tlb_e[idx].v_odd) { for (i=tlb_e[idx].start_odd>>12; i<=tlb_e[idx].end_odd>>12; i++) { if(blocks[i] && blocks[i]->adler32) { if(blocks[i]->adler32 == adler32(0,(uint8_t*)&g_rdram[(tlb_LUT_r[i]&0x7FF000)/4],0x1000)) invalid_code[i] = 0; } } } } } DECLARE_INSTRUCTION(TLBWI) { TLBWrite(g_cp0_regs[CP0_INDEX_REG] & 0x3F); ADD_TO_PC(1); } DECLARE_INSTRUCTION(TLBWR) { cp0_update_count(); g_cp0_regs[CP0_RANDOM_REG] = (g_cp0_regs[CP0_COUNT_REG] /2 % (32 - g_cp0_regs[CP0_WIRED_REG])) + g_cp0_regs[CP0_WIRED_REG]; TLBWrite(g_cp0_regs[CP0_RANDOM_REG]); ADD_TO_PC(1); } DECLARE_INSTRUCTION(TLBP) { int i; g_cp0_regs[CP0_INDEX_REG] |= UINT32_C(0x80000000); for (i=0; i<32; i++) { if (((tlb_e[i].vpn2 & (~tlb_e[i].mask)) == (((g_cp0_regs[CP0_ENTRYHI_REG] & UINT32_C(0xFFFFE000)) >> 13) & (~tlb_e[i].mask))) && ((tlb_e[i].g) || (tlb_e[i].asid == (g_cp0_regs[CP0_ENTRYHI_REG] & UINT32_C(0xFF))))) { g_cp0_regs[CP0_INDEX_REG] = i; break; } } ADD_TO_PC(1); } DECLARE_INSTRUCTION(ERET) { cp0_update_count(); if (g_cp0_regs[CP0_STATUS_REG] & UINT32_C(0x4)) { DebugMessage(M64MSG_ERROR, "error in ERET"); stop=1; } else { g_cp0_regs[CP0_STATUS_REG] &= ~UINT32_C(0x2); generic_jump_to(g_cp0_regs[CP0_EPC_REG]); } llbit = 0; check_interupt(); last_addr = PCADDR; if (next_interupt <= g_cp0_regs[CP0_COUNT_REG]) gen_interupt(); } gles2n64/src/gles2n64_rsp.c000664 001750 001750 00000014634 12655644434 016456 0ustar00sergiosergio000000 000000 #include #include "Common.h" #include "gles2N64.h" #include "OpenGL.h" #include "Debug.h" #include "RSP.h" #include "RDP.h" #include "N64.h" #include "F3D.h" #include "3DMath.h" #include "VI.h" #include "ShaderCombiner.h" #include "FrameBuffer.h" #include "DepthBuffer.h" #include "GBI.h" #include "gSP.h" #include "Turbo3D.h" #include "Textures.h" #include "Config.h" RSPInfo __RSP; void RSP_LoadMatrix( f32 mtx[4][4], u32 address ) { int i, j; f32 recip = 1.5258789e-05f; struct _N64Matrix { s16 integer[4][4]; u16 fraction[4][4]; } *n64Mat = (struct _N64Matrix *)&gfx_info.RDRAM[address]; for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) mtx[i][j] = (GLfloat)(n64Mat->integer[i][j^1]) + (GLfloat)(n64Mat->fraction[i][j^1]) * recip; } void RSP_CheckDLCounter(void) { if (__RSP.count != -1) { --__RSP.count; if (__RSP.count == 0) { __RSP.count = -1; --__RSP.PCi; #ifdef DEBUG DebugMsg( DEBUG_LOW | DEBUG_HANDLED, "End of DL\n" ); #endif } } } void RSP_ProcessDList(void) { int i, j; u32 uc_start, uc_dstart, uc_dsize; __RSP.PC[0] = *(u32*)&gfx_info.DMEM[0x0FF0]; __RSP.PCi = 0; __RSP.count = -1; __RSP.halt = FALSE; __RSP.busy = TRUE; gSP.matrix.stackSize = min( 32, *(u32*)&gfx_info.DMEM[0x0FE4] >> 6 ); gSP.matrix.modelViewi = 0; gSP.changed &= ~CHANGED_CPU_FB_WRITE; gSP.changed |= CHANGED_MATRIX; gDPSetTexturePersp(G_TP_PERSP); for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) gSP.matrix.modelView[0][i][j] = 0.0f; gSP.matrix.modelView[0][0][0] = 1.0f; gSP.matrix.modelView[0][1][1] = 1.0f; gSP.matrix.modelView[0][2][2] = 1.0f; gSP.matrix.modelView[0][3][3] = 1.0f; uc_start = *(u32*)&gfx_info.DMEM[0x0FD0]; uc_dstart = *(u32*)&gfx_info.DMEM[0x0FD8]; uc_dsize = *(u32*)&gfx_info.DMEM[0x0FDC]; if ((uc_start != __RSP.uc_start) || (uc_dstart != __RSP.uc_dstart)) gSPLoadUcodeEx( uc_start, uc_dstart, uc_dsize ); gDPSetCombineKey(G_CK_NONE); gDPSetTextureLUT(G_TT_NONE); gDPSetTexturePersp(G_TP_PERSP); gDPSetCycleType(G_CYC_1CYCLE); #ifdef NEW depthBufferList().setNotCleared(); #endif if (GBI_GetCurrentMicrocodeType() == Turbo3D) RunTurbo3D(); else while (!__RSP.halt) { u32 w0, w1, pc; pc = __RSP.PC[__RSP.PCi]; if ((pc + 8) > RDRAMSize) { #ifdef DEBUG DebugMsg( DEBUG_LOW | DEBUG_ERROR, "ATTEMPTING TO EXECUTE RSP COMMAND AT INVALID RDRAM LOCATION\n" ); #endif break; } w0 = *(u32*)&gfx_info.RDRAM[pc]; w1 = *(u32*)&gfx_info.RDRAM[pc+4]; __RSP.cmd = _SHIFTR( w0, 24, 8 ); #ifdef DEBUG DebugRSPState( RSP.PCi, RSP.PC[RSP.PCi], _SHIFTR( w0, 24, 8 ), w0, w1 ); DebugMsg( DEBUG_LOW | DEBUG_HANDLED, "0x%08lX: CMD=0x%02lX W0=0x%08lX W1=0x%08lX\n", RSP.PC[RSP.PCi], _SHIFTR( w0, 24, 8 ), w0, w1 ); #endif __RSP.PC[__RSP.PCi] += 8; __RSP.nextCmd = _SHIFTR( *(u32*)&gfx_info.RDRAM[pc+8], 24, 8 ); GBI.cmd[__RSP.cmd]( w0, w1 ); RSP_CheckDLCounter(); } if (config.frameBufferEmulation.copyToRDRAM) FrameBuffer_CopyToRDRAM( gDP.colorImage.address ); if (config.frameBufferEmulation.copyDepthToRDRAM) FrameBuffer_CopyDepthBuffer( gDP.colorImage.address ); __RSP.busy = FALSE; gSP.changed |= CHANGED_COLORBUFFER; } static void RSP_SetDefaultState(void) { unsigned i, j; gSPTexture(1.0f, 1.0f, 0, 0, TRUE); gDP.loadTile = &gDP.tiles[7]; gSP.textureTile[0] = &gDP.tiles[0]; gSP.textureTile[1] = &gDP.tiles[1]; gSP.lookat[0].x = gSP.lookat[1].x = 1.0f; gSP.lookatEnable = false; gSP.objMatrix.A = 1.0f; gSP.objMatrix.B = 0.0f; gSP.objMatrix.C = 0.0f; gSP.objMatrix.D = 1.0f; gSP.objMatrix.X = 0.0f; gSP.objMatrix.Y = 0.0f; gSP.objMatrix.baseScaleX = 1.0f; gSP.objMatrix.baseScaleY = 1.0f; gSP.objRendermode = 0; for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) gSP.matrix.modelView[0][i][j] = 0.0f; gSP.matrix.modelView[0][0][0] = 1.0f; gSP.matrix.modelView[0][1][1] = 1.0f; gSP.matrix.modelView[0][2][2] = 1.0f; gSP.matrix.modelView[0][3][3] = 1.0f; gDP.otherMode._u64 = 0U; } u32 DepthClearColor = 0xfffcfffc; static void setDepthClearColor(void) { if (strstr(__RSP.romname, (const char *)"Elmo's") != NULL) DepthClearColor = 0xFFFFFFFF; else if (strstr(__RSP.romname, (const char *)"Taz Express") != NULL) DepthClearColor = 0xFFBCFFBC; else if (strstr(__RSP.romname, (const char *)"NFL QBC 2000") != NULL || strstr(__RSP.romname, (const char *)"NFL Quarterback Club") != NULL || strstr(__RSP.romname, (const char *)"Jeremy McGrath Super") != NULL) DepthClearColor = 0xFFFDFFFC; else DepthClearColor = 0xFFFCFFFC; } void RSP_Init(void) { unsigned i; char romname[21]; RDRAMSize = 1024 * 1024 * 8; __RSP.DList = 0; __RSP.uc_start = __RSP.uc_dstart = 0; __RSP.bLLE = false; for (i = 0; i < 20; ++i) romname[i] = gfx_info.HEADER[(32 + i) ^ 3]; romname[20] = 0; // remove all trailing spaces while (romname[strlen(romname) - 1] == ' ') romname[strlen(romname) - 1] = 0; strncpy(__RSP.romname, romname, 21); setDepthClearColor(); config.generalEmulation.hacks = 0; if (strstr(__RSP.romname, (const char *)"OgreBattle64") != NULL) config.generalEmulation.hacks |= hack_Ogre64; else if (strstr(__RSP.romname, (const char *)"MarioGolf64") != NULL || strstr(__RSP.romname, (const char *)"F1 POLE POSITION 64") != NULL ) config.generalEmulation.hacks |= hack_noDepthFrameBuffers; else if (strstr(__RSP.romname, (const char *)"CONKER BFD") != NULL || strstr(__RSP.romname, (const char *)"MICKEY USA") != NULL ) config.generalEmulation.hacks |= hack_blurPauseScreen; else if (strstr(__RSP.romname, (const char *)"MarioTennis") != NULL) config.generalEmulation.hacks |= hack_scoreboard; else if (strstr(__RSP.romname, (const char *)"Pilot Wings64") != NULL) config.generalEmulation.hacks |= hack_pilotWings; else if (strstr(__RSP.romname, (const char *)"THE LEGEND OF ZELDA") != NULL || strstr(__RSP.romname, (const char *)"ZELDA MASTER QUEST") != NULL ) config.generalEmulation.hacks |= hack_subscreen; else if (strstr(__RSP.romname, (const char *)"LEGORacers") != NULL) config.generalEmulation.hacks |= hack_legoRacers; else if (strstr(__RSP.romname, (const char *)"Blast") != NULL) config.generalEmulation.hacks |= hack_blastCorps; RSP_SetDefaultState(); DepthBuffer_Init(); GBI_Init(); } libretro-common/000700 001750 001750 00000000000 12656647145 015016 5ustar00sergiosergio000000 000000 mupen64plus-video-gliden64/src/GLideNHQ/TxReSample.cpp000664 001750 001750 00000023130 12655644434 023510 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "TxReSample.h" #include "TxDbg.h" #include #include #define _USE_MATH_DEFINES #include #ifndef M_PI #define M_PI 3.14159265358979323846 #endif int TxReSample::nextPow2(int num) { num = num - 1; num = num | (num >> 1); num = num | (num >> 2); num = num | (num >> 4); num = num | (num >> 8); num = num | (num >> 16); /*num = num | (num >> 32);*//* for 64bit architecture */ num = num + 1; return num; } boolean TxReSample::nextPow2(uint8** image, int* width, int* height, int bpp, boolean use_3dfx = 0) { /* NOTE: bpp must be one of the follwing: 8, 16, 24, 32 bits per pixel */ if (!*image || !*width || !*height || !bpp) return 0; int row_bytes = ((*width * bpp) >> 3); int o_row_bytes = row_bytes; int o_width = *width; int n_width = *width; int o_height = *height; int n_height = *height; /* HACKALERT: I have explicitly subtracted (n) from width/height to * adjust textures that have (n) pixel larger width/height than * power of 2 size. This is a dirty hack for textures that have * munged aspect ratio by (n) pixel to the original. */ if (n_width > 64) n_width -= 4; else if (n_width > 16) n_width -= 2; else if (n_width > 4) n_width -= 1; if (n_height > 64) n_height -= 4; else if (n_height > 16) n_height -= 2; else if (n_height > 4) n_height -= 1; n_width = nextPow2(n_width); n_height = nextPow2(n_height); row_bytes = (n_width * bpp) >> 3; /* 3dfx Glide3 format, W:H aspect ratio range (8:1 - 1:8) */ if (use_3dfx) { if (n_width > n_height) { if (n_width > (n_height << 3)) n_height = n_width >> 3; } else { if (n_height > (n_width << 3)) { n_width = n_height >> 3; row_bytes = (n_width * bpp) >> 3; } } DBG_INFO(80, wst("using 3dfx W:H aspect ratio range (8:1 - 1:8).\n")); } /* do we really need to do this ? */ if (o_width == n_width && o_height == n_height) return 1; /* nope */ DBG_INFO(80, wst("expand image to next power of 2 dimensions. %d x %d -> %d x %d\n"), o_width, o_height, n_width, n_height); if (o_width > n_width) o_width = n_width; if (o_height > n_height) o_height = n_height; /* allocate memory to read in image */ uint8 *pow2image = (uint8*)malloc(row_bytes * n_height); /* read in image */ if (pow2image) { int i, j; uint8 *tmpimage = *image, *tmppow2image = pow2image; for (i = 0; i < o_height; i++) { /* copy row */ memcpy(tmppow2image, tmpimage, ((o_width * bpp) >> 3)); /* expand to pow2 size by replication */ for(j = ((o_width * bpp) >> 3); j < row_bytes; j++) tmppow2image[j] = tmppow2image[j - (bpp >> 3)]; tmppow2image += row_bytes; tmpimage += o_row_bytes; } /* expand to pow2 size by replication */ for (i = o_height; i < n_height; i++) memcpy(&pow2image[row_bytes * i], &pow2image[row_bytes * (i - 1)], row_bytes); free(*image); *image = pow2image; *height = n_height; *width = n_width; return 1; } return 0; } /* Ken Turkowski * Filters for Common Resampling Tasks * Apple Computer 1990 */ double TxReSample::tent(double x) { if (x < 0.0) x = -x; if (x < 1.0) return (1.0 - x); return 0.0; } double TxReSample::gaussian(double x) { if (x < 0) x = -x; if (x < 2.0) return pow(2.0, -2.0 * x * x); return 0.0; } double TxReSample::sinc(double x) { if (x == 0) return 1.0; x *= M_PI; return (sin(x) / x); } double TxReSample::lanczos3(double x) { if (x < 0) x = -x; if (x < 3.0) return (sinc(x) * sinc(x/3.0)); return 0.0; } /* Don P. Mitchell and Arun N. Netravali * Reconstruction Filters in Computer Graphics * SIGGRAPH '88 * Proceedings of the 15th annual conference on Computer * graphics and interactive techniques, pp221-228, 1988 */ double TxReSample::mitchell(double x) { if (x < 0) x = -x; if (x < 2.0) { const double B = 1.0 / 3.0; const double C = 1.0 / 3.0; if (x < 1.0) { x = (((12.0 - 9.0 * B - 6.0 * C) * (x * x * x)) + ((-18.0 + 12.0 * B + 6.0 * C) * (x * x)) + (6.0 - 2.0 * B)); } else { x = (((-1.0 * B - 6.0 * C) * (x * x * x)) + ((6.0 * B + 30.0 * C) * (x * x)) + ((-12.0 * B - 48.0 * C) * x) + (8.0 * B + 24.0 * C)); } return (x / 6.0); } return 0.0; } /* J. F. Kaiser and W. A. Reed * Data smoothing using low-pass digital filters * Rev. Sci. instrum. 48 (11), pp1447-1457, 1977 */ double TxReSample::besselI0(double x) { /* zero-order modified bessel function of the first kind */ const double eps_coeff = 1E-16; /* small enough */ double xh, sum, pow, ds; xh = 0.5 * x; sum = 1.0; pow = 1.0; ds = 1.0; int k = 0; while (ds > sum * eps_coeff) { k++; pow *= (xh / k); ds = pow * pow; sum = sum + ds; } return sum; } double TxReSample::kaiser(double x) { const double alpha = 4.0; const double half_window = 5.0; const double ratio = x / half_window; return sinc(x) * besselI0(alpha * sqrt(1 - ratio * ratio)) / besselI0(alpha); } boolean TxReSample::minify(uint8 **src, int *width, int *height, int ratio) { /* NOTE: src must be ARGB8888, ratio is the inverse representation */ if (!*src || ratio < 2) return 0; /* Image Resampling */ /* half width of filter window. * NOTE: must be 1.0 or larger. * * kaiser-bessel 5, lanczos3 3, mitchell 2, gaussian 1.5, tent 1 */ double half_window = 5.0; int x, y, x2, y2, z; double A, R, G, B; uint32 texel; int tmpwidth = *width / ratio; int tmpheight = *height / ratio; /* resampled destination */ uint8 *tmptex = (uint8*)malloc((tmpwidth * tmpheight) << 2); if (!tmptex) return 0; /* work buffer. single row */ uint8 *workbuf = (uint8*)malloc(*width << 2); if (!workbuf) { free(tmptex); return 0; } /* prepare filter lookup table. only half width required for symetric filters. */ double *weight = (double*)malloc((int)((half_window * ratio) * sizeof(double))); if (!weight) { free(tmptex); free(workbuf); return 0; } for (x = 0; x < half_window * ratio; x++) { //weight[x] = tent((double)x / ratio) / ratio; //weight[x] = gaussian((double)x / ratio) / ratio; //weight[x] = lanczos3((double)x / ratio) / ratio; //weight[x] = mitchell((double)x / ratio) / ratio; weight[x] = kaiser((double)x / ratio) / ratio; } /* linear convolution */ for (y = 0; y < tmpheight; y++) { for (x = 0; x < *width; x++) { texel = ((uint32*)*src)[y * ratio * *width + x]; A = (double)(texel >> 24) * weight[0]; R = (double)((texel >> 16) & 0xff) * weight[0]; G = (double)((texel >> 8) & 0xff) * weight[0]; B = (double)((texel ) & 0xff) * weight[0]; for (y2 = 1; y2 < half_window * ratio; y2++) { z = y * ratio + y2; if (z >= *height) z = *height - 1; texel = ((uint32*)*src)[z * *width + x]; A += (double)(texel >> 24) * weight[y2]; R += (double)((texel >> 16) & 0xff) * weight[y2]; G += (double)((texel >> 8) & 0xff) * weight[y2]; B += (double)((texel ) & 0xff) * weight[y2]; z = y * ratio - y2; if (z < 0) z = 0; texel = ((uint32*)*src)[z * *width + x]; A += (double)(texel >> 24) * weight[y2]; R += (double)((texel >> 16) & 0xff) * weight[y2]; G += (double)((texel >> 8) & 0xff) * weight[y2]; B += (double)((texel ) & 0xff) * weight[y2]; } if (A < 0) A = 0; else if (A > 255) A = 255; if (R < 0) R = 0; else if (R > 255) R = 255; if (G < 0) G = 0; else if (G > 255) G = 255; if (B < 0) B = 0; else if (B > 255) B = 255; ((uint32*)workbuf)[x] = (((uint32)A << 24) | ((uint32)R << 16) | ((uint32)G << 8) | (uint32)B); } for (x = 0; x < tmpwidth; x++) { texel = ((uint32*)workbuf)[x * ratio]; A = (double)(texel >> 24) * weight[0]; R = (double)((texel >> 16) & 0xff) * weight[0]; G = (double)((texel >> 8) & 0xff) * weight[0]; B = (double)((texel ) & 0xff) * weight[0]; for (x2 = 1; x2 < half_window * ratio; x2++) { z = x * ratio + x2; if (z >= *width) z = *width - 1; texel = ((uint32*)workbuf)[z]; A += (double)(texel >> 24) * weight[x2]; R += (double)((texel >> 16) & 0xff) * weight[x2]; G += (double)((texel >> 8) & 0xff) * weight[x2]; B += (double)((texel ) & 0xff) * weight[x2]; z = x * ratio - x2; if (z < 0) z = 0; texel = ((uint32*)workbuf)[z]; A += (double)(texel >> 24) * weight[x2]; R += (double)((texel >> 16) & 0xff) * weight[x2]; G += (double)((texel >> 8) & 0xff) * weight[x2]; B += (double)((texel ) & 0xff) * weight[x2]; } if (A < 0) A = 0; else if (A > 255) A = 255; if (R < 0) R = 0; else if (R > 255) R = 255; if (G < 0) G = 0; else if (G > 255) G = 255; if (B < 0) B = 0; else if (B > 255) B = 255; ((uint32*)tmptex)[y * tmpwidth + x] = (((uint32)A << 24) | ((uint32)R << 16) | ((uint32)G << 8) | (uint32)B); } } free(*src); *src = tmptex; free(weight); free(workbuf); *width = tmpwidth; *height = tmpheight; DBG_INFO(80, wst("minification ratio:%d -> %d x %d\n"), ratio, *width, *height); return 1; } mupen64plus-core/src/api/m64p_types.h000664 001750 001750 00000030271 12655644434 020575 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-core - m64p_types.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2012 CasualJames * * Copyright (C) 2009 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_TYPES_H #define M64P_TYPES_H #include #include /* ----------------------------------------- */ /* Platform-specific stuff */ /* ----------------------------------------- */ /* necessary headers */ #if defined(WIN32) #include #endif /* DLL handles and function declaration specifiers */ #define IMPORT #define EXPORT #define CALL typedef void * m64p_dynlib_handle; /* ----------------------------------------- */ /* Structures and Types for Core library API */ /* ----------------------------------------- */ typedef void * m64p_handle; typedef void (*m64p_frame_callback)(unsigned int FrameIndex); typedef void (*m64p_input_callback)(void); typedef void (*m64p_audio_callback)(void); typedef void (*m64p_vi_callback)(void); typedef enum { M64TYPE_INT = 1, M64TYPE_FLOAT, M64TYPE_BOOL, M64TYPE_STRING } m64p_type; typedef enum { M64MSG_ERROR = 1, M64MSG_WARNING, M64MSG_INFO, M64MSG_STATUS, M64MSG_VERBOSE } m64p_msg_level; typedef enum { M64ERR_SUCCESS = 0, M64ERR_NOT_INIT, /* Function is disallowed before InitMupen64Plus() is called */ M64ERR_ALREADY_INIT, /* InitMupen64Plus() was called twice */ M64ERR_INCOMPATIBLE, /* API versions between components are incompatible */ M64ERR_INPUT_ASSERT, /* Invalid parameters for function call, such as ParamValue=NULL for GetCoreParameter() */ M64ERR_INPUT_INVALID, /* Invalid input data, such as ParamValue="maybe" for SetCoreParameter() to set a BOOL-type value */ M64ERR_INPUT_NOT_FOUND, /* The input parameter(s) specified a particular item which was not found */ M64ERR_NO_MEMORY, /* Memory allocation failed */ M64ERR_FILES, /* Error opening, creating, reading, or writing to a file */ M64ERR_INTERNAL, /* Internal error (bug) */ M64ERR_INVALID_STATE, /* Current program state does not allow operation */ M64ERR_PLUGIN_FAIL, /* A plugin function returned a fatal error */ M64ERR_SYSTEM_FAIL, /* A system function call, such as an SDL or file operation, failed */ M64ERR_UNSUPPORTED, /* Function call is not supported (ie, core not built with debugger) */ M64ERR_WRONG_TYPE /* A given input type parameter cannot be used for desired operation */ } m64p_error; typedef enum { M64CAPS_DYNAREC = 1, M64CAPS_DEBUGGER = 2, M64CAPS_CORE_COMPARE = 4 } m64p_core_caps; typedef enum { M64PLUGIN_NULL = 0, M64PLUGIN_RSP = 1, M64PLUGIN_GFX, M64PLUGIN_AUDIO, M64PLUGIN_INPUT, M64PLUGIN_CORE } m64p_plugin_type; typedef enum { M64EMU_STOPPED = 1, M64EMU_RUNNING, M64EMU_PAUSED } m64p_emu_state; typedef enum { M64VIDEO_NONE = 1, M64VIDEO_WINDOWED, M64VIDEO_FULLSCREEN } m64p_video_mode; typedef enum { M64VIDEOFLAG_SUPPORT_RESIZING = 1 } m64p_video_flags; typedef enum { M64CORE_EMU_STATE = 1, M64CORE_VIDEO_SIZE, M64CORE_INPUT_GAMESHARK, M64CORE_STATE_LOADCOMPLETE, M64CORE_STATE_SAVECOMPLETE } m64p_core_param; typedef enum { M64CMD_NOP = 0, M64CMD_ROM_OPEN, M64CMD_ROM_CLOSE, M64CMD_ROM_GET_HEADER, M64CMD_ROM_GET_SETTINGS, M64CMD_EXECUTE, M64CMD_STOP, M64CMD_PAUSE, M64CMD_RESUME, M64CMD_CORE_STATE_QUERY, M64CMD_SET_FRAME_CALLBACK, M64CMD_CORE_STATE_SET, M64CMD_READ_SCREEN, M64CMD_RESET, M64CMD_ADVANCE_FRAME, M64CMD_DDROM_OPEN, M64CMD_DISK_OPEN, M64CMD_DISK_CLOSE } m64p_command; typedef struct { uint32_t address; int value; } m64p_cheat_code; /* ----------------------------------------- */ /* Structures to hold ROM image information */ /* ----------------------------------------- */ typedef enum { SYSTEM_NTSC = 0, SYSTEM_PAL, SYSTEM_MPAL } m64p_system_type; typedef struct { uint8_t init_PI_BSB_DOM1_LAT_REG; /* 0x00 */ uint8_t init_PI_BSB_DOM1_PGS_REG; /* 0x01 */ uint8_t init_PI_BSB_DOM1_PWD_REG; /* 0x02 */ uint8_t init_PI_BSB_DOM1_PGS_REG2; /* 0x03 */ uint32_t ClockRate; /* 0x04 */ uint32_t PC; /* 0x08 */ uint32_t Release; /* 0x0C */ uint32_t CRC1; /* 0x10 */ uint32_t CRC2; /* 0x14 */ uint32_t Unknown[2]; /* 0x18 */ uint8_t Name[20]; /* 0x20 to 0x33 */ uint32_t unknown; uint32_t Manufacturer_ID; /* 0x3B */ uint16_t Cartridge_ID; /* 0x3C to 0x3D */ char destination_code; /* 0x3E */ unsigned char mask_ROM_version; /* 0x3F */ } m64p_rom_header; typedef struct { char goodname[256]; char MD5[33]; unsigned char savetype; unsigned char status; /* Rom status on a scale from 0-5. */ unsigned char players; /* Local players 0-4, 2/3/4 way Netplay indicated by 5/6/7. */ unsigned char rumble; /* 0 - No, 1 - Yes boolean for rumble support. */ } m64p_rom_settings; /* ----------------------------------------- */ /* Structures and Types for the Debugger */ /* ----------------------------------------- */ typedef enum { M64P_DBG_RUN_STATE = 1, M64P_DBG_PREVIOUS_PC, M64P_DBG_NUM_BREAKPOINTS, M64P_DBG_CPU_DYNACORE, M64P_DBG_CPU_NEXT_INTERRUPT } m64p_dbg_state; typedef enum { M64P_DBG_RUNSTATE_PAUSED = 0, M64P_DBG_RUNSTATE_STEPPING, M64P_DBG_RUNSTATE_RUNNING } m64p_dbg_runstate; typedef enum { M64P_DBG_MEM_TYPE = 1, M64P_DBG_MEM_FLAGS, M64P_DBG_MEM_HAS_RECOMPILED, M64P_DBG_MEM_NUM_RECOMPILED, M64P_DBG_RECOMP_OPCODE = 16, M64P_DBG_RECOMP_ARGS, M64P_DBG_RECOMP_ADDR } m64p_dbg_mem_info; typedef enum { M64P_MEM_NOMEM = 0, M64P_MEM_NOTHING, M64P_MEM_RDRAM, M64P_MEM_RDRAMREG, M64P_MEM_RSPMEM, M64P_MEM_RSPREG, M64P_MEM_RSP, M64P_MEM_DP, M64P_MEM_DPS, M64P_MEM_VI, M64P_MEM_AI, M64P_MEM_PI, M64P_MEM_RI, M64P_MEM_SI, M64P_MEM_FLASHRAMSTAT, M64P_MEM_ROM, M64P_MEM_PIF, M64P_MEM_MI, M64P_MEM_BREAKPOINT, M64P_MEM_DD } m64p_dbg_mem_type; typedef enum { M64P_MEM_FLAG_READABLE = 0x01, M64P_MEM_FLAG_WRITABLE = 0x02, M64P_MEM_FLAG_READABLE_EMUONLY = 0x04, /* the EMUONLY flags signify that emulated code can read/write here, but debugger cannot */ M64P_MEM_FLAG_WRITABLE_EMUONLY = 0x08 } m64p_dbg_mem_flags; typedef enum { M64P_DBG_PTR_RDRAM = 1, M64P_DBG_PTR_PI_REG, M64P_DBG_PTR_SI_REG, M64P_DBG_PTR_VI_REG, M64P_DBG_PTR_RI_REG, M64P_DBG_PTR_AI_REG } m64p_dbg_memptr_type; typedef enum { M64P_CPU_PC = 1, M64P_CPU_REG_REG, M64P_CPU_REG_HI, M64P_CPU_REG_LO, M64P_CPU_REG_COP0, M64P_CPU_REG_COP1_DOUBLE_PTR, M64P_CPU_REG_COP1_SIMPLE_PTR, M64P_CPU_REG_COP1_FGR_64, M64P_CPU_TLB } m64p_dbg_cpu_data; typedef enum { M64P_BKP_CMD_ADD_ADDR = 1, M64P_BKP_CMD_ADD_STRUCT, M64P_BKP_CMD_REPLACE, M64P_BKP_CMD_REMOVE_ADDR, M64P_BKP_CMD_REMOVE_IDX, M64P_BKP_CMD_ENABLE, M64P_BKP_CMD_DISABLE, M64P_BKP_CMD_CHECK } m64p_dbg_bkp_command; #define M64P_MEM_INVALID 0xFFFFFFFF /* invalid memory read will return this */ #define BREAKPOINTS_MAX_NUMBER 128 typedef enum { M64P_BKP_FLAG_ENABLED = 0x01, M64P_BKP_FLAG_READ = 0x02, M64P_BKP_FLAG_WRITE = 0x04, M64P_BKP_FLAG_EXEC = 0x08, M64P_BKP_FLAG_LOG = 0x10 /* Log to the console when this breakpoint hits */ } m64p_dbg_bkp_flags; #define BPT_CHECK_FLAG(a, b) ((a.flags & b) == b) #define BPT_SET_FLAG(a, b) a.flags = (a.flags | b); #define BPT_CLEAR_FLAG(a, b) a.flags = (a.flags & (~b)); #define BPT_TOGGLE_FLAG(a, b) a.flags = (a.flags ^ b); typedef struct { uint32_t address; uint32_t endaddr; unsigned int flags; } m64p_breakpoint; /* ------------------------------------------------- */ /* Structures and Types for Core Video Extension API */ /* ------------------------------------------------- */ typedef struct { unsigned int uiWidth; unsigned int uiHeight; } m64p_2d_size; typedef enum { M64P_GL_DOUBLEBUFFER = 1, M64P_GL_BUFFER_SIZE, M64P_GL_DEPTH_SIZE, M64P_GL_RED_SIZE, M64P_GL_GREEN_SIZE, M64P_GL_BLUE_SIZE, M64P_GL_ALPHA_SIZE, M64P_GL_SWAP_CONTROL, M64P_GL_MULTISAMPLEBUFFERS, M64P_GL_MULTISAMPLESAMPLES, M64P_GL_CONTEXT_MAJOR_VERSION, M64P_GL_CONTEXT_MINOR_VERSION, M64P_GL_CONTEXT_PROFILE_MASK, } m64p_GLattr; typedef enum { M64P_GL_CONTEXT_PROFILE_CORE, M64P_GL_CONTEXT_PROFILE_COMPATIBILITY, M64P_GL_CONTEXT_PROFILE_ES } m64p_GLContextType; typedef struct { unsigned int Functions; m64p_error (*VidExtFuncInit)(void); m64p_error (*VidExtFuncQuit)(void); m64p_error (*VidExtFuncListModes)(m64p_2d_size *, int *); m64p_error (*VidExtFuncSetMode)(int, int, int, int, int); void * (*VidExtFuncGLGetProc)(const char*); m64p_error (*VidExtFuncGLSetAttr)(m64p_GLattr, int); m64p_error (*VidExtFuncGLGetAttr)(m64p_GLattr, int *); m64p_error (*VidExtFuncGLSwapBuf)(void); m64p_error (*VidExtFuncSetCaption)(const char *); m64p_error (*VidExtFuncToggleFS)(void); m64p_error (*VidExtFuncResizeWindow)(int, int); } m64p_video_extension_functions; /* ------------------------------------------ */ /* Structures and Types for Audio Backend API */ /* ------------------------------------------ */ /* Audio backend object * * user_data is a pointer which will ba passed as the first argument of audio backend functions. * Frontend writers are free to use it as they please. * * set_audio_format function allow the audio backend to be notified of the format of incoming samples. * 2nd parameter frequency is the sample rate of incoming samples. * 3rd parameter bits is the sample resolution (usually 16 bits) * * This function should be called by the core at least one time before any call to "push_audio_samples". * Audio backends are expected to handle gracefully eventual changes of audio format * even after this"initial" setup. Though in practice, very few game, if any, * changes the audio format after the initial setup. * * push_audio_samples function notify the audio backend of new samples ready to be played. * 2nd parameter buffer is a pointer to the beginning of the incoming samples. * 3rd parameter size is the size in bytes of the buffer. * * Samples are in stereo interleaved format (LR LR LR ...) and their resolution (bits per channel) * is specified by prior calls of set_audio_format. * Audio backends are expected not to block during the servicing of this function. * We invite audio backends writers to buffer (and maybe resample) the incoming samples * and return control to the core as soon as possible. */ struct m64p_audio_backend { void* user_data; void (*set_audio_format)(void*, unsigned int, unsigned int); void (*push_audio_samples)(void*, const void*, size_t); }; #endif /* define M64P_TYPES_H */ mupen64plus-core/src/ri/rdram.h000664 001750 001750 00000005141 12655644434 017527 0ustar00sergiosergio000000 000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - rdram.h * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2014 Bobby Smiles * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef M64P_RI_RDRAM_H #define M64P_RI_RDRAM_H #include #include #ifndef RDRAM_REG #define RDRAM_REG(a) ((a & 0x3ff) >> 2) #endif #ifndef RDRAM_DRAM_ADDR #define RDRAM_DRAM_ADDR(a) ((address & 0xffffff) >> 2) #endif enum rdram_registers { RDRAM_CONFIG_REG, RDRAM_DEVICE_ID_REG, RDRAM_DELAY_REG, RDRAM_MODE_REG, RDRAM_REF_INTERVAL_REG, RDRAM_REF_ROW_REG, RDRAM_RAS_INTERVAL_REG, RDRAM_MIN_INTERVAL_REG, RDRAM_ADDR_SELECT_REG, RDRAM_DEVICE_MANUF_REG, RDRAM_REGS_COUNT }; struct rdram { uint32_t regs[RDRAM_REGS_COUNT]; uint32_t* dram; size_t dram_size; }; void connect_rdram(struct rdram* rdram, uint32_t* dram, size_t dram_size); void init_rdram(struct rdram* rdram); int read_rdram_regs(void* opaque, uint32_t address, uint32_t* value); int write_rdram_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask); int read_rdram_dram(void* opaque, uint32_t address, uint32_t* value); int write_rdram_dram(void* opaque, uint32_t address, uint32_t value, uint32_t mask); #endif mupen64plus-video-gliden64/projects/cmake/Readme.txt000664 001750 001750 00000000723 12655644434 023510 0ustar00sergiosergio000000 000000 cmake project files located inside src folder. To build the project with cmake, run cmake [-DCMAKE_BUILD_TYPE=Debug] [-DOPT=On] -DMUPENPLUSAPI=On ../../src/ -DCMAKE_BUILD_TYPE=Debug - optional parameter, if you want debug build. Default buid type is Release -DOPT=On - optional parameter. set it if you want to enable additional optimizations (can cause additional bugs). -DMUPENPLUSAPI=On - currently cmake build works only for mupen64plus version of the plugin. mupen64plus-video-gliden64/src/GLideNHQ/TextureFilters_2xsai.h000664 001750 001750 00000011523 12655644434 025233 0ustar00sergiosergio000000 000000 /* * Texture Filtering * Version: 1.0 * * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. * Email koolsmoky(at)users.sourceforge.net * Web http://www.3dfxzone.it/koolsmoky * * this is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * this is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Based on Derek Liauw Kie Fa and Rice1964 Super2xSaI code */ int row0, row1, row2, row3; int col0, col1, col2, col3; uint16 x; uint16 y; for (y = 0; y < height; y++) { if ((y > 0) && (y < height - 1)) { row0 = width; row0 = -row0; row1 = 0; row2 = width; row3 = (y == height - 2 ? width : width << 1); } else { row0 = 0; row1 = 0; row2 = 0; row3 = 0; } for (x = 0; x < width; x++) { //--------------------------------------- B0 B1 B2 B3 // 4 5 6 S2 // 1 2 3 S1 // A0 A1 A2 A3 if ((x > 0) && (x < width - 1)) { col0 = -1; col1 = 0; col2 = 1; col3 = (x == width - 2 ? 1 : 2); } else { col0 = 0; col1 = 0; col2 = 0; col3 = 0; } colorB0 = *(srcPtr + col0 + row0); colorB1 = *(srcPtr + col1 + row0); colorB2 = *(srcPtr + col2 + row0); colorB3 = *(srcPtr + col3 + row0); color4 = *(srcPtr + col0 + row1); color5 = *(srcPtr + col1 + row1); color6 = *(srcPtr + col2 + row1); colorS2 = *(srcPtr + col3 + row1); color1 = *(srcPtr + col0 + row2); color2 = *(srcPtr + col1 + row2); color3 = *(srcPtr + col2 + row2); colorS1 = *(srcPtr + col3 + row2); colorA0 = *(srcPtr + col0 + row3); colorA1 = *(srcPtr + col1 + row3); colorA2 = *(srcPtr + col2 + row3); colorA3 = *(srcPtr + col3 + row3); //-------------------------------------- if (color2 == color6 && color5 != color3) product2b = product1b = color2; else if (color5 == color3 && color2 != color6) product2b = product1b = color5; else if (color5 == color3 && color2 == color6) { int r = 0; r += GET_RESULT(color6, color5, color1, colorA1); r += GET_RESULT(color6, color5, color4, colorB1); r += GET_RESULT(color6, color5, colorA2, colorS1); r += GET_RESULT(color6, color5, colorB2, colorS2); if (r > 0) product2b = product1b = color6; else if (r < 0) product2b = product1b = color5; else product2b = product1b = SAI_INTERPOLATE(color5, color6); } else { if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0) product2b = SAI_Q_INTERPOLATE(color3, color3, color3, color2); else if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3) product2b = SAI_Q_INTERPOLATE(color2, color2, color2, color3); else product2b = SAI_INTERPOLATE(color2, color3); if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0) product1b = SAI_Q_INTERPOLATE(color6, color6, color6, color5); else if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3) product1b = SAI_Q_INTERPOLATE(color6, color5, color5, color5); else product1b = SAI_INTERPOLATE(color5, color6); } if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2) product2a = SAI_INTERPOLATE(color2, color5); else if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0) product2a = SAI_INTERPOLATE(color2, color5); else product2a = color2; if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2) product1a = SAI_INTERPOLATE(color2, color5); else if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0) product1a = SAI_INTERPOLATE(color2, color5); else product1a = color5; destPtr[0] = product1a; destPtr[1] = product1b; destPtr[destWidth] = product2a; destPtr[destWidth + 1] = product2b; srcPtr++; destPtr += 2; } srcPtr += (pitch-width); destPtr += (((pitch-width)<<1)+(pitch<<1)); }